From 3b339909f6fc509df44f9c59da697136981fbec8 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 18 Feb 2021 16:21:18 +0000 Subject: [PATCH] client: Implement duplex mode Signed-off-by: Michael Tremer --- man/fireperf.txt | 5 +++++ src/client.c | 4 ++++ src/main.c | 37 +++++++++++++++++++++---------------- src/main.h | 1 + src/server.c | 2 +- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/man/fireperf.txt b/man/fireperf.txt index db54638..fa100f0 100644 --- a/man/fireperf.txt +++ b/man/fireperf.txt @@ -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 diff --git a/src/client.c b/src/client.c index 1354c3f..48b377a 100644 --- a/src/client.c +++ b/src/client.c @@ -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 diff --git a/src/main.c b/src/main.c index b6a551d..7e00baa 100644 --- a/src/main.c +++ b/src/main.c @@ -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; } diff --git a/src/main.h b/src/main.h index 7f74104..738516f 100644 --- a/src/main.h +++ b/src/main.h @@ -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; diff --git a/src/server.c b/src/server.c index b090b13..52a09a6 100644 --- a/src/server.c +++ b/src/server.c @@ -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)) { -- 2.47.2