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>