diff options
author | Joern Engel <joern@logfs.org> | 2012-01-17 09:40:09 -0800 |
---|---|---|
committer | Joern Engel <joern@logfs.org> | 2012-01-17 09:40:09 -0800 |
commit | 672d19dc9e9eb74565f8616702c733a0872add45 (patch) | |
tree | c831f76336c0ce2efcaba93791cf5bac66cb7eb3 | |
parent | 585f32119a017e6fc381d0407a7a3a31dc5328b4 (diff) | |
download | cancd-672d19dc9e9eb74565f8616702c733a0872add45.tar.gz |
Create DNS thread
When possible we should use DNS hostnames instead of IP addresses as
logfile names. But gethostbyaddr() can block indefinitely, so run that
command from a dedicated thread. If it blocks, we just write to the ip
address name.
Signed-off-by: Joern Engel <joern@logfs.org>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | cancd.c | 50 |
2 files changed, 47 insertions, 4 deletions
@@ -2,6 +2,7 @@ VERSION=0.1.0 CFLAGS += -Wall -g -O2 -DVERSION="\"$(VERSION)\"" +LDFLAGS += -lpthread cancd: cancd.o btree.o @@ -32,7 +32,10 @@ #include <getopt.h> #include <libgen.h> #include <limits.h> +#include <netdb.h> #include <netinet/in.h> +#include <pthread.h> +#include <semaphore.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> @@ -41,6 +44,7 @@ #include <syslog.h> #include <sys/socket.h> #include <sys/stat.h> +#include <sys/time.h> #include <sys/types.h> #include <time.h> #include <unistd.h> @@ -85,7 +89,10 @@ static int daemonize = 1; /* What signal did we catch? */ sig_atomic_t caught_sig = 0; + struct btree_head32 btree; +pthread_t dns_thread; +sem_t dns_sem; struct source_ip { const char *filename; @@ -360,6 +367,7 @@ static struct source_ip *get_source_ip(struct sockaddr_in *addr) sip->filename = get_path(&addr->sin_addr); err = btree_insert32(&btree, key, sip); assert(!err); + sem_post(&dns_sem); } return sip; } @@ -633,6 +641,41 @@ static int parse_options(int argc, char *argv[]) return 0; } +static void dns_visitor(void *_sip, long unused, u32 ip, size_t unused2) +{ + struct source_ip *sip = _sip; + struct hostent *he; + const char *old, *new; + + he = gethostbyaddr(&ip, 4, AF_INET); + if (!he) + return; + if (strcmp(he->h_name, sip->filename) == 0) + return; + new = strdup(he->h_name); + if (!new) + return; + old = sip->filename; + sip->filename = new; + free((void *)old); +} + +void *dns_thread_func(void *_arg) +{ + struct timespec ts; + struct timeval tv; + + for (;;) { + /* Wait for 60min or the main thread to wake us */ + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec + 3600; + ts.tv_nsec = 0; + sem_timedwait(&dns_sem, &ts); + /* Do DNS lookups for all hosts */ + btree_visitor32(&btree, 0, dns_visitor); + } +} + int main(int argc, char *argv[]) { int rc; @@ -641,21 +684,20 @@ int main(int argc, char *argv[]) rc = parse_options(argc, argv); if (rc) return rc; - rc = init_self(); if (rc) goto out; - rc = open_socket(); if (rc) goto out; + rc = pthread_create(&dns_thread, NULL, dns_thread_func, NULL); + if (rc) + goto out; rc = run(); close(sock_fd); - out: closelog(); - return rc; } |