File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / iperf / src / iperf_server_api.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:14:54 2023 UTC (11 months, 3 weeks ago) by misho
Branches: iperf, MAIN
CVS tags: v3_15, HEAD
Version 3.15

    1: /*
    2:  * iperf, Copyright (c) 2014-2022 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 TTD@lbl.gov.
   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: #ifdef HAVE_STDINT_H
   44: #include <stdint.h>
   45: #endif
   46: #include <sys/time.h>
   47: #include <sys/resource.h>
   48: #include <sched.h>
   49: #include <setjmp.h>
   50: 
   51: #include "iperf.h"
   52: #include "iperf_api.h"
   53: #include "iperf_udp.h"
   54: #include "iperf_tcp.h"
   55: #include "iperf_util.h"
   56: #include "timer.h"
   57: #include "iperf_time.h"
   58: #include "net.h"
   59: #include "units.h"
   60: #include "iperf_util.h"
   61: #include "iperf_locale.h"
   62: 
   63: #if defined(HAVE_TCP_CONGESTION)
   64: #if !defined(TCP_CA_NAME_MAX)
   65: #define TCP_CA_NAME_MAX 16
   66: #endif /* TCP_CA_NAME_MAX */
   67: #endif /* HAVE_TCP_CONGESTION */
   68: 
   69: int
   70: iperf_server_listen(struct iperf_test *test)
   71: {
   72:     retry:
   73:     if((test->listener = netannounce(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, test->server_port)) < 0) {
   74: 	if (errno == EAFNOSUPPORT && (test->settings->domain == AF_INET6 || test->settings->domain == AF_UNSPEC)) {
   75: 	    /* If we get "Address family not supported by protocol", that
   76: 	    ** probably means we were compiled with IPv6 but the running
   77: 	    ** kernel does not actually do IPv6.  This is not too unusual,
   78: 	    ** v6 support is and perhaps always will be spotty.
   79: 	    */
   80: 	    warning("this system does not seem to support IPv6 - trying IPv4");
   81: 	    test->settings->domain = AF_INET;
   82: 	    goto retry;
   83: 	} else {
   84: 	    i_errno = IELISTEN;
   85: 	    return -1;
   86: 	}
   87:     }
   88: 
   89:     if (!test->json_output) {
   90:         if (test->server_last_run_rc != 2)
   91:             test->server_test_number +=1;
   92:         if (test->debug || test->server_last_run_rc != 2) {
   93: 	    iperf_printf(test, "-----------------------------------------------------------\n");
   94: 	    iperf_printf(test, "Server listening on %d (test #%d)\n", test->server_port, test->server_test_number);
   95: 	    iperf_printf(test, "-----------------------------------------------------------\n");
   96: 	    if (test->forceflush)
   97: 	        iflush(test);
   98:         }
   99:     }
  100: 
  101:     FD_ZERO(&test->read_set);
  102:     FD_ZERO(&test->write_set);
  103:     FD_SET(test->listener, &test->read_set);
  104:     if (test->listener > test->max_fd) test->max_fd = test->listener;
  105: 
  106:     return 0;
  107: }
  108: 
  109: int
  110: iperf_accept(struct iperf_test *test)
  111: {
  112:     int s;
  113:     signed char rbuf = ACCESS_DENIED;
  114:     socklen_t len;
  115:     struct sockaddr_storage addr;
  116: 
  117:     len = sizeof(addr);
  118:     if ((s = accept(test->listener, (struct sockaddr *) &addr, &len)) < 0) {
  119:         i_errno = IEACCEPT;
  120:         return -1;
  121:     }
  122: 
  123:     if (test->ctrl_sck == -1) {
  124:         /* Server free, accept new client */
  125:         test->ctrl_sck = s;
  126:         // set TCP_NODELAY for lower latency on control messages
  127:         int flag = 1;
  128:         if (setsockopt(test->ctrl_sck, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int))) {
  129:             i_errno = IESETNODELAY;
  130:             return -1;
  131:         }
  132: 
  133: #if defined(HAVE_TCP_USER_TIMEOUT)
  134:         int opt;
  135:         if ((opt = test->settings->snd_timeout)) {
  136:             if (setsockopt(s, IPPROTO_TCP, TCP_USER_TIMEOUT, &opt, sizeof(opt)) < 0) {
  137:                 i_errno = IESETUSERTIMEOUT;
  138:                 return -1;
  139:             }
  140:         }
  141: #endif /* HAVE_TCP_USER_TIMEOUT */
  142: 
  143:         if (Nread(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) != COOKIE_SIZE) {
  144:             /*
  145:              * Note this error covers both the case of a system error
  146:              * or the inability to read the correct amount of data
  147:              * (i.e. timed out).
  148:              */
  149:             i_errno = IERECVCOOKIE;
  150:             return -1;
  151:         }
  152: 	FD_SET(test->ctrl_sck, &test->read_set);
  153: 	if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck;
  154: 
  155: 	if (iperf_set_send_state(test, PARAM_EXCHANGE) != 0)
  156:             return -1;
  157:         if (iperf_exchange_parameters(test) < 0)
  158:             return -1;
  159: 	if (test->server_affinity != -1)
  160: 	    if (iperf_setaffinity(test, test->server_affinity) != 0)
  161: 		return -1;
  162:         if (test->on_connect)
  163:             test->on_connect(test);
  164:     } else {
  165: 	/*
  166: 	 * Don't try to read from the socket.  It could block an ongoing test.
  167: 	 * Just send ACCESS_DENIED.
  168:          * Also, if sending failed, don't return an error, as the request is not related
  169:          * to the ongoing test, and returning an error will terminate the test.
  170: 	 */
  171:         if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Ptcp) < 0) {
  172:             if (test->debug)
  173:                 printf("failed to send ACCESS_DENIED to an unsolicited connection request during active test\n");
  174:         } else {
  175:             if (test->debug)
  176:                 printf("successfully sent ACCESS_DENIED to an unsolicited connection request during active test\n");
  177:         }
  178:         close(s);
  179:     }
  180: 
  181:     return 0;
  182: }
  183: 
  184: 
  185: /**************************************************************************/
  186: int
  187: iperf_handle_message_server(struct iperf_test *test)
  188: {
  189:     int rval;
  190:     struct iperf_stream *sp;
  191: 
  192:     // XXX: Need to rethink how this behaves to fit API
  193:     if ((rval = Nread(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp)) <= 0) {
  194:         if (rval == 0) {
  195: 	    iperf_err(test, "the client has unexpectedly closed the connection");
  196:             i_errno = IECTRLCLOSE;
  197:             test->state = IPERF_DONE;
  198:             return 0;
  199:         } else {
  200:             i_errno = IERECVMESSAGE;
  201:             return -1;
  202:         }
  203:     }
  204: 
  205:     switch(test->state) {
  206:         case TEST_START:
  207:             break;
  208:         case TEST_END:
  209: 	    test->done = 1;
  210:             cpu_util(test->cpu_util);
  211:             test->stats_callback(test);
  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->reporter_callback(test);
  218: 	    if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
  219:                 return -1;
  220:             if (iperf_exchange_results(test) < 0)
  221:                 return -1;
  222: 	    if (iperf_set_send_state(test, DISPLAY_RESULTS) != 0)
  223:                 return -1;
  224:             if (test->on_test_finish)
  225:                 test->on_test_finish(test);
  226:             break;
  227:         case IPERF_DONE:
  228:             break;
  229:         case CLIENT_TERMINATE:
  230:             i_errno = IECLIENTTERM;
  231: 
  232: 	    // Temporarily be in DISPLAY_RESULTS phase so we can get
  233: 	    // ending summary statistics.
  234: 	    signed char oldstate = test->state;
  235: 	    cpu_util(test->cpu_util);
  236: 	    test->state = DISPLAY_RESULTS;
  237: 	    test->reporter_callback(test);
  238: 	    test->state = oldstate;
  239: 
  240:             // XXX: Remove this line below!
  241: 	    iperf_err(test, "the client has terminated");
  242:             SLIST_FOREACH(sp, &test->streams, streams) {
  243:                 FD_CLR(sp->socket, &test->read_set);
  244:                 FD_CLR(sp->socket, &test->write_set);
  245:                 close(sp->socket);
  246:             }
  247:             test->state = IPERF_DONE;
  248:             break;
  249:         default:
  250:             i_errno = IEMESSAGE;
  251:             return -1;
  252:     }
  253: 
  254:     return 0;
  255: }
  256: 
  257: static void
  258: server_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
  259: {
  260:     struct iperf_test *test = client_data.p;
  261:     struct iperf_stream *sp;
  262: 
  263:     test->timer = NULL;
  264:     if (test->done)
  265:         return;
  266:     test->done = 1;
  267:     /* Free streams */
  268:     while (!SLIST_EMPTY(&test->streams)) {
  269:         sp = SLIST_FIRST(&test->streams);
  270:         SLIST_REMOVE_HEAD(&test->streams, streams);
  271:         close(sp->socket);
  272:         iperf_free_stream(sp);
  273:     }
  274:     close(test->ctrl_sck);
  275:     test->ctrl_sck = -1;
  276: }
  277: 
  278: static void
  279: server_stats_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
  280: {
  281:     struct iperf_test *test = client_data.p;
  282: 
  283:     if (test->done)
  284:         return;
  285:     if (test->stats_callback)
  286: 	test->stats_callback(test);
  287: }
  288: 
  289: static void
  290: server_reporter_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
  291: {
  292:     struct iperf_test *test = client_data.p;
  293: 
  294:     if (test->done)
  295:         return;
  296:     if (test->reporter_callback)
  297: 	test->reporter_callback(test);
  298: }
  299: 
  300: static int
  301: create_server_timers(struct iperf_test * test)
  302: {
  303:     struct iperf_time now;
  304:     TimerClientData cd;
  305:     int max_rtt = 4; /* seconds */
  306:     int state_transitions = 10; /* number of state transitions in iperf3 */
  307:     int grace_period = max_rtt * state_transitions;
  308: 
  309:     if (iperf_time_now(&now) < 0) {
  310: 	i_errno = IEINITTEST;
  311: 	return -1;
  312:     }
  313:     cd.p = test;
  314:     test->timer = test->stats_timer = test->reporter_timer = NULL;
  315:     if (test->duration != 0 ) {
  316:         test->done = 0;
  317:         test->timer = tmr_create(&now, server_timer_proc, cd, (test->duration + test->omit + grace_period) * SEC_TO_US, 0);
  318:         if (test->timer == NULL) {
  319:             i_errno = IEINITTEST;
  320:             return -1;
  321:         }
  322:     }
  323: 
  324:     test->stats_timer = test->reporter_timer = NULL;
  325:     if (test->stats_interval != 0) {
  326:         test->stats_timer = tmr_create(&now, server_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1);
  327:         if (test->stats_timer == NULL) {
  328:             i_errno = IEINITTEST;
  329:             return -1;
  330: 	}
  331:     }
  332:     if (test->reporter_interval != 0) {
  333:         test->reporter_timer = tmr_create(&now, server_reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1);
  334:         if (test->reporter_timer == NULL) {
  335:             i_errno = IEINITTEST;
  336:             return -1;
  337: 	}
  338:     }
  339:     return 0;
  340: }
  341: 
  342: static void
  343: server_omit_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
  344: {
  345:     struct iperf_test *test = client_data.p;
  346: 
  347:     test->omit_timer = NULL;
  348:     test->omitting = 0;
  349:     iperf_reset_stats(test);
  350:     if (test->verbose && !test->json_output && test->reporter_interval == 0)
  351: 	iperf_printf(test, "%s", report_omit_done);
  352: 
  353:     /* Reset the timers. */
  354:     if (test->stats_timer != NULL)
  355: 	tmr_reset(nowP, test->stats_timer);
  356:     if (test->reporter_timer != NULL)
  357: 	tmr_reset(nowP, test->reporter_timer);
  358: }
  359: 
  360: static int
  361: create_server_omit_timer(struct iperf_test * test)
  362: {
  363:     struct iperf_time now;
  364:     TimerClientData cd;
  365: 
  366:     if (test->omit == 0) {
  367: 	test->omit_timer = NULL;
  368: 	test->omitting = 0;
  369:     } else {
  370: 	if (iperf_time_now(&now) < 0) {
  371: 	    i_errno = IEINITTEST;
  372: 	    return -1;
  373: 	}
  374: 	test->omitting = 1;
  375: 	cd.p = test;
  376: 	test->omit_timer = tmr_create(&now, server_omit_timer_proc, cd, test->omit * SEC_TO_US, 0);
  377: 	if (test->omit_timer == NULL) {
  378: 	    i_errno = IEINITTEST;
  379: 	    return -1;
  380: 	}
  381:     }
  382: 
  383:     return 0;
  384: }
  385: 
  386: static void
  387: cleanup_server(struct iperf_test *test)
  388: {
  389:     struct iperf_stream *sp;
  390: 
  391:     /* Close open streams */
  392:     SLIST_FOREACH(sp, &test->streams, streams) {
  393: 	if (sp->socket > -1) {
  394:             FD_CLR(sp->socket, &test->read_set);
  395:             FD_CLR(sp->socket, &test->write_set);
  396:             close(sp->socket);
  397:             sp->socket = -1;
  398: 	}
  399:     }
  400: 
  401:     /* Close open test sockets */
  402:     if (test->ctrl_sck > -1) {
  403: 	close(test->ctrl_sck);
  404:         test->ctrl_sck = -1;
  405:     }
  406:     if (test->listener > -1) {
  407: 	close(test->listener);
  408:         test->listener = -1;
  409:     }
  410:     if (test->prot_listener > -1) {     // May remain open if create socket failed
  411: 	close(test->prot_listener);
  412:         test->prot_listener = -1;
  413:     }
  414: 
  415:     /* Cancel any remaining timers. */
  416:     if (test->stats_timer != NULL) {
  417: 	tmr_cancel(test->stats_timer);
  418: 	test->stats_timer = NULL;
  419:     }
  420:     if (test->reporter_timer != NULL) {
  421: 	tmr_cancel(test->reporter_timer);
  422: 	test->reporter_timer = NULL;
  423:     }
  424:     if (test->omit_timer != NULL) {
  425: 	tmr_cancel(test->omit_timer);
  426: 	test->omit_timer = NULL;
  427:     }
  428:     if (test->congestion_used != NULL) {
  429:         free(test->congestion_used);
  430: 	test->congestion_used = NULL;
  431:     }
  432:     if (test->timer != NULL) {
  433:         tmr_cancel(test->timer);
  434:         test->timer = NULL;
  435:     }
  436: }
  437: 
  438: 
  439: int
  440: iperf_run_server(struct iperf_test *test)
  441: {
  442:     int result, s;
  443:     int send_streams_accepted, rec_streams_accepted;
  444:     int streams_to_send = 0, streams_to_rec = 0;
  445: #if defined(HAVE_TCP_CONGESTION)
  446:     int saved_errno;
  447: #endif /* HAVE_TCP_CONGESTION */
  448:     fd_set read_set, write_set;
  449:     struct iperf_stream *sp;
  450:     struct iperf_time now;
  451:     struct iperf_time last_receive_time;
  452:     struct iperf_time diff_time;
  453:     struct timeval* timeout;
  454:     struct timeval used_timeout;
  455:     int flag;
  456:     int64_t t_usecs;
  457:     int64_t timeout_us;
  458:     int64_t rcv_timeout_us;
  459: 
  460:     if (test->logfile)
  461:         if (iperf_open_logfile(test) < 0)
  462:             return -2;
  463: 
  464:     if (test->affinity != -1)
  465: 	if (iperf_setaffinity(test, test->affinity) != 0) {
  466:             cleanup_server(test);
  467: 	    return -2;
  468:         }
  469: 
  470:     if (test->json_output)
  471: 	if (iperf_json_start(test) < 0) {
  472:             cleanup_server(test);
  473: 	    return -2;
  474:         }
  475: 
  476:     if (test->json_output) {
  477: 	cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version));
  478: 	cJSON_AddItemToObject(test->json_start, "system_info", cJSON_CreateString(get_system_info()));
  479:     } else if (test->verbose) {
  480: 	iperf_printf(test, "%s\n", version);
  481: 	iperf_printf(test, "%s", "");
  482: 	iperf_printf(test, "%s\n", get_system_info());
  483: 	iflush(test);
  484:     }
  485: 
  486:     // Open socket and listen
  487:     if (iperf_server_listen(test) < 0) {
  488: 	cleanup_server(test);
  489:         return -2;
  490:     }
  491: 
  492:     iperf_time_now(&last_receive_time); // Initialize last time something was received
  493: 
  494:     test->state = IPERF_START;
  495:     send_streams_accepted = 0;
  496:     rec_streams_accepted = 0;
  497:     rcv_timeout_us = (test->settings->rcv_timeout.secs * SEC_TO_US) + test->settings->rcv_timeout.usecs;
  498: 
  499:     while (test->state != IPERF_DONE) {
  500: 
  501:         // Check if average transfer rate was exceeded (condition set in the callback routines)
  502: 	if (test->bitrate_limit_exceeded) {
  503: 	    cleanup_server(test);
  504:             i_errno = IETOTALRATE;
  505:             return -1;
  506: 	}
  507: 
  508:         memcpy(&read_set, &test->read_set, sizeof(fd_set));
  509:         memcpy(&write_set, &test->write_set, sizeof(fd_set));
  510: 
  511: 	iperf_time_now(&now);
  512: 	timeout = tmr_timeout(&now);
  513: 
  514:         // Ensure select() will timeout to allow handling error cases that require server restart
  515:         if (test->state == IPERF_START) {       // In idle mode server may need to restart
  516:             if (timeout == NULL && test->settings->idle_timeout > 0) {
  517:                 used_timeout.tv_sec = test->settings->idle_timeout;
  518:                 used_timeout.tv_usec = 0;
  519:                 timeout = &used_timeout;
  520:             }
  521:         } else if (test->mode != SENDER) {     // In non-reverse active mode server ensures data is received
  522:             timeout_us = -1;
  523:             if (timeout != NULL) {
  524:                 used_timeout.tv_sec = timeout->tv_sec;
  525:                 used_timeout.tv_usec = timeout->tv_usec;
  526:                 timeout_us = (timeout->tv_sec * SEC_TO_US) + timeout->tv_usec;
  527:             }
  528:             if (timeout_us < 0 || timeout_us > rcv_timeout_us) {
  529:                 used_timeout.tv_sec = test->settings->rcv_timeout.secs;
  530:                 used_timeout.tv_usec = test->settings->rcv_timeout.usecs;
  531:             }
  532:             timeout = &used_timeout;
  533:         }
  534: 
  535:         result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
  536:         if (result < 0 && errno != EINTR) {
  537:             cleanup_server(test);
  538:             i_errno = IESELECT;
  539:             return -1;
  540:         } else if (result == 0) {
  541:             // If nothing was received during the specified time (per state)
  542:             // then probably something got stack either at the client, server or network,
  543:             // and Test should be forced to end.
  544:             iperf_time_now(&now);
  545:             t_usecs = 0;
  546:             if (iperf_time_diff(&now, &last_receive_time, &diff_time) == 0) {
  547:                 t_usecs = iperf_time_in_usecs(&diff_time);
  548:                 if (test->state == IPERF_START) {
  549:                     if (test->settings->idle_timeout > 0 && t_usecs >= test->settings->idle_timeout * SEC_TO_US) {
  550:                         test->server_forced_idle_restarts_count += 1;
  551:                         if (test->debug)
  552:                             printf("Server restart (#%d) in idle state as no connection request was received for %d sec\n",
  553:                                 test->server_forced_idle_restarts_count, test->settings->idle_timeout);
  554:                         cleanup_server(test);
  555: 			if ( iperf_get_test_one_off(test) ) {
  556: 			  if (test->debug)
  557:                             printf("No connection request was received for %d sec in one-off mode; exiting.\n",
  558: 				   test->settings->idle_timeout);
  559: 			  exit(0);
  560: 			}
  561: 
  562:                         return 2;
  563:                     }
  564:                 }
  565:                 else if (test->mode != SENDER && t_usecs > rcv_timeout_us) {
  566:                     test->server_forced_no_msg_restarts_count += 1;
  567:                     i_errno = IENOMSG;
  568:                     if (iperf_get_verbose(test))
  569:                         iperf_err(test, "Server restart (#%d) during active test due to idle timeout for receiving data",
  570:                                   test->server_forced_no_msg_restarts_count);
  571:                     cleanup_server(test);
  572:                     return -1;
  573:                 }
  574: 
  575:             }
  576:         }
  577: 
  578: 	if (result > 0) {
  579:             iperf_time_now(&last_receive_time);
  580:             if (FD_ISSET(test->listener, &read_set)) {
  581:                 if (test->state != CREATE_STREAMS) {
  582:                     if (iperf_accept(test) < 0) {
  583: 			cleanup_server(test);
  584:                         return -1;
  585:                     }
  586:                     FD_CLR(test->listener, &read_set);
  587: 
  588:                     // Set streams number
  589:                     if (test->mode == BIDIRECTIONAL) {
  590:                         streams_to_send = test->num_streams;
  591:                         streams_to_rec = test->num_streams;
  592:                     } else if (test->mode == RECEIVER) {
  593:                         streams_to_rec = test->num_streams;
  594:                         streams_to_send = 0;
  595:                     } else {
  596:                         streams_to_send = test->num_streams;
  597:                         streams_to_rec = 0;
  598:                     }
  599:                 }
  600:             }
  601:             if (FD_ISSET(test->ctrl_sck, &read_set)) {
  602:                 if (iperf_handle_message_server(test) < 0) {
  603: 		    cleanup_server(test);
  604:                     return -1;
  605: 		}
  606:                 FD_CLR(test->ctrl_sck, &read_set);
  607:             }
  608: 
  609:             if (test->state == CREATE_STREAMS) {
  610:                 if (FD_ISSET(test->prot_listener, &read_set)) {
  611: 
  612:                     if ((s = test->protocol->accept(test)) < 0) {
  613: 			cleanup_server(test);
  614:                         return -1;
  615: 		    }
  616: 
  617: 		    /* apply other common socket options */
  618:                     if (iperf_common_sockopts(test, s) < 0)
  619:                     {
  620:                         cleanup_server(test);
  621:                         return -1;
  622:                     }
  623: 
  624:                     if (!is_closed(s)) {
  625: 
  626: #if defined(HAVE_TCP_USER_TIMEOUT)
  627: 		    if (test->protocol->id == Ptcp) {
  628:                         int opt;
  629:                         if ((opt = test->settings->snd_timeout)) {
  630:                             if (setsockopt(s, IPPROTO_TCP, TCP_USER_TIMEOUT, &opt, sizeof(opt)) < 0) {
  631:                                 saved_errno = errno;
  632:                                 close(s);
  633:                                 cleanup_server(test);
  634:                                 errno = saved_errno;
  635:                                 i_errno = IESETUSERTIMEOUT;
  636:                                 return -1;
  637:                             }
  638:                         }
  639:                     }
  640: #endif /* HAVE_TCP_USER_TIMEOUT */
  641: 
  642: #if defined(HAVE_TCP_CONGESTION)
  643: 		    if (test->protocol->id == Ptcp) {
  644: 			if (test->congestion) {
  645: 			    if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) {
  646: 				/*
  647: 				 * ENOENT means we tried to set the
  648: 				 * congestion algorithm but the algorithm
  649: 				 * specified doesn't exist.  This can happen
  650: 				 * if the client and server have different
  651: 				 * congestion algorithms available.  In this
  652: 				 * case, print a warning, but otherwise
  653: 				 * continue.
  654: 				 */
  655: 				if (errno == ENOENT) {
  656: 				    warning("TCP congestion control algorithm not supported");
  657: 				}
  658: 				else {
  659: 				    saved_errno = errno;
  660: 				    close(s);
  661: 				    cleanup_server(test);
  662: 				    errno = saved_errno;
  663: 				    i_errno = IESETCONGESTION;
  664: 				    return -1;
  665: 				}
  666: 			    }
  667: 			}
  668: 			{
  669: 			    socklen_t len = TCP_CA_NAME_MAX;
  670: 			    char ca[TCP_CA_NAME_MAX + 1];
  671:                             int rc;
  672: 			    rc = getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len);
  673:                             if (rc < 0 && test->congestion) {
  674: 				saved_errno = errno;
  675: 				close(s);
  676: 				cleanup_server(test);
  677: 				errno = saved_errno;
  678: 				i_errno = IESETCONGESTION;
  679: 				return -1;
  680: 			    }
  681:                             /*
  682:                              * If not the first connection, discard prior
  683:                              * congestion algorithm name so we don't leak
  684:                              * duplicated strings.  We probably don't need
  685:                              * the old string anyway.
  686:                              */
  687:                             if (test->congestion_used != NULL) {
  688:                                 free(test->congestion_used);
  689:                             }
  690:                             // Set actual used congestion alg, or set to unknown if could not get it
  691:                             if (rc < 0)
  692:                                 test->congestion_used = strdup("unknown");
  693:                             else
  694:                                 test->congestion_used = strdup(ca);
  695: 			    if (test->debug) {
  696: 				printf("Congestion algorithm is %s\n", test->congestion_used);
  697: 			    }
  698: 			}
  699: 		    }
  700: #endif /* HAVE_TCP_CONGESTION */
  701: 
  702:                         if (rec_streams_accepted != streams_to_rec) {
  703:                             flag = 0;
  704:                             ++rec_streams_accepted;
  705:                         } else if (send_streams_accepted != streams_to_send) {
  706:                             flag = 1;
  707:                             ++send_streams_accepted;
  708:                         }
  709: 
  710:                         if (flag != -1) {
  711:                             sp = iperf_new_stream(test, s, flag);
  712:                             if (!sp) {
  713:                                 cleanup_server(test);
  714:                                 return -1;
  715:                             }
  716: 
  717:                             if (sp->sender)
  718:                                 FD_SET(s, &test->write_set);
  719:                             else
  720:                                 FD_SET(s, &test->read_set);
  721: 
  722:                             if (s > test->max_fd) test->max_fd = s;
  723: 
  724:                             /*
  725:                              * If the protocol isn't UDP, or even if it is but
  726:                              * we're the receiver, set nonblocking sockets.
  727:                              * We need this to allow a server receiver to
  728:                              * maintain interactivity with the control channel.
  729:                              */
  730:                             if (test->protocol->id != Pudp ||
  731:                                 !sp->sender) {
  732:                                 setnonblocking(s, 1);
  733:                             }
  734: 
  735:                             if (test->on_new_stream)
  736:                                 test->on_new_stream(sp);
  737: 
  738:                             flag = -1;
  739:                         }
  740:                     }
  741:                     FD_CLR(test->prot_listener, &read_set);
  742:                 }
  743: 
  744: 
  745:                 if (rec_streams_accepted == streams_to_rec && send_streams_accepted == streams_to_send) {
  746:                     if (test->protocol->id != Ptcp) {
  747:                         FD_CLR(test->prot_listener, &test->read_set);
  748:                         close(test->prot_listener);
  749:                         test->prot_listener = -1;
  750:                     } else {
  751:                         if (test->no_delay || test->settings->mss || test->settings->socket_bufsize) {
  752:                             FD_CLR(test->listener, &test->read_set);
  753:                             close(test->listener);
  754: 			    test->listener = -1;
  755:                             if ((s = netannounce(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, test->server_port)) < 0) {
  756: 				cleanup_server(test);
  757:                                 i_errno = IELISTEN;
  758:                                 return -1;
  759:                             }
  760:                             test->listener = s;
  761:                             FD_SET(test->listener, &test->read_set);
  762: 			    if (test->listener > test->max_fd) test->max_fd = test->listener;
  763:                         }
  764:                     }
  765:                     test->prot_listener = -1;
  766: 
  767: 		    /* Ensure that total requested data rate is not above limit */
  768: 		    iperf_size_t total_requested_rate = test->num_streams * test->settings->rate * (test->mode == BIDIRECTIONAL? 2 : 1);
  769: 		    if (test->settings->bitrate_limit > 0 && total_requested_rate > test->settings->bitrate_limit) {
  770:                         if (iperf_get_verbose(test))
  771:                             iperf_err(test, "Client total requested throughput rate of %" PRIu64 " bps exceeded %" PRIu64 " bps limit",
  772:                                       total_requested_rate, test->settings->bitrate_limit);
  773: 			cleanup_server(test);
  774: 			i_errno = IETOTALRATE;
  775: 			return -1;
  776: 		    }
  777: 
  778: 		    // Begin calculating CPU utilization
  779: 		    cpu_util(NULL);
  780: 
  781: 		    if (iperf_set_send_state(test, TEST_START) != 0) {
  782: 			cleanup_server(test);
  783:                         return -1;
  784: 		    }
  785:                     if (iperf_init_test(test) < 0) {
  786: 			cleanup_server(test);
  787:                         return -1;
  788: 		    }
  789: 		    if (create_server_timers(test) < 0) {
  790: 			cleanup_server(test);
  791:                         return -1;
  792: 		    }
  793: 		    if (create_server_omit_timer(test) < 0) {
  794: 			cleanup_server(test);
  795:                         return -1;
  796: 		    }
  797: 		    if (test->mode != RECEIVER)
  798: 			if (iperf_create_send_timers(test) < 0) {
  799: 			    cleanup_server(test);
  800: 			    return -1;
  801: 			}
  802: 		    if (iperf_set_send_state(test, TEST_RUNNING) != 0) {
  803: 			cleanup_server(test);
  804:                         return -1;
  805: 		    }
  806:                 }
  807:             }
  808: 
  809:             if (test->state == TEST_RUNNING) {
  810:                 if (test->mode == BIDIRECTIONAL) {
  811:                     if (iperf_recv(test, &read_set) < 0) {
  812:                         cleanup_server(test);
  813:                         return -1;
  814:                     }
  815:                     if (iperf_send(test, &write_set) < 0) {
  816:                         cleanup_server(test);
  817:                         return -1;
  818:                     }
  819:                 } else if (test->mode == SENDER) {
  820:                     // Reverse mode. Server sends.
  821:                     if (iperf_send(test, &write_set) < 0) {
  822: 			cleanup_server(test);
  823:                         return -1;
  824: 		    }
  825:                 } else {
  826:                     // Regular mode. Server receives.
  827:                     if (iperf_recv(test, &read_set) < 0) {
  828: 			cleanup_server(test);
  829:                         return -1;
  830: 		    }
  831:                 }
  832: 	    }
  833:         }
  834: 
  835: 	if (result == 0 ||
  836: 	    (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) {
  837: 	    /* Run the timers. */
  838: 	    iperf_time_now(&now);
  839: 	    tmr_run(&now);
  840: 	}
  841:     }
  842: 
  843: 
  844:     if (test->json_output) {
  845: 	if (iperf_json_finish(test) < 0)
  846: 	    return -1;
  847:     }
  848: 
  849:     iflush(test);
  850:     cleanup_server(test);
  851: 
  852:     if (test->server_affinity != -1)
  853: 	if (iperf_clearaffinity(test) != 0)
  854: 	    return -1;
  855: 
  856:     return 0;
  857: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>