mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-17 23:20:42 +01:00
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
This commit is contained in:
parent
223b103ccc
commit
2b9e5ac193
@ -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
|
||||
|
||||
@ -8,6 +8,8 @@ librsyslog_la_SOURCES = \
|
||||
rsyslog.c \
|
||||
rsyslog.h \
|
||||
typedefs.h \
|
||||
dnscache.c \
|
||||
dnscache.h \
|
||||
unicode-helper.h \
|
||||
atomic.h \
|
||||
batch.h \
|
||||
|
||||
295
runtime/dnscache.c
Normal file
295
runtime/dnscache.c
Normal file
@ -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;
|
||||
}
|
||||
31
runtime/dnscache.h
Normal file
31
runtime/dnscache.h
Normal file
@ -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 */
|
||||
107
runtime/net.c
107
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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user