aboutsummaryrefslogtreecommitdiffstats
path: root/pingu_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'pingu_host.c')
-rw-r--r--pingu_host.c220
1 files changed, 29 insertions, 191 deletions
diff --git a/pingu_host.c b/pingu_host.c
index efc3f43..1f1b534 100644
--- a/pingu_host.c
+++ b/pingu_host.c
@@ -2,7 +2,6 @@
#include <arpa/inet.h>
#include <linux/rtnetlink.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -18,188 +17,6 @@
#include "xlib.h"
static struct list_head host_list = LIST_INITIALIZER(host_list);
-float default_burst_interval = 30.0;
-float default_timeout = 1.0;
-int default_max_retries = 5;
-int default_required_replies = 2;
-char *default_up_action = NULL;
-char *default_down_action = NULL;
-char *default_route_script = NULL;
-int default_route_table = 10;
-
-/* note: this overwrite the line buffer */
-static void parse_line(char *line, char **key, char **value)
-{
- char *p;
-
- /* strip comments and trailng \n */
- p = strpbrk(line, "#\n");
- if (p)
- *p = '\0';
-
- (*value) = NULL;
- if (line[0] == '\0') {
- (*key) = NULL;
- return;
- }
-
- /* skip leading whitespace */
- while (isspace(*p)) {
- if (*p == '\0')
- return;
- p++;
- }
- (*key) = line;
-
- /* find space between keyword and value */
- p = line;
- while (!isspace(*p)) {
- if (*p == '\0')
- return;
- p++;
- }
- *p++ = '\0';
-
- /* find value */
- while (isspace(*p)) {
- if (*p == '\0')
- return;
- p++;
- }
- (*value) = p;
-}
-
-int pingu_host_read_config(const char *file)
-{
- FILE *f = fopen(file, "r");
- struct pingu_host *p = NULL;
- int lineno = 0;
- char line[256];
- if (f == NULL) {
- log_perror(file);
- return -1;
- }
- while (fgets(line, sizeof(line), f)) {
- char *key, *value;
- lineno++;
- parse_line(line, &key, &value);
- if (key == NULL)
- continue;
-
- if (strcmp(key, "host") == 0) {
- p = xmalloc(sizeof(struct pingu_host));
- memset(p, 0, sizeof(struct pingu_host));
- p->host = xstrdup(value);
- p->gateway = xstrdup(value);
- p->status = 1; /* online by default */
- p->max_retries = default_max_retries;
- p->timeout = default_timeout;
- p->up_action = default_up_action;
- p->down_action = default_down_action;
- p->required_replies = default_required_replies;
- p->burst_interval = default_burst_interval;
- list_add(&p->host_list_entry, &host_list);
- continue;
- }
- if (p == NULL) {
- if (strcmp(key, "interval") == 0) {
- default_burst_interval = atof(value);
- } else if (strcmp(key, "retry") == 0) {
- default_max_retries = atoi(value);
- } else if (strcmp(key, "required") == 0) {
- default_required_replies = atoi(value);
- } else if (strcmp(key, "timeout") == 0) {
- default_timeout = atof(value);
- } else if (strcmp(key, "up-action") == 0) {
- default_up_action = xstrdup(value);
- } else if (strcmp(key, "down-action") == 0) {
- default_down_action = xstrdup(value);
- } else if (strcmp(key, "route-script") == 0) {
- default_route_script = xstrdup(value);
- } else if (strcmp(key, "route-table") == 0) {
- default_route_table = atoi(value);
- } else
- log_error("host not specified");
- } else if (strcmp(key, "interface") == 0) {
- p->interface = xstrdup(value);
- } else if (strcmp(key, "gateway") == 0) {
- if (p->gateway)
- free(p->gateway);
- p->gateway = xstrdup(value);
- } else if ((strcmp(key, "name") == 0) || (strcmp(key, "label") == 0)) {
- p->label = xstrdup(value);
- } else if (strcmp(key, "up-action") == 0) {
- p->up_action = xstrdup(value);
- } else if (strcmp(key, "down-action") == 0) {
- p->down_action = xstrdup(value);
- } else if (strcmp(key, "retry") == 0) {
- p->max_retries = atoi(value);
- } else if (strcmp(key, "required") == 0) {
- p->required_replies = atoi(value);
- } else if (strcmp(key, "timeout") == 0) {
- p->timeout = atof(value);
- } else if (strcmp(key, "source-ip") == 0) {
- p->source_ip = xstrdup(value);
- } else if (strcmp(key, "interval") == 0) {
- p->burst_interval = atof(value);
- } else if (strcmp(key, "route-table") == 0) {
- p->iface_route_table = atoi(value);
- } else {
- log_error("Unknown keyword '%s' on line %i", key,
- lineno);
- }
- }
- return 0;
-}
-
-static char *get_provider_gateway(struct pingu_host *p)
-{
- if (p->gateway != NULL)
- return p->gateway;
- return p->host;
-}
-
-static void exec_route_change_hook(void)
-{
- struct pingu_host *host;
- struct list_head *n;
- char **args;
- int i = 0;
- pid_t pid;
-
- if (default_route_script == NULL)
- return;
-
- list_for_each(n, &host_list)
- i++;
-
- args = malloc(sizeof(char *) * (i + 2));
- if (args == NULL) {
- log_perror("malloc");
- return;
- }
-
- i = 0;
- args[i++] = default_route_script;
- list_for_each_entry(host, &host_list, host_list_entry) {
- if (host->status)
- args[i++] = get_provider_gateway(host);
- }
- args[i] = NULL;
- pid = fork();
- if (pid < 0) {
- log_perror("fork");
- free(args);
- return;
- }
- if (pid == 0) {
- /* the child */
- execvp(default_route_script, args);
- log_perror(args[0]);
- exit(1);
- }
- /* libev reaps all children */
-}
static void execute_action(const char *action)
{
@@ -245,7 +62,6 @@ int pingu_host_set_status(struct pingu_host *host, int status)
if (action != NULL)
execute_action(action);
pingu_iface_update_routes(host->iface, route_action);
- exec_route_change_hook();
return status;
}
@@ -260,16 +76,38 @@ int pingu_host_verify_status(struct ev_loop *loop, struct pingu_host *host)
return 0;
}
-int pingu_host_init(struct ev_loop *loop, const char *config)
+struct pingu_host *pingu_host_new(char *hoststr, float burst_interval,
+ int max_retries, int required_replies,
+ float timeout,
+ const char *up_action,
+ const char *down_action)
{
- struct pingu_host *host;
- if (pingu_host_read_config(config) < 0)
- return -1;
-
- if (pingu_iface_init(loop, &host_list) < 0)
- return -1;
+ struct pingu_host *host = calloc(1, sizeof(struct pingu_host));
+ if (host == NULL) {
+ log_perror(hoststr);
+ return NULL;
+ }
+
+ host->host = hoststr;
+ host->status = 1; /* online by default */
+ host->burst_interval = burst_interval;
+ host->max_retries = max_retries;
+ host->required_replies = required_replies;
+ host->timeout = timeout;
+ host->up_action = up_action;
+ host->down_action = down_action;
+
+ list_add(&host->host_list_entry, &host_list);
+ return host;
+}
+
+int pingu_host_init(struct ev_loop *loop)
+{
+ struct pingu_host *host;
list_for_each_entry(host, &host_list, host_list_entry) {
+ if (host->label == NULL)
+ host->label = host->host;
ev_timer_init(&host->burst_timeout_watcher,
pingu_burst_timeout_cb, 0, host->burst_interval);
ev_timer_start(loop, &host->burst_timeout_watcher);