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