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