Add support for specifying client-side epemeral port

-e/--cport now allows a user to specify the client-side port
used for data transfer.

Signed-off-by: Kevin Constantine <kevin.constantine@gmail.com>
This commit is contained in:
Kevin Constantine 2014-09-09 16:31:57 -07:00
parent bd9e3ae5bf
commit b7b1b32afe
6 changed files with 23 additions and 1 deletions

View File

@ -172,6 +172,7 @@ struct iperf_test
signed char state;
char *server_hostname; /* -c option */
char *bind_address; /* -B option */
int *bind_port; /* -e option */
int server_port;
int omit; /* duration of omit period (-O flag) */
int duration; /* total duration of test (-t flag) */

View File

@ -584,6 +584,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"reverse", no_argument, NULL, 'R'},
{"window", required_argument, NULL, 'w'},
{"bind", required_argument, NULL, 'B'},
{"cport", required_argument, NULL, 'e'},
{"set-mss", required_argument, NULL, 'M'},
{"no-delay", no_argument, NULL, 'N'},
{"version4", no_argument, NULL, '4'},
@ -624,7 +625,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
blksize = 0;
server_flag = client_flag = rate_flag = duration_flag = 0;
while ((flag = getopt_long(argc, argv, "p:f:i:DVJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:h", longopts, NULL)) != -1) {
while ((flag = getopt_long(argc, argv, "p:f:i:DVJvsc:ub:t:n:k:l:P:Rw:B:e:M:N46S:L:ZO:F:A:T:C:dI:h", longopts, NULL)) != -1) {
switch (flag) {
case 'p':
test->server_port = atoi(optarg);
@ -745,6 +746,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
case 'B':
test->bind_address = strdup(optarg);
break;
case 'e':
test->bind_port = atoi(optarg);
break;
case 'M':
test->settings->mss = atoi(optarg);
if (test->settings->mss > MAX_MSS) {
@ -876,6 +880,10 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
return -1;
}
if (!test->bind_address && test->bind_port) {
i_errno = IEBIND;
return -1;
}
if (blksize == 0) {
if (test->protocol->id == Pudp)
blksize = DEFAULT_UDP_BLKSIZE;

View File

@ -262,6 +262,7 @@ enum {
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
IELOGFILE = 17, // Can't open log file
IENOSCTP = 18, // No SCTP support available
IEBIND = 19, // Local port specified with no local bind option
/* Test errors */
IENEWTEST = 100, // Unable to create a new test (check perror)
IEINITTEST = 101, // Test initialization failed (check perror)

View File

@ -104,6 +104,9 @@ iperf_strerror(int i_errno)
case IEINTERVAL:
snprintf(errstr, len, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
break;
case IEBIND:
snprintf(errstr, len, "--bind must be specified to use --cport");
break;
case IEMSS:
snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
break;

View File

@ -325,6 +325,11 @@ iperf_tcp_connect(struct iperf_test *test)
}
if (test->bind_address) {
struct sockaddr_in *lcladdr;
lcladdr = (struct sockaddr_in *)local_res->ai_addr;
lcladdr->sin_port = htons(test->bind_port);
local_res->ai_addr = (struct sockaddr *)lcladdr;
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
saved_errno = errno;
close(s);

View File

@ -108,6 +108,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
" -k, --blockcount #[KMG] number of blocks (packets) to transmit (instead of -t or -n)\n"
" -l, --len #[KMG] length of buffer to read or write\n"
" (default %d KB for TCP, %d KB for UDP)\n"
" -e, --cport <host> bind to a specific client port (default: ephemeral port)\n"
" -P, --parallel # number of parallel client streams to run\n"
" -R, --reverse run in reverse mode (server sends, client receives)\n"
" -w, --window #[KMG] TCP window size (socket buffer size)\n"
@ -171,6 +172,9 @@ const char client_port[] =
const char bind_address[] =
"Binding to local address %s\n";
const char bind_port[] =
"Binding to local port %s\n";
const char multicast_ttl[] =
"Setting multicast TTL to %d\n";