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