Home | History | Annotate | Download | only in src
      1 /*
      2  * iperf, Copyright (c) 2014-2018, 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 (at) 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 #include <netinet/tcp.h>
     43 
     44 #if defined(HAVE_CPUSET_SETAFFINITY)
     45 #include <sys/param.h>
     46 #include <sys/cpuset.h>
     47 #endif /* HAVE_CPUSET_SETAFFINITY */
     48 
     49 #if defined(HAVE_INTTYPES_H)
     50 # include <inttypes.h>
     51 #else
     52 # ifndef PRIu64
     53 #  if sizeof(long) == 8
     54 #   define PRIu64		"lu"
     55 #  else
     56 #   define PRIu64		"llu"
     57 #  endif
     58 # endif
     59 #endif
     60 
     61 #include "timer.h"
     62 #include "queue.h"
     63 #include "cjson.h"
     64 #include "iperf_time.h"
     65 
     66 #if defined(HAVE_SSL)
     67 #include <openssl/bio.h>
     68 #include <openssl/evp.h>
     69 #endif // HAVE_SSL
     70 
     71 typedef uint64_t iperf_size_t;
     72 
     73 struct iperf_interval_results
     74 {
     75     iperf_size_t bytes_transferred; /* bytes transfered in this interval */
     76     struct iperf_time interval_start_time;
     77     struct iperf_time interval_end_time;
     78     float     interval_duration;
     79 
     80     /* for UDP */
     81     int       interval_packet_count;
     82     int       interval_outoforder_packets;
     83     int       interval_cnt_error;
     84     int       packet_count;
     85     double    jitter;
     86     int       outoforder_packets;
     87     int       cnt_error;
     88 
     89     int omitted;
     90 #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) && \
     91 	defined(TCP_INFO)
     92     struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) for Linux, {Free,Net}BSD */
     93 #else
     94     /* Just placeholders, never accessed. */
     95     char *tcpInfo;
     96 #endif
     97     int interval_retrans;
     98     int interval_sacks;
     99     int snd_cwnd;
    100     TAILQ_ENTRY(iperf_interval_results) irlistentries;
    101     void     *custom_data;
    102     int rtt;
    103     int rttvar;
    104     int pmtu;
    105 };
    106 
    107 struct iperf_stream_result
    108 {
    109     iperf_size_t bytes_received;
    110     iperf_size_t bytes_sent;
    111     iperf_size_t bytes_received_this_interval;
    112     iperf_size_t bytes_sent_this_interval;
    113     iperf_size_t bytes_sent_omit;
    114     int stream_prev_total_retrans;
    115     int stream_retrans;
    116     int stream_prev_total_sacks;
    117     int stream_sacks;
    118     int stream_max_rtt;
    119     int stream_min_rtt;
    120     int stream_sum_rtt;
    121     int stream_count_rtt;
    122     int stream_max_snd_cwnd;
    123     struct iperf_time start_time;
    124     struct iperf_time end_time;
    125     struct iperf_time start_time_fixed;
    126     double sender_time;
    127     double receiver_time;
    128     TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
    129     void     *data;
    130 };
    131 
    132 #define COOKIE_SIZE 37		/* size of an ascii uuid */
    133 struct iperf_settings
    134 {
    135     int       domain;               /* AF_INET or AF_INET6 */
    136     int       socket_bufsize;       /* window size for TCP */
    137     int       blksize;              /* size of read/writes (-l) */
    138     uint64_t  rate;                 /* target data rate for application pacing*/
    139     uint64_t  fqrate;               /* target data rate for FQ pacing*/
    140     int	      pacing_timer;	    /* pacing timer in microseconds */
    141     int       burst;                /* packets per burst */
    142     int       mss;                  /* for TCP MSS */
    143     int       ttl;                  /* IP TTL option */
    144     int       tos;                  /* type of service bit */
    145     int       flowlabel;            /* IPv6 flow label */
    146     iperf_size_t bytes;             /* number of bytes to send */
    147     iperf_size_t blocks;            /* number of blocks (packets) to send */
    148     char      unit_format;          /* -f */
    149     int       num_ostreams;         /* SCTP initmsg settings */
    150 #if defined(HAVE_SSL)
    151     char      *authtoken;           /* Authentication token */
    152     char      *client_username;
    153     char      *client_password;
    154     EVP_PKEY  *client_rsa_pubkey;
    155 #endif // HAVE_SSL
    156     int	      connect_timeout;	    /* socket connection timeout, in ms */
    157 };
    158 
    159 struct iperf_test;
    160 
    161 struct iperf_stream
    162 {
    163     struct iperf_test* test;
    164 
    165     /* configurable members */
    166     int       local_port;
    167     int       remote_port;
    168     int       socket;
    169     int       id;
    170     int       sender;
    171 	/* XXX: is settings just a pointer to the same struct in iperf_test? if not,
    172 		should it be? */
    173     struct iperf_settings *settings;	/* pointer to structure settings */
    174 
    175     /* non configurable members */
    176     struct iperf_stream_result *result;	/* structure pointer to result */
    177     Timer     *send_timer;
    178     int       green_light;
    179     int       buffer_fd;	/* data to send, file descriptor */
    180     char      *buffer;		/* data to send, mmapped */
    181     int       diskfile_fd;	/* file to send, file descriptor */
    182     int	      diskfile_left;	/* remaining file data on disk */
    183 
    184     /*
    185      * for udp measurements - This can be a structure outside stream, and
    186      * stream can have a pointer to this
    187      */
    188     int       packet_count;
    189     int	      peer_packet_count;
    190     int       omitted_packet_count;
    191     double    jitter;
    192     double    prev_transit;
    193     int       outoforder_packets;
    194     int       omitted_outoforder_packets;
    195     int       cnt_error;
    196     int       omitted_cnt_error;
    197     uint64_t  target;
    198 
    199     struct sockaddr_storage local_addr;
    200     struct sockaddr_storage remote_addr;
    201 
    202     int       (*rcv) (struct iperf_stream * stream);
    203     int       (*snd) (struct iperf_stream * stream);
    204 
    205     /* chained send/receive routines for -F mode */
    206     int       (*rcv2) (struct iperf_stream * stream);
    207     int       (*snd2) (struct iperf_stream * stream);
    208 
    209 //    struct iperf_stream *next;
    210     SLIST_ENTRY(iperf_stream) streams;
    211 
    212     void     *data;
    213 };
    214 
    215 struct protocol {
    216     int       id;
    217     char      *name;
    218     int       (*accept)(struct iperf_test *);
    219     int       (*listen)(struct iperf_test *);
    220     int       (*connect)(struct iperf_test *);
    221     int       (*send)(struct iperf_stream *);
    222     int       (*recv)(struct iperf_stream *);
    223     int       (*init)(struct iperf_test *);
    224     SLIST_ENTRY(protocol) protocols;
    225 };
    226 
    227 struct iperf_textline {
    228     char *line;
    229     TAILQ_ENTRY(iperf_textline) textlineentries;
    230 };
    231 
    232 struct xbind_entry {
    233     char *name;
    234     struct addrinfo *ai;
    235     TAILQ_ENTRY(xbind_entry) link;
    236 };
    237 
    238 enum iperf_mode {
    239 	SENDER = 1,
    240 	RECEIVER = 0,
    241 	BIDIRECTIONAL = -1
    242 };
    243 
    244 struct iperf_test
    245 {
    246     char      role;                             /* 'c' lient or 's' erver */
    247     enum iperf_mode mode;
    248     int       sender_has_retransmits;
    249     int       other_side_has_retransmits;       /* used if mode == BIDIRECTIONAL */
    250     struct protocol *protocol;
    251     signed char state;
    252     char     *server_hostname;                  /* -c option */
    253     char     *tmp_template;
    254     char     *bind_address;                     /* first -B option */
    255     TAILQ_HEAD(xbind_addrhead, xbind_entry) xbind_addrs; /* all -X opts */
    256     int       bind_port;                        /* --cport option */
    257     int       server_port;
    258     int       omit;                             /* duration of omit period (-O flag) */
    259     int       duration;                         /* total duration of test (-t flag) */
    260     char     *diskfile_name;			/* -F option */
    261     int       affinity, server_affinity;	/* -A option */
    262 #if defined(HAVE_CPUSET_SETAFFINITY)
    263     cpuset_t cpumask;
    264 #endif /* HAVE_CPUSET_SETAFFINITY */
    265     char     *title;				/* -T option */
    266     char     *extra_data;			/* --extra-data */
    267     char     *congestion;			/* -C option */
    268     char     *congestion_used;			/* what was actually used */
    269     char     *remote_congestion_used;		/* what the other side used */
    270     char     *pidfile;				/* -P option */
    271 
    272     char     *logfile;				/* --logfile option */
    273     FILE     *outfile;
    274 
    275     int       ctrl_sck;
    276     int       listener;
    277     int       prot_listener;
    278 
    279     int	      ctrl_sck_mss;			/* MSS for the control channel */
    280 
    281 #if defined(HAVE_SSL)
    282     char      *server_authorized_users;
    283     EVP_PKEY  *server_rsa_private_key;
    284 #endif // HAVE_SSL
    285 
    286     /* boolean variables for Options */
    287     int       daemon;                           /* -D option */
    288     int       one_off;                          /* -1 option */
    289     int       no_delay;                         /* -N option */
    290     int       reverse;                          /* -R option */
    291     int       bidirectional;                    /* --bidirectional */
    292     int	      verbose;                          /* -V option - verbose mode */
    293     int	      json_output;                      /* -J option - JSON output */
    294     int	      zerocopy;                         /* -Z option - use sendfile */
    295     int       debug;				/* -d option - enable debug */
    296     int	      get_server_output;		/* --get-server-output */
    297     int	      udp_counters_64bit;		/* --use-64-bit-udp-counters */
    298     int       forceflush; /* --forceflush - flushing output at every interval */
    299     int	      multisend;
    300     int	      repeating_payload;                /* --repeating-payload */
    301 
    302     char     *json_output_string; /* rendered JSON output if json_output is set */
    303     /* Select related parameters */
    304     int       max_fd;
    305     fd_set    read_set;                         /* set of read sockets */
    306     fd_set    write_set;                        /* set of write sockets */
    307 
    308     /* Interval related members */
    309     int       omitting;
    310     double    stats_interval;
    311     double    reporter_interval;
    312     void      (*stats_callback) (struct iperf_test *);
    313     void      (*reporter_callback) (struct iperf_test *);
    314     Timer     *omit_timer;
    315     Timer     *timer;
    316     int        done;
    317     Timer     *stats_timer;
    318     Timer     *reporter_timer;
    319 
    320     double cpu_util[3];                            /* cpu utilization of the test - total, user, system */
    321     double remote_cpu_util[3];                     /* cpu utilization for the remote host/client - total, user, system */
    322 
    323     int       num_streams;                      /* total streams in the test (-P) */
    324 
    325     iperf_size_t bytes_sent;
    326     iperf_size_t blocks_sent;
    327 
    328     iperf_size_t bytes_received;
    329     iperf_size_t blocks_received;
    330 
    331     char      cookie[COOKIE_SIZE];
    332 //    struct iperf_stream *streams;               /* pointer to list of struct stream */
    333     SLIST_HEAD(slisthead, iperf_stream) streams;
    334     struct iperf_settings *settings;
    335 
    336     SLIST_HEAD(plisthead, protocol) protocols;
    337 
    338     /* callback functions */
    339     void      (*on_new_stream)(struct iperf_stream *);
    340     void      (*on_test_start)(struct iperf_test *);
    341     void      (*on_connect)(struct iperf_test *);
    342     void      (*on_test_finish)(struct iperf_test *);
    343 
    344     /* cJSON handles for use when in -J mode */\
    345     cJSON *json_top;
    346     cJSON *json_start;
    347     cJSON *json_connected;
    348     cJSON *json_intervals;
    349     cJSON *json_end;
    350 
    351     /* Server output (use on client side only) */
    352     char *server_output_text;
    353     cJSON *json_server_output;
    354 
    355     /* Server output (use on server side only) */
    356     TAILQ_HEAD(iperf_textlisthead, iperf_textline) server_output_list;
    357 
    358 };
    359 
    360 /* default settings */
    361 #define PORT 5201  /* default port to listen on (don't use the same port as iperf2) */
    362 #define uS_TO_NS 1000
    363 #define SEC_TO_US 1000000LL
    364 #define UDP_RATE (1024 * 1024) /* 1 Mbps */
    365 #define OMIT 0 /* seconds */
    366 #define DURATION 10 /* seconds */
    367 
    368 #define SEC_TO_NS 1000000000LL	/* too big for enum/const on some platforms */
    369 #define MAX_RESULT_STRING 4096
    370 
    371 #define UDP_BUFFER_EXTRA 1024
    372 
    373 /* constants for command line arg sanity checks */
    374 #define MB (1024 * 1024)
    375 #define MAX_TCP_BUFFER (512 * MB)
    376 #define MAX_BLOCKSIZE MB
    377 /* Minimum size UDP send is the size of two 32-bit ints followed by a 64-bit int */
    378 #define MIN_UDP_BLOCKSIZE (4 + 4 + 8)
    379 /* Maximum size UDP send is (64K - 1) - IP and UDP header sizes */
    380 #define MAX_UDP_BLOCKSIZE (65535 - 8 - 20)
    381 #define MIN_INTERVAL 0.1
    382 #define MAX_INTERVAL 60.0
    383 #define MAX_TIME 86400
    384 #define MAX_BURST 1000
    385 #define MAX_MSS (9 * 1024)
    386 #define MAX_STREAMS 128
    387 
    388 #endif /* !__IPERF_H */
    389