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