Diff for /embedaddon/iperf/src/net.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 33 Line 33
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/types.h>  #include <sys/types.h>
 #include <netinet/in.h>  #include <netinet/in.h>
 #include <netinet/tcp.h>  
 #include <assert.h>  #include <assert.h>
 #include <netdb.h>  #include <netdb.h>
 #include <string.h>  #include <string.h>
Line 61 Line 60
 #include <poll.h>  #include <poll.h>
 #endif /* HAVE_POLL_H */  #endif /* HAVE_POLL_H */
   
   #include "iperf.h"
 #include "iperf_util.h"  #include "iperf_util.h"
 #include "net.h"  #include "net.h"
 #include "timer.h"  #include "timer.h"
   
   static int nread_read_timeout = 10;
   static int nread_overall_timeout = 30;
   
 /*  /*
  * Declaration of gerror in iperf_error.c.  Most other files in iperf3 can get this   * Declaration of gerror in iperf_error.c.  Most other files in iperf3 can get this
  * by including "iperf.h", but net.c lives "below" this layer.  Clearly the   * by including "iperf.h", but net.c lives "below" this layer.  Clearly the
Line 119  timeout_connect(int s, const struct sockaddr *name, so Line 122  timeout_connect(int s, const struct sockaddr *name, so
  * Copyright: http://swtch.com/libtask/COPYRIGHT   * Copyright: http://swtch.com/libtask/COPYRIGHT
 */  */
   
/* make connection to server *//* create a socket */
 int  int
