xref: /iperf/src/iperf_api.c (revision faf335bb)
1 /*
2  * iperf, Copyright (c) 2014-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 file
25  * for complete information.
26  */
27 #define _GNU_SOURCE
28 #define __USE_GNU
29 
30 #include "iperf_config.h"
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <getopt.h>
36 #include <errno.h>
37 #include <signal.h>
38 #include <unistd.h>
39 #include <assert.h>
40 #include <fcntl.h>
41 #include <sys/socket.h>
42 #include <sys/types.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <netdb.h>
46 #include <pthread.h>
47 #ifdef HAVE_STDINT_H
48 #include <stdint.h>
49 #endif
50 #include <netinet/tcp.h>
51 #include <sys/time.h>
52 #include <sys/resource.h>
53 #include <sys/mman.h>
54 #include <sys/stat.h>
55 #include <sched.h>
56 #include <setjmp.h>
57 #include <stdarg.h>
58 
59 #if defined(HAVE_CPUSET_SETAFFINITY)
60 #include <sys/param.h>
61 #include <sys/cpuset.h>
62 #endif /* HAVE_CPUSET_SETAFFINITY */
63 
64 #include "net.h"
65 #include "iperf.h"
66 #include "iperf_api.h"
67 #include "iperf_udp.h"
68 #include "iperf_tcp.h"
69 #if defined(HAVE_SCTP)
70 #include "iperf_sctp.h"
71 #endif /* HAVE_SCTP */
72 #include "timer.h"
73 
74 #include "cjson.h"
75 #include "units.h"
76 #include "tcp_window_size.h"
77 #include "iperf_util.h"
78 #include "iperf_locale.h"
79 #include "version.h"
80 #if defined(HAVE_SSL)
81 #include "iperf_auth.h"
82 #endif /* HAVE_SSL */
83 
84 /* Forwards. */
85 static int send_parameters(struct iperf_test *test);
86 static int get_parameters(struct iperf_test *test);
87 static int send_results(struct iperf_test *test);
88 static int get_results(struct iperf_test *test);
89 static int diskfile_send(struct iperf_stream *sp);
90 static int diskfile_recv(struct iperf_stream *sp);
91 static int JSON_write(int fd, cJSON *json);
92 static void print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *json_interval_streams);
93 static cJSON *JSON_read(int fd);
94 
95 
96 /*************************** Print usage functions ****************************/
97 
98 void
99 usage()
100 {
101     fputs(usage_shortstr, stderr);
102 }
103 
104 
105 void
106 usage_long(FILE *f)
107 {
108     fprintf(f, usage_longstr, UDP_RATE / (1024*1024), DURATION, DEFAULT_TCP_BLKSIZE / 1024, DEFAULT_UDP_BLKSIZE / 1024);
109 }
110 
111 
112 void warning(char *str)
113 {
114     fprintf(stderr, "warning: %s\n", str);
115 }
116 
117 
118 /************** Getter routines for some fields inside iperf_test *************/
119 
120 int
121 iperf_get_verbose(struct iperf_test *ipt)
122 {
123     return ipt->verbose;
124 }
125 
126 int
127 iperf_get_control_socket(struct iperf_test *ipt)
128 {
129     return ipt->ctrl_sck;
130 }
131 
132 int
133 iperf_get_control_socket_mss(struct iperf_test *ipt)
134 {
135     return ipt->ctrl_sck_mss;
136 }
137 
138 int
139 iperf_get_test_omit(struct iperf_test *ipt)
140 {
141     return ipt->omit;
142 }
143 
144 int
145 iperf_get_test_duration(struct iperf_test *ipt)
146 {
147     return ipt->duration;
148 }
149 
150 uint64_t
151 iperf_get_test_rate(struct iperf_test *ipt)
152 {
153     return ipt->settings->rate;
154 }
155 
156 uint64_t
157 iperf_get_test_fqrate(struct iperf_test *ipt)
158 {
159     return ipt->settings->fqrate;
160 }
161 
162 int
163 iperf_get_test_burst(struct iperf_test *ipt)
164 {
165     return ipt->settings->burst;
166 }
167 
168 char
169 iperf_get_test_role(struct iperf_test *ipt)
170 {
171     return ipt->role;
172 }
173 
174 int
175 iperf_get_test_reverse(struct iperf_test *ipt)
176 {
177     return ipt->reverse;
178 }
179 
180 int
181 iperf_get_test_blksize(struct iperf_test *ipt)
182 {
183     return ipt->settings->blksize;
184 }
185 
186 FILE *
187 iperf_get_test_outfile (struct iperf_test *ipt)
188 {
189     return ipt->outfile;
190 }
191 
192 int
193 iperf_get_test_socket_bufsize(struct iperf_test *ipt)
194 {
195     return ipt->settings->socket_bufsize;
196 }
197 
198 double
199 iperf_get_test_reporter_interval(struct iperf_test *ipt)
200 {
201     return ipt->reporter_interval;
202 }
203 
204 double
205 iperf_get_test_stats_interval(struct iperf_test *ipt)
206 {
207     return ipt->stats_interval;
208 }
209 
210 int
211 iperf_get_test_num_streams(struct iperf_test *ipt)
212 {
213     return ipt->num_streams;
214 }
215 
216 int
217 iperf_get_test_server_port(struct iperf_test *ipt)
218 {
219     return ipt->server_port;
220 }
221 
222 char*
223 iperf_get_test_server_hostname(struct iperf_test *ipt)
224 {
225     return ipt->server_hostname;
226 }
227 
228 char*
229 iperf_get_test_template(struct iperf_test *ipt)
230 {
231     return ipt->tmp_template;
232 }
233 
234 int
235 iperf_get_test_protocol_id(struct iperf_test *ipt)
236 {
237     return ipt->protocol->id;
238 }
239 
240 int
241 iperf_get_test_json_output(struct iperf_test *ipt)
242 {
243     return ipt->json_output;
244 }
245 
246 char *
247 iperf_get_test_json_output_string(struct iperf_test *ipt)
248 {
249     return ipt->json_output_string;
250 }
251 
252 int
253 iperf_get_test_zerocopy(struct iperf_test *ipt)
254 {
255     return ipt->zerocopy;
256 }
257 
258 int
259 iperf_get_test_get_server_output(struct iperf_test *ipt)
260 {
261     return ipt->get_server_output;
262 }
263 
264 char
265 iperf_get_test_unit_format(struct iperf_test *ipt)
266 {
267     return ipt->settings->unit_format;
268 }
269 
270 char *
271 iperf_get_test_bind_address(struct iperf_test *ipt)
272 {
273     return ipt->bind_address;
274 }
275 
276 int
277 iperf_get_test_udp_counters_64bit(struct iperf_test *ipt)
278 {
279     return ipt->udp_counters_64bit;
280 }
281 
282 int
283 iperf_get_test_one_off(struct iperf_test *ipt)
284 {
285     return ipt->one_off;
286 }
287 
288 /************** Setter routines for some fields inside iperf_test *************/
289 
290 void
291 iperf_set_verbose(struct iperf_test *ipt, int verbose)
292 {
293     ipt->verbose = verbose;
294 }
295 
296 void
297 iperf_set_control_socket(struct iperf_test *ipt, int ctrl_sck)
298 {
299     ipt->ctrl_sck = ctrl_sck;
300 }
301 
302 void
303 iperf_set_test_omit(struct iperf_test *ipt, int omit)
304 {
305     ipt->omit = omit;
306 }
307 
308 void
309 iperf_set_test_duration(struct iperf_test *ipt, int duration)
310 {
311     ipt->duration = duration;
312 }
313 
314 void
315 iperf_set_test_reporter_interval(struct iperf_test *ipt, double reporter_interval)
316 {
317     ipt->reporter_interval = reporter_interval;
318 }
319 
320 void
321 iperf_set_test_stats_interval(struct iperf_test *ipt, double stats_interval)
322 {
323     ipt->stats_interval = stats_interval;
324 }
325 
326 void
327 iperf_set_test_state(struct iperf_test *ipt, signed char state)
328 {
329     ipt->state = state;
330 }
331 
332 void
333 iperf_set_test_blksize(struct iperf_test *ipt, int blksize)
334 {
335     ipt->settings->blksize = blksize;
336 }
337 
338 void
339 iperf_set_test_rate(struct iperf_test *ipt, uint64_t rate)
340 {
341     ipt->settings->rate = rate;
342 }
343 
344 void
345 iperf_set_test_fqrate(struct iperf_test *ipt, uint64_t fqrate)
346 {
347     ipt->settings->fqrate = fqrate;
348 }
349 
350 void
351 iperf_set_test_burst(struct iperf_test *ipt, int burst)
352 {
353     ipt->settings->burst = burst;
354 }
355 
356 void
357 iperf_set_test_server_port(struct iperf_test *ipt, int srv_port)
358 {
359     ipt->server_port = srv_port;
360 }
361 
362 void
363 iperf_set_test_socket_bufsize(struct iperf_test *ipt, int socket_bufsize)
364 {
365     ipt->settings->socket_bufsize = socket_bufsize;
366 }
367 
368 void
369 iperf_set_test_num_streams(struct iperf_test *ipt, int num_streams)
370 {
371     ipt->num_streams = num_streams;
372 }
373 
374 static void
375 check_sender_has_retransmits(struct iperf_test *ipt)
376 {
377     if (ipt->sender && ipt->protocol->id == Ptcp && has_tcpinfo_retransmits())
378 	ipt->sender_has_retransmits = 1;
379     else
380 	ipt->sender_has_retransmits = 0;
381 }
382 
383 void
384 iperf_set_test_role(struct iperf_test *ipt, char role)
385 {
386     ipt->role = role;
387     if (role == 'c')
388 	ipt->sender = 1;
389     else if (role == 's')
390 	ipt->sender = 0;
391     if (ipt->reverse)
392         ipt->sender = ! ipt->sender;
393     check_sender_has_retransmits(ipt);
394 }
395 
396 void
397 iperf_set_test_server_hostname(struct iperf_test *ipt, char *server_hostname)
398 {
399     ipt->server_hostname = strdup(server_hostname);
400 }
401 
402 void
403 iperf_set_test_template(struct iperf_test *ipt, char *tmp_template)
404 {
405     ipt->tmp_template = strdup(tmp_template);
406 }
407 
408 void
409 iperf_set_test_reverse(struct iperf_test *ipt, int reverse)
410 {
411     ipt->reverse = reverse;
412     if (ipt->reverse)
413         ipt->sender = ! ipt->sender;
414     check_sender_has_retransmits(ipt);
415 }
416 
417 void
418 iperf_set_test_json_output(struct iperf_test *ipt, int json_output)
419 {
420     ipt->json_output = json_output;
421 }
422 
423 int
424 iperf_has_zerocopy( void )
425 {
426     return has_sendfile();
427 }
428 
429 void
430 iperf_set_test_zerocopy(struct iperf_test *ipt, int zerocopy)
431 {
432     ipt->zerocopy = (zerocopy && has_sendfile());
433 }
434 
435 void
436 iperf_set_test_get_server_output(struct iperf_test *ipt, int get_server_output)
437 {
438     ipt->get_server_output = get_server_output;
439 }
440 
441 void
442 iperf_set_test_unit_format(struct iperf_test *ipt, char unit_format)
443 {
444     ipt->settings->unit_format = unit_format;
445 }
446 
447 void
448 iperf_set_test_bind_address(struct iperf_test *ipt, char *bnd_address)
449 {
450     ipt->bind_address = strdup(bnd_address);
451 }
452 
453 void
454 iperf_set_test_udp_counters_64bit(struct iperf_test *ipt, int udp_counters_64bit)
455 {
456     ipt->udp_counters_64bit = udp_counters_64bit;
457 }
458 
459 void
460 iperf_set_test_one_off(struct iperf_test *ipt, int one_off)
461 {
462     ipt->one_off = one_off;
463 }
464 
465 /********************** Get/set test protocol structure ***********************/
466 
467 struct protocol *
468 get_protocol(struct iperf_test *test, int prot_id)
469 {
470     struct protocol *prot;
471 
472     SLIST_FOREACH(prot, &test->protocols, protocols) {
473         if (prot->id == prot_id)
474             break;
475     }
476 
477     if (prot == NULL)
478         i_errno = IEPROTOCOL;
479 
480     return prot;
481 }
482 
483 int
484 set_protocol(struct iperf_test *test, int prot_id)
485 {
486     struct protocol *prot = NULL;
487 
488     SLIST_FOREACH(prot, &test->protocols, protocols) {
489         if (prot->id == prot_id) {
490             test->protocol = prot;
491 	    check_sender_has_retransmits(test);
492             return 0;
493         }
494     }
495 
496     i_errno = IEPROTOCOL;
497     return -1;
498 }
499 
500 
501 /************************** Iperf callback functions **************************/
502 
503 void
504 iperf_on_new_stream(struct iperf_stream *sp)
505 {
506     connect_msg(sp);
507 }
508 
509 void
510 iperf_on_test_start(struct iperf_test *test)
511 {
512     if (test->json_output) {
513 	cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s  num_streams: %d  blksize: %d  omit: %d  duration: %d  bytes: %d  blocks: %d  reverse: %d  tos: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks, test->reverse?(int64_t)1:(int64_t)0, test->settings->tos));
514     } else {
515 	if (test->verbose) {
516 	    if (test->settings->bytes)
517 		iperf_printf(test, test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->bytes, test->settings->tos);
518 	    else if (test->settings->blocks)
519 		iperf_printf(test, test_start_blocks, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->blocks, test->settings->tos);
520 	    else
521 		iperf_printf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->duration, test->settings->tos);
522 	}
523     }
524 }
525 
526 /* This converts an IPv6 string address from IPv4-mapped format into regular
527 ** old IPv4 format, which is easier on the eyes of network veterans.
528 **
529 ** If the v6 address is not v4-mapped it is left alone.
530 */
531 static void
532 mapped_v4_to_regular_v4(char *str)
533 {
534     char *prefix = "::ffff:";
535     int prefix_len;
536 
537     prefix_len = strlen(prefix);
538     if (strncmp(str, prefix, prefix_len) == 0) {
539 	int str_len = strlen(str);
540 	memmove(str, str + prefix_len, str_len - prefix_len + 1);
541     }
542 }
543 
544 void
545 iperf_on_connect(struct iperf_test *test)
546 {
547     time_t now_secs;
548     const char* rfc1123_fmt = "%a, %d %b %Y %H:%M:%S GMT";
549     char now_str[100];
550     char ipr[INET6_ADDRSTRLEN];
551     int port;
552     struct sockaddr_storage sa;
553     struct sockaddr_in *sa_inP;
554     struct sockaddr_in6 *sa_in6P;
555     socklen_t len;
556 
557     now_secs = time((time_t*) 0);
558     (void) strftime(now_str, sizeof(now_str), rfc1123_fmt, gmtime(&now_secs));
559     if (test->json_output)
560 	cJSON_AddItemToObject(test->json_start, "timestamp", iperf_json_printf("time: %s  timesecs: %d", now_str, (int64_t) now_secs));
561     else if (test->verbose)
562 	iperf_printf(test, report_time, now_str);
563 
564     if (test->role == 'c') {
565 	if (test->json_output)
566 	    cJSON_AddItemToObject(test->json_start, "connecting_to", iperf_json_printf("host: %s  port: %d", test->server_hostname, (int64_t) test->server_port));
567 	else {
568 	    iperf_printf(test, report_connecting, test->server_hostname, test->server_port);
569 	    if (test->reverse)
570 		iperf_printf(test, report_reverse, test->server_hostname);
571 	}
572     } else {
573         len = sizeof(sa);
574         getpeername(test->ctrl_sck, (struct sockaddr *) &sa, &len);
575         if (getsockdomain(test->ctrl_sck) == AF_INET) {
576 	    sa_inP = (struct sockaddr_in *) &sa;
577             inet_ntop(AF_INET, &sa_inP->sin_addr, ipr, sizeof(ipr));
578 	    port = ntohs(sa_inP->sin_port);
579         } else {
580 	    sa_in6P = (struct sockaddr_in6 *) &sa;
581             inet_ntop(AF_INET6, &sa_in6P->sin6_addr, ipr, sizeof(ipr));
582 	    port = ntohs(sa_in6P->sin6_port);
583         }
584 	mapped_v4_to_regular_v4(ipr);
585 	if (test->json_output)
586 	    cJSON_AddItemToObject(test->json_start, "accepted_connection", iperf_json_printf("host: %s  port: %d", ipr, (int64_t) port));
587 	else
588 	    iperf_printf(test, report_accepted, ipr, port);
589     }
590     if (test->json_output) {
591 	cJSON_AddStringToObject(test->json_start, "cookie", test->cookie);
592         if (test->protocol->id == SOCK_STREAM) {
593 	    if (test->settings->mss)
594 		cJSON_AddNumberToObject(test->json_start, "tcp_mss", test->settings->mss);
595 	    else {
596 		cJSON_AddNumberToObject(test->json_start, "tcp_mss_default", test->ctrl_sck_mss);
597 	    }
598 	}
599     } else if (test->verbose) {
600         iperf_printf(test, report_cookie, test->cookie);
601         if (test->protocol->id == SOCK_STREAM) {
602             if (test->settings->mss)
603                 iperf_printf(test, "      TCP MSS: %d\n", test->settings->mss);
604             else {
605                 iperf_printf(test, "      TCP MSS: %d (default)\n", test->ctrl_sck_mss);
606             }
607         }
608 
609     }
610 }
611 
612 void
613 iperf_on_test_finish(struct iperf_test *test)
614 {
615 }
616 
617 
618 /******************************************************************************/
619 
620 int
621 iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
622 {
623     static struct option longopts[] =
624     {
625         {"port", required_argument, NULL, 'p'},
626         {"format", required_argument, NULL, 'f'},
627         {"interval", required_argument, NULL, 'i'},
628         {"daemon", no_argument, NULL, 'D'},
629         {"one-off", no_argument, NULL, '1'},
630         {"verbose", no_argument, NULL, 'V'},
631         {"json", no_argument, NULL, 'J'},
632         {"version", no_argument, NULL, 'v'},
633         {"server", no_argument, NULL, 's'},
634         {"client", required_argument, NULL, 'c'},
635         {"udp", no_argument, NULL, 'u'},
636         {"bandwidth", required_argument, NULL, 'b'},
637         {"time", required_argument, NULL, 't'},
638         {"bytes", required_argument, NULL, 'n'},
639         {"blockcount", required_argument, NULL, 'k'},
640         {"length", required_argument, NULL, 'l'},
641         {"parallel", required_argument, NULL, 'P'},
642         {"reverse", no_argument, NULL, 'R'},
643         {"window", required_argument, NULL, 'w'},
644         {"bind", required_argument, NULL, 'B'},
645         {"cport", required_argument, NULL, OPT_CLIENT_PORT},
646         {"set-mss", required_argument, NULL, 'M'},
647         {"no-delay", no_argument, NULL, 'N'},
648         {"version4", no_argument, NULL, '4'},
649         {"version6", no_argument, NULL, '6'},
650         {"tos", required_argument, NULL, 'S'},
651         {"dscp", required_argument, NULL, OPT_DSCP},
652 #if defined(HAVE_FLOWLABEL)
653         {"flowlabel", required_argument, NULL, 'L'},
654 #endif /* HAVE_FLOWLABEL */
655         {"zerocopy", no_argument, NULL, 'Z'},
656         {"omit", required_argument, NULL, 'O'},
657         {"file", required_argument, NULL, 'F'},
658 #if defined(HAVE_CPU_AFFINITY)
659         {"affinity", required_argument, NULL, 'A'},
660 #endif /* HAVE_CPU_AFFINITY */
661         {"title", required_argument, NULL, 'T'},
662 #if defined(HAVE_TCP_CONGESTION)
663         {"congestion", required_argument, NULL, 'C'},
664         {"linux-congestion", required_argument, NULL, 'C'},
665 #endif /* HAVE_TCP_CONGESTION */
666 #if defined(HAVE_SCTP)
667         {"sctp", no_argument, NULL, OPT_SCTP},
668         {"nstreams", required_argument, NULL, OPT_NUMSTREAMS},
669         {"xbind", required_argument, NULL, 'X'},
670 #endif
671 	{"pidfile", required_argument, NULL, 'I'},
672 	{"logfile", required_argument, NULL, OPT_LOGFILE},
673 	{"forceflush", no_argument, NULL, OPT_FORCEFLUSH},
674 	{"get-server-output", no_argument, NULL, OPT_GET_SERVER_OUTPUT},
675 	{"udp-counters-64bit", no_argument, NULL, OPT_UDP_COUNTERS_64BIT},
676  	{"no-fq-socket-pacing", no_argument, NULL, OPT_NO_FQ_SOCKET_PACING},
677 #if defined(HAVE_SSL)
678     {"username", required_argument, NULL, OPT_CLIENT_USERNAME},
679     {"rsa-public-key-path", required_argument, NULL, OPT_CLIENT_RSA_PUBLIC_KEY},
680     {"rsa-private-key-path", required_argument, NULL, OPT_SERVER_RSA_PRIVATE_KEY},
681     {"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS},
682 #endif /* HAVE_SSL */
683 	{"fq-rate", required_argument, NULL, OPT_FQ_RATE},
684         {"debug", no_argument, NULL, 'd'},
685         {"help", no_argument, NULL, 'h'},
686         {NULL, 0, NULL, 0}
687     };
688     int flag;
689     int blksize;
690     int server_flag, client_flag, rate_flag, duration_flag;
691     char *endptr;
692 #if defined(HAVE_CPU_AFFINITY)
693     char* comma;
694 #endif /* HAVE_CPU_AFFINITY */
695     char* slash;
696     struct xbind_entry *xbe;
697     double farg;
698 
699     blksize = 0;
700     server_flag = client_flag = rate_flag = duration_flag = 0;
701 #if defined(HAVE_SSL)
702     char *client_username = NULL, *client_rsa_public_key = NULL;
703 #endif /* HAVE_SSL */
704 
705     while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
706         switch (flag) {
707             case 'p':
708                 test->server_port = atoi(optarg);
709                 break;
710             case 'f':
711                 test->settings->unit_format = *optarg;
712                 break;
713             case 'i':
714                 /* XXX: could potentially want separate stat collection and reporting intervals,
715                    but just set them to be the same for now */
716                 test->stats_interval = test->reporter_interval = atof(optarg);
717                 if ((test->stats_interval < MIN_INTERVAL || test->stats_interval > MAX_INTERVAL) && test->stats_interval != 0) {
718                     i_errno = IEINTERVAL;
719                     return -1;
720                 }
721                 break;
722             case 'D':
723 		test->daemon = 1;
724 		server_flag = 1;
725 	        break;
726             case '1':
727 		test->one_off = 1;
728 		server_flag = 1;
729 	        break;
730             case 'V':
731                 test->verbose = 1;
732                 break;
733             case 'J':
734                 test->json_output = 1;
735                 break;
736             case 'v':
737                 printf("%s\n%s\n%s\n", version, get_system_info(),
738 		       get_optional_features());
739                 exit(0);
740             case 's':
741                 if (test->role == 'c') {
742                     i_errno = IESERVCLIENT;
743                     return -1;
744                 }
745 		iperf_set_test_role(test, 's');
746                 break;
747             case 'c':
748                 if (test->role == 's') {
749                     i_errno = IESERVCLIENT;
750                     return -1;
751                 }
752 		iperf_set_test_role(test, 'c');
753 		iperf_set_test_server_hostname(test, optarg);
754                 break;
755             case 'u':
756                 set_protocol(test, Pudp);
757 		client_flag = 1;
758                 break;
759             case OPT_SCTP:
760 #if defined(HAVE_SCTP)
761                 set_protocol(test, Psctp);
762                 client_flag = 1;
763                 break;
764 #else /* HAVE_SCTP */
765                 i_errno = IEUNIMP;
766                 return -1;
767 #endif /* HAVE_SCTP */
768 
769             case OPT_NUMSTREAMS:
770 #if defined(linux) || defined(__FreeBSD__)
771                 test->settings->num_ostreams = unit_atoi(optarg);
772                 client_flag = 1;
773 #else /* linux */
774                 i_errno = IEUNIMP;
775                 return -1;
776 #endif /* linux */
777             case 'b':
778 		slash = strchr(optarg, '/');
779 		if (slash) {
780 		    *slash = '\0';
781 		    ++slash;
782 		    test->settings->burst = atoi(slash);
783 		    if (test->settings->burst <= 0 ||
784 		        test->settings->burst > MAX_BURST) {
785 			i_errno = IEBURST;
786 			return -1;
787 		    }
788 		}
789                 test->settings->rate = unit_atof_rate(optarg);
790 		rate_flag = 1;
791 		client_flag = 1;
792                 break;
793             case 't':
794                 test->duration = atoi(optarg);
795                 if (test->duration > MAX_TIME) {
796                     i_errno = IEDURATION;
797                     return -1;
798                 }
799 		duration_flag = 1;
800 		client_flag = 1;
801                 break;
802             case 'n':
803                 test->settings->bytes = unit_atoi(optarg);
804 		client_flag = 1;
805                 break;
806             case 'k':
807                 test->settings->blocks = unit_atoi(optarg);
808 		client_flag = 1;
809                 break;
810             case 'l':
811                 blksize = unit_atoi(optarg);
812 		client_flag = 1;
813                 break;
814             case 'P':
815                 test->num_streams = atoi(optarg);
816                 if (test->num_streams > MAX_STREAMS) {
817                     i_errno = IENUMSTREAMS;
818                     return -1;
819                 }
820 		client_flag = 1;
821                 break;
822             case 'R':
823 		iperf_set_test_reverse(test, 1);
824 		client_flag = 1;
825                 break;
826             case 'w':
827                 // XXX: This is a socket buffer, not specific to TCP
828 		// Do sanity checks as double-precision floating point
829 		// to avoid possible integer overflows.
830                 farg = unit_atof(optarg);
831                 if (farg > (double) MAX_TCP_BUFFER) {
832                     i_errno = IEBUFSIZE;
833                     return -1;
834                 }
835                 test->settings->socket_bufsize = (int) farg;
836 		client_flag = 1;
837                 break;
838             case 'B':
839                 test->bind_address = strdup(optarg);
840                 break;
841             case OPT_CLIENT_PORT:
842                 test->bind_port = atoi(optarg);
843                 break;
844             case 'M':
845                 test->settings->mss = atoi(optarg);
846                 if (test->settings->mss > MAX_MSS) {
847                     i_errno = IEMSS;
848                     return -1;
849                 }
850 		client_flag = 1;
851                 break;
852             case 'N':
853                 test->no_delay = 1;
854 		client_flag = 1;
855                 break;
856             case '4':
857                 test->settings->domain = AF_INET;
858                 break;
859             case '6':
860                 test->settings->domain = AF_INET6;
861                 break;
862             case 'S':
863                 test->settings->tos = strtol(optarg, &endptr, 0);
864 		if (endptr == optarg ||
865 		    test->settings->tos < 0 ||
866 		    test->settings->tos > 255) {
867 		    i_errno = IEBADTOS;
868 		    return -1;
869 		}
870 		client_flag = 1;
871                 break;
872 	    case OPT_DSCP:
873                 test->settings->tos = parse_qos(optarg);
874 		if(test->settings->tos < 0) {
875 			i_errno = IEBADTOS;
876 			return -1;
877 		}
878 		client_flag = 1;
879                 break;
880             case 'L':
881 #if defined(HAVE_FLOWLABEL)
882                 test->settings->flowlabel = strtol(optarg, &endptr, 0);
883 		if (endptr == optarg ||
884 		    test->settings->flowlabel < 1 || test->settings->flowlabel > 0xfffff) {
885                     i_errno = IESETFLOW;
886                     return -1;
887 		}
888 		client_flag = 1;
889 #else /* HAVE_FLOWLABEL */
890                 i_errno = IEUNIMP;
891                 return -1;
892 #endif /* HAVE_FLOWLABEL */
893                 break;
894             case 'X':
895 		xbe = (struct xbind_entry *)malloc(sizeof(struct xbind_entry));
896                 if (!xbe) {
897 		    i_errno = IESETSCTPBINDX;
898                     return -1;
899                 }
900 	        memset(xbe, 0, sizeof(*xbe));
901                 xbe->name = strdup(optarg);
902                 if (!xbe->name) {
903 		    i_errno = IESETSCTPBINDX;
904                     return -1;
905                 }
906 		TAILQ_INSERT_TAIL(&test->xbind_addrs, xbe, link);
907                 break;
908             case 'Z':
909                 if (!has_sendfile()) {
910                     i_errno = IENOSENDFILE;
911                     return -1;
912                 }
913                 test->zerocopy = 1;
914 		client_flag = 1;
915                 break;
916             case 'O':
917                 test->omit = atoi(optarg);
918                 if (test->omit < 0 || test->omit > 60) {
919                     i_errno = IEOMIT;
920                     return -1;
921                 }
922 		client_flag = 1;
923                 break;
924             case 'F':
925                 test->diskfile_name = optarg;
926                 break;
927             case 'A':
928 #if defined(HAVE_CPU_AFFINITY)
929                 test->affinity = strtol(optarg, &endptr, 0);
930                 if (endptr == optarg ||
931 		    test->affinity < 0 || test->affinity > 1024) {
932                     i_errno = IEAFFINITY;
933                     return -1;
934                 }
935 		comma = strchr(optarg, ',');
936 		if (comma != NULL) {
937 		    test->server_affinity = atoi(comma+1);
938 		    if (test->server_affinity < 0 || test->server_affinity > 1024) {
939 			i_errno = IEAFFINITY;
940 			return -1;
941 		    }
942 		    client_flag = 1;
943 		}
944 #else /* HAVE_CPU_AFFINITY */
945                 i_errno = IEUNIMP;
946                 return -1;
947 #endif /* HAVE_CPU_AFFINITY */
948                 break;
949             case 'T':
950                 test->title = strdup(optarg);
951 		client_flag = 1;
952                 break;
953 	    case 'C':
954 #if defined(HAVE_TCP_CONGESTION)
955 		test->congestion = strdup(optarg);
956 		client_flag = 1;
957 #else /* HAVE_TCP_CONGESTION */
958 		i_errno = IEUNIMP;
959 		return -1;
960 #endif /* HAVE_TCP_CONGESTION */
961 		break;
962 	    case 'd':
963 		test->debug = 1;
964 		break;
965 	    case 'I':
966 		test->pidfile = strdup(optarg);
967 		server_flag = 1;
968 	        break;
969 	    case OPT_LOGFILE:
970 		test->logfile = strdup(optarg);
971 		break;
972 	    case OPT_FORCEFLUSH:
973 		test->forceflush = 1;
974 		break;
975 	    case OPT_GET_SERVER_OUTPUT:
976 		test->get_server_output = 1;
977 		client_flag = 1;
978 		break;
979 	    case OPT_UDP_COUNTERS_64BIT:
980 		test->udp_counters_64bit = 1;
981 		break;
982 	    case OPT_NO_FQ_SOCKET_PACING:
983 #if defined(HAVE_SO_MAX_PACING_RATE)
984 		printf("Warning:  --no-fq-socket-pacing is deprecated\n");
985 		test->settings->fqrate = 0;
986 		client_flag = 1;
987 #else /* HAVE_SO_MAX_PACING_RATE */
988 		i_errno = IEUNIMP;
989 		return -1;
990 #endif
991 		break;
992 	    case OPT_FQ_RATE:
993 #if defined(HAVE_SO_MAX_PACING_RATE)
994 		test->settings->fqrate = unit_atof_rate(optarg);
995 		client_flag = 1;
996 #else /* HAVE_SO_MAX_PACING_RATE */
997 		i_errno = IEUNIMP;
998 		return -1;
999 #endif
1000 		break;
1001 #if defined(HAVE_SSL)
1002         case OPT_CLIENT_USERNAME:
1003             client_username = strdup(optarg);
1004             break;
1005         case OPT_CLIENT_RSA_PUBLIC_KEY:
1006             client_rsa_public_key = strdup(optarg);
1007             break;
1008         case OPT_SERVER_RSA_PRIVATE_KEY:
1009             test->server_rsa_private_key = strdup(optarg);
1010             break;
1011         case OPT_SERVER_AUTHORIZED_USERS:
1012             test->server_authorized_users = strdup(optarg);
1013             break;
1014 #endif /* HAVE_SSL */
1015             case 'h':
1016 		usage_long(stdout);
1017 		exit(0);
1018             default:
1019                 usage_long(stderr);
1020                 exit(1);
1021         }
1022     }
1023 
1024     /* Set logging to a file if specified, otherwise use the default (stdout) */
1025     if (test->logfile) {
1026         test->outfile = fopen(test->logfile, "a+");
1027         if (test->outfile == NULL) {
1028             i_errno = IELOGFILE;
1029             return -1;
1030         }
1031     }
1032 
1033     /* Check flag / role compatibility. */
1034     if (test->role == 'c' && server_flag) {
1035         i_errno = IESERVERONLY;
1036         return -1;
1037     }
1038     if (test->role == 's' && client_flag) {
1039         i_errno = IECLIENTONLY;
1040         return -1;
1041     }
1042 
1043 #if defined(HAVE_SSL)
1044 
1045     if (test->role == 's' && (client_username || client_rsa_public_key)){
1046         i_errno = IECLIENTONLY;
1047         return -1;
1048     } else if (test->role == 'c' && (client_username || client_rsa_public_key) &&
1049         !(client_username && client_rsa_public_key)) {
1050         i_errno = IESETCLIENTAUTH;
1051         return -1;
1052     } else if (test->role == 'c' && (client_username && client_rsa_public_key)){
1053 
1054         char *client_password = NULL;
1055         size_t s;
1056         if (iperf_getpass(&client_password, &s, stdin) < 0){
1057             return -1;
1058         }
1059 
1060         if (strlen(client_username) > 20 || strlen(client_password) > 20){
1061             i_errno = IESETCLIENTAUTH;
1062             return -1;
1063         }
1064 
1065         if (test_load_pubkey(client_rsa_public_key) < 0){
1066             i_errno = IESETCLIENTAUTH;
1067             return -1;
1068         }
1069         encode_auth_setting(client_username, client_password, client_rsa_public_key, &test->settings->authtoken);
1070     }
1071 
1072     if (test->role == 'c' && (test->server_rsa_private_key || test->server_authorized_users)){
1073         i_errno = IESERVERONLY;
1074         return -1;
1075     } else if (test->role == 's' && (test->server_rsa_private_key || test->server_authorized_users) &&
1076         !(test->server_rsa_private_key && test->server_authorized_users)) {
1077          i_errno = IESETSERVERAUTH;
1078         return -1;
1079     } else if (test->role == 's' && test->server_rsa_private_key && test_load_private_key(test->server_rsa_private_key) < 0){
1080         i_errno = IESETSERVERAUTH;
1081         return -1;
1082     }
1083 #endif //HAVE_SSL
1084     if (!test->bind_address && test->bind_port) {
1085         i_errno = IEBIND;
1086         return -1;
1087     }
1088     if (blksize == 0) {
1089 	if (test->protocol->id == Pudp)
1090 	    blksize = 0;	/* try to dynamically determine from MSS */
1091 	else if (test->protocol->id == Psctp)
1092 	    blksize = DEFAULT_SCTP_BLKSIZE;
1093 	else
1094 	    blksize = DEFAULT_TCP_BLKSIZE;
1095     }
1096     if ((test->protocol->id != Pudp && blksize <= 0)
1097 	|| blksize > MAX_BLOCKSIZE) {
1098 	i_errno = IEBLOCKSIZE;
1099 	return -1;
1100     }
1101     if (test->protocol->id == Pudp &&
1102 	(blksize > 0 &&
1103 	    (blksize < MIN_UDP_BLOCKSIZE || blksize > MAX_UDP_BLOCKSIZE))) {
1104 	i_errno = IEUDPBLOCKSIZE;
1105 	return -1;
1106     }
1107     test->settings->blksize = blksize;
1108 
1109     if (!rate_flag)
1110 	test->settings->rate = test->protocol->id == Pudp ? UDP_RATE : 0;
1111 
1112     if ((test->settings->bytes != 0 || test->settings->blocks != 0) && ! duration_flag)
1113         test->duration = 0;
1114 
1115     /* Disallow specifying multiple test end conditions. The code actually
1116     ** works just fine without this prohibition. As soon as any one of the
1117     ** three possible end conditions is met, the test ends. So this check
1118     ** could be removed if desired.
1119     */
1120     if ((duration_flag && test->settings->bytes != 0) ||
1121         (duration_flag && test->settings->blocks != 0) ||
1122 	(test->settings->bytes != 0 && test->settings->blocks != 0)) {
1123         i_errno = IEENDCONDITIONS;
1124         return -1;
1125     }
1126 
1127     /* For subsequent calls to getopt */
1128 #ifdef __APPLE__
1129     optreset = 1;
1130 #endif
1131     optind = 0;
1132 
1133     if ((test->role != 'c') && (test->role != 's')) {
1134         i_errno = IENOROLE;
1135         return -1;
1136     }
1137 
1138     return 0;
1139 }
1140 
1141 int
1142 iperf_set_send_state(struct iperf_test *test, signed char state)
1143 {
1144     test->state = state;
1145     if (Nwrite(test->ctrl_sck, (char*) &state, sizeof(state), Ptcp) < 0) {
1146 	i_errno = IESENDMESSAGE;
1147 	return -1;
1148     }
1149     return 0;
1150 }
1151 
1152 void
1153 iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP)
1154 {
1155     double seconds;
1156     uint64_t bits_per_second;
1157 
1158     if (sp->test->done)
1159         return;
1160     seconds = timeval_diff(&sp->result->start_time_fixed, nowP);
1161     bits_per_second = sp->result->bytes_sent * 8 / seconds;
1162     if (bits_per_second < sp->test->settings->rate) {
1163         sp->green_light = 1;
1164         FD_SET(sp->socket, &sp->test->write_set);
1165     } else {
1166         sp->green_light = 0;
1167         FD_CLR(sp->socket, &sp->test->write_set);
1168     }
1169 }
1170 
1171 int
1172 iperf_send(struct iperf_test *test, fd_set *write_setP)
1173 {
1174     register int multisend, r, streams_active;
1175     register struct iperf_stream *sp;
1176     struct timeval now;
1177 
1178     /* Can we do multisend mode? */
1179     if (test->settings->burst != 0)
1180         multisend = test->settings->burst;
1181     else if (test->settings->rate == 0)
1182         multisend = test->multisend;
1183     else
1184         multisend = 1;	/* nope */
1185 
1186     for (; multisend > 0; --multisend) {
1187 	if (test->settings->rate != 0 && test->settings->burst == 0)
1188 	    gettimeofday(&now, NULL);
1189 	streams_active = 0;
1190 	SLIST_FOREACH(sp, &test->streams, streams) {
1191 	    if ((sp->green_light &&
1192 		 (write_setP == NULL || FD_ISSET(sp->socket, write_setP)))) {
1193 		if ((r = sp->snd(sp)) < 0) {
1194 		    if (r == NET_SOFTERROR)
1195 			break;
1196 		    i_errno = IESTREAMWRITE;
1197 		    return r;
1198 		}
1199 		streams_active = 1;
1200 		test->bytes_sent += r;
1201 		++test->blocks_sent;
1202 		if (test->settings->rate != 0 && test->settings->burst == 0)
1203 		    iperf_check_throttle(sp, &now);
1204 		if (multisend > 1 && test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes)
1205 		    break;
1206 		if (multisend > 1 && test->settings->blocks != 0 && test->blocks_sent >= test->settings->blocks)
1207 		    break;
1208 	    }
1209 	}
1210 	if (!streams_active)
1211 	    break;
1212     }
1213     if (test->settings->burst != 0) {
1214 	gettimeofday(&now, NULL);
1215 	SLIST_FOREACH(sp, &test->streams, streams)
1216 	    iperf_check_throttle(sp, &now);
1217     }
1218     if (write_setP != NULL)
1219 	SLIST_FOREACH(sp, &test->streams, streams)
1220 	    if (FD_ISSET(sp->socket, write_setP))
1221 		FD_CLR(sp->socket, write_setP);
1222 
1223     return 0;
1224 }
1225 
1226 int
1227 iperf_recv(struct iperf_test *test, fd_set *read_setP)
1228 {
1229     int r;
1230     struct iperf_stream *sp;
1231 
1232     SLIST_FOREACH(sp, &test->streams, streams) {
1233 	if (FD_ISSET(sp->socket, read_setP)) {
1234 	    if ((r = sp->rcv(sp)) < 0) {
1235 		i_errno = IESTREAMREAD;
1236 		return r;
1237 	    }
1238 	    test->bytes_sent += r;
1239 	    ++test->blocks_sent;
1240 	    FD_CLR(sp->socket, read_setP);
1241 	}
1242     }
1243 
1244     return 0;
1245 }
1246 
1247 int
1248 iperf_init_test(struct iperf_test *test)
1249 {
1250     struct timeval now;
1251     struct iperf_stream *sp;
1252 
1253     if (test->protocol->init) {
1254         if (test->protocol->init(test) < 0)
1255             return -1;
1256     }
1257 
1258     /* Init each stream. */
1259     if (gettimeofday(&now, NULL) < 0) {
1260 	i_errno = IEINITTEST;
1261 	return -1;
1262     }
1263     SLIST_FOREACH(sp, &test->streams, streams) {
1264 	sp->result->start_time = sp->result->start_time_fixed = now;
1265     }
1266 
1267     if (test->on_test_start)
1268         test->on_test_start(test);
1269 
1270     return 0;
1271 }
1272 
1273 static void
1274 send_timer_proc(TimerClientData client_data, struct timeval *nowP)
1275 {
1276     struct iperf_stream *sp = client_data.p;
1277 
1278     /* All we do here is set or clear the flag saying that this stream may
1279     ** be sent to.  The actual sending gets done in the send proc, after
1280     ** checking the flag.
1281     */
1282     iperf_check_throttle(sp, nowP);
1283 }
1284 
1285 int
1286 iperf_create_send_timers(struct iperf_test * test)
1287 {
1288     struct timeval now;
1289     struct iperf_stream *sp;
1290     TimerClientData cd;
1291 
1292     if (gettimeofday(&now, NULL) < 0) {
1293 	i_errno = IEINITTEST;
1294 	return -1;
1295     }
1296     SLIST_FOREACH(sp, &test->streams, streams) {
1297         sp->green_light = 1;
1298 	if (test->settings->rate != 0) {
1299 	    cd.p = sp;
1300 	    /* (Repeat every millisecond - arbitrary value to provide smooth pacing.) */
1301 	    sp->send_timer = tmr_create((struct timeval*) 0, send_timer_proc, cd, 1000L, 1);
1302 	    if (sp->send_timer == NULL) {
1303 		i_errno = IEINITTEST;
1304 		return -1;
1305 	    }
1306 	}
1307     }
1308     return 0;
1309 }
1310 
1311 #if defined(HAVE_SSL)
1312 int test_is_authorized(struct iperf_test *test){
1313     if ( !(test->server_rsa_private_key && test->server_authorized_users)) {
1314         return 0;
1315     }
1316 
1317     if (test->settings->authtoken){
1318         char *username = NULL, *password = NULL;
1319         time_t ts;
1320         decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts);
1321         int ret = check_authentication(username, password, ts, test->server_authorized_users);
1322         if (ret == 0){
1323             iperf_printf(test, report_authetication_successed, username, ts);
1324             return 0;
1325         } else {
1326             iperf_printf(test, report_authetication_failed, username, ts);
1327             return -1;
1328         }
1329     }
1330     return -1;
1331 }
1332 #endif //HAVE_SSL
1333 
1334 /**
1335  * iperf_exchange_parameters - handles the param_Exchange part for client
1336  *
1337  */
1338 
1339 int
1340 iperf_exchange_parameters(struct iperf_test *test)
1341 {
1342     int s;
1343     int32_t err;
1344 
1345     if (test->role == 'c') {
1346 
1347         if (send_parameters(test) < 0)
1348             return -1;
1349 
1350     } else {
1351 
1352         if (get_parameters(test) < 0)
1353             return -1;
1354 
1355 #if defined(HAVE_SSL)
1356         if (test_is_authorized(test) < 0){
1357             if (iperf_set_send_state(test, SERVER_ERROR) != 0)
1358                 return -1;
1359             i_errno = IEAUTHTEST;
1360             err = htonl(i_errno);
1361             if (Nwrite(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) {
1362                 i_errno = IECTRLWRITE;
1363                 return -1;
1364             }
1365             return -1;
1366         }
1367 #endif //HAVE_SSL
1368 
1369         if ((s = test->protocol->listen(test)) < 0) {
1370 	        if (iperf_set_send_state(test, SERVER_ERROR) != 0)
1371                 return -1;
1372             err = htonl(i_errno);
1373             if (Nwrite(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) {
1374                 i_errno = IECTRLWRITE;
1375                 return -1;
1376             }
1377             err = htonl(errno);
1378             if (Nwrite(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) {
1379                 i_errno = IECTRLWRITE;
1380                 return -1;
1381             }
1382             return -1;
1383         }
1384         FD_SET(s, &test->read_set);
1385         test->max_fd = (s > test->max_fd) ? s : test->max_fd;
1386         test->prot_listener = s;
1387 
1388         // Send the control message to create streams and start the test
1389 	if (iperf_set_send_state(test, CREATE_STREAMS) != 0)
1390             return -1;
1391 
1392     }
1393 
1394     return 0;
1395 }
1396 
1397 /*************************************************************/
1398 
1399 int
1400 iperf_exchange_results(struct iperf_test *test)
1401 {
1402     if (test->role == 'c') {
1403         /* Send results to server. */
1404 	if (send_results(test) < 0)
1405             return -1;
1406         /* Get server results. */
1407         if (get_results(test) < 0)
1408             return -1;
1409     } else {
1410         /* Get client results. */
1411         if (get_results(test) < 0)
1412             return -1;
1413         /* Send results to client. */
1414 	if (send_results(test) < 0)
1415             return -1;
1416     }
1417     return 0;
1418 }
1419 
1420 /*************************************************************/
1421 
1422 static int
1423 send_parameters(struct iperf_test *test)
1424 {
1425     int r = 0;
1426     cJSON *j;
1427 
1428     j = cJSON_CreateObject();
1429     if (j == NULL) {
1430 	i_errno = IESENDPARAMS;
1431 	r = -1;
1432     } else {
1433 	if (test->protocol->id == Ptcp)
1434 	    cJSON_AddTrueToObject(j, "tcp");
1435 	else if (test->protocol->id == Pudp)
1436 	    cJSON_AddTrueToObject(j, "udp");
1437         else if (test->protocol->id == Psctp)
1438             cJSON_AddTrueToObject(j, "sctp");
1439 	cJSON_AddNumberToObject(j, "omit", test->omit);
1440 	if (test->server_affinity != -1)
1441 	    cJSON_AddNumberToObject(j, "server_affinity", test->server_affinity);
1442 	if (test->duration)
1443 	    cJSON_AddNumberToObject(j, "time", test->duration);
1444 	if (test->settings->bytes)
1445 	    cJSON_AddNumberToObject(j, "num", test->settings->bytes);
1446 	if (test->settings->blocks)
1447 	    cJSON_AddNumberToObject(j, "blockcount", test->settings->blocks);
1448 	if (test->settings->mss)
1449 	    cJSON_AddNumberToObject(j, "MSS", test->settings->mss);
1450 	if (test->no_delay)
1451 	    cJSON_AddTrueToObject(j, "nodelay");
1452 	cJSON_AddNumberToObject(j, "parallel", test->num_streams);
1453 	if (test->reverse)
1454 	    cJSON_AddTrueToObject(j, "reverse");
1455 	if (test->settings->socket_bufsize)
1456 	    cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize);
1457 	if (test->settings->blksize)
1458 	    cJSON_AddNumberToObject(j, "len", test->settings->blksize);
1459 	if (test->settings->rate)
1460 	    cJSON_AddNumberToObject(j, "bandwidth", test->settings->rate);
1461 	if (test->settings->fqrate)
1462 	    cJSON_AddNumberToObject(j, "fqrate", test->settings->fqrate);
1463 	if (test->settings->burst)
1464 	    cJSON_AddNumberToObject(j, "burst", test->settings->burst);
1465 	if (test->settings->tos)
1466 	    cJSON_AddNumberToObject(j, "TOS", test->settings->tos);
1467 	if (test->settings->flowlabel)
1468 	    cJSON_AddNumberToObject(j, "flowlabel", test->settings->flowlabel);
1469 	if (test->title)
1470 	    cJSON_AddStringToObject(j, "title", test->title);
1471 	if (test->congestion)
1472 	    cJSON_AddStringToObject(j, "congestion", test->congestion);
1473 	if (test->congestion_used)
1474 	    cJSON_AddStringToObject(j, "congestion_used", test->congestion_used);
1475 	if (test->get_server_output)
1476 	    cJSON_AddNumberToObject(j, "get_server_output", iperf_get_test_get_server_output(test));
1477 	if (test->udp_counters_64bit)
1478 	    cJSON_AddNumberToObject(j, "udp_counters_64bit", iperf_get_test_udp_counters_64bit(test));
1479 #if defined(HAVE_SSL)
1480     if (test->settings->authtoken)
1481         cJSON_AddStringToObject(j, "authtoken", test->settings->authtoken);
1482 #endif // HAVE_SSL
1483 	cJSON_AddStringToObject(j, "client_version", IPERF_VERSION);
1484 
1485 	if (test->debug) {
1486 	    printf("send_parameters:\n%s\n", cJSON_Print(j));
1487 	}
1488 
1489 	if (JSON_write(test->ctrl_sck, j) < 0) {
1490 	    i_errno = IESENDPARAMS;
1491 	    r = -1;
1492 	}
1493 	cJSON_Delete(j);
1494     }
1495     return r;
1496 }
1497 
1498 /*************************************************************/
1499 
1500 static int
1501 get_parameters(struct iperf_test *test)
1502 {
1503     int r = 0;
1504     cJSON *j;
1505     cJSON *j_p;
1506 
1507     j = JSON_read(test->ctrl_sck);
1508     if (j == NULL) {
1509 	i_errno = IERECVPARAMS;
1510         r = -1;
1511     } else {
1512 	if (test->debug) {
1513 	    printf("get_parameters:\n%s\n", cJSON_Print(j));
1514 	}
1515 
1516 	if ((j_p = cJSON_GetObjectItem(j, "tcp")) != NULL)
1517 	    set_protocol(test, Ptcp);
1518 	if ((j_p = cJSON_GetObjectItem(j, "udp")) != NULL)
1519 	    set_protocol(test, Pudp);
1520         if ((j_p = cJSON_GetObjectItem(j, "sctp")) != NULL)
1521             set_protocol(test, Psctp);
1522 	if ((j_p = cJSON_GetObjectItem(j, "omit")) != NULL)
1523 	    test->omit = j_p->valueint;
1524 	if ((j_p = cJSON_GetObjectItem(j, "server_affinity")) != NULL)
1525 	    test->server_affinity = j_p->valueint;
1526 	if ((j_p = cJSON_GetObjectItem(j, "time")) != NULL)
1527 	    test->duration = j_p->valueint;
1528 	if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL)
1529 	    test->settings->bytes = j_p->valueint;
1530 	if ((j_p = cJSON_GetObjectItem(j, "blockcount")) != NULL)
1531 	    test->settings->blocks = j_p->valueint;
1532 	if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL)
1533 	    test->settings->mss = j_p->valueint;
1534 	if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL)
1535 	    test->no_delay = 1;
1536 	if ((j_p = cJSON_GetObjectItem(j, "parallel")) != NULL)
1537 	    test->num_streams = j_p->valueint;
1538 	if ((j_p = cJSON_GetObjectItem(j, "reverse")) != NULL)
1539 	    iperf_set_test_reverse(test, 1);
1540 	if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL)
1541 	    test->settings->socket_bufsize = j_p->valueint;
1542 	if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL)
1543 	    test->settings->blksize = j_p->valueint;
1544 	if ((j_p = cJSON_GetObjectItem(j, "bandwidth")) != NULL)
1545 	    test->settings->rate = j_p->valueint;
1546 	if ((j_p = cJSON_GetObjectItem(j, "fqrate")) != NULL)
1547 	    test->settings->fqrate = j_p->valueint;
1548 	if ((j_p = cJSON_GetObjectItem(j, "burst")) != NULL)
1549 	    test->settings->burst = j_p->valueint;
1550 	if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL)
1551 	    test->settings->tos = j_p->valueint;
1552 	if ((j_p = cJSON_GetObjectItem(j, "flowlabel")) != NULL)
1553 	    test->settings->flowlabel = j_p->valueint;
1554 	if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL)
1555 	    test->title = strdup(j_p->valuestring);
1556 	if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL)
1557 	    test->congestion = strdup(j_p->valuestring);
1558 	if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL)
1559 	    test->congestion_used = strdup(j_p->valuestring);
1560 	if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL)
1561 	    iperf_set_test_get_server_output(test, 1);
1562 	if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL)
1563 	    iperf_set_test_udp_counters_64bit(test, 1);
1564 #if defined(HAVE_SSL)
1565 	if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL)
1566         test->settings->authtoken = strdup(j_p->valuestring);
1567 #endif //HAVE_SSL
1568 	if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
1569 	    test->sender_has_retransmits = 1;
1570 	cJSON_Delete(j);
1571     }
1572     return r;
1573 }
1574 
1575 /*************************************************************/
1576 
1577 static int
1578 send_results(struct iperf_test *test)
1579 {
1580     int r = 0;
1581     cJSON *j;
1582     cJSON *j_streams;
1583     struct iperf_stream *sp;
1584     cJSON *j_stream;
1585     int sender_has_retransmits;
1586     iperf_size_t bytes_transferred;
1587     int retransmits;
1588 
1589     j = cJSON_CreateObject();
1590     if (j == NULL) {
1591 	i_errno = IEPACKAGERESULTS;
1592 	r = -1;
1593     } else {
1594 	cJSON_AddNumberToObject(j, "cpu_util_total", test->cpu_util[0]);
1595 	cJSON_AddNumberToObject(j, "cpu_util_user", test->cpu_util[1]);
1596 	cJSON_AddNumberToObject(j, "cpu_util_system", test->cpu_util[2]);
1597 	if ( ! test->sender )
1598 	    sender_has_retransmits = -1;
1599 	else
1600 	    sender_has_retransmits = test->sender_has_retransmits;
1601 	cJSON_AddNumberToObject(j, "sender_has_retransmits", sender_has_retransmits);
1602 	if ( test->congestion_used ) {
1603 	    cJSON_AddStringToObject(j, "congestion_used", test->congestion_used);
1604 	}
1605 
1606 	/* If on the server and sending server output, then do this */
1607 	if (test->role == 's' && test->get_server_output) {
1608 	    if (test->json_output) {
1609 		/* Add JSON output */
1610 		cJSON_AddItemReferenceToObject(j, "server_output_json", test->json_top);
1611 	    }
1612 	    else {
1613 		/* Add textual output */
1614 		size_t buflen = 0;
1615 
1616 		/* Figure out how much room we need to hold the complete output string */
1617 		struct iperf_textline *t;
1618 		TAILQ_FOREACH(t, &(test->server_output_list), textlineentries) {
1619 		    buflen += strlen(t->line);
1620 		}
1621 
1622 		/* Allocate and build it up from the component lines */
1623 		char *output = calloc(buflen + 1, 1);
1624 		TAILQ_FOREACH(t, &(test->server_output_list), textlineentries) {
1625 		    strncat(output, t->line, buflen);
1626 		    buflen -= strlen(t->line);
1627 		}
1628 
1629 		cJSON_AddStringToObject(j, "server_output_text", output);
1630         free(output);
1631 	    }
1632 	}
1633 
1634 	j_streams = cJSON_CreateArray();
1635 	if (j_streams == NULL) {
1636 	    i_errno = IEPACKAGERESULTS;
1637 	    r = -1;
1638 	} else {
1639 	    cJSON_AddItemToObject(j, "streams", j_streams);
1640 	    SLIST_FOREACH(sp, &test->streams, streams) {
1641 		j_stream = cJSON_CreateObject();
1642 		if (j_stream == NULL) {
1643 		    i_errno = IEPACKAGERESULTS;
1644 		    r = -1;
1645 		} else {
1646 		    cJSON_AddItemToArray(j_streams, j_stream);
1647 		    bytes_transferred = test->sender ? (sp->result->bytes_sent - sp->result->bytes_sent_omit) : sp->result->bytes_received;
1648 		    retransmits = (test->sender && test->sender_has_retransmits) ? sp->result->stream_retrans : -1;
1649 		    cJSON_AddNumberToObject(j_stream, "id", sp->id);
1650 		    cJSON_AddNumberToObject(j_stream, "bytes", bytes_transferred);
1651 		    cJSON_AddNumberToObject(j_stream, "retransmits", retransmits);
1652 		    cJSON_AddNumberToObject(j_stream, "jitter", sp->jitter);
1653 		    cJSON_AddNumberToObject(j_stream, "errors", sp->cnt_error);
1654 		    cJSON_AddNumberToObject(j_stream, "packets", sp->packet_count);
1655 		}
1656 	    }
1657 	    if (r == 0 && test->debug) {
1658 		printf("send_results\n%s\n", cJSON_Print(j));
1659 	    }
1660 	    if (r == 0 && JSON_write(test->ctrl_sck, j) < 0) {
1661 		i_errno = IESENDRESULTS;
1662 		r = -1;
1663 	    }
1664 	}
1665 	cJSON_Delete(j);
1666     }
1667     return r;
1668 }
1669 
1670 /*************************************************************/
1671 
1672 static int
1673 get_results(struct iperf_test *test)
1674 {
1675     int r = 0;
1676     cJSON *j;
1677     cJSON *j_cpu_util_total;
1678     cJSON *j_cpu_util_user;
1679     cJSON *j_cpu_util_system;
1680     cJSON *j_remote_congestion_used;
1681     cJSON *j_sender_has_retransmits;
1682     int result_has_retransmits;
1683     cJSON *j_streams;
1684     int n, i;
1685     cJSON *j_stream;
1686     cJSON *j_id;
1687     cJSON *j_bytes;
1688     cJSON *j_retransmits;
1689     cJSON *j_jitter;
1690     cJSON *j_errors;
1691     cJSON *j_packets;
1692     cJSON *j_server_output;
1693     int sid, cerror, pcount;
1694     double jitter;
1695     iperf_size_t bytes_transferred;
1696     int retransmits;
1697     struct iperf_stream *sp;
1698 
1699     j = JSON_read(test->ctrl_sck);
1700     if (j == NULL) {
1701 	i_errno = IERECVRESULTS;
1702         r = -1;
1703     } else {
1704 	j_cpu_util_total = cJSON_GetObjectItem(j, "cpu_util_total");
1705 	j_cpu_util_user = cJSON_GetObjectItem(j, "cpu_util_user");
1706 	j_cpu_util_system = cJSON_GetObjectItem(j, "cpu_util_system");
1707 	j_sender_has_retransmits = cJSON_GetObjectItem(j, "sender_has_retransmits");
1708 	if (j_cpu_util_total == NULL || j_cpu_util_user == NULL || j_cpu_util_system == NULL || j_sender_has_retransmits == NULL) {
1709 	    i_errno = IERECVRESULTS;
1710 	    r = -1;
1711 	} else {
1712 	    if (test->debug) {
1713 		printf("get_results\n%s\n", cJSON_Print(j));
1714 	    }
1715 
1716 	    test->remote_cpu_util[0] = j_cpu_util_total->valuedouble;
1717 	    test->remote_cpu_util[1] = j_cpu_util_user->valuedouble;
1718 	    test->remote_cpu_util[2] = j_cpu_util_system->valuedouble;
1719 	    result_has_retransmits = j_sender_has_retransmits->valueint;
1720 	    if (! test->sender)
1721 		test->sender_has_retransmits = result_has_retransmits;
1722 	    j_streams = cJSON_GetObjectItem(j, "streams");
1723 	    if (j_streams == NULL) {
1724 		i_errno = IERECVRESULTS;
1725 		r = -1;
1726 	    } else {
1727 	        n = cJSON_GetArraySize(j_streams);
1728 		for (i=0; i<n; ++i) {
1729 		    j_stream = cJSON_GetArrayItem(j_streams, i);
1730 		    if (j_stream == NULL) {
1731 			i_errno = IERECVRESULTS;
1732 			r = -1;
1733 		    } else {
1734 			j_id = cJSON_GetObjectItem(j_stream, "id");
1735 			j_bytes = cJSON_GetObjectItem(j_stream, "bytes");
1736 			j_retransmits = cJSON_GetObjectItem(j_stream, "retransmits");
1737 			j_jitter = cJSON_GetObjectItem(j_stream, "jitter");
1738 			j_errors = cJSON_GetObjectItem(j_stream, "errors");
1739 			j_packets = cJSON_GetObjectItem(j_stream, "packets");
1740 			if (j_id == NULL || j_bytes == NULL || j_retransmits == NULL || j_jitter == NULL || j_errors == NULL || j_packets == NULL) {
1741 			    i_errno = IERECVRESULTS;
1742 			    r = -1;
1743 			} else {
1744 			    sid = j_id->valueint;
1745 			    bytes_transferred = j_bytes->valueint;
1746 			    retransmits = j_retransmits->valueint;
1747 			    jitter = j_jitter->valuedouble;
1748 			    cerror = j_errors->valueint;
1749 			    pcount = j_packets->valueint;
1750 			    SLIST_FOREACH(sp, &test->streams, streams)
1751 				if (sp->id == sid) break;
1752 			    if (sp == NULL) {
1753 				i_errno = IESTREAMID;
1754 				r = -1;
1755 			    } else {
1756 				if (test->sender) {
1757 				    sp->jitter = jitter;
1758 				    sp->cnt_error = cerror;
1759 				    sp->packet_count = pcount;
1760 				    sp->result->bytes_received = bytes_transferred;
1761 				} else {
1762 				    sp->result->bytes_sent = bytes_transferred;
1763 				    sp->result->stream_retrans = retransmits;
1764 				}
1765 			    }
1766 			}
1767 		    }
1768 		}
1769 		/*
1770 		 * If we're the client and we're supposed to get remote results,
1771 		 * look them up and process accordingly.
1772 		 */
1773 		if (test->role == 'c' && iperf_get_test_get_server_output(test)) {
1774 		    /* Look for JSON.  If we find it, grab the object so it doesn't get deleted. */
1775 		    j_server_output = cJSON_DetachItemFromObject(j, "server_output_json");
1776 		    if (j_server_output != NULL) {
1777 			test->json_server_output = j_server_output;
1778 		    }
1779 		    else {
1780 			/* No JSON, look for textual output.  Make a copy of the text for later. */
1781 			j_server_output = cJSON_GetObjectItem(j, "server_output_text");
1782 			if (j_server_output != NULL) {
1783 			    test->server_output_text = strdup(j_server_output->valuestring);
1784 			}
1785 		    }
1786 		}
1787 	    }
1788 	}
1789 
1790 	j_remote_congestion_used = cJSON_GetObjectItem(j, "congestion_used");
1791 	if (j_remote_congestion_used != NULL) {
1792 	    test->remote_congestion_used = strdup(j_remote_congestion_used->valuestring);
1793 	}
1794 
1795 	cJSON_Delete(j);
1796     }
1797     return r;
1798 }
1799 
1800 /*************************************************************/
1801 
1802 static int
1803 JSON_write(int fd, cJSON *json)
1804 {
1805     uint32_t hsize, nsize;
1806     char *str;
1807     int r = 0;
1808 
1809     str = cJSON_PrintUnformatted(json);
1810     if (str == NULL)
1811 	r = -1;
1812     else {
1813 	hsize = strlen(str);
1814 	nsize = htonl(hsize);
1815 	if (Nwrite(fd, (char*) &nsize, sizeof(nsize), Ptcp) < 0)
1816 	    r = -1;
1817 	else {
1818 	    if (Nwrite(fd, str, hsize, Ptcp) < 0)
1819 		r = -1;
1820 	}
1821 	free(str);
1822     }
1823     return r;
1824 }
1825 
1826 /*************************************************************/
1827 
1828 static cJSON *
1829 JSON_read(int fd)
1830 {
1831     uint32_t hsize, nsize;
1832     char *str;
1833     cJSON *json = NULL;
1834     int rc;
1835 
1836     /*
1837      * Read a four-byte integer, which is the length of the JSON to follow.
1838      * Then read the JSON into a buffer and parse it.  Return a parsed JSON
1839      * structure, NULL if there was an error.
1840      */
1841     if (Nread(fd, (char*) &nsize, sizeof(nsize), Ptcp) >= 0) {
1842 	hsize = ntohl(nsize);
1843 	/* Allocate a buffer to hold the JSON */
1844 	str = (char *) calloc(sizeof(char), hsize+1);	/* +1 for trailing null */
1845 	if (str != NULL) {
1846 	    rc = Nread(fd, str, hsize, Ptcp);
1847 	    if (rc >= 0) {
1848 		/*
1849 		 * We should be reading in the number of bytes corresponding to the
1850 		 * length in that 4-byte integer.  If we don't the socket might have
1851 		 * prematurely closed.  Only do the JSON parsing if we got the
1852 		 * correct number of bytes.
1853 		 */
1854 		if (rc == hsize) {
1855 		    json = cJSON_Parse(str);
1856 		}
1857 		else {
1858 		    printf("WARNING:  Size of data read does not correspond to offered length\n");
1859 		}
1860 	    }
1861 	}
1862 	free(str);
1863     }
1864     return json;
1865 }
1866 
1867 /*************************************************************/
1868 /**
1869  * add_to_interval_list -- adds new interval to the interval_list
1870  */
1871 
1872 void
1873 add_to_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results * new)
1874 {
1875     struct iperf_interval_results *irp;
1876 
1877     irp = (struct iperf_interval_results *) malloc(sizeof(struct iperf_interval_results));
1878     memcpy(irp, new, sizeof(struct iperf_interval_results));
1879     TAILQ_INSERT_TAIL(&rp->interval_results, irp, irlistentries);
1880 }
1881 
1882 
1883 /************************************************************/
1884 
1885 /**
1886  * connect_msg -- displays connection message
1887  * denoting sender/receiver details
1888  *
1889  */
1890 
1891 void
1892 connect_msg(struct iperf_stream *sp)
1893 {
1894     char ipl[INET6_ADDRSTRLEN], ipr[INET6_ADDRSTRLEN];
1895     int lport, rport;
1896 
1897     if (getsockdomain(sp->socket) == AF_INET) {
1898         inet_ntop(AF_INET, (void *) &((struct sockaddr_in *) &sp->local_addr)->sin_addr, ipl, sizeof(ipl));
1899 	mapped_v4_to_regular_v4(ipl);
1900         inet_ntop(AF_INET, (void *) &((struct sockaddr_in *) &sp->remote_addr)->sin_addr, ipr, sizeof(ipr));
1901 	mapped_v4_to_regular_v4(ipr);
1902         lport = ntohs(((struct sockaddr_in *) &sp->local_addr)->sin_port);
1903         rport = ntohs(((struct sockaddr_in *) &sp->remote_addr)->sin_port);
1904     } else {
1905         inet_ntop(AF_INET6, (void *) &((struct sockaddr_in6 *) &sp->local_addr)->sin6_addr, ipl, sizeof(ipl));
1906 	mapped_v4_to_regular_v4(ipl);
1907         inet_ntop(AF_INET6, (void *) &((struct sockaddr_in6 *) &sp->remote_addr)->sin6_addr, ipr, sizeof(ipr));
1908 	mapped_v4_to_regular_v4(ipr);
1909         lport = ntohs(((struct sockaddr_in6 *) &sp->local_addr)->sin6_port);
1910         rport = ntohs(((struct sockaddr_in6 *) &sp->remote_addr)->sin6_port);
1911     }
1912 
1913     if (sp->test->json_output)
1914         cJSON_AddItemToArray(sp->test->json_connected, iperf_json_printf("socket: %d  local_host: %s  local_port: %d  remote_host: %s  remote_port: %d", (int64_t) sp->socket, ipl, (int64_t) lport, ipr, (int64_t) rport));
1915     else
1916 	iperf_printf(sp->test, report_connected, sp->socket, ipl, lport, ipr, rport);
1917 }
1918 
1919 
1920 /**************************************************************************/
1921 
1922 struct iperf_test *
1923 iperf_new_test()
1924 {
1925     struct iperf_test *test;
1926 
1927     test = (struct iperf_test *) malloc(sizeof(struct iperf_test));
1928     if (!test) {
1929         i_errno = IENEWTEST;
1930         return NULL;
1931     }
1932     /* initialize everything to zero */
1933     memset(test, 0, sizeof(struct iperf_test));
1934 
1935     test->settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings));
1936     if (!test->settings) {
1937         free(test);
1938 	i_errno = IENEWTEST;
1939 	return NULL;
1940     }
1941     memset(test->settings, 0, sizeof(struct iperf_settings));
1942 
1943     /* By default all output goes to stdout */
1944     test->outfile = stdout;
1945 
1946     return test;
1947 }
1948 
1949 /**************************************************************************/
1950 
1951 struct protocol *
1952 protocol_new(void)
1953 {
1954     struct protocol *proto;
1955 
1956     proto = malloc(sizeof(struct protocol));
1957     if(!proto) {
1958         return NULL;
1959     }
1960     memset(proto, 0, sizeof(struct protocol));
1961 
1962     return proto;
1963 }
1964 
1965 void
1966 protocol_free(struct protocol *proto)
1967 {
1968     free(proto);
1969 }
1970 
1971 /**************************************************************************/
1972 int
1973 iperf_defaults(struct iperf_test *testp)
1974 {
1975     struct protocol *tcp, *udp;
1976 #if defined(HAVE_SCTP)
1977     struct protocol *sctp;
1978 #endif /* HAVE_SCTP */
1979 
1980     testp->omit = OMIT;
1981     testp->duration = DURATION;
1982     testp->diskfile_name = (char*) 0;
1983     testp->affinity = -1;
1984     testp->server_affinity = -1;
1985     TAILQ_INIT(&testp->xbind_addrs);
1986 #if defined(HAVE_CPUSET_SETAFFINITY)
1987     CPU_ZERO(&testp->cpumask);
1988 #endif /* HAVE_CPUSET_SETAFFINITY */
1989     testp->title = NULL;
1990     testp->congestion = NULL;
1991     testp->congestion_used = NULL;
1992     testp->remote_congestion_used = NULL;
1993     testp->server_port = PORT;
1994     testp->ctrl_sck = -1;
1995     testp->prot_listener = -1;
1996 
1997     testp->stats_callback = iperf_stats_callback;
1998     testp->reporter_callback = iperf_reporter_callback;
1999 
2000     testp->stats_interval = testp->reporter_interval = 1;
2001     testp->num_streams = 1;
2002 
2003     testp->settings->domain = AF_UNSPEC;
2004     testp->settings->unit_format = 'a';
2005     testp->settings->socket_bufsize = 0;    /* use autotuning */
2006     testp->settings->blksize = DEFAULT_TCP_BLKSIZE;
2007     testp->settings->rate = 0;
2008     testp->settings->fqrate = 0;
2009     testp->settings->burst = 0;
2010     testp->settings->mss = 0;
2011     testp->settings->bytes = 0;
2012     testp->settings->blocks = 0;
2013     memset(testp->cookie, 0, COOKIE_SIZE);
2014 
2015     testp->multisend = 10;	/* arbitrary */
2016 
2017     /* Set up protocol list */
2018     SLIST_INIT(&testp->streams);
2019     SLIST_INIT(&testp->protocols);
2020 
2021     tcp = protocol_new();
2022     if (!tcp)
2023         return -1;
2024 
2025     tcp->id = Ptcp;
2026     tcp->name = "TCP";
2027     tcp->accept = iperf_tcp_accept;
2028     tcp->listen = iperf_tcp_listen;
2029     tcp->connect = iperf_tcp_connect;
2030     tcp->send = iperf_tcp_send;
2031     tcp->recv = iperf_tcp_recv;
2032     tcp->init = NULL;
2033     SLIST_INSERT_HEAD(&testp->protocols, tcp, protocols);
2034 
2035     udp = protocol_new();
2036     if (!udp) {
2037         protocol_free(tcp);
2038         return -1;
2039     }
2040 
2041     udp->id = Pudp;
2042     udp->name = "UDP";
2043     udp->accept = iperf_udp_accept;
2044     udp->listen = iperf_udp_listen;
2045     udp->connect = iperf_udp_connect;
2046     udp->send = iperf_udp_send;
2047     udp->recv = iperf_udp_recv;
2048     udp->init = iperf_udp_init;
2049     SLIST_INSERT_AFTER(tcp, udp, protocols);
2050 
2051     set_protocol(testp, Ptcp);
2052 
2053 #if defined(HAVE_SCTP)
2054     sctp = protocol_new();
2055     if (!sctp) {
2056         protocol_free(tcp);
2057         protocol_free(udp);
2058         return -1;
2059     }
2060 
2061     sctp->id = Psctp;
2062     sctp->name = "SCTP";
2063     sctp->accept = iperf_sctp_accept;
2064     sctp->listen = iperf_sctp_listen;
2065     sctp->connect = iperf_sctp_connect;
2066     sctp->send = iperf_sctp_send;
2067     sctp->recv = iperf_sctp_recv;
2068     sctp->init = iperf_sctp_init;
2069 
2070     SLIST_INSERT_AFTER(udp, sctp, protocols);
2071 #endif /* HAVE_SCTP */
2072 
2073     testp->on_new_stream = iperf_on_new_stream;
2074     testp->on_test_start = iperf_on_test_start;
2075     testp->on_connect = iperf_on_connect;
2076     testp->on_test_finish = iperf_on_test_finish;
2077 
2078     TAILQ_INIT(&testp->server_output_list);
2079 
2080     return 0;
2081 }
2082 
2083 
2084 /**************************************************************************/
2085 void
2086 iperf_free_test(struct iperf_test *test)
2087 {
2088     struct protocol *prot;
2089     struct iperf_stream *sp;
2090 
2091     /* Free streams */
2092     while (!SLIST_EMPTY(&test->streams)) {
2093         sp = SLIST_FIRST(&test->streams);
2094         SLIST_REMOVE_HEAD(&test->streams, streams);
2095         iperf_free_stream(sp);
2096     }
2097 
2098     if (test->server_hostname)
2099 	free(test->server_hostname);
2100     if (test->tmp_template)
2101 	free(test->tmp_template);
2102     if (test->bind_address)
2103 	free(test->bind_address);
2104     if (!TAILQ_EMPTY(&test->xbind_addrs)) {
2105         struct xbind_entry *xbe;
2106 
2107         while (!TAILQ_EMPTY(&test->xbind_addrs)) {
2108             xbe = TAILQ_FIRST(&test->xbind_addrs);
2109             TAILQ_REMOVE(&test->xbind_addrs, xbe, link);
2110             if (xbe->ai)
2111                 freeaddrinfo(xbe->ai);
2112             free(xbe->name);
2113             free(xbe);
2114         }
2115     }
2116     if (test->settings)
2117     free(test->settings);
2118     if (test->title)
2119 	free(test->title);
2120     if (test->congestion)
2121 	free(test->congestion);
2122     if (test->congestion_used)
2123 	free(test->congestion_used);
2124     if (test->remote_congestion_used)
2125 	free(test->remote_congestion_used);
2126     if (test->omit_timer != NULL)
2127 	tmr_cancel(test->omit_timer);
2128     if (test->timer != NULL)
2129 	tmr_cancel(test->timer);
2130     if (test->stats_timer != NULL)
2131 	tmr_cancel(test->stats_timer);
2132     if (test->reporter_timer != NULL)
2133 	tmr_cancel(test->reporter_timer);
2134 
2135     /* Free protocol list */
2136     while (!SLIST_EMPTY(&test->protocols)) {
2137         prot = SLIST_FIRST(&test->protocols);
2138         SLIST_REMOVE_HEAD(&test->protocols, protocols);
2139         free(prot);
2140     }
2141 
2142     if (test->server_output_text) {
2143 	free(test->server_output_text);
2144 	test->server_output_text = NULL;
2145     }
2146 
2147     if (test->json_output_string) {
2148 	free(test->json_output_string);
2149 	test->json_output_string = NULL;
2150     }
2151 
2152     /* Free output line buffers, if any (on the server only) */
2153     struct iperf_textline *t;
2154     while (!TAILQ_EMPTY(&test->server_output_list)) {
2155 	t = TAILQ_FIRST(&test->server_output_list);
2156 	TAILQ_REMOVE(&test->server_output_list, t, textlineentries);
2157 	free(t->line);
2158 	free(t);
2159     }
2160 
2161     /* sctp_bindx: do not free the arguments, only the resolver results */
2162     if (!TAILQ_EMPTY(&test->xbind_addrs)) {
2163         struct xbind_entry *xbe;
2164 
2165         TAILQ_FOREACH(xbe, &test->xbind_addrs, link) {
2166             if (xbe->ai) {
2167                 freeaddrinfo(xbe->ai);
2168                 xbe->ai = NULL;
2169             }
2170         }
2171     }
2172 
2173     /* XXX: Why are we setting these values to NULL? */
2174     // test->streams = NULL;
2175     test->stats_callback = NULL;
2176     test->reporter_callback = NULL;
2177     free(test);
2178 }
2179 
2180 
2181 void
2182 iperf_reset_test(struct iperf_test *test)
2183 {
2184     struct iperf_stream *sp;
2185 
2186     /* Free streams */
2187     while (!SLIST_EMPTY(&test->streams)) {
2188         sp = SLIST_FIRST(&test->streams);
2189         SLIST_REMOVE_HEAD(&test->streams, streams);
2190         iperf_free_stream(sp);
2191     }
2192     if (test->omit_timer != NULL) {
2193 	tmr_cancel(test->omit_timer);
2194 	test->omit_timer = NULL;
2195     }
2196     if (test->timer != NULL) {
2197 	tmr_cancel(test->timer);
2198 	test->timer = NULL;
2199     }
2200     if (test->stats_timer != NULL) {
2201 	tmr_cancel(test->stats_timer);
2202 	test->stats_timer = NULL;
2203     }
2204     if (test->reporter_timer != NULL) {
2205 	tmr_cancel(test->reporter_timer);
2206 	test->reporter_timer = NULL;
2207     }
2208     test->done = 0;
2209 
2210     SLIST_INIT(&test->streams);
2211 
2212     test->role = 's';
2213     test->sender = 0;
2214     test->sender_has_retransmits = 0;
2215     set_protocol(test, Ptcp);
2216     test->omit = OMIT;
2217     test->duration = DURATION;
2218     test->server_affinity = -1;
2219 #if defined(HAVE_CPUSET_SETAFFINITY)
2220     CPU_ZERO(&test->cpumask);
2221 #endif /* HAVE_CPUSET_SETAFFINITY */
2222     test->state = 0;
2223 
2224     test->ctrl_sck = -1;
2225     test->prot_listener = -1;
2226 
2227     test->bytes_sent = 0;
2228     test->blocks_sent = 0;
2229 
2230     test->reverse = 0;
2231     test->no_delay = 0;
2232 
2233     FD_ZERO(&test->read_set);
2234     FD_ZERO(&test->write_set);
2235 
2236     test->num_streams = 1;
2237     test->settings->socket_bufsize = 0;
2238     test->settings->blksize = DEFAULT_TCP_BLKSIZE;
2239     test->settings->rate = 0;
2240     test->settings->burst = 0;
2241     test->settings->mss = 0;
2242     memset(test->cookie, 0, COOKIE_SIZE);
2243     test->multisend = 10;	/* arbitrary */
2244     test->udp_counters_64bit = 0;
2245     if (test->title) {
2246 	free(test->title);
2247 	test->title = NULL;
2248     }
2249 
2250     /* Free output line buffers, if any (on the server only) */
2251     struct iperf_textline *t;
2252     while (!TAILQ_EMPTY(&test->server_output_list)) {
2253 	t = TAILQ_FIRST(&test->server_output_list);
2254 	TAILQ_REMOVE(&test->server_output_list, t, textlineentries);
2255 	free(t->line);
2256 	free(t);
2257     }
2258 }
2259 
2260 
2261 /* Reset all of a test's stats back to zero.  Called when the omitting
2262 ** period is over.
2263 */
2264 void
2265 iperf_reset_stats(struct iperf_test *test)
2266 {
2267     struct timeval now;
2268     struct iperf_stream *sp;
2269     struct iperf_stream_result *rp;
2270 
2271     test->bytes_sent = 0;
2272     test->blocks_sent = 0;
2273     gettimeofday(&now, NULL);
2274     SLIST_FOREACH(sp, &test->streams, streams) {
2275 	sp->omitted_packet_count = sp->packet_count;
2276         sp->omitted_cnt_error = sp->cnt_error;
2277         sp->omitted_outoforder_packets = sp->outoforder_packets;
2278 	sp->jitter = 0;
2279 	rp = sp->result;
2280         rp->bytes_sent_omit = rp->bytes_sent;
2281         rp->bytes_received = 0;
2282         rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0;
2283 	if (test->sender && test->sender_has_retransmits) {
2284 	    struct iperf_interval_results ir; /* temporary results structure */
2285 	    save_tcpinfo(sp, &ir);
2286 	    rp->stream_prev_total_retrans = get_total_retransmits(&ir);
2287 	}
2288 	rp->stream_retrans = 0;
2289 	rp->start_time = now;
2290     }
2291 }
2292 
2293 
2294 /**************************************************************************/
2295 
2296 /**
2297  * Gather statistics during a test.
2298  * This function works for both the client and server side.
2299  */
2300 void
2301 iperf_stats_callback(struct iperf_test *test)
2302 {
2303     struct iperf_stream *sp;
2304     struct iperf_stream_result *rp = NULL;
2305     struct iperf_interval_results *irp, temp;
2306 
2307     temp.omitted = test->omitting;
2308     SLIST_FOREACH(sp, &test->streams, streams) {
2309         rp = sp->result;
2310 
2311 	temp.bytes_transferred = test->sender ? rp->bytes_sent_this_interval : rp->bytes_received_this_interval;
2312 
2313 	irp = TAILQ_LAST(&rp->interval_results, irlisthead);
2314         /* result->end_time contains timestamp of previous interval */
2315         if ( irp != NULL ) /* not the 1st interval */
2316             memcpy(&temp.interval_start_time, &rp->end_time, sizeof(struct timeval));
2317         else /* or use timestamp from beginning */
2318             memcpy(&temp.interval_start_time, &rp->start_time, sizeof(struct timeval));
2319         /* now save time of end of this interval */
2320         gettimeofday(&rp->end_time, NULL);
2321         memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct timeval));
2322         temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
2323         //temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
2324 	if (test->protocol->id == Ptcp) {
2325 	    if ( has_tcpinfo()) {
2326 		save_tcpinfo(sp, &temp);
2327 		if (test->sender && test->sender_has_retransmits) {
2328 		    long total_retrans = get_total_retransmits(&temp);
2329 		    temp.interval_retrans = total_retrans - rp->stream_prev_total_retrans;
2330 		    rp->stream_retrans += temp.interval_retrans;
2331 		    rp->stream_prev_total_retrans = total_retrans;
2332 
2333 		    temp.snd_cwnd = get_snd_cwnd(&temp);
2334 		    if (temp.snd_cwnd > rp->stream_max_snd_cwnd) {
2335 			rp->stream_max_snd_cwnd = temp.snd_cwnd;
2336 		    }
2337 
2338 		    temp.rtt = get_rtt(&temp);
2339 		    if (temp.rtt > rp->stream_max_rtt) {
2340 			rp->stream_max_rtt = temp.rtt;
2341 		    }
2342 		    if (rp->stream_min_rtt == 0 ||
2343 			temp.rtt < rp->stream_min_rtt) {
2344 			rp->stream_min_rtt = temp.rtt;
2345 		    }
2346 		    rp->stream_sum_rtt += temp.rtt;
2347 		    rp->stream_count_rtt++;
2348 
2349 		    temp.rttvar = get_rttvar(&temp);
2350 		}
2351 	    }
2352 	} else {
2353 	    if (irp == NULL) {
2354 		temp.interval_packet_count = sp->packet_count;
2355 		temp.interval_outoforder_packets = sp->outoforder_packets;
2356 		temp.interval_cnt_error = sp->cnt_error;
2357 	    } else {
2358 		temp.interval_packet_count = sp->packet_count - irp->packet_count;
2359 		temp.interval_outoforder_packets = sp->outoforder_packets - irp->outoforder_packets;
2360 		temp.interval_cnt_error = sp->cnt_error - irp->cnt_error;
2361 	    }
2362 	    temp.packet_count = sp->packet_count;
2363 	    temp.jitter = sp->jitter;
2364 	    temp.outoforder_packets = sp->outoforder_packets;
2365 	    temp.cnt_error = sp->cnt_error;
2366 	}
2367         add_to_interval_list(rp, &temp);
2368         rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0;
2369     }
2370 }
2371 
2372 /**
2373  * Print intermediate results during a test (interval report).
2374  * Uses print_interval_results to print the results for each stream,
2375  * then prints an interval summary for all streams in this
2376  * interval.
2377  */
2378 static void
2379 iperf_print_intermediate(struct iperf_test *test)
2380 {
2381     char ubuf[UNIT_LEN];
2382     char nbuf[UNIT_LEN];
2383     struct iperf_stream *sp = NULL;
2384     struct iperf_interval_results *irp;
2385     iperf_size_t bytes = 0;
2386     double bandwidth;
2387     int retransmits = 0;
2388     double start_time, end_time;
2389     cJSON *json_interval;
2390     cJSON *json_interval_streams;
2391     int total_packets = 0, lost_packets = 0;
2392     double avg_jitter = 0.0, lost_percent;
2393 
2394     if (test->json_output) {
2395         json_interval = cJSON_CreateObject();
2396 	if (json_interval == NULL)
2397 	    return;
2398 	cJSON_AddItemToArray(test->json_intervals, json_interval);
2399         json_interval_streams = cJSON_CreateArray();
2400 	if (json_interval_streams == NULL)
2401 	    return;
2402 	cJSON_AddItemToObject(json_interval, "streams", json_interval_streams);
2403     } else {
2404         json_interval = NULL;
2405         json_interval_streams = NULL;
2406     }
2407 
2408     SLIST_FOREACH(sp, &test->streams, streams) {
2409         print_interval_results(test, sp, json_interval_streams);
2410 	/* sum up all streams */
2411 	irp = TAILQ_LAST(&sp->result->interval_results, irlisthead);
2412 	if (irp == NULL) {
2413 	    iperf_err(test, "iperf_print_intermediate error: interval_results is NULL");
2414 	    return;
2415 	}
2416         bytes += irp->bytes_transferred;
2417 	if (test->protocol->id == Ptcp) {
2418 	    if (test->sender && test->sender_has_retransmits) {
2419 		retransmits += irp->interval_retrans;
2420 	    }
2421 	} else {
2422             total_packets += irp->interval_packet_count;
2423             lost_packets += irp->interval_cnt_error;
2424             avg_jitter += irp->jitter;
2425 	}
2426     }
2427 
2428     /* next build string with sum of all streams */
2429     if (test->num_streams > 1 || test->json_output) {
2430         sp = SLIST_FIRST(&test->streams); /* reset back to 1st stream */
2431 	/* Only do this of course if there was a first stream */
2432 	if (sp) {
2433         irp = TAILQ_LAST(&sp->result->interval_results, irlisthead);    /* use 1st stream for timing info */
2434 
2435         unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
2436 	bandwidth = (double) bytes / (double) irp->interval_duration;
2437         unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
2438 
2439         start_time = timeval_diff(&sp->result->start_time,&irp->interval_start_time);
2440         end_time = timeval_diff(&sp->result->start_time,&irp->interval_end_time);
2441 	if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2442 	    if (test->sender && test->sender_has_retransmits) {
2443 		/* Interval sum, TCP with retransmits. */
2444 		if (test->json_output)
2445 		    cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  omitted: %b", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, (int64_t) retransmits, irp->omitted)); /* XXX irp->omitted or test->omitting? */
2446 		else
2447 		    iperf_printf(test, report_sum_bw_retrans_format, start_time, end_time, ubuf, nbuf, retransmits, irp->omitted?report_omitted:""); /* XXX irp->omitted or test->omitting? */
2448 	    } else {
2449 		/* Interval sum, TCP without retransmits. */
2450 		if (test->json_output)
2451 		    cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  omitted: %b", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, test->omitting));
2452 		else
2453 		    iperf_printf(test, report_sum_bw_format, start_time, end_time, ubuf, nbuf, test->omitting?report_omitted:"");
2454 	    }
2455 	} else {
2456 	    /* Interval sum, UDP. */
2457 	    if (test->sender) {
2458 		if (test->json_output)
2459 		    cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  packets: %d  omitted: %b", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, (int64_t) total_packets, test->omitting));
2460 		else
2461 		    iperf_printf(test, report_sum_bw_udp_sender_format, start_time, end_time, ubuf, nbuf, total_packets, test->omitting?report_omitted:"");
2462 	    } else {
2463 		avg_jitter /= test->num_streams;
2464 		if (total_packets > 0) {
2465 		    lost_percent = 100.0 * lost_packets / total_packets;
2466 		}
2467 		else {
2468 		    lost_percent = 0.0;
2469 		}
2470 		if (test->json_output)
2471 		    cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  jitter_ms: %f  lost_packets: %d  packets: %d  lost_percent: %f  omitted: %b", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, (double) avg_jitter * 1000.0, (int64_t) lost_packets, (int64_t) total_packets, (double) lost_percent, test->omitting));
2472 		else
2473 		    iperf_printf(test, report_sum_bw_udp_format, start_time, end_time, ubuf, nbuf, avg_jitter * 1000.0, lost_packets, total_packets, lost_percent, test->omitting?report_omitted:"");
2474 	    }
2475 	}
2476 	}
2477     }
2478 }
2479 
2480 /**
2481  * Print overall summary statistics at the end of a test.
2482  */
2483 static void
2484 iperf_print_results(struct iperf_test *test)
2485 {
2486 
2487     cJSON *json_summary_streams = NULL;
2488     cJSON *json_summary_stream = NULL;
2489     int total_retransmits = 0;
2490     int total_packets = 0, lost_packets = 0;
2491     char ubuf[UNIT_LEN];
2492     char nbuf[UNIT_LEN];
2493     struct stat sb;
2494     char sbuf[UNIT_LEN];
2495     struct iperf_stream *sp = NULL;
2496     iperf_size_t bytes_sent, total_sent = 0;
2497     iperf_size_t bytes_received, total_received = 0;
2498     double start_time, end_time = 0.0, avg_jitter = 0.0, lost_percent;
2499     double bandwidth;
2500 
2501     /* print final summary for all intervals */
2502 
2503     if (test->json_output) {
2504         json_summary_streams = cJSON_CreateArray();
2505 	if (json_summary_streams == NULL)
2506 	    return;
2507 	cJSON_AddItemToObject(test->json_end, "streams", json_summary_streams);
2508     } else {
2509 	iperf_printf(test, "%s", report_bw_separator);
2510 	if (test->verbose)
2511 	    iperf_printf(test, "%s", report_summary);
2512 	if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2513 	    if (test->sender_has_retransmits)
2514 		iperf_printf(test, "%s", report_bw_retrans_header);
2515 	    else
2516 		iperf_printf(test, "%s", report_bw_header);
2517 	} else
2518 	    iperf_printf(test, "%s", report_bw_udp_header);
2519     }
2520 
2521     start_time = 0.;
2522     sp = SLIST_FIRST(&test->streams);
2523     /*
2524      * If there is at least one stream, then figure out the length of time
2525      * we were running the tests and print out some statistics about
2526      * the streams.  It's possible to not have any streams at all
2527      * if the client got interrupted before it got to do anything.
2528      */
2529     if (sp) {
2530     end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
2531     SLIST_FOREACH(sp, &test->streams, streams) {
2532 	if (test->json_output) {
2533 	    json_summary_stream = cJSON_CreateObject();
2534 	    if (json_summary_stream == NULL)
2535 		return;
2536 	    cJSON_AddItemToArray(json_summary_streams, json_summary_stream);
2537 	}
2538 
2539         bytes_sent = sp->result->bytes_sent - sp->result->bytes_sent_omit;
2540         bytes_received = sp->result->bytes_received;
2541         total_sent += bytes_sent;
2542         total_received += bytes_received;
2543 
2544         if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2545 	    if (test->sender_has_retransmits) {
2546 		total_retransmits += sp->result->stream_retrans;
2547 	    }
2548 	} else {
2549             total_packets += (sp->packet_count - sp->omitted_packet_count);
2550             lost_packets += (sp->cnt_error - sp->omitted_cnt_error);
2551             avg_jitter += sp->jitter;
2552         }
2553 
2554 	unit_snprintf(ubuf, UNIT_LEN, (double) bytes_sent, 'A');
2555 	bandwidth = (double) bytes_sent / (double) end_time;
2556 	unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
2557 	if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2558 	    if (test->sender_has_retransmits) {
2559 		/* Summary, TCP with retransmits. */
2560 		if (test->json_output)
2561 		    cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  max_snd_cwnd:  %d  max_rtt:  %d  min_rtt:  %d  mean_rtt:  %d", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt)));
2562 		else
2563 		    iperf_printf(test, report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->stream_retrans, report_sender);
2564 	    } else {
2565 		/* Summary, TCP without retransmits. */
2566 		if (test->json_output)
2567 		    cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8));
2568 		else
2569 		    iperf_printf(test, report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf, report_sender);
2570 	    }
2571 	} else {
2572 	    /* Summary, UDP. */
2573 	    if (sp->packet_count - sp->omitted_packet_count > 0) {
2574               lost_percent = 100.0 * (sp->cnt_error - sp->omitted_cnt_error) / (sp->packet_count - sp->omitted_packet_count);
2575 	    }
2576 	    else {
2577 		lost_percent = 0.0;
2578 	    }
2579 	    if (test->json_output)
2580               cJSON_AddItemToObject(json_summary_stream, "udp", iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  jitter_ms: %f  lost_packets: %d  packets: %d  lost_percent: %f  out_of_order: %d", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8, (double) sp->jitter * 1000.0, (int64_t) (sp->cnt_error - sp->omitted_cnt_error), (int64_t) (sp->packet_count - sp->omitted_packet_count), (double) lost_percent, (int64_t) (sp->outoforder_packets - sp->omitted_outoforder_packets)));
2581 	    else {
2582               iperf_printf(test, report_bw_udp_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->jitter * 1000.0, (sp->cnt_error - sp->omitted_cnt_error), (sp->packet_count - sp->omitted_packet_count), lost_percent, "");
2583 		if (test->role == 'c')
2584 		    iperf_printf(test, report_datagrams, sp->socket, (sp->packet_count - sp->omitted_packet_count));
2585 		if ((sp->outoforder_packets - sp->omitted_outoforder_packets) > 0)
2586                   iperf_printf(test, report_sum_outoforder, start_time, end_time, (sp->outoforder_packets - sp->omitted_outoforder_packets));
2587 	    }
2588 	}
2589 
2590 	if (sp->diskfile_fd >= 0) {
2591 	    if (fstat(sp->diskfile_fd, &sb) == 0) {
2592 		/* In the odd case that it's a zero-sized file, say it was all transferred. */
2593 		int percent = 100;
2594 		if (sb.st_size > 0) {
2595 		    percent = (int) ( ( (double) bytes_sent / (double) sb.st_size ) * 100.0 );
2596 		}
2597 		unit_snprintf(sbuf, UNIT_LEN, (double) sb.st_size, 'A');
2598 		if (test->json_output)
2599 		    cJSON_AddItemToObject(json_summary_stream, "diskfile", iperf_json_printf("sent: %d  size: %d  percent: %d  filename: %s", (int64_t) bytes_sent, (int64_t) sb.st_size, (int64_t) percent, test->diskfile_name));
2600 		else
2601 		    iperf_printf(test, report_diskfile, ubuf, sbuf, percent, test->diskfile_name);
2602 	    }
2603 	}
2604 
2605 	unit_snprintf(ubuf, UNIT_LEN, (double) bytes_received, 'A');
2606 	bandwidth = (double) bytes_received / (double) end_time;
2607 	unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
2608 	if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2609 	    if (test->json_output)
2610 		cJSON_AddItemToObject(json_summary_stream, "receiver", iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_received, bandwidth * 8));
2611 	    else
2612 		iperf_printf(test, report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf, report_receiver);
2613 	}
2614     }
2615     }
2616 
2617     if (test->num_streams > 1 || test->json_output) {
2618         unit_snprintf(ubuf, UNIT_LEN, (double) total_sent, 'A');
2619 	/* If no tests were run, arbitrariliy set bandwidth to 0. */
2620 	if (end_time > 0.0) {
2621 	    bandwidth = (double) total_sent / (double) end_time;
2622 	}
2623 	else {
2624 	    bandwidth = 0.0;
2625 	}
2626         unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
2627         if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2628 	    if (test->sender_has_retransmits) {
2629 		/* Summary sum, TCP with retransmits. */
2630 		if (test->json_output)
2631 		    cJSON_AddItemToObject(test->json_end, "sum_sent", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8, (int64_t) total_retransmits));
2632 		else
2633 		    iperf_printf(test, report_sum_bw_retrans_format, start_time, end_time, ubuf, nbuf, total_retransmits, report_sender);
2634 	    } else {
2635 		/* Summary sum, TCP without retransmits. */
2636 		if (test->json_output)
2637 		    cJSON_AddItemToObject(test->json_end, "sum_sent", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8));
2638 		else
2639 		    iperf_printf(test, report_sum_bw_format, start_time, end_time, ubuf, nbuf, report_sender);
2640 	    }
2641             unit_snprintf(ubuf, UNIT_LEN, (double) total_received, 'A');
2642 	    /* If no tests were run, set received bandwidth to 0 */
2643 	    if (end_time > 0.0) {
2644 		bandwidth = (double) total_received / (double) end_time;
2645 	    }
2646 	    else {
2647 		bandwidth = 0.0;
2648 	    }
2649             unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
2650 	    if (test->json_output)
2651 		cJSON_AddItemToObject(test->json_end, "sum_received", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_received, bandwidth * 8));
2652 	    else
2653 		iperf_printf(test, report_sum_bw_format, start_time, end_time, ubuf, nbuf, report_receiver);
2654         } else {
2655 	    /* Summary sum, UDP. */
2656             avg_jitter /= test->num_streams;
2657 	    /* If no packets were sent, arbitrarily set loss percentage to 0. */
2658 	    if (total_packets > 0) {
2659 		lost_percent = 100.0 * lost_packets / total_packets;
2660 	    }
2661 	    else {
2662 		lost_percent = 0.0;
2663 	    }
2664 	    if (test->json_output)
2665 		cJSON_AddItemToObject(test->json_end, "sum", iperf_json_printf("start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  jitter_ms: %f  lost_packets: %d  packets: %d  lost_percent: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8, (double) avg_jitter * 1000.0, (int64_t) lost_packets, (int64_t) total_packets, (double) lost_percent));
2666 	    else
2667 		iperf_printf(test, report_sum_bw_udp_format, start_time, end_time, ubuf, nbuf, avg_jitter * 1000.0, lost_packets, total_packets, lost_percent, "");
2668         }
2669     }
2670 
2671     if (test->json_output) {
2672 	cJSON_AddItemToObject(test->json_end, "cpu_utilization_percent", iperf_json_printf("host_total: %f  host_user: %f  host_system: %f  remote_total: %f  remote_user: %f  remote_system: %f", (double) test->cpu_util[0], (double) test->cpu_util[1], (double) test->cpu_util[2], (double) test->remote_cpu_util[0], (double) test->remote_cpu_util[1], (double) test->remote_cpu_util[2]));
2673 	if (test->protocol->id == Ptcp) {
2674 	    char *snd_congestion = NULL, *rcv_congestion = NULL;
2675 	    if (test->sender) {
2676 		snd_congestion = test->congestion_used;
2677 		rcv_congestion = test->remote_congestion_used;
2678 	    }
2679 	    else {
2680 		snd_congestion = test->remote_congestion_used;
2681 		rcv_congestion = test->congestion_used;
2682 	    }
2683 	    if (snd_congestion) {
2684 		cJSON_AddStringToObject(test->json_end, "sender_tcp_congestion", snd_congestion);
2685 	    }
2686 	    if (rcv_congestion) {
2687 		cJSON_AddStringToObject(test->json_end, "receiver_tcp_congestion", rcv_congestion);
2688 	    }
2689 	}
2690     }
2691     else {
2692 	if (test->verbose) {
2693 	    iperf_printf(test, report_cpu, report_local, test->sender?report_sender:report_receiver, test->cpu_util[0], test->cpu_util[1], test->cpu_util[2], report_remote, test->sender?report_receiver:report_sender, test->remote_cpu_util[0], test->remote_cpu_util[1], test->remote_cpu_util[2]);
2694 
2695 	    if (test->protocol->id == Ptcp) {
2696 		char *snd_congestion = NULL, *rcv_congestion = NULL;
2697 		if (test->sender) {
2698 		    snd_congestion = test->congestion_used;
2699 		    rcv_congestion = test->remote_congestion_used;
2700 		}
2701 		else {
2702 		    snd_congestion = test->remote_congestion_used;
2703 		    rcv_congestion = test->congestion_used;
2704 		}
2705 		if (snd_congestion) {
2706 		    iperf_printf(test, "snd_tcp_congestion %s\n", snd_congestion);
2707 		}
2708 		if (rcv_congestion) {
2709 		    iperf_printf(test, "rcv_tcp_congestion %s\n", rcv_congestion);
2710 		}
2711 	    }
2712 	}
2713 
2714 	/* Print server output if we're on the client and it was requested/provided */
2715 	if (test->role == 'c' && iperf_get_test_get_server_output(test)) {
2716 	    if (test->json_server_output) {
2717 		iperf_printf(test, "\nServer JSON output:\n%s\n", cJSON_Print(test->json_server_output));
2718 		cJSON_Delete(test->json_server_output);
2719 		test->json_server_output = NULL;
2720 	    }
2721 	    if (test->server_output_text) {
2722 		iperf_printf(test, "\nServer output:\n%s\n", test->server_output_text);
2723 		test->server_output_text = NULL;
2724 	    }
2725 	}
2726     }
2727 }
2728 
2729 /**************************************************************************/
2730 
2731 /**
2732  * Main report-printing callback.
2733  * Prints results either during a test (interval report only) or
2734  * after the entire test has been run (last interval report plus
2735  * overall summary).
2736  */
2737 void
2738 iperf_reporter_callback(struct iperf_test *test)
2739 {
2740     switch (test->state) {
2741         case TEST_RUNNING:
2742         case STREAM_RUNNING:
2743             /* print interval results for each stream */
2744             iperf_print_intermediate(test);
2745             break;
2746         case TEST_END:
2747         case DISPLAY_RESULTS:
2748             iperf_print_intermediate(test);
2749             iperf_print_results(test);
2750             break;
2751     }
2752 
2753 }
2754 
2755 /**
2756  * Print the interval results for one stream.
2757  * This function needs to know about the overall test so it can determine the
2758  * context for printing headers, separators, etc.
2759  */
2760 static void
2761 print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *json_interval_streams)
2762 {
2763     char ubuf[UNIT_LEN];
2764     char nbuf[UNIT_LEN];
2765     char cbuf[UNIT_LEN];
2766     double st = 0., et = 0.;
2767     struct iperf_interval_results *irp = NULL;
2768     double bandwidth, lost_percent;
2769 
2770     irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* get last entry in linked list */
2771     if (irp == NULL) {
2772 	iperf_err(test, "print_interval_results error: interval_results is NULL");
2773         return;
2774     }
2775     if (!test->json_output) {
2776 	/* First stream? */
2777 	if (sp == SLIST_FIRST(&test->streams)) {
2778 	    /* It it's the first interval, print the header;
2779 	    ** else if there's more than one stream, print the separator;
2780 	    ** else nothing.
2781 	    */
2782 	    if (timeval_equals(&sp->result->start_time, &irp->interval_start_time)) {
2783 		if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2784 		    if (test->sender && test->sender_has_retransmits)
2785 			iperf_printf(test, "%s", report_bw_retrans_cwnd_header);
2786 		    else
2787 			iperf_printf(test, "%s", report_bw_header);
2788 		} else {
2789 		    if (test->sender)
2790 			iperf_printf(test, "%s", report_bw_udp_sender_header);
2791 		    else
2792 			iperf_printf(test, "%s", report_bw_udp_header);
2793 		}
2794 	    } else if (test->num_streams > 1)
2795 		iperf_printf(test, "%s", report_bw_separator);
2796 	}
2797     }
2798 
2799     unit_snprintf(ubuf, UNIT_LEN, (double) (irp->bytes_transferred), 'A');
2800     if (irp->interval_duration > 0.0) {
2801 	bandwidth = (double) irp->bytes_transferred / (double) irp->interval_duration;
2802     }
2803     else {
2804 	bandwidth = 0.0;
2805     }
2806     unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
2807 
2808     st = timeval_diff(&sp->result->start_time, &irp->interval_start_time);
2809     et = timeval_diff(&sp->result->start_time, &irp->interval_end_time);
2810 
2811     if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
2812 	if (test->sender && test->sender_has_retransmits) {
2813 	    /* Interval, TCP with retransmits. */
2814 	    if (test->json_output)
2815 		cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  snd_cwnd:  %d  rtt:  %d  rttvar: %d  omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, (int64_t) irp->rtt, (int64_t) irp->rttvar, irp->omitted));
2816 	    else {
2817 		unit_snprintf(cbuf, UNIT_LEN, irp->snd_cwnd, 'A');
2818 		iperf_printf(test, report_bw_retrans_cwnd_format, sp->socket, st, et, ubuf, nbuf, irp->interval_retrans, cbuf, irp->omitted?report_omitted:"");
2819 	    }
2820 	} else {
2821 	    /* Interval, TCP without retransmits. */
2822 	    if (test->json_output)
2823 		cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, irp->omitted));
2824 	    else
2825 		iperf_printf(test, report_bw_format, sp->socket, st, et, ubuf, nbuf, irp->omitted?report_omitted:"");
2826 	}
2827     } else {
2828 	/* Interval, UDP. */
2829 	if (test->sender) {
2830 	    if (test->json_output)
2831 		cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  packets: %d  omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_packet_count, irp->omitted));
2832 	    else
2833 		iperf_printf(test, report_bw_udp_sender_format, sp->socket, st, et, ubuf, nbuf, irp->interval_packet_count, irp->omitted?report_omitted:"");
2834 	} else {
2835 	    if (irp->interval_packet_count > 0) {
2836 		lost_percent = 100.0 * irp->interval_cnt_error / irp->interval_packet_count;
2837 	    }
2838 	    else {
2839 		lost_percent = 0.0;
2840 	    }
2841 	    if (test->json_output)
2842 		cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  jitter_ms: %f  lost_packets: %d  packets: %d  lost_percent: %f  omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (double) irp->jitter * 1000.0, (int64_t) irp->interval_cnt_error, (int64_t) irp->interval_packet_count, (double) lost_percent, irp->omitted));
2843 	    else
2844 		iperf_printf(test, report_bw_udp_format, sp->socket, st, et, ubuf, nbuf, irp->jitter * 1000.0, irp->interval_cnt_error, irp->interval_packet_count, lost_percent, irp->omitted?report_omitted:"");
2845 	}
2846     }
2847 
2848     if (test->logfile || test->forceflush)
2849         iflush(test);
2850 }
2851 
2852 /**************************************************************************/
2853 void
2854 iperf_free_stream(struct iperf_stream *sp)
2855 {
2856     struct iperf_interval_results *irp, *nirp;
2857 
2858     /* XXX: need to free interval list too! */
2859     munmap(sp->buffer, sp->test->settings->blksize);
2860     close(sp->buffer_fd);
2861     if (sp->diskfile_fd >= 0)
2862 	close(sp->diskfile_fd);
2863     for (irp = TAILQ_FIRST(&sp->result->interval_results); irp != NULL; irp = nirp) {
2864         nirp = TAILQ_NEXT(irp, irlistentries);
2865         free(irp);
2866     }
2867     free(sp->result);
2868     if (sp->send_timer != NULL)
2869 	tmr_cancel(sp->send_timer);
2870     free(sp);
2871 }
2872 
2873 /**************************************************************************/
2874 struct iperf_stream *
2875 iperf_new_stream(struct iperf_test *test, int s)
2876 {
2877     int i;
2878     struct iperf_stream *sp;
2879 
2880     char template[1024];
2881     if (test->tmp_template) {
2882         snprintf(template, sizeof(template) / sizeof(char), "%s", test->tmp_template);
2883     } else {
2884         //find the system temporary dir *unix, windows, cygwin support
2885         char* tempdir = getenv("TMPDIR");
2886         if (tempdir == 0){
2887             tempdir = getenv("TEMP");
2888         }
2889         if (tempdir == 0){
2890             tempdir = getenv("TMP");
2891         }
2892         if (tempdir == 0){
2893             tempdir = "/tmp";
2894         }
2895         snprintf(template, sizeof(template) / sizeof(char), "%s/iperf3.XXXXXX", tempdir);
2896     }
2897 
2898     sp = (struct iperf_stream *) malloc(sizeof(struct iperf_stream));
2899     if (!sp) {
2900         i_errno = IECREATESTREAM;
2901         return NULL;
2902     }
2903 
2904     memset(sp, 0, sizeof(struct iperf_stream));
2905 
2906     sp->test = test;
2907     sp->settings = test->settings;
2908     sp->result = (struct iperf_stream_result *) malloc(sizeof(struct iperf_stream_result));
2909     if (!sp->result) {
2910         free(sp);
2911         i_errno = IECREATESTREAM;
2912         return NULL;
2913     }
2914 
2915     memset(sp->result, 0, sizeof(struct iperf_stream_result));
2916     TAILQ_INIT(&sp->result->interval_results);
2917 
2918     /* Create and randomize the buffer */
2919     sp->buffer_fd = mkstemp(template);
2920     if (sp->buffer_fd == -1) {
2921         i_errno = IECREATESTREAM;
2922         free(sp->result);
2923         free(sp);
2924         return NULL;
2925     }
2926     if (unlink(template) < 0) {
2927         i_errno = IECREATESTREAM;
2928         free(sp->result);
2929         free(sp);
2930         return NULL;
2931     }
2932     if (ftruncate(sp->buffer_fd, test->settings->blksize) < 0) {
2933         i_errno = IECREATESTREAM;
2934         free(sp->result);
2935         free(sp);
2936         return NULL;
2937     }
2938     sp->buffer = (char *) mmap(NULL, test->settings->blksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, sp->buffer_fd, 0);
2939     if (sp->buffer == MAP_FAILED) {
2940         i_errno = IECREATESTREAM;
2941         free(sp->result);
2942         free(sp);
2943         return NULL;
2944     }
2945     srandom(time(NULL));
2946     for (i = 0; i < test->settings->blksize; ++i)
2947         sp->buffer[i] = random();
2948 
2949     /* Set socket */
2950     sp->socket = s;
2951 
2952     sp->snd = test->protocol->send;
2953     sp->rcv = test->protocol->recv;
2954 
2955     if (test->diskfile_name != (char*) 0) {
2956 	sp->diskfile_fd = open(test->diskfile_name, test->sender ? O_RDONLY : (O_WRONLY|O_CREAT|O_TRUNC), S_IRUSR|S_IWUSR);
2957 	if (sp->diskfile_fd == -1) {
2958 	    i_errno = IEFILE;
2959             munmap(sp->buffer, sp->test->settings->blksize);
2960             free(sp->result);
2961             free(sp);
2962 	    return NULL;
2963 	}
2964         sp->snd2 = sp->snd;
2965 	sp->snd = diskfile_send;
2966 	sp->rcv2 = sp->rcv;
2967 	sp->rcv = diskfile_recv;
2968     } else
2969         sp->diskfile_fd = -1;
2970 
2971     /* Initialize stream */
2972     if (iperf_init_stream(sp, test) < 0) {
2973         close(sp->buffer_fd);
2974         munmap(sp->buffer, sp->test->settings->blksize);
2975         free(sp->result);
2976         free(sp);
2977         return NULL;
2978     }
2979     iperf_add_stream(test, sp);
2980 
2981     return sp;
2982 }
2983 
2984 /**************************************************************************/
2985 int
2986 iperf_init_stream(struct iperf_stream *sp, struct iperf_test *test)
2987 {
2988     socklen_t len;
2989     int opt;
2990 
2991     len = sizeof(struct sockaddr_storage);
2992     if (getsockname(sp->socket, (struct sockaddr *) &sp->local_addr, &len) < 0) {
2993         i_errno = IEINITSTREAM;
2994         return -1;
2995     }
2996     len = sizeof(struct sockaddr_storage);
2997     if (getpeername(sp->socket, (struct sockaddr *) &sp->remote_addr, &len) < 0) {
2998         i_errno = IEINITSTREAM;
2999         return -1;
3000     }
3001 
3002     /* Set IP TOS */
3003     if ((opt = test->settings->tos)) {
3004         if (getsockdomain(sp->socket) == AF_INET6) {
3005 #ifdef IPV6_TCLASS
3006             if (setsockopt(sp->socket, IPPROTO_IPV6, IPV6_TCLASS, &opt, sizeof(opt)) < 0) {
3007                 i_errno = IESETCOS;
3008                 return -1;
3009             }
3010 #else
3011             i_errno = IESETCOS;
3012             return -1;
3013 #endif
3014         } else {
3015             if (setsockopt(sp->socket, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)) < 0) {
3016                 i_errno = IESETTOS;
3017                 return -1;
3018             }
3019         }
3020     }
3021 
3022     return 0;
3023 }
3024 
3025 /**************************************************************************/
3026 void
3027 iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
3028 {
3029     int i;
3030     struct iperf_stream *n, *prev;
3031 
3032     if (SLIST_EMPTY(&test->streams)) {
3033         SLIST_INSERT_HEAD(&test->streams, sp, streams);
3034         sp->id = 1;
3035     } else {
3036         // for (n = test->streams, i = 2; n->next; n = n->next, ++i);
3037         i = 2;
3038         SLIST_FOREACH(n, &test->streams, streams) {
3039             prev = n;
3040             ++i;
3041         }
3042         SLIST_INSERT_AFTER(prev, sp, streams);
3043         sp->id = i;
3044     }
3045 }
3046 
3047 /* This pair of routines gets inserted into the snd/rcv function pointers
3048 ** when there's a -F flag. They handle the file stuff and call the real
3049 ** snd/rcv functions, which have been saved in snd2/rcv2.
3050 **
3051 ** The advantage of doing it this way is that in the much more common
3052 ** case of no -F flag, there is zero extra overhead.
3053 */
3054 
3055 static int
3056 diskfile_send(struct iperf_stream *sp)
3057 {
3058     int r;
3059 
3060     r = read(sp->diskfile_fd, sp->buffer, sp->test->settings->blksize);
3061     if (r == 0)
3062         sp->test->done = 1;
3063     else
3064 	r = sp->snd2(sp);
3065     return r;
3066 }
3067 
3068 static int
3069 diskfile_recv(struct iperf_stream *sp)
3070 {
3071     int r;
3072 
3073     r = sp->rcv2(sp);
3074     if (r > 0) {
3075 	(void) write(sp->diskfile_fd, sp->buffer, r);
3076 	(void) fsync(sp->diskfile_fd);
3077     }
3078     return r;
3079 }
3080 
3081 
3082 void
3083 iperf_catch_sigend(void (*handler)(int))
3084 {
3085     signal(SIGINT, handler);
3086     signal(SIGTERM, handler);
3087     signal(SIGHUP, handler);
3088 }
3089 
3090 /**
3091  * Called as a result of getting a signal.
3092  * Depending on the current state of the test (and the role of this
3093  * process) compute and report one more set of ending statistics
3094  * before cleaning up and exiting.
3095  */
3096 void
3097 iperf_got_sigend(struct iperf_test *test)
3098 {
3099     /*
3100      * If we're the client, or if we're a server and running a test,
3101      * then dump out the accumulated stats so far.
3102      */
3103     if (test->role == 'c' ||
3104       (test->role == 's' && test->state == TEST_RUNNING)) {
3105 
3106 	test->done = 1;
3107 	cpu_util(test->cpu_util);
3108 	test->stats_callback(test);
3109 	test->state = DISPLAY_RESULTS; /* change local state only */
3110 	if (test->on_test_finish)
3111 	    test->on_test_finish(test);
3112 	test->reporter_callback(test);
3113     }
3114 
3115     if (test->ctrl_sck >= 0) {
3116 	test->state = (test->role == 'c') ? CLIENT_TERMINATE : SERVER_TERMINATE;
3117 	(void) Nwrite(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp);
3118     }
3119     i_errno = (test->role == 'c') ? IECLIENTTERM : IESERVERTERM;
3120     iperf_errexit(test, "interrupt - %s", iperf_strerror(i_errno));
3121 }
3122 
3123 /* Try to write a PID file if requested, return -1 on an error. */
3124 int
3125 iperf_create_pidfile(struct iperf_test *test)
3126 {
3127     if (test->pidfile) {
3128 	int fd;
3129 	char buf[8];
3130 	fd = open(test->pidfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR|S_IWUSR);
3131 	if (fd < 0) {
3132 	    return -1;
3133 	}
3134 	snprintf(buf, sizeof(buf), "%d", getpid()); /* no trailing newline */
3135 	if (write(fd, buf, strlen(buf) + 1) < 0) {
3136 	    return -1;
3137 	}
3138 	if (close(fd) < 0) {
3139 	    return -1;
3140 	};
3141     }
3142     return 0;
3143 }
3144 
3145 /* Get rid of a PID file, return -1 on error. */
3146 int
3147 iperf_delete_pidfile(struct iperf_test *test)
3148 {
3149     if (test->pidfile) {
3150 	if (unlink(test->pidfile) < 0) {
3151 	    return -1;
3152 	}
3153     }
3154     return 0;
3155 }
3156 
3157 int
3158 iperf_json_start(struct iperf_test *test)
3159 {
3160     test->json_top = cJSON_CreateObject();
3161     if (test->json_top == NULL)
3162         return -1;
3163     test->json_start = cJSON_CreateObject();
3164     if (test->json_start == NULL)
3165         return -1;
3166     cJSON_AddItemToObject(test->json_top, "start", test->json_start);
3167     test->json_connected = cJSON_CreateArray();
3168     if (test->json_connected == NULL)
3169         return -1;
3170     cJSON_AddItemToObject(test->json_start, "connected", test->json_connected);
3171     test->json_intervals = cJSON_CreateArray();
3172     if (test->json_intervals == NULL)
3173         return -1;
3174     cJSON_AddItemToObject(test->json_top, "intervals", test->json_intervals);
3175     test->json_end = cJSON_CreateObject();
3176     if (test->json_end == NULL)
3177         return -1;
3178     cJSON_AddItemToObject(test->json_top, "end", test->json_end);
3179     return 0;
3180 }
3181 
3182 int
3183 iperf_json_finish(struct iperf_test *test)
3184 {
3185     if (test->title)
3186 	cJSON_AddStringToObject(test->json_top, "title", test->title);
3187     /* Include server output */
3188     if (test->json_server_output) {
3189 	cJSON_AddItemToObject(test->json_top, "server_output_json", test->json_server_output);
3190     }
3191     if (test->server_output_text) {
3192 	cJSON_AddStringToObject(test->json_top, "server_output_text", test->server_output_text);
3193     }
3194     test->json_output_string = cJSON_Print(test->json_top);
3195     if (test->json_output_string == NULL)
3196         return -1;
3197     fprintf(test->outfile, "%s\n", test->json_output_string);
3198     iflush(test);
3199     cJSON_Delete(test->json_top);
3200     test->json_top = test->json_start = test->json_connected = test->json_intervals = test->json_server_output = test->json_end = NULL;
3201     return 0;
3202 }
3203 
3204 
3205 /* CPU affinity stuff - Linux and FreeBSD only. */
3206 
3207 int
3208 iperf_setaffinity(struct iperf_test *test, int affinity)
3209 {
3210 #if defined(HAVE_SCHED_SETAFFINITY)
3211     cpu_set_t cpu_set;
3212 
3213     CPU_ZERO(&cpu_set);
3214     CPU_SET(affinity, &cpu_set);
3215     if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0) {
3216 	i_errno = IEAFFINITY;
3217         return -1;
3218     }
3219     return 0;
3220 #elif defined(HAVE_CPUSET_SETAFFINITY)
3221     cpuset_t cpumask;
3222 
3223     if(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
3224                           sizeof(cpuset_t), &test->cpumask) != 0) {
3225         i_errno = IEAFFINITY;
3226         return -1;
3227     }
3228 
3229     CPU_ZERO(&cpumask);
3230     CPU_SET(affinity, &cpumask);
3231 
3232     if(cpuset_setaffinity(CPU_LEVEL_WHICH,CPU_WHICH_PID, -1,
3233                           sizeof(cpuset_t), &cpumask) != 0) {
3234         i_errno = IEAFFINITY;
3235         return -1;
3236     }
3237     return 0;
3238 #else /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */
3239     i_errno = IEAFFINITY;
3240     return -1;
3241 #endif /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */
3242 }
3243 
3244 int
3245 iperf_clearaffinity(struct iperf_test *test)
3246 {
3247 #if defined(HAVE_SCHED_SETAFFINITY)
3248     cpu_set_t cpu_set;
3249     int i;
3250 
3251     CPU_ZERO(&cpu_set);
3252     for (i = 0; i < CPU_SETSIZE; ++i)
3253 	CPU_SET(i, &cpu_set);
3254     if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0) {
3255 	i_errno = IEAFFINITY;
3256         return -1;
3257     }
3258     return 0;
3259 #elif defined(HAVE_CPUSET_SETAFFINITY)
3260     if(cpuset_setaffinity(CPU_LEVEL_WHICH,CPU_WHICH_PID, -1,
3261                           sizeof(cpuset_t), &test->cpumask) != 0) {
3262         i_errno = IEAFFINITY;
3263         return -1;
3264     }
3265     return 0;
3266 #else /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */
3267     i_errno = IEAFFINITY;
3268     return -1;
3269 #endif /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */
3270 }
3271 
3272 int
3273 iperf_printf(struct iperf_test *test, const char* format, ...)
3274 {
3275     va_list argp;
3276     int r = -1;
3277 
3278     /*
3279      * There are roughly two use cases here.  If we're the client,
3280      * want to print stuff directly to the output stream.
3281      * If we're the sender we might need to buffer up output to send
3282      * to the client.
3283      *
3284      * This doesn't make a whole lot of difference except there are
3285      * some chunks of output on the client (on particular the whole
3286      * of the server output with --get-server-output) that could
3287      * easily exceed the size of the line buffer, but which don't need
3288      * to be buffered up anyway.
3289      */
3290     if (test->role == 'c') {
3291 	if (test->title)
3292 	    fprintf(test->outfile, "%s:  ", test->title);
3293 	va_start(argp, format);
3294 	r = vfprintf(test->outfile, format, argp);
3295 	va_end(argp);
3296     }
3297     else if (test->role == 's') {
3298 	char linebuffer[1024];
3299 	va_start(argp, format);
3300 	r = vsnprintf(linebuffer, sizeof(linebuffer), format, argp);
3301 	va_end(argp);
3302 	fprintf(test->outfile, "%s", linebuffer);
3303 
3304 	if (test->role == 's' && iperf_get_test_get_server_output(test)) {
3305 	    struct iperf_textline *l = (struct iperf_textline *) malloc(sizeof(struct iperf_textline));
3306 	    l->line = strdup(linebuffer);
3307 	    TAILQ_INSERT_TAIL(&(test->server_output_list), l, textlineentries);
3308 	}
3309     }
3310     return r;
3311 }
3312 
3313 int
3314 iflush(struct iperf_test *test)
3315 {
3316     return fflush(test->outfile);
3317 }
3318