2009-10-23 22:30:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* routines related to collection TCP_INFO using getsockopt()
|
|
|
|
*
|
|
|
|
* Brian Tierney, ESnet (bltierney@es.net)
|
|
|
|
*
|
2009-10-26 14:34:41 +00:00
|
|
|
* Note that this is only really useful on Linux.
|
|
|
|
#
|
|
|
|
* FreeBSD has a limitted implementation that only includes the following:
|
|
|
|
* tcpi_snd_ssthresh, tcpi_snd_cwnd, tcpi_rcv_space, tcpi_rtt
|
|
|
|
* Based on information on http://wiki.freebsd.org/8.0TODO, I dont think this will be
|
|
|
|
* fixed before v8.1 at the earliest.
|
|
|
|
*
|
|
|
|
* OSX has no support.
|
|
|
|
*
|
|
|
|
* I think MS Windows does support TCP_INFO, but iperf3 does not currently support Windows.
|
2009-10-23 22:30:17 +00:00
|
|
|
*/
|
|
|
|
|
2009-10-24 21:15:04 +00:00
|
|
|
|
2009-10-23 22:30:17 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
|
|
|
#include "iperf_api.h"
|
|
|
|
#include "locale.h"
|
|
|
|
|
|
|
|
/*************************************************************/
|
|
|
|
void
|
2009-10-23 22:58:32 +00:00
|
|
|
get_tcpinfo(struct iperf_test *test, struct iperf_interval_results *rp)
|
2009-10-23 22:30:17 +00:00
|
|
|
{
|
|
|
|
#if defined(linux) || defined(__FreeBSD__)
|
|
|
|
socklen_t tcp_info_length;
|
|
|
|
struct iperf_stream *sp = test->streams;
|
|
|
|
|
2009-11-16 01:58:22 +00:00
|
|
|
tcp_info_length = sizeof(struct tcp_info);
|
2009-10-23 22:30:17 +00:00
|
|
|
//printf("getting TCP_INFO for socket %d \n", sp->socket);
|
2009-11-16 01:58:22 +00:00
|
|
|
if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&rp->tcpInfo, &tcp_info_length) < 0) {
|
2009-10-23 22:30:17 +00:00
|
|
|
perror("getsockopt");
|
|
|
|
}
|
2009-11-16 01:58:22 +00:00
|
|
|
/* for debugging */
|
2009-10-23 22:58:32 +00:00
|
|
|
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;
|
2009-10-23 22:30:17 +00:00
|
|
|
#else
|
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************/
|
|
|
|
void
|
|
|
|
print_tcpinfo(struct iperf_interval_results *r)
|
|
|
|
{
|
|
|
|
#if defined(linux)
|
|
|
|
printf(report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh,
|
2009-11-13 19:20:52 +00:00
|
|
|
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);
|
2009-10-23 22:30:17 +00:00
|
|
|
#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
|
2009-10-23 22:58:32 +00:00
|
|
|
}
|
2009-10-23 22:30:17 +00:00
|
|
|
|
|
|
|
|
2009-10-23 22:58:32 +00:00
|
|
|
/*************************************************************/
|
|
|
|
void
|
|
|
|
build_tcpinfo_message(struct iperf_interval_results *r, char *message)
|
|
|
|
{
|
2009-11-16 01:58:22 +00:00
|
|
|
printf("in build_tcpinfo_message \n");
|
2009-10-23 22:58:32 +00:00
|
|
|
#if defined(linux)
|
|
|
|
sprintf(message, 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,
|
2009-11-13 19:20:52 +00:00
|
|
|
r->tcpInfo.tcpi_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets,
|
|
|
|
r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering);
|
2009-10-23 22:58:32 +00:00
|
|
|
#endif
|
|
|
|
#if defined(__FreeBSD__)
|
|
|
|
sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd,
|
2009-11-13 19:20:52 +00:00
|
|
|
r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt);
|
2009-10-23 22:58:32 +00:00
|
|
|
#endif
|
2009-10-23 22:30:17 +00:00
|
|
|
|
|
|
|
}
|
2009-11-16 01:58:22 +00:00
|
|
|
|