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