From c9fe03878b1808e9c33e3f9b16964a142331253b Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Sat, 31 Jan 2009 12:50:08 +0000 Subject: pingu: cofigurable timeout/retry. default values. invert -d - make timeout and retry configurable - possible to set default action, timeout and retry values - the -d option means "daemonize" rather than "debug mode". --- icmp.c | 10 +++++----- icmp.h | 2 +- mtu.c | 2 +- pingu.c | 60 +++++++++++++++++++++++++++++++++++++++++++----------------- pingu.conf | 22 +++++++++++++--------- 5 files changed, 63 insertions(+), 33 deletions(-) diff --git a/icmp.c b/icmp.c index 7135254..eb1ec5c 100644 --- a/icmp.c +++ b/icmp.c @@ -316,7 +316,7 @@ int icmp_read_reply(int fd, struct sockaddr *from, int fromlen, return len; } -int icmp_open(void) +int icmp_open(float timeout) { const int pmtudisc = IP_PMTUDISC_DO, yes = 1; struct timeval tv; @@ -334,12 +334,12 @@ int icmp_open(void) goto err_close; } - tv.tv_sec = 1; - tv.tv_usec = 0; + tv.tv_sec = (time_t) timeout; + tv.tv_usec = (timeout - tv.tv_sec) * 1000000; setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)); - tv.tv_sec = 1; - tv.tv_usec = 0; + tv.tv_sec = (time_t) timeout; + tv.tv_usec = (timeout - tv.tv_sec) * 1000000; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)) == -1) goto err_close; diff --git a/icmp.h b/icmp.h index d5c597f..0fc94e1 100644 --- a/icmp.h +++ b/icmp.h @@ -15,7 +15,7 @@ int icmp_send_ping(int fd, struct sockaddr *to, int tolen, int seq, int total_size); int icmp_read_reply(int fd, struct sockaddr *from, int fromlen, __u8 *buf, int buflen); -int icmp_open(void); +int icmp_open(float timeout); void icmp_close(int fd); diff --git a/mtu.c b/mtu.c index 8e03c07..aa1c74b 100644 --- a/mtu.c +++ b/mtu.c @@ -223,7 +223,7 @@ int main(int argc, char **argv) target = argv[optind]; - fd = icmp_open(); + fd = icmp_open(1.0); if (fd < 0) exit(1); diff --git a/pingu.c b/pingu.c index cebd349..53011a9 100644 --- a/pingu.c +++ b/pingu.c @@ -21,9 +21,13 @@ #define DEFAULT_CONFIG "/etc/pingu.conf" #define DEFAULT_PIDFILE "/var/run/pingu.pid" -int pingu_verbose = 0, pid_file_fd = 0; +int pingu_verbose = 0, pid_file_fd = 0, pingu_daemonize = 0; char *pid_file = DEFAULT_PIDFILE; int interval = 30; +float default_timeout = 1.0; +int default_retry = 3; +char *default_up_action = NULL; +char *default_down_action = NULL; struct provider { struct sockaddr_in address; @@ -32,6 +36,8 @@ struct provider { char *up_action; char *down_action; int status; + int retry; + float timeout; SLIST_ENTRY(provider) provider_list; }; @@ -108,33 +114,53 @@ int read_config(const char *file, struct provider_list *head) if (key == NULL) continue; - if (p == NULL && strcmp(key, "interval") == 0) { - interval = atoi(value); - } else if (strcmp(key, "router") == 0) { + if (strcmp(key, "host") == 0) { p = xmalloc(sizeof(struct provider)); memset(p, 0, sizeof(struct provider)); if (init_sockaddr(&p->address, value) < 0) return 1; p->status = 1; /* online by default */ + p->retry = default_retry; + p->timeout = default_timeout; + p->up_action = default_up_action; + p->down_action = default_down_action; SLIST_INSERT_HEAD(head, p, provider_list); - } else if (p && strcmp(key, "interface") == 0) { + continue; + } + if (p == NULL) { + if (strcmp(key, "interval") == 0) { + interval = atoi(value); + } else if (strcmp(key, "retry") == 0) { + default_retry = atoi(value); + } else if (strcmp(key, "timeout") == 0) { + default_timeout = atof(value); + } else if (strcmp(key, "up-action") == 0) { + default_up_action = value; + } else if (strcmp(key, "down-action") == 0) { + default_down_action = value; + } else + log_error("host not specified"); + } else if (strcmp(key, "interface") == 0) { p->interface = xstrdup(value); - } else if (p && strcmp(key, "provider") == 0) { + } else if (strcmp(key, "name") == 0) { p->name = xstrdup(value); - } else if (p && strcmp(key, "up-action") == 0) { + } else if (strcmp(key, "up-action") == 0) { p->up_action = xstrdup(value); - } else if (p && strcmp(key, "down-action") == 0) { + } else if (strcmp(key, "down-action") == 0) { p->down_action = xstrdup(value); - } else if (p) { - log_error("Unknown keyword '%s' on line %i", key, lineno); + } else if (strcmp(key, "retry") == 0) { + p->retry = atoi(value); + } else if (strcmp(key, "timeout") == 0) { + p->timeout = atof(value); } else { - log_error("provider not specified"); + log_error("Unknown keyword '%s' on line %i", key, + lineno); } } return 0; } -int do_ping(struct sockaddr_in *to, int seq, int retries) +int do_ping(struct sockaddr_in *to, int seq, int retries, float timeout) { __u8 buf[1500]; struct iphdr *ip = (struct iphdr *) buf; @@ -142,7 +168,7 @@ int do_ping(struct sockaddr_in *to, int seq, int retries) struct sockaddr_in from; int retry; int len = sizeof(struct iphdr) + sizeof(struct icmphdr); - int fd = icmp_open(); + int fd = icmp_open(timeout); for (retry = 0; retry < retries; retry++) { icmp_send_ping(fd, (struct sockaddr *) to, sizeof(*to), @@ -168,7 +194,7 @@ int usage(const char *program) "options:\n" " -c Read configuration from FILE (default is " DEFAULT_CONFIG ")\n" - " -d Debug mode. Stay in foreground\n" + " -d Fork to background (damonize)\n" " -h Show this help\n" " -p Use PIDFILE as pidfile (default is " DEFAULT_PIDFILE ")\n" @@ -201,7 +227,7 @@ void ping_loop(struct provider_list *head, int interval) while (1) { seq++; SLIST_FOREACH(p, head, provider_list) { - int status = (do_ping(&p->address, seq, 3) == 0); + int status = (do_ping(&p->address, seq, 2, 0.3) == 0); if (status != p->status) { p->status = status; if (status) @@ -285,7 +311,7 @@ int main(int argc, char *argv[]) config_file = optarg; break; case 'd': - debug_mode++; + pingu_daemonize++; break; case 'h': return usage(basename(argv[0])); @@ -303,7 +329,7 @@ int main(int argc, char *argv[]) if (read_config(config_file, &providers) == -1) return 1; - if (!debug_mode) { + if (pingu_daemonize) { if (daemonize() == -1) return 1; } diff --git a/pingu.conf b/pingu.conf index 215b25c..51c7573 100644 --- a/pingu.conf +++ b/pingu.conf @@ -2,17 +2,21 @@ # comments are prefixed with # # global option -interval 3 +interval 1 +retry 3 +timeout 1.0 -router 10.65.67.11 +host 10.65.67.11 +name ISP-1 interface eth1 -provider ISP-1 -up-action echo "isp 1 went up" >> /tmp/pingu.log -down-action echo "iso 1 went down" >> /tmp/pingu.log +timeout 0.3 +retry 2 +up-action echo "isp 1 went up" +down-action echo "iso 1 went down" -#router 10.2.0.3 +#host 10.2.0.3 +#name ISP-2 #interface eth0 -#provider ISP-1 -#up-action /etc/pingu/isp1 up -#down-action /etc/pingu/isp1 down +#up-action /etc/pingu/isp2 up +#down-action /etc/pingu/isp2 down -- cgit v1.2.3