From e577977a3b3444fe413a2be433602fa3fd1fbdf2 Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Wed, 21 Aug 2019 11:42:52 +0000 Subject: [PATCH 1/5] First revision, simple window with 0=unsent 1=sent 2=received and crappy ascii art Todo, put sent times in window instead? --- src/fping.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/fping.c b/src/fping.c index 9650db91..0615160d 100644 --- a/src/fping.c +++ b/src/fping.c @@ -43,6 +43,7 @@ extern "C" { #include #include #include +#include #include "config.h" #include "seqmap.h" @@ -214,6 +215,8 @@ typedef struct host_entry { int total_time_i; /* sum of response times */ int discard_next_recv_i; /* don't count next received reply for split reporting */ int* resp_times; /* individual response times */ + int* window; + int window_size; #if defined(DEBUG) || defined(_DEBUG) int* sent_times; /* per-sent-ping timestamp */ #endif /* DEBUG || _DEBUG */ @@ -1702,6 +1705,9 @@ int send_ping(HOST_ENTRY* h) if (!loop_flag) h->resp_times[h->num_sent] = RESP_WAITING; + /* mark this trial outstanding in the window */ + h->window[h->num_sent % h->window_size] = 1; + #if defined(DEBUG) || defined(_DEBUG) if (sent_times_flag) h->sent_times[h->num_sent] = timeval_diff(&h->last_send_time, &start_time); @@ -2185,6 +2191,9 @@ int wait_for_reply(long wait_time) } } + /* Mark as received in window */ + h->window[this_count % h->window_size] = 2; + if (h->num_recv == 1) { num_alive++; if (verbose_flag || alive_flag) { @@ -2217,9 +2226,26 @@ int wait_for_reply(long wait_time) h->host, h->pad, this_count, result, sprint_tm(this_reply)); printf(" (%s avg, ", sprint_tm(avg)); + /* Remove from expected count any still in window */ + int expected = h->num_sent; + for (int j = 0; j < h->window_size; j++) { + if ( h->window[j] == 0 ) + fprintf(stderr, " "); + if ( h->window[j] == 1 ) + fprintf(stderr, "o"); + if ( h->window[j] == 2 ) + fprintf(stderr, "+"); + + if ( h->window[j] == 1 ) + expected--; + } + fprintf(stderr, " "); + if ( expected < 0 ) + expected = 0; + if (h->num_recv <= h->num_sent) { - printf("%d%% loss)", - ((h->num_sent - h->num_recv) * 100) / h->num_sent); + printf("%d%% loss %d/%d/%d)", + ((expected - h->num_recv) * 100) / expected, h->num_recv, expected, h->num_sent); } else { printf("%d%% return)", @@ -2387,6 +2413,7 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_ p->timeout = timeout; p->running = 1; p->min_reply = 0; + p->window_size = ceil((float)timeout / (float)perhost_interval); if (netdata_flag) { char* s = p->name; @@ -2412,6 +2439,15 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_ p->resp_times = i; } + /* Array for in-flight packet window */ + i = (int*)malloc(p->window_size * sizeof(int)); + if (!i) + crash_and_burn("can't allocate window array"); + for (n = 1; n < p->window_size; n++) + i[n] = 0; + + p->window = i; + #if defined(DEBUG) || defined(_DEBUG) /* likewise for sent times */ if (sent_times_flag) { From 312e04029d0e8d6893d758ea10669831d5a2863e Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Wed, 21 Aug 2019 12:28:05 +0000 Subject: [PATCH 2/5] Change window to hold sent times, and compare them to current time and timeout. Window size is no longer critical, and results are correct when timeout is not a multiple of period. --- src/fping.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/fping.c b/src/fping.c index 0615160d..f89c32f8 100644 --- a/src/fping.c +++ b/src/fping.c @@ -43,7 +43,7 @@ extern "C" { #include #include #include -#include +#include #include "config.h" #include "seqmap.h" @@ -215,8 +215,8 @@ typedef struct host_entry { int total_time_i; /* sum of response times */ int discard_next_recv_i; /* don't count next received reply for split reporting */ int* resp_times; /* individual response times */ - int* window; - int window_size; + int* window; /* circular buffer of per-sent-ping timestamps for pings within their timeouts */ + int window_size; /* size of above; needs to be larger than ceil(timeout / period) */ #if defined(DEBUG) || defined(_DEBUG) int* sent_times; /* per-sent-ping timestamp */ #endif /* DEBUG || _DEBUG */ @@ -1706,7 +1706,7 @@ int send_ping(HOST_ENTRY* h) h->resp_times[h->num_sent] = RESP_WAITING; /* mark this trial outstanding in the window */ - h->window[h->num_sent % h->window_size] = 1; + h->window[h->num_sent % h->window_size] = timeval_diff(&h->last_send_time, &start_time);; #if defined(DEBUG) || defined(_DEBUG) if (sent_times_flag) @@ -2192,7 +2192,7 @@ int wait_for_reply(long wait_time) } /* Mark as received in window */ - h->window[this_count % h->window_size] = 2; + h->window[this_count % h->window_size] = INT_MIN; if (h->num_recv == 1) { num_alive++; @@ -2226,18 +2226,27 @@ int wait_for_reply(long wait_time) h->host, h->pad, this_count, result, sprint_tm(this_reply)); printf(" (%s avg, ", sprint_tm(avg)); - /* Remove from expected count any still in window */ + /* Calculate the expected number of packets */ + long now = timeval_diff(¤t_time, &start_time); int expected = h->num_sent; for (int j = 0; j < h->window_size; j++) { - if ( h->window[j] == 0 ) + int v = h->window[j]; + if ( v == INT_MIN ){ + /* This entry has been received */ fprintf(stderr, " "); - if ( h->window[j] == 1 ) - fprintf(stderr, "o"); - if ( h->window[j] == 2 ) - fprintf(stderr, "+"); - - if ( h->window[j] == 1 ) - expected--; + } + else { + /* This entry has not been received yet */ + if (h->window[j] + h->timeout > now ){ + /* And it is still within it's timeout, do not count it*/ + expected--; + fprintf(stderr, "."); + } + else { + /* It has timed out */ + fprintf(stderr, "x"); + } + } } fprintf(stderr, " "); if ( expected < 0 ) @@ -2413,7 +2422,7 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_ p->timeout = timeout; p->running = 1; p->min_reply = 0; - p->window_size = ceil((float)timeout / (float)perhost_interval); + p->window_size = 2 * timeout / perhost_interval; if (netdata_flag) { char* s = p->name; @@ -2444,7 +2453,7 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_ if (!i) crash_and_burn("can't allocate window array"); for (n = 1; n < p->window_size; n++) - i[n] = 0; + i[n] = INT_MIN; p->window = i; From f31a56f17408691ac50cdbac2aa853cb0bce0964 Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Wed, 21 Aug 2019 14:02:27 +0000 Subject: [PATCH 3/5] Fix comparison in conditional loss output --- src/fping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fping.c b/src/fping.c index f89c32f8..ec6f89e2 100644 --- a/src/fping.c +++ b/src/fping.c @@ -2252,7 +2252,7 @@ int wait_for_reply(long wait_time) if ( expected < 0 ) expected = 0; - if (h->num_recv <= h->num_sent) { + if (h->num_recv <= expected) { printf("%d%% loss %d/%d/%d)", ((expected - h->num_recv) * 100) / expected, h->num_recv, expected, h->num_sent); } From 398ebbb7bd14a8c781368ee3251506f0ed97c0ff Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Wed, 21 Aug 2019 14:11:40 +0000 Subject: [PATCH 4/5] remove superfluous output --- src/fping.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/fping.c b/src/fping.c index ec6f89e2..238d9cc3 100644 --- a/src/fping.c +++ b/src/fping.c @@ -2227,34 +2227,35 @@ int wait_for_reply(long wait_time) printf(" (%s avg, ", sprint_tm(avg)); /* Calculate the expected number of packets */ - long now = timeval_diff(¤t_time, &start_time); + long now = timeval_diff(&recv_time, &start_time); int expected = h->num_sent; for (int j = 0; j < h->window_size; j++) { int v = h->window[j]; + if ( v >= 0 && h->window[j] + h->timeout > now ){ + /* This entry has not been received yet */ + /* And it is still within it's timeout, do not count it*/ + expected--; + } +#if 0 if ( v == INT_MIN ){ - /* This entry has been received */ fprintf(stderr, " "); } else { - /* This entry has not been received yet */ if (h->window[j] + h->timeout > now ){ - /* And it is still within it's timeout, do not count it*/ - expected--; fprintf(stderr, "."); } else { - /* It has timed out */ fprintf(stderr, "x"); } } +#endif } - fprintf(stderr, " "); if ( expected < 0 ) expected = 0; if (h->num_recv <= expected) { - printf("%d%% loss %d/%d/%d)", - ((expected - h->num_recv) * 100) / expected, h->num_recv, expected, h->num_sent); + printf("%d%% loss)", + ((expected - h->num_recv) * 100) / expected); } else { printf("%d%% return)", From 17299a12855a895eb1b27b1aa3d9d9d75a38ba73 Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Wed, 21 Aug 2019 14:35:04 +0000 Subject: [PATCH 5/5] Make sure window is at least one. --- src/fping.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fping.c b/src/fping.c index 238d9cc3..c8a14ca2 100644 --- a/src/fping.c +++ b/src/fping.c @@ -2250,8 +2250,8 @@ int wait_for_reply(long wait_time) } #endif } - if ( expected < 0 ) - expected = 0; + if ( expected < 1 ) + expected = 1; if (h->num_recv <= expected) { printf("%d%% loss)", @@ -2423,7 +2423,10 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_ p->timeout = timeout; p->running = 1; p->min_reply = 0; + p->window_size = 2 * timeout / perhost_interval; + if ( p->window_size <= 0 ) + p->window_size = 1; if (netdata_flag) { char* s = p->name;