Diff for /embedaddon/iperf/src/iperf_tcp.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2021/03/17 00:36:46 version 1.1.1.3, 2023/09/27 11:14:54
Line 1 Line 1
 /*  /*
 * iperf, Copyright (c) 2014-2019, The Regents of the University of * iperf, Copyright (c) 2014-2022, The Regents of the University of
  * California, through Lawrence Berkeley National Laboratory (subject   * California, through Lawrence Berkeley National Laboratory (subject
  * to receipt of any required approvals from the U.S. Dept. of   * to receipt of any required approvals from the U.S. Dept. of
  * Energy).  All rights reserved.   * Energy).  All rights reserved.
Line 76  iperf_tcp_recv(struct iperf_stream *sp) Line 76  iperf_tcp_recv(struct iperf_stream *sp)
 }  }
   
   
/* iperf_tcp_send /* iperf_tcp_send
  *   *
  * sends the data for TCP   * sends the data for TCP
  */   */
Line 85  iperf_tcp_send(struct iperf_stream *sp) Line 85  iperf_tcp_send(struct iperf_stream *sp)
 {  {
     int r;      int r;
   
       if (!sp->pending_size)
           sp->pending_size = sp->settings->blksize;
   
     if (sp->test->zerocopy)      if (sp->test->zerocopy)
        r = Nsendfile(sp->buffer_fd, sp->socket, sp->buffer, sp->settings->blksize);        r = Nsendfile(sp->buffer_fd, sp->socket, sp->buffer, sp->pending_size);
     else      else
        r = Nwrite(sp->socket, sp->buffer, sp->settings->blksize, Ptcp);        r = Nwrite(sp->socket, sp->buffer, sp->pending_size, Ptcp);
   
     if (r < 0)      if (r < 0)
         return r;          return r;
   
       sp->pending_size -= r;
     sp->result->bytes_sent += r;      sp->result->bytes_sent += r;
     sp->result->bytes_sent_this_interval += r;      sp->result->bytes_sent_this_interval += r;
   
    if (sp->test->debug)    if (sp->test->debug_level >=  DEBUG_LEVEL_DEBUG)
        printf("sent %d bytes of %d, total %" PRIu64 "\n", r, sp->settings->blksize, sp->result->bytes_sent);        printf("sent %d bytes of %d, pending %d, total %" PRIu64 "\n",
             r, sp->settings->blksize, sp->pending_size, sp->result->bytes_sent);
   
     return r;      return r;
 }  }
Line 129  iperf_tcp_accept(struct iperf_test * test) Line 134  iperf_tcp_accept(struct iperf_test * test)
   
     if (strcmp(test->cookie, cookie) != 0) {      if (strcmp(test->cookie, cookie) != 0) {
         if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Ptcp) < 0) {          if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Ptcp) < 0) {
            i_errno = IESENDMESSAGE;            iperf_err(test, "failed to send access denied from busy server to new connecting client, errno = %d\n", errno);
            return -1; 
         }          }
         close(s);          close(s);
     }      }
Line 270  iperf_tcp_listen(struct iperf_test *test) Line 274  iperf_tcp_listen(struct iperf_test *test)
         }          }
   
         /*          /*
         * If we got an IPv6 socket, figure out if it shoudl accept IPv4         * If we got an IPv6 socket, figure out if it should accept IPv4
          * connections as well.  See documentation in netannounce() for           * connections as well.  See documentation in netannounce() for
          * more details.           * more details.
          */           */
