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