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