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