1 /* 2 * iperf, Copyright (c) 2014-2021, The Regents of the University of 3 * California, through Lawrence Berkeley National Laboratory (subject 4 * to receipt of any required approvals from the U.S. Dept. of 5 * Energy). All rights reserved. 6 * 7 * If you have questions about your rights to use or distribute this 8 * software, please contact Berkeley Lab's Technology Transfer 9 * Department at [email protected]. 10 * 11 * NOTICE. This software is owned by the U.S. Department of Energy. 12 * As such, the U.S. Government has been granted for itself and others 13 * acting on its behalf a paid-up, nonexclusive, irrevocable, 14 * worldwide license in the Software to reproduce, prepare derivative 15 * works, and perform publicly and display publicly. Beginning five 16 * (5) years after the date permission to assert copyright is obtained 17 * from the U.S. Department of Energy, and subject to any subsequent 18 * five (5) year renewals, the U.S. Government is granted for itself 19 * and others acting on its behalf a paid-up, nonexclusive, 20 * irrevocable, worldwide license in the Software to reproduce, 21 * prepare derivative works, distribute copies to the public, perform 22 * publicly and display publicly, and to permit others to do so. 23 * 24 * This code is distributed under a BSD style license, see the LICENSE 25 * file for complete information. 26 */ 27 #include <errno.h> 28 #include <setjmp.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 #include <signal.h> 34 #include <sys/types.h> 35 #include <netinet/in.h> 36 #include <sys/select.h> 37 #include <sys/uio.h> 38 #include <arpa/inet.h> 39 40 #include "iperf.h" 41 #include "iperf_api.h" 42 #include "iperf_util.h" 43 #include "iperf_locale.h" 44 #include "iperf_time.h" 45 #include "net.h" 46 #include "timer.h" 47 48 #if defined(HAVE_TCP_CONGESTION) 49 #if !defined(TCP_CA_NAME_MAX) 50 #define TCP_CA_NAME_MAX 16 51 #endif /* TCP_CA_NAME_MAX */ 52 #endif /* HAVE_TCP_CONGESTION */ 53 54 int 55 iperf_create_streams(struct iperf_test *test, int sender) 56 { 57 int i, s; 58 #if defined(HAVE_TCP_CONGESTION) 59 int saved_errno; 60 #endif /* HAVE_TCP_CONGESTION */ 61 struct iperf_stream *sp; 62 63 int orig_bind_port = test->bind_port; 64 for (i = 0; i < test->num_streams; ++i) { 65 66 test->bind_port = orig_bind_port; 67 if (orig_bind_port) { 68 test->bind_port += i; 69 // If Bidir make sure send and receive ports are different 70 if (!sender && test->mode == BIDIRECTIONAL) 71 test->bind_port += test->num_streams; 72 } 73 s = test->protocol->connect(test); 74 test->bind_port = orig_bind_port; 75 if (s < 0) 76 return -1; 77 78 #if defined(HAVE_TCP_CONGESTION) 79 if (test->protocol->id == Ptcp) { 80 if (test->congestion) { 81 if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) { 82 saved_errno = errno; 83 close(s); 84 errno = saved_errno; 85 i_errno = IESETCONGESTION; 86 return -1; 87 } 88 } 89 { 90 socklen_t len = TCP_CA_NAME_MAX; 91 char ca[TCP_CA_NAME_MAX + 1]; 92 int rc; 93 rc = getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len); 94 if (rc < 0 && test->congestion) { 95 saved_errno = errno; 96 close(s); 97 errno = saved_errno; 98 i_errno = IESETCONGESTION; 99 return -1; 100 } 101 // Set actual used congestion alg, or set to unknown if could not get it 102 if (rc < 0) 103 test->congestion_used = strdup("unknown"); 104 else 105 test->congestion_used = strdup(ca); 106 if (test->debug) { 107 printf("Congestion algorithm is %s\n", test->congestion_used); 108 } 109 } 110 } 111 #endif /* HAVE_TCP_CONGESTION */ 112 113 if (sender) 114 FD_SET(s, &test->write_set); 115 else 116 FD_SET(s, &test->read_set); 117 if (s > test->max_fd) test->max_fd = s; 118 119 sp = iperf_new_stream(test, s, sender); 120 if (!sp) 121 return -1; 122 123 /* Perform the new stream callback */ 124 if (test->on_new_stream) 125 test->on_new_stream(sp); 126 } 127 128 return 0; 129 } 130 131 static void 132 test_timer_proc(TimerClientData client_data, struct iperf_time *nowP) 133 { 134 struct iperf_test *test = client_data.p; 135 136 test->timer = NULL; 137 test->done = 1; 138 } 139 140 static void 141 client_stats_timer_proc(TimerClientData client_data, struct iperf_time *nowP) 142 { 143 struct iperf_test *test = client_data.p; 144 145 if (test->done) 146 return; 147 if (test->stats_callback) 148 test->stats_callback(test); 149 } 150 151 static void 152 client_reporter_timer_proc(TimerClientData client_data, struct iperf_time *nowP) 153 { 154 struct iperf_test *test = client_data.p; 155 156 if (test->done) 157 return; 158 if (test->reporter_callback) 159 test->reporter_callback(test); 160 } 161 162 static int 163 create_client_timers(struct iperf_test * test) 164 { 165 struct iperf_time now; 166 TimerClientData cd; 167 168 if (iperf_time_now(&now) < 0) { 169 i_errno = IEINITTEST; 170 return -1; 171 } 172 cd.p = test; 173 test->timer = test->stats_timer = test->reporter_timer = NULL; 174 if (test->duration != 0) { 175 test->done = 0; 176 test->timer = tmr_create(&now, test_timer_proc, cd, ( test->duration + test->omit ) * SEC_TO_US, 0); 177 if (test->timer == NULL) { 178 i_errno = IEINITTEST; 179 return -1; 180 } 181 } 182 if (test->stats_interval != 0) { 183 test->stats_timer = tmr_create(&now, client_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1); 184 if (test->stats_timer == NULL) { 185 i_errno = IEINITTEST; 186 return -1; 187 } 188 } 189 if (test->reporter_interval != 0) { 190 test->reporter_timer = tmr_create(&now, client_reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1); 191 if (test->reporter_timer == NULL) { 192 i_errno = IEINITTEST; 193 return -1; 194 } 195 } 196 return 0; 197 } 198 199 static void 200 client_omit_timer_proc(TimerClientData client_data, struct iperf_time *nowP) 201 { 202 struct iperf_test *test = client_data.p; 203 204 test->omit_timer = NULL; 205 test->omitting = 0; 206 iperf_reset_stats(test); 207 if (test->verbose && !test->json_output && test->reporter_interval == 0) 208 iperf_printf(test, "%s", report_omit_done); 209 210 /* Reset the timers. */ 211 if (test->stats_timer != NULL) 212 tmr_reset(nowP, test->stats_timer); 213 if (test->reporter_timer != NULL) 214 tmr_reset(nowP, test->reporter_timer); 215 } 216 217 static int 218 create_client_omit_timer(struct iperf_test * test) 219 { 220 struct iperf_time now; 221 TimerClientData cd; 222 223 if (test->omit == 0) { 224 test->omit_timer = NULL; 225 test->omitting = 0; 226 } else { 227 if (iperf_time_now(&now) < 0) { 228 i_errno = IEINITTEST; 229 return -1; 230 } 231 test->omitting = 1; 232 cd.p = test; 233 test->omit_timer = tmr_create(&now, client_omit_timer_proc, cd, test->omit * SEC_TO_US, 0); 234 if (test->omit_timer == NULL) { 235 i_errno = IEINITTEST; 236 return -1; 237 } 238 } 239 return 0; 240 } 241 242 int 243 iperf_handle_message_client(struct iperf_test *test) 244 { 245 int rval; 246 int32_t err; 247 248 /*!!! Why is this read() and not Nread()? */ 249 if ((rval = read(test->ctrl_sck, (char*) &test->state, sizeof(signed char))) <= 0) { 250 if (rval == 0) { 251 i_errno = IECTRLCLOSE; 252 return -1; 253 } else { 254 i_errno = IERECVMESSAGE; 255 return -1; 256 } 257 } 258 259 switch (test->state) { 260 case PARAM_EXCHANGE: 261 if (iperf_exchange_parameters(test) < 0) 262 return -1; 263 if (test->on_connect) 264 test->on_connect(test); 265 break; 266 case CREATE_STREAMS: 267 if (test->mode == BIDIRECTIONAL) 268 { 269 if (iperf_create_streams(test, 1) < 0) 270 return -1; 271 if (iperf_create_streams(test, 0) < 0) 272 return -1; 273 } 274 else if (iperf_create_streams(test, test->mode) < 0) 275 return -1; 276 break; 277 case TEST_START: 278 if (iperf_init_test(test) < 0) 279 return -1; 280 if (create_client_timers(test) < 0) 281 return -1; 282 if (create_client_omit_timer(test) < 0) 283 return -1; 284 if (test->mode) 285 if (iperf_create_send_timers(test) < 0) 286 return -1; 287 break; 288 case TEST_RUNNING: 289 break; 290 case EXCHANGE_RESULTS: 291 if (iperf_exchange_results(test) < 0) 292 return -1; 293 break; 294 case DISPLAY_RESULTS: 295 if (test->on_test_finish) 296 test->on_test_finish(test); 297 iperf_client_end(test); 298 break; 299 case IPERF_DONE: 300 break; 301 case SERVER_TERMINATE: 302 i_errno = IESERVERTERM; 303 304 /* 305 * Temporarily be in DISPLAY_RESULTS phase so we can get 306 * ending summary statistics. 307 */ 308 signed char oldstate = test->state; 309 cpu_util(test->cpu_util); 310 test->state = DISPLAY_RESULTS; 311 test->reporter_callback(test); 312 test->state = oldstate; 313 return -1; 314 case ACCESS_DENIED: 315 i_errno = IEACCESSDENIED; 316 return -1; 317 case SERVER_ERROR: 318 if (Nread(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) { 319 i_errno = IECTRLREAD; 320 return -1; 321 } 322 i_errno = ntohl(err); 323 if (Nread(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) { 324 i_errno = IECTRLREAD; 325 return -1; 326 } 327 errno = ntohl(err); 328 return -1; 329 default: 330 i_errno = IEMESSAGE; 331 return -1; 332 } 333 334 return 0; 335 } 336 337 338 339 /* iperf_connect -- client to server connection function */ 340 int 341 iperf_connect(struct iperf_test *test) 342 { 343 FD_ZERO(&test->read_set); 344 FD_ZERO(&test->write_set); 345 346 make_cookie(test->cookie); 347 348 /* Create and connect the control channel */ 349 if (test->ctrl_sck < 0) 350 // Create the control channel using an ephemeral port 351 test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, 0, test->server_hostname, test->server_port, test->settings->connect_timeout); 352 if (test->ctrl_sck < 0) { 353 i_errno = IECONNECT; 354 return -1; 355 } 356 357 // set TCP_NODELAY for lower latency on control messages 358 int flag = 1; 359 if (setsockopt(test->ctrl_sck, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int))) { 360 i_errno = IESETNODELAY; 361 return -1; 362 } 363 364 if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { 365 i_errno = IESENDCOOKIE; 366 return -1; 367 } 368 369 FD_SET(test->ctrl_sck, &test->read_set); 370 if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck; 371 372 int opt; 373 socklen_t len; 374 375 len = sizeof(opt); 376 if (getsockopt(test->ctrl_sck, IPPROTO_TCP, TCP_MAXSEG, &opt, &len) < 0) { 377 test->ctrl_sck_mss = 0; 378 } 379 else { 380 if (opt > 0 && opt <= MAX_UDP_BLOCKSIZE) { 381 test->ctrl_sck_mss = opt; 382 } 383 else { 384 char str[128]; 385 snprintf(str, sizeof(str), 386 "Ignoring nonsense TCP MSS %d", opt); 387 warning(str); 388 389 test->ctrl_sck_mss = 0; 390 } 391 } 392 393 if (test->verbose) { 394 printf("Control connection MSS %d\n", test->ctrl_sck_mss); 395 } 396 397 /* 398 * If we're doing a UDP test and the block size wasn't explicitly 399 * set, then use the known MSS of the control connection to pick 400 * an appropriate default. If we weren't able to get the 401 * MSS for some reason, then default to something that should 402 * work on non-jumbo-frame Ethernet networks. The goal is to 403 * pick a reasonable default that is large but should get from 404 * sender to receiver without any IP fragmentation. 405 * 406 * We assume that the control connection is routed the same as the 407 * data packets (thus has the same PMTU). Also in the case of 408 * --reverse tests, we assume that the MTU is the same in both 409 * directions. Note that even if the algorithm guesses wrong, 410 * the user always has the option to override. 411 */ 412 if (test->protocol->id == Pudp) { 413 if (test->settings->blksize == 0) { 414 if (test->ctrl_sck_mss) { 415 test->settings->blksize = test->ctrl_sck_mss; 416 } 417 else { 418 test->settings->blksize = DEFAULT_UDP_BLKSIZE; 419 } 420 if (test->verbose) { 421 printf("Setting UDP block size to %d\n", test->settings->blksize); 422 } 423 } 424 425 /* 426 * Regardless of whether explicitly or implicitly set, if the 427 * block size is larger than the MSS, print a warning. 428 */ 429 if (test->ctrl_sck_mss > 0 && 430 test->settings->blksize > test->ctrl_sck_mss) { 431 char str[128]; 432 snprintf(str, sizeof(str), 433 "UDP block size %d exceeds TCP MSS %d, may result in fragmentation / drops", test->settings->blksize, test->ctrl_sck_mss); 434 warning(str); 435 } 436 } 437 438 return 0; 439 } 440 441 442 int 443 iperf_client_end(struct iperf_test *test) 444 { 445 struct iperf_stream *sp; 446 447 /* Close all stream sockets */ 448 SLIST_FOREACH(sp, &test->streams, streams) { 449 close(sp->socket); 450 } 451 452 /* show final summary */ 453 test->reporter_callback(test); 454 455 /* Send response only if no error in server */ 456 if (test->state > 0) { 457 if (iperf_set_send_state(test, IPERF_DONE) != 0) 458 return -1; 459 } 460 461 /* Close control socket */ 462 if (test->ctrl_sck >= 0) 463 close(test->ctrl_sck); 464 465 return 0; 466 } 467 468 469 int 470 iperf_run_client(struct iperf_test * test) 471 { 472 int startup; 473 int result = 0; 474 fd_set read_set, write_set; 475 struct iperf_time now; 476 struct timeval* timeout = NULL; 477 struct iperf_stream *sp; 478 struct iperf_time last_receive_time; 479 struct iperf_time diff_time; 480 struct timeval used_timeout; 481 int64_t t_usecs; 482 int64_t timeout_us; 483 int64_t rcv_timeout_us; 484 485 if (test->logfile) 486 if (iperf_open_logfile(test) < 0) 487 return -1; 488 489 if (test->affinity != -1) 490 if (iperf_setaffinity(test, test->affinity) != 0) 491 return -1; 492 493 if (test->json_output) 494 if (iperf_json_start(test) < 0) 495 return -1; 496 497 if (test->json_output) { 498 cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version)); 499 cJSON_AddItemToObject(test->json_start, "system_info", cJSON_CreateString(get_system_info())); 500 } else if (test->verbose) { 501 iperf_printf(test, "%s\n", version); 502 iperf_printf(test, "%s", ""); 503 iperf_printf(test, "%s\n", get_system_info()); 504 iflush(test); 505 } 506 507 /* Start the client and connect to the server */ 508 if (iperf_connect(test) < 0) 509 goto cleanup_and_fail; 510 511 /* Begin calculating CPU utilization */ 512 cpu_util(NULL); 513 if (test->mode != SENDER) 514 rcv_timeout_us = (test->settings->rcv_timeout.secs * SEC_TO_US) + test->settings->rcv_timeout.usecs; 515 else 516 rcv_timeout_us = 0; 517 518 startup = 1; 519 while (test->state != IPERF_DONE) { 520 memcpy(&read_set, &test->read_set, sizeof(fd_set)); 521 memcpy(&write_set, &test->write_set, sizeof(fd_set)); 522 iperf_time_now(&now); 523 timeout = tmr_timeout(&now); 524 525 // In reverse active mode client ensures data is received 526 if (test->state == TEST_RUNNING && rcv_timeout_us > 0) { 527 timeout_us = -1; 528 if (timeout != NULL) { 529 used_timeout.tv_sec = timeout->tv_sec; 530 used_timeout.tv_usec = timeout->tv_usec; 531 timeout_us = (timeout->tv_sec * SEC_TO_US) + timeout->tv_usec; 532 } 533 if (timeout_us < 0 || timeout_us > rcv_timeout_us) { 534 used_timeout.tv_sec = test->settings->rcv_timeout.secs; 535 used_timeout.tv_usec = test->settings->rcv_timeout.usecs; 536 } 537 timeout = &used_timeout; 538 } 539 540 result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); 541 if (result < 0 && errno != EINTR) { 542 i_errno = IESELECT; 543 goto cleanup_and_fail; 544 } else if (result == 0 && test->state == TEST_RUNNING && rcv_timeout_us > 0) { 545 // If nothing was received in non-reverse running state then probably something got stack - 546 // either client, server or network, and test should be terminated. 547 iperf_time_now(&now); 548 if (iperf_time_diff(&now, &last_receive_time, &diff_time) == 0) { 549 t_usecs = iperf_time_in_usecs(&diff_time); 550 if (t_usecs > rcv_timeout_us) { 551 i_errno = IENOMSG; 552 goto cleanup_and_fail; 553 } 554 555 } 556 } 557 558 if (result > 0) { 559 if (rcv_timeout_us > 0) { 560 iperf_time_now(&last_receive_time); 561 } 562 if (FD_ISSET(test->ctrl_sck, &read_set)) { 563 if (iperf_handle_message_client(test) < 0) { 564 goto cleanup_and_fail; 565 } 566 FD_CLR(test->ctrl_sck, &read_set); 567 } 568 } 569 570 if (test->state == TEST_RUNNING) { 571 572 /* Is this our first time really running? */ 573 if (startup) { 574 startup = 0; 575 576 // Set non-blocking for non-UDP tests 577 if (test->protocol->id != Pudp) { 578 SLIST_FOREACH(sp, &test->streams, streams) { 579 setnonblocking(sp->socket, 1); 580 } 581 } 582 } 583 584 585 if (test->mode == BIDIRECTIONAL) 586 { 587 if (iperf_send(test, &write_set) < 0) 588 goto cleanup_and_fail; 589 if (iperf_recv(test, &read_set) < 0) 590 goto cleanup_and_fail; 591 } else if (test->mode == SENDER) { 592 // Regular mode. Client sends. 593 if (iperf_send(test, &write_set) < 0) 594 goto cleanup_and_fail; 595 } else { 596 // Reverse mode. Client receives. 597 if (iperf_recv(test, &read_set) < 0) 598 goto cleanup_and_fail; 599 } 600 601 602 /* Run the timers. */ 603 iperf_time_now(&now); 604 tmr_run(&now); 605 606 /* 607 * Is the test done yet? We have to be out of omitting 608 * mode, and then we have to have fulfilled one of the 609 * ending criteria, either by times, bytes, or blocks. 610 * The bytes and blocks tests needs to handle both the 611 * cases of the client being the sender and the client 612 * being the receiver. 613 */ 614 if ((!test->omitting) && 615 (test->done || 616 (test->settings->bytes != 0 && (test->bytes_sent >= test->settings->bytes || 617 test->bytes_received >= test->settings->bytes)) || 618 (test->settings->blocks != 0 && (test->blocks_sent >= test->settings->blocks || 619 test->blocks_received >= test->settings->blocks)))) { 620 621 // Unset non-blocking for non-UDP tests 622 if (test->protocol->id != Pudp) { 623 SLIST_FOREACH(sp, &test->streams, streams) { 624 setnonblocking(sp->socket, 0); 625 } 626 } 627 628 /* Yes, done! Send TEST_END. */ 629 test->done = 1; 630 cpu_util(test->cpu_util); 631 test->stats_callback(test); 632 if (iperf_set_send_state(test, TEST_END) != 0) 633 goto cleanup_and_fail; 634 } 635 } 636 // If we're in reverse mode, continue draining the data 637 // connection(s) even if test is over. This prevents a 638 // deadlock where the server side fills up its pipe(s) 639 // and gets blocked, so it can't receive state changes 640 // from the client side. 641 else if (test->mode == RECEIVER && test->state == TEST_END) { 642 if (iperf_recv(test, &read_set) < 0) 643 goto cleanup_and_fail; 644 } 645 } 646 647 if (test->json_output) { 648 if (iperf_json_finish(test) < 0) 649 return -1; 650 } else { 651 iperf_printf(test, "\n"); 652 iperf_printf(test, "%s", report_done); 653 } 654 655 iflush(test); 656 657 return 0; 658 659 cleanup_and_fail: 660 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 661 iperf_client_end(test); 662 if (test->json_output) { 663 if (iperf_json_finish(test) < 0) 664 return -1; // It is o.k. that error will be logged later outside the JSON output since its creation failed 665 } 666 iflush(test); 667 return 0; // Return 0 and not -1 since all terminating function were done here. 668 // Also prevents error message logging outside the already closed JSON output. 669 } 670