File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / iperf / src / iperf.h
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:14:54 2023 UTC (8 months, 3 weeks ago) by misho
Branches: iperf, MAIN
CVS tags: v3_15, HEAD
Version 3.15

    1: /*
    2:  * iperf, Copyright (c) 2014-2020, 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: #ifndef __IPERF_H
   28: #define __IPERF_H
   29: 
   30: #include "iperf_config.h"
   31: 
   32: #include <sys/time.h>
   33: #include <sys/types.h>
   34: #ifdef HAVE_STDINT_H
   35: #include <stdint.h>
   36: #endif
   37: #include <sys/select.h>
   38: #include <sys/socket.h>
   39: #ifndef _GNU_SOURCE
   40: # define _GNU_SOURCE
   41: #endif
   42: #ifdef HAVE_LINUX_TCP_H
   43: #include <linux/tcp.h>
   44: #else
   45: #include <netinet/tcp.h>
   46: #endif
   47: #include <net/if.h> // for IFNAMSIZ
   48: 
   49: #if defined(HAVE_CPUSET_SETAFFINITY)
   50: #include <sys/param.h>
   51: #include <sys/cpuset.h>
   52: #endif /* HAVE_CPUSET_SETAFFINITY */
   53: 
   54: #if defined(HAVE_INTTYPES_H)
   55: # include <inttypes.h>
   56: #else
   57: # ifndef PRIu64
   58: #  if sizeof(long) == 8
   59: #   define PRIu64		"lu"
   60: #  else
   61: #   define PRIu64		"llu"
   62: #  endif
   63: # endif
   64: #endif
   65: 
   66: #include "timer.h"
   67: #include "queue.h"
   68: #include "cjson.h"
   69: #include "iperf_time.h"
   70: 
   71: #if defined(HAVE_SSL)
   72: #include <openssl/bio.h>
   73: #include <openssl/evp.h>
   74: #endif // HAVE_SSL
   75: 
   76: #if !defined(__IPERF_API_H)
   77: typedef uint64_t iperf_size_t;
   78: #endif // __IPERF_API_H
   79: 
   80: struct iperf_interval_results
   81: {
   82:     iperf_size_t bytes_transferred; /* bytes transferred in this interval */
   83:     struct iperf_time interval_start_time;
   84:     struct iperf_time interval_end_time;
   85:     float     interval_duration;
   86: 
   87:     /* for UDP */
   88:     int64_t   interval_packet_count;
   89:     int64_t   interval_outoforder_packets;
   90:     int64_t   interval_cnt_error;
   91:     int64_t   packet_count;
   92:     double    jitter;
   93:     int64_t   outoforder_packets;
   94:     int64_t   cnt_error;
   95: 
   96:     int omitted;
   97: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \
   98: 	defined(TCP_INFO)
   99:     struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) for Linux, {Free,Net,Open}BSD */
  100: #else
  101:     /* Just placeholders, never accessed. */
  102:     char *tcpInfo;
  103: #endif
  104:     long interval_retrans;
  105:     long snd_cwnd;
  106:     long snd_wnd;
  107:     TAILQ_ENTRY(iperf_interval_results) irlistentries;
  108:     void     *custom_data;
  109:     long rtt;
  110:     long rttvar;
  111:     long pmtu;
  112: };
  113: 
  114: struct iperf_stream_result
  115: {
  116:     iperf_size_t bytes_received;
  117:     iperf_size_t bytes_sent;
  118:     iperf_size_t bytes_received_this_interval;
  119:     iperf_size_t bytes_sent_this_interval;
  120:     iperf_size_t bytes_sent_omit;
  121:     long stream_prev_total_retrans;
  122:     long stream_retrans;
  123:     long stream_max_rtt;
  124:     long stream_min_rtt;
  125:     long stream_sum_rtt;
  126:     int stream_count_rtt;
  127:     long stream_max_snd_cwnd;
  128:     long stream_max_snd_wnd;
  129:     struct iperf_time start_time;
  130:     struct iperf_time end_time;
  131:     struct iperf_time start_time_fixed;
  132:     double sender_time;
  133:     double receiver_time;
  134:     TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
  135:     void     *data;
  136: };
  137: 
  138: #define COOKIE_SIZE 37		/* size of an ascii uuid */
  139: struct iperf_settings
  140: {
  141:     int       domain;               /* AF_INET or AF_INET6 */
  142:     int       socket_bufsize;       /* window size for TCP */
  143:     int       blksize;              /* size of read/writes (-l) */
  144:     iperf_size_t  rate;                 /* target data rate for application pacing*/
  145:     iperf_size_t  bitrate_limit;   /* server's maximum allowed total data rate for all streams*/
  146:     double        bitrate_limit_interval;  /* interval for averaging total data rate */
  147:     int           bitrate_limit_stats_per_interval;     /* calculated number of stats periods for averaging total data rate */
  148:     uint64_t  fqrate;               /* target data rate for FQ pacing*/
  149:     int	      pacing_timer;	    /* pacing timer in microseconds */
  150:     int       burst;                /* packets per burst */
  151:     int       mss;                  /* for TCP MSS */
  152:     int       ttl;                  /* IP TTL option */
  153:     int       tos;                  /* type of service bit */
  154:     int       flowlabel;            /* IPv6 flow label */
  155:     iperf_size_t bytes;             /* number of bytes to send */
  156:     iperf_size_t blocks;            /* number of blocks (packets) to send */
  157:     char      unit_format;          /* -f */
  158:     int       num_ostreams;         /* SCTP initmsg settings */
  159:     int       dont_fragment;        /* Whether to set IP flag Do-Not_Fragment */
  160: #if defined(HAVE_SSL)
  161:     char      *authtoken;           /* Authentication token */
  162:     char      *client_username;
  163:     char      *client_password;
  164:     EVP_PKEY  *client_rsa_pubkey;
  165: #endif // HAVE_SSL
  166:     int	      connect_timeout;	    /* socket connection timeout, in ms */
  167:     int       idle_timeout;         /* server idle time timeout */
  168:     unsigned int snd_timeout; /* Timeout for sending tcp messages in active mode, in us */
  169:     struct iperf_time rcv_timeout;  /* Timeout for receiving messages in active mode, in us */
  170: };
  171: 
  172: struct iperf_test;
  173: 
  174: struct iperf_stream
  175: {
  176:     struct iperf_test* test;
  177: 
  178:     /* configurable members */
  179:     int       local_port;
  180:     int       remote_port;
  181:     int       socket;
  182:     int       id;
  183:     int       sender;
  184: 	/* XXX: is settings just a pointer to the same struct in iperf_test? if not,
  185: 		should it be? */
  186:     struct iperf_settings *settings;	/* pointer to structure settings */
  187: 
  188:     /* non configurable members */
  189:     struct iperf_stream_result *result;	/* structure pointer to result */
  190:     Timer     *send_timer;
  191:     int       green_light;
  192:     int       buffer_fd;	/* data to send, file descriptor */
  193:     char      *buffer;		/* data to send, mmapped */
  194:     int       pending_size;     /* pending data to send */
  195:     int       diskfile_fd;	/* file to send, file descriptor */
  196:     int	      diskfile_left;	/* remaining file data on disk */
  197: 
  198:     /*
  199:      * for udp measurements - This can be a structure outside stream, and
  200:      * stream can have a pointer to this
  201:      */
  202:     int64_t   packet_count;
  203:     int64_t   peer_packet_count;
  204:     int64_t   peer_omitted_packet_count;
  205:     int64_t   omitted_packet_count;
  206:     double    jitter;
  207:     double    prev_transit;
  208:     int64_t   outoforder_packets;
  209:     int64_t   omitted_outoforder_packets;
  210:     int64_t   cnt_error;
  211:     int64_t   omitted_cnt_error;
  212:     uint64_t  target;
  213: 
  214:     struct sockaddr_storage local_addr;
  215:     struct sockaddr_storage remote_addr;
  216: 
  217:     int       (*rcv) (struct iperf_stream * stream);
  218:     int       (*snd) (struct iperf_stream * stream);
  219: 
  220:     /* chained send/receive routines for -F mode */
  221:     int       (*rcv2) (struct iperf_stream * stream);
  222:     int       (*snd2) (struct iperf_stream * stream);
  223: 
  224: //    struct iperf_stream *next;
  225:     SLIST_ENTRY(iperf_stream) streams;
  226: 
  227:     void     *data;
  228: };
  229: 
  230: struct protocol {
  231:     int       id;
  232:     char      *name;
  233:     int       (*accept)(struct iperf_test *);
  234:     int       (*listen)(struct iperf_test *);
  235:     int       (*connect)(struct iperf_test *);
  236:     int       (*send)(struct iperf_stream *);
  237:     int       (*recv)(struct iperf_stream *);
  238:     int       (*init)(struct iperf_test *);
  239:     SLIST_ENTRY(protocol) protocols;
  240: };
  241: 
  242: struct iperf_textline {
  243:     char *line;
  244:     TAILQ_ENTRY(iperf_textline) textlineentries;
  245: };
  246: 
  247: struct xbind_entry {
  248:     char *name;
  249:     struct addrinfo *ai;
  250:     TAILQ_ENTRY(xbind_entry) link;
  251: };
  252: 
  253: enum iperf_mode {
  254: 	SENDER = 1,
  255: 	RECEIVER = 0,
  256: 	BIDIRECTIONAL = -1
  257: };
  258: 
  259: enum debug_level {
  260:     DEBUG_LEVEL_ERROR = 1,
  261:     DEBUG_LEVEL_WARN = 2,
  262:     DEBUG_LEVEL_INFO = 3,
  263:     DEBUG_LEVEL_DEBUG = 4,
  264:     DEBUG_LEVEL_MAX = 4
  265: };
  266: 
  267: 
  268: struct iperf_test
  269: {
  270:     char      role;                             /* 'c' lient or 's' erver */
  271:     enum iperf_mode mode;
  272:     int       sender_has_retransmits;
  273:     int       other_side_has_retransmits;       /* used if mode == BIDIRECTIONAL */
  274:     struct protocol *protocol;
  275:     signed char state;
  276:     char     *server_hostname;                  /* -c option */
  277:     char     *tmp_template;
  278:     char     *bind_address;                     /* first -B option */
  279:     char     *bind_dev;                         /* bind to network device */
  280:     TAILQ_HEAD(xbind_addrhead, xbind_entry) xbind_addrs; /* all -X opts */
  281:     int       bind_port;                        /* --cport option */
  282:     int       server_port;
  283:     int       omit;                             /* duration of omit period (-O flag) */
  284:     int       duration;                         /* total duration of test (-t flag) */
  285:     char     *diskfile_name;			/* -F option */
  286:     int       affinity, server_affinity;	/* -A option */
  287: #if defined(HAVE_CPUSET_SETAFFINITY)
  288:     cpuset_t cpumask;
  289: #endif /* HAVE_CPUSET_SETAFFINITY */
  290:     char     *title;				/* -T option */
  291:     char     *extra_data;			/* --extra-data */
  292:     char     *congestion;			/* -C option */
  293:     char     *congestion_used;			/* what was actually used */
  294:     char     *remote_congestion_used;		/* what the other side used */
  295:     char     *pidfile;				/* -P option */
  296: 
  297:     char     *logfile;				/* --logfile option */
  298:     FILE     *outfile;
  299: 
  300:     int       ctrl_sck;
  301:     int       mapped_v4;
  302:     int       listener;
  303:     int       prot_listener;
  304: 
  305:     int	      ctrl_sck_mss;			/* MSS for the control channel */
  306: 
  307: #if defined(HAVE_SSL)
  308:     char      *server_authorized_users;
  309:     EVP_PKEY  *server_rsa_private_key;
  310:     int       server_skew_threshold;
  311: #endif // HAVE_SSL
  312: 
  313:     /* boolean variables for Options */
  314:     int       daemon;                           /* -D option */
  315:     int       one_off;                          /* -1 option */
  316:     int       no_delay;                         /* -N option */
  317:     int       reverse;                          /* -R option */
  318:     int       bidirectional;                    /* --bidirectional */
  319:     int	      verbose;                          /* -V option - verbose mode */
  320:     int	      json_output;                      /* -J option - JSON output */
  321:     int	      zerocopy;                         /* -Z option - use sendfile */
  322:     int       debug;				/* -d option - enable debug */
  323:     enum      debug_level debug_level;          /* -d option option - level of debug messages to show */
  324:     int	      get_server_output;		/* --get-server-output */
  325:     int	      udp_counters_64bit;		/* --use-64-bit-udp-counters */
  326:     int       forceflush; /* --forceflush - flushing output at every interval */
  327:     int	      multisend;
  328:     int	      repeating_payload;                /* --repeating-payload */
  329:     int       timestamps;			/* --timestamps */
  330:     char     *timestamp_format;
  331: 
  332:     char     *json_output_string; /* rendered JSON output if json_output is set */
  333:     /* Select related parameters */
  334:     int       max_fd;
  335:     fd_set    read_set;                         /* set of read sockets */
  336:     fd_set    write_set;                        /* set of write sockets */
  337: 
  338:     /* Interval related members */
  339:     int       omitting;
  340:     double    stats_interval;
  341:     double    reporter_interval;
  342:     void      (*stats_callback) (struct iperf_test *);
  343:     void      (*reporter_callback) (struct iperf_test *);
  344:     Timer     *omit_timer;
  345:     Timer     *timer;
  346:     int        done;
  347:     Timer     *stats_timer;
  348:     Timer     *reporter_timer;
  349: 
  350:     double cpu_util[3];                            /* cpu utilization of the test - total, user, system */
  351:     double remote_cpu_util[3];                     /* cpu utilization for the remote host/client - total, user, system */
  352: 
  353:     int       num_streams;                      /* total streams in the test (-P) */
  354: 
  355:     iperf_size_t bytes_sent;
  356:     iperf_size_t blocks_sent;
  357: 
  358:     iperf_size_t bytes_received;
  359:     iperf_size_t blocks_received;
  360: 
  361:     iperf_size_t bitrate_limit_stats_count;               /* Number of stats periods accumulated for server's total bitrate average */
  362:     iperf_size_t *bitrate_limit_intervals_traffic_bytes;  /* Pointer to a cyclic array that includes the last interval's bytes transferred */
  363:     iperf_size_t bitrate_limit_last_interval_index;       /* Index of the last interval traffic inserted into the cyclic array */
  364:     int          bitrate_limit_exceeded;                  /* Set by callback routine when average data rate exceeded the server's bitrate limit */
  365: 
  366:     int server_last_run_rc;                      /* Save last server run rc for next test */
  367:     uint server_forced_idle_restarts_count;      /* count number of forced server restarts to make sure it is not stack */
  368:     uint server_forced_no_msg_restarts_count;    /* count number of forced server restarts to make sure it is not stack */
  369:     uint server_test_number;                     /* count number of tests performed by a server */
  370: 
  371:     char      cookie[COOKIE_SIZE];
  372: //    struct iperf_stream *streams;               /* pointer to list of struct stream */
  373:     SLIST_HEAD(slisthead, iperf_stream) streams;
  374:     struct iperf_settings *settings;
  375: 
  376:     SLIST_HEAD(plisthead, protocol) protocols;
  377: 
  378:     /* callback functions */
  379:     void      (*on_new_stream)(struct iperf_stream *);
  380:     void      (*on_test_start)(struct iperf_test *);
  381:     void      (*on_connect)(struct iperf_test *);
  382:     void      (*on_test_finish)(struct iperf_test *);
  383: 
  384:     /* cJSON handles for use when in -J mode */\
  385:     cJSON *json_top;
  386:     cJSON *json_start;
  387:     cJSON *json_connected;
  388:     cJSON *json_intervals;
  389:     cJSON *json_end;
  390: 
  391:     /* Server output (use on client side only) */
  392:     char *server_output_text;
  393:     cJSON *json_server_output;
  394: 
  395:     /* Server output (use on server side only) */
  396:     TAILQ_HEAD(iperf_textlisthead, iperf_textline) server_output_list;
  397: 
  398: };
  399: 
  400: /* default settings */
  401: #define PORT 5201  /* default port to listen on (don't use the same port as iperf2) */
  402: #define uS_TO_NS 1000
  403: #define mS_TO_US 1000
  404: #define SEC_TO_mS 1000
  405: #define SEC_TO_US 1000000LL
  406: #define UDP_RATE (1024 * 1024) /* 1 Mbps */
  407: #define OMIT 0 /* seconds */
  408: #define DURATION 10 /* seconds */
  409: 
  410: #define SEC_TO_NS 1000000000LL	/* too big for enum/const on some platforms */
  411: #define MAX_RESULT_STRING 4096
  412: 
  413: #define UDP_BUFFER_EXTRA 1024
  414: 
  415: /* constants for command line arg sanity checks */
  416: #define MB (1024 * 1024)
  417: #define MAX_TCP_BUFFER (512 * MB)
  418: #define MAX_BLOCKSIZE MB
  419: /* Minimum size UDP send is the size of two 32-bit ints followed by a 64-bit int */
  420: #define MIN_UDP_BLOCKSIZE (4 + 4 + 8)
  421: /* Maximum size UDP send is (64K - 1) - IP and UDP header sizes */
  422: #define MAX_UDP_BLOCKSIZE (65535 - 8 - 20)
  423: #define MIN_INTERVAL 0.1
  424: #define MAX_INTERVAL 60.0
  425: #define MAX_TIME 86400
  426: #define MAX_BURST 1000
  427: #define MAX_MSS (9 * 1024)
  428: #define MAX_STREAMS 128
  429: 
  430: #define TIMESTAMP_FORMAT "%c "
  431: 
  432: extern int gerror; /* error value from getaddrinfo(3), for use in internal error handling */
  433: 
  434: /* UDP "connect" message and reply (textual value for Wireshark, etc. readability - legacy was numeric) */
  435: #define UDP_CONNECT_MSG 0x36373839          // "6789" - legacy value was 123456789
  436: #define UDP_CONNECT_REPLY 0x39383736        // "9876" - legacy value was 987654321
  437: #define LEGACY_UDP_CONNECT_REPLY 987654321  // Old servers may still reply with the legacy value
  438: 
  439: /* In Reverse mode, maximum number of packets to wait for "accept" response - to handle out of order packets */
  440: #define MAX_REVERSE_OUT_OF_ORDER_PACKETS 2
  441: 
  442: #endif /* !__IPERF_H */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>