diff --git a/src/iperf_api.c b/src/iperf_api.c index dd5655b15..6d6e69716 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -134,6 +134,12 @@ iperf_get_verbose(struct iperf_test *ipt) return ipt->verbose; } +int +iperf_get_debug(struct iperf_test *ipt) +{ + return ipt->debug; +} + int iperf_get_control_socket(struct iperf_test *ipt) { @@ -411,6 +417,12 @@ iperf_get_test_congestion_control(struct iperf_test* ipt) return ipt->congestion; } +uint64_t +iperf_get_test_bytes_sent(struct iperf_test* ipt) +{ + return ipt->bytes_sent; +} + /************** Setter routines for some fields inside iperf_test *************/ void @@ -419,6 +431,12 @@ iperf_set_verbose(struct iperf_test *ipt, int verbose) ipt->verbose = verbose; } +void +iperf_set_debug(struct iperf_test *ipt, int debug) +{ + ipt->debug = debug; +} + void iperf_set_control_socket(struct iperf_test *ipt, int ctrl_sck) { @@ -767,6 +785,30 @@ iperf_set_test_congestion_control(struct iperf_test* ipt, char* cc) ipt->congestion = strdup(cc); } +void +iperf_set_test_file(struct iperf_test* ipt, char* file) +{ + ipt->diskfile_name = strdup(file); +} + +void +iperf_set_test_snd_fileseek(struct iperf_test* ipt, int seek) +{ + ipt->diskfile_seek = seek; +} + +void +iperf_set_test_rcv_fileappend(struct iperf_test* ipt, int append) +{ + ipt->diskfile_append = append; +} + +void +iperf_set_test_rcv_reliable(struct iperf_test* ipt, int reliable) +{ + ipt->reliable_receive_in_full = reliable; +} + /********************** Get/set test protocol structure ***********************/ diff --git a/src/iperf_api.h b/src/iperf_api.h index cb4a86d76..3e7d2f5ec 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -110,6 +110,7 @@ typedef uint64_t iperf_size_t; /* Getter routines for some fields inside iperf_test. */ int iperf_get_verbose( struct iperf_test* ipt ); +int iperf_get_debug( struct iperf_test* ipt ); int iperf_get_control_socket( struct iperf_test* ipt ); int iperf_get_test_omit( struct iperf_test* ipt ); int iperf_get_test_duration( struct iperf_test* ipt ); @@ -147,9 +148,11 @@ int iperf_get_test_no_delay( struct iperf_test* ipt ); int iperf_get_test_connect_timeout( struct iperf_test* ipt ); int iperf_get_dont_fragment( struct iperf_test* ipt ); char* iperf_get_test_congestion_control(struct iperf_test* ipt); +uint64_t iperf_get_test_bytes_sent(struct iperf_test* ipt); /* Setter routines for some fields inside iperf_test. */ void iperf_set_verbose( struct iperf_test* ipt, int verbose ); +void iperf_set_debug( struct iperf_test* ipt, int debug ); void iperf_set_control_socket( struct iperf_test* ipt, int ctrl_sck ); void iperf_set_test_omit( struct iperf_test* ipt, int omit ); void iperf_set_test_duration( struct iperf_test* ipt, int duration ); @@ -186,6 +189,10 @@ void iperf_set_test_bidirectional( struct iperf_test* ipt, int bidirectional) void iperf_set_test_no_delay( struct iperf_test* ipt, int no_delay); void iperf_set_dont_fragment( struct iperf_test* ipt, int dont_fragment ); void iperf_set_test_congestion_control(struct iperf_test* ipt, char* cc); +void iperf_set_test_file(struct iperf_test* ipt, char* file); +void iperf_set_test_snd_fileseek(struct iperf_test* ipt, int seek); +void iperf_set_test_rcv_fileappend(struct iperf_test* ipt, int append); +void iperf_set_test_rcv_reliable(struct iperf_test* ipt, int reliable); #if defined(HAVE_SSL) void iperf_set_test_client_username(struct iperf_test *ipt, const char *client_username); diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c index 3a4c885fb..0698b26b1 100644 --- a/src/iperf_client_api.c +++ b/src/iperf_client_api.c @@ -51,12 +51,14 @@ #endif /* TCP_CA_NAME_MAX */ #endif /* HAVE_TCP_CONGESTION */ + int iperf_create_streams(struct iperf_test *test, int sender) { int i, s; #if defined(HAVE_TCP_CONGESTION) int saved_errno; + static int sender_id = 0; /* use this to set congestion control based on even or odd */ #endif /* HAVE_TCP_CONGESTION */ struct iperf_stream *sp; @@ -72,13 +74,26 @@ iperf_create_streams(struct iperf_test *test, int sender) #if defined(HAVE_TCP_CONGESTION) if (test->protocol->id == Ptcp) { if (test->congestion) { - if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) { - saved_errno = errno; - close(s); - errno = saved_errno; - i_errno = IESETCONGESTION; - return -1; - } + if(sender_id % 2 == 0) { /* CC testing hack: only do this for even numbered senders */ + /* + printf("setting cong cntrl on stream %d to %s \n",sender_id,test->congestion); + */ + if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) { + saved_errno = errno; + close(s); + errno = saved_errno; + i_errno = IESETCONGESTION; + return -1; + } + } else { /* for CC hack: sleep N seconds to give even numbered streams (eg: cubic) a head start */ + int sleep_time = 1; + /* + printf("default cong cntrl on stream %d \n",sender_id); + printf("sleeping for %d seconds to let stream %d have a head start \n",sleep_time, sender_id-1); + */ + sleep(sleep_time); + } + sender_id++; } { socklen_t len = TCP_CA_NAME_MAX; @@ -348,13 +363,6 @@ iperf_connect(struct iperf_test *test) return -1; } - // set TCP_NODELAY for lower latency on control messages - int flag = 1; - if (setsockopt(test->ctrl_sck, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int))) { - i_errno = IESETNODELAY; - return -1; - } - if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { i_errno = IESENDCOOKIE; return -1; diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c index c78f4f5cc..256bd7064 100644 --- a/src/iperf_tcp.c +++ b/src/iperf_tcp.c @@ -375,6 +375,7 @@ iperf_tcp_connect(struct iperf_test *test) socklen_t optlen; int saved_errno; int rcvbuf_actual, sndbuf_actual; + useconds_t sleepTime; if (test->bind_address) { memset(&hints, 0, sizeof(hints)); @@ -397,6 +398,14 @@ iperf_tcp_connect(struct iperf_test *test) return -1; } + /* for CC hack, sleep for a random number of usec between 0 and 500 ms */ + /* + srand(time(0)); + sleepTime = (useconds_t)(((rand() % 5) + 1) * 1000); + printf("DEBUG: sleeping for %d us \n", sleepTime); + usleep(sleepTime); + */ + if ((s = socket(server_res->ai_family, SOCK_STREAM, 0)) < 0) { if (test->bind_address) freeaddrinfo(local_res);