summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-06-18 13:22:21 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2009-06-18 13:22:21 +0200
commit8628312396b1535c41124e499d292f4d1e77d955 (patch)
treed294b3fc3f9adc29b3b9137ce2bff55c21fdee81 /runtime
parentf529e8b2c3bb2c087bfba3fc5610a66fdbe1a8ae (diff)
downloadrsyslog-8628312396b1535c41124e499d292f4d1e77d955.tar.gz
rsyslog-8628312396b1535c41124e499d292f4d1e77d955.tar.xz
rsyslog-8628312396b1535c41124e499d292f4d1e77d955.zip
cleaned up/optimized raw message handling in msg object
Diffstat (limited to 'runtime')
-rw-r--r--runtime/msg.c43
-rw-r--r--runtime/msg.h7
-rw-r--r--runtime/parser.c79
3 files changed, 64 insertions, 65 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index d9ff2e73..be62e52f 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -510,7 +510,8 @@ CODESTARTobjDestruct(msg)
if(currRefCount == 0)
{
/* DEV Debugging Only! dbgprintf("msgDestruct\t0x%lx, RefCount now 0, doing DESTROY\n", (unsigned long)pThis); */
- free(pThis->pszRawMsg);
+ if(pThis->pszRawMsg != pThis->szRawMsg)
+ free(pThis->pszRawMsg);
free(pThis->pszTAG);
free(pThis->pszHOSTNAME);
free(pThis->pszInputName);
@@ -876,11 +877,12 @@ char *getMSG(msg_t *pM)
{
if(pM == NULL)
return "";
- else
+ else {
if(pM->pszMSG == NULL)
return "";
else
return (char*)pM->pszMSG;
+ }
}
@@ -1674,19 +1676,38 @@ void MsgSetMSG(msg_t *pMsg, char* pszMSG)
dbgprintf("MsgSetMSG could not allocate memory for pszMSG buffer.");
}
-/* rgerhards 2004-11-11: set RawMsg in msg object
+/* set raw message in message object. Size of message is provided.
+ * rgerhards, 2009-06-16
*/
-void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg)
+void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg, size_t lenMsg)
{
assert(pMsg != NULL);
- if(pMsg->pszRawMsg != NULL)
+ if(pMsg->pszRawMsg != pMsg->szRawMsg)
free(pMsg->pszRawMsg);
- pMsg->iLenRawMsg = strlen(pszRawMsg);
- if((pMsg->pszRawMsg = (uchar*) malloc(pMsg->iLenRawMsg + 1)) != NULL)
- memcpy(pMsg->pszRawMsg, pszRawMsg, pMsg->iLenRawMsg + 1);
- else
- dbgprintf("Could not allocate memory for pszRawMsg buffer.");
+ pMsg->iLenRawMsg = lenMsg;
+ if(pMsg->iLenRawMsg < CONF_RAWMSG_BUFSIZE) {
+ /* small enough: use fixed buffer (faster!) */
+ pMsg->pszRawMsg = pMsg->szRawMsg;
+ } else if((pMsg->pszRawMsg = (uchar*) malloc(pMsg->iLenRawMsg + 1)) == NULL) {
+ /* truncate message, better than completely loosing it... */
+ pMsg->pszRawMsg = pMsg->szRawMsg;
+ pMsg->iLenRawMsg = CONF_RAWMSG_BUFSIZE - 1;
+ }
+
+ memcpy(pMsg->pszRawMsg, pszRawMsg, pMsg->iLenRawMsg);
+ pMsg->pszRawMsg[pMsg->iLenRawMsg] = '\0'; /* this also works with truncation! */
+}
+
+
+/* set raw message in message object. Size of message is not provided. This
+ * function should only be used when it is unavoidable (and over time we should
+ * try to remove it altogether).
+ * rgerhards, 2009-06-16
+ */
+void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg)
+{
+ MsgSetRawMsg(pMsg, pszRawMsg, strlen(pszRawMsg));
}
@@ -2558,7 +2579,7 @@ rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp)
} else if(isProp("msgFlags")) {
pThis->msgFlags = pProp->val.num;
} else if(isProp("pszRawMsg")) {
- MsgSetRawMsg(pThis, (char*) rsCStrGetSzStrNoNULL(pProp->val.pStr));
+ MsgSetRawMsg(pThis, (char*) rsCStrGetSzStrNoNULL(pProp->val.pStr), cstrLen(pProp->val.pStr));
/* enable this, if someone actually uses UxTradMsg, delete after some time has
* passed and nobody complained -- rgerhards, 2009-06-16
} else if(isProp("offAfterPRI")) {
diff --git a/runtime/msg.h b/runtime/msg.h
index 703fdd9f..f2701780 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -28,6 +28,9 @@
#ifndef MSG_H_INCLUDED
#define MSG_H_INCLUDED 1
+/* some configuration constants */
+#define CONF_RAWMSG_BUFSIZE 101
+
#include <pthread.h>
#include "obj.h"
#include "syslogd-types.h"
@@ -109,6 +112,7 @@ struct msg {
int msgFlags; /* flags associated with this message */
ruleset_t *pRuleset; /* ruleset to be used for processing this message */
/* some fixed-size buffers to save malloc()/free() for frequently used fields (from the default templates) */
+ uchar szRawMsg[CONF_RAWMSG_BUFSIZE]; /* most messages are small, and these are stored here (without malloc/free!) */
char pszTimestamp3164[16];
char pszTimestamp3339[33];
};
@@ -149,7 +153,8 @@ void MsgAssignHOSTNAME(msg_t *pMsg, char *pBuf);
void MsgSetHOSTNAME(msg_t *pMsg, uchar* pszHOSTNAME);
rsRetVal MsgSetAfterPRIOffs(msg_t *pMsg, short offs);
void MsgSetMSG(msg_t *pMsg, char* pszMSG);
-void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg);
+void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg);
+void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg, size_t lenMsg);
void moveHOSTNAMEtoTAG(msg_t *pM);
char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
cstr_t *pCSPropName, unsigned short *pbMustBeFreed);
diff --git a/runtime/parser.c b/runtime/parser.c
index c13edb8f..75cde343 100644
--- a/runtime/parser.c
+++ b/runtime/parser.c
@@ -114,10 +114,8 @@ static inline rsRetVal uncompressMessage(msg_t *pMsg)
"Message ignored.", ret);
FINALIZE; /* unconditional exit, nothing left to do... */
}
- free(pMsg->pszRawMsg);
- pMsg->pszRawMsg = deflateBuf;
- pMsg->iLenRawMsg = iLenDefBuf;
- deflateBuf = NULL; /* logically "freed" - caller is now responsible */
+ MsgSetRawMsg(pMsg, (char*)deflateBuf, iLenDefBuf);
+ free(deflateBuf);
}
finalize_it:
if(deflateBuf != NULL)
@@ -165,6 +163,8 @@ sanitizeMessage(msg_t *pMsg)
size_t iSrc;
size_t iDst;
size_t iMaxLine;
+ size_t maxDest;
+ uchar szSanBuf[32*1024]; /* buffer used for sanitizing a string */
assert(pMsg != NULL);
@@ -205,70 +205,43 @@ sanitizeMessage(msg_t *pMsg)
}
}
}
- if(bNeedSanitize == 0) {
- /* what a shame - we do not have a \0 byte...
- * TODO: think about adding it or otherwise be able to use it...
- */
- uchar *pRaw;
- CHKmalloc(pRaw = realloc(pMsg->pszRawMsg, pMsg->iLenRawMsg + 1));
- pRaw[pMsg->iLenRawMsg] = '\0';
- pMsg->pszRawMsg = pRaw;
+
+ if(!bNeedSanitize)
FINALIZE;
- }
/* now copy over the message and sanitize it */
- /* TODO: can we get cheaper memory alloc? {alloca()?}*/
iMaxLine = glbl.GetMaxLine();
- CHKmalloc(pDst = malloc(sizeof(uchar) * (iMaxLine + 1)));
+ maxDest = lenMsg * 4; /* message can grow at most four-fold */
+ if(maxDest > iMaxLine)
+ maxDest = iMaxLine; /* but not more than the max size! */
+ if(maxDest < sizeof(szSanBuf))
+ pDst = szSanBuf;
+ else
+ CHKmalloc(pDst = malloc(sizeof(uchar) * (iMaxLine + 1)));
iSrc = iDst = 0;
- while(iSrc < lenMsg && iDst < iMaxLine) {
+ while(iSrc < lenMsg && iDst < maxDest - 3) { /* leave some space if last char must be escaped */
if(pszMsg[iSrc] == '\0') { /* guard against \0 characters... */
- /* changed to the sequence (somewhat) proposed in
- * draft-ietf-syslog-protocol-19. rgerhards, 2006-11-30
- */
- if(iDst + 3 < iMaxLine) { /* do we have space? */
- pDst[iDst++] = cCCEscapeChar;
- pDst[iDst++] = '0';
- pDst[iDst++] = '0';
- pDst[iDst++] = '0';
- } /* if we do not have space, we simply ignore the '\0'... */
- /* log an error? Very questionable... rgerhards, 2006-11-30 */
- /* decided: we do not log an error, it won't help... rger, 2007-06-21 */
- } else if(bEscapeCCOnRcv && iscntrl((int) pszMsg[iSrc])) {
+ } else if(iscntrl((int) pszMsg[iSrc])) {
+ if(pszMsg[iSrc] == '\0' || bEscapeCCOnRcv) {
/* we are configured to escape control characters. Please note
* that this most probably break non-western character sets like
* Japanese, Korean or Chinese. rgerhards, 2007-07-17
- * Note: sysklogd logs octal values only for DEL and CCs above 127.
- * For others, it logs ^n where n is the control char converted to an
- * alphabet character. We like consistency and thus escape it to octal
- * in all cases. If someone complains, we may change the mode. At least
- * we known now what's going on.
- * rgerhards, 2007-07-17
*/
- if(iDst + 3 < iMaxLine) { /* do we have space? */
- pDst[iDst++] = cCCEscapeChar;
- pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0300) >> 6);
- pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0070) >> 3);
- pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0007));
- } /* again, if we do not have space, we ignore the char - see comment at '\0' */
+ pDst[iDst++] = cCCEscapeChar;
+ pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0300) >> 6);
+ pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0070) >> 3);
+ pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0007));
+ }
} else {
pDst[iDst++] = pszMsg[iSrc];
}
++iSrc;
}
- pDst[iDst] = '\0'; /* space *is* reserved for this! */
-
- /* we have a sanitized string. Let's save it now */
- free(pMsg->pszRawMsg);
- if((pMsg->pszRawMsg = malloc((iDst+1) * sizeof(uchar))) == NULL) {
- /* when we get no new buffer, we use what we already have ;) */
- pMsg->pszRawMsg = pDst;
- } else {
- /* trim buffer */
- memcpy(pMsg->pszRawMsg, pDst, iDst+1);
- free(pDst); /* too big! */
- pMsg->iLenRawMsg = iDst;
- }
+
+ MsgSetRawMsg(pMsg, (char*)pDst, iDst); /* save sanitized string */
+
+ if(pDst != szSanBuf)
+ free(pDst);
finalize_it:
RETiRet;