summaryrefslogtreecommitdiff
path: root/src/tools/oping
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/oping')
-rw-r--r--src/tools/oping/oping.c61
-rw-r--r--src/tools/oping/oping_client.c42
-rw-r--r--src/tools/oping/oping_server.c16
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;
}