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_timer_proc(TimerClientData client_data, struct timeval *nowP) 320 { 321 struct iperf_test *test = client_data.p; 322 struct iperf_stream *sp; 323 324 test->timer = NULL; 325 if (test->done) 326 return; 327 test->done = 1; 328 /* Free streams */ 329 while (!SLIST_EMPTY(&test->streams)) { 330 sp = SLIST_FIRST(&test->streams); 331 SLIST_REMOVE_HEAD(&test->streams, streams); 332 close(sp->socket); 333 iperf_free_stream(sp); 334 } 335 close(test->ctrl_sck); 336 } 337 338 static void 339 server_stats_timer_proc(TimerClientData client_data, struct timeval *nowP) 340 { 341 struct iperf_test *test = client_data.p; 342 343 if (test->done) 344 return; 345 if (test->stats_callback) 346 test->stats_callback(test); 347 } 348 349 static void 350 server_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP) 351 { 352 struct iperf_test *test = client_data.p; 353 354 if (test->done) 355 return; 356 if (test->reporter_callback) 357 test->reporter_callback(test); 358 } 359 360 static int 361 create_server_timers(struct iperf_test * test) 362 { 363 struct timeval now; 364 TimerClientData cd; 365 366 if (gettimeofday(&now, NULL) < 0) { 367 i_errno = IEINITTEST; 368 return -1; 369 } 370 cd.p = test; 371 test->timer = test->stats_timer = test->reporter_timer = NULL; 372 if (test->duration != 0 ) { 373 test->done = 0; 374 test->timer = tmr_create(&now, server_timer_proc, cd, (test->duration + test->omit + 5) * SEC_TO_US, 0); 375 if (test->timer == NULL) { 376 i_errno = IEINITTEST; 377 return -1; 378 } 379 } 380 381 test->stats_timer = test->reporter_timer = NULL; 382 if (test->stats_interval != 0) { 383 test->stats_timer = tmr_create(&now, server_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1); 384 if (test->stats_timer == NULL) { 385 i_errno = IEINITTEST; 386 return -1; 387 } 388 } 389 if (test->reporter_interval != 0) { 390 test->reporter_timer = tmr_create(&now, server_reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1); 391 if (test->reporter_timer == NULL) { 392 i_errno = IEINITTEST; 393 return -1; 394 } 395 } 396 return 0; 397 } 398 399 static void 400 server_omit_timer_proc(TimerClientData client_data, struct timeval *nowP) 401 { 402 struct iperf_test *test = client_data.p; 403 404 test->omit_timer = NULL; 405 test->omitting = 0; 406 iperf_reset_stats(test); 407 if (test->verbose && !test->json_output && test->reporter_interval == 0) 408 iperf_printf(test, "%s", report_omit_done); 409 410 /* Reset the timers. */ 411 if (test->stats_timer != NULL) 412 tmr_reset(nowP, test->stats_timer); 413 if (test->reporter_timer != NULL) 414 tmr_reset(nowP, test->reporter_timer); 415 } 416 417 static int 418 create_server_omit_timer(struct iperf_test * test) 419 { 420 struct timeval now; 421 TimerClientData cd; 422 423 if (test->omit == 0) { 424 test->omit_timer = NULL; 425 test->omitting = 0; 426 } else { 427 if (gettimeofday(&now, NULL) < 0) { 428 i_errno = IEINITTEST; 429 return -1; 430 } 431 test->omitting = 1; 432 cd.p = test; 433 test->omit_timer = tmr_create(&now, server_omit_timer_proc, cd, test->omit * SEC_TO_US, 0); 434 if (test->omit_timer == NULL) { 435 i_errno = IEINITTEST; 436 return -1; 437 } 438 } 439 440 return 0; 441 } 442 443 static void 444 cleanup_server(struct iperf_test *test) 445 { 446 /* Close open test sockets */ 447 if (test->ctrl_sck) { 448 close(test->ctrl_sck); 449 } 450 if (test->listener) { 451 close(test->listener); 452 } 453 454 /* Cancel any remaining timers. */ 455 if (test->stats_timer != NULL) { 456 tmr_cancel(test->stats_timer); 457 test->stats_timer = NULL; 458 } 459 if (test->reporter_timer != NULL) { 460 tmr_cancel(test->reporter_timer); 461 test->reporter_timer = NULL; 462 } 463 if (test->omit_timer != NULL) { 464 tmr_cancel(test->omit_timer); 465 test->omit_timer = NULL; 466 } 467 if (test->congestion_used != NULL) { 468 free(test->congestion_used); 469 } 470 if (test->timer != NULL) { 471 tmr_cancel(test->timer); 472 test->timer = NULL; 473 } 474 } 475 476 477 int 478 iperf_run_server(struct iperf_test *test) 479 { 480 int result, s, streams_accepted; 481 fd_set read_set, write_set; 482 struct iperf_stream *sp; 483 struct timeval now; 484 struct timeval* timeout; 485 486 if (test->affinity != -1) 487 if (iperf_setaffinity(test, test->affinity) != 0) 488 return -2; 489 490 if (test->json_output) 491 if (iperf_json_start(test) < 0) 492 return -2; 493 494 if (test->json_output) { 495 cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version)); 496 cJSON_AddItemToObject(test->json_start, "system_info", cJSON_CreateString(get_system_info())); 497 } else if (test->verbose) { 498 iperf_printf(test, "%s\n", version); 499 iperf_printf(test, "%s", ""); 500 iperf_printf(test, "%s\n", get_system_info()); 501 iflush(test); 502 } 503 504 // Open socket and listen 505 if (iperf_server_listen(test) < 0) { 506 return -2; 507 } 508 509 // Begin calculating CPU utilization 510 cpu_util(NULL); 511 512 test->state = IPERF_START; 513 streams_accepted = 0; 514 515 while (test->state != IPERF_DONE) { 516 517 memcpy(&read_set, &test->read_set, sizeof(fd_set)); 518 memcpy(&write_set, &test->write_set, sizeof(fd_set)); 519 520 (void) gettimeofday(&now, NULL); 521 timeout = tmr_timeout(&now); 522 result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); 523 if (result < 0 && errno != EINTR) { 524 cleanup_server(test); 525 i_errno = IESELECT; 526 return -1; 527 } 528 if (result > 0) { 529 if (FD_ISSET(test->listener, &read_set)) { 530 if (test->state != CREATE_STREAMS) { 531 if (iperf_accept(test) < 0) { 532 cleanup_server(test); 533 return -1; 534 } 535 FD_CLR(test->listener, &read_set); 536 } 537 } 538 if (FD_ISSET(test->ctrl_sck, &read_set)) { 539 if (iperf_handle_message_server(test) < 0) { 540 cleanup_server(test); 541 return -1; 542 } 543 FD_CLR(test->ctrl_sck, &read_set); 544 } 545 546 if (test->state == CREATE_STREAMS) { 547 if (FD_ISSET(test->prot_listener, &read_set)) { 548 549 if ((s = test->protocol->accept(test)) < 0) { 550 cleanup_server(test); 551 return -1; 552 } 553 554 #if defined(HAVE_TCP_CONGESTION) 555 if (test->protocol->id == Ptcp) { 556 if (test->congestion) { 557 if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) { 558 /* 559 * ENOENT means we tried to set the 560 * congestion algorithm but the algorithm 561 * specified doesn't exist. This can happen 562 * if the client and server have different 563 * congestion algorithms available. In this 564 * case, print a warning, but otherwise 565 * continue. 566 */ 567 if (errno == ENOENT) { 568 warning("TCP congestion control algorithm not supported"); 569 } 570 else { 571 close(s); 572 cleanup_server(test); 573 i_errno = IESETCONGESTION; 574 return -1; 575 } 576 } 577 } 578 { 579 socklen_t len = TCP_CA_NAME_MAX; 580 char ca[TCP_CA_NAME_MAX + 1]; 581 if (getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len) < 0) { 582 close(s); 583 cleanup_server(test); 584 i_errno = IESETCONGESTION; 585 return -1; 586 } 587 test->congestion_used = strdup(ca); 588 if (test->debug) { 589 printf("Congestion algorithm is %s\n", test->congestion_used); 590 } 591 } 592 } 593 #endif /* HAVE_TCP_CONGESTION */ 594 595 if (!is_closed(s)) { 596 sp = iperf_new_stream(test, s); 597 if (!sp) { 598 cleanup_server(test); 599 return -1; 600 } 601 602 if (test->sender) 603 FD_SET(s, &test->write_set); 604 else 605 FD_SET(s, &test->read_set); 606 if (s > test->max_fd) test->max_fd = s; 607 608 /* 609 * If the protocol isn't UDP, or even if it is but 610 * we're the receiver, set nonblocking sockets. 611 * We need this to allow a server receiver to 612 * maintain interactivity with the control channel. 613 */ 614 if (test->protocol->id != Pudp || 615 !test->sender) { 616 setnonblocking(s, 1); 617 } 618 619 streams_accepted++; 620 if (test->on_new_stream) 621 test->on_new_stream(sp); 622 } 623 FD_CLR(test->prot_listener, &read_set); 624 } 625 626 if (streams_accepted == test->num_streams) { 627 if (test->protocol->id != Ptcp) { 628 FD_CLR(test->prot_listener, &test->read_set); 629 close(test->prot_listener); 630 } else { 631 if (test->no_delay || test->settings->mss || test->settings->socket_bufsize) { 632 FD_CLR(test->listener, &test->read_set); 633 close(test->listener); 634 test->listener = 0; 635 if ((s = netannounce(test->settings->domain, Ptcp, test->bind_address, test->server_port)) < 0) { 636 cleanup_server(test); 637 i_errno = IELISTEN; 638 return -1; 639 } 640 test->listener = s; 641 FD_SET(test->listener, &test->read_set); 642 if (test->listener > test->max_fd) test->max_fd = test->listener; 643 } 644 } 645 test->prot_listener = -1; 646 if (iperf_set_send_state(test, TEST_START) != 0) { 647 cleanup_server(test); 648 return -1; 649 } 650 if (iperf_init_test(test) < 0) { 651 cleanup_server(test); 652 return -1; 653 } 654 if (create_server_timers(test) < 0) { 655 cleanup_server(test); 656 return -1; 657 } 658 if (create_server_omit_timer(test) < 0) { 659 cleanup_server(test); 660 return -1; 661 } 662 if (test->reverse) 663 if (iperf_create_send_timers(test) < 0) { 664 cleanup_server(test); 665 return -1; 666 } 667 if (iperf_set_send_state(test, TEST_RUNNING) != 0) { 668 cleanup_server(test); 669 return -1; 670 } 671 } 672 } 673 674 if (test->state == TEST_RUNNING) { 675 if (test->reverse) { 676 // Reverse mode. Server sends. 677 if (iperf_send(test, &write_set) < 0) { 678 cleanup_server(test); 679 return -1; 680 } 681 } else { 682 // Regular mode. Server receives. 683 if (iperf_recv(test, &read_set) < 0) { 684 cleanup_server(test); 685 return -1; 686 } 687 } 688 } 689 } 690 691 if (result == 0 || 692 (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) { 693 /* Run the timers. */ 694 (void) gettimeofday(&now, NULL); 695 tmr_run(&now); 696 } 697 } 698 699 cleanup_server(test); 700 701 if (test->json_output) { 702 if (iperf_json_finish(test) < 0) 703 return -1; 704 } 705 706 iflush(test); 707 708 if (test->server_affinity != -1) 709 if (iperf_clearaffinity(test) != 0) 710 return -1; 711 712 return 0; 713 } 714