1*7ab6e6acSAndroid Build Coastguard Worker /*
2*7ab6e6acSAndroid Build Coastguard Worker * iperf, Copyright (c) 2014-2020 The Regents of the University of
3*7ab6e6acSAndroid Build Coastguard Worker * California, through Lawrence Berkeley National Laboratory (subject
4*7ab6e6acSAndroid Build Coastguard Worker * to receipt of any required approvals from the U.S. Dept. of
5*7ab6e6acSAndroid Build Coastguard Worker * Energy). All rights reserved.
6*7ab6e6acSAndroid Build Coastguard Worker *
7*7ab6e6acSAndroid Build Coastguard Worker * If you have questions about your rights to use or distribute this
8*7ab6e6acSAndroid Build Coastguard Worker * software, please contact Berkeley Lab's Technology Transfer
9*7ab6e6acSAndroid Build Coastguard Worker * Department at [email protected].
10*7ab6e6acSAndroid Build Coastguard Worker *
11*7ab6e6acSAndroid Build Coastguard Worker * NOTICE. This software is owned by the U.S. Department of Energy.
12*7ab6e6acSAndroid Build Coastguard Worker * As such, the U.S. Government has been granted for itself and others
13*7ab6e6acSAndroid Build Coastguard Worker * acting on its behalf a paid-up, nonexclusive, irrevocable,
14*7ab6e6acSAndroid Build Coastguard Worker * worldwide license in the Software to reproduce, prepare derivative
15*7ab6e6acSAndroid Build Coastguard Worker * works, and perform publicly and display publicly. Beginning five
16*7ab6e6acSAndroid Build Coastguard Worker * (5) years after the date permission to assert copyright is obtained
17*7ab6e6acSAndroid Build Coastguard Worker * from the U.S. Department of Energy, and subject to any subsequent
18*7ab6e6acSAndroid Build Coastguard Worker * five (5) year renewals, the U.S. Government is granted for itself
19*7ab6e6acSAndroid Build Coastguard Worker * and others acting on its behalf a paid-up, nonexclusive,
20*7ab6e6acSAndroid Build Coastguard Worker * irrevocable, worldwide license in the Software to reproduce,
21*7ab6e6acSAndroid Build Coastguard Worker * prepare derivative works, distribute copies to the public, perform
22*7ab6e6acSAndroid Build Coastguard Worker * publicly and display publicly, and to permit others to do so.
23*7ab6e6acSAndroid Build Coastguard Worker *
24*7ab6e6acSAndroid Build Coastguard Worker * This code is distributed under a BSD style license, see the LICENSE
25*7ab6e6acSAndroid Build Coastguard Worker * file for complete information.
26*7ab6e6acSAndroid Build Coastguard Worker */
27*7ab6e6acSAndroid Build Coastguard Worker /* iperf_server_api.c: Functions to be used by an iperf server
28*7ab6e6acSAndroid Build Coastguard Worker */
29*7ab6e6acSAndroid Build Coastguard Worker
30*7ab6e6acSAndroid Build Coastguard Worker #include <stdio.h>
31*7ab6e6acSAndroid Build Coastguard Worker #include <stdlib.h>
32*7ab6e6acSAndroid Build Coastguard Worker #include <string.h>
33*7ab6e6acSAndroid Build Coastguard Worker #include <getopt.h>
34*7ab6e6acSAndroid Build Coastguard Worker #include <errno.h>
35*7ab6e6acSAndroid Build Coastguard Worker #include <unistd.h>
36*7ab6e6acSAndroid Build Coastguard Worker #include <assert.h>
37*7ab6e6acSAndroid Build Coastguard Worker #include <fcntl.h>
38*7ab6e6acSAndroid Build Coastguard Worker #include <sys/socket.h>
39*7ab6e6acSAndroid Build Coastguard Worker #include <sys/types.h>
40*7ab6e6acSAndroid Build Coastguard Worker #include <netinet/in.h>
41*7ab6e6acSAndroid Build Coastguard Worker #include <arpa/inet.h>
42*7ab6e6acSAndroid Build Coastguard Worker #include <netdb.h>
43*7ab6e6acSAndroid Build Coastguard Worker #ifdef HAVE_STDINT_H
44*7ab6e6acSAndroid Build Coastguard Worker #include <stdint.h>
45*7ab6e6acSAndroid Build Coastguard Worker #endif
46*7ab6e6acSAndroid Build Coastguard Worker #include <sys/time.h>
47*7ab6e6acSAndroid Build Coastguard Worker #include <sys/resource.h>
48*7ab6e6acSAndroid Build Coastguard Worker #include <sched.h>
49*7ab6e6acSAndroid Build Coastguard Worker #include <setjmp.h>
50*7ab6e6acSAndroid Build Coastguard Worker
51*7ab6e6acSAndroid Build Coastguard Worker #include "iperf.h"
52*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_api.h"
53*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_udp.h"
54*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_tcp.h"
55*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_util.h"
56*7ab6e6acSAndroid Build Coastguard Worker #include "timer.h"
57*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_time.h"
58*7ab6e6acSAndroid Build Coastguard Worker #include "net.h"
59*7ab6e6acSAndroid Build Coastguard Worker #include "units.h"
60*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_util.h"
61*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_locale.h"
62*7ab6e6acSAndroid Build Coastguard Worker
63*7ab6e6acSAndroid Build Coastguard Worker #if defined(HAVE_TCP_CONGESTION)
64*7ab6e6acSAndroid Build Coastguard Worker #if !defined(TCP_CA_NAME_MAX)
65*7ab6e6acSAndroid Build Coastguard Worker #define TCP_CA_NAME_MAX 16
66*7ab6e6acSAndroid Build Coastguard Worker #endif /* TCP_CA_NAME_MAX */
67*7ab6e6acSAndroid Build Coastguard Worker #endif /* HAVE_TCP_CONGESTION */
68*7ab6e6acSAndroid Build Coastguard Worker
69*7ab6e6acSAndroid Build Coastguard Worker int
iperf_server_listen(struct iperf_test * test)70*7ab6e6acSAndroid Build Coastguard Worker iperf_server_listen(struct iperf_test *test)
71*7ab6e6acSAndroid Build Coastguard Worker {
72*7ab6e6acSAndroid Build Coastguard Worker retry:
73*7ab6e6acSAndroid Build Coastguard Worker if((test->listener = netannounce(test->settings->domain, Ptcp, test->bind_address, test->server_port)) < 0) {
74*7ab6e6acSAndroid Build Coastguard Worker if (errno == EAFNOSUPPORT && (test->settings->domain == AF_INET6 || test->settings->domain == AF_UNSPEC)) {
75*7ab6e6acSAndroid Build Coastguard Worker /* If we get "Address family not supported by protocol", that
76*7ab6e6acSAndroid Build Coastguard Worker ** probably means we were compiled with IPv6 but the running
77*7ab6e6acSAndroid Build Coastguard Worker ** kernel does not actually do IPv6. This is not too unusual,
78*7ab6e6acSAndroid Build Coastguard Worker ** v6 support is and perhaps always will be spotty.
79*7ab6e6acSAndroid Build Coastguard Worker */
80*7ab6e6acSAndroid Build Coastguard Worker warning("this system does not seem to support IPv6 - trying IPv4");
81*7ab6e6acSAndroid Build Coastguard Worker test->settings->domain = AF_INET;
82*7ab6e6acSAndroid Build Coastguard Worker goto retry;
83*7ab6e6acSAndroid Build Coastguard Worker } else {
84*7ab6e6acSAndroid Build Coastguard Worker i_errno = IELISTEN;
85*7ab6e6acSAndroid Build Coastguard Worker return -1;
86*7ab6e6acSAndroid Build Coastguard Worker }
87*7ab6e6acSAndroid Build Coastguard Worker }
88*7ab6e6acSAndroid Build Coastguard Worker
89*7ab6e6acSAndroid Build Coastguard Worker if (!test->json_output) {
90*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "-----------------------------------------------------------\n");
91*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "Server listening on %d\n", test->server_port);
92*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "-----------------------------------------------------------\n");
93*7ab6e6acSAndroid Build Coastguard Worker if (test->forceflush)
94*7ab6e6acSAndroid Build Coastguard Worker iflush(test);
95*7ab6e6acSAndroid Build Coastguard Worker }
96*7ab6e6acSAndroid Build Coastguard Worker
97*7ab6e6acSAndroid Build Coastguard Worker FD_ZERO(&test->read_set);
98*7ab6e6acSAndroid Build Coastguard Worker FD_ZERO(&test->write_set);
99*7ab6e6acSAndroid Build Coastguard Worker FD_SET(test->listener, &test->read_set);
100*7ab6e6acSAndroid Build Coastguard Worker if (test->listener > test->max_fd) test->max_fd = test->listener;
101*7ab6e6acSAndroid Build Coastguard Worker
102*7ab6e6acSAndroid Build Coastguard Worker return 0;
103*7ab6e6acSAndroid Build Coastguard Worker }
104*7ab6e6acSAndroid Build Coastguard Worker
105*7ab6e6acSAndroid Build Coastguard Worker int
iperf_accept(struct iperf_test * test)106*7ab6e6acSAndroid Build Coastguard Worker iperf_accept(struct iperf_test *test)
107*7ab6e6acSAndroid Build Coastguard Worker {
108*7ab6e6acSAndroid Build Coastguard Worker int s;
109*7ab6e6acSAndroid Build Coastguard Worker signed char rbuf = ACCESS_DENIED;
110*7ab6e6acSAndroid Build Coastguard Worker socklen_t len;
111*7ab6e6acSAndroid Build Coastguard Worker struct sockaddr_storage addr;
112*7ab6e6acSAndroid Build Coastguard Worker
113*7ab6e6acSAndroid Build Coastguard Worker len = sizeof(addr);
114*7ab6e6acSAndroid Build Coastguard Worker if ((s = accept(test->listener, (struct sockaddr *) &addr, &len)) < 0) {
115*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEACCEPT;
116*7ab6e6acSAndroid Build Coastguard Worker return -1;
117*7ab6e6acSAndroid Build Coastguard Worker }
118*7ab6e6acSAndroid Build Coastguard Worker
119*7ab6e6acSAndroid Build Coastguard Worker if (test->ctrl_sck == -1) {
120*7ab6e6acSAndroid Build Coastguard Worker /* Server free, accept new client */
121*7ab6e6acSAndroid Build Coastguard Worker test->ctrl_sck = s;
122*7ab6e6acSAndroid Build Coastguard Worker if (Nread(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
123*7ab6e6acSAndroid Build Coastguard Worker i_errno = IERECVCOOKIE;
124*7ab6e6acSAndroid Build Coastguard Worker return -1;
125*7ab6e6acSAndroid Build Coastguard Worker }
126*7ab6e6acSAndroid Build Coastguard Worker FD_SET(test->ctrl_sck, &test->read_set);
127*7ab6e6acSAndroid Build Coastguard Worker if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck;
128*7ab6e6acSAndroid Build Coastguard Worker
129*7ab6e6acSAndroid Build Coastguard Worker if (iperf_set_send_state(test, PARAM_EXCHANGE) != 0)
130*7ab6e6acSAndroid Build Coastguard Worker return -1;
131*7ab6e6acSAndroid Build Coastguard Worker if (iperf_exchange_parameters(test) < 0)
132*7ab6e6acSAndroid Build Coastguard Worker return -1;
133*7ab6e6acSAndroid Build Coastguard Worker if (test->server_affinity != -1)
134*7ab6e6acSAndroid Build Coastguard Worker if (iperf_setaffinity(test, test->server_affinity) != 0)
135*7ab6e6acSAndroid Build Coastguard Worker return -1;
136*7ab6e6acSAndroid Build Coastguard Worker if (test->on_connect)
137*7ab6e6acSAndroid Build Coastguard Worker test->on_connect(test);
138*7ab6e6acSAndroid Build Coastguard Worker } else {
139*7ab6e6acSAndroid Build Coastguard Worker /*
140*7ab6e6acSAndroid Build Coastguard Worker * Don't try to read from the socket. It could block an ongoing test.
141*7ab6e6acSAndroid Build Coastguard Worker * Just send ACCESS_DENIED.
142*7ab6e6acSAndroid Build Coastguard Worker */
143*7ab6e6acSAndroid Build Coastguard Worker if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Ptcp) < 0) {
144*7ab6e6acSAndroid Build Coastguard Worker i_errno = IESENDMESSAGE;
145*7ab6e6acSAndroid Build Coastguard Worker return -1;
146*7ab6e6acSAndroid Build Coastguard Worker }
147*7ab6e6acSAndroid Build Coastguard Worker close(s);
148*7ab6e6acSAndroid Build Coastguard Worker }
149*7ab6e6acSAndroid Build Coastguard Worker
150*7ab6e6acSAndroid Build Coastguard Worker return 0;
151*7ab6e6acSAndroid Build Coastguard Worker }
152*7ab6e6acSAndroid Build Coastguard Worker
153*7ab6e6acSAndroid Build Coastguard Worker
154*7ab6e6acSAndroid Build Coastguard Worker /**************************************************************************/
155*7ab6e6acSAndroid Build Coastguard Worker int
iperf_handle_message_server(struct iperf_test * test)156*7ab6e6acSAndroid Build Coastguard Worker iperf_handle_message_server(struct iperf_test *test)
157*7ab6e6acSAndroid Build Coastguard Worker {
158*7ab6e6acSAndroid Build Coastguard Worker int rval;
159*7ab6e6acSAndroid Build Coastguard Worker struct iperf_stream *sp;
160*7ab6e6acSAndroid Build Coastguard Worker
161*7ab6e6acSAndroid Build Coastguard Worker // XXX: Need to rethink how this behaves to fit API
162*7ab6e6acSAndroid Build Coastguard Worker if ((rval = Nread(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp)) <= 0) {
163*7ab6e6acSAndroid Build Coastguard Worker if (rval == 0) {
164*7ab6e6acSAndroid Build Coastguard Worker iperf_err(test, "the client has unexpectedly closed the connection");
165*7ab6e6acSAndroid Build Coastguard Worker i_errno = IECTRLCLOSE;
166*7ab6e6acSAndroid Build Coastguard Worker test->state = IPERF_DONE;
167*7ab6e6acSAndroid Build Coastguard Worker return 0;
168*7ab6e6acSAndroid Build Coastguard Worker } else {
169*7ab6e6acSAndroid Build Coastguard Worker i_errno = IERECVMESSAGE;
170*7ab6e6acSAndroid Build Coastguard Worker return -1;
171*7ab6e6acSAndroid Build Coastguard Worker }
172*7ab6e6acSAndroid Build Coastguard Worker }
173*7ab6e6acSAndroid Build Coastguard Worker
174*7ab6e6acSAndroid Build Coastguard Worker switch(test->state) {
175*7ab6e6acSAndroid Build Coastguard Worker case TEST_START:
176*7ab6e6acSAndroid Build Coastguard Worker break;
177*7ab6e6acSAndroid Build Coastguard Worker case TEST_END:
178*7ab6e6acSAndroid Build Coastguard Worker test->done = 1;
179*7ab6e6acSAndroid Build Coastguard Worker cpu_util(test->cpu_util);
180*7ab6e6acSAndroid Build Coastguard Worker test->stats_callback(test);
181*7ab6e6acSAndroid Build Coastguard Worker SLIST_FOREACH(sp, &test->streams, streams) {
182*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(sp->socket, &test->read_set);
183*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(sp->socket, &test->write_set);
184*7ab6e6acSAndroid Build Coastguard Worker close(sp->socket);
185*7ab6e6acSAndroid Build Coastguard Worker }
186*7ab6e6acSAndroid Build Coastguard Worker test->reporter_callback(test);
187*7ab6e6acSAndroid Build Coastguard Worker if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
188*7ab6e6acSAndroid Build Coastguard Worker return -1;
189*7ab6e6acSAndroid Build Coastguard Worker if (iperf_exchange_results(test) < 0)
190*7ab6e6acSAndroid Build Coastguard Worker return -1;
191*7ab6e6acSAndroid Build Coastguard Worker if (iperf_set_send_state(test, DISPLAY_RESULTS) != 0)
192*7ab6e6acSAndroid Build Coastguard Worker return -1;
193*7ab6e6acSAndroid Build Coastguard Worker if (test->on_test_finish)
194*7ab6e6acSAndroid Build Coastguard Worker test->on_test_finish(test);
195*7ab6e6acSAndroid Build Coastguard Worker break;
196*7ab6e6acSAndroid Build Coastguard Worker case IPERF_DONE:
197*7ab6e6acSAndroid Build Coastguard Worker break;
198*7ab6e6acSAndroid Build Coastguard Worker case CLIENT_TERMINATE:
199*7ab6e6acSAndroid Build Coastguard Worker i_errno = IECLIENTTERM;
200*7ab6e6acSAndroid Build Coastguard Worker
201*7ab6e6acSAndroid Build Coastguard Worker // Temporarily be in DISPLAY_RESULTS phase so we can get
202*7ab6e6acSAndroid Build Coastguard Worker // ending summary statistics.
203*7ab6e6acSAndroid Build Coastguard Worker signed char oldstate = test->state;
204*7ab6e6acSAndroid Build Coastguard Worker cpu_util(test->cpu_util);
205*7ab6e6acSAndroid Build Coastguard Worker test->state = DISPLAY_RESULTS;
206*7ab6e6acSAndroid Build Coastguard Worker test->reporter_callback(test);
207*7ab6e6acSAndroid Build Coastguard Worker test->state = oldstate;
208*7ab6e6acSAndroid Build Coastguard Worker
209*7ab6e6acSAndroid Build Coastguard Worker // XXX: Remove this line below!
210*7ab6e6acSAndroid Build Coastguard Worker iperf_err(test, "the client has terminated");
211*7ab6e6acSAndroid Build Coastguard Worker SLIST_FOREACH(sp, &test->streams, streams) {
212*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(sp->socket, &test->read_set);
213*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(sp->socket, &test->write_set);
214*7ab6e6acSAndroid Build Coastguard Worker close(sp->socket);
215*7ab6e6acSAndroid Build Coastguard Worker }
216*7ab6e6acSAndroid Build Coastguard Worker test->state = IPERF_DONE;
217*7ab6e6acSAndroid Build Coastguard Worker break;
218*7ab6e6acSAndroid Build Coastguard Worker default:
219*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEMESSAGE;
220*7ab6e6acSAndroid Build Coastguard Worker return -1;
221*7ab6e6acSAndroid Build Coastguard Worker }
222*7ab6e6acSAndroid Build Coastguard Worker
223*7ab6e6acSAndroid Build Coastguard Worker return 0;
224*7ab6e6acSAndroid Build Coastguard Worker }
225*7ab6e6acSAndroid Build Coastguard Worker
226*7ab6e6acSAndroid Build Coastguard Worker static void
server_timer_proc(TimerClientData client_data,struct iperf_time * nowP)227*7ab6e6acSAndroid Build Coastguard Worker server_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
228*7ab6e6acSAndroid Build Coastguard Worker {
229*7ab6e6acSAndroid Build Coastguard Worker struct iperf_test *test = client_data.p;
230*7ab6e6acSAndroid Build Coastguard Worker struct iperf_stream *sp;
231*7ab6e6acSAndroid Build Coastguard Worker
232*7ab6e6acSAndroid Build Coastguard Worker test->timer = NULL;
233*7ab6e6acSAndroid Build Coastguard Worker if (test->done)
234*7ab6e6acSAndroid Build Coastguard Worker return;
235*7ab6e6acSAndroid Build Coastguard Worker test->done = 1;
236*7ab6e6acSAndroid Build Coastguard Worker /* Free streams */
237*7ab6e6acSAndroid Build Coastguard Worker while (!SLIST_EMPTY(&test->streams)) {
238*7ab6e6acSAndroid Build Coastguard Worker sp = SLIST_FIRST(&test->streams);
239*7ab6e6acSAndroid Build Coastguard Worker SLIST_REMOVE_HEAD(&test->streams, streams);
240*7ab6e6acSAndroid Build Coastguard Worker close(sp->socket);
241*7ab6e6acSAndroid Build Coastguard Worker iperf_free_stream(sp);
242*7ab6e6acSAndroid Build Coastguard Worker }
243*7ab6e6acSAndroid Build Coastguard Worker close(test->ctrl_sck);
244*7ab6e6acSAndroid Build Coastguard Worker }
245*7ab6e6acSAndroid Build Coastguard Worker
246*7ab6e6acSAndroid Build Coastguard Worker static void
server_stats_timer_proc(TimerClientData client_data,struct iperf_time * nowP)247*7ab6e6acSAndroid Build Coastguard Worker server_stats_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
248*7ab6e6acSAndroid Build Coastguard Worker {
249*7ab6e6acSAndroid Build Coastguard Worker struct iperf_test *test = client_data.p;
250*7ab6e6acSAndroid Build Coastguard Worker
251*7ab6e6acSAndroid Build Coastguard Worker if (test->done)
252*7ab6e6acSAndroid Build Coastguard Worker return;
253*7ab6e6acSAndroid Build Coastguard Worker if (test->stats_callback)
254*7ab6e6acSAndroid Build Coastguard Worker test->stats_callback(test);
255*7ab6e6acSAndroid Build Coastguard Worker }
256*7ab6e6acSAndroid Build Coastguard Worker
257*7ab6e6acSAndroid Build Coastguard Worker static void
server_reporter_timer_proc(TimerClientData client_data,struct iperf_time * nowP)258*7ab6e6acSAndroid Build Coastguard Worker server_reporter_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
259*7ab6e6acSAndroid Build Coastguard Worker {
260*7ab6e6acSAndroid Build Coastguard Worker struct iperf_test *test = client_data.p;
261*7ab6e6acSAndroid Build Coastguard Worker
262*7ab6e6acSAndroid Build Coastguard Worker if (test->done)
263*7ab6e6acSAndroid Build Coastguard Worker return;
264*7ab6e6acSAndroid Build Coastguard Worker if (test->reporter_callback)
265*7ab6e6acSAndroid Build Coastguard Worker test->reporter_callback(test);
266*7ab6e6acSAndroid Build Coastguard Worker }
267*7ab6e6acSAndroid Build Coastguard Worker
268*7ab6e6acSAndroid Build Coastguard Worker static int
create_server_timers(struct iperf_test * test)269*7ab6e6acSAndroid Build Coastguard Worker create_server_timers(struct iperf_test * test)
270*7ab6e6acSAndroid Build Coastguard Worker {
271*7ab6e6acSAndroid Build Coastguard Worker struct iperf_time now;
272*7ab6e6acSAndroid Build Coastguard Worker TimerClientData cd;
273*7ab6e6acSAndroid Build Coastguard Worker int max_rtt = 4; /* seconds */
274*7ab6e6acSAndroid Build Coastguard Worker int state_transitions = 10; /* number of state transitions in iperf3 */
275*7ab6e6acSAndroid Build Coastguard Worker int grace_period = max_rtt * state_transitions;
276*7ab6e6acSAndroid Build Coastguard Worker
277*7ab6e6acSAndroid Build Coastguard Worker if (iperf_time_now(&now) < 0) {
278*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEINITTEST;
279*7ab6e6acSAndroid Build Coastguard Worker return -1;
280*7ab6e6acSAndroid Build Coastguard Worker }
281*7ab6e6acSAndroid Build Coastguard Worker cd.p = test;
282*7ab6e6acSAndroid Build Coastguard Worker test->timer = test->stats_timer = test->reporter_timer = NULL;
283*7ab6e6acSAndroid Build Coastguard Worker if (test->duration != 0 ) {
284*7ab6e6acSAndroid Build Coastguard Worker test->done = 0;
285*7ab6e6acSAndroid Build Coastguard Worker test->timer = tmr_create(&now, server_timer_proc, cd, (test->duration + test->omit + grace_period) * SEC_TO_US, 0);
286*7ab6e6acSAndroid Build Coastguard Worker if (test->timer == NULL) {
287*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEINITTEST;
288*7ab6e6acSAndroid Build Coastguard Worker return -1;
289*7ab6e6acSAndroid Build Coastguard Worker }
290*7ab6e6acSAndroid Build Coastguard Worker }
291*7ab6e6acSAndroid Build Coastguard Worker
292*7ab6e6acSAndroid Build Coastguard Worker test->stats_timer = test->reporter_timer = NULL;
293*7ab6e6acSAndroid Build Coastguard Worker if (test->stats_interval != 0) {
294*7ab6e6acSAndroid Build Coastguard Worker test->stats_timer = tmr_create(&now, server_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1);
295*7ab6e6acSAndroid Build Coastguard Worker if (test->stats_timer == NULL) {
296*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEINITTEST;
297*7ab6e6acSAndroid Build Coastguard Worker return -1;
298*7ab6e6acSAndroid Build Coastguard Worker }
299*7ab6e6acSAndroid Build Coastguard Worker }
300*7ab6e6acSAndroid Build Coastguard Worker if (test->reporter_interval != 0) {
301*7ab6e6acSAndroid Build Coastguard Worker test->reporter_timer = tmr_create(&now, server_reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1);
302*7ab6e6acSAndroid Build Coastguard Worker if (test->reporter_timer == NULL) {
303*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEINITTEST;
304*7ab6e6acSAndroid Build Coastguard Worker return -1;
305*7ab6e6acSAndroid Build Coastguard Worker }
306*7ab6e6acSAndroid Build Coastguard Worker }
307*7ab6e6acSAndroid Build Coastguard Worker return 0;
308*7ab6e6acSAndroid Build Coastguard Worker }
309*7ab6e6acSAndroid Build Coastguard Worker
310*7ab6e6acSAndroid Build Coastguard Worker static void
server_omit_timer_proc(TimerClientData client_data,struct iperf_time * nowP)311*7ab6e6acSAndroid Build Coastguard Worker server_omit_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
312*7ab6e6acSAndroid Build Coastguard Worker {
313*7ab6e6acSAndroid Build Coastguard Worker struct iperf_test *test = client_data.p;
314*7ab6e6acSAndroid Build Coastguard Worker
315*7ab6e6acSAndroid Build Coastguard Worker test->omit_timer = NULL;
316*7ab6e6acSAndroid Build Coastguard Worker test->omitting = 0;
317*7ab6e6acSAndroid Build Coastguard Worker iperf_reset_stats(test);
318*7ab6e6acSAndroid Build Coastguard Worker if (test->verbose && !test->json_output && test->reporter_interval == 0)
319*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "%s", report_omit_done);
320*7ab6e6acSAndroid Build Coastguard Worker
321*7ab6e6acSAndroid Build Coastguard Worker /* Reset the timers. */
322*7ab6e6acSAndroid Build Coastguard Worker if (test->stats_timer != NULL)
323*7ab6e6acSAndroid Build Coastguard Worker tmr_reset(nowP, test->stats_timer);
324*7ab6e6acSAndroid Build Coastguard Worker if (test->reporter_timer != NULL)
325*7ab6e6acSAndroid Build Coastguard Worker tmr_reset(nowP, test->reporter_timer);
326*7ab6e6acSAndroid Build Coastguard Worker }
327*7ab6e6acSAndroid Build Coastguard Worker
328*7ab6e6acSAndroid Build Coastguard Worker static int
create_server_omit_timer(struct iperf_test * test)329*7ab6e6acSAndroid Build Coastguard Worker create_server_omit_timer(struct iperf_test * test)
330*7ab6e6acSAndroid Build Coastguard Worker {
331*7ab6e6acSAndroid Build Coastguard Worker struct iperf_time now;
332*7ab6e6acSAndroid Build Coastguard Worker TimerClientData cd;
333*7ab6e6acSAndroid Build Coastguard Worker
334*7ab6e6acSAndroid Build Coastguard Worker if (test->omit == 0) {
335*7ab6e6acSAndroid Build Coastguard Worker test->omit_timer = NULL;
336*7ab6e6acSAndroid Build Coastguard Worker test->omitting = 0;
337*7ab6e6acSAndroid Build Coastguard Worker } else {
338*7ab6e6acSAndroid Build Coastguard Worker if (iperf_time_now(&now) < 0) {
339*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEINITTEST;
340*7ab6e6acSAndroid Build Coastguard Worker return -1;
341*7ab6e6acSAndroid Build Coastguard Worker }
342*7ab6e6acSAndroid Build Coastguard Worker test->omitting = 1;
343*7ab6e6acSAndroid Build Coastguard Worker cd.p = test;
344*7ab6e6acSAndroid Build Coastguard Worker test->omit_timer = tmr_create(&now, server_omit_timer_proc, cd, test->omit * SEC_TO_US, 0);
345*7ab6e6acSAndroid Build Coastguard Worker if (test->omit_timer == NULL) {
346*7ab6e6acSAndroid Build Coastguard Worker i_errno = IEINITTEST;
347*7ab6e6acSAndroid Build Coastguard Worker return -1;
348*7ab6e6acSAndroid Build Coastguard Worker }
349*7ab6e6acSAndroid Build Coastguard Worker }
350*7ab6e6acSAndroid Build Coastguard Worker
351*7ab6e6acSAndroid Build Coastguard Worker return 0;
352*7ab6e6acSAndroid Build Coastguard Worker }
353*7ab6e6acSAndroid Build Coastguard Worker
354*7ab6e6acSAndroid Build Coastguard Worker static void
cleanup_server(struct iperf_test * test)355*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(struct iperf_test *test)
356*7ab6e6acSAndroid Build Coastguard Worker {
357*7ab6e6acSAndroid Build Coastguard Worker struct iperf_stream *sp;
358*7ab6e6acSAndroid Build Coastguard Worker
359*7ab6e6acSAndroid Build Coastguard Worker /* Close open streams */
360*7ab6e6acSAndroid Build Coastguard Worker SLIST_FOREACH(sp, &test->streams, streams) {
361*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(sp->socket, &test->read_set);
362*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(sp->socket, &test->write_set);
363*7ab6e6acSAndroid Build Coastguard Worker close(sp->socket);
364*7ab6e6acSAndroid Build Coastguard Worker }
365*7ab6e6acSAndroid Build Coastguard Worker
366*7ab6e6acSAndroid Build Coastguard Worker /* Close open test sockets */
367*7ab6e6acSAndroid Build Coastguard Worker if (test->ctrl_sck) {
368*7ab6e6acSAndroid Build Coastguard Worker close(test->ctrl_sck);
369*7ab6e6acSAndroid Build Coastguard Worker }
370*7ab6e6acSAndroid Build Coastguard Worker if (test->listener) {
371*7ab6e6acSAndroid Build Coastguard Worker close(test->listener);
372*7ab6e6acSAndroid Build Coastguard Worker }
373*7ab6e6acSAndroid Build Coastguard Worker
374*7ab6e6acSAndroid Build Coastguard Worker /* Cancel any remaining timers. */
375*7ab6e6acSAndroid Build Coastguard Worker if (test->stats_timer != NULL) {
376*7ab6e6acSAndroid Build Coastguard Worker tmr_cancel(test->stats_timer);
377*7ab6e6acSAndroid Build Coastguard Worker test->stats_timer = NULL;
378*7ab6e6acSAndroid Build Coastguard Worker }
379*7ab6e6acSAndroid Build Coastguard Worker if (test->reporter_timer != NULL) {
380*7ab6e6acSAndroid Build Coastguard Worker tmr_cancel(test->reporter_timer);
381*7ab6e6acSAndroid Build Coastguard Worker test->reporter_timer = NULL;
382*7ab6e6acSAndroid Build Coastguard Worker }
383*7ab6e6acSAndroid Build Coastguard Worker if (test->omit_timer != NULL) {
384*7ab6e6acSAndroid Build Coastguard Worker tmr_cancel(test->omit_timer);
385*7ab6e6acSAndroid Build Coastguard Worker test->omit_timer = NULL;
386*7ab6e6acSAndroid Build Coastguard Worker }
387*7ab6e6acSAndroid Build Coastguard Worker if (test->congestion_used != NULL) {
388*7ab6e6acSAndroid Build Coastguard Worker free(test->congestion_used);
389*7ab6e6acSAndroid Build Coastguard Worker test->congestion_used = NULL;
390*7ab6e6acSAndroid Build Coastguard Worker }
391*7ab6e6acSAndroid Build Coastguard Worker if (test->timer != NULL) {
392*7ab6e6acSAndroid Build Coastguard Worker tmr_cancel(test->timer);
393*7ab6e6acSAndroid Build Coastguard Worker test->timer = NULL;
394*7ab6e6acSAndroid Build Coastguard Worker }
395*7ab6e6acSAndroid Build Coastguard Worker }
396*7ab6e6acSAndroid Build Coastguard Worker
397*7ab6e6acSAndroid Build Coastguard Worker
398*7ab6e6acSAndroid Build Coastguard Worker int
iperf_run_server(struct iperf_test * test)399*7ab6e6acSAndroid Build Coastguard Worker iperf_run_server(struct iperf_test *test)
400*7ab6e6acSAndroid Build Coastguard Worker {
401*7ab6e6acSAndroid Build Coastguard Worker int result, s;
402*7ab6e6acSAndroid Build Coastguard Worker int send_streams_accepted, rec_streams_accepted;
403*7ab6e6acSAndroid Build Coastguard Worker int streams_to_send = 0, streams_to_rec = 0;
404*7ab6e6acSAndroid Build Coastguard Worker #if defined(HAVE_TCP_CONGESTION)
405*7ab6e6acSAndroid Build Coastguard Worker int saved_errno;
406*7ab6e6acSAndroid Build Coastguard Worker #endif /* HAVE_TCP_CONGESTION */
407*7ab6e6acSAndroid Build Coastguard Worker fd_set read_set, write_set;
408*7ab6e6acSAndroid Build Coastguard Worker struct iperf_stream *sp;
409*7ab6e6acSAndroid Build Coastguard Worker struct iperf_time now;
410*7ab6e6acSAndroid Build Coastguard Worker struct timeval* timeout;
411*7ab6e6acSAndroid Build Coastguard Worker int flag;
412*7ab6e6acSAndroid Build Coastguard Worker
413*7ab6e6acSAndroid Build Coastguard Worker if (test->logfile)
414*7ab6e6acSAndroid Build Coastguard Worker if (iperf_open_logfile(test) < 0)
415*7ab6e6acSAndroid Build Coastguard Worker return -1;
416*7ab6e6acSAndroid Build Coastguard Worker
417*7ab6e6acSAndroid Build Coastguard Worker if (test->affinity != -1)
418*7ab6e6acSAndroid Build Coastguard Worker if (iperf_setaffinity(test, test->affinity) != 0)
419*7ab6e6acSAndroid Build Coastguard Worker return -2;
420*7ab6e6acSAndroid Build Coastguard Worker
421*7ab6e6acSAndroid Build Coastguard Worker if (test->json_output)
422*7ab6e6acSAndroid Build Coastguard Worker if (iperf_json_start(test) < 0)
423*7ab6e6acSAndroid Build Coastguard Worker return -2;
424*7ab6e6acSAndroid Build Coastguard Worker
425*7ab6e6acSAndroid Build Coastguard Worker if (test->json_output) {
426*7ab6e6acSAndroid Build Coastguard Worker cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version));
427*7ab6e6acSAndroid Build Coastguard Worker cJSON_AddItemToObject(test->json_start, "system_info", cJSON_CreateString(get_system_info()));
428*7ab6e6acSAndroid Build Coastguard Worker } else if (test->verbose) {
429*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "%s\n", version);
430*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "%s", "");
431*7ab6e6acSAndroid Build Coastguard Worker iperf_printf(test, "%s\n", get_system_info());
432*7ab6e6acSAndroid Build Coastguard Worker iflush(test);
433*7ab6e6acSAndroid Build Coastguard Worker }
434*7ab6e6acSAndroid Build Coastguard Worker
435*7ab6e6acSAndroid Build Coastguard Worker // Open socket and listen
436*7ab6e6acSAndroid Build Coastguard Worker if (iperf_server_listen(test) < 0) {
437*7ab6e6acSAndroid Build Coastguard Worker return -2;
438*7ab6e6acSAndroid Build Coastguard Worker }
439*7ab6e6acSAndroid Build Coastguard Worker
440*7ab6e6acSAndroid Build Coastguard Worker // Begin calculating CPU utilization
441*7ab6e6acSAndroid Build Coastguard Worker cpu_util(NULL);
442*7ab6e6acSAndroid Build Coastguard Worker
443*7ab6e6acSAndroid Build Coastguard Worker test->state = IPERF_START;
444*7ab6e6acSAndroid Build Coastguard Worker send_streams_accepted = 0;
445*7ab6e6acSAndroid Build Coastguard Worker rec_streams_accepted = 0;
446*7ab6e6acSAndroid Build Coastguard Worker
447*7ab6e6acSAndroid Build Coastguard Worker while (test->state != IPERF_DONE) {
448*7ab6e6acSAndroid Build Coastguard Worker
449*7ab6e6acSAndroid Build Coastguard Worker // Check if average transfer rate was exceeded (condition set in the callback routines)
450*7ab6e6acSAndroid Build Coastguard Worker if (test->bitrate_limit_exceeded) {
451*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
452*7ab6e6acSAndroid Build Coastguard Worker i_errno = IETOTALRATE;
453*7ab6e6acSAndroid Build Coastguard Worker return -1;
454*7ab6e6acSAndroid Build Coastguard Worker }
455*7ab6e6acSAndroid Build Coastguard Worker
456*7ab6e6acSAndroid Build Coastguard Worker memcpy(&read_set, &test->read_set, sizeof(fd_set));
457*7ab6e6acSAndroid Build Coastguard Worker memcpy(&write_set, &test->write_set, sizeof(fd_set));
458*7ab6e6acSAndroid Build Coastguard Worker
459*7ab6e6acSAndroid Build Coastguard Worker iperf_time_now(&now);
460*7ab6e6acSAndroid Build Coastguard Worker timeout = tmr_timeout(&now);
461*7ab6e6acSAndroid Build Coastguard Worker result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
462*7ab6e6acSAndroid Build Coastguard Worker
463*7ab6e6acSAndroid Build Coastguard Worker if (result < 0 && errno != EINTR) {
464*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
465*7ab6e6acSAndroid Build Coastguard Worker i_errno = IESELECT;
466*7ab6e6acSAndroid Build Coastguard Worker return -1;
467*7ab6e6acSAndroid Build Coastguard Worker }
468*7ab6e6acSAndroid Build Coastguard Worker if (result > 0) {
469*7ab6e6acSAndroid Build Coastguard Worker if (FD_ISSET(test->listener, &read_set)) {
470*7ab6e6acSAndroid Build Coastguard Worker if (test->state != CREATE_STREAMS) {
471*7ab6e6acSAndroid Build Coastguard Worker if (iperf_accept(test) < 0) {
472*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
473*7ab6e6acSAndroid Build Coastguard Worker return -1;
474*7ab6e6acSAndroid Build Coastguard Worker }
475*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(test->listener, &read_set);
476*7ab6e6acSAndroid Build Coastguard Worker
477*7ab6e6acSAndroid Build Coastguard Worker // Set streams number
478*7ab6e6acSAndroid Build Coastguard Worker if (test->mode == BIDIRECTIONAL) {
479*7ab6e6acSAndroid Build Coastguard Worker streams_to_send = test->num_streams;
480*7ab6e6acSAndroid Build Coastguard Worker streams_to_rec = test->num_streams;
481*7ab6e6acSAndroid Build Coastguard Worker } else if (test->mode == RECEIVER) {
482*7ab6e6acSAndroid Build Coastguard Worker streams_to_rec = test->num_streams;
483*7ab6e6acSAndroid Build Coastguard Worker streams_to_send = 0;
484*7ab6e6acSAndroid Build Coastguard Worker } else {
485*7ab6e6acSAndroid Build Coastguard Worker streams_to_send = test->num_streams;
486*7ab6e6acSAndroid Build Coastguard Worker streams_to_rec = 0;
487*7ab6e6acSAndroid Build Coastguard Worker }
488*7ab6e6acSAndroid Build Coastguard Worker }
489*7ab6e6acSAndroid Build Coastguard Worker }
490*7ab6e6acSAndroid Build Coastguard Worker if (FD_ISSET(test->ctrl_sck, &read_set)) {
491*7ab6e6acSAndroid Build Coastguard Worker if (iperf_handle_message_server(test) < 0) {
492*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
493*7ab6e6acSAndroid Build Coastguard Worker return -1;
494*7ab6e6acSAndroid Build Coastguard Worker }
495*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(test->ctrl_sck, &read_set);
496*7ab6e6acSAndroid Build Coastguard Worker }
497*7ab6e6acSAndroid Build Coastguard Worker
498*7ab6e6acSAndroid Build Coastguard Worker if (test->state == CREATE_STREAMS) {
499*7ab6e6acSAndroid Build Coastguard Worker if (FD_ISSET(test->prot_listener, &read_set)) {
500*7ab6e6acSAndroid Build Coastguard Worker
501*7ab6e6acSAndroid Build Coastguard Worker if ((s = test->protocol->accept(test)) < 0) {
502*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
503*7ab6e6acSAndroid Build Coastguard Worker return -1;
504*7ab6e6acSAndroid Build Coastguard Worker }
505*7ab6e6acSAndroid Build Coastguard Worker
506*7ab6e6acSAndroid Build Coastguard Worker #if defined(HAVE_TCP_CONGESTION)
507*7ab6e6acSAndroid Build Coastguard Worker if (test->protocol->id == Ptcp) {
508*7ab6e6acSAndroid Build Coastguard Worker if (test->congestion) {
509*7ab6e6acSAndroid Build Coastguard Worker if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) {
510*7ab6e6acSAndroid Build Coastguard Worker /*
511*7ab6e6acSAndroid Build Coastguard Worker * ENOENT means we tried to set the
512*7ab6e6acSAndroid Build Coastguard Worker * congestion algorithm but the algorithm
513*7ab6e6acSAndroid Build Coastguard Worker * specified doesn't exist. This can happen
514*7ab6e6acSAndroid Build Coastguard Worker * if the client and server have different
515*7ab6e6acSAndroid Build Coastguard Worker * congestion algorithms available. In this
516*7ab6e6acSAndroid Build Coastguard Worker * case, print a warning, but otherwise
517*7ab6e6acSAndroid Build Coastguard Worker * continue.
518*7ab6e6acSAndroid Build Coastguard Worker */
519*7ab6e6acSAndroid Build Coastguard Worker if (errno == ENOENT) {
520*7ab6e6acSAndroid Build Coastguard Worker warning("TCP congestion control algorithm not supported");
521*7ab6e6acSAndroid Build Coastguard Worker }
522*7ab6e6acSAndroid Build Coastguard Worker else {
523*7ab6e6acSAndroid Build Coastguard Worker saved_errno = errno;
524*7ab6e6acSAndroid Build Coastguard Worker close(s);
525*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
526*7ab6e6acSAndroid Build Coastguard Worker errno = saved_errno;
527*7ab6e6acSAndroid Build Coastguard Worker i_errno = IESETCONGESTION;
528*7ab6e6acSAndroid Build Coastguard Worker return -1;
529*7ab6e6acSAndroid Build Coastguard Worker }
530*7ab6e6acSAndroid Build Coastguard Worker }
531*7ab6e6acSAndroid Build Coastguard Worker }
532*7ab6e6acSAndroid Build Coastguard Worker {
533*7ab6e6acSAndroid Build Coastguard Worker socklen_t len = TCP_CA_NAME_MAX;
534*7ab6e6acSAndroid Build Coastguard Worker char ca[TCP_CA_NAME_MAX + 1];
535*7ab6e6acSAndroid Build Coastguard Worker if (getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len) < 0) {
536*7ab6e6acSAndroid Build Coastguard Worker saved_errno = errno;
537*7ab6e6acSAndroid Build Coastguard Worker close(s);
538*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
539*7ab6e6acSAndroid Build Coastguard Worker errno = saved_errno;
540*7ab6e6acSAndroid Build Coastguard Worker i_errno = IESETCONGESTION;
541*7ab6e6acSAndroid Build Coastguard Worker return -1;
542*7ab6e6acSAndroid Build Coastguard Worker }
543*7ab6e6acSAndroid Build Coastguard Worker test->congestion_used = strdup(ca);
544*7ab6e6acSAndroid Build Coastguard Worker if (test->debug) {
545*7ab6e6acSAndroid Build Coastguard Worker printf("Congestion algorithm is %s\n", test->congestion_used);
546*7ab6e6acSAndroid Build Coastguard Worker }
547*7ab6e6acSAndroid Build Coastguard Worker }
548*7ab6e6acSAndroid Build Coastguard Worker }
549*7ab6e6acSAndroid Build Coastguard Worker #endif /* HAVE_TCP_CONGESTION */
550*7ab6e6acSAndroid Build Coastguard Worker
551*7ab6e6acSAndroid Build Coastguard Worker if (!is_closed(s)) {
552*7ab6e6acSAndroid Build Coastguard Worker
553*7ab6e6acSAndroid Build Coastguard Worker if (rec_streams_accepted != streams_to_rec) {
554*7ab6e6acSAndroid Build Coastguard Worker flag = 0;
555*7ab6e6acSAndroid Build Coastguard Worker ++rec_streams_accepted;
556*7ab6e6acSAndroid Build Coastguard Worker } else if (send_streams_accepted != streams_to_send) {
557*7ab6e6acSAndroid Build Coastguard Worker flag = 1;
558*7ab6e6acSAndroid Build Coastguard Worker ++send_streams_accepted;
559*7ab6e6acSAndroid Build Coastguard Worker }
560*7ab6e6acSAndroid Build Coastguard Worker
561*7ab6e6acSAndroid Build Coastguard Worker if (flag != -1) {
562*7ab6e6acSAndroid Build Coastguard Worker sp = iperf_new_stream(test, s, flag);
563*7ab6e6acSAndroid Build Coastguard Worker if (!sp) {
564*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
565*7ab6e6acSAndroid Build Coastguard Worker return -1;
566*7ab6e6acSAndroid Build Coastguard Worker }
567*7ab6e6acSAndroid Build Coastguard Worker
568*7ab6e6acSAndroid Build Coastguard Worker if (sp->sender)
569*7ab6e6acSAndroid Build Coastguard Worker FD_SET(s, &test->write_set);
570*7ab6e6acSAndroid Build Coastguard Worker else
571*7ab6e6acSAndroid Build Coastguard Worker FD_SET(s, &test->read_set);
572*7ab6e6acSAndroid Build Coastguard Worker
573*7ab6e6acSAndroid Build Coastguard Worker if (s > test->max_fd) test->max_fd = s;
574*7ab6e6acSAndroid Build Coastguard Worker
575*7ab6e6acSAndroid Build Coastguard Worker /*
576*7ab6e6acSAndroid Build Coastguard Worker * If the protocol isn't UDP, or even if it is but
577*7ab6e6acSAndroid Build Coastguard Worker * we're the receiver, set nonblocking sockets.
578*7ab6e6acSAndroid Build Coastguard Worker * We need this to allow a server receiver to
579*7ab6e6acSAndroid Build Coastguard Worker * maintain interactivity with the control channel.
580*7ab6e6acSAndroid Build Coastguard Worker */
581*7ab6e6acSAndroid Build Coastguard Worker if (test->protocol->id != Pudp ||
582*7ab6e6acSAndroid Build Coastguard Worker !sp->sender) {
583*7ab6e6acSAndroid Build Coastguard Worker setnonblocking(s, 1);
584*7ab6e6acSAndroid Build Coastguard Worker }
585*7ab6e6acSAndroid Build Coastguard Worker
586*7ab6e6acSAndroid Build Coastguard Worker if (test->on_new_stream)
587*7ab6e6acSAndroid Build Coastguard Worker test->on_new_stream(sp);
588*7ab6e6acSAndroid Build Coastguard Worker
589*7ab6e6acSAndroid Build Coastguard Worker flag = -1;
590*7ab6e6acSAndroid Build Coastguard Worker }
591*7ab6e6acSAndroid Build Coastguard Worker }
592*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(test->prot_listener, &read_set);
593*7ab6e6acSAndroid Build Coastguard Worker }
594*7ab6e6acSAndroid Build Coastguard Worker
595*7ab6e6acSAndroid Build Coastguard Worker
596*7ab6e6acSAndroid Build Coastguard Worker if (rec_streams_accepted == streams_to_rec && send_streams_accepted == streams_to_send) {
597*7ab6e6acSAndroid Build Coastguard Worker if (test->protocol->id != Ptcp) {
598*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(test->prot_listener, &test->read_set);
599*7ab6e6acSAndroid Build Coastguard Worker close(test->prot_listener);
600*7ab6e6acSAndroid Build Coastguard Worker } else {
601*7ab6e6acSAndroid Build Coastguard Worker if (test->no_delay || test->settings->mss || test->settings->socket_bufsize) {
602*7ab6e6acSAndroid Build Coastguard Worker FD_CLR(test->listener, &test->read_set);
603*7ab6e6acSAndroid Build Coastguard Worker close(test->listener);
604*7ab6e6acSAndroid Build Coastguard Worker test->listener = 0;
605*7ab6e6acSAndroid Build Coastguard Worker if ((s = netannounce(test->settings->domain, Ptcp, test->bind_address, test->server_port)) < 0) {
606*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
607*7ab6e6acSAndroid Build Coastguard Worker i_errno = IELISTEN;
608*7ab6e6acSAndroid Build Coastguard Worker return -1;
609*7ab6e6acSAndroid Build Coastguard Worker }
610*7ab6e6acSAndroid Build Coastguard Worker test->listener = s;
611*7ab6e6acSAndroid Build Coastguard Worker FD_SET(test->listener, &test->read_set);
612*7ab6e6acSAndroid Build Coastguard Worker if (test->listener > test->max_fd) test->max_fd = test->listener;
613*7ab6e6acSAndroid Build Coastguard Worker }
614*7ab6e6acSAndroid Build Coastguard Worker }
615*7ab6e6acSAndroid Build Coastguard Worker test->prot_listener = -1;
616*7ab6e6acSAndroid Build Coastguard Worker
617*7ab6e6acSAndroid Build Coastguard Worker /* Ensure that total requested data rate is not above limit */
618*7ab6e6acSAndroid Build Coastguard Worker iperf_size_t total_requested_rate = test->num_streams * test->settings->rate * (test->mode == BIDIRECTIONAL? 2 : 1);
619*7ab6e6acSAndroid Build Coastguard Worker if (test->settings->bitrate_limit > 0 && total_requested_rate > test->settings->bitrate_limit) {
620*7ab6e6acSAndroid Build Coastguard Worker iperf_err(test, "Client total requested throughput rate of %" PRIu64 " bps exceeded %" PRIu64 " bps limit",
621*7ab6e6acSAndroid Build Coastguard Worker total_requested_rate, test->settings->bitrate_limit);
622*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
623*7ab6e6acSAndroid Build Coastguard Worker i_errno = IETOTALRATE;
624*7ab6e6acSAndroid Build Coastguard Worker return -1;
625*7ab6e6acSAndroid Build Coastguard Worker }
626*7ab6e6acSAndroid Build Coastguard Worker
627*7ab6e6acSAndroid Build Coastguard Worker if (iperf_set_send_state(test, TEST_START) != 0) {
628*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
629*7ab6e6acSAndroid Build Coastguard Worker return -1;
630*7ab6e6acSAndroid Build Coastguard Worker }
631*7ab6e6acSAndroid Build Coastguard Worker if (iperf_init_test(test) < 0) {
632*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
633*7ab6e6acSAndroid Build Coastguard Worker return -1;
634*7ab6e6acSAndroid Build Coastguard Worker }
635*7ab6e6acSAndroid Build Coastguard Worker if (create_server_timers(test) < 0) {
636*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
637*7ab6e6acSAndroid Build Coastguard Worker return -1;
638*7ab6e6acSAndroid Build Coastguard Worker }
639*7ab6e6acSAndroid Build Coastguard Worker if (create_server_omit_timer(test) < 0) {
640*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
641*7ab6e6acSAndroid Build Coastguard Worker return -1;
642*7ab6e6acSAndroid Build Coastguard Worker }
643*7ab6e6acSAndroid Build Coastguard Worker if (test->mode != RECEIVER)
644*7ab6e6acSAndroid Build Coastguard Worker if (iperf_create_send_timers(test) < 0) {
645*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
646*7ab6e6acSAndroid Build Coastguard Worker return -1;
647*7ab6e6acSAndroid Build Coastguard Worker }
648*7ab6e6acSAndroid Build Coastguard Worker if (iperf_set_send_state(test, TEST_RUNNING) != 0) {
649*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
650*7ab6e6acSAndroid Build Coastguard Worker return -1;
651*7ab6e6acSAndroid Build Coastguard Worker }
652*7ab6e6acSAndroid Build Coastguard Worker }
653*7ab6e6acSAndroid Build Coastguard Worker }
654*7ab6e6acSAndroid Build Coastguard Worker
655*7ab6e6acSAndroid Build Coastguard Worker if (test->state == TEST_RUNNING) {
656*7ab6e6acSAndroid Build Coastguard Worker if (test->mode == BIDIRECTIONAL) {
657*7ab6e6acSAndroid Build Coastguard Worker if (iperf_recv(test, &read_set) < 0) {
658*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
659*7ab6e6acSAndroid Build Coastguard Worker return -1;
660*7ab6e6acSAndroid Build Coastguard Worker }
661*7ab6e6acSAndroid Build Coastguard Worker if (iperf_send(test, &write_set) < 0) {
662*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
663*7ab6e6acSAndroid Build Coastguard Worker return -1;
664*7ab6e6acSAndroid Build Coastguard Worker }
665*7ab6e6acSAndroid Build Coastguard Worker } else if (test->mode == SENDER) {
666*7ab6e6acSAndroid Build Coastguard Worker // Reverse mode. Server sends.
667*7ab6e6acSAndroid Build Coastguard Worker if (iperf_send(test, &write_set) < 0) {
668*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
669*7ab6e6acSAndroid Build Coastguard Worker return -1;
670*7ab6e6acSAndroid Build Coastguard Worker }
671*7ab6e6acSAndroid Build Coastguard Worker } else {
672*7ab6e6acSAndroid Build Coastguard Worker // Regular mode. Server receives.
673*7ab6e6acSAndroid Build Coastguard Worker if (iperf_recv(test, &read_set) < 0) {
674*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
675*7ab6e6acSAndroid Build Coastguard Worker return -1;
676*7ab6e6acSAndroid Build Coastguard Worker }
677*7ab6e6acSAndroid Build Coastguard Worker }
678*7ab6e6acSAndroid Build Coastguard Worker }
679*7ab6e6acSAndroid Build Coastguard Worker }
680*7ab6e6acSAndroid Build Coastguard Worker
681*7ab6e6acSAndroid Build Coastguard Worker if (result == 0 ||
682*7ab6e6acSAndroid Build Coastguard Worker (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) {
683*7ab6e6acSAndroid Build Coastguard Worker /* Run the timers. */
684*7ab6e6acSAndroid Build Coastguard Worker iperf_time_now(&now);
685*7ab6e6acSAndroid Build Coastguard Worker tmr_run(&now);
686*7ab6e6acSAndroid Build Coastguard Worker }
687*7ab6e6acSAndroid Build Coastguard Worker }
688*7ab6e6acSAndroid Build Coastguard Worker
689*7ab6e6acSAndroid Build Coastguard Worker cleanup_server(test);
690*7ab6e6acSAndroid Build Coastguard Worker
691*7ab6e6acSAndroid Build Coastguard Worker if (test->json_output) {
692*7ab6e6acSAndroid Build Coastguard Worker if (iperf_json_finish(test) < 0)
693*7ab6e6acSAndroid Build Coastguard Worker return -1;
694*7ab6e6acSAndroid Build Coastguard Worker }
695*7ab6e6acSAndroid Build Coastguard Worker
696*7ab6e6acSAndroid Build Coastguard Worker iflush(test);
697*7ab6e6acSAndroid Build Coastguard Worker
698*7ab6e6acSAndroid Build Coastguard Worker if (test->server_affinity != -1)
699*7ab6e6acSAndroid Build Coastguard Worker if (iperf_clearaffinity(test) != 0)
700*7ab6e6acSAndroid Build Coastguard Worker return -1;
701*7ab6e6acSAndroid Build Coastguard Worker
702*7ab6e6acSAndroid Build Coastguard Worker return 0;
703*7ab6e6acSAndroid Build Coastguard Worker }
704