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