xref: /iperf/src/iperf_tcp.c (revision ff1ea4e5)
1 /*
2  * iperf, Copyright (c) 2014-2018, 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 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <sys/socket.h>
33 #include <sys/types.h>
34 #include <netinet/in.h>
35 #include <netdb.h>
36 #include <sys/time.h>
37 #include <sys/select.h>
38 
39 #include "iperf.h"
40 #include "iperf_api.h"
41 #include "iperf_tcp.h"
42 #include "net.h"
43 #include "cjson.h"
44 
45 #if defined(HAVE_FLOWLABEL)
46 #include "flowlabel.h"
47 #endif /* HAVE_FLOWLABEL */
48 
49 /* iperf_tcp_recv
50  *
51  * receives the data for TCP
52  */
53 int
54 iperf_tcp_recv(struct iperf_stream *sp)
55 {
56     int r;
57 
58     r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Ptcp);
59 
60     if (r < 0)
61         return r;
62 
63     /* Only count bytes received while we're in the correct state. */
64     if (sp->test->state == TEST_RUNNING) {
65 	sp->result->bytes_received += r;
66 	sp->result->bytes_received_this_interval += r;
67     }
68     else {
69 	if (sp->test->debug)
70 	    printf("Late receive, state = %d\n", sp->test->state);
71     }
72 
73     return r;
74 }
75 
76 
77 /* iperf_tcp_send
78  *
79  * sends the data for TCP
80  */
81 int
82 iperf_tcp_send(struct iperf_stream *sp)
83 {
84     int r;
85 
86     if (sp->test->zerocopy)
87 	r = Nsendfile(sp->buffer_fd, sp->socket, sp->buffer, sp->settings->blksize);
88     else
89 	r = Nwrite(sp->socket, sp->buffer, sp->settings->blksize, Ptcp);
90 
91     if (r < 0)
92         return r;
93 
94     sp->result->bytes_sent += r;
95     sp->result->bytes_sent_this_interval += r;
96 
97     if (sp->test->debug)
98 	printf("sent %d bytes of %d, total %" PRIu64 "\n", r, sp->settings->blksize, sp->result->bytes_sent);
99 
100     return r;
101 }
102 
103 
104 /* iperf_tcp_accept
105  *
106  * accept a new TCP stream connection
107  */
108 int
109 iperf_tcp_accept(struct iperf_test * test)
110 {
111     int     s;
112     signed char rbuf = ACCESS_DENIED;
113     char    cookie[COOKIE_SIZE];
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 = IESTREAMCONNECT;
120         return -1;
121     }
122 
123     if (Nread(s, cookie, COOKIE_SIZE, Ptcp) < 0) {
124         i_errno = IERECVCOOKIE;
125         return -1;
126     }
127 
128     if (strcmp(test->cookie, cookie) != 0) {
129         if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Ptcp) < 0) {
130             i_errno = IESENDMESSAGE;
131             return -1;
132         }
133         close(s);
134     }
135 
136     return s;
137 }
138 
139 
140 /* iperf_tcp_listen
141  *
142  * start up a listener for TCP stream connections
143  */
144 int
145 iperf_tcp_listen(struct iperf_test *test)
146 {
147     int s, opt;
148     socklen_t optlen;
149     int saved_errno;
150     int rcvbuf_actual, sndbuf_actual;
151 
152     s = test->listener;
153 
154     /*
155      * If certain parameters are specified (such as socket buffer
156      * size), then throw away the listening socket (the one for which
157      * we just accepted the control connection) and recreate it with
158      * those parameters.  That way, when new data connections are
159      * set, they'll have all the correct parameters in place.
160      *
161      * It's not clear whether this is a requirement or a convenience.
162      */
163     if (test->no_delay || test->settings->mss || test->settings->socket_bufsize) {
164 	struct addrinfo hints, *res;
165 	char portstr[6];
166 
167         FD_CLR(s, &test->read_set);
168         close(s);
169 
170         snprintf(portstr, 6, "%d", test->server_port);
171         memset(&hints, 0, sizeof(hints));
172 
173 	/*
174 	 * If binding to the wildcard address with no explicit address
175 	 * family specified, then force us to get an AF_INET6 socket.
176 	 * More details in the comments in netanounce().
177 	 */
178 	if (test->settings->domain == AF_UNSPEC && !test->bind_address) {
179 	    hints.ai_family = AF_INET6;
180 	}
181 	else {
182 	    hints.ai_family = test->settings->domain;
183 	}
184         hints.ai_socktype = SOCK_STREAM;
185         hints.ai_flags = AI_PASSIVE;
186         if (getaddrinfo(test->bind_address, portstr, &hints, &res) != 0) {
187             i_errno = IESTREAMLISTEN;
188             return -1;
189         }
190 
191         if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
192 	    freeaddrinfo(res);
193             i_errno = IESTREAMLISTEN;
194             return -1;
195         }
196 
197         if (test->no_delay) {
198             opt = 1;
199             if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
200 		saved_errno = errno;
201 		close(s);
202 		freeaddrinfo(res);
203 		errno = saved_errno;
204                 i_errno = IESETNODELAY;
205                 return -1;
206             }
207         }
208         // XXX: Setting MSS is very buggy!
209         if ((opt = test->settings->mss)) {
210             if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) {
211 		saved_errno = errno;
212 		close(s);
213 		freeaddrinfo(res);
214 		errno = saved_errno;
215                 i_errno = IESETMSS;
216                 return -1;
217             }
218         }
219         if ((opt = test->settings->socket_bufsize)) {
220             if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
221 		saved_errno = errno;
222 		close(s);
223 		freeaddrinfo(res);
224 		errno = saved_errno;
225                 i_errno = IESETBUF;
226                 return -1;
227             }
228             if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) {
229 		saved_errno = errno;
230 		close(s);
231 		freeaddrinfo(res);
232 		errno = saved_errno;
233                 i_errno = IESETBUF;
234                 return -1;
235             }
236         }
237 #if defined(HAVE_SO_MAX_PACING_RATE)
238     /* If fq socket pacing is specified, enable it. */
239     if (test->settings->fqrate) {
240 	/* Convert bits per second to bytes per second */
241 	unsigned int fqrate = test->settings->fqrate / 8;
242 	if (fqrate > 0) {
243 	    if (test->debug) {
244 		printf("Setting fair-queue socket pacing to %u\n", fqrate);
245 	    }
246 	    if (setsockopt(s, SOL_SOCKET, SO_MAX_PACING_RATE, &fqrate, sizeof(fqrate)) < 0) {
247 		warning("Unable to set socket pacing");
248 	    }
249 	}
250     }
251 #endif /* HAVE_SO_MAX_PACING_RATE */
252     {
253 	unsigned int rate = test->settings->rate / 8;
254 	if (rate > 0) {
255 	    if (test->debug) {
256 		printf("Setting application pacing to %u\n", rate);
257 	    }
258 	}
259     }
260         opt = 1;
261         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
262 	    saved_errno = errno;
263             close(s);
264 	    freeaddrinfo(res);
265 	    errno = saved_errno;
266             i_errno = IEREUSEADDR;
267             return -1;
268         }
269 
270 	/*
271 	 * If we got an IPv6 socket, figure out if it shoudl accept IPv4
272 	 * connections as well.  See documentation in netannounce() for
273 	 * more details.
274 	 */
275 #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
276 	if (res->ai_family == AF_INET6 && (test->settings->domain == AF_UNSPEC || test->settings->domain == AF_INET)) {
277 	    if (test->settings->domain == AF_UNSPEC)
278 		opt = 0;
279 	    else
280 		opt = 1;
281 	    if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
282 			   (char *) &opt, sizeof(opt)) < 0) {
283 		saved_errno = errno;
284 		close(s);
285 		freeaddrinfo(res);
286 		errno = saved_errno;
287 		i_errno = IEV6ONLY;
288 		return -1;
289 	    }
290 	}
291 #endif /* IPV6_V6ONLY */
292 
293         if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) {
294 	    saved_errno = errno;
295             close(s);
296 	    freeaddrinfo(res);
297 	    errno = saved_errno;
298             i_errno = IESTREAMLISTEN;
299             return -1;
300         }
301 
302         freeaddrinfo(res);
303 
304         if (listen(s, 5) < 0) {
305             i_errno = IESTREAMLISTEN;
306             return -1;
307         }
308 
309         test->listener = s;
310     }
311 
312     /* Read back and verify the sender socket buffer size */
313     optlen = sizeof(sndbuf_actual);
314     if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_actual, &optlen) < 0) {
315 	saved_errno = errno;
316 	close(s);
317 	errno = saved_errno;
318 	i_errno = IESETBUF;
319 	return -1;
320     }
321     if (test->debug) {
322 	printf("SNDBUF is %u, expecting %u\n", sndbuf_actual, test->settings->socket_bufsize);
323     }
324     if (test->settings->socket_bufsize && test->settings->socket_bufsize > sndbuf_actual) {
325 	i_errno = IESETBUF2;
326 	return -1;
327     }
328 
329     /* Read back and verify the receiver socket buffer size */
330     optlen = sizeof(rcvbuf_actual);
331     if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf_actual, &optlen) < 0) {
332 	saved_errno = errno;
333 	close(s);
334 	errno = saved_errno;
335 	i_errno = IESETBUF;
336 	return -1;
337     }
338     if (test->debug) {
339 	printf("RCVBUF is %u, expecting %u\n", rcvbuf_actual, test->settings->socket_bufsize);
340     }
341     if (test->settings->socket_bufsize && test->settings->socket_bufsize > rcvbuf_actual) {
342 	i_errno = IESETBUF2;
343 	return -1;
344     }
345 
346     if (test->json_output) {
347 	cJSON_AddNumberToObject(test->json_start, "sock_bufsize", test->settings->socket_bufsize);
348 	cJSON_AddNumberToObject(test->json_start, "sndbuf_actual", sndbuf_actual);
349 	cJSON_AddNumberToObject(test->json_start, "rcvbuf_actual", rcvbuf_actual);
350     }
351 
352     return s;
353 }
354 
355 
356 /* iperf_tcp_connect
357  *
358  * connect to a TCP stream listener
359  * This function is roughly similar to netdial(), and may indeed have
360  * been derived from it at some point, but it sets many TCP-specific
361  * options between socket creation and connection.
362  */
363 int
364 iperf_tcp_connect(struct iperf_test *test)
365 {
366     struct addrinfo hints, *local_res, *server_res;
367     char portstr[6];
368     int s, opt;
369     socklen_t optlen;
370     int saved_errno;
371     int rcvbuf_actual, sndbuf_actual;
372 
373     if (test->bind_address) {
374         memset(&hints, 0, sizeof(hints));
375         hints.ai_family = test->settings->domain;
376         hints.ai_socktype = SOCK_STREAM;
377         if (getaddrinfo(test->bind_address, NULL, &hints, &local_res) != 0) {
378             i_errno = IESTREAMCONNECT;
379             return -1;
380         }
381     }
382 
383     memset(&hints, 0, sizeof(hints));
384     hints.ai_family = test->settings->domain;
385     hints.ai_socktype = SOCK_STREAM;
386     snprintf(portstr, sizeof(portstr), "%d", test->server_port);
387     if (getaddrinfo(test->server_hostname, portstr, &hints, &server_res) != 0) {
388 	if (test->bind_address)
389 	    freeaddrinfo(local_res);
390         i_errno = IESTREAMCONNECT;
391         return -1;
392     }
393 
394     if ((s = socket(server_res->ai_family, SOCK_STREAM, 0)) < 0) {
395 	if (test->bind_address)
396 	    freeaddrinfo(local_res);
397 	freeaddrinfo(server_res);
398         i_errno = IESTREAMCONNECT;
399         return -1;
400     }
401 
402     /*
403      * Various ways to bind the local end of the connection.
404      * 1.  --bind (with or without --cport).
405      */
406     if (test->bind_address) {
407         struct sockaddr_in *lcladdr;
408         lcladdr = (struct sockaddr_in *)local_res->ai_addr;
409         lcladdr->sin_port = htons(test->bind_port);
410 
411         if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
412 	    saved_errno = errno;
413 	    close(s);
414 	    freeaddrinfo(local_res);
415 	    freeaddrinfo(server_res);
416 	    errno = saved_errno;
417             i_errno = IESTREAMCONNECT;
418             return -1;
419         }
420         freeaddrinfo(local_res);
421     }
422     /* --cport, no --bind */
423     else if (test->bind_port) {
424 	size_t addrlen;
425 	struct sockaddr_storage lcl;
426 
427 	/* IPv4 */
428 	if (server_res->ai_family == AF_INET) {
429 	    struct sockaddr_in *lcladdr = (struct sockaddr_in *) &lcl;
430 	    lcladdr->sin_family = AF_INET;
431 	    lcladdr->sin_port = htons(test->bind_port);
432 	    lcladdr->sin_addr.s_addr = INADDR_ANY;
433 	    addrlen = sizeof(struct sockaddr_in);
434 	}
435 	/* IPv6 */
436 	else if (server_res->ai_family == AF_INET6) {
437 	    struct sockaddr_in6 *lcladdr = (struct sockaddr_in6 *) &lcl;
438 	    lcladdr->sin6_family = AF_INET6;
439 	    lcladdr->sin6_port = htons(test->bind_port);
440 	    lcladdr->sin6_addr = in6addr_any;
441 	    addrlen = sizeof(struct sockaddr_in6);
442 	}
443 	/* Unknown protocol */
444 	else {
445 	    saved_errno = errno;
446 	    close(s);
447 	    freeaddrinfo(server_res);
448 	    errno = saved_errno;
449             i_errno = IEPROTOCOL;
450             return -1;
451 	}
452 
453         if (bind(s, (struct sockaddr *) &lcl, addrlen) < 0) {
454 	    saved_errno = errno;
455 	    close(s);
456 	    freeaddrinfo(server_res);
457 	    errno = saved_errno;
458             i_errno = IESTREAMCONNECT;
459             return -1;
460         }
461     }
462 
463     /* Set socket options */
464     if (test->no_delay) {
465         opt = 1;
466         if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
467 	    saved_errno = errno;
468 	    close(s);
469 	    freeaddrinfo(server_res);
470 	    errno = saved_errno;
471             i_errno = IESETNODELAY;
472             return -1;
473         }
474     }
475     if ((opt = test->settings->mss)) {
476         if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) {
477 	    saved_errno = errno;
478 	    close(s);
479 	    freeaddrinfo(server_res);
480 	    errno = saved_errno;
481             i_errno = IESETMSS;
482             return -1;
483         }
484     }
485     if ((opt = test->settings->socket_bufsize)) {
486         if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
487 	    saved_errno = errno;
488 	    close(s);
489 	    freeaddrinfo(server_res);
490 	    errno = saved_errno;
491             i_errno = IESETBUF;
492             return -1;
493         }
494         if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) {
495 	    saved_errno = errno;
496 	    close(s);
497 	    freeaddrinfo(server_res);
498 	    errno = saved_errno;
499             i_errno = IESETBUF;
500             return -1;
501         }
502     }
503 
504     /* Read back and verify the sender socket buffer size */
505     optlen = sizeof(sndbuf_actual);
506     if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_actual, &optlen) < 0) {
507 	saved_errno = errno;
508 	close(s);
509 	freeaddrinfo(server_res);
510 	errno = saved_errno;
511 	i_errno = IESETBUF;
512 	return -1;
513     }
514     if (test->debug) {
515 	printf("SNDBUF is %u, expecting %u\n", sndbuf_actual, test->settings->socket_bufsize);
516     }
517     if (test->settings->socket_bufsize && test->settings->socket_bufsize > sndbuf_actual) {
518 	i_errno = IESETBUF2;
519 	return -1;
520     }
521 
522     /* Read back and verify the receiver socket buffer size */
523     optlen = sizeof(rcvbuf_actual);
524     if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf_actual, &optlen) < 0) {
525 	saved_errno = errno;
526 	close(s);
527 	freeaddrinfo(server_res);
528 	errno = saved_errno;
529 	i_errno = IESETBUF;
530 	return -1;
531     }
532     if (test->debug) {
533 	printf("RCVBUF is %u, expecting %u\n", rcvbuf_actual, test->settings->socket_bufsize);
534     }
535     if (test->settings->socket_bufsize && test->settings->socket_bufsize > rcvbuf_actual) {
536 	i_errno = IESETBUF2;
537 	return -1;
538     }
539 
540     if (test->json_output) {
541 	cJSON_AddNumberToObject(test->json_start, "sock_bufsize", test->settings->socket_bufsize);
542 	cJSON_AddNumberToObject(test->json_start, "sndbuf_actual", sndbuf_actual);
543 	cJSON_AddNumberToObject(test->json_start, "rcvbuf_actual", rcvbuf_actual);
544     }
545 
546 #if defined(HAVE_FLOWLABEL)
547     if (test->settings->flowlabel) {
548         if (server_res->ai_addr->sa_family != AF_INET6) {
549 	    saved_errno = errno;
550 	    close(s);
551 	    freeaddrinfo(server_res);
552 	    errno = saved_errno;
553             i_errno = IESETFLOW;
554             return -1;
555 	} else {
556 	    struct sockaddr_in6* sa6P = (struct sockaddr_in6*) server_res->ai_addr;
557             char freq_buf[sizeof(struct in6_flowlabel_req)];
558             struct in6_flowlabel_req *freq = (struct in6_flowlabel_req *)freq_buf;
559             int freq_len = sizeof(*freq);
560 
561             memset(freq, 0, sizeof(*freq));
562             freq->flr_label = htonl(test->settings->flowlabel & IPV6_FLOWINFO_FLOWLABEL);
563             freq->flr_action = IPV6_FL_A_GET;
564             freq->flr_flags = IPV6_FL_F_CREATE;
565             freq->flr_share = IPV6_FL_S_ANY;
566             memcpy(&freq->flr_dst, &sa6P->sin6_addr, 16);
567 
568             if (setsockopt(s, IPPROTO_IPV6, IPV6_FLOWLABEL_MGR, freq, freq_len) < 0) {
569 		saved_errno = errno;
570                 close(s);
571                 freeaddrinfo(server_res);
572 		errno = saved_errno;
573                 i_errno = IESETFLOW;
574                 return -1;
575             }
576             sa6P->sin6_flowinfo = freq->flr_label;
577 
578             opt = 1;
579             if (setsockopt(s, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, &opt, sizeof(opt)) < 0) {
580 		saved_errno = errno;
581                 close(s);
582                 freeaddrinfo(server_res);
583 		errno = saved_errno;
584                 i_errno = IESETFLOW;
585                 return -1;
586             }
587 	}
588     }
589 #endif /* HAVE_FLOWLABEL */
590 
591 #if defined(HAVE_SO_MAX_PACING_RATE)
592     /* If socket pacing is specified try to enable it. */
593     if (test->settings->fqrate) {
594 	/* Convert bits per second to bytes per second */
595 	unsigned int fqrate = test->settings->fqrate / 8;
596 	if (fqrate > 0) {
597 	    if (test->debug) {
598 		printf("Setting fair-queue socket pacing to %u\n", fqrate);
599 	    }
600 	    if (setsockopt(s, SOL_SOCKET, SO_MAX_PACING_RATE, &fqrate, sizeof(fqrate)) < 0) {
601 		warning("Unable to set socket pacing");
602 	    }
603 	}
604     }
605 #endif /* HAVE_SO_MAX_PACING_RATE */
606     {
607 	unsigned int rate = test->settings->rate / 8;
608 	if (rate > 0) {
609 	    if (test->debug) {
610 		printf("Setting application pacing to %u\n", rate);
611 	    }
612 	}
613     }
614 
615     if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) {
616 	saved_errno = errno;
617 	close(s);
618 	freeaddrinfo(server_res);
619 	errno = saved_errno;
620         i_errno = IESTREAMCONNECT;
621         return -1;
622     }
623 
624     freeaddrinfo(server_res);
625 
626     /* Send cookie for verification */
627     if (Nwrite(s, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
628 	saved_errno = errno;
629 	close(s);
630 	errno = saved_errno;
631         i_errno = IESENDCOOKIE;
632         return -1;
633     }
634 
635     return s;
636 }
637