|
version 1.1, 2016/10/18 13:28:18
|
version 1.1.1.3, 2023/09/27 11:14:54
|
|
Line 1
|
Line 1
|
| /* |
/* |
| * iperf, Copyright (c) 2014, The Regents of the University of | * iperf, Copyright (c) 2014, 2017, The Regents of the University of |
| * California, through Lawrence Berkeley National Laboratory (subject |
* California, through Lawrence Berkeley National Laboratory (subject |
| * to receipt of any required approvals from the U.S. Dept. of |
* to receipt of any required approvals from the U.S. Dept. of |
| * Energy). All rights reserved. |
* Energy). All rights reserved. |
|
Line 27
|
Line 27
|
| |
|
| /* |
/* |
| * routines related to collection TCP_INFO using getsockopt() |
* routines related to collection TCP_INFO using getsockopt() |
| * | * |
| * Brian Tierney, ESnet (bltierney@es.net) |
* Brian Tierney, ESnet (bltierney@es.net) |
| * | * |
| * Note that this is only really useful on Linux. |
* Note that this is only really useful on Linux. |
| * XXX: only standard on linux versions 2.4 and later |
* XXX: only standard on linux versions 2.4 and later |
| # |
# |
| * FreeBSD has a limitted implementation that only includes the following: | * FreeBSD has a limited implementation that only includes the following: |
| * tcpi_snd_ssthresh, tcpi_snd_cwnd, tcpi_rcv_space, tcpi_rtt |
* 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 |
* Based on information on http://wiki.freebsd.org/8.0TODO, I dont think this will be |
| * fixed before v8.1 at the earliest. |
* fixed before v8.1 at the earliest. |
|
Line 48
|
Line 48
|
| #include <sys/param.h> |
#include <sys/param.h> |
| #include <sys/types.h> |
#include <sys/types.h> |
| #include <sys/socket.h> |
#include <sys/socket.h> |
| #include <netinet/tcp.h> |
|
| #include <string.h> |
#include <string.h> |
| #include <netinet/in.h> |
#include <netinet/in.h> |
| #include <errno.h> |
#include <errno.h> |
|
Line 61
|
Line 60
|
| int |
int |
| has_tcpinfo(void) |
has_tcpinfo(void) |
| { |
{ |
| #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) \ | #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) \ |
| && defined(TCP_INFO) |
&& defined(TCP_INFO) |
| return 1; |
return 1; |
| #else |
#else |
|
Line 76 has_tcpinfo_retransmits(void)
|
Line 75 has_tcpinfo_retransmits(void)
|
| #if defined(linux) && defined(TCP_MD5SIG) |
#if defined(linux) && defined(TCP_MD5SIG) |
| /* TCP_MD5SIG doesn't actually have anything to do with TCP |
/* TCP_MD5SIG doesn't actually have anything to do with TCP |
| ** retransmits, it just showed up in the same rev of the header |
** retransmits, it just showed up in the same rev of the header |
| ** file. If it's present then struct tcp_info has the | ** file. If it's present then struct tcp_info has the |
| ** tcpi_total_retrans field that we need; if not, not. |
** tcpi_total_retrans field that we need; if not, not. |
| */ |
*/ |
| return 1; |
return 1; |
| #else |
#else |
| #if defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
#if defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
| return 1; /* Should work now */ |
return 1; /* Should work now */ |
| #elif defined(__NetBSD__) && defined(TCP_INFO) | #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO) |
| return 1; |
return 1; |
| #else |
#else |
| return 0; |
return 0; |
|
Line 95 has_tcpinfo_retransmits(void)
|
Line 94 has_tcpinfo_retransmits(void)
|
| void |
void |
| save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp) |
save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp) |
| { |
{ |
| #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) && \ | #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ |
| defined(TCP_INFO) |
defined(TCP_INFO) |
| socklen_t tcp_info_length = sizeof(struct tcp_info); |
socklen_t tcp_info_length = sizeof(struct tcp_info); |
| |
|
|
Line 119 get_total_retransmits(struct iperf_interval_results *i
|
Line 118 get_total_retransmits(struct iperf_interval_results *i
|
| return irp->tcpInfo.tcpi_total_retrans; |
return irp->tcpInfo.tcpi_total_retrans; |
| #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
#elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
| return irp->tcpInfo.tcpi_snd_rexmitpack; |
return irp->tcpInfo.tcpi_snd_rexmitpack; |
| #elif defined(__NetBSD__) && defined(TCP_INFO) | #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO) |
| return irp->tcpInfo.tcpi_snd_rexmitpack; |
return irp->tcpInfo.tcpi_snd_rexmitpack; |
| #else |
#else |
| return -1; |
return -1; |
|
Line 134 long
|
Line 133 long
|
| get_snd_cwnd(struct iperf_interval_results *irp) |
get_snd_cwnd(struct iperf_interval_results *irp) |
| { |
{ |
| #if defined(linux) && defined(TCP_MD5SIG) |
#if defined(linux) && defined(TCP_MD5SIG) |
| return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss; | return (long)irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss; |
| #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
#elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
| return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss; | return irp->tcpInfo.tcpi_snd_cwnd; |
| #elif defined(__NetBSD__) && defined(TCP_INFO) |
#elif defined(__NetBSD__) && defined(TCP_INFO) |
| return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss; | return (long)irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss; |
| | #elif defined(__OpenBSD__) && defined(TCP_INFO) |
| | return irp->tcpInfo.tcpi_snd_cwnd; |
| #else |
#else |
| return -1; |
return -1; |
| #endif |
#endif |
|
Line 146 get_snd_cwnd(struct iperf_interval_results *irp)
|
Line 147 get_snd_cwnd(struct iperf_interval_results *irp)
|
| |
|
| /*************************************************************/ |
/*************************************************************/ |
| /* |
/* |
| |
* Return snd_wnd in octets. |
| |
*/ |
| |
long |
| |
get_snd_wnd(struct iperf_interval_results *irp) |
| |
{ |
| |
#if !defined(HAVE_TCP_INFO_SND_WND) |
| |
return -1; |
| |
#elif defined(linux) && defined(TCP_MD5SIG) |
| |
return irp->tcpInfo.tcpi_snd_wnd; |
| |
#elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
| |
return irp->tcpInfo.tcpi_snd_wnd; |
| |
#elif defined(__NetBSD__) && defined(TCP_INFO) |
| |
return (long)irp->tcpInfo.tcpi_snd_wnd * irp->tcpInfo.tcpi_snd_mss; |
| |
#elif defined(__OpenBSD__) && defined(TCP_INFO) |
| |
return irp->tcpInfo.tcpi_snd_wnd; |
| |
#else |
| |
return -1; |
| |
#endif |
| |
} |
| |
|
| |
/*************************************************************/ |
| |
/* |
| * Return rtt in usec. |
* Return rtt in usec. |
| */ |
*/ |
| long |
long |
|
Line 155 get_rtt(struct iperf_interval_results *irp)
|
Line 178 get_rtt(struct iperf_interval_results *irp)
|
| return irp->tcpInfo.tcpi_rtt; |
return irp->tcpInfo.tcpi_rtt; |
| #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
#elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
| return irp->tcpInfo.tcpi_rtt; |
return irp->tcpInfo.tcpi_rtt; |
| #elif defined(__NetBSD__) && defined(TCP_INFO) | #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO) |
| return irp->tcpInfo.tcpi_rtt; |
return irp->tcpInfo.tcpi_rtt; |
| #else |
#else |
| return -1; |
return -1; |
|
Line 163 get_rtt(struct iperf_interval_results *irp)
|
Line 186 get_rtt(struct iperf_interval_results *irp)
|
| } |
} |
| |
|
| /*************************************************************/ |
/*************************************************************/ |
| |
/* |
| |
* Return rttvar in usec. |
| |
*/ |
| |
long |
| |
get_rttvar(struct iperf_interval_results *irp) |
| |
{ |
| |
#if defined(linux) && defined(TCP_MD5SIG) |
| |
return irp->tcpInfo.tcpi_rttvar; |
| |
#elif defined(__FreeBSD__) && __FreeBSD_version >= 600000 |
| |
return irp->tcpInfo.tcpi_rttvar; |
| |
#elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO) |
| |
return irp->tcpInfo.tcpi_rttvar; |
| |
#else |
| |
return -1; |
| |
#endif |
| |
} |
| |
|
| |
/*************************************************************/ |
| |
/* |
| |
* Return PMTU in bytes. |
| |
*/ |
| |
long |
| |
get_pmtu(struct iperf_interval_results *irp) |
| |
{ |
| |
#if defined(linux) && defined(TCP_MD5SIG) |
| |
return irp->tcpInfo.tcpi_pmtu; |
| |
#else |
| |
return -1; |
| |
#endif |
| |
} |
| |
|
| |
/*************************************************************/ |
| void |
void |
| build_tcpinfo_message(struct iperf_interval_results *r, char *message) |
build_tcpinfo_message(struct iperf_interval_results *r, char *message) |
| { |
{ |
| #if defined(linux) | #if defined(linux) && defined(TCP_INFO) |
| sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh, |
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, |
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_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets, |
| r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering); |
r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering); |
| #endif |
#endif |
| #if defined(__FreeBSD__) | #if (defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO) |
| sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, | |
| r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt); | |
| #endif | |
| #if defined(__NetBSD__) && defined(TCP_INFO) | |
| sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, |
sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, |
| r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt); |
r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt); |
| #endif |
#endif |