Diff for /embedaddon/iperf/src/iperf_udp.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-2020, 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 123  iperf_udp_recv(struct iperf_stream *sp) Line 123  iperf_udp_recv(struct iperf_stream *sp)
             sent_time.usecs = usec;              sent_time.usecs = usec;
         }          }
   
        if (sp->test->debug)        if (sp->test->debug_level >= DEBUG_LEVEL_DEBUG)
            fprintf(stderr, "pcount %" PRIu64 " packet_count %d\n", pcount, sp->packet_count);            fprintf(stderr, "pcount %" PRIu64 " packet_count %" PRIu64 "\n", pcount, sp->packet_count);
   
         /*          /*
          * Try to handle out of order packets.  The way we do this           * Try to handle out of order packets.  The way we do this
Line 150  iperf_udp_recv(struct iperf_stream *sp) Line 150  iperf_udp_recv(struct iperf_stream *sp)
             sp->packet_count = pcount;              sp->packet_count = pcount;
         } else {          } else {
   
            /*             /*
              * Sequence number went backward (or was stationary?!?).               * Sequence number went backward (or was stationary?!?).
              * This counts as an out-of-order packet.               * This counts as an out-of-order packet.
              */               */
Line 164  iperf_udp_recv(struct iperf_stream *sp) Line 164  iperf_udp_recv(struct iperf_stream *sp)
              */               */
             if (sp->cnt_error > 0)              if (sp->cnt_error > 0)
                 sp->cnt_error--;                  sp->cnt_error--;
        
             /* Log the out-of-order packet */              /* Log the out-of-order packet */
            if (sp->test->debug)             if (sp->test->debug)
                fprintf(stderr, "OUT OF ORDER - incoming packet sequence %" PRIu64 " but expected sequence %d on stream %d", pcount, sp->packet_count + 1, sp->socket);                fprintf(stderr, "OUT OF ORDER - incoming packet sequence %" PRIu64 " but expected sequence %" PRIu64 " on stream %d", pcount, sp->packet_count + 1, sp->socket);
         }          }
   
         /*          /*
Line 228  iperf_udp_send(struct iperf_stream *sp) Line 228  iperf_udp_send(struct iperf_stream *sp)
         sec = htonl(before.secs);          sec = htonl(before.secs);
         usec = htonl(before.usecs);          usec = htonl(before.usecs);
         pcount = htobe64(sp->packet_count);          pcount = htobe64(sp->packet_count);
        
         memcpy(sp->buffer, &sec, sizeof(sec));          memcpy(sp->buffer, &sec, sizeof(sec));
         memcpy(sp->buffer+4, &usec, sizeof(usec));          memcpy(sp->buffer+4, &usec, sizeof(usec));
         memcpy(sp->buffer+8, &pcount, sizeof(pcount));          memcpy(sp->buffer+8, &pcount, sizeof(pcount));
        
     }      }
     else {      else {
   
Line 241  iperf_udp_send(struct iperf_stream *sp) Line 241  iperf_udp_send(struct iperf_stream *sp)
         sec = htonl(before.secs);          sec = htonl(before.secs);
         usec = htonl(before.usecs);          usec = htonl(before.usecs);
         pcount = htonl(sp->packet_count);          pcount = htonl(sp->packet_count);
        
         memcpy(sp->buffer, &sec, sizeof(sec));          memcpy(sp->buffer, &sec, sizeof(sec));
         memcpy(sp->buffer+4, &usec, sizeof(usec));          memcpy(sp->buffer+4, &usec, sizeof(usec));
         memcpy(sp->buffer+8, &pcount, sizeof(pcount));          memcpy(sp->buffer+8, &pcount, sizeof(pcount));
        
     }      }
   
     r = Nwrite(sp->socket, sp->buffer, size, Pudp);      r = Nwrite(sp->socket, sp->buffer, size, Pudp);
   
    if (r < 0)    if (r <= 0) {
        return r;        --sp->packet_count;     /* Don't count messages that no data was sent from them.
                                  * Allows "resending" a massage with the same numbering */
         if (r < 0) {
             if (r == NET_SOFTERROR && sp->test->debug_level >= DEBUG_LEVEL_INFO)
                 printf("UDP send failed on NET_SOFTERROR. errno=%s\n", strerror(errno));
             return 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, total %" PRIu64 "\n", r, sp->settings->blksize, sp->result->bytes_sent);
   
     return r;      return r;
Line 291  iperf_udp_buffercheck(struct iperf_test *test, int s) Line 298  iperf_udp_buffercheck(struct iperf_test *test, int s)
      */       */
     int opt;      int opt;
     socklen_t optlen;      socklen_t optlen;
    
     if ((opt = test->settings->socket_bufsize)) {      if ((opt = test->settings->socket_bufsize)) {
         if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {          if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
             i_errno = IESETBUF;              i_errno = IESETBUF;
Line 317  iperf_udp_buffercheck(struct iperf_test *test, int s) Line 324  iperf_udp_buffercheck(struct iperf_test *test, int s)
         return -1;          return -1;
     }      }
     if (test->settings->blksize > sndbuf_actual) {      if (test->settings->blksize > sndbuf_actual) {
        char str[80];        char str[WARN_STR_LEN];
         snprintf(str, sizeof(str),          snprintf(str, sizeof(str),
                  "Block size %d > sending socket buffer size %d",                   "Block size %d > sending socket buffer size %d",
                  test->settings->blksize, sndbuf_actual);                   test->settings->blksize, sndbuf_actual);
Line 339  iperf_udp_buffercheck(struct iperf_test *test, int s) Line 346  iperf_udp_buffercheck(struct iperf_test *test, int s)
         return -1;          return -1;
     }      }
     if (test->settings->blksize > rcvbuf_actual) {      if (test->settings->blksize > rcvbuf_actual) {
        char str[80];        char str[WARN_STR_LEN];
         snprintf(str, sizeof(str),          snprintf(str, sizeof(str),
                  "Block size %d > receiving socket buffer size %d",                   "Block size %d > receiving socket buffer size %d",
                  test->settings->blksize, rcvbuf_actual);                   test->settings->blksize, rcvbuf_actual);
Line 348  iperf_udp_buffercheck(struct iperf_test *test, int s) Line 355  iperf_udp_buffercheck(struct iperf_test *test, int s)
     }      }
   
     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);
     }      }
       }
   
     return rc;      return rc;
 }  }
