Added support for setting the IP TOS (IPv4) and IPv6 Traffic Class (-S option)

This commit is contained in:
sethdelliott 2010-08-03 21:38:48 +00:00
parent 76ceadbc24
commit 9a599d5f8d
4 changed files with 61 additions and 23 deletions

View File

@ -199,7 +199,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
};
char ch;
while ((ch = getopt_long(argc, argv, "c:p:st:uP:B:b:l:w:i:n:mRNTvh6VdM:f:", longopts, NULL)) != -1) {
while ((ch = getopt_long(argc, argv, "c:p:st:uP:B:b:l:w:i:n:mRS:NTvh6VdM:f:", longopts, NULL)) != -1) {
switch (ch) {
case 'c':
if (test->role == 's') {
@ -346,6 +346,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
}
test->reverse = 1;
break;
case 'S':
if (test->role == 's') {
i_errno = IECLIENTONLY;
return (-1);
}
// XXX: Checking for errors in strtol is not portable. Leave as is?
test->settings->tos = strtol(optarg, NULL, 0);
break;
case 'v':
printf(version);
exit(0);
@ -556,6 +564,11 @@ package_parameters(struct iperf_test *test)
strncat(pstring, optbuf, sizeof(pstring));
}
if (test->settings->tos) {
snprintf(optbuf, sizeof(optbuf), "-S %d ", test->settings->tos);
strncat(pstring, optbuf, sizeof(pstring));
}
*pstring = (char) (strlen(pstring) - 1);
if (Nwrite(test->ctrl_sck, pstring, strlen(pstring), Ptcp) < 0) {
@ -597,7 +610,7 @@ parse_parameters(struct iperf_test *test)
}
// XXX: Should we check for parameters exceeding maximum values here?
while ((ch = getopt(n, params, "pt:n:m:uNP:Rw:l:b:")) != -1) {
while ((ch = getopt(n, params, "pt:n:m:uNP:Rw:l:b:S:")) != -1) {
switch (ch) {
case 'p':
set_protocol(test, Ptcp);
@ -632,6 +645,9 @@ parse_parameters(struct iperf_test *test)
case 'b':
test->settings->rate = atoll(optarg);
break;
case 'S':
test->settings->tos = atoi(optarg);
break;
}
}
#ifdef __APPLE__
@ -697,7 +713,6 @@ iperf_exchange_results(struct iperf_test *test)
/* Prepare results string and send to server */
results = NULL;
size = 0;
// for (sp = test->streams; sp; sp = sp->next) {
SLIST_FOREACH(sp, &test->streams, streams) {
bytes_transferred = (test->reverse ? sp->result->bytes_received : sp->result->bytes_sent);
snprintf(buf, 128, "%d:%llu,%lf,%d,%d\n", sp->id, bytes_transferred,sp->jitter,
@ -771,7 +786,6 @@ iperf_exchange_results(struct iperf_test *test)
/* Prepare results string and send to client */
results = NULL;
size = 0;
// for (sp = test->streams; sp; sp = sp->next) {
SLIST_FOREACH(sp, &test->streams, streams) {
bytes_transferred = (test->reverse ? sp->result->bytes_sent : sp->result->bytes_received);
snprintf(buf, 128, "%d:%llu,%lf,%d,%d\n", sp->id, bytes_transferred, sp->jitter,
@ -1342,9 +1356,10 @@ iperf_new_stream(struct iperf_test *test, int s)
/**************************************************************************/
int
iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp)
iperf_init_stream(struct iperf_stream *sp, struct iperf_test *test)
{
socklen_t len;
int opt;
len = sizeof(struct sockaddr_storage);
if (getsockname(sp->socket, (struct sockaddr *) &sp->local_addr, &len) < 0) {
@ -1356,6 +1371,20 @@ iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp)
i_errno = IEINITSTREAM;
return (-1);
}
/* Set IP TOS */
if ((opt = test->settings->tos)) {
if (test->settings->domain == AF_INET6) {
if (setsockopt(sp->socket, IPPROTO_IPV6, IPV6_TCLASS, &opt, sizeof(opt)) < 0) {
i_errno = IESETCOS;
return (-1);
}
} else {
if (setsockopt(sp->socket, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)) < 0) {
i_errno = IESETTOS;
return (-1);
}
}
}
return (0);
}
@ -1382,7 +1411,6 @@ iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp)
}
}
void
sig_handler(int sig)
{

View File

@ -81,7 +81,7 @@ void iperf_add_stream(struct iperf_test * test, struct iperf_stream * strea
* iperf_init_stream -- init resources associated with test
*
*/
int iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp);
int iperf_init_stream(struct iperf_stream *, struct iperf_test *);
/**
* iperf_free_stream -- free resources associated with test

View File

@ -131,7 +131,7 @@ iperf_strerror(int i_errno)
snprintf(errstr, len, "The server has terminated");
break;
case IEACCESSDENIED:
snprintf(errstr, len, "The server is busy running a test. try again later.");
snprintf(errstr, len, "The server is busy running a test. try again later");
break;
case IESETNODELAY:
snprintf(errstr, len, "Unable to set TCP NODELAY");
@ -145,6 +145,14 @@ iperf_strerror(int i_errno)
snprintf(errstr, len, "Unable to set socket buffer size");
perr = 1;
break;
case IESETTOS:
snprintf(errstr, len, "Unable to set IP TOS");
perr = 1;
break;
case IESETCOS:
snprintf(errstr, len, "Unable to set IPv6 traffic class");
perr = 1;
break;
case IEREUSEADDR:
snprintf(errstr, len, "Unable to reuse address on socket");
perr = 1;

View File

@ -52,25 +52,27 @@ enum {
IESETNODELAY = 32, // Unable to set TCP NODELAY (check perror)
IESETMSS = 33, // Unable to set TCP MSS (check perror)
IESETBUF = 34, // Unable to set socket buffer size (check perror)
IEREUSEADDR = 35, // Unable to set reuse address on socket (check perror)
IENONBLOCKING = 36, // Unable to set socket to non-blocking (check perror)
IESETWINDOWSIZE = 37, // Unable to set socket window size (check perror)
IEPROTOCOL = 38, // Protocol does not exist
IESETTOS = 35, // Unable to set IP TOS (check perror)
IESETCOS = 36, // Unable to set IPv6 traffic class (check perror)
IEREUSEADDR = 37, // Unable to set reuse address on socket (check perror)
IENONBLOCKING = 38, // Unable to set socket to non-blocking (check perror)
IESETWINDOWSIZE = 39, // Unable to set socket window size (check perror)
IEPROTOCOL = 40, // Protocol does not exist
/* Stream errors */
IECREATESTREAM = 39, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 40, // Unable to initialize stream (check herror/perror)
IESTREAMLISTEN = 41, // Unable to start stream listener (check perror)
IESTREAMCONNECT = 42, // Unable to connect stream (check herror/perror)
IESTREAMACCEPT = 43, // Unable to accepte stream connection (check perror)
IESTREAMWRITE = 44, // Unable to write to stream socket (check perror)
IESTREAMREAD = 45, // Unable to read from stream (check perror)
IESTREAMCLOSE = 46, // Stream has closed unexpectedly
IESTREAMID = 47, // Stream has invalid ID
IECREATESTREAM = 41, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 42, // Unable to initialize stream (check herror/perror)
IESTREAMLISTEN = 43, // Unable to start stream listener (check perror)
IESTREAMCONNECT = 44, // Unable to connect stream (check herror/perror)
IESTREAMACCEPT = 45, // Unable to accepte stream connection (check perror)
IESTREAMWRITE = 46, // Unable to write to stream socket (check perror)
IESTREAMREAD = 47, // Unable to read from stream (check perror)
IESTREAMCLOSE = 48, // Stream has closed unexpectedly
IESTREAMID = 49, // Stream has invalid ID
/* Timer errors */
IENEWTIMER = 48, // Unable to create new timer (check perror)
IEUPDATETIMER = 49, // Unable to update timer (check perror)
IENEWTIMER = 50, // Unable to create new timer (check perror)
IEUPDATETIMER = 51, // Unable to update timer (check perror)
};
#endif