version 1.23, 2011/08/20 11:11:30 |
version 1.24, 2011/08/23 04:13:38 |
|
|
int Sflag; /* Socket buffer size (tcp mode) */ |
int Sflag; /* Socket buffer size (tcp mode) */ |
u_int rflag; /* Report rate (ms) */ |
u_int rflag; /* Report rate (ms) */ |
int sflag; /* True if server */ |
int sflag; /* True if server */ |
|
int Tflag; /* ToS if != -1 */ |
int vflag; /* Verbose */ |
int vflag; /* Verbose */ |
int uflag; /* UDP mode */ |
int uflag; /* UDP mode */ |
kvm_t *kvmh; /* Kvm handler */ |
kvm_t *kvmh; /* Kvm handler */ |
|
|
static int clock_gettime_tv(clockid_t, struct timeval *); |
static int clock_gettime_tv(clockid_t, struct timeval *); |
static void udp_server_handle_sc(int, short, void *); |
static void udp_server_handle_sc(int, short, void *); |
static void udp_process_slice(int, short, void *); |
static void udp_process_slice(int, short, void *); |
|
static int map_tos(char *, int *); |
/* |
/* |
* We account the mainstats here, that is the stats |
* We account the mainstats here, that is the stats |
* for all connections, all variables starting with slice |
* for all connections, all variables starting with slice |
|
|
fprintf(stderr, |
fprintf(stderr, |
"usage: tcpbench -l\n" |
"usage: tcpbench -l\n" |
" tcpbench [-uv] [-B buf] [-k kvars] [-n connections] [-p port]\n" |
" tcpbench [-uv] [-B buf] [-k kvars] [-n connections] [-p port]\n" |
" [-r interval] [-S space] [-V rtable] hostname\n" |
" [-r interval] [-S space] [-T toskeyword] [-V rtable]\n" |
|
" hostname\n" |
" tcpbench -s [-uv] [-B buf] [-k kvars] [-p port]\n" |
" tcpbench -s [-uv] [-B buf] [-k kvars] [-p port]\n" |
" [-r interval] [-S space] [-V rtable]\n"); |
" [-r interval] [-S space] [-T toskeyword] [-V rtable]\n"); |
exit(1); |
exit(1); |
} |
} |
|
|
|
|
r |= O_NONBLOCK; |
r |= O_NONBLOCK; |
if (fcntl(sock, F_SETFL, r) == -1) |
if (fcntl(sock, F_SETFL, r) == -1) |
err(1, "fcntl(F_SETFL, O_NONBLOCK)"); |
err(1, "fcntl(F_SETFL, O_NONBLOCK)"); |
|
if (ptb->Tflag != -1 && ss.ss_family == AF_INET) { |
|
if (setsockopt(sock, IPPROTO_IP, IP_TOS, |
|
&ptb->Tflag, sizeof(ptb->Tflag))) |
|
err(1, "setsockopt IP_TOS"); |
|
} |
|
if (ptb->Tflag != -1 && ss.ss_family == AF_INET6) { |
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, |
|
&ptb->Tflag, sizeof(ptb->Tflag))) |
|
err(1, "setsockopt IPV6_TCLASS"); |
|
} |
/* Alloc client structure and register reading callback */ |
/* Alloc client structure and register reading callback */ |
if ((sc = calloc(1, sizeof(*sc))) == NULL) |
if ((sc = calloc(1, sizeof(*sc))) == NULL) |
err(1, "calloc"); |
err(1, "calloc"); |
|
|
err(1, "setsockopt SO_RTABLE"); |
err(1, "setsockopt SO_RTABLE"); |
} |
} |
} |
} |
|
if (ptb->Tflag != -1 && ai->ai_family == AF_INET) { |
|
if (setsockopt(sock, IPPROTO_IP, IP_TOS, |
|
&ptb->Tflag, sizeof(ptb->Tflag))) |
|
err(1, "setsockopt IP_TOS"); |
|
} |
|
if (ptb->Tflag != -1 && ai->ai_family == AF_INET6) { |
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, |
|
&ptb->Tflag, sizeof(ptb->Tflag))) |
|
err(1, "setsockopt IPV6_TCLASS"); |
|
} |
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, |
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, |
&on, sizeof(on)) == -1) |
&on, sizeof(on)) == -1) |
warn("reuse port"); |
warn("reuse port"); |
|
|
warn("socket"); |
warn("socket"); |
continue; |
continue; |
} |
} |
|
if (ptb->Tflag != -1 && ai->ai_family == AF_INET) { |
|
if (setsockopt(sock, IPPROTO_IP, IP_TOS, |
|
&ptb->Tflag, sizeof(ptb->Tflag))) |
|
err(1, "setsockopt IP_TOS"); |
|
} |
|
if (ptb->Tflag != -1 && ai->ai_family == AF_INET6) { |
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, |
|
&ptb->Tflag, sizeof(ptb->Tflag))) |
|
err(1, "setsockopt IPV6_TCLASS"); |
|
} |
if (ptb->Vflag) { |
if (ptb->Vflag) { |
if (setsockopt(sock, SOL_SOCKET, SO_RTABLE, |
if (setsockopt(sock, SOL_SOCKET, SO_RTABLE, |
&ptb->Vflag, sizeof(ptb->Vflag)) == -1) { |
&ptb->Vflag, sizeof(ptb->Vflag)) == -1) { |
|
|
fprintf(stderr, "%u connections established\n", nconn); |
fprintf(stderr, "%u connections established\n", nconn); |
} |
} |
|
|
|
static int |
|
map_tos(char *s, int *val) |
|
{ |
|
/* DiffServ Codepoints and other TOS mappings */ |
|
const struct toskeywords { |
|
const char *keyword; |
|
int val; |
|
} *t, toskeywords[] = { |
|
{ "af11", IPTOS_DSCP_AF11 }, |
|
{ "af12", IPTOS_DSCP_AF12 }, |
|
{ "af13", IPTOS_DSCP_AF13 }, |
|
{ "af21", IPTOS_DSCP_AF21 }, |
|
{ "af22", IPTOS_DSCP_AF22 }, |
|
{ "af23", IPTOS_DSCP_AF23 }, |
|
{ "af31", IPTOS_DSCP_AF31 }, |
|
{ "af32", IPTOS_DSCP_AF32 }, |
|
{ "af33", IPTOS_DSCP_AF33 }, |
|
{ "af41", IPTOS_DSCP_AF41 }, |
|
{ "af42", IPTOS_DSCP_AF42 }, |
|
{ "af43", IPTOS_DSCP_AF43 }, |
|
{ "critical", IPTOS_PREC_CRITIC_ECP }, |
|
{ "cs0", IPTOS_DSCP_CS0 }, |
|
{ "cs1", IPTOS_DSCP_CS1 }, |
|
{ "cs2", IPTOS_DSCP_CS2 }, |
|
{ "cs3", IPTOS_DSCP_CS3 }, |
|
{ "cs4", IPTOS_DSCP_CS4 }, |
|
{ "cs5", IPTOS_DSCP_CS5 }, |
|
{ "cs6", IPTOS_DSCP_CS6 }, |
|
{ "cs7", IPTOS_DSCP_CS7 }, |
|
{ "ef", IPTOS_DSCP_EF }, |
|
{ "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, |
|
{ "lowdelay", IPTOS_LOWDELAY }, |
|
{ "netcontrol", IPTOS_PREC_NETCONTROL }, |
|
{ "reliability", IPTOS_RELIABILITY }, |
|
{ "throughput", IPTOS_THROUGHPUT }, |
|
{ NULL, -1 }, |
|
}; |
|
|
|
for (t = toskeywords; t->keyword != NULL; t++) { |
|
if (strcmp(s, t->keyword) == 0) { |
|
*val = t->val; |
|
return (1); |
|
} |
|
} |
|
|
|
return (0); |
|
} |
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
|
|
ptb->kvmh = NULL; |
ptb->kvmh = NULL; |
ptb->kvars = NULL; |
ptb->kvars = NULL; |
ptb->rflag = DEFAULT_STATS_INTERVAL; |
ptb->rflag = DEFAULT_STATS_INTERVAL; |
|
ptb->Tflag = -1; |
nconn = 1; |
nconn = 1; |
|
|
while ((ch = getopt(argc, argv, "B:hlk:n:p:r:sS:uvV:")) != -1) { |
while ((ch = getopt(argc, argv, "B:hlk:n:p:r:sS:T:uvV:")) != -1) { |
switch (ch) { |
switch (ch) { |
case 'l': |
case 'l': |
list_kvars(); |
list_kvars(); |
|
|
break; |
break; |
case 'u': |
case 'u': |
ptb->uflag = 1; |
ptb->uflag = 1; |
|
break; |
|
case 'T': |
|
if (map_tos(optarg, &ptb->Tflag)) |
|
break; |
|
errstr = NULL; |
|
if (strlen(optarg) > 1 && optarg[0] == '0' && |
|
optarg[1] == 'x') |
|
ptb->Tflag = (int)strtol(optarg, NULL, 16); |
|
else |
|
ptb->Tflag = (int)strtonum(optarg, 0, 255, |
|
&errstr); |
|
if (ptb->Tflag == -1 || ptb->Tflag > 255 || errstr) |
|
errx(1, "illegal tos value %s", optarg); |
break; |
break; |
case 'h': |
case 'h': |
default: |
default: |