Line 365  int Line 383  int
 iperf_udp_accept(struct iperf_test *test)  iperf_udp_accept(struct iperf_test *test)
 {  {
     struct sockaddr_storage sa_peer;      struct sockaddr_storage sa_peer;
    int       buf;    unsigned int buf;
     socklen_t len;      socklen_t len;
     int       sz, s;      int       sz, s;
     int       rc;      int       rc;
Line 403  iperf_udp_accept(struct iperf_test *test) Line 421  iperf_udp_accept(struct iperf_test *test)
      */       */
     if (rc > 0) {      if (rc > 0) {
         if (test->settings->socket_bufsize == 0) {          if (test->settings->socket_bufsize == 0) {
               char str[WARN_STR_LEN];
             int bufsize = test->settings->blksize + UDP_BUFFER_EXTRA;              int bufsize = test->settings->blksize + UDP_BUFFER_EXTRA;
            printf("Increasing socket buffer size to %d\n",            snprintf(str, sizeof(str), "Increasing socket buffer size to %d",
                bufsize);                     bufsize);
             warning(str);
             test->settings->socket_bufsize = bufsize;              test->settings->socket_bufsize = bufsize;
             rc = iperf_udp_buffercheck(test, s);              rc = iperf_udp_buffercheck(test, s);
             if (rc < 0)              if (rc < 0)
                 return rc;                  return rc;
         }          }
     }      }
        
 #if defined(HAVE_SO_MAX_PACING_RATE)  #if defined(HAVE_SO_MAX_PACING_RATE)
     /* If socket pacing is specified, try it. */      /* If socket pacing is specified, try it. */
     if (test->settings->fqrate) {      if (test->settings->fqrate) {
Line 440  iperf_udp_accept(struct iperf_test *test) Line 460  iperf_udp_accept(struct iperf_test *test)
     /*      /*
      * Create a new "listening" socket to replace the one we were using before.       * Create a new "listening" socket to replace the one we were using before.
      */       */
    test->prot_listener = netannounce(test->settings->domain, Pudp, test->bind_address, test->server_port);    test->prot_listener = netannounce(test->settings->domain, Pudp, test->bind_address, test->bind_dev, test->server_port);
     if (test->prot_listener < 0) {      if (test->prot_listener < 0) {
         i_errno = IESTREAMLISTEN;          i_errno = IESTREAMLISTEN;
         return -1;          return -1;
Line 450  iperf_udp_accept(struct iperf_test *test) Line 470  iperf_udp_accept(struct iperf_test *test)
     test->max_fd = (test->max_fd < test->prot_listener) ? test->prot_listener : test->max_fd;      test->max_fd = (test->max_fd < test->prot_listener) ? test->prot_listener : test->max_fd;
   
     /* Let the client know we're ready "accept" another UDP "stream" */      /* Let the client know we're ready "accept" another UDP "stream" */
    buf = 987654321;              /* any content will work here */    buf = UDP_CONNECT_REPLY;
     if (write(s, &buf, sizeof(buf)) < 0) {      if (write(s, &buf, sizeof(buf)) < 0) {
         i_errno = IESTREAMWRITE;          i_errno = IESTREAMWRITE;
         return -1;          return -1;
Line 472  iperf_udp_listen(struct iperf_test *test) Line 492  iperf_udp_listen(struct iperf_test *test)
 {  {
     int s;      int s;
   
    if ((s = netannounce(test->settings->domain, Pudp, test->bind_address, test->server_port)) < 0) {    if ((s = netannounce(test->settings->domain, Pudp, test->bind_address, test->bind_dev, test->server_port)) < 0) {
         i_errno = IESTREAMLISTEN;          i_errno = IESTREAMLISTEN;
         return -1;          return -1;
     }      }
Line 492  iperf_udp_listen(struct iperf_test *test) Line 512  iperf_udp_listen(struct iperf_test *test)
 int  int
 iperf_udp_connect(struct iperf_test *test)  iperf_udp_connect(struct iperf_test *test)
 {  {
    int s, buf, sz;    int s, sz;
     unsigned int buf;
 #ifdef SO_RCVTIMEO  #ifdef SO_RCVTIMEO
     struct timeval tv;      struct timeval tv;
 #endif  #endif
     int rc;      int rc;
       int i, max_len_wait_for_reply;
   
     /* Create and bind our local socket. */      /* Create and bind our local socket. */
    if ((s = netdial(test->settings->domain, Pudp, test->bind_address, test->bind_port, test->server_hostname, test->server_port, -1)) < 0) {    if ((s = netdial(test->settings->domain, Pudp, test->bind_address, test->bind_dev, test->bind_port, test->server_hostname, test->server_port, -1)) < 0) {
         i_errno = IESTREAMCONNECT;          i_errno = IESTREAMCONNECT;
         return -1;          return -1;
     }      }
Line 515  iperf_udp_connect(struct iperf_test *test) Line 537  iperf_udp_connect(struct iperf_test *test)
      */       */
     if (rc > 0) {      if (rc > 0) {
         if (test->settings->socket_bufsize == 0) {          if (test->settings->socket_bufsize == 0) {
               char str[WARN_STR_LEN];
             int bufsize = test->settings->blksize + UDP_BUFFER_EXTRA;              int bufsize = test->settings->blksize + UDP_BUFFER_EXTRA;
            printf("Increasing socket buffer size to %d\n",            snprintf(str, sizeof(str), "Increasing socket buffer size to %d",
                bufsize);                     bufsize);
             warning(str);
             test->settings->socket_bufsize = bufsize;              test->settings->socket_bufsize = bufsize;
             rc = iperf_udp_buffercheck(test, s);              rc = iperf_udp_buffercheck(test, s);
             if (rc < 0)              if (rc < 0)
                 return rc;                  return rc;
         }          }
     }      }
        
 #if defined(HAVE_SO_MAX_PACING_RATE)  #if defined(HAVE_SO_MAX_PACING_RATE)
     /* If socket pacing is available and not disabled, try it. */      /* If socket pacing is available and not disabled, try it. */
     if (test->settings->fqrate) {      if (test->settings->fqrate) {
Line 549  iperf_udp_connect(struct iperf_test *test) Line 573  iperf_udp_connect(struct iperf_test *test)
         }          }
     }      }
   
       /* Set common socket options */
       iperf_common_sockopts(test, s);
   
 #ifdef SO_RCVTIMEO  #ifdef SO_RCVTIMEO
     /* 30 sec timeout for a case when there is a network problem. */      /* 30 sec timeout for a case when there is a network problem. */
     tv.tv_sec = 30;      tv.tv_sec = 30;
Line 560  iperf_udp_connect(struct iperf_test *test) Line 587  iperf_udp_connect(struct iperf_test *test)
      * Write a datagram to the UDP stream to let the server know we're here.       * Write a datagram to the UDP stream to let the server know we're here.
      * The server learns our address by obtaining its peer's address.       * The server learns our address by obtaining its peer's address.
      */       */
    buf = 123456789;              /* this can be pretty much anything */    buf = UDP_CONNECT_MSG;
     if (test->debug) {
         printf("Sending Connect message to Socket %d\n", s);
     }
     if (write(s, &buf, sizeof(buf)) < 0) {      if (write(s, &buf, sizeof(buf)) < 0) {
        // XXX: Should this be changed to IESTREAMCONNECT?         // XXX: Should this be changed to IESTREAMCONNECT?
         i_errno = IESTREAMWRITE;          i_errno = IESTREAMWRITE;
         return -1;          return -1;
     }      }
   
     /*      /*
     * Wait until the server replies back to us.     * Wait until the server replies back to us with the "accept" response.
      */       */
    if ((sz = recv(s, &buf, sizeof(buf), 0)) < 0) {    i = 0;
     max_len_wait_for_reply = sizeof(buf);
     if (test->reverse) /* In reverse mode allow few packets to have the "accept" response - to handle out of order packets */
         max_len_wait_for_reply += MAX_REVERSE_OUT_OF_ORDER_PACKETS * test->settings->blksize;
     do {
         if ((sz = recv(s, &buf, sizeof(buf), 0)) < 0) {
             i_errno = IESTREAMREAD;
             return -1;
         }
         if (test->debug) {
             printf("Connect received for Socket %d, sz=%d, buf=%x, i=%d, max_len_wait_for_reply=%d\n", s, sz, buf, i, max_len_wait_for_reply);
         }
         i += sz;
     } while (buf != UDP_CONNECT_REPLY && buf != LEGACY_UDP_CONNECT_REPLY && i < max_len_wait_for_reply);
 
     if (buf != UDP_CONNECT_REPLY  && buf != LEGACY_UDP_CONNECT_REPLY) {
         i_errno = IESTREAMREAD;          i_errno = IESTREAMREAD;
         return -1;          return -1;
     }      }

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


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