]> git.ipfire.org Git - fireperf.git/commitdiff
client: Implement duplex mode
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 18 Feb 2021 16:21:18 +0000 (16:21 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 18 Feb 2021 16:21:18 +0000 (16:21 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
man/fireperf.txt
src/client.c
src/main.c
src/main.h
src/server.c

index db54638b7fd98b3dcca2f6552a9067627875c96d..fa100f042a115be70dc4a047fa8f2c28fe40bd6b 100644 (file)
@@ -68,6 +68,11 @@ a network between a fireperf client and fireperf server.
        This starts the program in client mode. In this mode, the client will connect to
        the server at ADDRESS and start a throughput test.
 
+--duplex::
+-D::
+       Duplex mode enables the client to send data instead of only receiving it from the
+       server. The same TCP connection will be used for traffic in both directions.
+
 --keepalive::
 -k::
        Instead of sending data to the server, this will configure the client to only
index 1354c3ff983b04f687b653738d2fe7348d9f297d..48b377a44af8dd55263af676038061c8e061db56 100644 (file)
@@ -165,6 +165,10 @@ int fireperf_client(struct fireperf_config* conf, struct fireperf_stats* stats,
        if (!conf->keepalive_only)
                ev.events |= EPOLLIN;
 
+       // In duplex mode, we send data, too
+       if (conf->duplex)
+               ev.events |= EPOLLOUT;
+
        DEBUG(conf, "Opening %lu connections...\n", conf->parallel);
 
        // Configure timeout if set
index b6a551de3407a6eaca04540cfe29f929c773055a..7e00baa638a1177bad8e45d2675324f97dc5cf4f 100644 (file)
@@ -128,6 +128,7 @@ static int parse_argv(int argc, char* argv[], struct fireperf_config* conf) {
                {"client",     required_argument, 0, 'c'},
                {"close",      no_argument,       0, 'x'},
                {"debug",      no_argument,       0, 'd'},
+               {"duplex",     no_argument,       0, 'D'},
                {"keepalive",  no_argument,       0, 'k'},
                {"parallel",   required_argument, 0, 'P'},
                {"port",       required_argument, 0, 'p'},
@@ -142,7 +143,7 @@ static int parse_argv(int argc, char* argv[], struct fireperf_config* conf) {
        int done = 0;
 
        while (!done) {
-               int c = getopt_long(argc, argv, "c:dkp:st:xzP:V", long_options, &option_index);
+               int c = getopt_long(argc, argv, "c:dkp:st:xzDP:V", long_options, &option_index);
 
                // End
                if (c == -1)
@@ -187,6 +188,10 @@ static int parse_argv(int argc, char* argv[], struct fireperf_config* conf) {
                                }
                                break;
 
+                       case 'D':
+                               conf->duplex = 1;
+                               break;
+
                        case 'd':
                                conf->loglevel = LOG_DEBUG;
                                break;
@@ -386,18 +391,22 @@ int fireperf_dump_stats(struct fireperf_config* conf, struct fireperf_stats* sta
                free(bps);
        }
 
-       // Total bytes sent/received
-       char* total_bytes = NULL;
-       switch (mode) {
-               case FIREPERF_MODE_CLIENT:
-                       total_bytes = format_size(stats->total_bytes_received, FIREPERF_FORMAT_BYTES);
-                       INFO(conf, "  %-20s: %20s\n", "Total Bytes Received", total_bytes);
-                       break;
+       struct total_bytes {
+               const char* label;
+               size_t bytes;
+       } totals[] = {
+               { "Total Bytes Received", stats->total_bytes_received, },
+               { "Total Bytes Sent", stats->total_bytes_sent, },
+               { NULL },
+       };
 
-               case FIREPERF_MODE_SERVER:
-                       total_bytes = format_size(stats->total_bytes_sent, FIREPERF_FORMAT_BYTES);
-                       INFO(conf, "  %-20s: %20s\n", "Total Bytes Sent", total_bytes);
-                       break;
+       for (struct total_bytes* total = totals; total->label; total++) {
+               if (!total->bytes)
+                       continue;
+
+               char* s = format_size(total->bytes, FIREPERF_FORMAT_BYTES);
+               INFO(conf, "  %-20s: %20s\n", total->label, s);
+               free(s);
        }
 
        // Remember when this was printed last
@@ -408,10 +417,6 @@ int fireperf_dump_stats(struct fireperf_config* conf, struct fireperf_stats* sta
        stats->bytes_received = 0;
        stats->bytes_sent = 0;
 
-       // Cleanup
-       if (total_bytes)
-               free(total_bytes);
-
        return 0;
 }
 
index 7f741042f1669cef78760b66c4ea7b1c4b98b0f6..738516fbfbe8ad0b3dff32324737001d8407fac3 100644 (file)
@@ -54,6 +54,7 @@ struct fireperf_config {
                FIREPERF_MODE_SERVER,
        } mode;
        struct in6_addr address;
+       int duplex;
        int keepalive_only;
        int keepalive_count;
        int keepalive_interval;
index b090b135506701bf2cfbb286a8418206af004d25..52a09a69f342c586e6863d61d740de539b665ca7 100644 (file)
@@ -171,7 +171,7 @@ int fireperf_server(struct fireperf_config* conf, struct fireperf_stats* stats,
                                        goto ERROR;
 
                                // Add the new socket to epoll()
-                               ev.events  = EPOLLOUT|EPOLLRDHUP;
+                               ev.events  = EPOLLIN|EPOLLOUT|EPOLLRDHUP;
                                ev.data.fd = connfd;
 
                                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &ev)) {