summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoern Engel <joern@logfs.org>2012-01-17 09:40:09 -0800
committerJoern Engel <joern@logfs.org>2012-01-17 09:40:09 -0800
commit672d19dc9e9eb74565f8616702c733a0872add45 (patch)
treec831f76336c0ce2efcaba93791cf5bac66cb7eb3
parent585f32119a017e6fc381d0407a7a3a31dc5328b4 (diff)
downloadcancd-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--Makefile1
-rw-r--r--cancd.c50
2 files changed, 47 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index 3c5c45b..985cb20 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,7 @@
VERSION=0.1.0
CFLAGS += -Wall -g -O2 -DVERSION="\"$(VERSION)\""
+LDFLAGS += -lpthread
cancd: cancd.o btree.o
diff --git a/cancd.c b/cancd.c
index 070a9db..b560ff0 100644
--- a/cancd.c
+++ b/cancd.c
@@ -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;
}