From 70a037337b955840904a4d78ed45a67ce24aa8ac Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 22 Jun 2008 13:00:48 +0200 Subject: [PATCH] src/rrdd.[ch]: Implement listening to arbitrary addresses. --- src/rrdd.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ src/rrdd.h | 3 +- 2 files changed, 121 insertions(+), 12 deletions(-) diff --git a/src/rrdd.c b/src/rrdd.c index c2f7936..a9a1e05 100644 --- a/src/rrdd.c +++ b/src/rrdd.c @@ -29,6 +29,8 @@ # define RRDD_LOG(severity, ...) syslog ((severity), __VA_ARGS__) #endif +#define DEFAULT_PORT "42217" + /* * Types */ @@ -78,6 +80,9 @@ static pthread_cond_t cache_cond = PTHREAD_COND_INITIALIZER; static int config_write_interval = 300; static int config_flush_interval = 3600; +static char **config_listen_address_list = NULL; +static int config_listen_address_list_len = 0; + /* * Functions */ @@ -163,7 +168,7 @@ static void *queue_thread_main (void *args) /* {{{ */ RRDD_LOG (LOG_DEBUG, "queue_thread_main: rrd_update (%s, %i, %p)", file, values_num, (void *) values); - status = rrd_update_r (file, NULL, values_num, values); + status = rrd_update_r (file, NULL, values_num, (void *) values); if (status != 0) { RRDD_LOG (LOG_ERR, "queue_thread_main: " @@ -454,7 +459,7 @@ static void *connection_thread_main (void *args) /* {{{ */ return (NULL); } /* }}} void *connection_thread_main */ -static int open_listen_socket (const char *path) /* {{{ */ +static int open_listen_socket_unix (const char *path) /* {{{ */ { int fd; struct sockaddr_un sa; @@ -465,7 +470,7 @@ static int open_listen_socket (const char *path) /* {{{ */ sizeof (listen_fds[0]) * (listen_fds_num + 1)); if (temp == NULL) { - RRDD_LOG (LOG_ERR, "open_listen_socket: realloc failed."); + RRDD_LOG (LOG_ERR, "open_listen_socket_unix: realloc failed."); return (-1); } listen_fds = temp; @@ -474,7 +479,7 @@ static int open_listen_socket (const char *path) /* {{{ */ fd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0); if (fd < 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket: socket(2) failed."); + RRDD_LOG (LOG_ERR, "open_listen_socket_unix: socket(2) failed."); return (-1); } @@ -485,7 +490,7 @@ static int open_listen_socket (const char *path) /* {{{ */ status = bind (fd, (struct sockaddr *) &sa, sizeof (sa)); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket: bind(2) failed."); + RRDD_LOG (LOG_ERR, "open_listen_socket_unix: bind(2) failed."); close (fd); unlink (path); return (-1); @@ -494,7 +499,7 @@ static int open_listen_socket (const char *path) /* {{{ */ status = listen (fd, /* backlog = */ 10); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket: listen(2) failed."); + RRDD_LOG (LOG_ERR, "open_listen_socket_unix: listen(2) failed."); close (fd); unlink (path); return (-1); @@ -506,6 +511,85 @@ static int open_listen_socket (const char *path) /* {{{ */ listen_fds_num++; return (0); +} /* }}} int open_listen_socket_unix */ + +static int open_listen_socket (const char *addr) /* {{{ */ +{ + struct addrinfo ai_hints; + struct addrinfo *ai_res; + struct addrinfo *ai_ptr; + int status; + + assert (addr != NULL); + + if (strncmp ("unix:", addr, strlen ("unix:")) == 0) + return (open_listen_socket_unix (addr + strlen ("unix:"))); + else if (addr[0] == '/') + return (open_listen_socket_unix (addr)); + + memset (&ai_hints, 0, sizeof (ai_hints)); + ai_hints.ai_flags = 0; +#ifdef AI_ADDRCONFIG + ai_hints.ai_flags |= AI_ADDRCONFIG; +#endif + ai_hints.ai_family = AF_UNSPEC; + ai_hints.ai_socktype = SOCK_STREAM; + + ai_res = NULL; + status = getaddrinfo (addr, DEFAULT_PORT, &ai_hints, &ai_res); + if (status != 0) + { + RRDD_LOG (LOG_ERR, "open_listen_socket: getaddrinfo(%s) failed: " + "%s", addr, gai_strerror (status)); + return (-1); + } + + for (ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) + { + int fd; + struct sockaddr_storage sa; + listen_socket_t *temp; + + temp = (listen_socket_t *) realloc (listen_fds, + sizeof (listen_fds[0]) * (listen_fds_num + 1)); + if (temp == NULL) + { + RRDD_LOG (LOG_ERR, "open_listen_socket: realloc failed."); + continue; + } + listen_fds = temp; + memset (listen_fds + listen_fds_num, 0, sizeof (listen_fds[0])); + + fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) + { + RRDD_LOG (LOG_ERR, "open_listen_socket: socket(2) failed."); + continue; + } + + status = bind (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) + { + RRDD_LOG (LOG_ERR, "open_listen_socket: bind(2) failed."); + close (fd); + continue; + } + + status = listen (fd, /* backlog = */ 10); + if (status != 0) + { + RRDD_LOG (LOG_ERR, "open_listen_socket: listen(2) failed."); + close (fd); + return (-1); + } + + listen_fds[listen_fds_num].fd = fd; + strncpy (listen_fds[listen_fds_num].path, addr, + sizeof (listen_fds[listen_fds_num].path) - 1); + listen_fds_num++; + } /* for (ai_ptr) */ + + return (0); } /* }}} int open_listen_socket */ static int close_listen_sockets (void) /* {{{ */ @@ -531,17 +615,24 @@ static void *listen_thread_main (void *args) /* {{{ */ int status; int i; - status = open_listen_socket (RRDD_SOCK_PATH); - if (status != 0) + for (i = 0; i < config_listen_address_list_len; i++) + { + RRDD_LOG (LOG_DEBUG, "listen_thread_main: config_listen_address_list[%i] " + "= %s", i, config_listen_address_list[i]); + open_listen_socket (config_listen_address_list[i]); + } + + if (listen_fds_num < 1) { - RRDD_LOG (LOG_ERR, "listen_thread_main: open_listen_socket failed."); + RRDD_LOG (LOG_ERR, "listen_thread_main: No listen sockets " + "could be opened. Sorry."); return (NULL); } while (do_shutdown == 0) { int *client_sd; - struct sockaddr_un client_sa; + struct sockaddr_storage client_sa; socklen_t client_sa_size; pthread_t tid; @@ -698,7 +789,24 @@ static int read_options (int argc, char **argv) /* {{{ */ { case 'l': { - printf ("Listening to: %s\n", optarg); + char **temp; + + temp = (char **) realloc (config_listen_address_list, + sizeof (char *) * (config_listen_address_list_len + 1)); + if (temp == NULL) + { + fprintf (stderr, "read_options: realloc failed.\n"); + return (2); + } + config_listen_address_list = temp; + + temp[config_listen_address_list_len] = strdup (optarg); + if (temp[config_listen_address_list_len] == NULL) + { + fprintf (stderr, "read_options: strdup failed.\n"); + return (2); + } + config_listen_address_list_len++; } break; diff --git a/src/rrdd.h b/src/rrdd.h index 33e6f2f..e8ea258 100644 --- a/src/rrdd.h +++ b/src/rrdd.h @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,6 @@ #include "config.h" -#define RRDD_SOCK_PATH "/tmp/rrdd.sock" +#define RRDD_SOCK_PATH "unix:/tmp/rrdd.sock" #endif /* __RRDD_H */ -- 2.11.0