From 6162535684716885f3f279a34484af7b61748a1c Mon Sep 17 00:00:00 2001 From: kaustubhprabhu Date: Fri, 19 Jun 2009 22:35:42 +0000 Subject: [PATCH] implemented options -m, -M, -N, -f for command line arguements --- src/iperf_api.c | 109 ++++++++++++++++++++++++++++++++++++++++++------ src/iperf_api.h | 22 ++++++---- 2 files changed, 110 insertions(+), 21 deletions(-) diff --git a/src/iperf_api.c b/src/iperf_api.c index 0ec15bc..af1e28d 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -7,16 +7,14 @@ #include #include #include - #include #include #include #include #include - #include #include - +#include #include #include "iperf_api.h" @@ -41,6 +39,69 @@ static struct option longopts[] = }; +int getsock_tcp_mss( int inSock ) +{ + int theMSS = 0; + + int rc; + socklen_t len; + assert( inSock >= 0 ); + + /* query for MSS */ + len = sizeof( theMSS ); + rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &theMSS, &len ); + + return theMSS; +} + + + +int set_socket_options(struct iperf_stream *sp, struct iperf_test *tp) +{ + + socklen_t len; + + // -N + if(tp->mNodelay == 1) + { + int nodelay = 1; + len = sizeof(nodelay); + int rc = setsockopt( sp->socket, IPPROTO_TCP, TCP_NODELAY, + (char*) &nodelay, len); + if(rc == -1) + { + perror("TCP_NODELAY"); + return -1; + } + } + + + //-M + if(tp->default_settings->MSS > 0) + { + int rc; + int newMSS; + len = sizeof(newMSS); + + assert( sp->socket != -1); + + /* set */ + newMSS = tp->default_settings->MSS; + len = sizeof( newMSS ); + rc = setsockopt( sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, len); + if ( rc == -1) { + perror("setsockopt"); + return -1; + } + + /* verify results */ + rc = getsockopt( sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len); + if ( newMSS != tp->default_settings->MSS ) + perror("mismatch"); + } + +} + void connect_msg(struct iperf_stream *sp) { char ipl[512], ipr[512]; @@ -193,6 +254,8 @@ void iperf_defaults(struct iperf_test *testp) testp->server_port = 5001; testp->state = TEST_START; + testp->mFormat = 'a'; + testp->stats_interval = testp->duration; testp->reporter_interval = testp->duration; testp->num_streams = 1; @@ -314,14 +377,14 @@ char *iperf_reporter_callback(struct iperf_test *test) if(test->role == 'c') { bytes+= sp->result->interval_results->bytes_transferred; - unit_snprintf(ubuf, UNIT_LEN, (double) ( sp->result->interval_results->bytes_transferred / test->stats_interval), 'a'); + unit_snprintf(ubuf, UNIT_LEN, (double) ( sp->result->interval_results->bytes_transferred / test->stats_interval), test->mFormat); printf("[%d]\t %llu bytes sent \t %s per sec \n",sp->socket, sp->result->interval_results->bytes_transferred , ubuf); } else if(test->role == 's') { bytes+= sp->result->interval_results->bytes_transferred; - unit_snprintf(ubuf, UNIT_LEN, (double) ( sp->result->interval_results->bytes_transferred / test->stats_interval), 'a'); + unit_snprintf(ubuf, UNIT_LEN, (double) ( sp->result->interval_results->bytes_transferred / test->stats_interval), test->mFormat); printf("[%d]\t %llu bytes received \t %s per sec \n",sp->socket, sp->result->interval_results->bytes_transferred , ubuf); } @@ -329,7 +392,7 @@ char *iperf_reporter_callback(struct iperf_test *test) } printf("---------------------------------------------------\n"); - unit_snprintf(ubuf, UNIT_LEN, (double) ( bytes / test->stats_interval), 'a'); + unit_snprintf(ubuf, UNIT_LEN, (double) ( bytes / test->stats_interval), test->mFormat); printf("SUM\t %llu bytes COUNT \t %s per sec \n", bytes , ubuf); printf("---------------------------------------------------\n"); @@ -352,15 +415,16 @@ char *iperf_reporter_callback(struct iperf_test *test) gettimeofday( &sp->result->end_time, NULL); - unit_snprintf(ubuf, UNIT_LEN, (double) (sp->result->bytes_sent /(sp->result->end_time.tv_sec - sp->result->start_time.tv_sec)), 'a'); + unit_snprintf(ubuf, UNIT_LEN, (double) (sp->result->bytes_sent /(sp->result->end_time.tv_sec - sp->result->start_time.tv_sec)), test->mFormat); printf("[%d]\t %llu bytes sent %s per sec \n",sp->socket, sp->result->bytes_sent , ubuf); + } else if(test->role == 's') { bytes+= sp->result->bytes_received; gettimeofday( &sp->result->end_time, NULL); - unit_snprintf(ubuf, UNIT_LEN, (double) sp->result->bytes_received /(sp->result->end_time.tv_sec - sp->result->start_time.tv_sec), 'a'); + unit_snprintf(ubuf, UNIT_LEN, (double) sp->result->bytes_received /(sp->result->end_time.tv_sec - sp->result->start_time.tv_sec), test->mFormat); printf("[%d]\t %llu bytes received %s per sec \n",sp->socket, sp->result->bytes_received, ubuf); // IF SERVER IS DEAMON, ONLY THIS IS NEEDED sprintf(messege,"[%d]\t %llu bytes received %s per sec\n", sp->socket, sp->result->bytes_received, ubuf); @@ -373,7 +437,7 @@ char *iperf_reporter_callback(struct iperf_test *test) sp = test->streams; printf("---------------------------------------------------\n"); - unit_snprintf(ubuf, UNIT_LEN, (double) bytes /(sp->result->end_time.tv_sec - sp->result->start_time.tv_sec), 'a'); + unit_snprintf(ubuf, UNIT_LEN, (double) bytes /(sp->result->end_time.tv_sec - sp->result->start_time.tv_sec), test->mFormat); printf("SUM\t %llu bytes TOTAL %s per sec \n", bytes , ubuf); printf("---------------------------------------------------\n\n"); @@ -384,6 +448,12 @@ char *iperf_reporter_callback(struct iperf_test *test) strcat(messege_final, messege); sprintf(messege, "---------------------------------------------------\n\n"); strcat(messege_final, messege); + + // -m option + if((test->mPrintMSS != 0) && (test->role == 'c')) + { + printf(" the TCP maximum segment size MSS = %d \n", getsock_tcp_mss(sp->socket)); + } } @@ -593,6 +663,8 @@ void iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp) } + //set socket options + if(set_tcp_windowsize(sp->socket, testp->default_settings->socket_bufsize, testp->role == 's' ? SO_RCVBUF : SO_SNDBUF) < 0) fprintf(stderr, "unable to set window size\n"); @@ -601,14 +673,14 @@ void iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp) x = getsock_tcp_windowsize(sp->socket, SO_RCVBUF); if(x < 0) perror("SO_RCVBUF"); - - // printf("RCV: %d\n", x); + // printf("RCV: %d\n", x); x = getsock_tcp_windowsize(sp->socket, SO_SNDBUF); if(x < 0) perror("SO_SNDBUF"); + // printf("SND: %d\n", x); - // printf("SND: %d\n", x); + set_socket_options(sp, testp); } @@ -883,7 +955,7 @@ main(int argc, char **argv) test= iperf_new_test(); iperf_defaults(test); - while( (ch = getopt_long(argc, argv, "c:p:st:uP:b:l:w:i:", longopts, NULL)) != -1 ) + while( (ch = getopt_long(argc, argv, "c:p:st:uP:b:l:w:i:mNM:f:", longopts, NULL)) != -1 ) switch (ch) { case 'c': test->role = 'c'; @@ -918,6 +990,17 @@ main(int argc, char **argv) test->stats_interval = atoi(optarg); test->reporter_interval = atoi(optarg); break; + case 'm': + test->mPrintMSS = 1; + break; + case 'N': + test->mNodelay = 1; + break; + case 'M': + test->default_settings->MSS = atoi(optarg); + case 'f': + test->mFormat = *optarg; + break; } printf("ROLE = %s\n", (test->role == 's') ? "Server" : "Client"); diff --git a/src/iperf_api.h b/src/iperf_api.h index 5769f7c..4f262e0 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -26,7 +26,7 @@ struct iperf_settings int blksize; // -l size of each read/write, in UDP this relates directly to packet_size int rate; // target data rate, UDP only - + int MSS; //for TCP MSS int ttl; int tos; }; @@ -63,15 +63,19 @@ struct iperf_test char *server_hostname; // arg of -c int server_port; // arg of -p - - int duration; // total duration of test -t - - int listener_sock; - + int duration; // total duration of test -t + int listener_sock; int state; - /* Select related parameters */ - int max_fd; + /*boolen variables for Options */ + int mDaemon; // -D + int mNodelay; // -N + int mPrintMSS; // -m + int mDomain; // -V + char mFormat; // -f + + /* Select related parameters */ + int max_fd; fd_set read_set; fd_set temp_set; fd_set write_set; @@ -93,6 +97,8 @@ struct iperf_test }; +int getsock_tcp_mss( int inSock ); +int set_socket_options(struct iperf_stream *sp, struct iperf_test *test); void connect_msg(struct iperf_stream *sp); void Display(struct iperf_test *test); int iperf_tcp_accept(struct iperf_test *test);