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