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