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