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