From e170832926e9defcc3f05d1eec5c587f99ad5824 Mon Sep 17 00:00:00 2001 From: sethdelliott Date: Wed, 16 Mar 2011 17:43:25 +0000 Subject: [PATCH] Added working TCP_INFO code (only displays retransmits for now) --- src/iperf_api.c | 29 ++++++++++++++++------------- src/iperf_api.h | 4 ++-- src/tcp_info.c | 47 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/iperf_api.c b/src/iperf_api.c index a178adb..ffa71ec 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -341,7 +341,11 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) test->settings->unit_format = *optarg; break; case 'T': +#if !defined(linux) && !defined(__FreeBSD__) + warning("TCP_INFO (-T) is not supported on your current platform"); +#else test->tcp_info = 1; +#endif break; case '6': test->settings->domain = AF_INET6; @@ -918,7 +922,7 @@ parse_results(struct iperf_test *test, char *results) /*************************************************************/ /** * add_to_interval_list -- adds new interval to the interval_list - * + * XXX: Interval lists should use SLIST implementation fro queue */ void @@ -1180,7 +1184,7 @@ iperf_stats_callback(struct iperf_test * test) temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time); //temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time); if (test->tcp_info) - get_tcpinfo(test, &temp); + get_tcpinfo(sp, &temp); add_to_interval_list(rp, &temp); rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0; @@ -1231,12 +1235,10 @@ iperf_reporter_callback(struct iperf_test * test) start_time = timeval_diff(&sp->result->start_time,&ip->interval_start_time); end_time = timeval_diff(&sp->result->start_time,&ip->interval_end_time); printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf); - -#if defined(linux) || defined(__FreeBSD__) /* is it usful to figure out a way so sum * TCP_info acrross multiple streams? */ - if (test->tcp_info) - print_tcpinfo(ip); -#endif } + if (test->tcp_info) + print_tcpinfo(test); +// print_tcpinfo(ip); break; case DISPLAY_RESULTS: /* print final summary for all intervals */ @@ -1265,12 +1267,12 @@ iperf_reporter_callback(struct iperf_test * test) printf(" Sent\n"); printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf); -#if defined(linux) || defined(__FreeBSD__) if (test->tcp_info) { - ip = sp->result->last_interval_results; - print_tcpinfo(ip); +// ip = sp->result->last_interval_results; +// print_tcpinfo(ip); + print_tcpinfo(test); } -#endif + } else { printf(report_bw_jitter_loss_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->jitter * 1000, sp->cnt_error, @@ -1345,10 +1347,11 @@ print_interval_results(struct iperf_test * test, struct iperf_stream * sp) printf(report_bw_format, sp->socket, st, et, ubuf, nbuf); -#if defined(linux) || defined(__FreeBSD__) +/* doing aggregate TCP_INFO reporting for now... if (test->tcp_info) print_tcpinfo(ir); -#endif +*/ + } /**************************************************************************/ diff --git a/src/iperf_api.h b/src/iperf_api.h index d2e49d9..447598a 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -89,8 +89,8 @@ int iperf_init_stream(struct iperf_stream *, struct iperf_test *); */ void iperf_free_stream(struct iperf_stream * sp); -void get_tcpinfo(struct iperf_test *test, struct iperf_interval_results *rp); -void print_tcpinfo(struct iperf_interval_results *); +void get_tcpinfo(struct iperf_stream *, struct iperf_interval_results *); +void print_tcpinfo(struct iperf_test *); void build_tcpinfo_message(struct iperf_interval_results *r, char *message); void print_interval_results(struct iperf_test * test, struct iperf_stream *sp); diff --git a/src/tcp_info.c b/src/tcp_info.c index 05c901d..2f07d9a 100644 --- a/src/tcp_info.c +++ b/src/tcp_info.c @@ -5,6 +5,7 @@ * Brian Tierney, ESnet (bltierney@es.net) * * Note that this is only really useful on Linux. + * XXX: only standard on linux versions 2.4 and later # * FreeBSD has a limitted implementation that only includes the following: * tcpi_snd_ssthresh, tcpi_snd_cwnd, tcpi_rcv_space, tcpi_rtt @@ -16,7 +17,6 @@ * I think MS Windows does support TCP_INFO, but iperf3 does not currently support Windows. */ - #include #include #include @@ -31,39 +31,59 @@ /*************************************************************/ void -get_tcpinfo(struct iperf_test *test, struct iperf_interval_results *rp) +get_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *rp) { #if defined(linux) || defined(__FreeBSD__) - socklen_t tcp_info_length; - struct iperf_stream *sp = SLIST_FIRST(&test->streams); + socklen_t tcp_info_length; +// struct tcp_info tempinfo; +// struct iperf_stream *sp = SLIST_FIRST(&test->streams); tcp_info_length = sizeof(struct tcp_info); - //printf("getting TCP_INFO for socket %d \n", sp->socket); + if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&rp->tcpInfo, &tcp_info_length) < 0) { - perror("getsockopt"); + perror("getsockopt"); } - /* for debugging */ - //printf(" got TCP_INFO: %d, %d, %d, %d\n", rp->tcpInfo.tcpi_snd_cwnd, - // rp->tcpInfo.tcpi_snd_ssthresh, rp->tcpInfo.tcpi_rcv_space, rp->tcpInfo.tcpi_rtt); - return; -#else - return; + +/* + for (sp = SLIST_NEXT(sp, streams); sp != SLIST_END(&test->streams); + sp = SLIST_NEXT(sp, streams)) { + tcp_info_length = sizeof(struct tcp_info); + if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *) &tempinfo, &tcp_info_length) < 0) { + perror("getsockopt"); + } + rp->tcpInfo.tcpi_retransmits += tempinfo.tcpi_retransmits; + } +*/ #endif + return; } /*************************************************************/ +//print_tcpinfo(struct iperf_interval_results *r) void -print_tcpinfo(struct iperf_interval_results *r) +print_tcpinfo(struct iperf_test *test) { + long int retransmits = 0; + struct iperf_stream *sp; #if defined(linux) + SLIST_FOREACH(sp, &test->streams, streams) { + retransmits += sp->result->last_interval_results.tcpInfo.tcpi_retransmits; + } + printf("TCP Info\n"); + printf(" Retransmits: %ld\n", retransmits); + +/* old test print_tcpinfo code printf(report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rcv_ssthresh, r->tcpInfo.tcpi_unacked, r->tcpInfo.tcpi_sacked, r->tcpInfo.tcpi_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets, r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering); +*/ #endif #if defined(__FreeBSD__) +/* printf(report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt); +*/ #endif } @@ -82,6 +102,5 @@ build_tcpinfo_message(struct iperf_interval_results *r, char *message) sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt); #endif - }