summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-01-22 16:55:21 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2013-01-22 16:55:21 +0100
commit35bec820b601bfcf9eff314fbfc718bb8949bda1 (patch)
treee67ec971d8d89df26727330e527df955535410f3
parent45d11af0b9975937e536d1c9b6d7bdaff5ade1b0 (diff)
downloadrsyslog-35bec820b601bfcf9eff314fbfc718bb8949bda1.tar.gz
rsyslog-35bec820b601bfcf9eff314fbfc718bb8949bda1.tar.bz2
rsyslog-35bec820b601bfcf9eff314fbfc718bb8949bda1.zip
optimze: reduce memory operations during dns resolution/hostname setting
previously, hostname and ip strings were shuffled to the msg object, which created a property out of them. Now the cache holds the property, and it is resused (almost) everywhere, what saves a lot of memory operations. The only exception is imtcp session setup, where different handling of the hostname is done, which we need to sort out (but that's another story).
-rw-r--r--runtime/dnscache.c100
-rw-r--r--runtime/dnscache.h2
-rw-r--r--runtime/msg.c58
-rw-r--r--runtime/net.c86
-rw-r--r--runtime/net.h2
-rw-r--r--runtime/nsd_ptcp.c2
-rw-r--r--runtime/prop.c7
-rw-r--r--tools/syslogd.c12
8 files changed, 145 insertions, 124 deletions
diff --git a/runtime/dnscache.c b/runtime/dnscache.c
index ef168f23..2096aa36 100644
--- a/runtime/dnscache.c
+++ b/runtime/dnscache.c
@@ -50,6 +50,7 @@ struct dnscache_entry_s {
struct sockaddr_storage addr;
prop_t *fqdn;
prop_t *fqdnLowerCase;
+ prop_t *localName; /* only local name, without domain part (if configured so) */
prop_t *ip;
struct dnscache_entry_s *next;
unsigned nUsed;
@@ -106,6 +107,8 @@ entryDestruct(dnscache_entry_t *etry)
prop.Destruct(&etry->fqdn);
if(etry->fqdnLowerCase != NULL)
prop.Destruct(&etry->fqdnLowerCase);
+ if(etry->localName != NULL)
+ prop.Destruct(&etry->localName);
if(etry->ip != NULL)
prop.Destruct(&etry->ip);
free(etry);
@@ -177,6 +180,73 @@ mygetnameinfo(const struct sockaddr *sa, socklen_t salen,
}
+/* get only the local part of the hostname and set it in cache entry */
+static inline void
+setLocalHostName(dnscache_entry_t *etry)
+{
+ uchar *fqdnLower;
+ uchar *p;
+ int count;
+ int i;
+ uchar hostbuf[NI_MAXHOST];
+
+ if(glbl.GetPreserveFQDN()) {
+ prop.AddRef(etry->fqdnLowerCase);
+ etry->localName = etry->fqdnLowerCase;
+ goto done;
+ }
+
+ /* strip domain, if configured for this entry */
+ fqdnLower = propGetSzStr(etry->fqdnLowerCase);
+ p = (uchar*)strchr((char*)fqdnLower, '.'); /* find start of domain name "machine.example.com" */
+ if(p == NULL) { /* do we have a domain part? */
+ prop.AddRef(etry->fqdnLowerCase); /* no! */
+ etry->localName = etry->fqdnLowerCase;
+ goto done;
+ }
+
+ i = p - fqdnLower; /* length of hostname */
+ memcpy(hostbuf, fqdnLower, i);
+ /* now check if we belong to any of the domain names that were specified
+ * in the -s command line option. If so, remove and we are done.
+ */
+ if(glbl.GetStripDomains() != NULL) {
+ count=0;
+ while(glbl.GetStripDomains()[count]) {
+ if(strcmp((char*)(p + 1), glbl.GetStripDomains()[count]) == 0) {
+ prop.CreateStringProp(&etry->localName, hostbuf, i);
+ goto done;
+ }
+ count++;
+ }
+ }
+ /* if we reach this point, we have not found any domain we should strip. Now
+ * we try and see if the host itself is listed in the -l command line option
+ * and so should be stripped also. If so, we do it and return. Please note that
+ * -l list FQDNs, not just the hostname part. If it did just list the hostname, the
+ * door would be wide-open for all kinds of mixing up of hosts. Because of this,
+ * you'll see comparison against the full string (pszHostFQDN) below.
+ */
+ if(glbl.GetLocalHosts() != NULL) {
+ count=0;
+ while(glbl.GetLocalHosts()[count]) {
+ if(!strcmp((char*)fqdnLower, (char*)glbl.GetLocalHosts()[count])) {
+ prop.CreateStringProp(&etry->localName, hostbuf, i);
+ goto done;
+ }
+ count++;
+ }
+ }
+
+ /* at this point, we have not found anything, so we again use the
+ * already-created complete full name property.
+ */
+ prop.AddRef(etry->fqdnLowerCase);
+ etry->localName = etry->fqdnLowerCase;
+done: return;
+}
+
+
/* resolve an address.
*
* Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats)
@@ -187,7 +257,7 @@ mygetnameinfo(const struct sockaddr *sa, socklen_t salen,
* message should be processed (1) or discarded (0).
*/
static rsRetVal
-resolveAddr(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase, prop_t **ip)
+resolveAddr(struct sockaddr_storage *addr, dnscache_entry_t *etry)
{
DEFiRet;
int error;
@@ -258,10 +328,10 @@ resolveAddr(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase
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);
+ prop.CreateStringProp(&etry->fqdn, (uchar*)fqdnBuf, fqdnLen);
for(i = 0 ; i < fqdnLen ; ++i)
fqdnBuf[i] = tolower(fqdnBuf[i]);
- prop.CreateStringProp(fqdnLowerCase, (uchar*)fqdnBuf, fqdnLen);
+ prop.CreateStringProp(&etry->fqdnLowerCase, (uchar*)fqdnBuf, fqdnLen);
}
}
pthread_sigmask(SIG_SETMASK, &omask, NULL);
@@ -275,16 +345,18 @@ finalize_it:
}
/* we need to create the inputName property (only once during our lifetime) */
- prop.CreateStringProp(ip, (uchar*)szIP, strlen(szIP));
+ prop.CreateStringProp(&etry->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;
+ prop.AddRef(etry->ip);
+ etry->fqdn = etry->ip;
+ prop.AddRef(etry->ip);
+ etry->fqdnLowerCase = etry->ip;
}
+ setLocalHostName(etry);
+
RETiRet;
}
@@ -298,7 +370,7 @@ addEntry(struct sockaddr_storage *addr, dnscache_entry_t **pEtry)
DEFiRet;
CHKmalloc(etry = MALLOC(sizeof(dnscache_entry_t)));
- CHKiRet(resolveAddr(addr, &etry->fqdn, &etry->fqdnLowerCase, &etry->ip));
+ CHKiRet(resolveAddr(addr, etry));
memcpy(&etry->addr, addr, SALEN((struct sockaddr*) addr));
etry->nUsed = 0;
*pEtry = etry;
@@ -342,7 +414,7 @@ validateEntry(dnscache_entry_t __attribute__((unused)) *etry, struct sockaddr_st
*/
rsRetVal
dnscacheLookup(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase,
- prop_t **ip)
+ prop_t **localName, prop_t **ip)
{
dnscache_entry_t *etry;
DEFiRet;
@@ -365,6 +437,10 @@ dnscacheLookup(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerC
prop.AddRef(etry->fqdnLowerCase);
*fqdnLowerCase = etry->fqdnLowerCase;
}
+ if(localName != NULL) {
+ prop.AddRef(etry->localName);
+ *localName = etry->localName;
+ }
finalize_it:
pthread_rwlock_unlock(&dnsCache.rwlock);
@@ -380,6 +456,10 @@ finalize_it:
prop.AddRef(staticErrValue);
*fqdnLowerCase = staticErrValue;
}
+ if(localName != NULL) {
+ prop.AddRef(staticErrValue);
+ *localName = staticErrValue;
+ }
}
RETiRet;
}
diff --git a/runtime/dnscache.h b/runtime/dnscache.h
index 7113c942..9c21a645 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, prop_t **fqdn, prop_t **fqdnLowerCase, prop_t **ip);
+rsRetVal dnscacheLookup(struct sockaddr_storage *addr, prop_t **fqdn, prop_t **fqdnLowerCase, prop_t **localName, prop_t **ip);
#endif /* #ifndef INCLUDED_DNSCACHE_H */
diff --git a/runtime/msg.c b/runtime/msg.c
index 86c2e68c..68577ad0 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -337,6 +337,37 @@ MsgUnlock(msg_t *pThis)
}
+/* set RcvFromIP name in msg object WITHOUT calling AddRef.
+ * rgerhards, 2013-01-22
+ */
+static inline void
+MsgSetRcvFromIPWithoutAddRef(msg_t *pThis, prop_t *new)
+{
+ if(pThis->pRcvFromIP != NULL)
+ prop.Destruct(&pThis->pRcvFromIP);
+ pThis->pRcvFromIP = new;
+}
+
+
+/* set RcvFrom name in msg object WITHOUT calling AddRef.
+ * rgerhards, 2013-01-22
+ */
+void MsgSetRcvFromWithoutAddRef(msg_t *pThis, prop_t *new)
+{
+ assert(pThis != NULL);
+
+ if(pThis->msgFlags & NEEDS_DNSRESOL) {
+ if(pThis->rcvFrom.pfrominet != NULL)
+ free(pThis->rcvFrom.pfrominet);
+ pThis->msgFlags &= ~NEEDS_DNSRESOL;
+ } else {
+ if(pThis->rcvFrom.pRcvFrom != NULL)
+ prop.Destruct(&pThis->rcvFrom.pRcvFrom);
+ }
+ pThis->rcvFrom.pRcvFrom = new;
+}
+
+
/* rgerhards 2012-04-18: set associated ruleset (by ruleset name)
* If ruleset cannot be found, no update is done.
*/
@@ -361,18 +392,17 @@ resolveDNS(msg_t *pMsg) {
rsRetVal localRet;
prop_t *propFromHost = NULL;
prop_t *ip;
- uchar fromHost[NI_MAXHOST];
- uchar fromHostFQDN[NI_MAXHOST];
+ prop_t *localName;
DEFiRet;
MsgLock(pMsg);
CHKiRet(objUse(net, CORE_COMPONENT));
if(pMsg->msgFlags & NEEDS_DNSRESOL) {
- localRet = net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN,
- &ip);
+ localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
if(localRet == RS_RET_OK) {
- MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost);
- CHKiRet(MsgSetRcvFromIP(pMsg, ip));
+ /* we pass down the props, so no need for AddRef */
+ MsgSetRcvFromWithoutAddRef(pMsg, localName);
+ MsgSetRcvFromIPWithoutAddRef(pMsg, ip);
}
}
finalize_it:
@@ -2207,18 +2237,8 @@ finalize_it:
*/
void MsgSetRcvFrom(msg_t *pThis, prop_t *new)
{
- assert(pThis != NULL);
-
prop.AddRef(new);
- if(pThis->msgFlags & NEEDS_DNSRESOL) {
- if(pThis->rcvFrom.pfrominet != NULL)
- free(pThis->rcvFrom.pfrominet);
- pThis->msgFlags &= ~NEEDS_DNSRESOL;
- } else {
- if(pThis->rcvFrom.pRcvFrom != NULL)
- prop.Destruct(&pThis->rcvFrom.pRcvFrom);
- }
- pThis->rcvFrom.pRcvFrom = new;
+ MsgSetRcvFromWithoutAddRef(pThis, new);
}
@@ -2251,9 +2271,7 @@ rsRetVal MsgSetRcvFromIP(msg_t *pThis, prop_t *new)
BEGINfunc
prop.AddRef(new);
- if(pThis->pRcvFromIP != NULL)
- prop.Destruct(&pThis->pRcvFromIP);
- pThis->pRcvFromIP = new;
+ MsgSetRcvFromIPWithoutAddRef(pThis, new);
ENDfunc
return RS_RET_OK;
}
diff --git a/runtime/net.c b/runtime/net.c
index e5d8b4a4..b291213e 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1117,91 +1117,15 @@ void debugListenInfo(int fd, char *type)
}
-/* Return a printable representation of a host address.
- * Now (2007-07-16) also returns the full host name (if it could be obtained)
- * in the second param [thanks to mildew@gmail.com for the patch].
- * The caller must provide buffer space for pszHost and pszHostFQDN. These
- * buffers must be of size NI_MAXHOST. This is not checked here, because
- * there is no way to check it. We use this way of doing things because it
- * frees us from using dynamic memory allocation where it really does not
- * pay.
- * 2005-05-16 rgerhards: added IP representation. Must also be NI_MAXHOST
+/* Return a printable representation of a host addresses. If
+ * a parameter is NULL, it is not set. rgerhards, 2013-01-22
*/
-rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN, prop_t **ip)
+rsRetVal
+cvthname(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t **ip)
{
DEFiRet;
- prop_t *fqdnLowerCase;
- register uchar *p;
- int count;
- int i;
-
assert(f != NULL);
- assert(pszHost != NULL);
- assert(pszHostFQDN != NULL);
-
- 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 */
- ABORT_FINALIZE(RS_RET_OK); /* this is handled, we are happy with it */
- } else if(iRet != RS_RET_OK) {
- FINALIZE; /* we return whatever error state we have - can not handle it */
- }
-
- /* OK, the fqdn is now known. Now it is time to extract only the hostname
- * part if we were instructed to do so.
- */
- if(glbl.GetPreserveFQDN()) {
- strcpy((char*)pszHost, (char*)pszHostFQDN);
- } else { /* strip domain, if configured for this entry */
- p = (uchar*)strchr((char*)pszHostFQDN, '.'); /* find start of domain name "machine.example.com" */
- if(p == NULL) { /* do we have a domain part? */
- strcpy((char*)pszHost, (char*)pszHostFQDN); /* no! */
- } else {
- i = p - pszHostFQDN; /* length of hostname */
- memcpy(pszHost, pszHostFQDN, i);
- /* now check if we belong to any of the domain names that were specified
- * in the -s command line option. If so, remove and we are done.
- */
- if(glbl.GetStripDomains() != NULL) {
- count=0;
- while(glbl.GetStripDomains()[count]) {
- if(strcmp((char*)(p + 1), glbl.GetStripDomains()[count]) == 0) {
- pszHost[i] = '\0';
- FINALIZE; /* we are done */
- }
- count++;
- }
- }
- /* if we reach this point, we have not found any domain we should strip. Now
- * we try and see if the host itself is listed in the -l command line option
- * and so should be stripped also. If so, we do it and return. Please note that
- * -l list FQDNs, not just the hostname part. If it did just list the hostname, the
- * door would be wide-open for all kinds of mixing up of hosts. Because of this,
- * you'll see comparison against the full string (pszHostFQDN) below. The termination
- * still occurs at *p, which points at the first dot after the hostname.
- * TODO: this must also go away - see comment above -- rgerhards, 2008-04-16
- */
- if(glbl.GetLocalHosts() != NULL) {
- count=0;
- while (glbl.GetLocalHosts()[count]) {
- if (!strcmp((char*)pszHostFQDN, (char*)glbl.GetLocalHosts()[count])) {
- pszHost[i] = '\0';
- FINALIZE; /* we are done */
- }
- count++;
- }
- }
- /* at this point, we have not found anything, so we need to copy
- * over the rest.
- */
- strcpy((char*)pszHost+i, (char*)p);
- }
- }
-
-finalize_it:
+ iRet = dnscacheLookup(f, NULL, fqdn, localName, ip);
RETiRet;
}
diff --git a/runtime/net.h b/runtime/net.h
index ec8ad5d8..b196116b 100644
--- a/runtime/net.h
+++ b/runtime/net.h
@@ -131,7 +131,7 @@ struct permittedPeers_s {
/* interfaces */
BEGINinterface(net) /* name must also be changed in ENDinterface macro! */
- rsRetVal (*cvthname)(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN, prop_t **ip);
+ rsRetVal (*cvthname)(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t **ip);
/* things to go away after proper modularization */
rsRetVal (*addAllowedSenderLine)(char* pName, uchar** ppRestOfConfLine);
void (*PrintAllowedSenders)(int iListToPrint);
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index ebfed722..f889a00e 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -258,7 +258,7 @@ FillRemHost(nsd_ptcp_t *pThis, struct sockaddr_storage *pAddr)
ISOBJ_TYPE_assert(pThis, nsd_ptcp);
assert(pAddr != NULL);
- CHKiRet(dnscacheLookup(pAddr, &fqdn, NULL, &pThis->remoteIP));
+ CHKiRet(dnscacheLookup(pAddr, &fqdn, NULL, 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
diff --git a/runtime/prop.c b/runtime/prop.c
index a1f51ed1..cb89fac0 100644
--- a/runtime/prop.c
+++ b/runtime/prop.c
@@ -100,8 +100,7 @@ static int GetStringLen(prop_t *pThis)
/* get string */
-rsRetVal
-propGetString(prop_t *pThis, uchar **ppsz, int *plen)
+rsRetVal GetString(prop_t *pThis, uchar **ppsz, int *plen)
{
BEGINfunc
ISOBJ_TYPE_assert(pThis, prop);
@@ -174,7 +173,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 */
- propGetString(*ppThis, &pszPrev, &lenPrev);
+ GetString(*ppThis, &pszPrev, &lenPrev);
if(len != lenPrev || ustrcmp(psz, pszPrev)) {
/* different, need to discard old & create new one */
propDestruct(ppThis);
@@ -213,7 +212,7 @@ CODESTARTobjQueryInterface(prop)
pIf->Destruct = propDestruct;
pIf->DebugPrint = propDebugPrint;
pIf->SetString = SetString;
- pIf->GetString = propGetString;
+ pIf->GetString = GetString;
pIf->GetStringLen = GetStringLen;
pIf->AddRef = AddRef;
pIf->CreateStringProp = CreateStringProp;
diff --git a/tools/syslogd.c b/tools/syslogd.c
index e33c2f4b..ae1b3de5 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -500,9 +500,9 @@ finalize_it:
*/
static inline rsRetVal
preprocessBatch(batch_t *pBatch) {
- uchar fromHost[NI_MAXHOST];
- uchar fromHostFQDN[NI_MAXHOST];
prop_t *ip;
+ prop_t *fqdn;
+ prop_t *localName;
prop_t *propFromHost = NULL;
prop_t *propFromHostIP = NULL;
int bSingleRuleset;
@@ -520,17 +520,17 @@ preprocessBatch(batch_t *pBatch) {
pMsg = pBatch->pElem[i].pMsg;
if((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) {
DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n");
- if(net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, &ip) != RS_RET_OK)
+ if(net.cvthname(pMsg->rcvFrom.pfrominet, &localName, &fqdn, &ip) != RS_RET_OK)
continue;
bIsPermitted = net.isAllowedSender2((uchar*)"UDP",
- (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)fromHostFQDN, 1);
+ (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char*)propGetSzStr(fqdn), 1);
if(!bIsPermitted) {
DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n",
- fromHostFQDN);
+ propGetSzStr(fqdn));
pBatch->eltState[i] = BATCH_STATE_DISC;
} else {
/* save some of the info we obtained */
- MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost);
+ MsgSetRcvFrom(pMsg, localName);
CHKiRet(MsgSetRcvFromIP(pMsg, ip));
pMsg->msgFlags &= ~NEEDS_ACLCHK_U;
}