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