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 [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 "net.h" 45 #include "timer.h" 46 47 #if defined(HAVE_TCP_CONGESTION) 48 #if !defined(TCP_CA_NAME_MAX) 49 #define TCP_CA_NAME_MAX 16 50 #endif /* TCP_CA_NAME_MAX */ 51 #endif /* HAVE_TCP_CONGESTION */ 52 53 int 54 iperf_create_streams(struct iperf_test *test) 55 { 56 int i, s; 57 #if defined(HAVE_TCP_CONGESTION) 58 int saved_errno; 59 #endif /* HAVE_TCP_CONGESTION */ 60 struct iperf_stream *sp; 61 62 int orig_bind_port = test->bind_port; 63 for (i = 0; i < test->num_streams; ++i) { 64 65 test->bind_port = orig_bind_port; 66 if (orig_bind_port) 67 test->bind_port += i; 68 if ((s = test->protocol->connect(test)) < 0) 69 return -1; 70 71 #if defined(HAVE_TCP_CONGESTION) 72 if (test->protocol->id == Ptcp) { 73 if (test->congestion) { 74 if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) { 75 saved_errno = errno; 76 close(s); 77 errno = saved_errno; 78 i_errno = IESETCONGESTION; 79 return -1; 80 } 81 } 82 { 83 socklen_t len = TCP_CA_NAME_MAX; 84 char ca[TCP_CA_NAME_MAX + 1]; 85 if (getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len) < 0) { 86 saved_errno = errno; 87 close(s); 88 errno = saved_errno; 89 i_errno = IESETCONGESTION; 90 return -1; 91 } 92 test->congestion_used = strdup(ca); 93 if (test->debug) { 94 printf("Congestion algorithm is %s\n", test->congestion_used); 95 } 96 } 97 } 98 #endif /* HAVE_TCP_CONGESTION */ 99 100 if (test->sender) 101 FD_SET(s, &test->write_set); 102 else 103 FD_SET(s, &test->read_set); 104 if (s > test->max_fd) test->max_fd = s; 105 106 sp = iperf_new_stream(test, s); 107 if (!sp) 108 return -1; 109 110 /* Perform the new stream callback */ 111 if (test->on_new_stream) 112 test->on_new_stream(sp); 113 } 114 115 return 0; 116 } 117 118 static void 119 test_timer_proc(TimerClientData client_data, struct timeval *nowP) 120 { 121 struct iperf_test *test = client_data.p; 122 123 test->timer = NULL; 124 test->done = 1; 125 } 126 127 static void 128 client_stats_timer_proc(TimerClientData client_data, struct timeval *nowP) 129 { 130 struct iperf_test *test = client_data.p; 131 132 if (test->done) 133 return; 134 if (test->stats_callback) 135 test->stats_callback(test); 136 } 137 138 static void 139 client_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP) 140 { 141 struct iperf_test *test = client_data.p; 142 143 if (test->done) 144 return; 145 if (test->reporter_callback) 146 test->reporter_callback(test); 147 } 148 149 static int 150 create_client_timers(struct iperf_test * test) 151 { 152 struct timeval now; 153 TimerClientData cd; 154 155 if (gettimeofday(&now, NULL) < 0) { 156 i_errno = IEINITTEST; 157 return -1; 158 } 159 cd.p = test; 160 test->timer = test->stats_timer = test->reporter_timer = NULL; 161 if (test->duration != 0) { 162 test->done = 0; 163 test->timer = tmr_create(&now, test_timer_proc, cd, ( test->duration + test->omit ) * SEC_TO_US, 0); 164 if (test->timer == NULL) { 165 i_errno = IEINITTEST; 166 return -1; 167 } 168 } 169 if (test->stats_interval != 0) { 170 test->stats_timer = tmr_create(&now, client_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1); 171 if (test->stats_timer == NULL) { 172 i_errno = IEINITTEST; 173 return -1; 174 } 175 } 176 if (test->reporter_interval != 0) { 177 test->reporter_timer = tmr_create(&now, client_reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1); 178 if (test->reporter_timer == NULL) { 179 i_errno = IEINITTEST; 180 return -1; 181 } 182 } 183 return 0; 184 } 185 186 static void 187 client_omit_timer_proc(TimerClientData client_data, struct timeval *nowP) 188 { 189 struct iperf_test *test = client_data.p; 190 191 test->omit_timer = NULL; 192 test->omitting = 0; 193 iperf_reset_stats(test); 194 if (test->verbose && !test->json_output && test->reporter_interval == 0) 195 iperf_printf(test, "%s", report_omit_done); 196 197 /* Reset the timers. */ 198 if (test->stats_timer != NULL) 199 tmr_reset(nowP, test->stats_timer); 200 if (test->reporter_timer != NULL) 201 tmr_reset(nowP, test->reporter_timer); 202 } 203 204 static int 205 create_client_omit_timer(struct iperf_test * test) 206 { 207 struct timeval now; 208 TimerClientData cd; 209 210 if (test->omit == 0) { 211 test->omit_timer = NULL; 212 test->omitting = 0; 213 } else { 214 if (gettimeofday(&now, NULL) < 0) { 215 i_errno = IEINITTEST; 216 return -1; 217 } 218 test->omitting = 1; 219 cd.p = test; 220 test->omit_timer = tmr_create(&now, client_omit_timer_proc, cd, test->omit * SEC_TO_US, 0); 221 if (test->omit_timer == NULL) { 222 i_errno = IEINITTEST; 223 return -1; 224 } 225 } 226 return 0; 227 } 228 229 int 230 iperf_handle_message_client(struct iperf_test *test) 231 { 232 int rval; 233 int32_t err; 234 235 /*!!! Why is this read() and not Nread()? */ 236 if ((rval = read(test->ctrl_sck, (char*) &test->state, sizeof(signed char))) <= 0) { 237 if (rval == 0) { 238 i_errno = IECTRLCLOSE; 239 return -1; 240 } else { 241 i_errno = IERECVMESSAGE; 242 return -1; 243 } 244 } 245 246 switch (test->state) { 247 case PARAM_EXCHANGE: 248 if (iperf_exchange_parameters(test) < 0) 249 return -1; 250 if (test->on_connect) 251 test->on_connect(test); 252 break; 253 case CREATE_STREAMS: 254 if (iperf_create_streams(test) < 0) 255 return -1; 256 break; 257 case TEST_START: 258 if (iperf_init_test(test) < 0) 259 return -1; 260 if (create_client_timers(test) < 0) 261 return -1; 262 if (create_client_omit_timer(test) < 0) 263 return -1; 264 if (!test->reverse) 265 if (iperf_create_send_timers(test) < 0) 266 return -1; 267 break; 268 case TEST_RUNNING: 269 break; 270 case EXCHANGE_RESULTS: 271 if (iperf_exchange_results(test) < 0) 272 return -1; 273 break; 274 case DISPLAY_RESULTS: 275 if (test->on_test_finish) 276 test->on_test_finish(test); 277 iperf_client_end(test); 278 break; 279 case IPERF_DONE: 280 break; 281 case SERVER_TERMINATE: 282 i_errno = IESERVERTERM; 283 284 /* 285 * Temporarily be in DISPLAY_RESULTS phase so we can get 286 * ending summary statistics. 287 */ 288 signed char oldstate = test->state; 289 cpu_util(test->cpu_util); 290 test->state = DISPLAY_RESULTS; 291 test->reporter_callback(test); 292 test->state = oldstate; 293 return -1; 294 case ACCESS_DENIED: 295 i_errno = IEACCESSDENIED; 296 return -1; 297 case SERVER_ERROR: 298 if (Nread(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) { 299 i_errno = IECTRLREAD; 300 return -1; 301 } 302 i_errno = ntohl(err); 303 if (Nread(test->ctrl_sck, (char*) &err, sizeof(err), Ptcp) < 0) { 304 i_errno = IECTRLREAD; 305 return -1; 306 } 307 errno = ntohl(err); 308 return -1; 309 default: 310 i_errno = IEMESSAGE; 311 return -1; 312 } 313 314 return 0; 315 } 316 317 318 319 /* iperf_connect -- client to server connection function */ 320 int 321 iperf_connect(struct iperf_test *test) 322 { 323 FD_ZERO(&test->read_set); 324 FD_ZERO(&test->write_set); 325 326 make_cookie(test->cookie); 327 328 /* Create and connect the control channel */ 329 if (test->ctrl_sck < 0) 330 // Create the control channel using an ephemeral port 331 test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, 0, test->server_hostname, test->server_port, test->settings->connect_timeout); 332 if (test->ctrl_sck < 0) { 333 i_errno = IECONNECT; 334 return -1; 335 } 336 337 if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { 338 i_errno = IESENDCOOKIE; 339 return -1; 340 } 341 342 FD_SET(test->ctrl_sck, &test->read_set); 343 if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck; 344 345 int opt; 346 socklen_t len; 347 348 len = sizeof(opt); 349 if (getsockopt(test->ctrl_sck, IPPROTO_TCP, TCP_MAXSEG, &opt, &len) < 0) { 350 test->ctrl_sck_mss = 0; 351 } 352 else { 353 if (opt > 0 && opt <= MAX_UDP_BLOCKSIZE) { 354 test->ctrl_sck_mss = opt; 355 } 356 else { 357 char str[128]; 358 snprintf(str, sizeof(str), 359 "Ignoring nonsense TCP MSS %d", opt); 360 warning(str); 361 362 test->ctrl_sck_mss = 0; 363 } 364 } 365 366 if (test->verbose) { 367 printf("Control connection MSS %d\n", test->ctrl_sck_mss); 368 } 369 370 /* 371 * If we're doing a UDP test and the block size wasn't explicitly 372 * set, then use the known MSS of the control connection to pick 373 * an appropriate default. If we weren't able to get the 374 * MSS for some reason, then default to something that should 375 * work on non-jumbo-frame Ethernet networks. The goal is to 376 * pick a reasonable default that is large but should get from 377 * sender to receiver without any IP fragmentation. 378 * 379 * We assume that the control connection is routed the same as the 380 * data packets (thus has the same PMTU). Also in the case of 381 * --reverse tests, we assume that the MTU is the same in both 382 * directions. Note that even if the algorithm guesses wrong, 383 * the user always has the option to override. 384 */ 385 if (test->protocol->id == Pudp) { 386 if (test->settings->blksize == 0) { 387 if (test->ctrl_sck_mss) { 388 test->settings->blksize = test->ctrl_sck_mss; 389 } 390 else { 391 test->settings->blksize = DEFAULT_UDP_BLKSIZE; 392 } 393 if (test->verbose) { 394 printf("Setting UDP block size to %d\n", test->settings->blksize); 395 } 396 } 397 398 /* 399 * Regardless of whether explicitly or implicitly set, if the 400 * block size is larger than the MSS, print a warning. 401 */ 402 if (test->ctrl_sck_mss > 0 && 403 test->settings->blksize > test->ctrl_sck_mss) { 404 char str[128]; 405 snprintf(str, sizeof(str), 406 "UDP block size %d exceeds TCP MSS %d, may result in fragmentation / drops", test->settings->blksize, test->ctrl_sck_mss); 407 warning(str); 408 } 409 } 410 411 return 0; 412 } 413 414 415 int 416 iperf_client_end(struct iperf_test *test) 417 { 418 struct iperf_stream *sp; 419 420 /* Close all stream sockets */ 421 SLIST_FOREACH(sp, &test->streams, streams) { 422 close(sp->socket); 423 } 424 425 /* show final summary */ 426 test->reporter_callback(test); 427 428 if (iperf_set_send_state(test, IPERF_DONE) != 0) 429 return -1; 430 431 /* Close control socket */ 432 if (test->ctrl_sck) 433 close(test->ctrl_sck); 434 435 return 0; 436 } 437 438 439 int 440 iperf_run_client(struct iperf_test * test) 441 { 442 int startup; 443 int result = 0; 444 fd_set read_set, write_set; 445 struct timeval now; 446 struct timeval* timeout = NULL; 447 struct iperf_stream *sp; 448 449 if (test->affinity != -1) 450 if (iperf_setaffinity(test, test->affinity) != 0) 451 return -1; 452 453 if (test->json_output) 454 if (iperf_json_start(test) < 0) 455 return -1; 456 457 if (test->json_output) { 458 cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version)); 459 cJSON_AddItemToObject(test->json_start, "system_info", cJSON_CreateString(get_system_info())); 460 } else if (test->verbose) { 461 iperf_printf(test, "%s\n", version); 462 iperf_printf(test, "%s", ""); 463 iperf_printf(test, "%s\n", get_system_info()); 464 iflush(test); 465 } 466 467 /* Start the client and connect to the server */ 468 if (iperf_connect(test) < 0) 469 return -1; 470 471 /* Begin calculating CPU utilization */ 472 cpu_util(NULL); 473 474 startup = 1; 475 while (test->state != IPERF_DONE) { 476 memcpy(&read_set, &test->read_set, sizeof(fd_set)); 477 memcpy(&write_set, &test->write_set, sizeof(fd_set)); 478 (void) gettimeofday(&now, NULL); 479 timeout = tmr_timeout(&now); 480 result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); 481 if (result < 0 && errno != EINTR) { 482 i_errno = IESELECT; 483 return -1; 484 } 485 if (result > 0) { 486 if (FD_ISSET(test->ctrl_sck, &read_set)) { 487 if (iperf_handle_message_client(test) < 0) { 488 return -1; 489 } 490 FD_CLR(test->ctrl_sck, &read_set); 491 } 492 } 493 494 if (test->state == TEST_RUNNING) { 495 496 /* Is this our first time really running? */ 497 if (startup) { 498 startup = 0; 499 500 // Set non-blocking for non-UDP tests 501 if (test->protocol->id != Pudp) { 502 SLIST_FOREACH(sp, &test->streams, streams) { 503 setnonblocking(sp->socket, 1); 504 } 505 } 506 } 507 508 if (test->reverse) { 509 // Reverse mode. Client receives. 510 if (iperf_recv(test, &read_set) < 0) 511 return -1; 512 } else { 513 // Regular mode. Client sends. 514 if (iperf_send(test, &write_set) < 0) 515 return -1; 516 } 517 518 /* Run the timers. */ 519 (void) gettimeofday(&now, NULL); 520 tmr_run(&now); 521 522 /* Is the test done yet? */ 523 if ((!test->omitting) && 524 ((test->duration != 0 && test->done) || 525 (test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes) || 526 (test->settings->blocks != 0 && test->blocks_sent >= test->settings->blocks))) { 527 528 // Unset non-blocking for non-UDP tests 529 if (test->protocol->id != Pudp) { 530 SLIST_FOREACH(sp, &test->streams, streams) { 531 setnonblocking(sp->socket, 0); 532 } 533 } 534 535 /* Yes, done! Send TEST_END. */ 536 test->done = 1; 537 cpu_util(test->cpu_util); 538 test->stats_callback(test); 539 if (iperf_set_send_state(test, TEST_END) != 0) 540 return -1; 541 } 542 } 543 // If we're in reverse mode, continue draining the data 544 // connection(s) even if test is over. This prevents a 545 // deadlock where the server side fills up its pipe(s) 546 // and gets blocked, so it can't receive state changes 547 // from the client side. 548 else if (test->reverse && test->state == TEST_END) { 549 if (iperf_recv(test, &read_set) < 0) 550 return -1; 551 } 552 } 553 554 if (test->json_output) { 555 if (iperf_json_finish(test) < 0) 556 return -1; 557 } else { 558 iperf_printf(test, "\n"); 559 iperf_printf(test, "%s", report_done); 560 } 561 562 iflush(test); 563 564 return 0; 565 } 566