Added working TCP_INFO code (only displays retransmits for now)

This commit is contained in:
sethdelliott 2011-03-16 17:43:25 +00:00
parent f970ce8ecd
commit e170832926
3 changed files with 51 additions and 29 deletions

View File

@ -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
*/
}
/**************************************************************************/

View File

@ -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);

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>
@ -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
}