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