diff options
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/CMakeLists.txt | 71 | ||||
| -rw-r--r-- | src/tools/oping/oping.c | 11 | ||||
| -rw-r--r-- | src/tools/oping/oping_client.c | 149 | ||||
| -rw-r--r-- | src/tools/oping/oping_server.c | 5 |
4 files changed, 198 insertions, 38 deletions
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 00000000..3cec8172 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,71 @@ +# Tools build configuration + +set(TOOLS_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include +) + +set(IRM_SOURCES + irm/irm.c + irm/irm_bind_program.c + irm/irm_bind_process.c + irm/irm_bind_ipcp.c + irm/irm_ipcp_create.c + irm/irm_ipcp_destroy.c + irm/irm_ipcp_bootstrap.c + irm/irm_ipcp_enroll.c + irm/irm_ipcp_list.c + irm/irm_ipcp_connect.c + irm/irm_ipcp_disconnect.c + irm/irm_unbind_program.c + irm/irm_unbind_process.c + irm/irm_unbind_ipcp.c + irm/irm_unbind.c + irm/irm_bind.c + irm/irm_ipcp.c + irm/irm_name.c + irm/irm_name_create.c + irm/irm_name_destroy.c + irm/irm_name_reg.c + irm/irm_name_unreg.c + irm/irm_name_list.c + irm/irm_utils.c +) + +add_executable(irm ${IRM_SOURCES}) +target_include_directories(irm PRIVATE ${TOOLS_INCLUDE_DIRS}) +target_link_libraries(irm PRIVATE ouroboros-irm) +install(TARGETS irm RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) + +add_executable(oping oping/oping.c) +target_include_directories(oping PRIVATE ${TOOLS_INCLUDE_DIRS}) +target_link_libraries(oping PRIVATE ${LIBM_LIBRARIES} ouroboros-dev) +install(TARGETS oping RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(oecho oecho/oecho.c) +target_include_directories(oecho PRIVATE ${TOOLS_INCLUDE_DIRS}) +target_link_libraries(oecho PRIVATE ouroboros-dev) +install(TARGETS oecho RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(ocbr ocbr/ocbr.c) +target_include_directories(ocbr PRIVATE ${TOOLS_INCLUDE_DIRS}) +target_link_libraries(ocbr PRIVATE ouroboros-dev) +install(TARGETS ocbr RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(obc obc/obc.c) +target_include_directories(obc PRIVATE ${TOOLS_INCLUDE_DIRS}) +target_link_libraries(obc PRIVATE ouroboros-dev) +install(TARGETS obc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(operf operf/operf.c) +target_include_directories(operf PRIVATE ${TOOLS_INCLUDE_DIRS}) +target_link_libraries(operf PRIVATE ouroboros-dev) +install(TARGETS operf RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + add_executable(ovpn ovpn/ovpn.c) + target_include_directories(ovpn PRIVATE ${TOOLS_INCLUDE_DIRS}) + target_link_libraries(ovpn PRIVATE ouroboros-dev) + install(TARGETS ovpn RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c index 87c1ee18..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, 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; } diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index 5a9e03dc..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); @@ -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(&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"); - } + 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 c1d5e6e5..13ab8f47 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -89,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) { |
