summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/dnscache.c97
-rw-r--r--runtime/dnscache.h2
-rw-r--r--runtime/net.c16
-rw-r--r--runtime/nsd_ptcp.c10
-rw-r--r--runtime/prop.c7
-rw-r--r--runtime/prop.h7
6 files changed, 85 insertions, 54 deletions
diff --git a/runtime/dnscache.c b/runtime/dnscache.c
index 5aa8a235..7e9ebf5b 100644
--- a/runtime/dnscache.c
+++ b/runtime/dnscache.c
@@ -33,6 +33,7 @@
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
+#include <ctype.h>
#include "syslogd-types.h"
#include "glbl.h"
@@ -47,9 +48,9 @@
/* module data structures */
struct dnscache_entry_s {
struct sockaddr_storage addr;
- uchar *pszHostFQDN;
+ prop_t *fqdn;
+ prop_t *fqdnLowerCase;
prop_t *ip;
- rs_size_t lenHost;
struct dnscache_entry_s *next;
unsigned nUsed;
};
@@ -101,9 +102,12 @@ key_equals_fn(void *key1, void *key2)
static void
entryDestruct(dnscache_entry_t *etry)
{
-dbgprintf("dnscache: entryDestruct %p:%s\n", etry, etry->pszHostFQDN);
- free(etry->pszHostFQDN);
- free(etry->ip);
+ if(etry->fqdn != NULL)
+ prop.Destruct(&etry->fqdn);
+ if(etry->fqdnLowerCase != NULL)
+ prop.Destruct(&etry->fqdnLowerCase);
+ if(etry->ip != NULL)
+ prop.Destruct(&etry->ip);
free(etry);
}
@@ -183,19 +187,19 @@ mygetnameinfo(const struct sockaddr *sa, socklen_t salen,
* message should be processed (1) or discarded (0).
*/
static rsRetVal
-resolveAddr(struct sockaddr_storage *addr, uchar *pszHostFQDN, prop_t **ip)
+resolveAddr(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase, prop_t **ip)
{
DEFiRet;
int error;
sigset_t omask, nmask;
struct addrinfo hints, *res;
char szIP[80]; /* large enough for IPv6 */
+ char fqdnBuf[NI_MAXHOST];
+ rs_size_t fqdnLen;
+ rs_size_t i;
- assert(addr != NULL);
- assert(pszHostFQDN != NULL);
-
error = mygetnameinfo((struct sockaddr *)addr, SALEN((struct sockaddr *)addr),
- (char*) szIP, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ (char*) szIP, sizeof(szIP), NULL, 0, NI_NUMERICHOST);
if(error) {
dbgprintf("Malformed from address %s\n", gai_strerror(error));
ABORT_FINALIZE(RS_RET_INVALID_SOURCE);
@@ -207,7 +211,7 @@ resolveAddr(struct sockaddr_storage *addr, uchar *pszHostFQDN, prop_t **ip)
pthread_sigmask(SIG_BLOCK, &nmask, &omask);
error = mygetnameinfo((struct sockaddr *)addr, SALEN((struct sockaddr *) addr),
- (char*)pszHostFQDN, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
+ fqdnBuf, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
if(error == 0) {
memset (&hints, 0, sizeof (struct addrinfo));
@@ -217,7 +221,7 @@ resolveAddr(struct sockaddr_storage *addr, uchar *pszHostFQDN, prop_t **ip)
* 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) {
+ if(getaddrinfo (fqdnBuf, NULL, &hints, &res) == 0) {
uchar szErrMsg[1024];
freeaddrinfo (res);
/* OK, we know we have evil. The question now is what to do about
@@ -233,7 +237,7 @@ resolveAddr(struct sockaddr_storage *addr, uchar *pszHostFQDN, prop_t **ip)
snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
"Malicious PTR record, message dropped "
"IP = \"%s\" HOST = \"%s\"",
- szIP, pszHostFQDN);
+ szIP, fqdnBuf);
errmsg.LogError(0, RS_RET_MALICIOUS_ENTITY, "%s", szErrMsg);
pthread_sigmask(SIG_SETMASK, &omask, NULL);
ABORT_FINALIZE(RS_RET_MALICIOUS_ENTITY);
@@ -248,28 +252,38 @@ resolveAddr(struct sockaddr_storage *addr, uchar *pszHostFQDN, prop_t **ip)
snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
"Malicious PTR record (message accepted, but used IP "
"instead of PTR name: IP = \"%s\" HOST = \"%s\"",
- szIP, pszHostFQDN);
+ szIP, fqdnBuf);
errmsg.LogError(0, NO_ERRCODE, "%s", szErrMsg);
error = 1; /* that will trigger using IP address below. */
+ } else {/* we have a valid entry, so let's create the respective properties */
+ fqdnLen = strlen(fqdnBuf);
+ prop.CreateStringProp(fqdn, (uchar*)fqdnBuf, fqdnLen);
+ for(i = 0 ; i < fqdnLen ; ++i)
+ fqdnBuf[i] = tolower(fqdnBuf[i]);
+ prop.CreateStringProp(fqdnLowerCase, (uchar*)fqdnBuf, fqdnLen);
}
}
pthread_sigmask(SIG_SETMASK, &omask, NULL);
}
- if(error || glbl.GetDisableDNS()) {
- dbgprintf("Host name for your address (%s) unknown\n", szIP);
- strcpy((char*) pszHostFQDN, (char*)szIP);
- }
finalize_it:
if(iRet != RS_RET_OK) {
strcpy(szIP, "?error.obtaining.ip?");
+ error = 1; /* trigger hostname copies below! */
}
+
/* we need to create the inputName property (only once during our lifetime) */
- prop.Construct(ip);
- prop.SetString(*ip, (uchar*)szIP, strlen(szIP));
- prop.ConstructFinalize(*ip);
+ prop.CreateStringProp(ip, (uchar*)szIP, strlen(szIP));
+
+ if(error || glbl.GetDisableDNS()) {
+ dbgprintf("Host name for your address (%s) unknown\n", szIP);
+ prop.AddRef(*ip);
+ *fqdn = *ip;
+ prop.AddRef(*ip);
+ *fqdnLowerCase = *ip;
+ }
RETiRet;
}
@@ -280,16 +294,11 @@ addEntry(struct sockaddr_storage *addr, dnscache_entry_t **pEtry)
{
int r;
struct sockaddr_storage *keybuf;
- uchar pszHostFQDN[NI_MAXHOST];
- prop_t *ip;
- dnscache_entry_t *etry;
+ dnscache_entry_t *etry = NULL;
DEFiRet;
- CHKiRet(resolveAddr(addr, pszHostFQDN, &ip));
CHKmalloc(etry = MALLOC(sizeof(dnscache_entry_t)));
- etry->lenHost = ustrlen(pszHostFQDN);
- CHKmalloc(etry->pszHostFQDN = ustrdup(pszHostFQDN));
- etry->ip = ip;
+ CHKiRet(resolveAddr(addr, &etry->fqdn, &etry->fqdnLowerCase, &etry->ip));
memcpy(&etry->addr, addr, SALEN((struct sockaddr*) addr));
etry->nUsed = 0;
*pEtry = etry;
@@ -307,6 +316,10 @@ addEntry(struct sockaddr_storage *addr, dnscache_entry_t **pEtry)
pthread_rwlock_rdlock(&dnsCache.rwlock); /* we need this again */
finalize_it:
+ if(iRet != RS_RET_OK && etry != NULL) {
+ /* Note: sub-fields cannot be populated in this case */
+ free(etry);
+ }
RETiRet;
}
@@ -324,10 +337,11 @@ validateEntry(dnscache_entry_t __attribute__((unused)) *etry, struct sockaddr_st
/* 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.
+ * If the entry can not be resolved, an error is reported back. If fqdn
+ * or fqdnLowerCase are NULL, they are not set.
*/
rsRetVal
-dnscacheLookup(struct sockaddr_storage *addr, uchar **pszHostFQDN, rs_size_t *lenHost,
+dnscacheLookup(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase,
prop_t **ip)
{
dnscache_entry_t *etry;
@@ -341,19 +355,30 @@ dnscacheLookup(struct sockaddr_storage *addr, uchar **pszHostFQDN, rs_size_t *le
} else {
CHKiRet(validateEntry(etry, addr));
}
- *pszHostFQDN = etry->pszHostFQDN;
- *lenHost = etry->lenHost;
- prop.AddRef(etry->ip);
*ip = etry->ip;
+ if(fqdn != NULL) {
+ prop.AddRef(etry->fqdn);
+ *fqdn = etry->fqdn;
+ }
+ if(fqdnLowerCase != NULL) {
+ prop.AddRef(etry->fqdnLowerCase);
+ *fqdnLowerCase = etry->fqdnLowerCase;
+ }
finalize_it:
pthread_rwlock_unlock(&dnsCache.rwlock);
-dbgprintf("XXXX: dnscacheLookup finished, iRet=%d\n", iRet);
if(iRet != RS_RET_OK && iRet != RS_RET_ADDRESS_UNKNOWN) {
DBGPRINTF("dnscacheLookup failed with iRet %d\n", iRet);
- *pszHostFQDN = (uchar*)"???";
- *lenHost = 3;
+ prop.AddRef(staticErrIPValue);
*ip = staticErrIPValue;
+ if(fqdn != NULL) {
+ prop.AddRef(staticErrIPValue);
+ *fqdn = staticErrIPValue;
+ }
+ if(fqdnLowerCase != NULL) {
+ prop.AddRef(staticErrIPValue);
+ *fqdnLowerCase = staticErrIPValue;
+ }
}
RETiRet;
}
diff --git a/runtime/dnscache.h b/runtime/dnscache.h
index ed60d9c5..7113c942 100644
--- a/runtime/dnscache.h
+++ b/runtime/dnscache.h
@@ -24,6 +24,6 @@
rsRetVal dnscacheInit(void);
rsRetVal dnscacheDeinit(void);
-rsRetVal dnscacheLookup(struct sockaddr_storage *addr, uchar **pszHostFQDN, rs_size_t *lenHost, prop_t **ip);
+rsRetVal dnscacheLookup(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase, prop_t **ip);
#endif /* #ifndef INCLUDED_DNSCACHE_H */
diff --git a/runtime/net.c b/runtime/net.c
index 5ec1b0b3..e5d8b4a4 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -70,6 +70,7 @@
#include "errmsg.h"
#include "net.h"
#include "dnscache.h"
+#include "prop.h"
#ifdef OS_SOLARIS
# define s6_addr32 _S6_un._S6_u32
@@ -83,6 +84,7 @@ MODULE_TYPE_NOKEEP
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
+DEFobjCurrIf(prop)
/* support for defining allowed TCP and UDP senders. We use the same
* structure to implement this (a linked list), but we define two different
@@ -1128,8 +1130,7 @@ void debugListenInfo(int fd, char *type)
rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN, prop_t **ip)
{
DEFiRet;
- uchar *host;
- rs_size_t lenHost;
+ prop_t *fqdnLowerCase;
register uchar *p;
int count;
int i;
@@ -1138,12 +1139,9 @@ rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN
assert(pszHost != NULL);
assert(pszHostFQDN != NULL);
- iRet = dnscacheLookup(f, &host, &lenHost, ip);
- /* Convert to lower case */
- for(i = 0 ; i < lenHost ; ++i) {
- pszHostFQDN[i] = tolower(host[i]);
- }
- pszHostFQDN [i] = '\0';
+ iRet = dnscacheLookup(f, NULL, &fqdnLowerCase, ip);
+ strcpy((char*)pszHostFQDN, (char*)propGetSzStr(fqdnLowerCase));
+ prop.Destruct(&fqdnLowerCase);
if(iRet == RS_RET_INVALID_SOURCE) {
strcpy((char*) pszHost, (char*) pszHostFQDN); /* we use whatever was provided as replacement */
@@ -1578,6 +1576,7 @@ BEGINObjClassExit(net, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO
CODESTARTObjClassExit(net)
/* release objects we no longer need */
objRelease(glbl, CORE_COMPONENT);
+ objRelease(prop, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
ENDObjClassExit(net)
@@ -1590,6 +1589,7 @@ BEGINAbstractObjClassInit(net, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(prop, CORE_COMPONENT));
/* set our own handlers */
ENDObjClassInit(net)
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index 630c8e68..c05397a6 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -252,23 +252,21 @@ Abort(nsd_t *pNsd)
static rsRetVal
FillRemHost(nsd_ptcp_t *pThis, struct sockaddr_storage *pAddr)
{
- uchar *szHname;
- rs_size_t lenHname;
+ prop_t *fqdn;
DEFiRet;
ISOBJ_TYPE_assert(pThis, nsd_ptcp);
assert(pAddr != NULL);
- CHKiRet(dnscacheLookup(pAddr, &szHname, &lenHname, &pThis->remoteIP));
+ CHKiRet(dnscacheLookup(pAddr, &fqdn, NULL, &pThis->remoteIP));
/* 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
* memory consumption)
*/
- lenHname++;
- if((pThis->pRemHostName = MALLOC(lenHname)) == NULL)
+ if((pThis->pRemHostName = MALLOC(prop.GetStringLen(fqdn+1))) == NULL)
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- memcpy(pThis->pRemHostName, szHname, lenHname);
+ memcpy(pThis->pRemHostName, propGetSzStr(fqdn), prop.GetStringLen(fqdn)+1);
finalize_it:
RETiRet;
diff --git a/runtime/prop.c b/runtime/prop.c
index 9d5927fd..a1f51ed1 100644
--- a/runtime/prop.c
+++ b/runtime/prop.c
@@ -100,7 +100,8 @@ static int GetStringLen(prop_t *pThis)
/* get string */
-static rsRetVal GetString(prop_t *pThis, uchar **ppsz, int *plen)
+rsRetVal
+propGetString(prop_t *pThis, uchar **ppsz, int *plen)
{
BEGINfunc
ISOBJ_TYPE_assert(pThis, prop);
@@ -173,7 +174,7 @@ rsRetVal CreateOrReuseStringProp(prop_t **ppThis, uchar *psz, int len)
CHKiRet(CreateStringProp(ppThis, psz, len));
} else {
/* already exists, check if we can re-use it */
- GetString(*ppThis, &pszPrev, &lenPrev);
+ propGetString(*ppThis, &pszPrev, &lenPrev);
if(len != lenPrev || ustrcmp(psz, pszPrev)) {
/* different, need to discard old & create new one */
propDestruct(ppThis);
@@ -212,7 +213,7 @@ CODESTARTobjQueryInterface(prop)
pIf->Destruct = propDestruct;
pIf->DebugPrint = propDebugPrint;
pIf->SetString = SetString;
- pIf->GetString = GetString;
+ pIf->GetString = propGetString;
pIf->GetStringLen = GetStringLen;
pIf->AddRef = AddRef;
pIf->CreateStringProp = CreateStringProp;
diff --git a/runtime/prop.h b/runtime/prop.h
index 40a35f9b..c7564e6b 100644
--- a/runtime/prop.h
+++ b/runtime/prop.h
@@ -52,6 +52,13 @@ ENDinterface(prop)
#define propCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+/* get classic c-style string */
+static inline uchar *
+propGetSzStr(prop_t *pThis)
+{
+ return(pThis->len < CONF_PROP_BUFSIZE) ? pThis->szVal.sz : pThis->szVal.psz;
+}
+
/* prototypes */
PROTOTYPEObj(prop);