xref: /iperf/src/iperf_server_api.c (revision ad98a8fe)
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