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