summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-06-06 16:41:55 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2011-06-06 16:41:55 +0200
commit2b9e5ac193ea91817ff17851a4a16a42a5b87fdb (patch)
tree207ffb12ed68bc729ac9809b69cc00552c598037
parent223b103ccca416effbed2d61798e4aad7d421cc3 (diff)
downloadrsyslog-2b9e5ac193ea91817ff17851a4a16a42a5b87fdb.tar.gz
rsyslog-2b9e5ac193ea91817ff17851a4a16a42a5b87fdb.tar.xz
rsyslog-2b9e5ac193ea91817ff17851a4a16a42a5b87fdb.zip
added a first implementation of a DNS name cache
this still has a couple of weaknesses, like no size limit, no expiration of entries, suboptimal algorithms -- but it should perform better than what we had previously. Implementation will be improved based on feedback during the next couple of releases
-rw-r--r--ChangeLog7
-rw-r--r--runtime/Makefile.am2
-rw-r--r--runtime/dnscache.c295
-rw-r--r--runtime/dnscache.h31
-rw-r--r--runtime/net.c107
-rw-r--r--runtime/nsd_ptcp.c34
-rw-r--r--tools/syslogd.c3
7 files changed, 343 insertions, 136 deletions
diff --git a/ChangeLog b/ChangeLog
index 796ea032..fe37c8c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
---------------------------------------------------------------------------
+Version 6.3.1 [DEVEL] (rgerhards), 2011-06-01
+- added a first implementation of a DNS name cache
+ this still has a couple of weaknesses, like no size limit, no expiration
+ of entries, suboptimal algorithms -- but it should perform better than
+ what we had previously. Implementation will be improved based on
+ feedback during the next couple of releases
+---------------------------------------------------------------------------
Version 6.3.0 [DEVEL] (rgerhards), 2011-06-01
- introduced new config system
http://blog.gerhards.net/2011/06/new-rsyslog-config-system-materializes.html
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index a107e21a..232d8f03 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -8,6 +8,8 @@ librsyslog_la_SOURCES = \
rsyslog.c \
rsyslog.h \
typedefs.h \
+ dnscache.c \
+ dnscache.h \
unicode-helper.h \
atomic.h \
batch.h \
diff --git a/runtime/dnscache.c b/runtime/dnscache.c
new file mode 100644
index 00000000..b47a30b8
--- /dev/null
+++ b/runtime/dnscache.c
@@ -0,0 +1,295 @@
+/* dnscache.c
+ * Implementation of a real DNS cache
+ *
+ * File begun on 2011-06-06 by RGerhards
+ * The initial implementation is far from being optimal. The idea is to
+ * first get somethting that'S functionally OK, and then evolve the algorithm.
+ * In any case, even the initial implementaton is far faster than what we had
+ * before. -- rgerhards, 2011-06-06
+ *
+ * Copyright 2011 by Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of the rsyslog runtime library.
+ *
+ * The rsyslog runtime library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The rsyslog runtime library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
+ */
+#include "config.h"
+
+#include "rsyslog.h"
+#include <stdio.h>
+#include <signal.h>
+#include <netdb.h>
+#include <unistd.h>
+
+#include "syslogd-types.h"
+#include "glbl.h"
+#include "errmsg.h"
+#include "obj.h"
+#include "unicode-helper.h"
+#include "net.h"
+
+/* in this initial implementation, we use a simple, non-optimized at all
+ * linear list.
+ */
+/* module data structures */
+struct dnscache_entry_s {
+ struct sockaddr_storage addr;
+ uchar *pszHostFQDN;
+ uchar *ip;
+ struct dnscache_entry_s *next;
+};
+typedef struct dnscache_entry_s dnscache_entry_t;
+struct dnscache_s {
+ pthread_rwlock_t rwlock;
+ dnscache_entry_t *root;
+};
+typedef struct dnscache_s dnscache_t;
+
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(errmsg)
+static dnscache_t dnsCache;
+
+
+/* init function (must be called once) */
+rsRetVal
+dnscacheInit(void)
+{
+ DEFiRet;
+ dnsCache.root = NULL;
+ pthread_rwlock_init(&dnsCache.rwlock, NULL);
+ CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+finalize_it:
+ RETiRet;
+}
+
+/* deinit function (must be called once) */
+rsRetVal
+dnscacheDeinit(void)
+{
+ DEFiRet;
+ //TODO: free cache elements dnsCache.root = NULL;
+ pthread_rwlock_destroy(&dnsCache.rwlock);
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+ RETiRet;
+}
+
+
+static inline dnscache_entry_t*
+findEntry(struct sockaddr_storage *addr)
+{
+ dnscache_entry_t *etry;
+ for( etry = dnsCache.root
+ ; etry != NULL && !memcmp(addr, &etry->addr, sizeof(struct sockaddr_storage))
+ ; etry = etry->next)
+ /* just search, no other processing necessary */;
+ return etry;
+}
+
+
+/* This is a cancel-safe getnameinfo() version, because we learned
+ * (via drd/valgrind) that getnameinfo() seems to have some issues
+ * when being cancelled, at least if the module was dlloaded.
+ * rgerhards, 2008-09-30
+ */
+static inline int
+mygetnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen, int flags)
+{
+ int iCancelStateSave;
+ int i;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave);
+ i = getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+ pthread_setcancelstate(iCancelStateSave, NULL);
+ return i;
+}
+
+
+/* resolve an address.
+ *
+ * Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats)
+ * for some explanation of the code found below. We do by default not
+ * discard message where we detected malicouos DNS PTR records. However,
+ * there is a user-configurabel option that will tell us if
+ * we should abort. For this, the return value tells the caller if the
+ * message should be processed (1) or discarded (0).
+ */
+static rsRetVal
+resolveAddr(struct sockaddr_storage *addr, uchar *pszHostFQDN, uchar *ip)
+{
+ DEFiRet;
+ int error;
+ sigset_t omask, nmask;
+ struct addrinfo hints, *res;
+
+ assert(addr != NULL);
+ assert(pszHostFQDN != NULL);
+
+ error = mygetnameinfo((struct sockaddr *)addr, SALEN((struct sockaddr *)addr),
+ (char*) ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ if(error) {
+ dbgprintf("Malformed from address %s\n", gai_strerror(error));
+ ABORT_FINALIZE(RS_RET_INVALID_SOURCE);
+ }
+
+ if(!glbl.GetDisableDNS()) {
+ sigemptyset(&nmask);
+ sigaddset(&nmask, SIGHUP);
+ pthread_sigmask(SIG_BLOCK, &nmask, &omask);
+
+ error = mygetnameinfo((struct sockaddr *)addr, SALEN((struct sockaddr *) addr),
+ (char*)pszHostFQDN, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
+
+ if(error == 0) {
+ memset (&hints, 0, sizeof (struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST;
+
+ /* we now do a lookup once again. This one should fail,
+ * because we should not have obtained a non-numeric address. If
+ * we got a numeric one, someone messed with DNS!
+ */
+ if(getaddrinfo ((char*)pszHostFQDN, NULL, &hints, &res) == 0) {
+ uchar szErrMsg[1024];
+ freeaddrinfo (res);
+ /* OK, we know we have evil. The question now is what to do about
+ * it. One the one hand, the message might probably be intended
+ * to harm us. On the other hand, losing the message may also harm us.
+ * Thus, the behaviour is controlled by the $DropMsgsWithMaliciousDnsPTRRecords
+ * option. If it tells us we should discard, we do so, else we proceed,
+ * but log an error message together with it.
+ * time being, we simply drop the name we obtained and use the IP - that one
+ * is OK in any way. We do also log the error message. rgerhards, 2007-07-16
+ */
+ if(glbl.GetDropMalPTRMsgs() == 1) {
+ snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
+ "Malicious PTR record, message dropped "
+ "IP = \"%s\" HOST = \"%s\"",
+ ip, pszHostFQDN);
+ errmsg.LogError(0, RS_RET_MALICIOUS_ENTITY, "%s", szErrMsg);
+ pthread_sigmask(SIG_SETMASK, &omask, NULL);
+ ABORT_FINALIZE(RS_RET_MALICIOUS_ENTITY);
+ }
+
+ /* Please note: we deal with a malicous entry. Thus, we have crafted
+ * the snprintf() below so that all text is in front of the entry - maybe
+ * it contains characters that make the message unreadable
+ * (OK, I admit this is more or less impossible, but I am paranoid...)
+ * rgerhards, 2007-07-16
+ */
+ snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
+ "Malicious PTR record (message accepted, but used IP "
+ "instead of PTR name: IP = \"%s\" HOST = \"%s\"",
+ ip, pszHostFQDN);
+ errmsg.LogError(0, NO_ERRCODE, "%s", szErrMsg);
+
+ error = 1; /* that will trigger using IP address below. */
+ }
+ }
+ pthread_sigmask(SIG_SETMASK, &omask, NULL);
+ }
+
+ if(error || glbl.GetDisableDNS()) {
+ dbgprintf("Host name for your address (%s) unknown\n", ip);
+ strcpy((char*) pszHostFQDN, (char*)ip);
+ ABORT_FINALIZE(RS_RET_ADDRESS_UNKNOWN);
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+/* add a new entry to the cache. This means the address is resolved and
+ * then added to the cache.
+ */
+//static inline rsRetVal
+static rsRetVal
+addEntry(struct sockaddr_storage *addr, dnscache_entry_t **pEtry)
+{
+ uchar pszHostFQDN[NI_MAXHOST];
+ uchar ip[80]; /* 80 is safe for larges IPv6 addr */
+ dnscache_entry_t *etry;
+ DEFiRet;
+ CHKiRet(resolveAddr(addr, pszHostFQDN, ip));
+ CHKmalloc(etry = MALLOC(sizeof(dnscache_entry_t)));
+ CHKmalloc(etry->pszHostFQDN = ustrdup(pszHostFQDN));
+ CHKmalloc(etry->ip = ustrdup(ip));
+ *pEtry = etry;
+
+ /* add to list. Currently, we place the new element always at
+ * the root node. This needs to be optimized later. 2011-06-06
+ */
+ pthread_rwlock_unlock(&dnsCache.rwlock); /* release read lock */
+ pthread_rwlock_wrlock(&dnsCache.rwlock); /* and re-aquire for writing */
+ etry->next = dnsCache.root;
+ dnsCache.root = etry;
+ pthread_rwlock_unlock(&dnsCache.rwlock);
+ pthread_rwlock_rdlock(&dnsCache.rwlock); /* TODO: optimize this! */
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* validate if an entry is still valid and, if not, re-query it.
+ * In the initial implementation, this is a dummy!
+ * TODO: implement!
+ */
+static inline rsRetVal
+validateEntry(dnscache_entry_t *etry, struct sockaddr_storage *addr)
+{
+ return RS_RET_OK;
+}
+
+
+/* This is the main function: it looks up an entry and returns it's name
+ * and IP address. If the entry is not yet inside the cache, it is added.
+ * If the entry can not be resolved, an error is reported back.
+ */
+rsRetVal
+dnscacheLookup(struct sockaddr_storage *addr, uchar *pszHostFQDN, uchar *ip)
+{
+ dnscache_entry_t *etry;
+ DEFiRet;
+
+ pthread_rwlock_rdlock(&dnsCache.rwlock); /* TODO: optimize this! */
+ etry = findEntry(addr);
+ dbgprintf("dnscache: entry %p found\n", etry);
+ if(etry == NULL) {
+ CHKiRet(addEntry(addr, &etry));
+ } else {
+ CHKiRet(validateEntry(etry, addr));
+ }
+ // TODO/QUESTION: can we get rid of the strcpy?
+dbgprintf("XXXX: hostn '%s', ip '%s'\n", etry->pszHostFQDN, etry->ip);
+ strcpy((char*)pszHostFQDN, (char*)etry->pszHostFQDN);
+ strcpy((char*)ip, (char*)etry->ip);
+
+finalize_it:
+ pthread_rwlock_unlock(&dnsCache.rwlock);
+ if(iRet != RS_RET_OK) {
+ strcpy((char*) pszHostFQDN, "???");
+ strcpy((char*) ip, "???");
+ }
+ RETiRet;
+}
diff --git a/runtime/dnscache.h b/runtime/dnscache.h
new file mode 100644
index 00000000..9eee07ba
--- /dev/null
+++ b/runtime/dnscache.h
@@ -0,0 +1,31 @@
+/* Definitions for dnscache module.
+ *
+ * Copyright 2011 by Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of the rsyslog runtime library.
+ *
+ * The rsyslog runtime library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The rsyslog runtime library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
+ */
+
+#ifndef INCLUDED_DNSCACHE_H
+#define INCLUDED_DNSCACHE_H
+
+rsRetVal dnscacheInit(void);
+rsRetVal dnscacheDeinit(void);
+rsRetVal dnscacheLookup(struct sockaddr_storage *addr, uchar *pszHostFQDN, uchar *ip);
+
+#endif /* #ifndef INCLUDED_DNSCACHE_H */
diff --git a/runtime/net.c b/runtime/net.c
index 789790f6..41a344ab 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -12,7 +12,7 @@
* long term, but it is good to have it out of syslogd.c. Maybe this here is
* an interim location ;)
*
- * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH.
*
* rgerhards, 2008-04-16: I changed this code to LGPL today. I carefully analyzed
* that it does not borrow code from the original sysklogd and that I have
@@ -62,6 +62,7 @@
#include "obj.h"
#include "errmsg.h"
#include "net.h"
+#include "dnscache.h"
#ifdef OS_SOLARIS
# define s6_addr32 _S6_un._S6_u32
@@ -1064,108 +1065,6 @@ should_use_so_bsdcompat(void)
#define SO_BSDCOMPAT 0
#endif
-/* get the hostname of the message source. This was originally in cvthname()
- * but has been moved out of it because of clarity and fuctional separation.
- * It must be provided by the socket we received the message on as well as
- * a NI_MAXHOST size large character buffer for the FQDN.
- * 2008-05-16 rgerhards: added field for IP address representation. Must also
- * be NI_MAXHOST size large.
- *
- * Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats)
- * for some explanation of the code found below. We do by default not
- * discard message where we detected malicouos DNS PTR records. However,
- * there is a user-configurabel option that will tell us if
- * we should abort. For this, the return value tells the caller if the
- * message should be processed (1) or discarded (0).
- */
-static rsRetVal
-gethname(struct sockaddr_storage *f, uchar *pszHostFQDN, uchar *ip)
-{
- DEFiRet;
- int error;
- sigset_t omask, nmask;
- struct addrinfo hints, *res;
-
- assert(f != NULL);
- assert(pszHostFQDN != NULL);
-
- error = mygetnameinfo((struct sockaddr *)f, SALEN((struct sockaddr *)f),
- (char*) ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
-
- if (error) {
- dbgprintf("Malformed from address %s\n", gai_strerror(error));
- strcpy((char*) pszHostFQDN, "???");
- strcpy((char*) ip, "???");
- ABORT_FINALIZE(RS_RET_INVALID_SOURCE);
- }
-
- if(!glbl.GetDisableDNS()) {
- sigemptyset(&nmask);
- sigaddset(&nmask, SIGHUP);
- pthread_sigmask(SIG_BLOCK, &nmask, &omask);
-
- error = mygetnameinfo((struct sockaddr *)f, SALEN((struct sockaddr *) f),
- (char*)pszHostFQDN, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
-
- if (error == 0) {
- memset (&hints, 0, sizeof (struct addrinfo));
- hints.ai_flags = AI_NUMERICHOST;
-
- /* we now do a lookup once again. This one should fail,
- * because we should not have obtained a non-numeric address. If
- * we got a numeric one, someone messed with DNS!
- */
- if (getaddrinfo ((char*)pszHostFQDN, NULL, &hints, &res) == 0) {
- uchar szErrMsg[1024];
- freeaddrinfo (res);
- /* OK, we know we have evil. The question now is what to do about
- * it. One the one hand, the message might probably be intended
- * to harm us. On the other hand, losing the message may also harm us.
- * Thus, the behaviour is controlled by the $DropMsgsWithMaliciousDnsPTRRecords
- * option. If it tells us we should discard, we do so, else we proceed,
- * but log an error message together with it.
- * time being, we simply drop the name we obtained and use the IP - that one
- * is OK in any way. We do also log the error message. rgerhards, 2007-07-16
- */
- if(glbl.GetDropMalPTRMsgs() == 1) {
- snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
- "Malicious PTR record, message dropped "
- "IP = \"%s\" HOST = \"%s\"",
- ip, pszHostFQDN);
- errmsg.LogError(0, RS_RET_MALICIOUS_ENTITY, "%s", szErrMsg);
- pthread_sigmask(SIG_SETMASK, &omask, NULL);
- ABORT_FINALIZE(RS_RET_MALICIOUS_ENTITY);
- }
-
- /* Please note: we deal with a malicous entry. Thus, we have crafted
- * the snprintf() below so that all text is in front of the entry - maybe
- * it contains characters that make the message unreadable
- * (OK, I admit this is more or less impossible, but I am paranoid...)
- * rgerhards, 2007-07-16
- */
- snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
- "Malicious PTR record (message accepted, but used IP "
- "instead of PTR name: IP = \"%s\" HOST = \"%s\"",
- ip, pszHostFQDN);
- errmsg.LogError(0, NO_ERRCODE, "%s", szErrMsg);
-
- error = 1; /* that will trigger using IP address below. */
- }
- }
- pthread_sigmask(SIG_SETMASK, &omask, NULL);
- }
-
- if(error || glbl.GetDisableDNS()) {
- dbgprintf("Host name for your address (%s) unknown\n", ip);
- strcpy((char*) pszHostFQDN, (char*)ip);
- ABORT_FINALIZE(RS_RET_ADDRESS_UNKNOWN);
- }
-
-finalize_it:
- RETiRet;
-}
-
-
/* print out which socket we are listening on. This is only
* a debug aid. rgerhards, 2007-07-02
@@ -1229,7 +1128,7 @@ rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN
assert(pszHost != NULL);
assert(pszHostFQDN != NULL);
- iRet = gethname(f, pszHostFQDN, pszIP);
+ iRet = dnscacheLookup(f, pszHostFQDN, pszIP);
if(iRet == RS_RET_INVALID_SOURCE || iRet == RS_RET_ADDRESS_UNKNOWN) {
strcpy((char*) pszHost, (char*) pszHostFQDN); /* we use whatever was provided as replacement */
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index dd6764fa..7dd489e9 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -50,6 +50,7 @@
#include "nsdsel_ptcp.h"
#include "nsdpoll_ptcp.h"
#include "nsd_ptcp.h"
+#include "dnscache.h"
MODULE_TYPE_LIB
MODULE_TYPE_NOKEEP
@@ -260,38 +261,7 @@ FillRemHost(nsd_ptcp_t *pThis, struct sockaddr *pAddr)
ISOBJ_TYPE_assert(pThis, nsd_ptcp);
assert(pAddr != NULL);
- error = getnameinfo(pAddr, SALEN(pAddr), (char*)szIP, sizeof(szIP), NULL, 0, NI_NUMERICHOST);
-
- if(error) {
- dbgprintf("Malformed from address %s\n", gai_strerror(error));
- strcpy((char*)szHname, "???");
- strcpy((char*)szIP, "???");
- ABORT_FINALIZE(RS_RET_INVALID_HNAME);
- }
-
- if(!glbl.GetDisableDNS()) {
- error = getnameinfo(pAddr, SALEN(pAddr), (char*)szHname, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
- if(error == 0) {
- memset (&hints, 0, sizeof (struct addrinfo));
- hints.ai_flags = AI_NUMERICHOST;
- hints.ai_socktype = SOCK_STREAM;
- /* we now do a lookup once again. This one should fail,
- * because we should not have obtained a non-numeric address. If
- * we got a numeric one, someone messed with DNS!
- */
- if(getaddrinfo((char*)szHname, NULL, &hints, &res) == 0) {
- freeaddrinfo (res);
- /* OK, we know we have evil, so let's indicate this to our caller */
- snprintf((char*)szHname, NI_MAXHOST, "[MALICIOUS:IP=%s]", szIP);
- dbgprintf("Malicious PTR record, IP = \"%s\" HOST = \"%s\"", szIP, szHname);
- iRet = RS_RET_MALICIOUS_HNAME;
- }
- } else {
- strcpy((char*)szHname, (char*)szIP);
- }
- } else {
- strcpy((char*)szHname, (char*)szIP);
- }
+ CHKiRet(dnscacheLookup(pAddr, szHname, szIP));
/* We now have the names, so now let's allocate memory and store them permanently.
* (side note: we may hold on to these values for quite a while, thus we trim their
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 4c512ac2..bbace3de 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -124,6 +124,7 @@
#include "vm.h"
#include "prop.h"
#include "rsconf.h"
+#include "dnscache.h"
#include "sd-daemon.h"
/* definitions for objects we access */
@@ -1567,6 +1568,7 @@ InitGlobalClasses(void)
/* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */
pErrObj = "net";
CHKiRet(objUse(net, LM_NET_FILENAME));
+ dnscacheInit();
finalize_it:
if(iRet != RS_RET_OK) {
@@ -1615,6 +1617,7 @@ GlobalClassExit(void)
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(module, CORE_COMPONENT));
#endif
+ dnscacheDeinit();
rsrtExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */
RETiRet;