Add --repeating-payload option to the client side (#726)

This option simulates payload in iperf2, which is just repetitive pattern
(ASCII '0..9' repeating), as opposed to iperf3 where payload is random.
It might help in testing and reveal problems in networking gear with hardware
compression (including WiFi access points), where iperf2 and iperf3 perform
differently, just based on payload entropy.
diff --git a/src/iperf.h b/src/iperf.h
index f55994f..8469083 100755
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -273,6 +273,7 @@
     int	      udp_counters_64bit;		/* --use-64-bit-udp-counters */
     int       forceflush; /* --forceflush - flushing output at every interval */
     int	      multisend;
+    int	      repeating_payload;                /* --repeating-payload */
 
     char     *json_output_string; /* rendered JSON output if json_output is set */
     /* Select related parameters */
diff --git a/src/iperf3.1 b/src/iperf3.1
index 639d5a4..601ffca 100644
--- a/src/iperf3.1
+++ b/src/iperf3.1
@@ -350,6 +350,13 @@
 in a JSON object; otherwise it is appended at the bottom of the
 human-readable output.
 .TP
+.BR --repeating-payload
+Use repeating pattern in payload, instead of random bytes.
+The same payload is used in iperf2 (ASCII '0..9' repeating).
+It might help to test and reveal problems in networking gear with hardware
+compression (including some WiFi access points), where iperf2 and iperf3
+perform differently, just based on payload entropy.
+.TP
 .BR --username " \fIusername\fR" 
 username to use for authentication to the iperf server (if built with
 OpenSSL support).
diff --git a/src/iperf_api.c b/src/iperf_api.c
index 38d4f6b..92252e6 100755
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -673,6 +673,7 @@
         {"zerocopy", no_argument, NULL, 'Z'},
         {"omit", required_argument, NULL, 'O'},
         {"file", required_argument, NULL, 'F'},
+        {"repeating-payload", no_argument, NULL, OPT_REPEATING_PAYLOAD},
 #if defined(HAVE_CPU_AFFINITY)
         {"affinity", required_argument, NULL, 'A'},
 #endif /* HAVE_CPU_AFFINITY */
@@ -951,6 +952,10 @@
                 test->zerocopy = 1;
 		client_flag = 1;
                 break;
+            case OPT_REPEATING_PAYLOAD:
+                test->repeating_payload = 1;
+                client_flag = 1;
+                break;
             case 'O':
                 test->omit = atoi(optarg);
                 if (test->omit < 0 || test->omit > 60) {
@@ -3175,7 +3180,8 @@
 iperf_new_stream(struct iperf_test *test, int s)
 {
     struct iperf_stream *sp;
-    
+    int ret = 0;
+
     char template[1024];
     if (test->tmp_template) {
         snprintf(template, sizeof(template) / sizeof(char), "%s", test->tmp_template);
@@ -3265,8 +3271,12 @@
         sp->diskfile_fd = -1;
 
     /* Initialize stream */
-    if ((readentropy(sp->buffer, test->settings->blksize) < 0) ||
-        (iperf_init_stream(sp, test) < 0)) {
+    if (test->repeating_payload)
+        fill_with_repeating_pattern(sp->buffer, test->settings->blksize);
+    else
+        ret = readentropy(sp->buffer, test->settings->blksize);
+
+    if ((ret < 0) || (iperf_init_stream(sp, test) < 0)) {
         close(sp->buffer_fd);
         munmap(sp->buffer, sp->test->settings->blksize);
         free(sp->result);
diff --git a/src/iperf_api.h b/src/iperf_api.h
index ddd002b..7ebeb3c 100755
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -68,6 +68,7 @@
 #define OPT_SERVER_AUTHORIZED_USERS 15
 #define OPT_PACING_TIMER 16
 #define OPT_CONNECT_TIMEOUT 17
+#define OPT_REPEATING_PAYLOAD 18
 
 /* states */
 #define TEST_START 1
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
index b0d8a96..2f31f13 100644
--- a/src/iperf_locale.c
+++ b/src/iperf_locale.c
@@ -171,6 +171,8 @@
                            "  -T, --title str           prefix every output line with this string\n"
                            "  --get-server-output       get results from server\n"
                            "  --udp-counters-64bit      use 64-bit counters in UDP test packets\n"
+                           "  --repeating-payload       use repeating pattern in payload, instead of\n"
+                           "                            randomized payload (like in iperf2)\n"
 #if defined(HAVE_SSL)
                            "  --username                username for authentication\n"
                            "  --rsa-public-key-path     path to the RSA public key used to encrypt\n"
diff --git a/src/iperf_util.c b/src/iperf_util.c
index 22ff43a..3922def 100644
--- a/src/iperf_util.c
+++ b/src/iperf_util.c
@@ -79,6 +79,27 @@
 }
 
 
+/*
+ * Fills buffer with repeating pattern (similar to pattern that used in iperf2)
+ */
+void fill_with_repeating_pattern(void *out, size_t outsize)
+{
+    size_t i;
+    int counter = 0;
+    char *buf = (char *)out;
+
+    if (!outsize) return;
+
+    for (i = 0; i < outsize; i++) {
+        buf[i] = (char)('0' + counter);
+        if (counter >= 9)
+            counter = 0;
+        else
+            counter++;
+    }
+}
+
+
 /* make_cookie
  *
  * Generate and return a cookie string
diff --git a/src/iperf_util.h b/src/iperf_util.h
index ee1d58c..76bfd20 100644
--- a/src/iperf_util.h
+++ b/src/iperf_util.h
@@ -34,6 +34,8 @@
 
 int readentropy(void *out, size_t outsize);
 
+void fill_with_repeating_pattern(void *out, size_t outsize);
+
 void make_cookie(char *);
 
 int is_closed(int);