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