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