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