diff --git a/src/iperf_api.c b/src/iperf_api.c index cd81eed..3385557 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -37,34 +37,37 @@ #include "locale.h" int -all_data_sent(struct iperf_test *test) +all_data_sent(struct iperf_test * test) { if (test->default_settings->bytes == 0) return 0; - else { - int total_bytes = 0; + else + { + int total_bytes = 0; struct iperf_stream *sp; sp = test->streams; - while (sp) { + while (sp) + { total_bytes += sp->result->bytes_sent; sp = sp->next; } - if (total_bytes >= (test->num_streams * test->default_settings->bytes)) { + if (total_bytes >= (test->num_streams * test->default_settings->bytes)) + { return 1; - } - else + } else return 0; } } +/*********************************************************/ void -exchange_parameters(struct iperf_test *test) +exchange_parameters(struct iperf_test * test) { - int result, size = DEFAULT_TCP_BLKSIZE; + int result; struct iperf_test *temp; struct iperf_stream *sp; struct param_exchange *param; @@ -75,10 +78,11 @@ exchange_parameters(struct iperf_test *test) temp->server_hostname = test->server_hostname; temp->server_port = test->server_port; - iperf_init_test(temp); + printf("in exchange_parameters: calling iperf_init_test \n"); + iperf_init_test(temp); /* XXX: This is way overkill for just exchaning parameters. Does way more than needed */ sp = temp->streams; sp->settings->state = PARAM_EXCHANGE; - param = (struct param_exchange *)sp->buffer; + param = (struct param_exchange *) sp->buffer; get_uuid(test->default_settings->cookie); strncpy(param->cookie, test->default_settings->cookie, 37); @@ -86,22 +90,26 @@ exchange_parameters(struct iperf_test *test) /* setting up exchange parameters */ param->state = PARAM_EXCHANGE; param->blksize = test->default_settings->blksize; - /* need to decide setting of window size */ - param->recv_window = test->default_settings->socket_rcv_bufsize; - param->send_window = test->default_settings->socket_snd_bufsize; + param->recv_window = test->default_settings->socket_bufsize; + param->send_window = test->default_settings->socket_bufsize; param->format = test->default_settings->unit_format; - result = send(sp->socket, sp->buffer, size, 0); + printf(" sending exchange params: size = %d \n", (int) sizeof(struct param_exchange)); + result = send(sp->socket, sp->buffer, sizeof(struct param_exchange), 0); + /* XXX: no error checking! -blt */ - //printf("result = %d state = %d, %d = error\n", result, sp->buffer[0], errno); + printf("result = %d state = %d, error = %d \n", result, sp->buffer[0], errno); - do { - result = recv(sp->socket, sp->buffer, size, 0); + /* get answer back from server */ + do + { + printf("reading result from server .. \n"); + result = recv(sp->socket, sp->buffer, sizeof(struct param_exchange), 0); } while (result == -1 && errno == EINTR); - if (result > 0 && sp->buffer[0] == ACCESS_DENIED) { - printf("Busy server Detected\n"); - + if (result > 0 && sp->buffer[0] == ACCESS_DENIED) + { + fprintf(stderr, "Busy server Detected. Exiting.\n"); close(sp->socket); iperf_free_stream(temp, sp); iperf_free_test(temp); @@ -112,31 +120,37 @@ exchange_parameters(struct iperf_test *test) iperf_free_test(temp); } +/*********************************************************************/ int -param_received(struct iperf_stream *sp, struct param_exchange *param) +param_received(struct iperf_stream * sp, struct param_exchange * param) { - int result; + int result; - if (sp->settings->cookie[0] == '\0') { + /* XXX: only sends back a message on failure ?? -blt */ + + printf("in param_received \n"); + if (sp->settings->cookie[0] == '\0') + { strncpy(sp->settings->cookie, param->cookie, 37); sp->settings->blksize = param->blksize; - sp->settings->socket_rcv_bufsize = param->recv_window; - - if (param->recv_window != 0) - sp->settings->socket_bufsize = param->recv_window; + sp->settings->socket_bufsize = param->recv_window; sp->settings->unit_format = param->format; return param->state; - } - else if (strncmp(param->cookie, sp->settings->cookie, 37) != 0) { - printf("New connection denied\n"); + } else if (strncmp(param->cookie, sp->settings->cookie, 37) != 0) + { + fprintf(stderr, "New connection denied\n"); /* send NO to client */ - int size = DEFAULT_TCP_BLKSIZE; - char *buf = (char *)malloc(size); + char *buf = (char *) malloc(sizeof(struct param_exchange)); buf[0] = -1; - result = send(sp->socket, buf, size, 0); + /* + * XXX: only first byte matters, I think, so why not just alloc and + * send 1 byte? + */ + result = send(sp->socket, buf, sizeof(struct param_exchange), 0); + /* XXX: no error checking! -blt */ free(buf); return ACCESS_DENIED; } @@ -146,10 +160,11 @@ param_received(struct iperf_stream *sp, struct param_exchange *param) void setnonblocking(int sock) { - int opts; + int opts; opts = (opts | O_NONBLOCK); - if (fcntl(sock, F_SETFL, opts) < 0) { + if (fcntl(sock, F_SETFL, opts) < 0) + { perror("fcntl(F_SETFL)"); exit(EXIT_FAILURE); } @@ -157,11 +172,11 @@ setnonblocking(int sock) } void -add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results temp) +add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results temp) { struct iperf_interval_results *n; - struct iperf_interval_results *ip = (struct iperf_interval_results *)malloc(sizeof(struct iperf_interval_results)); + struct iperf_interval_results *ip = (struct iperf_interval_results *) malloc(sizeof(struct iperf_interval_results)); ip->bytes_transferred = temp.bytes_transferred; ip->interval_duration = temp.interval_duration; @@ -169,10 +184,11 @@ add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results ip->tcpInfo = temp.tcpInfo; #endif - if (!rp->interval_results) { + if (!rp->interval_results) + { rp->interval_results = ip; - } - else { + } else + { n = rp->interval_results; while (n->next) n = n->next; @@ -183,13 +199,14 @@ add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results } void -display_interval_list(struct iperf_stream_result *rp) +display_interval_list(struct iperf_stream_result * rp) { struct iperf_interval_results *n; n = rp->interval_results; - while (n) { + while (n) + { printf("Interval = %f\tBytes transferred = %llu\n", n->interval_duration, n->bytes_transferred); #if defined(linux) /* @@ -209,20 +226,21 @@ display_interval_list(struct iperf_stream_result *rp) } void -send_result_to_client(struct iperf_stream *sp) +send_result_to_client(struct iperf_stream * sp) { - int result; - int size = sp->settings->blksize; + int result; + int size = sp->settings->blksize; - char *buf = (char *)malloc(size); + char *buf = (char *) malloc(size); - if (!buf) { + if (!buf) + { perror("malloc: unable to allocate transmit buffer"); } /* adding the string terminator to the message */ - buf[strlen((char *)sp->data)] = '\0'; + buf[strlen((char *) sp->data)] = '\0'; - memcpy(buf, sp->data, strlen((char *)sp->data)); + memcpy(buf, sp->data, strlen((char *) sp->data)); result = send(sp->socket, buf, size, 0); printf("RESULT SENT TO CLIENT\n"); @@ -231,13 +249,13 @@ send_result_to_client(struct iperf_stream *sp) } void -receive_result_from_server(struct iperf_test *test) +receive_result_from_server(struct iperf_test * test) { - int result; + int result; struct iperf_test *temp; struct iperf_stream *sp; - int size = 0; - char *buf = NULL; + int size = 0; + char *buf = NULL; temp = iperf_new_test(); iperf_defaults(temp); @@ -248,7 +266,8 @@ receive_result_from_server(struct iperf_test *test) temp->server_port = test->server_port; strncpy(temp->default_settings->cookie, test->default_settings->cookie, 37); - iperf_init_test(temp); + printf("in receive_result_from_server: calling iperf_init_test \n"); + iperf_init_test(temp); /* XXX: should this be here??? -blt */ sp = temp->streams; sp->settings->state = ALL_STREAMS_END; @@ -259,9 +278,10 @@ receive_result_from_server(struct iperf_test *test) /* receive from server */ size = sp->settings->blksize; - buf = (char *)malloc(size); + buf = (char *) malloc(size); - do { + do + { result = recv(sp->socket, buf, size, 0); } while (result == -1 && errno == EINTR); @@ -275,42 +295,45 @@ receive_result_from_server(struct iperf_test *test) int getsock_tcp_mss(int inSock) { - int mss = 0; + int mss = 0; - int rc; - socklen_t len; + int rc; + socklen_t len; assert(inSock >= 0); /* query for mss */ len = sizeof(mss); - rc = getsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char *)&mss, &len); + rc = getsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char *) &mss, &len); return mss; } int -set_socket_options(struct iperf_stream *sp, struct iperf_test *tp) +set_socket_options(struct iperf_stream * sp, struct iperf_test * tp) { - socklen_t len; + socklen_t len; - if (tp->no_delay == 1) { - int no_delay = 1; + if (tp->no_delay == 1) + { + int no_delay = 1; len = sizeof(no_delay); - int rc = setsockopt(sp->socket, IPPROTO_TCP, TCP_NODELAY, - (char *)&no_delay, len); + int rc = setsockopt(sp->socket, IPPROTO_TCP, TCP_NODELAY, + (char *) &no_delay, len); - if (rc == -1) { + if (rc == -1) + { perror("TCP_NODELAY"); return -1; } } #ifdef TCP_MAXSEG - if (tp->default_settings->mss > 0) { - int rc; - int new_mss; + if (tp->default_settings->mss > 0) + { + int rc; + int new_mss; len = sizeof(new_mss); @@ -319,14 +342,16 @@ set_socket_options(struct iperf_stream *sp, struct iperf_test *tp) /* set */ new_mss = tp->default_settings->mss; len = sizeof(new_mss); - rc = setsockopt(sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char *)&new_mss, len); - if (rc == -1) { + rc = setsockopt(sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, len); + if (rc == -1) + { perror("setsockopt"); return -1; } /* verify results */ - rc = getsockopt(sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char *)&new_mss, &len); - if (new_mss != tp->default_settings->mss) { + rc = getsockopt(sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, &len); + if (new_mss != tp->default_settings->mss) + { perror("setsockopt value mismatch"); return -1; } @@ -336,37 +361,40 @@ set_socket_options(struct iperf_stream *sp, struct iperf_test *tp) } void -connect_msg(struct iperf_stream *sp) +connect_msg(struct iperf_stream * sp) { - char ipl [512], ipr[512]; + char ipl[512], ipr[512]; - inet_ntop(AF_INET, (void *)(&((struct sockaddr_in *)&sp->local_addr)->sin_addr), (void *)ipl, sizeof(ipl)); - inet_ntop(AF_INET, (void *)(&((struct sockaddr_in *)&sp->remote_addr)->sin_addr), (void *)ipr, sizeof(ipr)); + inet_ntop(AF_INET, (void *) (&((struct sockaddr_in *) & sp->local_addr)->sin_addr), (void *) ipl, sizeof(ipl)); + inet_ntop(AF_INET, (void *) (&((struct sockaddr_in *) & sp->remote_addr)->sin_addr), (void *) ipr, sizeof(ipr)); printf("[%3d] local %s port %d connected with %s port %d\n", sp->socket, - ipl, ntohs(((struct sockaddr_in *)&sp->local_addr)->sin_port), - ipr, ntohs(((struct sockaddr_in *)&sp->remote_addr)->sin_port)); + ipl, ntohs(((struct sockaddr_in *) & sp->local_addr)->sin_port), + ipr, ntohs(((struct sockaddr_in *) & sp->remote_addr)->sin_port)); } void -Display(struct iperf_test *test) +Display(struct iperf_test * test) { struct iperf_stream *n; n = test->streams; - int count = 1; + int count = 1; printf("===============DISPLAY==================\n"); - while (1) { - if (n) { + while (1) + { + if (n) + { if (test->role == 'c') - printf("position-%d\tsp=%d\tsocket=%d\tbytes sent=%llu\n", count++, (int)n, n->socket, n->result->bytes_sent); + printf("position-%d\tsp=%d\tsocket=%d\tbytes sent=%llu\n", count++, (int) n, n->socket, n->result->bytes_sent); else - printf("position-%d\tsp=%d\tsocket=%d\tbytes received=%llu\n", count++, (int)n, n->socket, n->result->bytes_received); + printf("position-%d\tsp=%d\tsocket=%d\tbytes received=%llu\n", count++, (int) n, n->socket, n->result->bytes_received); - if (n->next == NULL) { + if (n->next == NULL) + { printf("=================END====================\n"); fflush(stdout); break; @@ -376,41 +404,45 @@ Display(struct iperf_test *test) } } +/**************************************************************************/ int -iperf_tcp_recv(struct iperf_stream *sp) +iperf_tcp_recv(struct iperf_stream * sp) { - int result, message; - char ch; - int size = sp->settings->blksize; + int result, message; + char ch; + int size = sp->settings->blksize; errno = 0; - struct param_exchange *param = (struct param_exchange *)sp->buffer; + struct param_exchange *param = (struct param_exchange *) sp->buffer; - if (!sp->buffer) { + if (!sp->buffer) + { fprintf(stderr, "receive buffer not allocated \n"); exit(0); } - - do { + do + { result = recv(sp->socket, sp->buffer, size, MSG_WAITALL); } while (result == -1 && errno == EINTR); /* interprete the type of message in packet */ /* TODO = change this for Cookie implementation */ - if (result > 0) { + if (result > 0) + { ch = sp->buffer[0]; - message = (int)ch; + message = (int) ch; /* CHECK: packet length and state */ //printf("result = %d state = %d, %d = error\n", result, message, errno); - } - else { + } else + { //printf("result = %d state = %d, %d = error\n", result, message, errno); //printf("%d socket has been closed by client, result = 0\n", sp->socket); return 0; } - if (message != 7) { + if (message != STREAM_RUNNING) + { //printf("result = %d state = %d, %d = error\n", result, sp->buffer[0], errno); message = param_received(sp, param); } @@ -420,38 +452,45 @@ iperf_tcp_recv(struct iperf_stream *sp) return message; } +/**************************************************************************/ int -iperf_udp_recv(struct iperf_stream *sp) +iperf_udp_recv(struct iperf_stream * sp) { - int result, message; - int size = sp->settings->blksize; - double transit = 0, d = 0; - struct udp_datagram *udp = (struct udp_datagram *)sp->buffer; - struct timeval arrival_time; + int result, message; + int size = sp->settings->blksize; + double transit = 0, d = 0; + struct udp_datagram *udp = (struct udp_datagram *) sp->buffer; + struct timeval arrival_time; - if (!sp->buffer) { + if (!sp->buffer) + { fprintf(stderr, "receive buffer not allocated \n"); exit(0); } - do { + do + { result = recv(sp->socket, sp->buffer, size, 0); } while (result == -1 && errno == EINTR); /* interprete the type of message in packet */ - if (result > 0) { + if (result > 0) + { message = udp->state; } - if (message != 7) { + if (message != 7) + { //printf("result = %d state = %d, %d = error\n", result, sp->buffer[0], errno); } - if (message == STREAM_RUNNING && (sp->stream_id == udp->stream_id)) { + if (message == STREAM_RUNNING && (sp->stream_id == udp->stream_id)) + { sp->result->bytes_received += result; if (udp->packet_count == sp->packet_count + 1) sp->packet_count++; /* jitter measurement */ - if (gettimeofday(&arrival_time, NULL) < 0) { + if (gettimeofday(&arrival_time, NULL) < 0) + { perror("gettimeofday"); } transit = timeval_diff(&udp->sent_time, &arrival_time); @@ -463,12 +502,13 @@ iperf_udp_recv(struct iperf_stream *sp) /* OUT OF ORDER PACKETS */ - if (udp->packet_count != sp->packet_count) { - if (udp->packet_count < sp->packet_count + 1) { + if (udp->packet_count != sp->packet_count) + { + if (udp->packet_count < sp->packet_count + 1) + { sp->outoforder_packets++; printf("OUT OF ORDER - incoming packet = %d and received packet = %d AND SP = %d\n", udp->packet_count, sp->packet_count, sp->socket); - } - else + } else sp->cnt_error += udp->packet_count - sp->packet_count; } /* store the latest packet id */ @@ -482,17 +522,20 @@ iperf_udp_recv(struct iperf_stream *sp) } +/**************************************************************************/ int -iperf_tcp_send(struct iperf_stream *sp) +iperf_tcp_send(struct iperf_stream * sp) { - int result; - int size = sp->settings->blksize; - struct param_exchange *param = (struct param_exchange *)sp->buffer; + int result; + int size = sp->settings->blksize; + struct param_exchange *param = (struct param_exchange *) sp->buffer; - if (!sp->buffer) { + if (!sp->buffer) + { perror("malloc: unable to allocate transmit buffer"); } - switch (sp->settings->state) { + switch (sp->settings->state) + { case STREAM_BEGIN: param->state = STREAM_BEGIN; strncpy(param->cookie, sp->settings->cookie, 37); @@ -522,7 +565,8 @@ iperf_tcp_send(struct iperf_stream *sp) } /* applicable for 1st packet sent */ - if (sp->settings->state == STREAM_BEGIN) { + if (sp->settings->state == STREAM_BEGIN) + { sp->settings->state = STREAM_RUNNING; } result = send(sp->socket, sp->buffer, size, 0); @@ -534,23 +578,25 @@ iperf_tcp_send(struct iperf_stream *sp) return result; } +/**************************************************************************/ int -iperf_udp_send(struct iperf_stream *sp) +iperf_udp_send(struct iperf_stream * sp) { - int result = 0; - struct timeval before, after; - int64_t dtargus; - int64_t adjustus = 0; + int result = 0; + struct timeval before, after; + int64_t dtargus; + int64_t adjustus = 0; /* * the || part ensures that last packet is sent to server - the * STREAM_END MESSAGE */ - if (sp->send_timer->expired(sp->send_timer) || sp->settings->state == STREAM_END) { - int size = sp->settings->blksize; + if (sp->send_timer->expired(sp->send_timer) || sp->settings->state == STREAM_END) + { + int size = sp->settings->blksize; /* this is for udp packet/jitter/lost packet measurements */ - struct udp_datagram *udp = (struct udp_datagram *)sp->buffer; + struct udp_datagram *udp = (struct udp_datagram *) sp->buffer; struct param_exchange *param = NULL; dtargus = (int64_t) (sp->settings->blksize) * SEC_TO_US * 8; @@ -558,21 +604,22 @@ iperf_udp_send(struct iperf_stream *sp) assert(dtargus != 0); - switch (sp->settings->state) { + switch (sp->settings->state) + { case STREAM_BEGIN: udp->state = STREAM_BEGIN; - udp->stream_id = (int)sp; + udp->stream_id = (int) sp; /* udp->packet_count = ++sp->packet_count; */ break; case STREAM_END: udp->state = STREAM_END; - udp->stream_id = (int)sp; + udp->stream_id = (int) sp; break; case RESULT_REQUEST: udp->state = RESULT_REQUEST; - udp->stream_id = (int)sp; + udp->stream_id = (int) sp; break; case ALL_STREAMS_END: @@ -581,12 +628,13 @@ iperf_udp_send(struct iperf_stream *sp) case STREAM_RUNNING: udp->state = STREAM_RUNNING; - udp->stream_id = (int)sp; + udp->stream_id = (int) sp; udp->packet_count = ++sp->packet_count; break; } - if (sp->settings->state == STREAM_BEGIN) { + if (sp->settings->state == STREAM_BEGIN) + { sp->settings->state = STREAM_RUNNING; } if (gettimeofday(&before, 0) < 0) @@ -612,7 +660,8 @@ iperf_udp_send(struct iperf_stream *sp) adjustus += (before.tv_sec - after.tv_sec) * SEC_TO_US; adjustus += (before.tv_usec - after.tv_usec); - if (adjustus > 0) { + if (adjustus > 0) + { dtargus = adjustus; } /* RESET THE TIMER */ @@ -623,35 +672,38 @@ iperf_udp_send(struct iperf_stream *sp) return result; } +/**************************************************************************/ struct iperf_test * iperf_new_test() { struct iperf_test *testp; - testp = (struct iperf_test *)malloc(sizeof(struct iperf_test)); - if (!testp) { + testp = (struct iperf_test *) malloc(sizeof(struct iperf_test)); + if (!testp) + { perror("malloc"); return (NULL); } /* initialise everything to zero */ memset(testp, 0, sizeof(struct iperf_test)); - testp->default_settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings)); + testp->default_settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings)); memset(testp->default_settings, 0, sizeof(struct iperf_settings)); /* return an empty iperf_test* with memory alloted. */ return testp; } +/**************************************************************************/ void -iperf_defaults(struct iperf_test *testp) +iperf_defaults(struct iperf_test * testp) { - int i; + int i; testp->protocol = Ptcp; testp->role = 's'; - testp->duration = 10; - testp->server_port = 5001; + testp->duration = DURATION; + testp->server_port = PORT; testp->new_stream = iperf_new_tcp_stream; testp->stats_callback = iperf_stats_callback; @@ -662,9 +714,9 @@ iperf_defaults(struct iperf_test *testp) testp->num_streams = 1; testp->default_settings->unit_format = 'a'; - testp->default_settings->socket_bufsize = 0; + testp->default_settings->socket_bufsize = 0; /* use autotuning */ testp->default_settings->blksize = DEFAULT_TCP_BLKSIZE; - testp->default_settings->rate = RATE; + testp->default_settings->rate = RATE; /* UDP only */ testp->default_settings->state = TEST_START; testp->default_settings->mss = 0; testp->default_settings->bytes = 0; @@ -673,71 +725,76 @@ iperf_defaults(struct iperf_test *testp) testp->default_settings->cookie[i] = '\0'; } -void -iperf_init_test(struct iperf_test *test) -{ - char ubuf [UNIT_LEN]; - struct iperf_stream *sp; - int i , s = 0; +/**************************************************************************/ - if (test->role == 's') { +void +iperf_init_test(struct iperf_test * test) +{ + char ubuf[UNIT_LEN]; + struct iperf_stream *sp; + int i, s = 0; + + if (test->role == 's') + { /* server */ + /* XXX: looks like this is setting up both TCP and UDP. Why? -blt */ test->listener_sock_udp = netannounce(Pudp, NULL, test->server_port); if (test->listener_sock_udp < 0) exit(0); - if (set_tcp_windowsize(test->listener_sock_udp, test->default_settings->socket_bufsize, SO_RCVBUF) < 0) { - perror("unable to set window"); - } test->listener_sock_tcp = netannounce(Ptcp, NULL, test->server_port); if (test->listener_sock_tcp < 0) exit(0); - if (test->default_settings->socket_bufsize == 0) - test->default_settings->socket_bufsize = getsock_tcp_windowsize(test->listener_sock_tcp, SO_RCVBUF); - - if (set_tcp_windowsize(test->listener_sock_tcp, test->default_settings->socket_bufsize, SO_RCVBUF) < 0) { - perror("unable to set window"); + if (set_tcp_windowsize(test->listener_sock_tcp, test->default_settings->socket_bufsize, SO_RCVBUF) < 0) + { + perror("unable to set TCP window"); } + /* XXX: why do we do this?? -blt */ setnonblocking(test->listener_sock_tcp); setnonblocking(test->listener_sock_udp); printf("-----------------------------------------------------------\n"); printf("Server listening on %d\n", test->server_port); - int x; + int x; - if ((x = getsock_tcp_windowsize(test->listener_sock_tcp, SO_RCVBUF)) < 0) + /* make sure we got what we asked for */ + if ((x = get_tcp_windowsize(test->listener_sock_tcp, SO_RCVBUF)) < 0) perror("SO_RCVBUF"); - /* TODO - CHANGE THIS */ - unit_snprintf(ubuf, UNIT_LEN, (double)x, 'A'); - printf("%s: %s\n", - test->protocol == Ptcp ? "TCP window size" : "UDP buffer size", ubuf); + if (test->protocol == Ptcp) + { + { + if (test->default_settings->socket_bufsize > 0) + { + unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A'); + printf("TCP window size: %s\n", ubuf); + } else + { + printf("Using TCP Autotuning \n"); + } + } + } printf("-----------------------------------------------------------\n"); - } - else if (test->role == 'c') { + } else if (test->role == 'c') + { /* Client */ FD_ZERO(&test->write_set); FD_SET(s, &test->write_set); - for (i = 0; i < test->num_streams; i++) { + for (i = 0; i < test->num_streams; i++) + { s = netdial(test->protocol, test->server_hostname, test->server_port); - if (s < 0) { + if (s < 0) + { fprintf(stderr, "netdial failed\n"); exit(0); } FD_SET(s, &test->write_set); test->max_fd = (test->max_fd < s) ? s : test->max_fd; - if (test->default_settings->socket_bufsize == 0) - test->default_settings->socket_bufsize = getsock_tcp_windowsize(test->listener_sock_tcp, SO_SNDBUF); - - if (set_tcp_windowsize(s, test->default_settings->socket_bufsize, SO_SNDBUF)) { - perror("unable to set window"); - } - //setnonblocking(s); - sp = test->new_stream(test); sp->socket = s; + printf ("in iperf_init_test: tcp_windowsize: %d \n", test->default_settings->socket_bufsize); iperf_init_stream(sp, test); iperf_add_stream(test, sp); @@ -747,8 +804,9 @@ iperf_init_test(struct iperf_test *test) } } +/**************************************************************************/ void -iperf_free_test(struct iperf_test *test) +iperf_free_test(struct iperf_test * test) { free(test->default_settings); @@ -763,24 +821,27 @@ iperf_free_test(struct iperf_test *test) free(test); } -void * -iperf_stats_callback(struct iperf_test *test) +/**************************************************************************/ +void * +iperf_stats_callback(struct iperf_test * test) { - iperf_size_t cumulative_bytes = 0; - int i; + iperf_size_t cumulative_bytes = 0; + int i; #if defined(linux) || defined(__FreeBSD__) - socklen_t tcp_info_length; + socklen_t tcp_info_length; #endif struct iperf_stream *sp = test->streams; struct iperf_stream_result *rp = test->streams->result; struct iperf_interval_results *ip, temp; - for (i = 0; i < test->num_streams; i++) { + for (i = 0; i < test->num_streams; i++) + { rp = sp->result; - if (!rp->interval_results) { + if (!rp->interval_results) + { if (test->role == 'c') temp.bytes_transferred = rp->bytes_sent; else @@ -791,9 +852,11 @@ iperf_stats_callback(struct iperf_test *test) temp.interval_duration = timeval_diff(&sp->result->start_time, &temp.interval_time); #if defined(linux) || defined(__FreeBSD__) - if (test->tcp_info) { + if (test->tcp_info) + { tcp_info_length = sizeof(temp.tcpInfo); - if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&temp.tcpInfo, &tcp_info_length) == 0) { + if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *) &temp.tcpInfo, &tcp_info_length) == 0) + { perror("getsockopt"); } } @@ -801,10 +864,11 @@ iperf_stats_callback(struct iperf_test *test) gettimeofday(&sp->result->end_time, NULL); add_interval_list(rp, temp); - } - else { + } else + { ip = sp->result->interval_results; - while (1) { + while (1) + { cumulative_bytes += ip->bytes_transferred; if (ip->next != NULL) ip = ip->next; @@ -832,25 +896,27 @@ iperf_stats_callback(struct iperf_test *test) return 0; } -char * -iperf_reporter_callback(struct iperf_test *test) +/**************************************************************************/ +char * +iperf_reporter_callback(struct iperf_test * test) { - int count = 0, total_packets = 0, lost_packets = 0; - char ubuf [UNIT_LEN]; - char nbuf [UNIT_LEN]; + int count = 0, total_packets = 0, lost_packets = 0; + char ubuf[UNIT_LEN]; + char nbuf[UNIT_LEN]; struct iperf_stream *sp = test->streams; - iperf_size_t bytes = 0; - double start_time, end_time; - char *message = (char *)malloc(500); + iperf_size_t bytes = 0; + double start_time, end_time; + char *message = (char *) malloc(500); /* used to determine the length of reporter buffer */ - while (sp) { + while (sp) + { count++; sp = sp->next; } - char *message_final = (char *)malloc((count + 1) * (strlen(report_bw_jitter_loss_header) - + strlen(report_bw_jitter_loss_format) + strlen(report_sum_bw_jitter_loss_format))); + char *message_final = (char *) malloc((count + 1) * (strlen(report_bw_jitter_loss_header) + + strlen(report_bw_jitter_loss_format) + strlen(report_sum_bw_jitter_loss_format))); memset(message_final, 0, strlen(message_final)); @@ -859,19 +925,23 @@ iperf_reporter_callback(struct iperf_test *test) sp = test->streams; - if (test->default_settings->state == TEST_RUNNING) { - while (sp) { + if (test->default_settings->state == TEST_RUNNING) + { + while (sp) + { ip = sp->result->interval_results; - while (ip->next != NULL) { + while (ip->next != NULL) + { ip_prev = ip; ip = ip->next; } bytes += ip->bytes_transferred; - unit_snprintf(ubuf, UNIT_LEN, (double)(ip->bytes_transferred), 'A'); + unit_snprintf(ubuf, UNIT_LEN, (double) (ip->bytes_transferred), 'A'); - if (test->streams->result->interval_results->next != NULL) { - unit_snprintf(nbuf, UNIT_LEN, (double)(ip->bytes_transferred / (ip->interval_duration - ip_prev->interval_duration)), + if (test->streams->result->interval_results->next != NULL) + { + unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred / (ip->interval_duration - ip_prev->interval_duration)), test->default_settings->unit_format); sprintf(message, report_bw_format, sp->socket, ip_prev->interval_duration, ip->interval_duration, ubuf, nbuf); @@ -887,12 +957,12 @@ iperf_reporter_callback(struct iperf_test *test) #endif - } - else { + } else + { sprintf(message, report_bw_header); strcat(message_final, message); - unit_snprintf(nbuf, UNIT_LEN, (double)(ip->bytes_transferred / ip->interval_duration), test->default_settings->unit_format); + unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred / ip->interval_duration), test->default_settings->unit_format); sprintf(message, report_bw_format, sp->socket, 0.0, ip->interval_duration, ubuf, nbuf); } strcat(message_final, message); @@ -900,16 +970,18 @@ iperf_reporter_callback(struct iperf_test *test) } - if (test->num_streams > 1) { - unit_snprintf(ubuf, UNIT_LEN, (double)(bytes), 'A'); + if (test->num_streams > 1) + { + unit_snprintf(ubuf, UNIT_LEN, (double) (bytes), 'A'); - if (test->streams->result->interval_results->next != NULL) { - unit_snprintf(nbuf, UNIT_LEN, (double)(bytes / (ip->interval_duration - ip_prev->interval_duration)), + if (test->streams->result->interval_results->next != NULL) + { + unit_snprintf(nbuf, UNIT_LEN, (double) (bytes / (ip->interval_duration - ip_prev->interval_duration)), test->default_settings->unit_format); sprintf(message, report_sum_bw_format, ip_prev->interval_duration, ip->interval_duration, ubuf, nbuf); - } - else { - unit_snprintf(nbuf, UNIT_LEN, (double)(bytes / ip->interval_duration), test->default_settings->unit_format); + } else + { + unit_snprintf(nbuf, UNIT_LEN, (double) (bytes / ip->interval_duration), test->default_settings->unit_format); sprintf(message, report_sum_bw_format, 0.0, ip->interval_duration, ubuf, nbuf); } @@ -917,43 +989,50 @@ iperf_reporter_callback(struct iperf_test *test) free(message); } } - if (test->default_settings->state == RESULT_REQUEST) { + if (test->default_settings->state == RESULT_REQUEST) + { sp = test->streams; - while (sp) { - if (sp->settings->state == STREAM_END) { + while (sp) + { + if (sp->settings->state == STREAM_END) + { if (test->role == 'c') bytes += sp->result->bytes_sent; else bytes += sp->result->bytes_received; - if (test->protocol == Pudp) { + if (test->protocol == Pudp) + { total_packets += sp->packet_count; lost_packets += sp->cnt_error; } start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time); end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time); - if (test->role == 'c') { - unit_snprintf(ubuf, UNIT_LEN, (double)(sp->result->bytes_sent), 'A'); - unit_snprintf(nbuf, UNIT_LEN, (double)(sp->result->bytes_sent / end_time), test->default_settings->unit_format); + if (test->role == 'c') + { + unit_snprintf(ubuf, UNIT_LEN, (double) (sp->result->bytes_sent), 'A'); + unit_snprintf(nbuf, UNIT_LEN, (double) (sp->result->bytes_sent / end_time), test->default_settings->unit_format); - } - else { - unit_snprintf(ubuf, UNIT_LEN, (double)(sp->result->bytes_received), 'A'); - unit_snprintf(nbuf, UNIT_LEN, (double)(sp->result->bytes_received / end_time), test->default_settings->unit_format); + } else + { + unit_snprintf(ubuf, UNIT_LEN, (double) (sp->result->bytes_received), 'A'); + unit_snprintf(nbuf, UNIT_LEN, (double) (sp->result->bytes_received / end_time), test->default_settings->unit_format); } - if (test->protocol == Ptcp) { + if (test->protocol == Ptcp) + { sprintf(message, report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf); strcat(message_final, message); - } - else { + } else + { sprintf(message, report_bw_jitter_loss_format, sp->socket, start_time, - end_time, ubuf, nbuf, sp->jitter * 1000, sp->cnt_error, sp->packet_count, (double)(100.0 * sp->cnt_error / sp->packet_count)); + end_time, ubuf, nbuf, sp->jitter * 1000, sp->cnt_error, sp->packet_count, (double) (100.0 * sp->cnt_error / sp->packet_count)); strcat(message_final, message); - if (test->role == 'c') { + if (test->role == 'c') + { sprintf(message, report_datagrams, sp->socket, sp->packet_count); strcat(message_final, message); } @@ -969,21 +1048,24 @@ iperf_reporter_callback(struct iperf_test *test) start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time); end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time); - unit_snprintf(ubuf, UNIT_LEN, (double)bytes, 'A'); - unit_snprintf(nbuf, UNIT_LEN, (double)bytes / end_time, test->default_settings->unit_format); + unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A'); + unit_snprintf(nbuf, UNIT_LEN, (double) bytes / end_time, test->default_settings->unit_format); - if ((test->role == 'c' && test->num_streams > 1) || (test->role == 's')) { - if (test->protocol == Ptcp) { + if ((test->role == 'c' && test->num_streams > 1) || (test->role == 's')) + { + if (test->protocol == Ptcp) + { sprintf(message, report_sum_bw_format, start_time, end_time, ubuf, nbuf); strcat(message_final, message); - } - else { - sprintf(message, report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf, sp->jitter, lost_packets, total_packets, (double)(100.0 * lost_packets / total_packets)); + } else + { + sprintf(message, report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf, sp->jitter, lost_packets, total_packets, (double) (100.0 * lost_packets / total_packets)); strcat(message_final, message); } - if ((test->print_mss != 0) && (test->role == 'c')) { + if ((test->print_mss != 0) && (test->role == 'c')) + { sprintf(message, "\nThe TCP maximum segment size mss = %d \n", getsock_tcp_mss(sp->socket)); strcat(message_final, message); } @@ -993,25 +1075,30 @@ iperf_reporter_callback(struct iperf_test *test) return message_final; } +/**************************************************************************/ void -iperf_free_stream(struct iperf_test *test, struct iperf_stream *sp) +iperf_free_stream(struct iperf_test * test, struct iperf_stream * sp) { struct iperf_stream *prev, *start; prev = test->streams; start = test->streams; - if (test->streams->socket == sp->socket) { + if (test->streams->socket == sp->socket) + { test->streams = test->streams->next; - } - else { + } else + { start = test->streams->next; - while (1) { - if (start->socket == sp->socket) { + while (1) + { + if (start->socket == sp->socket) + { prev->next = sp->next; break; } - if (start->next != NULL) { + if (start->next != NULL) + { start = start->next; prev = prev->next; } @@ -1025,27 +1112,29 @@ iperf_free_stream(struct iperf_test *test, struct iperf_stream *sp) free(sp); } +/**************************************************************************/ struct iperf_stream * -iperf_new_stream(struct iperf_test *testp) +iperf_new_stream(struct iperf_test * testp) { struct iperf_stream *sp; - sp = (struct iperf_stream *)malloc(sizeof(struct iperf_stream)); - if (!sp) { + sp = (struct iperf_stream *) malloc(sizeof(struct iperf_stream)); + if (!sp) + { perror("malloc"); return (NULL); } memset(sp, 0, sizeof(struct iperf_stream)); - sp->buffer = (char *)malloc(testp->default_settings->blksize); - sp->settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings)); + sp->buffer = (char *) malloc(testp->default_settings->blksize); + sp->settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings)); memcpy(sp->settings, testp->default_settings, sizeof(struct iperf_settings)); - sp->result = (struct iperf_stream_result *)malloc(sizeof(struct iperf_stream_result)); + sp->result = (struct iperf_stream_result *) malloc(sizeof(struct iperf_stream_result)); sp->socket = -1; sp->packet_count = 0; - sp->stream_id = (int)sp; + sp->stream_id = (int) sp; sp->jitter = 0.0; sp->prev_transit = 0.0; sp->outoforder_packets = 0; @@ -1062,13 +1151,15 @@ iperf_new_stream(struct iperf_test *testp) return sp; } +/**************************************************************************/ struct iperf_stream * -iperf_new_tcp_stream(struct iperf_test *testp) +iperf_new_tcp_stream(struct iperf_test * testp) { struct iperf_stream *sp; - sp = (struct iperf_stream *)iperf_new_stream(testp); - if (!sp) { + sp = (struct iperf_stream *) iperf_new_stream(testp); + if (!sp) + { perror("malloc"); return (NULL); } @@ -1080,13 +1171,15 @@ iperf_new_tcp_stream(struct iperf_test *testp) return sp; } +/**************************************************************************/ struct iperf_stream * -iperf_new_udp_stream(struct iperf_test *testp) +iperf_new_udp_stream(struct iperf_test * testp) { struct iperf_stream *sp; - sp = (struct iperf_stream *)iperf_new_stream(testp); - if (!sp) { + sp = (struct iperf_stream *) iperf_new_stream(testp); + if (!sp) + { perror("malloc"); return (NULL); } @@ -1097,27 +1190,29 @@ iperf_new_udp_stream(struct iperf_test *testp) return sp; } +/**************************************************************************/ int -iperf_udp_accept(struct iperf_test *test) +iperf_udp_accept(struct iperf_test * test) { struct iperf_stream *sp; struct sockaddr_in sa_peer; - char *buf; - socklen_t len; - int sz; + char *buf; + socklen_t len; + int sz; - buf = (char *)malloc(test->default_settings->blksize); - struct udp_datagram *udp = (struct udp_datagram *)buf; + buf = (char *) malloc(test->default_settings->blksize); + struct udp_datagram *udp = (struct udp_datagram *) buf; len = sizeof sa_peer; - sz = recvfrom(test->listener_sock_udp, buf, test->default_settings->blksize, 0, (struct sockaddr *)&sa_peer, &len); + sz = recvfrom(test->listener_sock_udp, buf, test->default_settings->blksize, 0, (struct sockaddr *) & sa_peer, &len); if (!sz) return -1; - if (connect(test->listener_sock_udp, (struct sockaddr *)&sa_peer, len) < 0) { + if (connect(test->listener_sock_udp, (struct sockaddr *) & sa_peer, len) < 0) + { perror("connect"); return -1; } @@ -1146,7 +1241,8 @@ iperf_udp_accept(struct iperf_test *test) sp->result->bytes_received += sz; /* Count OUT OF ORDER PACKETS */ - if (udp->packet_count != 0) { + if (udp->packet_count != 0) + { if (udp->packet_count < sp->packet_count + 1) sp->outoforder_packets++; else @@ -1162,21 +1258,23 @@ iperf_udp_accept(struct iperf_test *test) return 0; } +/**************************************************************************/ int -iperf_tcp_accept(struct iperf_test *test) +iperf_tcp_accept(struct iperf_test * test) { - socklen_t len; + socklen_t len; struct sockaddr_in addr; - int peersock; + int peersock; struct iperf_stream *sp; len = sizeof(addr); - peersock = accept(test->listener_sock_tcp, (struct sockaddr *)&addr, &len); - if (peersock < 0) { + peersock = accept(test->listener_sock_tcp, (struct sockaddr *) & addr, &len); + if (peersock < 0) + { printf("Error in accept(): %s\n", strerror(errno)); return -1; - } - else { + } else + { sp = test->new_stream(test); setnonblocking(peersock); @@ -1184,6 +1282,7 @@ iperf_tcp_accept(struct iperf_test *test) test->max_fd = (test->max_fd < peersock) ? peersock : test->max_fd; sp->socket = peersock; + printf ("in iperf_tcp_accept: tcp_windowsize: %d \n", test->default_settings->socket_bufsize); iperf_init_stream(sp, test); iperf_add_stream(test, sp); @@ -1194,48 +1293,45 @@ iperf_tcp_accept(struct iperf_test *test) } } +/**************************************************************************/ void -iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp) +iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp) { - socklen_t len; + socklen_t len; len = sizeof(struct sockaddr_in); sp->protocol = testp->protocol; - if (getsockname(sp->socket, (struct sockaddr *)&sp->local_addr, &len) < 0) { + if (getsockname(sp->socket, (struct sockaddr *) & sp->local_addr, &len) < 0) + { perror("getsockname"); } - if (getpeername(sp->socket, (struct sockaddr *)&sp->remote_addr, &len) < 0) { + if (getpeername(sp->socket, (struct sockaddr *) & sp->remote_addr, &len) < 0) + { perror("getpeername"); } + printf ("in init_stream: calling set_tcp_windowsize: %d \n", testp->default_settings->socket_bufsize); 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"); - /* - * x = getsock_tcp_windowsize(sp->socket, SO_RCVBUF); if(x < 0) - * perror("SO_RCVBUF"); unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A'); - * printf("RCV: %s\n", ubuf); - * - * x = getsock_tcp_windowsize(sp->socket, SO_SNDBUF); if(x < 0) - * perror("SO_SNDBUF"); unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A'); - * printf("SND: %s\n", ubuf); - */ - - set_socket_options(sp, testp); + set_socket_options(sp, testp); /* set other options (TCP_NODELAY, + * MSS, etc.) */ } +/**************************************************************************/ int -iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp) +iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp) { struct iperf_stream *n; - if (!test->streams) { + if (!test->streams) + { test->streams = sp; return 1; - } - else { + } else + { n = test->streams; while (n->next) n = n->next; @@ -1246,14 +1342,16 @@ iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp) return 0; } +/**************************************************************************/ struct iperf_stream * -find_stream_by_socket(struct iperf_test *test, int sock) +find_stream_by_socket(struct iperf_test * test, int sock) { struct iperf_stream *n; n = test->streams; - while (1) { + while (1) + { if (n->socket == sock) break; @@ -1266,13 +1364,14 @@ find_stream_by_socket(struct iperf_test *test, int sock) return n; } +/**************************************************************************/ void -iperf_run_server(struct iperf_test *test) +iperf_run_server(struct iperf_test * test) { - struct timeval tv; + struct timeval tv; struct iperf_stream *np, *sp; - int j , result, message; - char *read = NULL; + int j, result, message; + char *read = NULL; FD_ZERO(&test->read_set); FD_SET(test->listener_sock_tcp, &test->read_set); @@ -1283,7 +1382,8 @@ iperf_run_server(struct iperf_test *test) test->num_streams = 0; test->default_settings->state = TEST_RUNNING; - while (test->default_settings->state != TEST_END) { + while (test->default_settings->state != TEST_END) + { memcpy(&test->temp_set, &test->read_set, sizeof(test->read_set)); tv.tv_sec = 15; tv.tv_usec = 0; @@ -1291,17 +1391,19 @@ iperf_run_server(struct iperf_test *test) /* using select to check on multiple descriptors. */ result = select(test->max_fd + 1, &test->temp_set, NULL, NULL, &tv); - if (result == 0) - printf("SERVER IDLE : %d sec\n", (int)tv.tv_sec); - - - else if (result < 0 && errno != EINTR) { + if (result == 0 ) + { + //printf("SERVER IDLE : %d sec\n", (int) tv.tv_sec); + continue; + } else if (result < 0 && errno != EINTR) + { printf("Error in select(): %s\n", strerror(errno)); exit(0); - } - else if (result > 0) { + } else if (result > 0) + { /* Accept a new TCP connection */ - if (FD_ISSET(test->listener_sock_tcp, &test->temp_set)) { + if (FD_ISSET(test->listener_sock_tcp, &test->temp_set)) + { test->protocol = Ptcp; test->accept = iperf_tcp_accept; test->new_stream = iperf_new_tcp_stream; @@ -1310,7 +1412,8 @@ iperf_run_server(struct iperf_test *test) FD_CLR(test->listener_sock_tcp, &test->temp_set); } /* Accept a new UDP connection */ - else if (FD_ISSET(test->listener_sock_udp, &test->temp_set)) { + else if (FD_ISSET(test->listener_sock_udp, &test->temp_set)) + { test->protocol = Pudp; test->accept = iperf_udp_accept; test->new_stream = iperf_new_udp_stream; @@ -1319,13 +1422,16 @@ iperf_run_server(struct iperf_test *test) FD_CLR(test->listener_sock_udp, &test->temp_set); } /* Process the sockets for read operation */ - for (j = 0; j < test->max_fd + 1; j++) { - if (FD_ISSET(j, &test->temp_set)) { + for (j = 0; j < test->max_fd + 1; j++) + { + if (FD_ISSET(j, &test->temp_set)) + { /* find the correct stream - possibly time consuming */ np = find_stream_by_socket(test, j); message = np->rcv(np); - if (message == PARAM_EXCHANGE || message == ACCESS_DENIED) { + if (message == PARAM_EXCHANGE || message == ACCESS_DENIED) + { /* copy the received settings into test */ if (message != ACCESS_DENIED) memcpy(test->default_settings, test->streams->settings, sizeof(struct iperf_settings)); @@ -1334,17 +1440,20 @@ iperf_run_server(struct iperf_test *test) FD_CLR(np->socket, &test->read_set); iperf_free_stream(test, np); } - if (message == STREAM_END) { + if (message == STREAM_END) + { np->settings->state = STREAM_END; gettimeofday(&np->result->end_time, NULL); } - if (message == RESULT_REQUEST) { + if (message == RESULT_REQUEST) + { np->settings->state = RESULT_RESPOND; np->data = read; send_result_to_client(np); /* FREE ALL STREAMS */ np = test->streams; - do { + do + { sp = np; close(sp->socket); FD_CLR(sp->socket, &test->read_set); @@ -1355,15 +1464,18 @@ iperf_run_server(struct iperf_test *test) printf("TEST_END\n\n"); test->default_settings->state = TEST_END; } - if (message == ALL_STREAMS_END) { + if (message == ALL_STREAMS_END) + { /* - * sometimes the server is not getting the STREAM_END - * message, hence changing the state of all but last - * stream forcefully - */ + * sometimes the server is not getting the STREAM_END + * message, hence changing the state of all but last + * stream forcefully + */ np = test->streams; - while (np->next) { - if (np->settings->state == STREAM_BEGIN) { + while (np->next) + { + if (np->settings->state == STREAM_BEGIN) + { np->settings->state = STREAM_END; gettimeofday(&np->result->end_time, NULL); } @@ -1387,21 +1499,23 @@ iperf_run_server(struct iperf_test *test) } void +/**************************************************************************/ catcher(int sig) { longjmp(env, sig); } +/**************************************************************************/ void -iperf_run_client(struct iperf_test *test) +iperf_run_client(struct iperf_test * test) { - int i , result = 0; + int i, result = 0; struct iperf_stream *sp, *np; - struct timer *timer, *stats_interval, *reporter_interval; - char *buf, *read = NULL; - int64_t delayus, adjustus, dtargus; - struct timeval tv; - int ret = 0; + struct timer *timer, *stats_interval, *reporter_interval; + char *buf, *read = NULL; + int64_t delayus, adjustus, dtargus; + struct timeval tv; + int ret = 0; struct sigaction sact; tv.tv_sec = 15; /* timeout interval in seconds */ @@ -1413,9 +1527,10 @@ iperf_run_client(struct iperf_test *test) sigaction(SIGINT, &sact, NULL); - buf = (char *)malloc(test->default_settings->blksize); + buf = (char *) malloc(test->default_settings->blksize); - if (test->protocol == Pudp) { + if (test->protocol == Pudp) + { dtargus = (int64_t) (test->default_settings->blksize) * SEC_TO_US * 8; dtargus /= test->default_settings->rate; @@ -1426,7 +1541,8 @@ iperf_run_client(struct iperf_test *test) printf("%lld adj %lld delay\n", adjustus, delayus); sp = test->streams; - for (i = 0; i < test->num_streams; i++) { + for (i = 0; i < test->num_streams; i++) + { sp->send_timer = new_timer(0, dtargus); sp = sp->next; } @@ -1444,7 +1560,8 @@ iperf_run_client(struct iperf_test *test) reporter_interval = new_timer(test->reporter_interval, 0); /* send data till the timer expires or bytes sent */ - while (!all_data_sent(test) && !timer->expired(timer)) { + while (!all_data_sent(test) && !timer->expired(timer)) + { memcpy(&test->temp_set, &test->write_set, sizeof(test->write_set)); /* XXX: Does this need * to be inside the * while loop? -blt */ @@ -1453,7 +1570,8 @@ iperf_run_client(struct iperf_test *test) continue; sp = test->streams; - for (i = 0; i < test->num_streams; i++) { + for (i = 0; i < test->num_streams; i++) + { result += sp->snd(sp); if (sp->next == NULL) @@ -1462,11 +1580,13 @@ iperf_run_client(struct iperf_test *test) } - if ((test->stats_interval != 0) && stats_interval->expired(stats_interval)) { + if ((test->stats_interval != 0) && stats_interval->expired(stats_interval)) + { test->stats_callback(test); update_timer(stats_interval, test->stats_interval, 0); } - if ((test->reporter_interval != 0) && reporter_interval->expired(reporter_interval)) { + if ((test->reporter_interval != 0) && reporter_interval->expired(reporter_interval)) + { read = test->reporter_callback(test); puts(read); update_timer(reporter_interval, test->reporter_interval, 0); @@ -1485,7 +1605,8 @@ iperf_run_client(struct iperf_test *test) /* sending STREAM_END packets */ sp = test->streams; np = sp; - do { + do + { sp = np; sp->settings->state = STREAM_END; sp->snd(sp); @@ -1502,7 +1623,8 @@ iperf_run_client(struct iperf_test *test) /* Deleting all streams - CAN CHANGE FREE_STREAM FN */ sp = test->streams; np = sp; - do { + do + { sp = np; close(sp->socket); np = sp->next; @@ -1516,12 +1638,14 @@ iperf_run_client(struct iperf_test *test) free_timer(timer); } +/**************************************************************************/ int -iperf_run(struct iperf_test *test) +iperf_run(struct iperf_test * test) { test->default_settings->state = TEST_RUNNING; - switch (test->role) { + switch (test->role) + { case 's': iperf_run_server(test); return 0; @@ -1537,6 +1661,7 @@ iperf_run(struct iperf_test *test) } +/**************************************************************************/ static struct option longopts[] = { @@ -1559,31 +1684,35 @@ static struct option longopts[] = {NULL, 0, NULL, 0} }; +/**************************************************************************/ +/**************************************************************************/ int main(int argc, char **argv) { - char ch , role; + char ch, role; struct iperf_test *test; - int port = 5001; + int port = PORT; #ifdef TEST_PROC_AFFINITY + /* didnt seem to work.... */ /* * increasing the priority of the process to minimise packet generation * delay */ - int rc = setpriority(PRIO_PROCESS, 0, -15); + int rc = setpriority(PRIO_PROCESS, 0, -15); - if (rc < 0) { + if (rc < 0) + { perror("setpriority:"); printf("setting priority to valid level\n"); rc = setpriority(PRIO_PROCESS, 0, 0); } /* setting the affinity of the process */ - cpu_set_t cpu_set; - int affinity = -1; - int ncores = 1; + cpu_set_t cpu_set; + int affinity = -1; + int ncores = 1; sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set); if (errno) @@ -1598,16 +1727,19 @@ main(int argc, char **argv) err("couldn't change CPU affinity"); #endif - while (1) { + while (1) /* XXX: should while 1 be server only?? -blt */ + { test = iperf_new_test(); iperf_defaults(test); - while ((ch = getopt_long(argc, argv, "c:p:st:uP:b:l:w:i:n:mNThM:f:", longopts, NULL)) != -1) { - switch (ch) { + while ((ch = getopt_long(argc, argv, "c:p:st:uP:b:l:w:i:n:mNThM:f:", longopts, NULL)) != -1) + { + switch (ch) + { case 'c': test->role = 'c'; role = test->role; - test->server_hostname = (char *)malloc(strlen(optarg)); + test->server_hostname = (char *) malloc(strlen(optarg)); strncpy(test->server_hostname, optarg, strlen(optarg)); break; case 'p': @@ -1678,7 +1810,9 @@ main(int argc, char **argv) if (test->role == 's'); test->server_port = port; + printf("in main: calling iperf_init_test \n"); iperf_init_test(test); + printf("in main: calling iperf_run \n"); iperf_run(test); iperf_free_test(test); diff --git a/src/iperf_api.h b/src/iperf_api.h index 17422cb..d8ea350 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -1,7 +1,7 @@ -/* - Copyright (c) 2004, The Regents of the University of California, through - Lawrence Berkeley National Laboratory (subject to receipt of any required +/* + Copyright (c) 2004, The Regents of the University of California, through + Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. */ @@ -10,148 +10,150 @@ typedef uint64_t iperf_size_t; struct iperf_interval_results { iperf_size_t bytes_transferred; - struct timeval interval_time; - float interval_duration; + struct timeval interval_time; + float interval_duration; #if defined(linux) || defined(__FreeBSD__) - /* include getsockopt(TCP_INFO results here for Linux and FreeBSD */ - struct tcp_info tcpInfo; + struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) results here for + * Linux and FreeBSD stored here */ #endif - struct iperf_interval_results *next; - void * custom_data; + struct iperf_interval_results *next; + void *custom_data; }; struct iperf_stream_result { - iperf_size_t bytes_received; - iperf_size_t bytes_sent; + iperf_size_t bytes_received; + iperf_size_t bytes_sent; struct timeval start_time; struct timeval end_time; - struct iperf_interval_results *interval_results; - void *data; + struct iperf_interval_results *interval_results; + void *data; }; struct iperf_settings { - int socket_bufsize; // -w buffer size for setsockopt(), window size for TCP - int socket_snd_bufsize; // overrides bufsize in the send direction - int socket_rcv_bufsize; // overrides bufsize in the receive direction - - int blksize; // -l size of each read/write, in UDP this relates directly to packet_size - - uint64_t rate; // target data rate, UDP only - int mss; /* for TCP MSS */ - int ttl; - int tos; - iperf_size_t bytes; /* -n option */ - char unit_format; /* -f */ - int state; /* This is state of a stream/test */ - char cookie[37]; + int socket_bufsize; /* window size for TCP */ + int blksize; /* size of read/writes (-l) */ + uint64_t rate; /* target data rate, UDP only */ + int mss; /* for TCP MSS */ + int ttl; + int tos; + iperf_size_t bytes; /* -n option */ + char unit_format; /* -f */ + int state; /* This is state of a stream/test */ + char cookie[37]; /* XXX: why 37? This should be a constant + * -blt */ }; struct iperf_stream -{ +{ /* configurable members */ - int local_port; // local port - int remote_port; // remote machine port - struct iperf_settings *settings; // pointer to structure settings - int protocol; // protocol- TCP/UDP - + int local_port; + int remote_port; + struct iperf_settings *settings; /* pointer to structure settings */ + int protocol; /* TCP or UDP */ + /* non configurable members */ - struct iperf_stream_result *result; //structure pointer to result - int socket; // socket + struct iperf_stream_result *result; /* structure pointer to result */ + int socket; struct timer *send_timer; - - char *buffer; - - /* for udp measurements - This can be a structure outside stream, - and stream can have a pointer to this */ - int packet_count; - int stream_id; // stream identity - double jitter; - double prev_transit; - int outoforder_packets; - int cnt_error; - uint64_t target; - + char *buffer; /* data to send */ + + /* + * for udp measurements - This can be a structure outside stream, and + * stream can have a pointer to this + */ + int packet_count; + int stream_id; /* stream identity */ + double jitter; + double prev_transit; + int outoforder_packets; + int cnt_error; + uint64_t target; + struct sockaddr_storage local_addr; struct sockaddr_storage remote_addr; - - int (*rcv)(struct iperf_stream *stream); - int (*snd)(struct iperf_stream *stream); - int (*update_stats)(struct iperf_stream *stream); - + + int (*rcv) (struct iperf_stream * stream); + int (*snd) (struct iperf_stream * stream); + int (*update_stats) (struct iperf_stream * stream); + struct iperf_stream *next; - void *data; + void *data; }; struct iperf_test { - char role; // 'c'lient or 's'erver -s / -c - int protocol; - - char *server_hostname; // arg of -c - int server_port; // arg of -p - int duration; // total duration of test -t - int listener_sock_tcp; - int listener_sock_udp; - - /*boolen variables for Options */ - int daemon; // -D - int no_delay; // -N - int print_mss; // -m - int domain; // -V - - /* Select related parameters */ - int max_fd; - fd_set read_set; - fd_set temp_set; - fd_set write_set; + char role; /* c' lient or 's' erver */ + int protocol; + char *server_hostname; /* -c option */ + int server_port; + int duration; /* total duration of test (-t flag) */ + int listener_sock_tcp; + int listener_sock_udp; - int (*accept)(struct iperf_test *); - struct iperf_stream *(*new_stream)(struct iperf_test *); - - int stats_interval; // time interval to gather stats -i - void *(*stats_callback)(struct iperf_test *); // callback function pointer for stats - - int reporter_interval; // time interval for reporter - char *(*reporter_callback)(struct iperf_test *); // callback function pointer for reporter - int reporter_fd; // file descriptor for reporter + /* boolen variables for Options */ + int daemon; /* -D option */ + int no_delay; /* -N option */ + int print_mss; /* -m option */ + int domain; /* -V option */ - int num_streams; // total streams in the test -P - int tcp_info; /* display getsockopt(TCP_INFO) results */ - struct iperf_stream *streams; // pointer to list of struct stream + /* Select related parameters */ + int max_fd; + fd_set read_set; + fd_set temp_set; + fd_set write_set; + + int (*accept) (struct iperf_test *); + struct iperf_stream *(*new_stream) (struct iperf_test *); + int stats_interval; /* time interval to gather stats (-i) */ + void *(*stats_callback) (struct iperf_test *); /* callback function + * pointer for stats */ + int reporter_interval;/* time interval for reporter */ + char *(*reporter_callback) (struct iperf_test *); /* callback function + * pointer for reporter */ + int reporter_fd; /* file descriptor for reporter */ + int num_streams; /* total streams in the test (-P) */ + int tcp_info; /* display getsockopt(TCP_INFO) results */ + struct iperf_stream *streams; /* pointer to list of struct stream */ struct iperf_settings *default_settings; }; struct udp_datagram -{ - int state; - int stream_id; - int packet_count; +{ + int state; + int stream_id; + int packet_count; struct timeval sent_time; }; struct param_exchange { - int state; - int stream_id; - int blksize; - int recv_window; - int send_window; - int mss; - char format; - char cookie[37]; + int state; + int stream_id; + int blksize; + int recv_window; + int send_window; + int mss; + char format; + char cookie[37]; /* size 37 makes total size 64 */ }; -enum { +enum +{ + /* default settings */ Ptcp = SOCK_STREAM, - Pudp = SOCK_DGRAM, + Pudp = SOCK_DGRAM, + PORT = 5001, /* default port to listen on */ uS_TO_NS = 1000, - RATE = 1000000, - MAX_BUFFER_SIZE =10, - DEFAULT_UDP_BLKSIZE = 1470, - DEFAULT_TCP_BLKSIZE = 8192, + SEC_TO_US = 1000000, + RATE = 1024 * 1024, /* 1 Mbps */ + DURATION = 10, /* seconds */ + DEFAULT_UDP_BLKSIZE = 1450, /* 1 packet per ethernet frame, IPV6 too */ + DEFAULT_TCP_BLKSIZE = 256 * 1024, /* default read/write block size */ + + /* other useful constants */ TEST_START = 1, TEST_RUNNING = 2, RESULT_REQUEST = 3, @@ -163,80 +165,79 @@ enum { ALL_STREAMS_END = 9, PARAM_EXCHANGE = 10, ACCESS_DENIED = -1, - SEC_TO_US = 1000000, }; -#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */ -jmp_buf env; +#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */ +jmp_buf env; /** - * exchange_parameters - handles the param_Exchange part for client - * - */ -void exchange_parameters(struct iperf_test *test); - -/** - * param_received - handles the param_Exchange part for server - * returns state on success, -1 on failure + * exchange_parameters - handles the param_Exchange part for client * */ -int param_received(struct iperf_stream *sp, struct param_exchange *param); +void exchange_parameters(struct iperf_test * test); + +/** + * param_received - handles the param_Exchange part for server + * returns state on success, -1 on failure + * + */ +int param_received(struct iperf_stream * sp, struct param_exchange * param); /** * add_interval_list -- adds new interval to the interval_list - * + * */ -void add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results temp); +void add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results temp); /** * Display -- Displays interval results for test * Mainly for DEBUG purpose - * + * */ -void display_interval_list(struct iperf_stream_result *rp); +void display_interval_list(struct iperf_stream_result * rp); /** - * send_result_to_client - sends result to client via + * send_result_to_client - sends result to client via * a new TCP connection */ -void send_result_to_client(struct iperf_stream *sp); +void send_result_to_client(struct iperf_stream * sp); /** - * receive_result_from_server - Receives result from server via + * receive_result_from_server - Receives result from server via * a new TCP connection */ -void receive_result_from_server(struct iperf_test *test); +void receive_result_from_server(struct iperf_test * test); /** * getsock_tcp_mss - Returns the MSS size for TCP - * + * */ -int getsock_tcp_mss( int inSock ); +int getsock_tcp_mss(int inSock); /** * set_socket_options - used for setsockopt() - * - * + * + * */ -int set_socket_options(struct iperf_stream *sp, struct iperf_test *test); +int set_socket_options(struct iperf_stream * sp, struct iperf_test * test); /** * connect_msg -- displays connection message * denoting senfer/receiver details - * + * */ -void connect_msg(struct iperf_stream *sp); +void connect_msg(struct iperf_stream * sp); /** * Display -- Displays streams in a test * Mainly for DEBUG purpose - * + * */ -void Display(struct iperf_test *test); +void Display(struct iperf_test * test); /** @@ -246,7 +247,7 @@ void Display(struct iperf_test *test); *returns 0 on success * */ -int iperf_tcp_accept(struct iperf_test *test); +int iperf_tcp_accept(struct iperf_test * test); /** * iperf_udp_accept -- accepts a new UDP connection @@ -254,40 +255,40 @@ int iperf_tcp_accept(struct iperf_test *test); *returns 0 on success * */ -int iperf_udp_accept(struct iperf_test *test); +int iperf_udp_accept(struct iperf_test * test); /** - * iperf_tcp_recv -- receives the data for TCP + * iperf_tcp_recv -- receives the data for TCP * and the Param/result message exchange *returns state of packet received * */ -int iperf_tcp_recv(struct iperf_stream *sp); +int iperf_tcp_recv(struct iperf_stream * sp); /** - * iperf_udp_recv -- receives the client data for UDP - * + * iperf_udp_recv -- receives the client data for UDP + * *returns state of packet received * */ -int iperf_udp_recv(struct iperf_stream *sp); +int iperf_udp_recv(struct iperf_stream * sp); /** - * iperf_tcp_send -- sends the client data for TCP + * iperf_tcp_send -- sends the client data for TCP * and the Param/result message exchanges - *returns bytes sent + * returns: bytes sent * */ -int iperf_tcp_send(struct iperf_stream *sp); +int iperf_tcp_send(struct iperf_stream * sp); /** * iperf_udp_send -- sends the client data for UDP * - *returns bytes sent + * returns: bytes sent * */ -int iperf_udp_send(struct iperf_stream *sp); +int iperf_udp_send(struct iperf_stream * sp); /** * iperf_stats_callback -- handles the statistic gathering @@ -295,7 +296,7 @@ int iperf_udp_send(struct iperf_stream *sp); *returns void * * */ -void *iperf_stats_callback(struct iperf_test *test); +void *iperf_stats_callback(struct iperf_test * test); /** @@ -304,7 +305,7 @@ void *iperf_stats_callback(struct iperf_test *test); *returns report * */ -char *iperf_reporter_callback(struct iperf_test *test); +char *iperf_reporter_callback(struct iperf_test * test); /** @@ -313,27 +314,27 @@ char *iperf_reporter_callback(struct iperf_test *test); *returns stream * */ -struct iperf_stream * find_stream_by_socket(struct iperf_test *test, int sock); +struct iperf_stream *find_stream_by_socket(struct iperf_test * test, int sock); /** * iperf_run_server -- Runs the server portion of a test * */ -void iperf_run_server(struct iperf_test *test); +void iperf_run_server(struct iperf_test * test); /** * iperf_run_client -- Runs the client portion of a test * */ -void iperf_run_client(struct iperf_test *test); +void iperf_run_client(struct iperf_test * test); /** * iperf_run -- runs the test either as client or server * - * returns status + * returns status * */ -int iperf_run(struct iperf_test *test); +int iperf_run(struct iperf_test * test); /** * iperf_new_test -- return a new iperf_test with default values @@ -343,20 +344,20 @@ int iperf_run(struct iperf_test *test); */ struct iperf_test *iperf_new_test(); -void iperf_defaults(struct iperf_test *testp); +void iperf_defaults(struct iperf_test * testp); /** * iperf_init_test -- perform pretest initialization (listen on sockets, etc) * */ -void iperf_init_test(struct iperf_test *testp); +void iperf_init_test(struct iperf_test * testp); /** * iperf_free_test -- free resources used by test, calls iperf_free_stream to * free streams * */ -void iperf_free_test(struct iperf_test *testp); +void iperf_free_test(struct iperf_test * testp); /** @@ -365,27 +366,26 @@ void iperf_free_test(struct iperf_test *testp); * returns NULL on failure * */ -struct iperf_stream *iperf_new_stream(struct iperf_test *testp); +struct iperf_stream *iperf_new_stream(struct iperf_test * testp); -struct iperf_stream *iperf_new_tcp_stream(struct iperf_test *testp); -struct iperf_stream *iperf_new_udp_stream(struct iperf_test *testp); +struct iperf_stream *iperf_new_tcp_stream(struct iperf_test * testp); +struct iperf_stream *iperf_new_udp_stream(struct iperf_test * testp); /** * iperf_add_stream -- add a stream to a test * * returns 1 on success 0 on failure */ -int iperf_add_stream(struct iperf_test *test, struct iperf_stream *stream); +int iperf_add_stream(struct iperf_test * test, struct iperf_stream * stream); /** * iperf_init_stream -- init resources associated with test * */ -void iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp); +void iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp); /** * iperf_free_stream -- free resources associated with test * */ -void iperf_free_stream(struct iperf_test *test, struct iperf_stream *sp); - +void iperf_free_stream(struct iperf_test * test, struct iperf_stream * sp); diff --git a/src/net.c b/src/net.c index c15435d..42f17a1 100644 --- a/src/net.c +++ b/src/net.c @@ -8,6 +8,7 @@ #include +/* make connection to server */ int netdial(int proto, char *client, int port) { @@ -16,6 +17,7 @@ netdial(int proto, char *client, int port) struct sockaddr_in sa; socklen_t sn; + /* XXX: should this be called server?? -blt */ if ((hent = gethostbyname(client)) == 0) { perror("gethostbyname"); diff --git a/src/socket.c b/src/socket.c deleted file mode 100644 index a7285b7..0000000 --- a/src/socket.c +++ /dev/null @@ -1,256 +0,0 @@ -/*--------------------------------------------------------------- - * Copyright (c) 1999,2000,2001,2002,2003 - * The Board of Trustees of the University of Illinois - * All Rights Reserved. - *--------------------------------------------------------------- - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software (Iperf) and associated - * documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * - * Redistributions of source code must retain the above - * copyright notice, this list of conditions and - * the following disclaimers. - * - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimers in the documentation and/or other materials - * provided with the distribution. - * - * - * Neither the names of the University of Illinois, NCSA, - * nor the names of its contributors may be used to endorse - * or promote products derived from this Software without - * specific prior written permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ________________________________________________________________ - * National Laboratory for Applied Network Research - * National Center for Supercomputing Applications - * University of Illinois at Urbana-Champaign - * http://www.ncsa.uiuc.edu - * ________________________________________________________________ - * - * socket.c - * by Mark Gates - * ------------------------------------------------------------------- - * set/getsockopt - * ------------------------------------------------------------------- */ - -#include "headers.h" -#include "util.h" - -/* ------------------------------------------------------------------- - * If req_mss > 0, set the TCP maximum segment size for sock. - * Otherwise leave it as the system default. - * ------------------------------------------------------------------- */ - -const char warn_mss_fail[] = "\ -WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\ -Setting the MSS may not be implemented on this OS.\n"; - -const char warn_mss_notset[] = -"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n"; - -void -setsock_tcp_mss(int sock, int req_mss) -{ -#ifdef TCP_MAXSEG - int rc; - int new_mss; - Socklen_t len; - - assert(sock != INVALID_SOCKET); - - if (req_mss > 0) - { - /* set */ - new_mss = req_mss; - len = sizeof(new_mss); - rc = setsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, len); - if (rc == SOCKET_ERROR) - { - fprintf(stderr, warn_mss_fail, new_mss); - return; - } - /* verify results */ - rc = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, &len); - WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG"); - if (new_mss != req_mss) - { - fprintf(stderr, warn_mss_notset, req_mss, new_mss); - } - } -#endif -} - -/* ------------------------------------------------------------------- - * returns the TCP maximum segment size - * ------------------------------------------------------------------- */ - -int -getsock_tcp_mss(int sock) -{ - int mss = 0; - -#ifdef TCP_MAXSEG - int rc; - Socklen_t len; - assert(sock >= 0); - - /* query for MSS */ - len = sizeof(mss); - rc = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &mss, &len); - WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG"); -#endif - - return mss; -} - -/* ------------------------------------------------------------------- - * If inTCPWin > 0, set the TCP window size (via the socket buffer - * sizes) for inSock. Otherwise leave it as the system default. - * - * This must be called prior to calling listen() or connect() on - * the socket, for TCP window sizes > 64 KB to be effective. - * - * This now works on UNICOS also, by setting TCP_WINSHIFT. - * This now works on AIX, by enabling RFC1323. - * returns -1 on error, 0 on no error. - * ------------------------------------------------------------------- */ - -int -setsock_tcp_windowsize(int inSock, int inTCPWin, int inSend) -{ -#ifdef SO_SNDBUF - int rc; - int newTCPWin; - - assert(inSock >= 0); - - if (inTCPWin > 0) - { - -#ifdef TCP_WINSHIFT - - /* UNICOS requires setting the winshift explicitly */ - if (inTCPWin > 65535) - { - int winShift = 0; - int scaledWin = inTCPWin >> 16; - while (scaledWin > 0) - { - scaledWin >>= 1; - winShift++; - } - - /* set TCP window shift */ - rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINSHIFT, - (char *) &winShift, sizeof(winShift)); - if (rc < 0) - { - return rc; - } - /* - * Note: you cannot verify TCP window shift, since it returns a - * structure and not the same integer we use to set it. (ugh) - */ - } -#endif /* TCP_WINSHIFT */ - -#ifdef TCP_RFC1323 - /* - * On AIX, RFC 1323 extensions can be set system-wide, using the 'no' - * network options command. But we can also set them per-socket, so - * let's try just in case. - */ - if (inTCPWin > 65535) - { - /* enable RFC 1323 */ - int on = 1; - rc = setsockopt(inSock, IPPROTO_TCP, TCP_RFC1323, - (char *) &on, sizeof(on)); - if (rc < 0) - { - return rc; - } - } -#endif /* TCP_RFC1323 */ - - if (!inSend) - { - /* - * receive buffer -- set note: results are verified after - * connect() or listen(), since some OS's don't show the - * corrected value until then. - */ - newTCPWin = inTCPWin; - rc = setsockopt(inSock, SOL_SOCKET, SO_RCVBUF, - (char *) &newTCPWin, sizeof(newTCPWin)); - } else - { - /* - * send buffer -- set note: results are verified after connect() - * or listen(), since some OS's don't show the corrected value - * until then. - */ - newTCPWin = inTCPWin; - rc = setsockopt(inSock, SOL_SOCKET, SO_SNDBUF, - (char *) &newTCPWin, sizeof(newTCPWin)); - } - if (rc < 0) - { - return rc; - } - } -#endif /* SO_SNDBUF */ - - return 0; -} - -/* ------------------------------------------------------------------- - * returns the TCP window size (on the sending buffer, SO_SNDBUF), - * or -1 on error. - * ------------------------------------------------------------------- */ - -int -getsock_tcp_windowsize(int inSock, int inSend) -{ - int theTCPWin = 0; - -#ifdef SO_SNDBUF - int rc; - Socklen_t len; - - /* send buffer -- query for buffer size */ - len = sizeof(theTCPWin); - if (inSend) - { - rc = getsockopt(inSock, SOL_SOCKET, SO_SNDBUF, - (char *) &theTCPWin, &len); - } else - { - rc = getsockopt(inSock, SOL_SOCKET, SO_RCVBUF, - (char *) &theTCPWin, &len); - } - if (rc < 0) - { - return rc; - } -#endif - - return theTCPWin; -} diff --git a/src/tcp_window_size.c b/src/tcp_window_size.c index fdec82f..b019afd 100644 --- a/src/tcp_window_size.c +++ b/src/tcp_window_size.c @@ -57,14 +57,10 @@ * removed some cruft */ +#include #include #include -#ifdef __cplusplus -extern "C" -{ -#endif - /* ------------------------------------------------------------------- * If bufsize > 0, set the TCP window size (via the socket buffer * sizes) for sock. Otherwise leave it as the system default. @@ -75,104 +71,55 @@ extern "C" * This now works on UNICOS also, by setting TCP_WINSHIFT. * This now works on AIX, by enabling RFC1323. * returns -1 on error, 0 on no error. - * ------------------------------------------------------------------- */ + * ------------------------------------------------------------------- + */ - int - set_tcp_windowsize(int sock, int bufsize, int dir) +int +set_tcp_windowsize(int sock, int bufsize, int dir) +{ + int rc; + int newbufsize; + + assert(sock >= 0); + + if (bufsize > 0) { -#ifdef SO_SNDBUF - int rc; - int newbufsize; - - assert(sock >= 0); - - if (bufsize > 0) - { - -#ifdef TCP_WINSHIFT - /* XXX: audit -- do we care about UNICOS? */ - /* UNICOS requires setting the winshift explicitly */ - if (bufsize > 65535) - { - int winshift = 0; - int scaledwin = bufsize >> 16; - while (scaledwin > 0) - { - scaledwin >>= 1; - winshift++; - } - - /* set TCP window shift */ - rc = setsockopt(sock, IPPROTO_TCP, TCP_WINSHIFT, - (char *) &winshift, sizeof(winshift)); - if (rc < 0) - return rc; - - /* - * Note: you cannot verify TCP window shift, since it returns - * a structure and not the same integer we use to set it. - * (ugh) - */ - } -#endif /* TCP_WINSHIFT */ - -#ifdef TCP_RFC1323 - /* - * On AIX, RFC 1323 extensions can be set system-wide, using the - * 'no' network options command. But we can also set them - * per-socket, so let's try just in case. - */ - if (bufsize > 65535) - { - /* enable RFC 1323 */ - int on = 1; - rc = setsockopt(sock, IPPROTO_TCP, TCP_RFC1323, - (char *) &on, sizeof(on)); - if (rc < 0) - return rc; - } -#endif /* TCP_RFC1323 */ - - /* - * note: results are verified after connect() or listen(), since - * some OS's don't show the corrected value until then. - */ - newbufsize = bufsize; - rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize); - if (rc < 0) - return rc; - } -#endif /* SO_SNDBUF */ - - return 0; + /* + * note: results are verified after connect() or listen(), since + * some OS's don't show the corrected value until then. + */ + printf("Setting TCP buffer to size: %d\n", bufsize); + newbufsize = bufsize; + rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize); + if (rc < 0) + return rc; + } else { + printf("Using default TCP buffer size and assuming OS will do autotuning \n"); } + return 0; +} + /* ------------------------------------------------------------------- * returns the TCP window size (on the sending buffer, SO_SNDBUF), * or -1 on error. * ------------------------------------------------------------------- */ - int - getsock_tcp_windowsize(int sock, int dir) - { - int bufsize = 0; +int +get_tcp_windowsize(int sock, int dir) +{ + int bufsize = 0; -#ifdef SO_SNDBUF - int rc; - socklen_t len; + int rc; + socklen_t len; - /* send buffer -- query for buffer size */ - len = sizeof bufsize; - rc = getsockopt(sock, SOL_SOCKET, dir, (char *) &bufsize, &len); + /* send buffer -- query for buffer size */ + len = sizeof bufsize; + rc = getsockopt(sock, SOL_SOCKET, dir, (char *) &bufsize, &len); - if (rc < 0) - return rc; -#endif + if (rc < 0) + return rc; - return bufsize; - } + return bufsize; +} -#ifdef __cplusplus -} /* end extern "C" */ - -#endif diff --git a/src/tcp_window_size.h b/src/tcp_window_size.h index 4dc529d..2051f56 100644 --- a/src/tcp_window_size.h +++ b/src/tcp_window_size.h @@ -1,2 +1,2 @@ int set_tcp_windowsize(int sock, int bufsize, int dir); -int getsock_tcp_windowsize(int sock, int dir); +int get_tcp_windowsize(int sock, int dir);