Line 278  iperf_tcp_listen(struct iperf_test *test) Line 282  iperf_tcp_listen(struct iperf_test *test)
         if (res->ai_family == AF_INET6 && (test->settings->domain == AF_UNSPEC || test->settings->domain == AF_INET)) {          if (res->ai_family == AF_INET6 && (test->settings->domain == AF_UNSPEC || test->settings->domain == AF_INET)) {
             if (test->settings->domain == AF_UNSPEC)              if (test->settings->domain == AF_UNSPEC)
                 opt = 0;                  opt = 0;
            else             else
                 opt = 1;                  opt = 1;
            if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,             if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
                            (char *) &opt, sizeof(opt)) < 0) {                             (char *) &opt, sizeof(opt)) < 0) {
                 saved_errno = errno;                  saved_errno = errno;
                 close(s);                  close(s);
Line 310  iperf_tcp_listen(struct iperf_test *test) Line 314  iperf_tcp_listen(struct iperf_test *test)
   
         test->listener = s;          test->listener = s;
     }      }
    
     /* Read back and verify the sender socket buffer size */      /* Read back and verify the sender socket buffer size */
     optlen = sizeof(sndbuf_actual);      optlen = sizeof(sndbuf_actual);
     if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_actual, &optlen) < 0) {      if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_actual, &optlen) < 0) {
Line 365  iperf_tcp_listen(struct iperf_test *test) Line 369  iperf_tcp_listen(struct iperf_test *test)
 int  int
 iperf_tcp_connect(struct iperf_test *test)  iperf_tcp_connect(struct iperf_test *test)
 {  {
    struct addrinfo hints, *local_res, *server_res;    struct addrinfo *server_res;
    char portstr[6]; 
     int s, opt;      int s, opt;
     socklen_t optlen;      socklen_t optlen;
     int saved_errno;      int saved_errno;
     int rcvbuf_actual, sndbuf_actual;      int rcvbuf_actual, sndbuf_actual;
   
    if (test->bind_address) {    s = create_socket(test->settings->domain, SOCK_STREAM, test->bind_address, test->bind_dev, test->bind_port, test->server_hostname, test->server_port, &server_res);
        memset(&hints, 0, sizeof(hints));    if (s < 0) {
        hints.ai_family = test->settings->domain;        i_errno = IESTREAMCONNECT;
        hints.ai_socktype = SOCK_STREAM;        return -1;
        if ((gerror = getaddrinfo(test->bind_address, NULL, &hints, &local_res)) != 0) { 
            i_errno = IESTREAMCONNECT; 
            return -1; 
        } 
     }      }
   
     memset(&hints, 0, sizeof(hints));  
     hints.ai_family = test->settings->domain;  
     hints.ai_socktype = SOCK_STREAM;  
     snprintf(portstr, sizeof(portstr), "%d", test->server_port);  
     if ((gerror = getaddrinfo(test->server_hostname, portstr, &hints, &server_res)) != 0) {  
         if (test->bind_address)  
             freeaddrinfo(local_res);  
         i_errno = IESTREAMCONNECT;  
         return -1;  
     }  
   
     if ((s = socket(server_res->ai_family, SOCK_STREAM, 0)) < 0) {  
         if (test->bind_address)  
             freeaddrinfo(local_res);  
         freeaddrinfo(server_res);  
         i_errno = IESTREAMCONNECT;  
         return -1;  
     }  
   
     /*  
      * Various ways to bind the local end of the connection.  
      * 1.  --bind (with or without --cport).  
      */  
     if (test->bind_address) {  
         struct sockaddr_in *lcladdr;  
         lcladdr = (struct sockaddr_in *)local_res->ai_addr;  
         lcladdr->sin_port = htons(test->bind_port);  
   
         if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {  
             saved_errno = errno;  
             close(s);  
             freeaddrinfo(local_res);  
             freeaddrinfo(server_res);  
             errno = saved_errno;  
             i_errno = IESTREAMCONNECT;  
             return -1;  
         }  
         freeaddrinfo(local_res);  
     }  
     /* --cport, no --bind */  
     else if (test->bind_port) {  
         size_t addrlen;  
         struct sockaddr_storage lcl;  
   
         /* IPv4 */  
         if (server_res->ai_family == AF_INET) {  
             struct sockaddr_in *lcladdr = (struct sockaddr_in *) &lcl;  
             lcladdr->sin_family = AF_INET;  
             lcladdr->sin_port = htons(test->bind_port);  
             lcladdr->sin_addr.s_addr = INADDR_ANY;  
             addrlen = sizeof(struct sockaddr_in);  
         }  
         /* IPv6 */  
         else if (server_res->ai_family == AF_INET6) {  
             struct sockaddr_in6 *lcladdr = (struct sockaddr_in6 *) &lcl;  
             lcladdr->sin6_family = AF_INET6;  
             lcladdr->sin6_port = htons(test->bind_port);  
             lcladdr->sin6_addr = in6addr_any;  
             addrlen = sizeof(struct sockaddr_in6);  
         }  
         /* Unknown protocol */  
         else {  
             saved_errno = errno;  
             close(s);  
             freeaddrinfo(server_res);  
             errno = saved_errno;  
             i_errno = IEPROTOCOL;  
             return -1;  
         }  
   
         if (bind(s, (struct sockaddr *) &lcl, addrlen) < 0) {  
             saved_errno = errno;  
             close(s);  
             freeaddrinfo(server_res);  
             errno = saved_errno;  
             i_errno = IESTREAMCONNECT;  
             return -1;  
         }  
     }  
   
     /* Set socket options */      /* Set socket options */
     if (test->no_delay) {      if (test->no_delay) {
         opt = 1;          opt = 1;
Line 502  iperf_tcp_connect(struct iperf_test *test) Line 421  iperf_tcp_connect(struct iperf_test *test)
             return -1;              return -1;
         }          }
     }      }
   #if defined(HAVE_TCP_USER_TIMEOUT)
       if ((opt = test->settings->snd_timeout)) {
           if (setsockopt(s, IPPROTO_TCP, TCP_USER_TIMEOUT, &opt, sizeof(opt)) < 0) {
               saved_errno = errno;
               close(s);
               freeaddrinfo(server_res);
               errno = saved_errno;
               i_errno = IESETUSERTIMEOUT;
               return -1;
           }
       }
   #endif /* HAVE_TCP_USER_TIMEOUT */
   
     /* Read back and verify the sender socket buffer size */      /* Read back and verify the sender socket buffer size */
     optlen = sizeof(sndbuf_actual);      optlen = sizeof(sndbuf_actual);
Line 540  iperf_tcp_connect(struct iperf_test *test) Line 471  iperf_tcp_connect(struct iperf_test *test)
     }      }
   
     if (test->json_output) {      if (test->json_output) {
        cJSON_AddNumberToObject(test->json_start, "sock_bufsize", test->settings->socket_bufsize);    cJSON *sock_bufsize_item = cJSON_GetObjectItem(test->json_start, "sock_bufsize");
     if (sock_bufsize_item == NULL) {
     cJSON_AddNumberToObject(test->json_start, "sock_bufsize", test->settings->socket_bufsize);
     }
 
     cJSON *sndbuf_actual_item = cJSON_GetObjectItem(test->json_start, "sndbuf_actual");
     if (sndbuf_actual_item == NULL) {
         cJSON_AddNumberToObject(test->json_start, "sndbuf_actual", sndbuf_actual);          cJSON_AddNumberToObject(test->json_start, "sndbuf_actual", sndbuf_actual);
       }
           
       cJSON *rcvbuf_actual_item = cJSON_GetObjectItem(test->json_start, "rcvbuf_actual");
       if (rcvbuf_actual_item == NULL) {
         cJSON_AddNumberToObject(test->json_start, "rcvbuf_actual", rcvbuf_actual);          cJSON_AddNumberToObject(test->json_start, "rcvbuf_actual", rcvbuf_actual);
     }      }
       }
   
 #if defined(HAVE_FLOWLABEL)  #if defined(HAVE_FLOWLABEL)
     if (test->settings->flowlabel) {      if (test->settings->flowlabel) {
Line 585  iperf_tcp_connect(struct iperf_test *test) Line 527  iperf_tcp_connect(struct iperf_test *test)
                 errno = saved_errno;                  errno = saved_errno;
                 i_errno = IESETFLOW;                  i_errno = IESETFLOW;
                 return -1;                  return -1;
            }             }
         }          }
     }      }
 #endif /* HAVE_FLOWLABEL */  #endif /* HAVE_FLOWLABEL */
Line 613  iperf_tcp_connect(struct iperf_test *test) Line 555  iperf_tcp_connect(struct iperf_test *test)
             }              }
         }          }
     }      }
   
       /* Set common socket options */
       iperf_common_sockopts(test, s);
   
     if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) {      if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) {
         saved_errno = errno;          saved_errno = errno;

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>