diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pinger.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/src/pinger.c b/src/pinger.c index 956f091..3ee36dd 100644 --- a/src/pinger.c +++ b/src/pinger.c @@ -235,6 +235,9 @@ send_echo(HOSTADDR *host, unsigned char *ping_buffer) return; } + if (verbose > 2) + info("sending %d bytes to %s, icmp_seq=%d", buflen, host->name, + seqno); icmp_generic_encode(ping_buffer, buflen, ICMP_ECHO, ping_ident, seqno); n = sendto(ping_fd, (char *) ping_buffer, buflen, 0, @@ -263,6 +266,27 @@ start_probe(void) static void host_stat_commit(HOSTADDR *host); +enum { NANOSEC_IN_SEC = 1000000000 }; + +static inline void +timespec_add(struct timespec const *a, struct timespec const *b, + struct timespec *res) +{ + res->tv_sec = a->tv_sec + b->tv_sec; + res->tv_nsec = a->tv_nsec + b->tv_nsec; + if (res->tv_nsec >= NANOSEC_IN_SEC) { + ++res->tv_sec; + res->tv_nsec -= NANOSEC_IN_SEC; + } +} + +static inline void +timespec_incr(struct timespec *a, struct timespec const *b) +{ + struct timespec t = *a; + timespec_add(&t, b, a); +} + void * p903_sender(void *p) { @@ -271,20 +295,32 @@ p903_sender(void *p) struct pollfd pfd; int n; unsigned send_count = 0; + double d; + struct timespec delay; pfd.fd = ping_fd; pfd.events = POLLOUT; ping_buffer = emalloc(sizeof(struct icmp) + data_length); + d = (double) ping_interval / hostaddr_count; + delay.tv_sec = (int) d; + delay.tv_nsec = (d - delay.tv_sec) * NANOSEC_IN_SEC; + pthread_mutex_lock(&sendq_mutex); while (1) { + struct timespec ts; + if (!send_p) { while (!send_p) pthread_cond_wait(&sendq_cond, &sendq_mutex); send_count = 0; } + clock_gettime(CLOCK_MONOTONIC, &ts); for (i = 0; i < hostaddr_count; i++) { + struct timespec nts; + clock_gettime(CLOCK_MONOTONIC, &nts); + timespec_incr(&nts, &delay); n = poll(&pfd, 1, -1); if (n == 1) { send_echo(&hostaddr[i], ping_buffer); @@ -292,12 +328,19 @@ p903_sender(void *p) fatal("poll: %s", strerror(errno)); exit(1); } + if (i < hostaddr_count - 1) + clock_nanosleep(CLOCK_MONOTONIC, + TIMER_ABSTIME, &nts, + NULL); } send_count++; if (send_count == ping_count) send_p = 0; - else - sleep(ping_interval); + else { + ts.tv_sec += ping_interval; + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, + NULL); + } } pthread_mutex_unlock(&sendq_mutex); return NULL; @@ -654,7 +697,7 @@ p903_receiver(void *p) struct icmp *icmp; struct ip *ip; HOSTADDR *host; - + n = recvfrom(ping_fd, ping_buffer, buflen, 0, (struct sockaddr *) &addr, &addrlen); if (n < 0) { @@ -719,7 +762,7 @@ p903_receiver(void *p) host->recv_count++; - if (verbose) + if (verbose > 1) log_echo((struct sockaddr *)&addr, addrlen, icmp, ip, n, rtt); if (host->recv_count == ping_count) host_stat_commit(host); @@ -740,8 +783,9 @@ p903_scheduler(void *p) host_reset(hostaddr + i); start_probe(); sleep(probe_interval); - info("total sent=%u, received=%u", - xmit_total, recv_total); + if (verbose) + info("total sent=%u, received=%u", + xmit_total, recv_total); xmit_total = recv_total = 0; } } |