aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce A. Mah <bmah@es.net>2014-09-15 12:58:01 -0700
committerBruce A. Mah <bmah@es.net>2014-09-15 12:58:01 -0700
commit785c8a42c91d01f88aa6ebbdd3838dd5218afe6a (patch)
tree3dd17be9f289178ac2d06a06ae217af195c2bbe0 /src
parentfbd89512afc26f6e0d9cd72bc5cbeb05f292432d (diff)
parent023fb45e7a945ccc905b4c7afc20ba2b68cf197b (diff)
downloadiperf3-785c8a42c91d01f88aa6ebbdd3838dd5218afe6a.tar.gz
Merge branch 'master' of github.com:kevinconstantine/iperf into kevinconstantine-master
Diffstat (limited to 'src')
-rw-r--r--src/iperf.h1
-rw-r--r--src/iperf_api.c8
-rw-r--r--src/iperf_api.h2
-rw-r--r--src/iperf_client_api.c3
-rw-r--r--src/iperf_error.c3
-rw-r--r--src/iperf_locale.c4
-rw-r--r--src/iperf_tcp.c5
-rw-r--r--src/iperf_udp.c2
-rw-r--r--src/net.c9
-rw-r--r--src/net.h2
10 files changed, 35 insertions, 4 deletions
diff --git a/src/iperf.h b/src/iperf.h
index 07ce9a2..dec9c7a 100644
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -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) */
diff --git a/src/iperf_api.c b/src/iperf_api.c
index dc46a53..1ecc2f3 100644
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -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, OPT_CLIENT_PORT},
{"set-mss", required_argument, NULL, 'M'},
{"no-delay", no_argument, NULL, 'N'},
{"version4", no_argument, NULL, '4'},
@@ -745,6 +746,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
case 'B':
test->bind_address = strdup(optarg);
break;
+ case OPT_CLIENT_PORT:
+ 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;
diff --git a/src/iperf_api.h b/src/iperf_api.h
index ecac575..a31a16b 100644
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -30,6 +30,7 @@ struct iperf_stream;
#define OPT_LOGFILE 2
#define OPT_GET_SERVER_OUTPUT 3
#define OPT_UDP_COUNTERS_64BIT 4
+#define OPT_CLIENT_PORT 5
/* states */
#define TEST_START 1
@@ -262,6 +263,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)
diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c
index 6780469..ab84cfa 100644
--- a/src/iperf_client_api.c
+++ b/src/iperf_client_api.c
@@ -268,7 +268,8 @@ iperf_connect(struct iperf_test *test)
/* Create and connect the control channel */
if (test->ctrl_sck < 0)
- test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, test->server_hostname, test->server_port);
+ // Create the control channel using an ephemeral port
+ test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, NULL, test->server_hostname, test->server_port);
if (test->ctrl_sck < 0) {
i_errno = IECONNECT;
return -1;
diff --git a/src/iperf_error.c b/src/iperf_error.c
index ef1d1ef..6dd1dc1 100644
--- a/src/iperf_error.c
+++ b/src/iperf_error.c
@@ -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;
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
index 9e4c647..ab32772 100644
--- a/src/iperf_locale.c
+++ b/src/iperf_locale.c
@@ -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"
+ " --cport <port> 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";
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
index cdf4cd2..0324e44 100644
--- a/src/iperf_tcp.c
+++ b/src/iperf_tcp.c
@@ -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);
diff --git a/src/iperf_udp.c b/src/iperf_udp.c
index 38d0cc7..8633436 100644
--- a/src/iperf_udp.c
+++ b/src/iperf_udp.c
@@ -234,7 +234,7 @@ iperf_udp_connect(struct iperf_test *test)
{
int s, buf, sz;
- if ((s = netdial(test->settings->domain, Pudp, test->bind_address, test->server_hostname, test->server_port)) < 0) {
+ if ((s = netdial(test->settings->domain, Pudp, test->bind_address, test->bind_port, test->server_hostname, test->server_port)) < 0) {
i_errno = IESTREAMCONNECT;
return -1;
}
diff --git a/src/net.c b/src/net.c
index 72947d3..1fb4094 100644
--- a/src/net.c
+++ b/src/net.c
@@ -48,7 +48,7 @@
/* make connection to server */
int
-netdial(int domain, int proto, char *local, char *server, int port)
+netdial(int domain, int proto, char *local, int local_port, char *server, int port)
{
struct addrinfo hints, *local_res, *server_res;
int s;
@@ -76,6 +76,13 @@ netdial(int domain, int proto, char *local, char *server, int port)
}
if (local) {
+ if (local_port) {
+ struct sockaddr_in *lcladdr;
+ lcladdr = (struct sockaddr_in *)local_res->ai_addr;
+ lcladdr->sin_port = htons(local_port);
+ local_res->ai_addr = (struct sockaddr *)lcladdr;
+ }
+
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
close(s);
freeaddrinfo(local_res);
diff --git a/src/net.h b/src/net.h
index 1d6f390..5ab10ec 100644
--- a/src/net.h
+++ b/src/net.h
@@ -10,7 +10,7 @@
#ifndef __NET_H
#define __NET_H
-int netdial(int domain, int proto, char *local, char *server, int port);
+int netdial(int domain, int proto, char *local, int local_port, char *server, int port);
int netannounce(int domain, int proto, char *local, int port);
int Nread(int fd, char *buf, size_t count, int prot);
int Nwrite(int fd, const char *buf, size_t count, int prot) /* __attribute__((hot)) */;