diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/batch.h | 13 | ||||
-rw-r--r-- | runtime/datetime.c | 5 | ||||
-rw-r--r-- | runtime/msg.c | 150 | ||||
-rw-r--r-- | runtime/msg.h | 8 | ||||
-rw-r--r-- | runtime/obj-types.h | 5 | ||||
-rw-r--r-- | runtime/parser.c | 17 | ||||
-rw-r--r-- | runtime/rsyslog.h | 1 | ||||
-rw-r--r-- | runtime/ruleset.c | 4 | ||||
-rw-r--r-- | runtime/stringbuf.c | 8 |
9 files changed, 100 insertions, 111 deletions
diff --git a/runtime/batch.h b/runtime/batch.h index 0f19f5bb..097e104a 100644 --- a/runtime/batch.h +++ b/runtime/batch.h @@ -34,13 +34,12 @@ * main message queue. But over time, it could potentially be useful to split the two. * rgerhad, 2009-05-12 */ -typedef enum { - BATCH_STATE_RDY = 0, /* object ready for processing */ - BATCH_STATE_BAD = 1, /* unrecoverable failure while processing, do NOT resubmit to same action */ - BATCH_STATE_SUB = 2, /* message submitted for processing, outcome yet unknown */ - BATCH_STATE_COMM = 3, /* message successfully commited */ - BATCH_STATE_DISC = 4, /* discarded - processed OK, but do not submit to any other action */ -} batch_state_t; +#define BATCH_STATE_RDY 0 /* object ready for processing */ +#define BATCH_STATE_BAD 1 /* unrecoverable failure while processing, do NOT resubmit to same action */ +#define BATCH_STATE_SUB 2 /* message submitted for processing, outcome yet unknown */ +#define BATCH_STATE_COMM 3 /* message successfully commited */ +#define BATCH_STATE_DISC 4 /* discarded - processed OK, but do not submit to any other action */ +typedef unsigned char batch_state_t; /* an object inside a batch, including any information (state!) needed for it to "life". diff --git a/runtime/datetime.c b/runtime/datetime.c index e839bf10..841ff625 100644 --- a/runtime/datetime.c +++ b/runtime/datetime.c @@ -182,12 +182,13 @@ getTime(time_t *ttSeconds) * the method always returns zero. * \retval The number parsed. */ -static int srSLMGParseInt32(uchar** ppsz, int *pLenStr) +static inline int +srSLMGParseInt32(uchar** ppsz, int *pLenStr) { register int i; i = 0; - while(*pLenStr > 0 && isdigit((int) **ppsz)) { + while(*pLenStr > 0 && **ppsz >= '0' && **ppsz <= '9') { i = i * 10 + **ppsz - '0'; ++(*ppsz); --(*pLenStr); diff --git a/runtime/msg.c b/runtime/msg.c index d16bbb75..390dd565 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -75,6 +75,18 @@ DEFobjCurrIf(prop) DEFobjCurrIf(net) DEFobjCurrIf(var) +static char *two_digits[100] = { + "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", + "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", + "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", + "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", + "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", + "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", + "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", + "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}; + static struct { uchar *pszName; short lenName; @@ -281,9 +293,15 @@ static char *syslog_fac_names[24] = { "kern", "user", "mail", "daemon", "auth", "news", "uucp", "cron", "authpriv", "ftp", "ntp", "audit", "alert", "clock", "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7" }; +/* length of the facility names string (for optimizatiions) */ +static short len_syslog_fac_names[24] = { 4, 4, 4, 6, 4, 6, 3, + 4, 4, 4, 8, 3, 3, 5, + 5, 5, 6, 6, 6, 6, + 6, 6, 6, 6 }; /* table of severity names (in numerical order)*/ static char *syslog_severity_names[8] = { "emerg", "alert", "crit", "err", "warning", "notice", "info", "debug" }; +static short len_syslog_severity_names[8] = { 5, 5, 4, 3, 7, 6, 4, 5 }; /* numerical values as string - this is the most efficient approach to convert severity * and facility values to a numerical string... -- rgerhars, 2009-06-17 @@ -634,6 +652,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis) pM->iRefCount = 1; pM->iSeverity = -1; pM->iFacility = -1; + pM->iLenPROGNAME = -1; pM->offAfterPRI = 0; pM->offMSG = -1; pM->iProtocolVersion = 0; @@ -652,7 +671,6 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis) pM->pszTIMESTAMP3339 = NULL; pM->pszTIMESTAMP_MySQL = NULL; pM->pszTIMESTAMP_PgSQL = NULL; - pM->pCSProgName = NULL; pM->pCSStrucData = NULL; pM->pCSAPPNAME = NULL; pM->pCSPROCID = NULL; @@ -795,8 +813,8 @@ CODESTARTobjDestruct(msg) free(pThis->pszRcvdAt_PgSQL); free(pThis->pszTIMESTAMP_MySQL); free(pThis->pszTIMESTAMP_PgSQL); - if(pThis->pCSProgName != NULL) - rsCStrDestruct(&pThis->pCSProgName); + if(pThis->iLenPROGNAME >= CONF_PROGNAME_BUFSIZE) + free(pThis->PROGNAME.ptr); if(pThis->pCSStrucData != NULL) rsCStrDestruct(&pThis->pCSStrucData); if(pThis->pCSAPPNAME != NULL) @@ -949,7 +967,6 @@ msg_t* MsgDup(msg_t* pOld) } } - tmpCOPYCSTR(ProgName); tmpCOPYCSTR(StrucData); tmpCOPYCSTR(APPNAME); tmpCOPYCSTR(PROCID); @@ -1297,32 +1314,33 @@ finalize_it: * The above definition has been taken from the FreeBSD syslogd sources. * * The program name is not parsed by default, because it is infrequently-used. - * If it is needed, this function should be called first. It checks if it is - * already set and extracts it, if not. - * * IMPORTANT: A locked message object must be provided, else a crash will occur. * rgerhards, 2005-10-19 */ -static rsRetVal aquireProgramName(msg_t *pM) +static inline rsRetVal +aquireProgramName(msg_t *pM) { - register int i; - uchar *pszTag; + int i; + uchar *pszTag, *pszProgName; DEFiRet; assert(pM != NULL); - if(pM->pCSProgName == NULL) { - /* ok, we do not yet have it. So let's parse the TAG to obtain it. */ - pszTag = (uchar*) ((pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG); - CHKiRet(cstrConstruct(&pM->pCSProgName)); - for( i = 0 - ; (i < pM->iLenTAG) && isprint((int) pszTag[i]) - && (pszTag[i] != '\0') && (pszTag[i] != ':') - && (pszTag[i] != '[') && (pszTag[i] != '/') - ; ++i) { - CHKiRet(cstrAppendChar(pM->pCSProgName, pszTag[i])); - } - CHKiRet(cstrFinalize(pM->pCSProgName)); + pszTag = (uchar*) ((pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG); + for( i = 0 + ; (i < pM->iLenTAG) && isprint((int) pszTag[i]) + && (pszTag[i] != '\0') && (pszTag[i] != ':') + && (pszTag[i] != '[') && (pszTag[i] != '/') + ; ++i) + ; /* just search end of PROGNAME */ + if(i < CONF_PROGNAME_BUFSIZE) { + pszProgName = pM->PROGNAME.szBuf; + } else { + CHKmalloc(pM->PROGNAME.ptr = malloc(i+1)); + pszProgName = pM->PROGNAME.ptr; } + memcpy((char*)pszProgName, (char*)pszTag, i); + pszProgName[i] = '\0'; + pM->iLenPROGNAME = i; finalize_it: RETiRet; } @@ -2059,53 +2077,20 @@ static inline char *getStructuredData(msg_t *pM) return (char*) pszRet; } -/* 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, sbool bLockMutex) -{ - if(pM->pCSProgName == NULL) { - if(bLockMutex == LOCK_MUTEX) - MsgLock(pM); - - /* re-query as things might have changed during locking */ - if(pM->pCSProgName == NULL) - aquireProgramName(pM); - - if(bLockMutex == LOCK_MUTEX) - MsgUnlock(pM); - } -} - - -/* get the length of the "programname" sz string - * rgerhards, 2005-10-19 - */ -int getProgramNameLen(msg_t *pM, sbool bLockMutex) -{ - assert(pM != NULL); - prepareProgramName(pM, bLockMutex); - return (pM->pCSProgName == NULL) ? 0 : rsCStrLen(pM->pCSProgName); -} - - /* get the "programname" as sz string * rgerhards, 2005-10-19 */ uchar *getProgramName(msg_t *pM, sbool bLockMutex) { - uchar *pszRet; - - if(bLockMutex == LOCK_MUTEX) + if(pM->iLenPROGNAME == -1 && bLockMutex == LOCK_MUTEX) { MsgLock(pM); - prepareProgramName(pM, MUTEX_ALREADY_LOCKED); - if(pM->pCSProgName == NULL) - pszRet = UCHAR_CONSTANT(""); - else - pszRet = rsCStrGetSzStrNoNULL(pM->pCSProgName); - if(bLockMutex == LOCK_MUTEX) + /* need to re-check, things may have change in between! */ + if(pM->iLenPROGNAME == -1) + aquireProgramName(pM); MsgUnlock(pM); - return pszRet; + } + return (pM->iLenPROGNAME < CONF_PROGNAME_BUFSIZE) ? pM->PROGNAME.szBuf + : pM->PROGNAME.ptr; } @@ -2420,21 +2405,20 @@ void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg) /* Decode a priority into textual information like auth.emerg. - * The variable pRes must point to a user-supplied buffer and - * pResLen must contain its size. The pointer to the buffer + * The variable pRes must point to a user-supplied buffer. + * The pointer to the buffer * is also returned, what makes this functiona suitable for * use in printf-like functions. * Note: a buffer size of 20 characters is always sufficient. - * Interface to this function changed 2007-06-15 by RGerhards */ -char *textpri(char *pRes, size_t pResLen, int pri) +char *textpri(char *pRes, int pri) { assert(pRes != NULL); - assert(pResLen > 0); - - snprintf(pRes, pResLen, "%s.%s", syslog_fac_names[LOG_FAC(pri)], - syslog_severity_names[LOG_PRI(pri)]); - + memcpy(pRes, syslog_fac_names[LOG_FAC(pri)], len_syslog_fac_names[LOG_FAC(pri)]); + pRes[len_syslog_fac_names[LOG_FAC(pri)]] = '.'; + memcpy(pRes+len_syslog_fac_names[LOG_FAC(pri)]+1, + syslog_severity_names[LOG_PRI(pri)], + len_syslog_severity_names[LOG_PRI(pri)]+1 /* for \0! */); return pRes; } @@ -2462,28 +2446,34 @@ static uchar *getNOW(eNOWType eNow, struct syslogTime *t) switch(eNow) { case NOW_NOW: - snprintf((char*) pBuf, tmpBUFSIZE, "%4.4d-%2.2d-%2.2d", t->year, t->month, t->day); + memcpy(pBuf, two_digits[t->year/100], 2); + memcpy(pBuf+2, two_digits[t->year%100], 2); + pBuf[4] = '-'; + memcpy(pBuf+5, two_digits[(int)t->month], 2); + pBuf[7] = '-'; + memcpy(pBuf+8, two_digits[(int)t->day], 3); break; case NOW_YEAR: - snprintf((char*) pBuf, tmpBUFSIZE, "%4.4d", t->year); + memcpy(pBuf, two_digits[t->year/100], 2); + memcpy(pBuf+2, two_digits[t->year%100], 3); break; case NOW_MONTH: - snprintf((char*) pBuf, tmpBUFSIZE, "%2.2d", t->month); + memcpy(pBuf, two_digits[(int)t->month], 3); break; case NOW_DAY: - snprintf((char*) pBuf, tmpBUFSIZE, "%2.2d", t->day); + memcpy(pBuf, two_digits[(int)t->day], 3); break; case NOW_HOUR: - snprintf((char*) pBuf, tmpBUFSIZE, "%2.2d", t->hour); + memcpy(pBuf, two_digits[(int)t->hour], 3); break; case NOW_HHOUR: - snprintf((char*) pBuf, tmpBUFSIZE, "%2.2d", t->minute / 30); + memcpy(pBuf, two_digits[t->hour/30], 3); break; case NOW_QHOUR: - snprintf((char*) pBuf, tmpBUFSIZE, "%2.2d", t->minute / 15); + memcpy(pBuf, two_digits[t->hour/15], 3); break; case NOW_MINUTE: - snprintf((char*) pBuf, tmpBUFSIZE, "%2.2d", t->minute); + memcpy(pBuf, two_digits[(int)t->minute], 3); break; } @@ -2829,7 +2819,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; - pRes = (uchar*)textpri((char*)pBuf, 20, getPRIi(pMsg)); + pRes = (uchar*)textpri((char*)pBuf, getPRIi(pMsg)); } break; case PROP_IUT: diff --git a/runtime/msg.h b/runtime/msg.h index c3acebd1..564441b6 100644 --- a/runtime/msg.h +++ b/runtime/msg.h @@ -76,6 +76,7 @@ struct msg { int iLenMSG; /* Length of the MSG part */ int iLenTAG; /* Length of the TAG part */ int iLenHOSTNAME; /* Length of HOSTNAME */ + int iLenPROGNAME; /* Length of PROGNAME (-1 = not yet set) */ uchar *pszRawMsg; /* message as it was received on the wire. This is important in case we * need to preserve cryptographic verifiers. */ uchar *pszHOSTNAME; /* HOSTNAME from syslog message */ @@ -87,7 +88,6 @@ struct msg { char *pszTIMESTAMP3339; /* TIMESTAMP as RFC3339 formatted string (32 charcters at most) */ char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 charcters) */ char *pszTIMESTAMP_PgSQL;/* TIMESTAMP as PgSQL formatted string (always 21 characters) */ - cstr_t *pCSProgName; /* the (BSD) program name */ cstr_t *pCSStrucData; /* STRUCTURED-DATA */ cstr_t *pCSAPPNAME; /* APP-NAME */ cstr_t *pCSPROCID; /* PROCID */ @@ -114,6 +114,10 @@ struct msg { uchar szRawMsg[CONF_RAWMSG_BUFSIZE]; /* most messages are small, and these are stored here (without malloc/free!) */ uchar szHOSTNAME[CONF_HOSTNAME_BUFSIZE]; union { + uchar *ptr; /* pointer to progname value */ + uchar szBuf[CONF_PROGNAME_BUFSIZE]; + } PROGNAME; + union { uchar *pszTAG; /* pointer to tag value */ uchar szBuf[CONF_TAG_BUFSIZE]; } TAG; @@ -175,7 +179,6 @@ rsRetVal MsgReplaceMSG(msg_t *pThis, uchar* pszMSG, int lenMSG); uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, propid_t propid, es_str_t *propName, rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow); -char *textpri(char *pRes, size_t pResLen, int pri); rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar); es_str_t* msgGetMsgVarNew(msg_t *pThis, uchar *name); uchar *getRcvFrom(msg_t *pM); @@ -200,7 +203,6 @@ int getMSGLen(msg_t *pM); char *getHOSTNAME(msg_t *pM); int getHOSTNAMELen(msg_t *pM); uchar *getProgramName(msg_t *pM, sbool bLockMutex); -int getProgramNameLen(msg_t *pM, sbool bLockMutex); uchar *getRcvFrom(msg_t *pM); rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID); uchar *propIDToName(propid_t propID); diff --git a/runtime/obj-types.h b/runtime/obj-types.h index da27a391..30a6a2c0 100644 --- a/runtime/obj-types.h +++ b/runtime/obj-types.h @@ -282,14 +282,12 @@ rsRetVal objName##ClassExit(void) \ rsRetVal OBJ##Destruct(OBJ##_t __attribute__((unused)) **ppThis) \ { \ DEFiRet; \ - int iCancelStateSave; \ OBJ##_t *pThis; #define CODESTARTobjDestruct(OBJ) \ ASSERT(ppThis != NULL); \ pThis = *ppThis; \ - ISOBJ_TYPE_assert(pThis, OBJ); \ - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); + ISOBJ_TYPE_assert(pThis, OBJ); /* note: there was a long-time bug in the macro below that lead to *ppThis = NULL * only when the object was actually destructed. I discovered this issue during @@ -309,7 +307,6 @@ rsRetVal objName##ClassExit(void) \ free(pThis); \ } \ *ppThis = NULL; \ - pthread_setcancelstate(iCancelStateSave, NULL); \ RETiRet; \ } diff --git a/runtime/parser.c b/runtime/parser.c index b40edf4c..74b28f4c 100644 --- a/runtime/parser.c +++ b/runtime/parser.c @@ -362,11 +362,10 @@ SanitizeMsg(msg_t *pMsg) */ int bNeedSanitize = 0; for(iSrc = 0 ; iSrc < lenMsg ; iSrc++) { - if(iscntrl(pszMsg[iSrc])) { + if(pszMsg[iSrc] < 32) { if(bSpaceLFOnRcv && pszMsg[iSrc] == '\n') pszMsg[iSrc] = ' '; - else - if(pszMsg[iSrc] == '\0' || bEscapeCCOnRcv) { + else if(pszMsg[iSrc] == '\0' || bEscapeCCOnRcv) { bNeedSanitize = 1; if (!bSpaceLFOnRcv) break; @@ -383,7 +382,9 @@ SanitizeMsg(msg_t *pMsg) FINALIZE; } - /* now copy over the message and sanitize it */ + /* now copy over the message and sanitize it. Note that up to iSrc-1 there was + * obviously no need to sanitize, so we can go over that quickly... + */ iMaxLine = glbl.GetMaxLine(); maxDest = lenMsg * 4; /* message can grow at most four-fold */ if(maxDest > iMaxLine) @@ -392,9 +393,13 @@ SanitizeMsg(msg_t *pMsg) pDst = szSanBuf; else CHKmalloc(pDst = MALLOC(sizeof(uchar) * (iMaxLine + 1))); - iSrc = iDst = 0; + if(iSrc > 0) { + iSrc--; /* go back to where everything is OK */ + memcpy(pDst, pszMsg, iSrc); /* fast copy known good */ + } + iDst = iSrc; while(iSrc < lenMsg && iDst < maxDest - 3) { /* leave some space if last char must be escaped */ - if(iscntrl((int) pszMsg[iSrc]) && (pszMsg[iSrc] != '\t' || bEscapeTab)) { + if((pszMsg[iSrc] < 32) && (pszMsg[iSrc] != '\t' || bEscapeTab)) { /* note: \0 must always be escaped, the rest of the code currently * can not handle it! -- rgerhards, 2009-08-26 */ diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 936a76e2..7e3761e0 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -46,6 +46,7 @@ #define CONF_HOSTNAME_MAXSIZE 512 /* a value that is deemed far too large for any valid HOSTNAME */ #define CONF_RAWMSG_BUFSIZE 101 #define CONF_TAG_BUFSIZE 32 +#define CONF_PROGNAME_BUFSIZE 16 #define CONF_HOSTNAME_BUFSIZE 32 #define CONF_PROP_BUFSIZE 16 /* should be close to sizeof(ptr) or lighly above it */ #define CONF_MIN_SIZE_FOR_COMPRESS 60 /* config param: minimum message size to try compression. The smaller diff --git a/runtime/ruleset.c b/runtime/ruleset.c index 21c3c337..16cb7cb3 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -401,12 +401,12 @@ evalPROPFILT(struct cnfstmt *stmt, msg_t *pMsg) break; case FIOP_ISEQUAL: if(rsCStrSzStrCmp(stmt->d.s_propfilt.pCSCompValue, - pszPropVal, ustrlen(pszPropVal)) == 0) + pszPropVal, propLen) == 0) bRet = 1; /* process message! */ break; case FIOP_STARTSWITH: if(rsCStrSzStrStartsWithCStr(stmt->d.s_propfilt.pCSCompValue, - pszPropVal, ustrlen(pszPropVal)) == 0) + pszPropVal, propLen) == 0) bRet = 1; /* process message! */ break; case FIOP_REGEX: diff --git a/runtime/stringbuf.c b/runtime/stringbuf.c index 5bca009d..d9f80231 100644 --- a/runtime/stringbuf.c +++ b/runtime/stringbuf.c @@ -870,13 +870,7 @@ int rsCStrSzStrCmp(cstr_t *pCS1, uchar *psz, size_t iLenSz) * length, so we need to actually check if they * are equal. */ - register size_t i; - for(i = 0 ; i < iLenSz ; ++i) { - if(pCS1->pBuf[i] != psz[i]) - return pCS1->pBuf[i] - psz[i]; - } - /* if we arrive here, the strings are equal */ - return 0; + return strncmp((char*)pCS1->pBuf, (char*)psz, iLenSz); } else return pCS1->iStrLen - iLenSz; |