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