diff options
Diffstat (limited to 'src/tools/oping')
| -rw-r--r-- | src/tools/oping/oping.c | 61 | ||||
| -rw-r--r-- | src/tools/oping/oping_client.c | 42 | ||||
| -rw-r--r-- | src/tools/oping/oping_server.c | 16 |
3 files changed, 74 insertions, 45 deletions
diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c index 763c0d62..10e1e23c 100644 --- a/src/tools/oping/oping.c +++ b/src/tools/oping/oping.c @@ -60,7 +60,7 @@ #include <errno.h> #include <float.h> -#define OPING_BUF_SIZE 1500 +#define OPING_BUF_SIZE 16384 #define ECHO_REQUEST 0 #define ECHO_REPLY 1 #define OPING_MAX_FLOWS 256 @@ -81,8 +81,9 @@ " -F, --flood-busy Flood with busy-polling (lower latency)\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" \ +" -q, --qos QoS (raw, safe, rt, rt-safe, msg)\n" \ " -s, --size Payload size (B, default 64)\n" \ +" -W, --timeout Per-packet recv timeout, ms (default 2000)\n" \ " -Q, --quiet Only print final statistics\n" \ " -D, --timeofday Print time of day before each line\n" \ "\n" \ @@ -93,9 +94,11 @@ struct { int interval; uint32_t count; int size; + int timeout; /* per-packet recv timeout, ms */ bool timestamp; bool flood; bool flood_busy; + long duration; qosspec_t qs; /* stats */ @@ -175,18 +178,20 @@ int main(int argc, argc--; argv++; - client.s_apn = NULL; - client.interval = 1000; - client.size = 64; - client.count = INT_MAX; - client.timestamp = false; - client.flood = false; + client.s_apn = NULL; + client.interval = 1000; + client.size = 64; + client.count = INT_MAX; + client.timeout = 2000; + client.timestamp = false; + client.flood = false; client.flood_busy = false; - client.qs = qos_raw; - client.quiet = false; - server.quiet = false; - server.poll = false; - server.busy = false; + client.duration = 0; + client.qs = qos_raw; + client.quiet = false; + server.quiet = false; + server.poll = false; + server.busy = false; while (argc > 0) { if ((strcmp(*argv, "-i") == 0 || @@ -216,6 +221,12 @@ int main(int argc, argc > 1) { client.size = strtol(*(++argv), &rem, 10); --argc; + } else if ((strcmp(*argv, "-W") == 0 || + strcmp(*argv, "--timeout") == 0) && + argc > 1) { + client.timeout = strtol(*(++argv), &rem, 10); + client.timeout *= time_mul(rem); + --argc; } else if ((strcmp(*argv, "-q") == 0 || strcmp(*argv, "--qos") == 0) && argc > 1) { @@ -249,23 +260,25 @@ int main(int argc, } if (duration > 0) { - if (client.interval == 0) + if (client.flood || client.flood_busy) + client.duration = duration; + else if (client.interval == 0) client.count = duration * 10; else client.count = duration / client.interval; } if (qos != NULL) { - if (strcmp(qos, "best") == 0) - client.qs = qos_best_effort; - else if (strcmp(qos, "raw") == 0) + if (strcmp(qos, "raw") == 0) client.qs = qos_raw; - else if (strcmp(qos, "video") == 0) - client.qs = qos_video; - else if (strcmp(qos, "voice") == 0) - client.qs = qos_voice; - else if (strcmp(qos, "data") == 0) - client.qs = qos_data; + else if (strcmp(qos, "safe") == 0) + client.qs = qos_raw_safe; + else if (strcmp(qos, "rt") == 0) + client.qs = qos_rt; + else if (strcmp(qos, "rt-safe") == 0) + client.qs = qos_rt_safe; + else if (strcmp(qos, "msg") == 0) + client.qs = qos_msg; else printf("Unknown QoS cube, defaulting to raw.\n"); } @@ -298,7 +311,7 @@ int main(int argc, if (ret < 0) exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + exit(ret); fail: usage(); diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index 23807f65..4b01315d 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -47,6 +47,7 @@ void shutdown_client(int signo, siginfo_t * info, void * c) case SIGINT: case SIGTERM: case SIGHUP: + case SIGALRM: stop = true; default: return; @@ -89,7 +90,7 @@ static void print_rtt(int len, int seq, void * reader(void * o) { - struct timespec timeout = {client.interval / 1000 + 2, 0}; + struct timespec timeout; struct timespec now = {0, 0}; struct timespec sent; @@ -100,6 +101,9 @@ void * reader(void * o) double ms = 0; uint32_t exp_id = 0; + timeout.tv_sec = client.timeout / 1000; + timeout.tv_nsec = (client.timeout % 1000) * MILLION; + fccntl(fd, FLOWSRCVTIMEO, &timeout); while (!stop && client.rcvd != client.count) { @@ -284,18 +288,15 @@ static int flood_busy_ping(int fd) 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"); + if (flow_write(fd, buf, client.size) < 0) { + printf("Failed to send packet.\n"); break; } ++client.sent; do { - n = flow_read(fd, buf, - OPING_BUF_SIZE); + n = flow_read(fd, buf, OPING_BUF_SIZE); } while (n == -EAGAIN && !stop); if (n < 0) @@ -315,9 +316,7 @@ static int flood_busy_ping(int fd) update_rtt_stats(ms); if (!client.quiet) - print_rtt(client.size, - ntohl(msg->id), ms, - NULL); + print_rtt(client.size, ntohl(msg->id), ms, NULL); } return 0; @@ -371,9 +370,7 @@ static int flood_ping(int fd) update_rtt_stats(ms); if (!client.quiet) - print_rtt(client.size, - ntohl(msg->id), ms, - NULL); + print_rtt(client.size, ntohl(msg->id), ms, NULL); } return 0; @@ -404,25 +401,34 @@ static int client_main(void) if (sigaction(SIGINT, &sig_act, NULL) || sigaction(SIGTERM, &sig_act, NULL) || sigaction(SIGHUP, &sig_act, NULL) || - sigaction(SIGPIPE, &sig_act, NULL)) { + sigaction(SIGPIPE, &sig_act, NULL) || + sigaction(SIGALRM, &sig_act, NULL)) { printf("Failed to install sighandler.\n"); - return -1; + return 2; } if (client_init()) { printf("Failed to initialize client.\n"); - return -1; + return 2; } fd = flow_alloc(client.s_apn, &client.qs, NULL); if (fd < 0) { printf("Failed to allocate flow: %d.\n", fd); client_fini(); - return -1; + return 2; } fccntl(fd, FLOWSFLAGS, FLOWFRDWR | FLOWFRNOPART); + if (client.duration > 0) { + struct itimerval it; + memset(&it, 0, sizeof(it)); + it.it_value.tv_sec = client.duration / 1000; + it.it_value.tv_usec = (client.duration % 1000) * 1000; + setitimer(ITIMER_REAL, &it, NULL); + } + clock_gettime(CLOCK_REALTIME, &tic); if (client.flood_busy) @@ -439,5 +445,5 @@ static int client_main(void) flow_dealloc(fd); client_fini(); - return 0; + return client.rcvd == client.sent ? 0 : 1; } diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c index 33af28c4..e98ca040 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -237,6 +237,14 @@ int server_main(void) return -1; } + if (pthread_mutex_init(&server.lock, NULL)) { + fqueue_destroy(server.fq); + fset_destroy(server.flows); + return -1; + } + + memset(server.times, 0, sizeof(server.times)); + pthread_create(&server.cleaner_pt, NULL, cleaner_thread, NULL); if (server.busy) { @@ -255,11 +263,13 @@ int server_main(void) pthread_cancel(server.cleaner_pt); - fset_destroy(server.flows); - fqueue_destroy(server.fq); - + /* Join cancellable threads before tearing down their fset. */ pthread_join(server.server_pt, NULL); pthread_join(server.cleaner_pt, NULL); + pthread_mutex_destroy(&server.lock); + fset_destroy(server.flows); + fqueue_destroy(server.fq); + return 0; } |
