Home | History | Annotate | Download | only in src
      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 (at) 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
    105 usage()
    106 {
    107     fputs(usage_shortstr, stderr);
    108 }
    109 
    110 
    111 void
    112 usage_long(FILE *f)
    113 {
    114     fprintf(f, usage_longstr, UDP_RATE / (1024*1024), DURATION, DEFAULT_TCP_BLKSIZE / 1024, DEFAULT_UDP_BLKSIZE);
    115 }
    116 
    117 
    118 void warning(char *str)
    119 {
    120     fprintf(stderr, "warning: %s\n", str);
    121 }
    122 
    123 
    124 /************** Getter routines for some fields inside iperf_test *************/
    125 
    126 int
    127 iperf_get_verbose(struct iperf_test *ipt)
    128 {
    129     return ipt->verbose;
    130 }
    131 
    132 int
    133 iperf_get_control_socket(struct iperf_test *ipt)
    134 {
    135     return ipt->ctrl_sck;
    136 }
    137 
    138 int
    139 iperf_get_control_socket_mss(struct iperf_test *ipt)
    140 {
    141     return ipt->ctrl_sck_mss;
    142 }
    143 
    144 int
    145 iperf_get_test_omit(struct iperf_test *ipt)
    146 {
    147     return ipt->omit;
    148 }
    149 
    150 int
    151 iperf_get_test_duration(struct iperf_test *ipt)
    152 {
    153     return ipt->duration;
    154 }
    155 
    156 uint64_t
    157 iperf_get_test_rate(struct iperf_test *ipt)
    158 {
    159     return ipt->settings->rate;
    160 }
    161 
    162 uint64_t
    163 iperf_get_test_fqrate(struct iperf_test *ipt)
    164 {
    165     return ipt->settings->fqrate;
    166 }
    167 
    168 int
    169 iperf_get_test_pacing_timer(struct iperf_test *ipt)
    170 {
    171     return ipt->settings->pacing_timer;
    172 }
    173 
    174 uint64_t
    175 iperf_get_test_bytes(struct iperf_test *ipt)
    176 {
    177     return (uint64_t) ipt->settings->bytes;
    178 }
    179 
    180 uint64_t
    181 iperf_get_test_blocks(struct iperf_test *ipt)
    182 {
    183     return (uint64_t) ipt->settings->blocks;
    184 }
    185 
    186 int
    187 iperf_get_test_burst(struct iperf_test *ipt)
    188 {
    189     return ipt->settings->burst;
    190 }
    191 
    192 char
    193 iperf_get_test_role(struct iperf_test *ipt)
    194 {
    195     return ipt->role;
    196 }
    197 
    198 int
    199 iperf_get_test_reverse(struct iperf_test *ipt)
    200 {
    201     return ipt->reverse;
    202 }
    203 
    204 int
    205 iperf_get_test_blksize(struct iperf_test *ipt)
    206 {
    207     return ipt->settings->blksize;
    208 }
    209 
    210 FILE *
    211 iperf_get_test_outfile (struct iperf_test *ipt)
    212 {
    213     return ipt->outfile;
    214 }
    215 
    216 int
    217 iperf_get_test_socket_bufsize(struct iperf_test *ipt)
    218 {
    219     return ipt->settings->socket_bufsize;
    220 }
    221 
    222 double
    223 iperf_get_test_reporter_interval(struct iperf_test *ipt)
    224 {
    225     return ipt->reporter_interval;
    226 }
    227 
    228 double
    229 iperf_get_test_stats_interval(struct iperf_test *ipt)
    230 {
    231     return ipt->stats_interval;
    232 }
    233 
    234 int
    235 iperf_get_test_num_streams(struct iperf_test *ipt)
    236 {
    237     return ipt->num_streams;
    238 }
    239 
    240 int
    241 iperf_get_test_server_port(struct iperf_test *ipt)
    242 {
    243     return ipt->server_port;
    244 }
    245 
    246 char*
    247 iperf_get_test_server_hostname(struct iperf_test *ipt)
    248 {
    249     return ipt->server_hostname;
    250 }
    251 
    252 char*
    253 iperf_get_test_template(struct iperf_test *ipt)
    254 {
    255     return ipt->tmp_template;
    256 }
    257 
    258 int
    259 iperf_get_test_protocol_id(struct iperf_test *ipt)
    260 {
    261     return ipt->protocol->id;
    262 }
    263 
    264 int
    265 iperf_get_test_json_output(struct iperf_test *ipt)
    266 {
    267     return ipt->json_output;
    268 }
    269 
    270 char *
    271 iperf_get_test_json_output_string(struct iperf_test *ipt)
    272 {
    273     return ipt->json_output_string;
    274 }
    275 
    276 int
    277 iperf_get_test_zerocopy(struct iperf_test *ipt)
    278 {
    279     return ipt->zerocopy;
    280 }
    281 
    282 int
    283 iperf_get_test_get_server_output(struct iperf_test *ipt)
    284 {
    285     return ipt->get_server_output;
    286 }
    287 
    288 char
    289 iperf_get_test_unit_format(struct iperf_test *ipt)
    290 {
    291     return ipt->settings->unit_format;
    292 }
    293 
    294 char *
    295 iperf_get_test_bind_address(struct iperf_test *ipt)
    296 {
    297     return ipt->bind_address;
    298 }
    299 
    300 int
    301 iperf_get_test_udp_counters_64bit(struct iperf_test *ipt)
    302 {
    303     return ipt->udp_counters_64bit;
    304 }
    305 
    306 int
    307 iperf_get_test_one_off(struct iperf_test *ipt)
    308 {
    309     return ipt->one_off;
    310 }
    311 
    312 int
    313 iperf_get_test_tos(struct iperf_test *ipt)
    314 {
    315     return ipt->settings->tos;
    316 }
    317 
    318 char *
    319 iperf_get_test_extra_data(struct iperf_test *ipt)
    320 {
    321     return ipt->extra_data;
    322 }
    323 
    324 static const char iperf_version[] = IPERF_VERSION;
    325 char *
    326 iperf_get_iperf_version(void)
    327 {
    328     return (char*)iperf_version;
    329 }
    330 
    331 /************** Setter routines for some fields inside iperf_test *************/
    332 
    333 void
    334 iperf_set_verbose(struct iperf_test *ipt, int verbose)
    335 {
    336     ipt->verbose = verbose;
    337 }
    338 
    339 void
    340 iperf_set_control_socket(struct iperf_test *ipt, int ctrl_sck)
    341 {
    342     ipt->ctrl_sck = ctrl_sck;
    343 }
    344 
    345 void
    346 iperf_set_test_omit(struct iperf_test *ipt, int omit)
    347 {
    348     ipt->omit = omit;
    349 }
    350 
    351 void
    352 iperf_set_test_duration(struct iperf_test *ipt, int duration)
    353 {
    354     ipt->duration = duration;
    355 }
    356 
    357 void
    358 iperf_set_test_reporter_interval(struct iperf_test *ipt, double reporter_interval)
    359 {
    360     ipt->reporter_interval = reporter_interval;
    361 }
    362 
    363 void
    364 iperf_set_test_stats_interval(struct iperf_test *ipt, double stats_interval)
    365 {
    366     ipt->stats_interval = stats_interval;
    367 }
    368 
    369 void
    370 iperf_set_test_state(struct iperf_test *ipt, signed char state)
    371 {
    372     ipt->state = state;
    373 }
    374 
    375 void
    376 iperf_set_test_blksize(struct iperf_test *ipt, int blksize)
    377 {
    378     ipt->settings->blksize = blksize;
    379 }
    380 
    381 void
    382 iperf_set_test_rate(struct iperf_test *ipt, uint64_t rate)
    383 {
    384     ipt->settings->rate = rate;
    385 }
    386 
    387 void
    388 iperf_set_test_fqrate(struct iperf_test *ipt, uint64_t fqrate)
    389 {
    390     ipt->settings->fqrate = fqrate;
    391 }
    392 
    393 void
    394 iperf_set_test_pacing_timer(struct iperf_test *ipt, int pacing_timer)
    395 {
    396     ipt->settings->pacing_timer = pacing_timer;
    397 }
    398 
    399 void
    400 iperf_set_test_bytes(struct iperf_test *ipt, uint64_t bytes)
    401 {
    402     ipt->settings->bytes = (iperf_size_t) bytes;
    403 }
    404 
    405 void
    406 iperf_set_test_blocks(struct iperf_test *ipt, uint64_t blocks)
    407 {
    408     ipt->settings->blocks = (iperf_size_t) blocks;
    409 }
    410 
    411 void
    412 iperf_set_test_burst(struct iperf_test *ipt, int burst)
    413 {
    414     ipt->settings->burst = burst;
    415 }
    416 
    417 void
    418 iperf_set_test_server_port(struct iperf_test *ipt, int srv_port)
    419 {
    420     ipt->server_port = srv_port;
    421 }
    422 
    423 void
    424 iperf_set_test_socket_bufsize(struct iperf_test *ipt, int socket_bufsize)
    425 {
    426     ipt->settings->socket_bufsize = socket_bufsize;
    427 }
    428 
    429 void
    430 iperf_set_test_num_streams(struct iperf_test *ipt, int num_streams)
    431 {
    432     ipt->num_streams = num_streams;
    433 }
    434 
    435 static void
    436 check_sender_has_retransmits(struct iperf_test *ipt)
    437 {
    438     if (ipt->mode != RECEIVER && ipt->protocol->id == Ptcp && has_tcpinfo_retransmits())
    439 	ipt->sender_has_retransmits = 1;
    440     else
    441 	ipt->sender_has_retransmits = 0;
    442 }
    443 
    444 void
    445 iperf_set_test_role(struct iperf_test *ipt, char role)
    446 {
    447     ipt->role = role;
    448     if (!ipt->reverse) {
    449         if (role == 'c')
    450             ipt->mode = SENDER;
    451         else if (role == 's')
    452             ipt->mode = RECEIVER;
    453     } else {
    454         if (role == 'c')
    455             ipt->mode = RECEIVER;
    456         else if (role == 's')
    457             ipt->mode = SENDER;
    458     }
    459     check_sender_has_retransmits(ipt);
    460 }
    461 
    462 void
    463 iperf_set_test_server_hostname(struct iperf_test *ipt, char *server_hostname)
    464 {
    465     ipt->server_hostname = strdup(server_hostname);
    466 }
    467 
    468 void
    469 iperf_set_test_template(struct iperf_test *ipt, char *tmp_template)
    470 {
    471     ipt->tmp_template = strdup(tmp_template);
    472 }
    473 
    474 void
    475 iperf_set_test_reverse(struct iperf_test *ipt, int reverse)
    476 {
    477     ipt->reverse = reverse;
    478     if (!ipt->reverse) {
    479         if (ipt->role == 'c')
    480             ipt->mode = SENDER;
    481         else if (ipt->role == 's')
    482             ipt->mode = RECEIVER;
    483     } else {
    484         if (ipt->role == 'c')
    485             ipt->mode = RECEIVER;
    486         else if (ipt->role == 's')
    487             ipt->mode = SENDER;
    488     }
    489     check_sender_has_retransmits(ipt);
    490 }
    491 
    492 void
    493 iperf_set_test_json_output(struct iperf_test *ipt, int json_output)
    494 {
    495     ipt->json_output = json_output;
    496 }
    497 
    498 int
    499 iperf_has_zerocopy( void )
    500 {
    501     return has_sendfile();
    502 }
    503 
    504 void
    505 iperf_set_test_zerocopy(struct iperf_test *ipt, int zerocopy)
    506 {
    507     ipt->zerocopy = (zerocopy && has_sendfile());
    508 }
    509 
    510 void
    511 iperf_set_test_get_server_output(struct iperf_test *ipt, int get_server_output)
    512 {
    513     ipt->get_server_output = get_server_output;
    514 }
    515 
    516 void
    517 iperf_set_test_unit_format(struct iperf_test *ipt, char unit_format)
    518 {
    519     ipt->settings->unit_format = unit_format;
    520 }
    521 
    522 #if defined(HAVE_SSL)
    523 void
    524 iperf_set_test_client_username(struct iperf_test *ipt, char *client_username)
    525 {
    526     ipt->settings->client_username = client_username;
    527 }
    528 
    529 void
    530 iperf_set_test_client_password(struct iperf_test *ipt, char *client_password)
    531 {
    532     ipt->settings->client_password = client_password;
    533 }
    534 
    535 void
    536 iperf_set_test_client_rsa_pubkey(struct iperf_test *ipt, char *client_rsa_pubkey_base64)
    537 {
    538     ipt->settings->client_rsa_pubkey = load_pubkey_from_base64(client_rsa_pubkey_base64);
    539 }
    540 #endif // HAVE_SSL
    541 
    542 void
    543 iperf_set_test_bind_address(struct iperf_test *ipt, char *bnd_address)
    544 {
    545     ipt->bind_address = strdup(bnd_address);
    546 }
    547 
    548 void
    549 iperf_set_test_udp_counters_64bit(struct iperf_test *ipt, int udp_counters_64bit)
    550 {
    551     ipt->udp_counters_64bit = udp_counters_64bit;
    552 }
    553 
    554 void
    555 iperf_set_test_one_off(struct iperf_test *ipt, int one_off)
    556 {
    557     ipt->one_off = one_off;
    558 }
    559 
    560 void
    561 iperf_set_test_tos(struct iperf_test *ipt, int tos)
    562 {
    563     ipt->settings->tos = tos;
    564 }
    565 
    566 void
    567 iperf_set_test_extra_data(struct iperf_test *ipt, char *dat)
    568 {
    569     ipt->extra_data = dat;
    570 }
    571 
    572 void
    573 iperf_set_test_bidirectional(struct iperf_test* ipt, int bidirectional)
    574 {
    575     ipt->bidirectional = bidirectional;
    576     if (bidirectional)
    577         ipt->mode = BIDIRECTIONAL;
    578     else
    579         iperf_set_test_reverse(ipt, ipt->reverse);
    580 }
    581 
    582 /********************** Get/set test protocol structure ***********************/
    583 
    584 struct protocol *
    585 get_protocol(struct iperf_test *test, int prot_id)
    586 {
    587     struct protocol *prot;
    588 
    589     SLIST_FOREACH(prot, &test->protocols, protocols) {
    590         if (prot->id == prot_id)
    591             break;
    592     }
    593 
    594     if (prot == NULL)
    595         i_errno = IEPROTOCOL;
    596 
    597     return prot;
    598 }
    599 
    600 int
    601 set_protocol(struct iperf_test *test, int prot_id)
    602 {
    603     struct protocol *prot = NULL;
    604 
    605     SLIST_FOREACH(prot, &test->protocols, protocols) {
    606         if (prot->id == prot_id) {
    607             test->protocol = prot;
    608 	    check_sender_has_retransmits(test);
    609             return 0;
    610         }
    611     }
    612 
    613     i_errno = IEPROTOCOL;
    614     return -1;
    615 }
    616 
    617 
    618 /************************** Iperf callback functions **************************/
    619 
    620 void
    621 iperf_on_new_stream(struct iperf_stream *sp)
    622 {
    623     connect_msg(sp);
    624 }
    625 
    626 void
    627 iperf_on_test_start(struct iperf_test *test)
    628 {
    629     if (test->json_output) {
    630 	cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s  num_streams: %d  blksize: %d  omit: %d  duration: %d  bytes: %d  blocks: %d  reverse: %d  tos: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks, test->reverse?(int64_t)1:(int64_t)0, (int64_t) test->settings->tos));
    631     } else {
    632 	if (test->verbose) {
    633 	    if (test->settings->bytes)
    634 		iperf_printf(test, test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->bytes, test->settings->tos);
    635 	    else if (test->settings->blocks)
    636 		iperf_printf(test, test_start_blocks, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->blocks, test->settings->tos);
    637 	    else
    638 		iperf_printf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->duration, test->settings->tos);
    639 	}
    640     }
    641 }
    642 
    643 /* This converts an IPv6 string address from IPv4-mapped format into regular
    644 ** old IPv4 format, which is easier on the eyes of network veterans.
    645 **
    646 ** If the v6 address is not v4-mapped it is left alone.
    647 */
    648 static void
    649 mapped_v4_to_regular_v4(char *str)
    650 {
    651     char *prefix = "::ffff:";
    652     int prefix_len;
    653 
    654     prefix_len = strlen(prefix);
    655     if (strncmp(str, prefix, prefix_len) == 0) {
    656 	int str_len = strlen(str);
    657 	memmove(str, str + prefix_len, str_len - prefix_len + 1);
    658     }
    659 }
    660 
    661 void
    662 iperf_on_connect(struct iperf_test *test)
    663 {
    664     time_t now_secs;
    665     const char* rfc1123_fmt = "%a, %d %b %Y %H:%M:%S GMT";
    666     char now_str[100];
    667     char ipr[INET6_ADDRSTRLEN];
    668     int port;
    669     struct sockaddr_storage sa;
    670     struct sockaddr_in *sa_inP;
    671     struct sockaddr_in6 *sa_in6P;
    672     socklen_t len;
    673 
    674     now_secs = time((time_t*) 0);
    675     (void) strftime(now_str, sizeof(now_str), rfc1123_fmt, gmtime(&now_secs));
    676     if (test->json_output)
    677 	cJSON_AddItemToObject(test->json_start, "timestamp", iperf_json_printf("time: %s  timesecs: %d", now_str, (int64_t) now_secs));
    678     else if (test->verbose)
    679 	iperf_printf(test, report_time, now_str);
    680 
    681     if (test->role == 'c') {
    682 	if (test->json_output)
    683 	    cJSON_AddItemToObject(test->json_start, "connecting_to", iperf_json_printf("host: %s  port: %d", test->server_hostname, (int64_t) test->server_port));
    684 	else {
    685 	    iperf_printf(test, report_connecting, test->server_hostname, test->server_port);
    686 	    if (test->reverse)
    687 		iperf_printf(test, report_reverse, test->server_hostname);
    688 	}
    689     } else {
    690         len = sizeof(sa);
    691         getpeername(test->ctrl_sck, (struct sockaddr *) &sa, &len);
    692         if (getsockdomain(test->ctrl_sck) == AF_INET) {
    693 	    sa_inP = (struct sockaddr_in *) &sa;
    694             inet_ntop(AF_INET, &sa_inP->sin_addr, ipr, sizeof(ipr));
    695 	    port = ntohs(sa_inP->sin_port);
    696         } else {
    697 	    sa_in6P = (struct sockaddr_in6 *) &sa;
    698             inet_ntop(AF_INET6, &sa_in6P->sin6_addr, ipr, sizeof(ipr));
    699 	    port = ntohs(sa_in6P->sin6_port);
    700         }
    701 	mapped_v4_to_regular_v4(ipr);
    702 	if (test->json_output)
    703 	    cJSON_AddItemToObject(test->json_start, "accepted_connection", iperf_json_printf("host: %s  port: %d", ipr, (int64_t) port));
    704 	else
    705 	    iperf_printf(test, report_accepted, ipr, port);
    706     }
    707     if (test->json_output) {
    708 	cJSON_AddStringToObject(test->json_start, "cookie", test->cookie);
    709         if (test->protocol->id == SOCK_STREAM) {
    710 	    if (test->settings->mss)
    711 		cJSON_AddNumberToObject(test->json_start, "tcp_mss", test->settings->mss);
    712 	    else {
    713 		cJSON_AddNumberToObject(test->json_start, "tcp_mss_default", test->ctrl_sck_mss);
    714 	    }
    715         if (test->settings->rate)
    716             cJSON_AddNumberToObject(test->json_start, "target_bitrate", test->settings->rate);
    717         }
    718     } else if (test->verbose) {
    719         iperf_printf(test, report_cookie, test->cookie);
    720         if (test->protocol->id == SOCK_STREAM) {
    721             if (test->settings->mss)
    722                 iperf_printf(test, "      TCP MSS: %d\n", test->settings->mss);
    723             else {
    724                 iperf_printf(test, "      TCP MSS: %d (default)\n", test->ctrl_sck_mss);
    725             }
    726         }
    727         if (test->settings->rate)
    728             iperf_printf(test, "      Target Bitrate: %llu\n", test->settings->rate);
    729     }
    730 }
    731 
    732 void
    733 iperf_on_test_finish(struct iperf_test *test)
    734 {
    735 }
    736 
    737 
    738 /******************************************************************************/
    739 
    740 int
    741 iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
    742 {
    743     static struct option longopts[] =
    744     {
    745         {"port", required_argument, NULL, 'p'},
    746         {"format", required_argument, NULL, 'f'},
    747         {"interval", required_argument, NULL, 'i'},
    748         {"daemon", no_argument, NULL, 'D'},
    749         {"one-off", no_argument, NULL, '1'},
    750         {"verbose", no_argument, NULL, 'V'},
    751         {"json", no_argument, NULL, 'J'},
    752         {"version", no_argument, NULL, 'v'},
    753         {"server", no_argument, NULL, 's'},
    754         {"client", required_argument, NULL, 'c'},
    755         {"udp", no_argument, NULL, 'u'},
    756         {"bitrate", required_argument, NULL, 'b'},
    757         {"bandwidth", required_argument, NULL, 'b'},
    758         {"time", required_argument, NULL, 't'},
    759         {"bytes", required_argument, NULL, 'n'},
    760         {"blockcount", required_argument, NULL, 'k'},
    761         {"length", required_argument, NULL, 'l'},
    762         {"parallel", required_argument, NULL, 'P'},
    763         {"reverse", no_argument, NULL, 'R'},
    764         {"bidir", no_argument, NULL, OPT_BIDIRECTIONAL},
    765         {"window", required_argument, NULL, 'w'},
    766         {"bind", required_argument, NULL, 'B'},
    767         {"cport", required_argument, NULL, OPT_CLIENT_PORT},
    768         {"set-mss", required_argument, NULL, 'M'},
    769         {"no-delay", no_argument, NULL, 'N'},
    770         {"version4", no_argument, NULL, '4'},
    771         {"version6", no_argument, NULL, '6'},
    772         {"tos", required_argument, NULL, 'S'},
    773         {"dscp", required_argument, NULL, OPT_DSCP},
    774 	{"extra-data", required_argument, NULL, OPT_EXTRA_DATA},
    775 #if defined(HAVE_FLOWLABEL)
    776         {"flowlabel", required_argument, NULL, 'L'},
    777 #endif /* HAVE_FLOWLABEL */
    778         {"zerocopy", no_argument, NULL, 'Z'},
    779         {"omit", required_argument, NULL, 'O'},
    780         {"file", required_argument, NULL, 'F'},
    781         {"repeating-payload", no_argument, NULL, OPT_REPEATING_PAYLOAD},
    782 #if defined(HAVE_CPU_AFFINITY)
    783         {"affinity", required_argument, NULL, 'A'},
    784 #endif /* HAVE_CPU_AFFINITY */
    785         {"title", required_argument, NULL, 'T'},
    786 #if defined(HAVE_TCP_CONGESTION)
    787         {"congestion", required_argument, NULL, 'C'},
    788         {"linux-congestion", required_argument, NULL, 'C'},
    789 #endif /* HAVE_TCP_CONGESTION */
    790 #if defined(HAVE_SCTP)
    791         {"sctp", no_argument, NULL, OPT_SCTP},
    792         {"nstreams", required_argument, NULL, OPT_NUMSTREAMS},
    793         {"xbind", required_argument, NULL, 'X'},
    794 #endif
    795 	{"pidfile", required_argument, NULL, 'I'},
    796 	{"logfile", required_argument, NULL, OPT_LOGFILE},
    797 	{"forceflush", no_argument, NULL, OPT_FORCEFLUSH},
    798 	{"get-server-output", no_argument, NULL, OPT_GET_SERVER_OUTPUT},
    799 	{"udp-counters-64bit", no_argument, NULL, OPT_UDP_COUNTERS_64BIT},
    800  	{"no-fq-socket-pacing", no_argument, NULL, OPT_NO_FQ_SOCKET_PACING},
    801 #if defined(HAVE_SSL)
    802     {"username", required_argument, NULL, OPT_CLIENT_USERNAME},
    803     {"rsa-public-key-path", required_argument, NULL, OPT_CLIENT_RSA_PUBLIC_KEY},
    804     {"rsa-private-key-path", required_argument, NULL, OPT_SERVER_RSA_PRIVATE_KEY},
    805     {"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS},
    806 #endif /* HAVE_SSL */
    807 	{"fq-rate", required_argument, NULL, OPT_FQ_RATE},
    808 	{"pacing-timer", required_argument, NULL, OPT_PACING_TIMER},
    809 	{"connect-timeout", required_argument, NULL, OPT_CONNECT_TIMEOUT},
    810         {"debug", no_argument, NULL, 'd'},
    811         {"help", no_argument, NULL, 'h'},
    812         {NULL, 0, NULL, 0}
    813     };
    814     int flag;
    815     int blksize;
    816     int server_flag, client_flag, rate_flag, duration_flag;
    817     char *endptr;
    818 #if defined(HAVE_CPU_AFFINITY)
    819     char* comma;
    820 #endif /* HAVE_CPU_AFFINITY */
    821     char* slash;
    822     struct xbind_entry *xbe;
    823     double farg;
    824 
    825     blksize = 0;
    826     server_flag = client_flag = rate_flag = duration_flag = 0;
    827 #if defined(HAVE_SSL)
    828     char *client_username = NULL, *client_rsa_public_key = NULL, *server_rsa_private_key = NULL;
    829 #endif /* HAVE_SSL */
    830 
    831     while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
    832         switch (flag) {
    833             case 'p':
    834                 test->server_port = atoi(optarg);
    835                 break;
    836             case 'f':
    837 		if (!optarg) {
    838 		    i_errno = IEBADFORMAT;
    839 		    return -1;
    840 		}
    841 		test->settings->unit_format = *optarg;
    842 		if (test->settings->unit_format == 'k' ||
    843 		    test->settings->unit_format == 'K' ||
    844 		    test->settings->unit_format == 'm' ||
    845 		    test->settings->unit_format == 'M' ||
    846 		    test->settings->unit_format == 'g' ||
    847 		    test->settings->unit_format == 'G' ||
    848 		    test->settings->unit_format == 't' ||
    849 		    test->settings->unit_format == 'T') {
    850 			break;
    851 		}
    852 		else {
    853 		    i_errno = IEBADFORMAT;
    854 		    return -1;
    855 		}
    856                 break;
    857             case 'i':
    858                 /* XXX: could potentially want separate stat collection and reporting intervals,
    859                    but just set them to be the same for now */
    860                 test->stats_interval = test->reporter_interval = atof(optarg);
    861                 if ((test->stats_interval < MIN_INTERVAL || test->stats_interval > MAX_INTERVAL) && test->stats_interval != 0) {
    862                     i_errno = IEINTERVAL;
    863                     return -1;
    864                 }
    865                 break;
    866             case 'D':
    867 		test->daemon = 1;
    868 		server_flag = 1;
    869 	        break;
    870             case '1':
    871 		test->one_off = 1;
    872 		server_flag = 1;
    873 	        break;
    874             case 'V':
    875                 test->verbose = 1;
    876                 break;
    877             case 'J':
    878                 test->json_output = 1;
    879                 break;
    880             case 'v':
    881                 printf("%s (cJSON %s)\n%s\n%s\n", version, cJSON_Version(), get_system_info(),
    882 		       get_optional_features());
    883                 exit(0);
    884             case 's':
    885                 if (test->role == 'c') {
    886                     i_errno = IESERVCLIENT;
    887                     return -1;
    888                 }
    889 		iperf_set_test_role(test, 's');
    890                 break;
    891             case 'c':
    892                 if (test->role == 's') {
    893                     i_errno = IESERVCLIENT;
    894                     return -1;
    895                 }
    896 		iperf_set_test_role(test, 'c');
    897 		iperf_set_test_server_hostname(test, optarg);
    898                 break;
    899             case 'u':
    900                 set_protocol(test, Pudp);
    901 		client_flag = 1;
    902                 break;
    903             case OPT_SCTP:
    904 #if defined(HAVE_SCTP)
    905                 set_protocol(test, Psctp);
    906                 client_flag = 1;
    907                 break;
    908 #else /* HAVE_SCTP */
    909                 i_errno = IEUNIMP;
    910                 return -1;
    911 #endif /* HAVE_SCTP */
    912 
    913             case OPT_NUMSTREAMS:
    914 #if defined(linux) || defined(__FreeBSD__)
    915                 test->settings->num_ostreams = unit_atoi(optarg);
    916                 client_flag = 1;
    917 #else /* linux */
    918                 i_errno = IEUNIMP;
    919                 return -1;
    920 #endif /* linux */
    921             case 'b':
    922 		slash = strchr(optarg, '/');
    923 		if (slash) {
    924 		    *slash = '\0';
    925 		    ++slash;
    926 		    test->settings->burst = atoi(slash);
    927 		    if (test->settings->burst <= 0 ||
    928 		        test->settings->burst > MAX_BURST) {
    929 			i_errno = IEBURST;
    930 			return -1;
    931 		    }
    932 		}
    933                 test->settings->rate = unit_atof_rate(optarg);
    934 		rate_flag = 1;
    935 		client_flag = 1;
    936                 break;
    937             case 't':
    938                 test->duration = atoi(optarg);
    939                 if (test->duration > MAX_TIME) {
    940                     i_errno = IEDURATION;
    941                     return -1;
    942                 }
    943 		duration_flag = 1;
    944 		client_flag = 1;
    945                 break;
    946             case 'n':
    947                 test->settings->bytes = unit_atoi(optarg);
    948 		client_flag = 1;
    949                 break;
    950             case 'k':
    951                 test->settings->blocks = unit_atoi(optarg);
    952 		client_flag = 1;
    953                 break;
    954             case 'l':
    955                 blksize = unit_atoi(optarg);
    956 		client_flag = 1;
    957                 break;
    958             case 'P':
    959                 test->num_streams = atoi(optarg);
    960                 if (test->num_streams > MAX_STREAMS) {
    961                     i_errno = IENUMSTREAMS;
    962                     return -1;
    963                 }
    964 		client_flag = 1;
    965                 break;
    966             case 'R':
    967                 if (test->bidirectional) {
    968                     i_errno = IEREVERSEBIDIR;
    969                     return -1;
    970                 }
    971 		iperf_set_test_reverse(test, 1);
    972 		client_flag = 1;
    973                 break;
    974             case OPT_BIDIRECTIONAL:
    975                 if (test->reverse) {
    976                     i_errno = IEREVERSEBIDIR;
    977                     return -1;
    978                 }
    979                 iperf_set_test_bidirectional(test, 1);
    980                 client_flag = 1;
    981                 break;
    982             case 'w':
    983                 // XXX: This is a socket buffer, not specific to TCP
    984 		// Do sanity checks as double-precision floating point
    985 		// to avoid possible integer overflows.
    986                 farg = unit_atof(optarg);
    987                 if (farg > (double) MAX_TCP_BUFFER) {
    988                     i_errno = IEBUFSIZE;
    989                     return -1;
    990                 }
    991                 test->settings->socket_bufsize = (int) farg;
    992 		client_flag = 1;
    993                 break;
    994             case 'B':
    995                 test->bind_address = strdup(optarg);
    996                 break;
    997             case OPT_CLIENT_PORT:
    998                 test->bind_port = atoi(optarg);
    999                 break;
   1000             case 'M':
   1001                 test->settings->mss = atoi(optarg);
   1002                 if (test->settings->mss > MAX_MSS) {
   1003                     i_errno = IEMSS;
   1004                     return -1;
   1005                 }
   1006 		client_flag = 1;
   1007                 break;
   1008             case 'N':
   1009                 test->no_delay = 1;
   1010 		client_flag = 1;
   1011                 break;
   1012             case '4':
   1013                 test->settings->domain = AF_INET;
   1014                 break;
   1015             case '6':
   1016                 test->settings->domain = AF_INET6;
   1017                 break;
   1018             case 'S':
   1019                 test->settings->tos = strtol(optarg, &endptr, 0);
   1020 		if (endptr == optarg ||
   1021 		    test->settings->tos < 0 ||
   1022 		    test->settings->tos > 255) {
   1023 		    i_errno = IEBADTOS;
   1024 		    return -1;
   1025 		}
   1026 		client_flag = 1;
   1027                 break;
   1028 	    case OPT_DSCP:
   1029                 test->settings->tos = parse_qos(optarg);
   1030 		if(test->settings->tos < 0) {
   1031 			i_errno = IEBADTOS;
   1032 			return -1;
   1033 		}
   1034 		client_flag = 1;
   1035                 break;
   1036 	    case OPT_EXTRA_DATA:
   1037 		test->extra_data = strdup(optarg);
   1038 		client_flag = 1;
   1039 	        break;
   1040             case 'L':
   1041 #if defined(HAVE_FLOWLABEL)
   1042                 test->settings->flowlabel = strtol(optarg, &endptr, 0);
   1043 		if (endptr == optarg ||
   1044 		    test->settings->flowlabel < 1 || test->settings->flowlabel > 0xfffff) {
   1045                     i_errno = IESETFLOW;
   1046                     return -1;
   1047 		}
   1048 		client_flag = 1;
   1049 #else /* HAVE_FLOWLABEL */
   1050                 i_errno = IEUNIMP;
   1051                 return -1;
   1052 #endif /* HAVE_FLOWLABEL */
   1053                 break;
   1054             case 'X':
   1055 		xbe = (struct xbind_entry *)malloc(sizeof(struct xbind_entry));
   1056                 if (!xbe) {
   1057 		    i_errno = IESETSCTPBINDX;
   1058                     return -1;
   1059                 }
   1060 	        memset(xbe, 0, sizeof(*xbe));
   1061                 xbe->name = strdup(optarg);
   1062                 if (!xbe->name) {
   1063 		    i_errno = IESETSCTPBINDX;
   1064                     return -1;
   1065                 }
   1066 		TAILQ_INSERT_TAIL(&test->xbind_addrs, xbe, link);
   1067                 break;
   1068             case 'Z':
   1069                 if (!has_sendfile()) {
   1070                     i_errno = IENOSENDFILE;
   1071                     return -1;
   1072                 }
   1073                 test->zerocopy = 1;
   1074 		client_flag = 1;
   1075                 break;
   1076             case OPT_REPEATING_PAYLOAD:
   1077                 test->repeating_payload = 1;
   1078                 client_flag = 1;
   1079                 break;
   1080             case 'O':
   1081                 test->omit = atoi(optarg);
   1082                 if (test->omit < 0 || test->omit > 60) {
   1083                     i_errno = IEOMIT;
   1084                     return -1;
   1085                 }
   1086 		client_flag = 1;
   1087                 break;
   1088             case 'F':
   1089                 test->diskfile_name = optarg;
   1090                 break;
   1091             case 'A':
   1092 #if defined(HAVE_CPU_AFFINITY)
   1093                 test->affinity = strtol(optarg, &endptr, 0);
   1094                 if (endptr == optarg ||
   1095 		    test->affinity < 0 || test->affinity > 1024) {
   1096                     i_errno = IEAFFINITY;
   1097                     return -1;
   1098                 }
   1099 		comma = strchr(optarg, ',');
   1100 		if (comma != NULL) {
   1101 		    test->server_affinity = atoi(comma+1);
   1102 		    if (test->server_affinity < 0 || test->server_affinity > 1024) {
   1103 			i_errno = IEAFFINITY;
   1104 			return -1;
   1105 		    }
   1106 		    client_flag = 1;
   1107 		}
   1108 #else /* HAVE_CPU_AFFINITY */
   1109                 i_errno = IEUNIMP;
   1110                 return -1;
   1111 #endif /* HAVE_CPU_AFFINITY */
   1112                 break;
   1113             case 'T':
   1114                 test->title = strdup(optarg);
   1115 		client_flag = 1;
   1116                 break;
   1117 	    case 'C':
   1118 #if defined(HAVE_TCP_CONGESTION)
   1119 		test->congestion = strdup(optarg);
   1120 		client_flag = 1;
   1121 #else /* HAVE_TCP_CONGESTION */
   1122 		i_errno = IEUNIMP;
   1123 		return -1;
   1124 #endif /* HAVE_TCP_CONGESTION */
   1125 		break;
   1126 	    case 'd':
   1127 		test->debug = 1;
   1128 		break;
   1129 	    case 'I':
   1130 		test->pidfile = strdup(optarg);
   1131 		server_flag = 1;
   1132 	        break;
   1133 	    case OPT_LOGFILE:
   1134 		test->logfile = strdup(optarg);
   1135 		break;
   1136 	    case OPT_FORCEFLUSH:
   1137 		test->forceflush = 1;
   1138 		break;
   1139 	    case OPT_GET_SERVER_OUTPUT:
   1140 		test->get_server_output = 1;
   1141 		client_flag = 1;
   1142 		break;
   1143 	    case OPT_UDP_COUNTERS_64BIT:
   1144 		test->udp_counters_64bit = 1;
   1145 		break;
   1146 	    case OPT_NO_FQ_SOCKET_PACING:
   1147 #if defined(HAVE_SO_MAX_PACING_RATE)
   1148 		printf("Warning:  --no-fq-socket-pacing is deprecated\n");
   1149 		test->settings->fqrate = 0;
   1150 		client_flag = 1;
   1151 #else /* HAVE_SO_MAX_PACING_RATE */
   1152 		i_errno = IEUNIMP;
   1153 		return -1;
   1154 #endif
   1155 		break;
   1156 	    case OPT_FQ_RATE:
   1157 #if defined(HAVE_SO_MAX_PACING_RATE)
   1158 		test->settings->fqrate = unit_atof_rate(optarg);
   1159 		client_flag = 1;
   1160 #else /* HAVE_SO_MAX_PACING_RATE */
   1161 		i_errno = IEUNIMP;
   1162 		return -1;
   1163 #endif
   1164 		break;
   1165 #if defined(HAVE_SSL)
   1166         case OPT_CLIENT_USERNAME:
   1167             client_username = strdup(optarg);
   1168             break;
   1169         case OPT_CLIENT_RSA_PUBLIC_KEY:
   1170             client_rsa_public_key = strdup(optarg);
   1171             break;
   1172         case OPT_SERVER_RSA_PRIVATE_KEY:
   1173             server_rsa_private_key = strdup(optarg);
   1174             break;
   1175         case OPT_SERVER_AUTHORIZED_USERS:
   1176             test->server_authorized_users = strdup(optarg);
   1177             break;
   1178 #endif /* HAVE_SSL */
   1179 	    case OPT_PACING_TIMER:
   1180 		test->settings->pacing_timer = unit_atoi(optarg);
   1181 		client_flag = 1;
   1182 		break;
   1183 	    case OPT_CONNECT_TIMEOUT:
   1184 		test->settings->connect_timeout = unit_atoi(optarg);
   1185 		client_flag = 1;
   1186 		break;
   1187 	    case 'h':
   1188 		usage_long(stdout);
   1189 		exit(0);
   1190             default:
   1191                 usage_long(stderr);
   1192                 exit(1);
   1193         }
   1194     }
   1195 
   1196     /* Set logging to a file if specified, otherwise use the default (stdout) */
   1197     if (test->logfile) {
   1198         test->outfile = fopen(test->logfile, "a+");
   1199         if (test->outfile == NULL) {
   1200             i_errno = IELOGFILE;
   1201             return -1;
   1202         }
   1203     }
   1204 
   1205     /* Check flag / role compatibility. */
   1206     if (test->role == 'c' && server_flag) {
   1207         i_errno = IESERVERONLY;
   1208         return -1;
   1209     }
   1210     if (test->role == 's' && client_flag) {
   1211         i_errno = IECLIENTONLY;
   1212         return -1;
   1213     }
   1214 
   1215 #if defined(HAVE_SSL)
   1216 
   1217     if (test->role == 's' && (client_username || client_rsa_public_key)){
   1218         i_errno = IECLIENTONLY;
   1219         return -1;
   1220     } else if (test->role == 'c' && (client_username || client_rsa_public_key) &&
   1221         !(client_username && client_rsa_public_key)) {
   1222         i_errno = IESETCLIENTAUTH;
   1223         return -1;
   1224     } else if (test->role == 'c' && (client_username && client_rsa_public_key)){
   1225 
   1226         char *client_password = NULL;
   1227         size_t s;
   1228         if ((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
   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
   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
   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
   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
   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
   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
   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)
   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
   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
   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
   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
   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
   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
   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
   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 *
   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
   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
   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 *
   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 *
   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
   2210 protocol_free(struct protocol *proto)
   2211 {
   2212     free(proto);
   2213 }
   2214 
   2215 /**************************************************************************/
   2216 int
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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 *
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   4043 iflush(struct iperf_test *test)
   4044 {
   4045     return fflush(test->outfile);
   4046 }
   4047