diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-11-17 08:11:31 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-11-17 08:11:31 +0100 |
commit | 8c29f2843591376f8a1abca5f09a9740927f1000 (patch) | |
tree | e606312593700d4dda370879b3ec16cd0faf48d0 /runtime/msg.c | |
parent | 4d93afabe9b10f2f60ab52b2a5134d6c37050e1b (diff) | |
download | rsyslog-8c29f2843591376f8a1abca5f09a9740927f1000.tar.gz rsyslog-8c29f2843591376f8a1abca5f09a9740927f1000.tar.xz rsyslog-8c29f2843591376f8a1abca5f09a9740927f1000.zip |
moved DNS resolution code out of imudp and into the backend processing
Most importantly, DNS resolution now never happens if the resolved name
is not required. Note that this applies to imudp - for the other inputs,
DNS resolution almost comes for free, so we do not do it there. However,
the new method has been implemented in a generic way and as such may
also be used by other modules in the future.
Diffstat (limited to 'runtime/msg.c')
-rw-r--r-- | runtime/msg.c | 121 |
1 files changed, 104 insertions, 17 deletions
diff --git a/runtime/msg.c b/runtime/msg.c index 623c5b4a..0597ea84 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -35,6 +35,8 @@ #include <string.h> #include <assert.h> #include <ctype.h> +#include <sys/socket.h> +#include <netdb.h> #if HAVE_MALLOC_H # include <malloc.h> #endif @@ -51,6 +53,7 @@ #include "unicode-helper.h" #include "ruleset.h" #include "prop.h" +#include "net.h" /* static data */ DEFobjStaticHelpers @@ -59,6 +62,7 @@ DEFobjCurrIf(datetime) DEFobjCurrIf(glbl) DEFobjCurrIf(regexp) DEFobjCurrIf(prop) +DEFobjCurrIf(net) static struct { uchar *pszName; @@ -284,6 +288,41 @@ static inline int getProtocolVersion(msg_t *pM) } +/* do a DNS reverse resolution, if not already done, reflect status + * rgerhards, 2009-11-16 + */ +static inline rsRetVal +resolveDNS(msg_t *pMsg) { + rsRetVal localRet; + prop_t *propFromHost = NULL; + prop_t *propFromHostIP = NULL; + uchar fromHost[NI_MAXHOST]; + uchar fromHostIP[NI_MAXHOST]; + uchar fromHostFQDN[NI_MAXHOST]; + DEFiRet; + + CHKiRet(objUse(net, CORE_COMPONENT)); + if(pMsg->msgFlags & NEEDS_DNSRESOL) { + localRet = net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP); + if(localRet == RS_RET_OK) { + MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); + CHKiRet(MsgSetRcvFromIPStr(pMsg, fromHostIP, ustrlen(fromHostIP), &propFromHostIP)); + } + } +finalize_it: + if(iRet != RS_RET_OK) { + /* best we can do: remove property */ + MsgSetRcvFromStr(pMsg, UCHAR_CONSTANT(""), 0, &propFromHost); + prop.Destruct(&propFromHost); + } + if(propFromHost != NULL) + prop.Destruct(&propFromHost); + if(propFromHostIP != NULL) + prop.Destruct(&propFromHostIP); + RETiRet; +} + + static inline void getInputName(msg_t *pM, uchar **ppsz, int *plen) { @@ -307,6 +346,7 @@ getRcvFromIP(msg_t *pM) if(pM == NULL) { psz = UCHAR_CONSTANT(""); } else { + resolveDNS(pM); /* make sure we have a resolved entry */ if(pM->pRcvFromIP == NULL) psz = UCHAR_CONSTANT(""); else @@ -660,7 +700,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis) pM->pCSMSGID = NULL; pM->pInputName = NULL; pM->pRcvFromIP = NULL; - pM->pRcvFrom = NULL; + pM->rcvFrom.pRcvFrom = NULL; pM->pRuleset = NULL; memset(&pM->tRcvdAt, 0, sizeof(pM->tRcvdAt)); memset(&pM->tTIMESTAMP, 0, sizeof(pM->tTIMESTAMP)); @@ -761,8 +801,12 @@ CODESTARTobjDestruct(msg) freeHOSTNAME(pThis); if(pThis->pInputName != NULL) prop.Destruct(&pThis->pInputName); - if(pThis->pRcvFrom != NULL) - prop.Destruct(&pThis->pRcvFrom); + if((pThis->msgFlags & NEEDS_DNSRESOL) == 0) { + if(pThis->rcvFrom.pRcvFrom != NULL) + prop.Destruct(&pThis->rcvFrom.pRcvFrom); + } else { + free(pThis->rcvFrom.pfrominet); + } if(pThis->pRcvFromIP != NULL) prop.Destruct(&pThis->pRcvFromIP); free(pThis->pszRcvdAt3164); @@ -848,6 +892,7 @@ ENDobjDestruct(msg) msg_t* MsgDup(msg_t* pOld) { msg_t* pNew; + rsRetVal localRet; assert(pOld != NULL); @@ -868,9 +913,19 @@ msg_t* MsgDup(msg_t* pOld) pNew->iLenMSG = pOld->iLenMSG; pNew->iLenTAG = pOld->iLenTAG; pNew->iLenHOSTNAME = pOld->iLenHOSTNAME; - if(pOld->pRcvFrom != NULL) { - pNew->pRcvFrom = pOld->pRcvFrom; - prop.AddRef(pNew->pRcvFrom); + if((pOld->msgFlags & NEEDS_DNSRESOL) == 1) { + localRet = msgSetFromSockinfo(pNew, pOld->rcvFrom.pfrominet); + if(localRet != RS_RET_OK) { + /* if something fails, we accept loss of this property, it is + * better than losing the whole message. + */ + pNew->msgFlags &= ~NEEDS_DNSRESOL; + } + } else { + if(pOld->rcvFrom.pRcvFrom != NULL) { + pNew->rcvFrom.pRcvFrom = pOld->rcvFrom.pRcvFrom; + prop.AddRef(pNew->rcvFrom.pRcvFrom); + } } if(pOld->pRcvFromIP != NULL) { pNew->pRcvFromIP = pOld->pRcvFromIP; @@ -1648,12 +1703,13 @@ int getHOSTNAMELen(msg_t *pM) if(pM == NULL) return 0; else - if(pM->pszHOSTNAME == NULL) - if(pM->pRcvFrom == NULL) + if(pM->pszHOSTNAME == NULL) { + resolveDNS(pM); + if(pM->rcvFrom.pRcvFrom == NULL) return 0; else - return prop.GetStringLen(pM->pRcvFrom); - else + return prop.GetStringLen(pM->rcvFrom.pRcvFrom); + } else return pM->iLenHOSTNAME; } @@ -1664,12 +1720,13 @@ char *getHOSTNAME(msg_t *pM) return ""; else if(pM->pszHOSTNAME == NULL) { - if(pM->pRcvFrom == NULL) { + resolveDNS(pM); + if(pM->rcvFrom.pRcvFrom == NULL) { return ""; } else { uchar *psz; int len; - prop.GetString(pM->pRcvFrom, &psz, &len); + prop.GetString(pM->rcvFrom.pRcvFrom, &psz, &len); return (char*) psz; } } else { @@ -1683,13 +1740,15 @@ uchar *getRcvFrom(msg_t *pM) uchar *psz; int len; BEGINfunc + if(pM == NULL) { psz = UCHAR_CONSTANT(""); } else { - if(pM->pRcvFrom == NULL) + resolveDNS(pM); + if(pM->rcvFrom.pRcvFrom == NULL) psz = UCHAR_CONSTANT(""); else - prop.GetString(pM->pRcvFrom, &psz, &len); + prop.GetString(pM->rcvFrom.pRcvFrom, &psz, &len); } ENDfunc return psz; @@ -1845,6 +1904,28 @@ void MsgSetInputName(msg_t *pThis, prop_t *inputName) } +/* Set the pfrominet socket store, so that we can obtain the peer at some + * later time. Note that we do not check if pRcvFrom is already set, so this + * function must only be called during message creation. + * NOTE: msgFlags is NOT set. While this is somewhat a violation of layers, + * it is done because it gains us some performance. So the caller must make + * sure the message flags are properly maintained. For all current callers, + * this is always the case and without extra effort required. + * rgerhards, 2009-11-17 + */ +rsRetVal +msgSetFromSockinfo(msg_t *pThis, struct sockaddr_storage *sa){ + DEFiRet; + assert(pThis->rcvFrom.pRcvFrom == NULL); + + CHKmalloc(pThis->rcvFrom.pfrominet = malloc(sizeof(struct sockaddr_storage))); + memcpy(pThis->rcvFrom.pfrominet, sa, sizeof(struct sockaddr_storage)); + +finalize_it: + RETiRet; +} + + /* rgerhards 2008-09-10: set RcvFrom name in msg object. This calls AddRef() * on the property, because this must be done in all current cases and there * is no case expected where this may not be necessary. @@ -1855,9 +1936,15 @@ void MsgSetRcvFrom(msg_t *pThis, prop_t *new) assert(pThis != NULL); prop.AddRef(new); - if(pThis->pRcvFrom != NULL) - prop.Destruct(&pThis->pRcvFrom); - pThis->pRcvFrom = 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; } |