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