Merge branch 'kevinconstantine-master'
Этот коммит содержится в:
Коммит
5fef310cdf
@ -172,6 +172,7 @@ struct iperf_test
|
|||||||
signed char state;
|
signed char state;
|
||||||
char *server_hostname; /* -c option */
|
char *server_hostname; /* -c option */
|
||||||
char *bind_address; /* -B option */
|
char *bind_address; /* -B option */
|
||||||
|
int *bind_port; /* -e option */
|
||||||
int server_port;
|
int server_port;
|
||||||
int omit; /* duration of omit period (-O flag) */
|
int omit; /* duration of omit period (-O flag) */
|
||||||
int duration; /* total duration of test (-t flag) */
|
int duration; /* total duration of test (-t flag) */
|
||||||
|
@ -113,6 +113,10 @@ number of blocks (packets) to transmit (instead of -t or -n)
|
|||||||
.BR -l ", " --length " \fIn\fR[KM]"
|
.BR -l ", " --length " \fIn\fR[KM]"
|
||||||
length of buffer to read or write (default 128 KB for TCP, 8KB for UDP)
|
length of buffer to read or write (default 128 KB for TCP, 8KB for UDP)
|
||||||
.TP
|
.TP
|
||||||
|
.BR --cport " \fIport\fR"
|
||||||
|
bind data streams to a specific client port (for TCP and UDP only,
|
||||||
|
default is to use an ephemeral port)
|
||||||
|
.TP
|
||||||
.BR -P ", " --parallel " \fIn\fR"
|
.BR -P ", " --parallel " \fIn\fR"
|
||||||
number of parallel client streams to run
|
number of parallel client streams to run
|
||||||
.TP
|
.TP
|
||||||
|
@ -584,6 +584,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
|||||||
{"reverse", no_argument, NULL, 'R'},
|
{"reverse", no_argument, NULL, 'R'},
|
||||||
{"window", required_argument, NULL, 'w'},
|
{"window", required_argument, NULL, 'w'},
|
||||||
{"bind", required_argument, NULL, 'B'},
|
{"bind", required_argument, NULL, 'B'},
|
||||||
|
{"cport", required_argument, NULL, OPT_CLIENT_PORT},
|
||||||
{"set-mss", required_argument, NULL, 'M'},
|
{"set-mss", required_argument, NULL, 'M'},
|
||||||
{"no-delay", no_argument, NULL, 'N'},
|
{"no-delay", no_argument, NULL, 'N'},
|
||||||
{"version4", no_argument, NULL, '4'},
|
{"version4", no_argument, NULL, '4'},
|
||||||
@ -745,6 +746,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
|||||||
case 'B':
|
case 'B':
|
||||||
test->bind_address = strdup(optarg);
|
test->bind_address = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case OPT_CLIENT_PORT:
|
||||||
|
test->bind_port = atoi(optarg);
|
||||||
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
test->settings->mss = atoi(optarg);
|
test->settings->mss = atoi(optarg);
|
||||||
if (test->settings->mss > MAX_MSS) {
|
if (test->settings->mss > MAX_MSS) {
|
||||||
@ -876,6 +880,10 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!test->bind_address && test->bind_port) {
|
||||||
|
i_errno = IEBIND;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (blksize == 0) {
|
if (blksize == 0) {
|
||||||
if (test->protocol->id == Pudp)
|
if (test->protocol->id == Pudp)
|
||||||
blksize = DEFAULT_UDP_BLKSIZE;
|
blksize = DEFAULT_UDP_BLKSIZE;
|
||||||
|
@ -30,6 +30,7 @@ struct iperf_stream;
|
|||||||
#define OPT_LOGFILE 2
|
#define OPT_LOGFILE 2
|
||||||
#define OPT_GET_SERVER_OUTPUT 3
|
#define OPT_GET_SERVER_OUTPUT 3
|
||||||
#define OPT_UDP_COUNTERS_64BIT 4
|
#define OPT_UDP_COUNTERS_64BIT 4
|
||||||
|
#define OPT_CLIENT_PORT 5
|
||||||
|
|
||||||
/* states */
|
/* states */
|
||||||
#define TEST_START 1
|
#define TEST_START 1
|
||||||
@ -262,6 +263,7 @@ enum {
|
|||||||
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
|
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
|
||||||
IELOGFILE = 17, // Can't open log file
|
IELOGFILE = 17, // Can't open log file
|
||||||
IENOSCTP = 18, // No SCTP support available
|
IENOSCTP = 18, // No SCTP support available
|
||||||
|
IEBIND = 19, // Local port specified with no local bind option
|
||||||
/* Test errors */
|
/* Test errors */
|
||||||
IENEWTEST = 100, // Unable to create a new test (check perror)
|
IENEWTEST = 100, // Unable to create a new test (check perror)
|
||||||
IEINITTEST = 101, // Test initialization failed (check perror)
|
IEINITTEST = 101, // Test initialization failed (check perror)
|
||||||
|
@ -268,7 +268,8 @@ iperf_connect(struct iperf_test *test)
|
|||||||
|
|
||||||
/* Create and connect the control channel */
|
/* Create and connect the control channel */
|
||||||
if (test->ctrl_sck < 0)
|
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) {
|
if (test->ctrl_sck < 0) {
|
||||||
i_errno = IECONNECT;
|
i_errno = IECONNECT;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -104,6 +104,9 @@ iperf_strerror(int i_errno)
|
|||||||
case IEINTERVAL:
|
case IEINTERVAL:
|
||||||
snprintf(errstr, len, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
|
snprintf(errstr, len, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
|
||||||
break;
|
break;
|
||||||
|
case IEBIND:
|
||||||
|
snprintf(errstr, len, "--bind must be specified to use --cport");
|
||||||
|
break;
|
||||||
case IEMSS:
|
case IEMSS:
|
||||||
snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
|
snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
|
||||||
break;
|
break;
|
||||||
|
@ -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"
|
" -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"
|
" -l, --len #[KMG] length of buffer to read or write\n"
|
||||||
" (default %d KB for TCP, %d KB for UDP)\n"
|
" (default %d KB for TCP, %d KB for UDP)\n"
|
||||||
|
" --cport <port> bind to a specific client port (TCP and UDP, default: ephemeral port)\n"
|
||||||
" -P, --parallel # number of parallel client streams to run\n"
|
" -P, --parallel # number of parallel client streams to run\n"
|
||||||
" -R, --reverse run in reverse mode (server sends, client receives)\n"
|
" -R, --reverse run in reverse mode (server sends, client receives)\n"
|
||||||
" -w, --window #[KMG] TCP window size (socket buffer size)\n"
|
" -w, --window #[KMG] TCP window size (socket buffer size)\n"
|
||||||
@ -171,6 +172,9 @@ const char client_port[] =
|
|||||||
const char bind_address[] =
|
const char bind_address[] =
|
||||||
"Binding to local address %s\n";
|
"Binding to local address %s\n";
|
||||||
|
|
||||||
|
const char bind_port[] =
|
||||||
|
"Binding to local port %s\n";
|
||||||
|
|
||||||
const char multicast_ttl[] =
|
const char multicast_ttl[] =
|
||||||
"Setting multicast TTL to %d\n";
|
"Setting multicast TTL to %d\n";
|
||||||
|
|
||||||
|
@ -325,6 +325,11 @@ iperf_tcp_connect(struct iperf_test *test)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (test->bind_address) {
|
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) {
|
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
close(s);
|
close(s);
|
||||||
|
@ -234,7 +234,7 @@ iperf_udp_connect(struct iperf_test *test)
|
|||||||
{
|
{
|
||||||
int s, buf, sz;
|
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;
|
i_errno = IESTREAMCONNECT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
/* make connection to server */
|
/* make connection to server */
|
||||||
int
|
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;
|
struct addrinfo hints, *local_res, *server_res;
|
||||||
int s;
|
int s;
|
||||||
@ -76,6 +76,13 @@ netdial(int domain, int proto, char *local, char *server, int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (local) {
|
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) {
|
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
|
||||||
close(s);
|
close(s);
|
||||||
freeaddrinfo(local_res);
|
freeaddrinfo(local_res);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef __NET_H
|
#ifndef __NET_H
|
||||||
#define __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 netannounce(int domain, int proto, char *local, int port);
|
||||||
int Nread(int fd, char *buf, size_t count, int prot);
|
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)) */;
|
int Nwrite(int fd, const char *buf, size_t count, int prot) /* __attribute__((hot)) */;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user