summaryrefslogtreecommitdiffstats
path: root/runtime/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/msg.c')
-rw-r--r--runtime/msg.c172
1 files changed, 137 insertions, 35 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index 6424b03a..1b188263 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;
@@ -274,8 +278,13 @@ static char *syslog_severity_names[8] = { "emerg", "alert", "crit", "err", "warn
static char *syslog_number_names[24] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
"15", "16", "17", "18", "19", "20", "21", "22", "23" };
+/* global variables */
+#if defined(HAVE_MALLOC_TRIM) && !defined(HAVE_ATOMIC_BUILTINS)
+static pthread_mutex_t mutTrimCtr; /* mutex to handle malloc trim */
+#endif
+
/* some forward declarations */
-static int getAPPNAMELen(msg_t *pM, bool bLockMutex);
+static int getAPPNAMELen(msg_t *pM, sbool bLockMutex);
static inline int getProtocolVersion(msg_t *pM)
@@ -284,6 +293,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 +351,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 +705,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));
@@ -744,10 +789,13 @@ static inline void freeHOSTNAME(msg_t *pThis)
BEGINobjDestruct(msg) /* be sure to specify the object type also in END and CODESTART macros! */
int currRefCount;
+# if HAVE_MALLOC_TRIM
+ int currCnt;
+# endif
CODESTARTobjDestruct(msg)
/* DEV Debugging only ! dbgprintf("msgDestruct\t0x%lx, Ref now: %d\n", (unsigned long)pThis, pThis->iRefCount - 1); */
# ifdef HAVE_ATOMIC_BUILTINS
- currRefCount = ATOMIC_DEC_AND_FETCH(pThis->iRefCount);
+ currRefCount = ATOMIC_DEC_AND_FETCH(&pThis->iRefCount, NULL);
# else
MsgLock(pThis);
currRefCount = --pThis->iRefCount;
@@ -761,8 +809,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);
@@ -799,7 +851,8 @@ CODESTARTobjDestruct(msg)
* that we trim too often when the counter wraps.
*/
static unsigned iTrimCtr = 1;
- if(ATOMIC_INC_AND_FETCH(iTrimCtr) % 100000 == 0) {
+ currCnt = ATOMIC_INC_AND_FETCH(&iTrimCtr, &mutTrimCtr);
+ if(currCnt % 100000 == 0) {
malloc_trim(128*1024);
}
}
@@ -848,6 +901,7 @@ ENDobjDestruct(msg)
msg_t* MsgDup(msg_t* pOld)
{
msg_t* pNew;
+ rsRetVal localRet;
assert(pOld != NULL);
@@ -868,9 +922,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;
@@ -1000,7 +1064,7 @@ msg_t *MsgAddRef(msg_t *pM)
{
assert(pM != NULL);
# ifdef HAVE_ATOMIC_BUILTINS
- ATOMIC_INC(pM->iRefCount);
+ ATOMIC_INC(&pM->iRefCount, NULL);
# else
MsgLock(pM);
pM->iRefCount++;
@@ -1193,7 +1257,8 @@ static int getPRIi(msg_t *pM)
/* Get PRI value in text form
*/
-static inline char *getPRI(msg_t *pM)
+char *
+getPRI(msg_t *pM)
{
/* PRI is a number in the range 0..191. Thus, we use a simple lookup table to obtain the
* string value. It looks a bit clumpsy here in code ;)
@@ -1208,7 +1273,8 @@ static inline char *getPRI(msg_t *pM)
}
-static inline char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
+char *
+getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
{
BEGINfunc
if(pM == NULL)
@@ -1492,7 +1558,7 @@ finalize_it:
* This must be called WITHOUT the message lock being held.
* rgerhards, 2009-06-26
*/
-static inline void preparePROCID(msg_t *pM, bool bLockMutex)
+static inline void preparePROCID(msg_t *pM, sbool bLockMutex)
{
if(pM->pCSPROCID == NULL) {
if(bLockMutex == LOCK_MUTEX)
@@ -1509,7 +1575,7 @@ static inline void preparePROCID(msg_t *pM, bool bLockMutex)
#if 0
/* rgerhards, 2005-11-24
*/
-static inline int getPROCIDLen(msg_t *pM, bool bLockMutex)
+static inline int getPROCIDLen(msg_t *pM, sbool bLockMutex)
{
assert(pM != NULL);
preparePROCID(pM, bLockMutex);
@@ -1520,7 +1586,7 @@ static inline int getPROCIDLen(msg_t *pM, bool bLockMutex)
/* rgerhards, 2005-11-24
*/
-char *getPROCID(msg_t *pM, bool bLockMutex)
+char *getPROCID(msg_t *pM, sbool bLockMutex)
{
ISOBJ_TYPE_assert(pM, msg);
preparePROCID(pM, bLockMutex);
@@ -1599,7 +1665,7 @@ void MsgSetTAG(msg_t *pMsg, uchar* pszBuf, size_t lenBuf)
* if there is a TAG and, if not, if it can emulate it.
* rgerhards, 2005-11-24
*/
-static inline void tryEmulateTAG(msg_t *pM, bool bLockMutex)
+static inline void tryEmulateTAG(msg_t *pM, sbool bLockMutex)
{
size_t lenTAG;
uchar bufTAG[CONF_TAG_MAXSIZE];
@@ -1627,7 +1693,7 @@ static inline void tryEmulateTAG(msg_t *pM, bool bLockMutex)
}
-static inline void
+void
getTAG(msg_t *pM, uchar **ppBuf, int *piLen)
{
if(pM == NULL) {
@@ -1652,12 +1718,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;
}
@@ -1668,12 +1735,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 {
@@ -1687,13 +1755,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;
@@ -1740,7 +1810,7 @@ static inline char *getStructuredData(msg_t *pM)
/* check if we have a ProgramName, and, if not, try to aquire/emulate it.
* rgerhards, 2009-06-26
*/
-static inline void prepareProgramName(msg_t *pM, bool bLockMutex)
+static inline void prepareProgramName(msg_t *pM, sbool bLockMutex)
{
if(pM->pCSProgName == NULL) {
if(bLockMutex == LOCK_MUTEX)
@@ -1759,7 +1829,7 @@ static inline void prepareProgramName(msg_t *pM, bool bLockMutex)
/* get the length of the "programname" sz string
* rgerhards, 2005-10-19
*/
-int getProgramNameLen(msg_t *pM, bool bLockMutex)
+int getProgramNameLen(msg_t *pM, sbool bLockMutex)
{
assert(pM != NULL);
prepareProgramName(pM, bLockMutex);
@@ -1770,7 +1840,7 @@ int getProgramNameLen(msg_t *pM, bool bLockMutex)
/* get the "programname" as sz string
* rgerhards, 2005-10-19
*/
-uchar *getProgramName(msg_t *pM, bool bLockMutex)
+uchar *getProgramName(msg_t *pM, sbool bLockMutex)
{
prepareProgramName(pM, bLockMutex);
return (pM->pCSProgName == NULL) ? UCHAR_CONSTANT("") : rsCStrGetSzStrNoNULL(pM->pCSProgName);
@@ -1800,7 +1870,7 @@ static void tryEmulateAPPNAME(msg_t *pM)
* This must be called WITHOUT the message lock being held.
* rgerhards, 2009-06-26
*/
-static inline void prepareAPPNAME(msg_t *pM, bool bLockMutex)
+static inline void prepareAPPNAME(msg_t *pM, sbool bLockMutex)
{
if(pM->pCSAPPNAME == NULL) {
if(bLockMutex == LOCK_MUTEX)
@@ -1817,7 +1887,7 @@ static inline void prepareAPPNAME(msg_t *pM, bool bLockMutex)
/* rgerhards, 2005-11-24
*/
-char *getAPPNAME(msg_t *pM, bool bLockMutex)
+char *getAPPNAME(msg_t *pM, sbool bLockMutex)
{
assert(pM != NULL);
prepareAPPNAME(pM, bLockMutex);
@@ -1826,7 +1896,7 @@ char *getAPPNAME(msg_t *pM, bool bLockMutex)
/* rgerhards, 2005-11-24
*/
-static int getAPPNAMELen(msg_t *pM, bool bLockMutex)
+static int getAPPNAMELen(msg_t *pM, sbool bLockMutex)
{
assert(pM != NULL);
prepareAPPNAME(pM, bLockMutex);
@@ -1849,6 +1919,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.
@@ -1859,9 +1951,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;
}
@@ -3054,7 +3152,7 @@ static rsRetVal msgConstructFinalizer(msg_t *pThis)
* rgerhards, 2008-01-14
*/
static rsRetVal
-MsgGetSeverity(obj_t *pThis, int *piSeverity)
+MsgGetSeverity(obj_t_ptr pThis, int *piSeverity)
{
ISOBJ_TYPE_assert(pThis, msg);
assert(piSeverity != NULL);
@@ -3087,6 +3185,10 @@ BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE)
funcUnlock = MsgLockingDummy;
funcDeleteMutex = MsgLockingDummy;
funcMsgPrepareEnqueue = MsgLockingDummy;
+ /* some more inits */
+# if HAVE_MALLOC_TRIM
+ INIT_ATOMIC_HELPER_MUT(mutTrimCtr);
+# endif
ENDObjClassInit(msg)
/* vim:set ai:
*/