Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not count packets that are still within their timeout window in packet loss calculation. #157

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions src/fping.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern "C" {
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include <limits.h>

#include "config.h"
#include "seqmap.h"
Expand Down Expand Up @@ -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; /* 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 */
Expand Down Expand Up @@ -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] = timeval_diff(&h->last_send_time, &start_time);;

#if defined(DEBUG) || defined(_DEBUG)
if (sent_times_flag)
h->sent_times[h->num_sent] = timeval_diff(&h->last_send_time, &start_time);
Expand Down Expand Up @@ -2185,6 +2191,9 @@ int wait_for_reply(long wait_time)
}
}

/* Mark as received in window */
h->window[this_count % h->window_size] = INT_MIN;

if (h->num_recv == 1) {
num_alive++;
if (verbose_flag || alive_flag) {
Expand Down Expand Up @@ -2217,9 +2226,36 @@ int wait_for_reply(long wait_time)
h->host, h->pad, this_count, result, sprint_tm(this_reply));
printf(" (%s avg, ", sprint_tm(avg));

if (h->num_recv <= h->num_sent) {
/* Calculate the expected number of packets */
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 ){
fprintf(stderr, " ");
}
else {
if (h->window[j] + h->timeout > now ){
fprintf(stderr, ".");
}
else {
fprintf(stderr, "x");
}
}
#endif
}
if ( expected < 1 )
expected = 1;

if (h->num_recv <= expected) {
printf("%d%% loss)",
((h->num_sent - h->num_recv) * 100) / h->num_sent);
((expected - h->num_recv) * 100) / expected);
}
else {
printf("%d%% return)",
Expand Down Expand Up @@ -2388,6 +2424,10 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_
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;
while (*s) {
Expand All @@ -2412,6 +2452,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] = INT_MIN;

p->window = i;

#if defined(DEBUG) || defined(_DEBUG)
/* likewise for sent times */
if (sent_times_flag) {
Expand Down