1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <ev.h>
#include "log.h"
#include "pingu_burst.h"
#include "pingu_host.h"
#include "pingu_ping.h"
#include "pingu_iface.h"
void ping_burst_start(struct ev_loop *loop, struct pingu_host *host)
{
struct addrinfo hints;
struct addrinfo *ai = NULL, *rp;
int r;
char buf[64];
/* we bind to device every burst in case an iface disappears and
comes back. e.g ppp0 */
if (pingu_iface_bind_socket(host->iface, host->status) < 0) {
pingu_host_set_status(host, PINGU_HOST_STATUS_OFFLINE);
return;
}
host->burst.active = 1;
host->burst.pings_sent = 0;
host->burst.pings_replied = 0;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
r = getaddrinfo(host->host, NULL, &hints, &ai);
if (r < 0) {
log_error("getaddrinfo(%s): %s", host->host, gai_strerror(r));
return;
}
for (rp = ai; rp != NULL; rp = rp->ai_next) {
sockaddr_from_addrinfo(&host->burst.saddr, ai);
r = pingu_ping_send(loop, host, PINGU_PING_IGNORE_ERROR);
if (r == 0)
break;
}
sockaddr_to_string(&host->burst.saddr, buf, sizeof(buf));
if (rp == NULL) {
log_debug("%s: failed to send first ping to %s", host->label, buf);
host->burst.active = 0;
}
freeaddrinfo(ai);
}
void pingu_burst_timeout_cb(struct ev_loop *loop, struct ev_timer *w,
int revents)
{
struct pingu_host *host = container_of(w, struct pingu_host, burst_timeout_watcher);
if (host->burst.active) {
log_warning("%s: burst already active", host->host);
return;
}
log_debug("%s: new burst to %s via %s", host->label, host->host, host->iface->name);
ping_burst_start(loop, host);
}
|