1 /* 2 * iperf, Copyright (c) 2014, 2015, 2016, 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 /* iperf_server_api.c: Functions to be used by an iperf server 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <getopt.h> 34 #include <errno.h> 35 #include <unistd.h> 36 #include <assert.h> 37 #include <fcntl.h> 38 #include <sys/socket.h> 39 #include <sys/types.h> 40 #include <netinet/in.h> 41 #include <arpa/inet.h> 42 #include <netdb.h> 43 #include <pthread.h> 44 #ifdef HAVE_STDINT_H 45 #include <stdint.h> 46 #endif 47 #include <sys/time.h> 48 #include <sys/resource.h> 49 #include <sched.h> 50 #include <setjmp.h> 51 52 #include "iperf.h" 53 #include "iperf_api.h" 54 #include "iperf_udp.h" 55 #include "iperf_tcp.h" 56 #include "iperf_util.h" 57 #include "timer.h" 58 #include "net.h" 59 #include "units.h" 60 #include "tcp_window_size.h" 61 #include "iperf_util.h" 62 #include "iperf_locale.h" 63 64 #if defined(HAVE_TCP_CONGESTION) 65 #if !defined(TCP_CA_NAME_MAX) 66 #define TCP_CA_NAME_MAX 16 67 #endif /* TCP_CA_NAME_MAX */ 68 #endif /* HAVE_TCP_CONGESTION */ 69 70 int 71 iperf_server_listen(struct iperf_test *test) 72 { 73 retry: 74 if((test->listener = netannounce(test->settings->domain, Ptcp, test->bind_address, test->server_port)) < 0) { 75 if (errno == EAFNOSUPPORT && (test->settings->domain == AF_INET6 || test->settings->domain == AF_UNSPEC)) { 76 /* If we get "Address family not supported by protocol", that 77 ** probably means we were compiled with IPv6 but the running 78 ** kernel does not actually do IPv6. This is not too unusual, 79 ** v6 support is and perhaps always will be spotty. 80 */ 81 warning("this system does not seem to support IPv6 - trying IPv4"); 82 test->settings->domain = AF_INET; 83 goto retry; 84 } else { 85 i_errno = IELISTEN; 86 return -1; 87 } 88 } 89 90 if (!test->json_output) { 91 iperf_printf(test, "-----------------------------------------------------------\n"); 92 iperf_printf(test, "Server listening on %d\n", test->server_port); 93 } 94 95 // This needs to be changed to reflect if client has different window size 96 // make sure we got what we asked for 97 /* XXX: This needs to be moved to the stream listener 98 if ((x = get_tcp_windowsize(test->listener, SO_RCVBUF)) < 0) { 99 // Needs to set some sort of error number/message 100 perror("SO_RCVBUF"); 101 return -1; 102 } 103 */ 104 105 // XXX: This code needs to be moved to after parameter exhange 106 /* 107 char ubuf[UNIT_LEN]; 108 int x; 109 110 if (test->protocol->id == Ptcp) { 111 if (test->settings->socket_bufsize > 0) { 112 unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A'); 113 if (!test->json_output) 114 iperf_printf(test, report_window, ubuf); 115 } else { 116 if (!test->json_output) 117 iperf_printf(test, "%s", report_autotune); 118 } 119 } 120 */ 121 if (!test->json_output) 122 iperf_printf(test, "-----------------------------------------------------------\n"); 123 124 FD_ZERO(&test->read_set); 125 FD_ZERO(&test->write_set); 126 FD_SET(test->listener, &test->read_set); 127 if (test->listener > test->max_fd) test->max_fd = test->listener; 128 129 return 0; 130 } 131 132 int 133 iperf_accept(struct iperf_test *test) 134 { 135 int s; 136 signed char rbuf = ACCESS_DENIED; 137 socklen_t len; 138 struct sockaddr_storage addr; 139 140 len = sizeof(addr); 141 if ((s = accept(test->listener, (struct sockaddr *) &addr, &len)) < 0) { 142 i_errno = IEACCEPT; 143 return -1; 144 } 145 146 if (test->ctrl_sck == -1) { 147 /* Server free, accept new client */ 148 test->ctrl_sck = s; 149 if (Nread(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { 150 i_errno = IERECVCOOKIE; 151 return -1; 152 } 153 FD_SET(test->ctrl_sck, &test->read_set); 154 if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck; 155 156 if (iperf_set_send_state(test, PARAM_EXCHANGE) != 0) 157 return -1; 158 if (iperf_exchange_parameters(test) < 0) 159 return -1; 160 if (test->server_affinity != -1) 161 if (iperf_setaffinity(test, test->server_affinity) != 0) 162 return -1; 163 if (test->on_connect) 164 test->on_connect(test); 165 } else { 166 /* 167 * Don't try to read from the socket. It could block an ongoing test. 168 * Just send ACCESS_DENIED. 169 */ 170 if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Ptcp) < 0) { 171 i_errno = IESENDMESSAGE; 172 return -1; 173 } 174 close(s); 175 } 176 177 return 0; 178 } 179 180 181 /**************************************************************************/ 182 int 183 iperf_handle_message_server(struct iperf_test *test) 184 { 185 int rval; 186 struct iperf_stream *sp; 187 188 // XXX: Need to rethink how this behaves to fit API 189 if ((rval = Nread(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp)) <= 0) { 190 if (rval == 0) { 191 iperf_err(test, "the client has unexpectedly closed the connection"); 192 i_errno = IECTRLCLOSE; 193 test->state = IPERF_DONE; 194 return 0; 195 } else { 196 i_errno = IERECVMESSAGE; 197 return -1; 198 } 199 } 200 201 switch(test->state) { 202 case TEST_START: 203 break; 204 case TEST_END: 205 test->done = 1; 206 cpu_util(test->cpu_util); 207 test->stats_callback(test); 208 SLIST_FOREACH(sp, &test->streams, streams) { 209 FD_CLR(sp->socket, &test->read_set); 210 FD_CLR(sp->socket, &test->write_set); 211 close(sp->socket); 212 } 213 test->reporter_callback(test); 214 if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0) 215 return -1; 216 if (iperf_exchange_results(test) < 0) 217 return -1; 218 if (iperf_set_send_state(test, DISPLAY_RESULTS) != 0) 219 return -1; 220 if (test->on_test_finish) 221 test->on_test_finish(test); 222 break; 223 case IPERF_DONE: 224 break; 225 case CLIENT_TERMINATE: 226 i_errno = IECLIENTTERM; 227 228 // Temporarily be in DISPLAY_RESULTS phase so we can get 229 // ending summary statistics. 230 signed char oldstate = test->state; 231 cpu_util(test->cpu_util); 232 test->state = DISPLAY_RESULTS; 233 test->reporter_callback(test); 234 test->state = oldstate; 235 236 // XXX: Remove this line below! 237 iperf_err(test, "the client has terminated"); 238 SLIST_FOREACH(sp, &test->streams, streams) { 239 FD_CLR(sp->socket, &test->read_set); 240 FD_CLR(sp->socket, &test->write_set); 241 close(sp->socket); 242 } 243 test->state = IPERF_DONE; 244 break; 245 default: 246 i_errno = IEMESSAGE; 247 return -1; 248 } 249 250 return 0; 251 } 252 253 /* XXX: This function is not used anymore */ 254 void 255 iperf_test_reset(struct iperf_test *test) 256 { 257 struct iperf_stream *sp; 258 259 close(test->ctrl_sck); 260 261 /* Free streams */ 262 while (!SLIST_EMPTY(&test->streams)) { 263 sp = SLIST_FIRST(&test->streams); 264 SLIST_REMOVE_HEAD(&test->streams, streams); 265 iperf_free_stream(sp); 266 } 267 if (test->timer != NULL) { 268 tmr_cancel(test->timer); 269 test->timer = NULL; 270 } 271 if (test->stats_timer != NULL) { 272 tmr_cancel(test->stats_timer); 273 test->stats_timer = NULL; 274 } 275 if (test->reporter_timer != NULL) { 276 tmr_cancel(test->reporter_timer); 277 test->reporter_timer = NULL; 278 } 279 test->done = 0; 280 281 SLIST_INIT(&test->streams); 282 283 test->role = 's'; 284 set_protocol(test, Ptcp); 285 test->omit = OMIT; 286 test->duration = DURATION; 287 test->diskfile_name = (char*) 0; 288 test->affinity = -1; 289 test->server_affinity = -1; 290 test->title = NULL; 291 test->congestion = NULL; 292 test->state = 0; 293 test->server_hostname = NULL; 294 295 test->ctrl_sck = -1; 296 test->prot_listener = -1; 297 298 test->bytes_sent = 0; 299 300 test->reverse = 0; 301 test->sender = 0; 302 test->sender_has_retransmits = 0; 303 test->no_delay = 0; 304 305 FD_ZERO(&test->read_set); 306 FD_ZERO(&test->write_set); 307 FD_SET(test->listener, &test->read_set); 308 test->max_fd = test->listener; 309 310 test->num_streams = 1; 311 test->settings->socket_bufsize = 0; 312 test->settings->blksize = DEFAULT_TCP_BLKSIZE; 313 test->settings->rate = 0; 314 test->settings->mss = 0; 315 memset(test->cookie, 0, COOKIE_SIZE); 316 } 317 318 static void 319 server_stats_timer_proc(TimerClientData client_data, struct timeval *nowP) 320 { 321 struct iperf_test *test = client_data.p; 322 323 if (test->done) 324 return; 325 if (test->stats_callback) 326 test->stats_callback(test); 327 } 328 329 static void 330 server_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP) 331 { 332 struct iperf_test *test = client_data.p; 333 334 if (test->done) 335 return; 336 if (test->reporter_callback) 337 test->reporter_callback(test); 338 } 339 340 static int 341 create_server_timers(struct iperf_test * test) 342 { 343 struct timeval now; 344 TimerClientData cd; 345 346 if (gettimeofday(&now, NULL) < 0) { 347 i_errno = IEINITTEST; 348 return -1; 349 } 350 cd.p = test; 351 test->stats_timer = test->reporter_timer = NULL; 352 if (test->stats_interval != 0) { 353 test->stats_timer = tmr_create(&now, server_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1); 354 if (test->stats_timer == NULL) { 355 i_errno = IEINITTEST; 356 return -1; 357 } 358 } 359 if (test->reporter_interval != 0) { 360 test->reporter_timer = tmr_create(&now, server_reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1); 361 if (test->reporter_timer == NULL) { 362 i_errno = IEINITTEST; 363 return -1; 364 } 365 } 366 return 0; 367 } 368 369 static void 370 server_omit_timer_proc(TimerClientData client_data, struct timeval *nowP) 371 { 372 struct iperf_test *test = client_data.p; 373 374 test->omit_timer = NULL; 375 test->omitting = 0; 376 iperf_reset_stats(test); 377 if (test->verbose && !test->json_output && test->reporter_interval == 0) 378 iperf_printf(test, "%s", report_omit_done); 379 380 /* Reset the timers. */ 381 if (test->stats_timer != NULL) 382 tmr_reset(nowP, test->stats_timer); 383 if (test->reporter_timer != NULL) 384 tmr_reset(nowP, test->reporter_timer); 385 } 386 387 static int 388 create_server_omit_timer(struct iperf_test * test) 389 { 390 struct timeval now; 391 TimerClientData cd; 392 393 if (test->omit == 0) { 394 test->omit_timer = NULL; 395 test->omitting = 0; 396 } else { 397 if (gettimeofday(&now, NULL) < 0) { 398 i_errno = IEINITTEST; 399 return -1; 400 } 401 test->omitting = 1; 402 cd.p = test; 403 test->omit_timer = tmr_create(&now, server_omit_timer_proc, cd, test->omit * SEC_TO_US, 0); 404 if (test->omit_timer == NULL) { 405 i_errno = IEINITTEST; 406 return -1; 407 } 408 } 409 410 return 0; 411 } 412 413 static void 414 cleanup_server(struct iperf_test *test) 415 { 416 /* Close open test sockets */ 417 if (test->ctrl_sck) { 418 close(test->ctrl_sck); 419 } 420 if (test->listener) { 421 close(test->listener); 422 } 423 424 /* Cancel any remaining timers. */ 425 if (test->stats_timer != NULL) { 426 tmr_cancel(test->stats_timer); 427 test->stats_timer = NULL; 428 } 429 if (test->reporter_timer != NULL) { 430 tmr_cancel(test->reporter_timer); 431 test->reporter_timer = NULL; 432 } 433 if (test->omit_timer != NULL) { 434 tmr_cancel(test->omit_timer); 435 test->omit_timer = NULL; 436 } 437 } 438 439 440 int 441 iperf_run_server(struct iperf_test *test) 442 { 443 int result, s, streams_accepted; 444 fd_set read_set, write_set; 445 struct iperf_stream *sp; 446 struct timeval now; 447 struct timeval* timeout; 448 449 if (test->affinity != -1) 450 if (iperf_setaffinity(test, test->affinity) != 0) 451 return -2; 452 453 if (test->json_output) 454 if (iperf_json_start(test) < 0) 455 return -2; 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 // Open socket and listen 468 if (iperf_server_listen(test) < 0) { 469 return -2; 470 } 471 472 // Begin calculating CPU utilization 473 cpu_util(NULL); 474 475 test->state = IPERF_START; 476 streams_accepted = 0; 477 478 while (test->state != IPERF_DONE) { 479 480 memcpy(&read_set, &test->read_set, sizeof(fd_set)); 481 memcpy(&write_set, &test->write_set, sizeof(fd_set)); 482 483 (void) gettimeofday(&now, NULL); 484 timeout = tmr_timeout(&now); 485 result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); 486 if (result < 0 && errno != EINTR) { 487 cleanup_server(test); 488 i_errno = IESELECT; 489 return -1; 490 } 491 if (result > 0) { 492 if (FD_ISSET(test->listener, &read_set)) { 493 if (test->state != CREATE_STREAMS) { 494 if (iperf_accept(test) < 0) { 495 cleanup_server(test); 496 return -1; 497 } 498 FD_CLR(test->listener, &read_set); 499 } 500 } 501 if (FD_ISSET(test->ctrl_sck, &read_set)) { 502 if (iperf_handle_message_server(test) < 0) { 503 cleanup_server(test); 504 return -1; 505 } 506 FD_CLR(test->ctrl_sck, &read_set); 507 } 508 509 if (test->state == CREATE_STREAMS) { 510 if (FD_ISSET(test->prot_listener, &read_set)) { 511 512 if ((s = test->protocol->accept(test)) < 0) { 513 cleanup_server(test); 514 return -1; 515 } 516 517 #if defined(HAVE_TCP_CONGESTION) 518 if (test->protocol->id == Ptcp) { 519 if (test->congestion) { 520 if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) { 521 /* 522 * ENOENT means we tried to set the 523 * congestion algorithm but the algorithm 524 * specified doesn't exist. This can happen 525 * if the client and server have different 526 * congestion algorithms available. In this 527 * case, print a warning, but otherwise 528 * continue. 529 */ 530 if (errno == ENOENT) { 531 warning("TCP congestion control algorithm not supported"); 532 } 533 else { 534 close(s); 535 cleanup_server(test); 536 i_errno = IESETCONGESTION; 537 return -1; 538 } 539 } 540 } 541 { 542 socklen_t len = TCP_CA_NAME_MAX; 543 char ca[TCP_CA_NAME_MAX + 1]; 544 if (getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len) < 0) { 545 close(s); 546 cleanup_server(test); 547 i_errno = IESETCONGESTION; 548 return -1; 549 } 550 test->congestion_used = strdup(ca); 551 if (test->debug) { 552 printf("Congestion algorithm is %s\n", test->congestion_used); 553 } 554 } 555 } 556 #endif /* HAVE_TCP_CONGESTION */ 557 558 if (!is_closed(s)) { 559 sp = iperf_new_stream(test, s); 560 if (!sp) { 561 cleanup_server(test); 562 return -1; 563 } 564 565 if (test->sender) 566 FD_SET(s, &test->write_set); 567 else 568 FD_SET(s, &test->read_set); 569 if (s > test->max_fd) test->max_fd = s; 570 571 /* 572 * If the protocol isn't UDP, or even if it is but 573 * we're the receiver, set nonblocking sockets. 574 * We need this to allow a server receiver to 575 * maintain interactivity with the control channel. 576 */ 577 if (test->protocol->id != Pudp || 578 !test->sender) { 579 setnonblocking(s, 1); 580 } 581 582 streams_accepted++; 583 if (test->on_new_stream) 584 test->on_new_stream(sp); 585 } 586 FD_CLR(test->prot_listener, &read_set); 587 } 588 589 if (streams_accepted == test->num_streams) { 590 if (test->protocol->id != Ptcp) { 591 FD_CLR(test->prot_listener, &test->read_set); 592 close(test->prot_listener); 593 } else { 594 if (test->no_delay || test->settings->mss || test->settings->socket_bufsize) { 595 FD_CLR(test->listener, &test->read_set); 596 close(test->listener); 597 test->listener = 0; 598 if ((s = netannounce(test->settings->domain, Ptcp, test->bind_address, test->server_port)) < 0) { 599 cleanup_server(test); 600 i_errno = IELISTEN; 601 return -1; 602 } 603 test->listener = s; 604 FD_SET(test->listener, &test->read_set); 605 if (test->listener > test->max_fd) test->max_fd = test->listener; 606 } 607 } 608 test->prot_listener = -1; 609 if (iperf_set_send_state(test, TEST_START) != 0) { 610 cleanup_server(test); 611 return -1; 612 } 613 if (iperf_init_test(test) < 0) { 614 cleanup_server(test); 615 return -1; 616 } 617 if (create_server_timers(test) < 0) { 618 cleanup_server(test); 619 return -1; 620 } 621 if (create_server_omit_timer(test) < 0) { 622 cleanup_server(test); 623 return -1; 624 } 625 if (test->reverse) 626 if (iperf_create_send_timers(test) < 0) { 627 cleanup_server(test); 628 return -1; 629 } 630 if (iperf_set_send_state(test, TEST_RUNNING) != 0) { 631 cleanup_server(test); 632 return -1; 633 } 634 } 635 } 636 637 if (test->state == TEST_RUNNING) { 638 if (test->reverse) { 639 // Reverse mode. Server sends. 640 if (iperf_send(test, &write_set) < 0) { 641 cleanup_server(test); 642 return -1; 643 } 644 } else { 645 // Regular mode. Server receives. 646 if (iperf_recv(test, &read_set) < 0) { 647 cleanup_server(test); 648 return -1; 649 } 650 } 651 } 652 } 653 654 if (result == 0 || 655 (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) { 656 /* Run the timers. */ 657 (void) gettimeofday(&now, NULL); 658 tmr_run(&now); 659 } 660 } 661 662 cleanup_server(test); 663 664 if (test->json_output) { 665 if (iperf_json_finish(test) < 0) 666 return -1; 667 } 668 669 iflush(test); 670 671 if (test->server_affinity != -1) 672 if (iperf_clearaffinity(test) != 0) 673 return -1; 674 675 return 0; 676 } 677