aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2020-03-05 09:10:32 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2020-03-05 09:10:32 +0200
commit2cd60c7e775b481332703d9674f02c68ab3b3e91 (patch)
tree604918caa9b42b176eae077157029d30ecaa82ea
parentb4f3a0766b322ab70d98372773e22afd6ebfdb30 (diff)
downloadping903-2cd60c7e775b481332703d9674f02c68ab3b3e91.tar.gz
ping903-2cd60c7e775b481332703d9674f02c68ab3b3e91.tar.bz2
Attempt better diagnosis of duplicate replies
* src/ping903.h (hostping): New member nreply - an array counting replies for each echo request. * src/pinger.c (hostping_create): Allocate nreply array. (seqidx): Remove "replied", introduce "ping_num" instead. Ping_num is the ordinal number of the echo request that was assigned this sequence number. It is used to address the host->nreply array. (seqno_alloc): Initialize ping_num to the number of transmitted echos (i.e. next ordinal number). (hostping_from_seqno): Diagnose all possible (and impossible) variants of duplicate and unsolicited replies.
-rw-r--r--src/ping903.h1
-rw-r--r--src/pinger.c34
2 files changed, 27 insertions, 8 deletions
diff --git a/src/ping903.h b/src/ping903.h
index ccf62b7..3e88c17 100644
--- a/src/ping903.h
+++ b/src/ping903.h
@@ -142,6 +142,7 @@ typedef struct hostping {
struct host_stat stat_last;
struct hostping *prev, *next;
+ int nreply[1];
} HOSTPING;
extern int verbose;
diff --git a/src/pinger.c b/src/pinger.c
index 2291a48..65e8e6a 100644
--- a/src/pinger.c
+++ b/src/pinger.c
@@ -114,10 +114,14 @@ hostping_free(HOSTPING *hp)
static HOSTPING *
hostping_create(char const *name, struct sockaddr *addr, socklen_t addrlen)
{
- HOSTPING *hp = malloc(sizeof(*hp));
+ HOSTPING *hp;
+ size_t hostsize = sizeof(*hp) +
+ (ping_count - 1) * sizeof(hp->nreply[0]);
+
+ hp = malloc(hostsize);
if (hp) {
- memset(hp, 0, sizeof(*hp));
+ memset(hp, 0, hostsize);
hp->tmin = HOSTPING_TMIN_INIT;
hp->name = strdup(name);
if (!hp)
@@ -306,6 +310,7 @@ hostping_reset(HOSTPING *host)
host->tmax = 0;
host->tsum = 0;
host->tsumsq = 0;
+ memset(host->nreply, 0, ping_count * sizeof(host->nreply[0]));
switch (host->stat_last.status) {
case HOST_STAT_INIT:
break;
@@ -942,7 +947,7 @@ enum {
struct seqidx {
HOSTPING *host;
struct timeval tv;
- int replied;
+ int ping_num;
};
static struct seqidx *seqidx;
@@ -958,7 +963,7 @@ seqno_alloc(HOSTPING *host, struct timeval *tv)
if (tv->tv_sec - seqidx[n].tv.tv_sec > MAX_PING_TIMEOUT) {
memcpy(&seqidx[n].tv, tv, sizeof(*tv));
seqidx[n].host = host;
- seqidx[n].replied = 0;
+ seqidx[n].ping_num = host->xmit_count;
next_seqno = (n + 1) % MOD_SEQNO;
return n;
}
@@ -976,13 +981,26 @@ hostping_from_seqno(int seq)
pthread_mutex_lock(&seqno_mutex);
host = seqidx[seq].host;
if (host) {
+ int n;
+
hostping_lock(host);
- if (seqidx[seq].replied) {
- host->dup_count++;
- info("%s:%d: DUP!", host->name, seq);
+ n = seqidx[seq].ping_num;
+ if (n >= 0 && n < ping_count) {
+ if (++host->nreply[n] > 1) {
+ host->dup_count++;
+ info("%s: duplicate reply for echo #%d, seqno %d",
+ host->name, n, seq);
+ host = NULL;
+ } else if (host->recv_count == host->xmit_count) {
+ error("%s: unexpected reply #%d, seqno %d",
+ host->name, n, seq);
+ host = NULL;
+ }
+ } else {
+ error("%s: duplicate reply for unregistered echo #%d, seqno %d",
+ host->name, n, seq);
host = NULL;
}
- seqidx[seq].replied++;
} else
fatal("no host found for sequence number %d", seq);
pthread_mutex_unlock(&seqno_mutex);

Return to:

Send suggestions and report system problems to the System administrator.