diff options
Diffstat (limited to 'src/tools/oping')
| -rw-r--r-- | src/tools/oping/CMakeLists.txt | 28 | ||||
| -rw-r--r-- | src/tools/oping/oping.c | 15 | ||||
| -rw-r--r-- | src/tools/oping/oping_client.c | 151 | ||||
| -rw-r--r-- | src/tools/oping/oping_server.c | 20 |
4 files changed, 138 insertions, 76 deletions
diff --git a/src/tools/oping/CMakeLists.txt b/src/tools/oping/CMakeLists.txt deleted file mode 100644 index 31a4f961..00000000 --- a/src/tools/oping/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -get_filename_component(CURRENT_SOURCE_PARENT_DIR - ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) - -include_directories(${CURRENT_SOURCE_PARENT_DIR}) - -find_library(LIBM_LIBRARIES m) -if(NOT LIBM_LIBRARIES) - message(FATAL_ERROR "libm not found") -endif() - -mark_as_advanced(LIBM_LIBRARIES) - -set(SOURCE_FILES - # Add source files here - oping.c - ) - -add_executable(oping ${SOURCE_FILES}) - -target_link_libraries(oping LINK_PUBLIC ${LIBM_LIBRARIES} ouroboros-dev) - -install(TARGETS oping RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c index ed3529e5..47b86c68 100644 --- a/src/tools/oping/oping.c +++ b/src/tools/oping/oping.c @@ -75,12 +75,14 @@ "\n" \ " -c, --count Number of packets\n" \ " -d, --duration Duration of the test (default 1s)\n" \ +" -f, --flood Send back-to-back without waiting\n" \ " -i, --interval Interval (default 1000ms)\n" \ " -n, --server-name Name of the oping server\n" \ -" -q, --qos QoS (raw, raw_crypt, best, video, voice, data)\n" \ +" -q, --qos QoS (raw, best, video, voice, data)\n" \ " -s, --size Payload size (B, default 64)\n" \ " -Q, --quiet Only print final statistics\n" \ " -D, --timeofday Print time of day before each line\n" \ +" --poll Server uses polling (lower latency)\n" \ "\n" \ " --help Display this help text and exit\n" \ @@ -90,6 +92,7 @@ struct { uint32_t count; int size; bool timestamp; + bool flood; qosspec_t qs; /* stats */ @@ -114,6 +117,7 @@ struct { pthread_mutex_t lock; bool quiet; + bool poll; pthread_t cleaner_pt; pthread_t accept_pt; @@ -172,9 +176,11 @@ int main(int argc, client.size = 64; client.count = INT_MAX; client.timestamp = false; + client.flood = false; client.qs = qos_raw; client.quiet = false; server.quiet = false; + server.poll = false; while (argc > 0) { if ((strcmp(*argv, "-i") == 0 || @@ -212,6 +218,9 @@ int main(int argc, } else if (strcmp(*argv, "-l") == 0 || strcmp(*argv, "--listen") == 0) { serv = true; + } else if (strcmp(*argv, "-f") == 0 || + strcmp(*argv, "--flood") == 0) { + client.flood = true; } else if (strcmp(*argv, "-D") == 0 || strcmp(*argv, "--timeofday") == 0) { client.timestamp = true; @@ -219,6 +228,8 @@ int main(int argc, strcmp(*argv, "--quiet") == 0) { client.quiet = true; server.quiet = true; + } else if (strcmp(*argv, "--poll") == 0) { + server.poll = true; } else { goto fail; } @@ -244,8 +255,6 @@ int main(int argc, client.qs = qos_voice; else if (strcmp(qos, "data") == 0) client.qs = qos_data; - else if (strcmp(qos, "raw_crypt") == 0) - client.qs = qos_raw_crypt; else printf("Unknown QoS cube, defaulting to raw.\n"); } diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index 7b03c83d..1513eac8 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -53,6 +53,20 @@ void shutdown_client(int signo, siginfo_t * info, void * c) } } +static void update_rtt_stats(double ms) +{ + double d; + + if (ms < client.rtt_min) + client.rtt_min = ms; + if (ms > client.rtt_max) + client.rtt_max = ms; + + d = (ms - client.rtt_avg); + client.rtt_avg += d / client.rcvd; + client.rtt_m2 += d * (ms - client.rtt_avg); +} + void * reader(void * o) { struct timespec timeout = {client.interval / 1000 + 2, 0}; @@ -64,7 +78,6 @@ void * reader(void * o) int fd = *((int *) o); int msg_len = 0; double ms = 0; - double d = 0; uint32_t exp_id = 0; fccntl(fd, FLOWSRCVTIMEO, &timeout); @@ -100,7 +113,7 @@ void * reader(void * o) sent.tv_sec = msg->tv_sec; sent.tv_nsec = msg->tv_nsec; - ms = ts_diff_us(&sent, &now) / 1000.0; + ms = ts_diff_us(&now, &sent) / 1000.0; if (id < exp_id) ++client.ooo; @@ -122,14 +135,7 @@ void * reader(void * o) id < exp_id ? " [out-of-order]" : ""); } - if (ms < client.rtt_min) - client.rtt_min = ms; - if (ms > client.rtt_max) - client.rtt_max = ms; - - d = (ms - client.rtt_avg); - client.rtt_avg += d / client.rcvd; - client.rtt_m2 += d * (ms - client.rtt_avg); + update_rtt_stats(ms); if (id >= exp_id) exp_id = id + 1; @@ -204,13 +210,103 @@ static void client_fini(void) return; } +static void print_stats(struct timespec * tic, + struct timespec * toc) +{ + printf("\n"); + printf("--- %s ping statistics ---\n", client.s_apn); + printf("%d packets transmitted, ", client.sent); + printf("%d received, ", client.rcvd); + printf("%zd out-of-order, ", client.ooo); + printf("%.0lf%% packet loss, ", client.sent == 0 ? 0 : + ceil(100 - (100 * (client.rcvd / (float) client.sent)))); + printf("time: %.3f ms\n", ts_diff_us(toc, tic) / 1000.0); + + if (client.rcvd > 0) { + printf("rtt min/avg/max/mdev = %.3f/%.3f/%.3f/", + client.rtt_min, + client.rtt_avg, + client.rtt_max); + if (client.rcvd > 1) + printf("%.3f ms\n", + sqrt(client.rtt_m2 / (client.rcvd - 1))); + else + printf("NaN ms\n"); + } +} + +static int flood_ping(int fd) +{ + char buf[OPING_BUF_SIZE]; + struct oping_msg * msg = (struct oping_msg *) buf; + struct timespec sent; + struct timespec rcvd; + double ms; + + memset(buf, 0, client.size); + + if (!client.quiet) + printf("Pinging %s with %d bytes of data (%u packets):\n\n", + client.s_apn, client.size, client.count); + + while (!stop && client.sent < client.count) { + clock_gettime(CLOCK_MONOTONIC, &sent); + + msg->type = htonl(ECHO_REQUEST); + msg->id = htonl(client.sent); + msg->tv_sec = sent.tv_sec; + msg->tv_nsec = sent.tv_nsec; + + if (flow_write(fd, buf, client.size) < 0) { + printf("Failed to send packet.\n"); + break; + } + + ++client.sent; + + if (flow_read(fd, buf, OPING_BUF_SIZE) < 0) { + printf("Failed to read packet.\n"); + break; + } + + clock_gettime(CLOCK_MONOTONIC, &rcvd); + + if (ntohl(msg->type) != ECHO_REPLY) + continue; + + ++client.rcvd; + + sent.tv_sec = msg->tv_sec; + sent.tv_nsec = msg->tv_nsec; + ms = ts_diff_us(&rcvd, &sent) / 1000.0; + + update_rtt_stats(ms); + + if (!client.quiet) + printf("%d bytes from %s: seq=%d time=%.3f ms\n", + client.size, client.s_apn, + ntohl(msg->id), ms); + } + + return 0; +} + +static int threaded_ping(int fd) +{ + pthread_create(&client.reader_pt, NULL, reader, &fd); + pthread_create(&client.writer_pt, NULL, writer, &fd); + + pthread_join(client.writer_pt, NULL); + pthread_join(client.reader_pt, NULL); + + return 0; +} + static int client_main(void) { struct sigaction sig_act; - struct timespec tic; struct timespec toc; - int fd; memset(&sig_act, 0, sizeof sig_act); @@ -241,37 +337,16 @@ static int client_main(void) clock_gettime(CLOCK_REALTIME, &tic); - pthread_create(&client.reader_pt, NULL, reader, &fd); - pthread_create(&client.writer_pt, NULL, writer, &fd); - - pthread_join(client.writer_pt, NULL); - pthread_join(client.reader_pt, NULL); + if (client.flood) + flood_ping(fd); + else + threaded_ping(fd); clock_gettime(CLOCK_REALTIME, &toc); - printf("\n"); - printf("--- %s ping statistics ---\n", client.s_apn); - printf("%d packets transmitted, ", client.sent); - printf("%d received, ", client.rcvd); - printf("%zd out-of-order, ", client.ooo); - printf("%.0lf%% packet loss, ", client.sent == 0 ? 0 : - ceil(100 - (100 * (client.rcvd / (float) client.sent)))); - printf("time: %.3f ms\n", ts_diff_us(&tic, &toc) / 1000.0); - - if (client.rcvd > 0) { - printf("rtt min/avg/max/mdev = %.3f/%.3f/%.3f/", - client.rtt_min, - client.rtt_avg, - client.rtt_max); - if (client.rcvd > 1) - printf("%.3f ms\n", - sqrt(client.rtt_m2 / (client.rcvd - 1))); - else - printf("NaN ms\n"); - } + print_stats(&tic, &toc); flow_dealloc(fd); - client_fini(); return 0; diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c index 6f76869c..13ab8f47 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -36,6 +36,8 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include <ouroboros/hash.h> + void shutdown_server(int signo, siginfo_t * info, void * c) { (void) info; @@ -67,7 +69,7 @@ void * cleaner_thread(void * o) time_t diff; pthread_mutex_lock(&server.lock); - diff = ts_diff_ms(&server.times[i], &now); + diff = ts_diff_ms(&now, &server.times[i]); pthread_mutex_unlock(&server.lock); if (diff > deadline_ms) { @@ -87,12 +89,15 @@ void * server_thread(void *o) struct oping_msg * msg = (struct oping_msg *) buf; struct timespec now = {0, 0}; struct timespec timeout = {0, 100 * MILLION}; + struct timespec poll_timeout = {0, 0}; int fd; (void) o; while (true) { - if (fevent(server.flows, server.fq, &timeout) == -ETIMEDOUT) + if (fevent(server.flows, server.fq, + server.poll ? &poll_timeout : &timeout) + == -ETIMEDOUT) continue; while ((fd = fqueue_next(server.fq)) >= 0) { @@ -100,14 +105,15 @@ void * server_thread(void *o) if (msg_len < 0) continue; + if (!server.quiet) + printf("Received %d bytes on fd %d.\n", + msg_len, fd); + if (ntohl(msg->type) != ECHO_REQUEST) { printf("Invalid message on fd %d.\n", fd); continue; } - if (!server.quiet) - printf("Received %d bytes on fd %d.\n", msg_len, fd); - clock_gettime(CLOCK_REALTIME, &now); pthread_mutex_lock(&server.lock); @@ -137,8 +143,8 @@ void * accept_thread(void * o) while (true) { fd = flow_accept(&qs, NULL); if (fd < 0) { - printf("Failed to accept flow.\n"); - break; + printf("Failed to accept flow: %d \n", fd); + continue; } printf("New flow %d.\n", fd); |
