aboutsummaryrefslogtreecommitdiff
path: root/src/iperf_udp.c
diff options
context:
space:
mode:
authorBruce A. Mah <bmah@es.net>2014-08-28 08:59:32 -0700
committerBruce A. Mah <bmah@es.net>2014-08-28 08:59:32 -0700
commit329523a5574bafe387241261c06919296d00a105 (patch)
treecc7b286c0326b2d5e6a50f1d9cd9af734cdd5a14 /src/iperf_udp.c
parentd30a2c8d04b2378ad3e47019e0db54a86a45d24e (diff)
downloadiperf3-329523a5574bafe387241261c06919296d00a105.tar.gz
Add a --udp-counters-64bit feature to support very long UDP tests.
UDP tests store a packet sequence number in the packets to detect loss and ordering issues. This sequence number is a 32-bit signed integer, which can wrap during very long-running UDP tests. This change adds an option (defaulting to off) which uses a 64-bit unsigned integer to store this quantity in the packet. The option is specified on the client side; the server must support this feature for proper functioning (older servers will interoperate with newer clients, as long as --udp-counters-64-bit is not used). The default might be changed in a future version of iperf3. As a part of this change, the client sends its version string to the server in the parameter block. Uses a public-domain compatibility shim for 64-bit byte order conversions. There are probably some additional platforms that need to be supported, in particular Solaris. We might add some configure-time checks to only enable this feature on platforms where we can support the byte-order conversions. This change is not well-tested. Towards issue #191.
Diffstat (limited to 'src/iperf_udp.c')
-rw-r--r--src/iperf_udp.c76
1 files changed, 57 insertions, 19 deletions
diff --git a/src/iperf_udp.c b/src/iperf_udp.c
index bc7a8f1..38d0cc7 100644
--- a/src/iperf_udp.c
+++ b/src/iperf_udp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2011, The Regents of the University of California,
+ * Copyright (c) 2009-2011, 2014, The Regents of the University of California,
* through Lawrence Berkeley National Laboratory (subject to receipt of any
* required approvals from the U.S. Dept. of Energy). All rights reserved.
*
@@ -28,7 +28,7 @@
#include "iperf_udp.h"
#include "timer.h"
#include "net.h"
-
+#include "portable_endian.h"
/* iperf_udp_recv
*
@@ -37,9 +37,10 @@
int
iperf_udp_recv(struct iperf_stream *sp)
{
+ uint32_t sec, usec;
+ uint64_t pcount;
int r;
int size = sp->settings->blksize;
- uint32_t sec, usec, pcount;
double transit = 0, d = 0;
struct timeval sent_time, arrival_time;
@@ -51,14 +52,27 @@ iperf_udp_recv(struct iperf_stream *sp)
sp->result->bytes_received += r;
sp->result->bytes_received_this_interval += r;
- memcpy(&sec, sp->buffer, sizeof(sec));
- memcpy(&usec, sp->buffer+4, sizeof(usec));
- memcpy(&pcount, sp->buffer+8, sizeof(pcount));
- sec = ntohl(sec);
- usec = ntohl(usec);
- pcount = ntohl(pcount);
- sent_time.tv_sec = sec;
- sent_time.tv_usec = usec;
+ if (sp->test->udp_counters_64bit) {
+ memcpy(&sec, sp->buffer, sizeof(sec));
+ memcpy(&usec, sp->buffer+4, sizeof(usec));
+ memcpy(&pcount, sp->buffer+8, sizeof(pcount));
+ sec = ntohl(sec);
+ usec = ntohl(usec);
+ pcount = be64toh(pcount);
+ sent_time.tv_sec = sec;
+ sent_time.tv_usec = usec;
+ }
+ else {
+ uint32_t pc;
+ memcpy(&sec, sp->buffer, sizeof(sec));
+ memcpy(&usec, sp->buffer+4, sizeof(usec));
+ memcpy(&pc, sp->buffer+8, sizeof(pc));
+ sec = ntohl(sec);
+ usec = ntohl(usec);
+ pcount = ntohl(pc);
+ sent_time.tv_sec = sec;
+ sent_time.tv_usec = usec;
+ }
/* Out of order packets */
if (pcount >= sp->packet_count + 1) {
@@ -68,7 +82,7 @@ iperf_udp_recv(struct iperf_stream *sp)
sp->packet_count = pcount;
} else {
sp->outoforder_packets++;
- iperf_err(sp->test, "OUT OF ORDER - incoming packet = %d and received packet = %d AND SP = %d", pcount, sp->packet_count, sp->socket);
+ iperf_err(sp->test, "OUT OF ORDER - incoming packet = %llu and received packet = %d AND SP = %d", pcount, sp->packet_count, sp->socket);
}
/* jitter measurement */
@@ -83,6 +97,10 @@ iperf_udp_recv(struct iperf_stream *sp)
// J = |(R1 - S1) - (R0 - S0)| [/ number of packets, for average]
sp->jitter += (d - sp->jitter) / 16.0;
+ if (sp->test->debug) {
+ fprintf(stderr, "packet_count %llu\n", sp->packet_count);
+ }
+
return r;
}
@@ -95,20 +113,40 @@ int
iperf_udp_send(struct iperf_stream *sp)
{
int r;
- uint32_t sec, usec, pcount;
int size = sp->settings->blksize;
struct timeval before;
gettimeofday(&before, 0);
++sp->packet_count;
- sec = htonl(before.tv_sec);
- usec = htonl(before.tv_usec);
- pcount = htonl(sp->packet_count);
- memcpy(sp->buffer, &sec, sizeof(sec));
- memcpy(sp->buffer+4, &usec, sizeof(usec));
- memcpy(sp->buffer+8, &pcount, sizeof(pcount));
+ if (sp->test->udp_counters_64bit) {
+
+ uint32_t sec, usec;
+ uint64_t pcount;
+
+ sec = htonl(before.tv_sec);
+ usec = htonl(before.tv_usec);
+ pcount = htobe64(sp->packet_count);
+
+ memcpy(sp->buffer, &sec, sizeof(sec));
+ memcpy(sp->buffer+4, &usec, sizeof(usec));
+ memcpy(sp->buffer+8, &pcount, sizeof(pcount));
+
+ }
+ else {
+
+ uint32_t sec, usec, pcount;
+
+ sec = htonl(before.tv_sec);
+ usec = htonl(before.tv_usec);
+ pcount = htonl(sp->packet_count);
+
+ memcpy(sp->buffer, &sec, sizeof(sec));
+ memcpy(sp->buffer+4, &usec, sizeof(usec));
+ memcpy(sp->buffer+8, &pcount, sizeof(pcount));
+
+ }
r = Nwrite(sp->socket, sp->buffer, size, Pudp);