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