netdial(int domain, int proto, const char *local, int local_port, const char *server, int port, int timeout)create_socket(int domain, int proto, const char *local, const char *bind_dev, int local_port, const char *server, int port, struct addrinfo **server_res_out)
 {  {
    struct addrinfo hints, *local_res, *server_res;    struct addrinfo hints, *local_res = NULL, *server_res = NULL;
     int s, saved_errno;      int s, saved_errno;
       char portstr[6];
   
     if (local) {      if (local) {
         memset(&hints, 0, sizeof(hints));          memset(&hints, 0, sizeof(hints));
Line 137  netdial(int domain, int proto, const char *local, int  Line 141  netdial(int domain, int proto, const char *local, int 
     memset(&hints, 0, sizeof(hints));      memset(&hints, 0, sizeof(hints));
     hints.ai_family = domain;      hints.ai_family = domain;
     hints.ai_socktype = proto;      hints.ai_socktype = proto;
    if ((gerror = getaddrinfo(server, NULL, &hints, &server_res)) != 0)    snprintf(portstr, sizeof(portstr), "%d", port);
     if ((gerror = getaddrinfo(server, portstr, &hints, &server_res)) != 0) {
         if (local)
             freeaddrinfo(local_res);
         return -1;          return -1;
       }
   
     s = socket(server_res->ai_family, proto, 0);      s = socket(server_res->ai_family, proto, 0);
     if (s < 0) {      if (s < 0) {
Line 148  netdial(int domain, int proto, const char *local, int  Line 156  netdial(int domain, int proto, const char *local, int 
         return -1;          return -1;
     }      }
   
       if (bind_dev) {
   #if defined(HAVE_SO_BINDTODEVICE)
           if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
                          bind_dev, IFNAMSIZ) < 0)
   #endif // HAVE_SO_BINDTODEVICE
           {
               saved_errno = errno;
               close(s);
               freeaddrinfo(local_res);
               freeaddrinfo(server_res);
               errno = saved_errno;
               return -1;
           }
       }
   
     /* Bind the local address if given a name (with or without --cport) */      /* Bind the local address if given a name (with or without --cport) */
     if (local) {      if (local) {
         if (local_port) {          if (local_port) {
Line 189  netdial(int domain, int proto, const char *local, int  Line 212  netdial(int domain, int proto, const char *local, int 
         }          }
         /* Unknown protocol */          /* Unknown protocol */
         else {          else {
               close(s);
               freeaddrinfo(server_res);
             errno = EAFNOSUPPORT;              errno = EAFNOSUPPORT;
             return -1;              return -1;
         }          }
Line 202  netdial(int domain, int proto, const char *local, int  Line 227  netdial(int domain, int proto, const char *local, int 
         }          }
     }      }
   
    ((struct sockaddr_in *) server_res->ai_addr)->sin_port = htons(port);    *server_res_out = server_res;
     return s;
 }
 
 /* make connection to server */
 int
 netdial(int domain, int proto, const char *local, const char *bind_dev, int local_port, const char *server, int port, int timeout)
 {
     struct addrinfo *server_res = NULL;
     int s, saved_errno;
 
     s = create_socket(domain, proto, local, bind_dev, local_port, server, port, &server_res);
     if (s < 0) {
       return -1;
     }
 
     if (timeout_connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen, timeout) < 0 && errno != EINPROGRESS) {      if (timeout_connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen, timeout) < 0 && errno != EINPROGRESS) {
         saved_errno = errno;          saved_errno = errno;
         close(s);          close(s);
Line 218  netdial(int domain, int proto, const char *local, int  Line 258  netdial(int domain, int proto, const char *local, int 
 /***************************************************************/  /***************************************************************/
   
 int  int
netannounce(int domain, int proto, const char *local, int port)netannounce(int domain, int proto, const char *local, const char *bind_dev, int port)
 {  {
     struct addrinfo hints, *res;      struct addrinfo hints, *res;
     char portstr[6];      char portstr[6];
Line 226  netannounce(int domain, int proto, const char *local,  Line 266  netannounce(int domain, int proto, const char *local, 
   
     snprintf(portstr, 6, "%d", port);      snprintf(portstr, 6, "%d", port);
     memset(&hints, 0, sizeof(hints));      memset(&hints, 0, sizeof(hints));
    /*     /*
      * If binding to the wildcard address with no explicit address       * If binding to the wildcard address with no explicit address
      * family specified, then force us to get an AF_INET6 socket.  On       * family specified, then force us to get an AF_INET6 socket.  On
      * CentOS 6 and MacOS, getaddrinfo(3) with AF_UNSPEC in ai_family,       * CentOS 6 and MacOS, getaddrinfo(3) with AF_UNSPEC in ai_family,
Line 247  netannounce(int domain, int proto, const char *local,  Line 287  netannounce(int domain, int proto, const char *local, 
     hints.ai_socktype = proto;      hints.ai_socktype = proto;
     hints.ai_flags = AI_PASSIVE;      hints.ai_flags = AI_PASSIVE;
     if ((gerror = getaddrinfo(local, portstr, &hints, &res)) != 0)      if ((gerror = getaddrinfo(local, portstr, &hints, &res)) != 0)
        return -1;         return -1;
   
     s = socket(res->ai_family, proto, 0);      s = socket(res->ai_family, proto, 0);
     if (s < 0) {      if (s < 0) {
Line 255  netannounce(int domain, int proto, const char *local,  Line 295  netannounce(int domain, int proto, const char *local, 
         return -1;          return -1;
     }      }
   
       if (bind_dev) {
   #if defined(HAVE_SO_BINDTODEVICE)
           if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
                          bind_dev, IFNAMSIZ) < 0)
   #endif // HAVE_SO_BINDTODEVICE
           {
               saved_errno = errno;
               close(s);
               freeaddrinfo(res);
               errno = saved_errno;
               return -1;
           }
       }
   
     opt = 1;      opt = 1;
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,     if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
                    (char *) &opt, sizeof(opt)) < 0) {                     (char *) &opt, sizeof(opt)) < 0) {
         saved_errno = errno;          saved_errno = errno;
         close(s);          close(s);
Line 278  netannounce(int domain, int proto, const char *local,  Line 332  netannounce(int domain, int proto, const char *local, 
             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 298  netannounce(int domain, int proto, const char *local,  Line 352  netannounce(int domain, int proto, const char *local, 
     }      }
   
     freeaddrinfo(res);      freeaddrinfo(res);
    
     if (proto == SOCK_STREAM) {      if (proto == SOCK_STREAM) {
         if (listen(s, INT_MAX) < 0) {          if (listen(s, INT_MAX) < 0) {
             saved_errno = errno;              saved_errno = errno;
Line 321  Nread(int fd, char *buf, size_t count, int prot) Line 375  Nread(int fd, char *buf, size_t count, int prot)
 {  {
     register ssize_t r;      register ssize_t r;
     register size_t nleft = count;      register size_t nleft = count;
       struct iperf_time ftimeout = { 0, 0 };
   
       fd_set rfdset;
       struct timeval timeout = { nread_read_timeout, 0 };
   
       /*
        * fd might not be ready for reading on entry. Check for this
        * (with timeout) first.
        *
        * This check could go inside the while() loop below, except we're
        * currently considering whether it might make sense to support a
        * codepath that bypassese this check, for situations where we
        * already know that fd has data on it (for example if we'd gotten
        * to here as the result of a select() call.
        */
       {
           FD_ZERO(&rfdset);
           FD_SET(fd, &rfdset);
           r = select(fd + 1, &rfdset, NULL, NULL, &timeout);
           if (r < 0) {
               return NET_HARDERROR;
           }
           if (r == 0) {
               return 0;
           }
       }
   
     while (nleft > 0) {      while (nleft > 0) {
         r = read(fd, buf, nleft);          r = read(fd, buf, nleft);
         if (r < 0) {          if (r < 0) {
Line 334  Nread(int fd, char *buf, size_t count, int prot) Line 414  Nread(int fd, char *buf, size_t count, int prot)
   
         nleft -= r;          nleft -= r;
         buf += r;          buf += r;
   
           /*
            * We need some more bytes but don't want to wait around
            * forever for them. In the case of partial results, we need
            * to be able to read some bytes every nread_timeout seconds.
            */
           if (nleft > 0) {
               struct iperf_time now;
   
               /*
                * Also, we have an approximate upper limit for the total time
                * that a Nread call is supposed to take. We trade off accuracy
                * of this timeout for a hopefully lower performance impact.
                */
               iperf_time_now(&now);
               if (ftimeout.secs == 0) {
                   ftimeout = now;
                   iperf_time_add_usecs(&ftimeout, nread_overall_timeout * 1000000L);
               }
               if (iperf_time_compare(&ftimeout, &now) < 0) {
                   break;
               }
   
               FD_ZERO(&rfdset);
               FD_SET(fd, &rfdset);
               r = select(fd + 1, &rfdset, NULL, NULL, &timeout);
               if (r < 0) {
                   return NET_HARDERROR;
               }
               if (r == 0) {
                   break;
               }
           }
     }      }
     return count - nleft;      return count - nleft;
 }  }
Line 394  has_sendfile(void) Line 507  has_sendfile(void)
 int  int
 Nsendfile(int fromfd, int tofd, const char *buf, size_t count)  Nsendfile(int fromfd, int tofd, const char *buf, size_t count)
 {  {
     off_t offset;  
 #if defined(HAVE_SENDFILE)  #if defined(HAVE_SENDFILE)
       off_t offset;
 #if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_6))  #if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_6))
     off_t sent;      off_t sent;
 #endif  #endif

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


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