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