Annotation of embedaddon/iperf/src/tcp_info.c, revision 1.1
1.1 ! misho 1: /*
! 2: * iperf, Copyright (c) 2014, The Regents of the University of
! 3: * California, through Lawrence Berkeley National Laboratory (subject
! 4: * to receipt of any required approvals from the U.S. Dept. of
! 5: * Energy). All rights reserved.
! 6: *
! 7: * If you have questions about your rights to use or distribute this
! 8: * software, please contact Berkeley Lab's Technology Transfer
! 9: * Department at TTD@lbl.gov.
! 10: *
! 11: * NOTICE. This software is owned by the U.S. Department of Energy.
! 12: * As such, the U.S. Government has been granted for itself and others
! 13: * acting on its behalf a paid-up, nonexclusive, irrevocable,
! 14: * worldwide license in the Software to reproduce, prepare derivative
! 15: * works, and perform publicly and display publicly. Beginning five
! 16: * (5) years after the date permission to assert copyright is obtained
! 17: * from the U.S. Department of Energy, and subject to any subsequent
! 18: * five (5) year renewals, the U.S. Government is granted for itself
! 19: * and others acting on its behalf a paid-up, nonexclusive,
! 20: * irrevocable, worldwide license in the Software to reproduce,
! 21: * prepare derivative works, distribute copies to the public, perform
! 22: * publicly and display publicly, and to permit others to do so.
! 23: *
! 24: * This code is distributed under a BSD style license, see the LICENSE
! 25: * file for complete information.
! 26: */
! 27:
! 28: /*
! 29: * routines related to collection TCP_INFO using getsockopt()
! 30: *
! 31: * Brian Tierney, ESnet (bltierney@es.net)
! 32: *
! 33: * Note that this is only really useful on Linux.
! 34: * XXX: only standard on linux versions 2.4 and later
! 35: #
! 36: * FreeBSD has a limitted implementation that only includes the following:
! 37: * tcpi_snd_ssthresh, tcpi_snd_cwnd, tcpi_rcv_space, tcpi_rtt
! 38: * Based on information on http://wiki.freebsd.org/8.0TODO, I dont think this will be
! 39: * fixed before v8.1 at the earliest.
! 40: *
! 41: * OSX has no support.
! 42: *
! 43: * I think MS Windows does support TCP_INFO, but iperf3 does not currently support Windows.
! 44: */
! 45:
! 46: #include <stdio.h>
! 47: #include <stdlib.h>
! 48: #include <sys/param.h>
! 49: #include <sys/types.h>
! 50: #include <sys/socket.h>
! 51: #include <netinet/tcp.h>
! 52: #include <string.h>
! 53: #include <netinet/in.h>
! 54: #include <errno.h>
! 55:
! 56: #include "iperf.h"
! 57: #include "iperf_api.h"
! 58: #include "iperf_locale.h"
! 59:
! 60: /*************************************************************/
! 61: int
! 62: has_tcpinfo(void)
! 63: {
! 64: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) \
! 65: && defined(TCP_INFO)
! 66: return 1;
! 67: #else
! 68: return 0;
! 69: #endif
! 70: }
! 71:
! 72: /*************************************************************/
! 73: int
! 74: has_tcpinfo_retransmits(void)
! 75: {
! 76: #if defined(linux) && defined(TCP_MD5SIG)
! 77: /* TCP_MD5SIG doesn't actually have anything to do with TCP
! 78: ** retransmits, it just showed up in the same rev of the header
! 79: ** file. If it's present then struct tcp_info has the
! 80: ** tcpi_total_retrans field that we need; if not, not.
! 81: */
! 82: return 1;
! 83: #else
! 84: #if defined(__FreeBSD__) && __FreeBSD_version >= 600000
! 85: return 1; /* Should work now */
! 86: #elif defined(__NetBSD__) && defined(TCP_INFO)
! 87: return 1;
! 88: #else
! 89: return 0;
! 90: #endif
! 91: #endif
! 92: }
! 93:
! 94: /*************************************************************/
! 95: void
! 96: save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp)
! 97: {
! 98: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) && \
! 99: defined(TCP_INFO)
! 100: socklen_t tcp_info_length = sizeof(struct tcp_info);
! 101:
! 102: if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&irp->tcpInfo, &tcp_info_length) < 0)
! 103: iperf_err(sp->test, "getsockopt - %s", strerror(errno));
! 104:
! 105: if (sp->test->debug) {
! 106: printf("tcpi_snd_cwnd %u tcpi_snd_mss %u tcpi_rtt %u\n",
! 107: irp->tcpInfo.tcpi_snd_cwnd, irp->tcpInfo.tcpi_snd_mss,
! 108: irp->tcpInfo.tcpi_rtt);
! 109: }
! 110:
! 111: #endif
! 112: }
! 113:
! 114: /*************************************************************/
! 115: long
! 116: get_total_retransmits(struct iperf_interval_results *irp)
! 117: {
! 118: #if defined(linux) && defined(TCP_MD5SIG)
! 119: return irp->tcpInfo.tcpi_total_retrans;
! 120: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
! 121: return irp->tcpInfo.tcpi_snd_rexmitpack;
! 122: #elif defined(__NetBSD__) && defined(TCP_INFO)
! 123: return irp->tcpInfo.tcpi_snd_rexmitpack;
! 124: #else
! 125: return -1;
! 126: #endif
! 127: }
! 128:
! 129: /*************************************************************/
! 130: /*
! 131: * Return snd_cwnd in octets.
! 132: */
! 133: long
! 134: get_snd_cwnd(struct iperf_interval_results *irp)
! 135: {
! 136: #if defined(linux) && defined(TCP_MD5SIG)
! 137: return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
! 138: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
! 139: return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
! 140: #elif defined(__NetBSD__) && defined(TCP_INFO)
! 141: return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
! 142: #else
! 143: return -1;
! 144: #endif
! 145: }
! 146:
! 147: /*************************************************************/
! 148: /*
! 149: * Return rtt in usec.
! 150: */
! 151: long
! 152: get_rtt(struct iperf_interval_results *irp)
! 153: {
! 154: #if defined(linux) && defined(TCP_MD5SIG)
! 155: return irp->tcpInfo.tcpi_rtt;
! 156: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
! 157: return irp->tcpInfo.tcpi_rtt;
! 158: #elif defined(__NetBSD__) && defined(TCP_INFO)
! 159: return irp->tcpInfo.tcpi_rtt;
! 160: #else
! 161: return -1;
! 162: #endif
! 163: }
! 164:
! 165: /*************************************************************/
! 166: void
! 167: build_tcpinfo_message(struct iperf_interval_results *r, char *message)
! 168: {
! 169: #if defined(linux)
! 170: sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh,
! 171: r->tcpInfo.tcpi_rcv_ssthresh, r->tcpInfo.tcpi_unacked, r->tcpInfo.tcpi_sacked,
! 172: r->tcpInfo.tcpi_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets,
! 173: r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering);
! 174: #endif
! 175: #if defined(__FreeBSD__)
! 176: sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd,
! 177: r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt);
! 178: #endif
! 179: #if defined(__NetBSD__) && defined(TCP_INFO)
! 180: sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd,
! 181: r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt);
! 182: #endif
! 183: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>