diff --git a/src/fping.c b/src/fping.c index 4a0c60a1..c693f953 100644 --- a/src/fping.c +++ b/src/fping.c @@ -312,6 +312,7 @@ long timeval_diff(struct timeval* a, struct timeval* b); void timeval_add(struct timeval* a, long t_10u); void usage(int); int wait_for_reply(long); +void handle_reply_timeouts(); void print_per_system_stats(void); void print_per_system_splits(void); void print_netdata(void); @@ -626,7 +627,7 @@ int main(int argc, char** argv) case 'x': if (!(min_reachable = (unsigned int)atoi(optparse_state.optarg))) - usage(1); + usage(1); break; case 'f': @@ -1281,6 +1282,9 @@ void main_loop() gettimeofday(¤t_time, &tz); + /* Replies without answers */ + handle_reply_timeouts(); + /* Print report */ if (report_interval && (loop_flag || count_flag) && (timeval_diff(¤t_time, &next_report_time) >= 0)) { if (netdata_flag) @@ -2241,9 +2245,73 @@ int wait_for_reply(long wait_time) } fflush(stdout); + seqmap_clear(seq); return num_jobs; } +void handle_reply_timeouts() +{ + unsigned int seq; + SEQMAP_VALUE * seqmap_value; + HOST_ENTRY* h; + long duration; + int ping_number; + int avg; + + for(;;) { + + seq = seqmap_get_oldest_id(); + seqmap_value = seqmap_fetch(seq, ¤t_time); + + if (seqmap_value == NULL) { + break; + } + + h = table[seqmap_value->host_nr]; + + ping_number = seqmap_value->ping_count; + duration = timeval_diff(¤t_time, &(seqmap_value->ping_ts)); + + /* not yet in a timeout */ + if (duration <= h->timeout) { + break; + } + + if (per_recv_flag) { + if (timestamp_flag) { + printf("[%lu.%06lu] ", + (unsigned long)current_time.tv_sec, + (unsigned long)current_time.tv_usec); + } + + printf("%s%s : [%d], timed out", + h->host, h->pad, ping_number); + + if (h->num_recv > 0) { + avg = h->total_time / h->num_recv; + printf(" (%s avg, ", sprint_tm(avg)); + } + else { + printf(" (no avg, "); + } + if (h->num_recv <= h->num_sent) { + printf("%d%% loss)", + ((h->num_sent - h->num_recv) * 100) / h->num_sent); + } + else { + printf("%d%% return)", + (h->num_recv_total * 100) / h->num_sent); + } + + printf("\n"); + fflush(stdout); + } + + seqmap_clear(seq); + } + return; +} + /************************************************************ Function: add_name diff --git a/src/seqmap.c b/src/seqmap.c index 3cff4c0b..410e1170 100644 --- a/src/seqmap.c +++ b/src/seqmap.c @@ -41,6 +41,7 @@ #include #include +#include /* description of the data structure used: * @@ -53,6 +54,7 @@ static SEQMAP_VALUE* seqmap_map = NULL; static unsigned int seqmap_next_id = 0; +static unsigned int seqmap_first_id = 0; #define SEQMAP_TIMEOUT_IN_S 10 #define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX @@ -114,3 +116,24 @@ SEQMAP_VALUE* seqmap_fetch(unsigned int id, struct timeval* now) return value; } + +void seqmap_clear(unsigned int id) +{ + if (id > SEQMAP_MAXSEQ) { + return; + } + + memset(&seqmap_map[id], 0, sizeof(SEQMAP_VALUE)); + + while (seqmap_map[seqmap_first_id].ping_ts.tv_sec == 0 + && seqmap_first_id != seqmap_next_id ) { + seqmap_first_id = (seqmap_first_id + 1) % SEQMAP_MAXSEQ; + } + + return; +} + +unsigned int seqmap_get_oldest_id() +{ + return seqmap_first_id; +} diff --git a/src/seqmap.h b/src/seqmap.h index cafde4d0..0d97bc7c 100644 --- a/src/seqmap.h +++ b/src/seqmap.h @@ -16,5 +16,7 @@ typedef struct seqmap_value void seqmap_init(); unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timeval *now); SEQMAP_VALUE *seqmap_fetch(unsigned int id, struct timeval *now); +void seqmap_clear(unsigned int id); +unsigned int seqmap_get_oldest_id(); #endif