diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | plugins/imfile/imfile.c | 1 | ||||
-rw-r--r-- | plugins/imudp/imudp.c | 15 | ||||
-rw-r--r-- | runtime/conf.c | 25 | ||||
-rw-r--r-- | runtime/conf.h | 4 | ||||
-rw-r--r-- | runtime/queue.c | 21 | ||||
-rw-r--r-- | runtime/rule.c | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rwxr-xr-x | tests/diag.sh | 2 | ||||
-rw-r--r-- | tests/nettester.c | 18 | ||||
-rwxr-xr-x | tests/parsertest.sh | 10 | ||||
-rw-r--r-- | tests/testsuites/parse2.conf | 8 | ||||
-rw-r--r-- | tests/testsuites/reallife.parse1 | 12 | ||||
-rw-r--r-- | tests/testsuites/reallife.parse2 | 12 | ||||
-rw-r--r-- | tools/syslogd.c | 16 |
15 files changed, 109 insertions, 48 deletions
@@ -8,6 +8,8 @@ Version 5.3.2 [DEVEL] (rgerhards), 2009-10-?? potential race conditions (in very unusual shutdown conditions) along the way. The threading model has seriously changes, so there may be some regressions. +--------------------------------------------------------------------------- +Version 5.3.2 [DEVEL] (rgerhards), 2009-10-21 - enhanced omfile to support transactional interface. This will increase performance in many cases. - added multi-ruleset support to imudp @@ -29,10 +31,13 @@ Version 5.3.2 [DEVEL] (rgerhards), 2009-10-?? used together with the new interface. The removal also enables us to drop a lot of duplicate code, reducing complexity and increasing maintainability. +- bugfix: segfault when starting up with an invalid .qi file for a disk queue + Failed for both pure disk as well as DA queues. Now, we emit an error + message and disable disk queueing facility. - bugfix: potential segfault on messages with empty MSG part. This was a recently introduced regression. - bugfix: debug string larger than 1K were improperly displayed. Max size - is now 32K, and if a string is even longer it is meaningful truncated. + is now 32K, and if a string is even longer it is meaningfully truncated. --------------------------------------------------------------------------- Version 5.3.1 [DEVEL] (rgerhards), 2009-10-05 - added $AbortOnUncleanConfig directive - permits to prevent startup when diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c index 955d5b14..8a10e26f 100644 --- a/plugins/imfile/imfile.c +++ b/plugins/imfile/imfile.c @@ -213,6 +213,7 @@ static rsRetVal pollFile(fileInfo_t *pThis, int *pbHadFileData) } finalize_it: + ; /*EMPTY STATEMENT - needed to keep compiler happy - see below! */ /* Note: the problem above is that pthread:cleanup_pop() is a macro which * evaluates to something like "} while(0);". So the code would become * "finalize_it: }", that is a label without a statement. The C standard does diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 5a1d9e8b..6ce8039f 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -117,8 +117,9 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal) if(udpLstnSocks == NULL) { /* esay, we can just replace it */ udpLstnSocks = newSocks; +RUNLOG_VAR("%d", newSocks[0]); CHKmalloc(udpRulesets = (ruleset_t**) malloc(sizeof(ruleset_t*) * (newSocks[0] + 1))); - for(iDst = 1 ; iDst < newSocks[0] ; ++iDst) + for(iDst = 1 ; iDst <= newSocks[0] ; ++iDst) udpRulesets[iDst] = pBindRuleset; } else { /* we need to add them */ @@ -136,13 +137,13 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal) } else { /* ready to copy */ iDst = 1; - for(iSrc = 1 ; iSrc <= udpLstnSocks[0] ; ++iSrc) { - tmpSocks[iDst++] = udpLstnSocks[iSrc]; - tmpRulesets[iDst++] = udpRulesets[iSrc]; + for(iSrc = 1 ; iSrc <= udpLstnSocks[0] ; ++iSrc, ++iDst) { + tmpSocks[iDst] = udpLstnSocks[iSrc]; + tmpRulesets[iDst] = udpRulesets[iSrc]; } - for(iSrc = 1 ; iSrc <= newSocks[0] ; ++iSrc) { - tmpSocks[iDst++] = newSocks[iSrc]; - tmpRulesets[iDst++] = pBindRuleset; + for(iSrc = 1 ; iSrc <= newSocks[0] ; ++iSrc, ++iDst) { + tmpSocks[iDst] = newSocks[iSrc]; + tmpRulesets[iDst] = pBindRuleset; } tmpSocks[0] = udpLstnSocks[0] + newSocks[0]; free(newSocks); diff --git a/runtime/conf.c b/runtime/conf.c index 2e37edf2..d6e6ccf6 100644 --- a/runtime/conf.c +++ b/runtime/conf.c @@ -95,17 +95,16 @@ DEFobjCurrIf(ruleset) static int iNbrActions = 0; /* number of currently defined actions */ -/* The following global variables are used for building +/* The following module-global variables are used for building * tag and host selector lines during startup and config reload. * This is stored as a global variable pool because of its ease. It is * also fairly compatible with multi-threading as the stratup code must - * be run in a single thread anyways. So there can be no race conditions. These - * variables are no longer used once the configuration has been loaded (except, - * of course, during a reload). rgerhards 2005-10-18 + * be run in a single thread anyways. So there can be no race conditions. + * rgerhards 2005-10-18 */ -EHostnameCmpMode eDfltHostnameCmpMode; -cstr_t *pDfltHostnameCmp; -cstr_t *pDfltProgNameCmp; +static EHostnameCmpMode eDfltHostnameCmpMode = HN_NO_COMP; +static cstr_t *pDfltHostnameCmp = NULL; +static cstr_t *pDfltProgNameCmp = NULL; /* process a directory and include all of its files into @@ -1038,7 +1037,7 @@ static rsRetVal cflineDoFilter(uchar **pp, rule_t *f) DEFiRet; ASSERT(pp != NULL); - ASSERT(f != NULL); + ISOBJ_TYPE_assert(f, rule); /* check which filter we need to pull... */ switch(**pp) { @@ -1060,6 +1059,7 @@ static rsRetVal cflineDoFilter(uchar **pp, rule_t *f) * and, if so, we copy them over. rgerhards, 2005-10-18 */ if(pDfltProgNameCmp != NULL) { +RUNLOG_STR("dflt ProgNameCmp != NULL, setting opCSProgNameComp"); CHKiRet(rsCStrConstructFromCStr(&(f->pCSProgNameComp), pDfltProgNameCmp)); } @@ -1248,6 +1248,15 @@ ENDobjQueryInterface(conf) */ BEGINObjClassExit(conf, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(conf) + /* free no-longer needed module-global variables */ + if(pDfltHostnameCmp != NULL) { + rsCStrDestruct(&pDfltHostnameCmp); + } + + if(pDfltProgNameCmp != NULL) { + rsCStrDestruct(&pDfltProgNameCmp); + } + /* release objects we no longer need */ objRelease(expr, CORE_COMPONENT); objRelease(ctok, CORE_COMPONENT); diff --git a/runtime/conf.h b/runtime/conf.h index 6db1623e..d85d1f82 100644 --- a/runtime/conf.h +++ b/runtime/conf.h @@ -49,10 +49,6 @@ ENDinterface(conf) PROTOTYPEObj(conf); -/* TODO: remove them below (means move the config init code) -- rgerhards, 2008-02-19 */ -extern EHostnameCmpMode eDfltHostnameCmpMode; -extern cstr_t *pDfltHostnameCmp; -extern cstr_t *pDfltProgNameCmp; /* TODO: the following 2 need to go in conf obj interface... */ rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName); rsRetVal cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *pszTpl); diff --git a/runtime/queue.c b/runtime/queue.c index 62fb339b..85acdb8e 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -55,6 +55,7 @@ #include "wti.h" #include "msg.h" #include "atomic.h" +#include "errmsg.h" #include "unicode-helper.h" #include "msg.h" /* TODO: remove once we remove MsgAddRef() call */ @@ -66,6 +67,7 @@ DEFobjStaticHelpers DEFobjCurrIf(glbl) DEFobjCurrIf(strm) +DEFobjCurrIf(errmsg) /* forward-definitions */ static rsRetVal qqueueChkPersist(qqueue_t *pThis, int nUpdates); @@ -320,8 +322,12 @@ StartDA(qqueue_t *pThis) iRet = qqueueStart(pThis->pqDA); /* file not found is expected, that means it is no previous QIF available */ - if(iRet != RS_RET_OK && iRet != RS_RET_FILE_NOT_FOUND) + if(iRet != RS_RET_OK && iRet != RS_RET_FILE_NOT_FOUND) { + errno = 0; /* else an errno is shown in errmsg! */ + errmsg.LogError(errno, iRet, "error starting up disk queue, using pure in-memory mode"); + pThis->bIsDA = 0; /* disable memory mode */ FINALIZE; /* something is wrong */ + } DBGOPRINT((obj_t*) pThis, "DA queue initialized, disk queue 0x%lx\n", qqueueGetID(pThis->pqDA)); @@ -774,9 +780,12 @@ static rsRetVal qDestructDisk(qqueue_t *pThis) ASSERT(pThis != NULL); - strm.Destruct(&pThis->tVars.disk.pWrite); - strm.Destruct(&pThis->tVars.disk.pReadDeq); - strm.Destruct(&pThis->tVars.disk.pReadDel); + if(pThis->tVars.disk.pWrite != NULL) + strm.Destruct(&pThis->tVars.disk.pWrite); + if(pThis->tVars.disk.pReadDeq != NULL) + strm.Destruct(&pThis->tVars.disk.pReadDeq); + if(pThis->tVars.disk.pReadDel != NULL) + strm.Destruct(&pThis->tVars.disk.pReadDel); RETiRet; } @@ -1928,7 +1937,8 @@ static rsRetVal qqueuePersist(qqueue_t *pThis, int bIsCheckpoint) pThis->bNeedDelQIF = 0; } /* indicate spool file needs to be deleted */ - CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 1)); + if(pThis->tVars.disk.pReadDel != NULL) /* may be NULL if we had a startup failure! */ + CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 1)); FINALIZE; /* nothing left to do, so be happy */ } @@ -2381,6 +2391,7 @@ BEGINObjClassInit(qqueue, 1, OBJ_IS_CORE_MODULE) /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(strm, CORE_COMPONENT)); + CHKiRet(objUse(errmsg, CORE_COMPONENT)); /* now set our own handlers */ OBJSetMethodHandler(objMethod_SETPROPERTY, qqueueSetProperty); diff --git a/runtime/rule.c b/runtime/rule.c index 182d616a..fe2cf432 100644 --- a/runtime/rule.c +++ b/runtime/rule.c @@ -138,6 +138,7 @@ shouldProcessThisMessage(rule_t *pRule, msg_t *pMsg, int *bProcessMsg) } } +RUNLOG_VAR("%p", pRule->pCSProgNameComp); if(pRule->pCSProgNameComp != NULL) { int bInv = 0, bEqv = 0, offset = 0; if(*(rsCStrGetSzStrNoNULL(pRule->pCSProgNameComp)) == '-') { diff --git a/tests/Makefile.am b/tests/Makefile.am index cdf2c4be..4ba7db75 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -90,7 +90,10 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/rfc5424-2.parse1 \ testsuites/rfc5424-3.parse1 \ testsuites/rfc5424-4.parse1 \ - testsuites/malformed.parse1 \ + testsuites/malformed1.parse1 \ + testsuites/reallife.parse1 \ + testsuites/parse2.conf \ + testsuites/reallife.parse2 \ testsuites/omod-if-array.conf \ testsuites/1.omod-if-array \ testsuites/1.field1 \ diff --git a/tests/diag.sh b/tests/diag.sh index d8ba43b8..b6b39a4b 100755 --- a/tests/diag.sh +++ b/tests/diag.sh @@ -90,7 +90,7 @@ case $1 in ;; 'nettester') # perform nettester-based tests # use -v for verbose output! - ./nettester -t$2 -i$3 + ./nettester -t$2 -i$3 $4 if [ "$?" -ne "0" ]; then exit 1 fi diff --git a/tests/nettester.c b/tests/nettester.c index 2838b919..3ab96e62 100644 --- a/tests/nettester.c +++ b/tests/nettester.c @@ -62,6 +62,7 @@ static char *testSuite = NULL; /* name of current test suite */ static int iPort = 12514; /* port which shall be used for sending data */ static char* pszCustomConf = NULL; /* custom config file, use -c conf to specify */ static int verbose = 0; /* verbose output? -v option */ +static int IPv4Only = 0; /* use only IPv4 in rsyslogd call? */ /* these two are quick hacks... */ int iFailed = 0; @@ -221,7 +222,7 @@ int openPipe(char *configFile, pid_t *pid, int *pfd) int pipefd[2]; pid_t cpid; char *newargv[] = {"../tools/rsyslogd", "dummy", "-c4", "-u2", "-n", "-irsyslog.pid", - "-M../runtime/.libs:../.libs", NULL }; + "-M../runtime/.libs:../.libs", NULL, NULL}; char confFile[1024]; char *newenviron[] = { NULL }; /* debug aide... @@ -233,6 +234,9 @@ int openPipe(char *configFile, pid_t *pid, int *pfd) (pszCustomConf == NULL) ? configFile : pszCustomConf); newargv[1] = confFile; + if(IPv4Only) + newargv[(sizeof(newargv)/sizeof(char*)) - 2] = "-4"; + if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); @@ -326,10 +330,13 @@ processTestFile(int fd, char *pszFileName) ret = 1; } + /* clean up after the try */ + free(testdata); + testdata = NULL; + free(expected); + expected = NULL; } - free(testdata); - free(expected); fclose(fp); return(ret); } @@ -423,8 +430,11 @@ int main(int argc, char *argv[]) char buf[4096]; char testcases[4096]; - while((opt = getopt(argc, argv, "c:i:p:t:v")) != EOF) { + while((opt = getopt(argc, argv, "4c:i:p:t:v")) != EOF) { switch((char)opt) { + case '4': + IPv4Only = 1; + break; case 'c': pszCustomConf = optarg; break; diff --git a/tests/parsertest.sh b/tests/parsertest.sh index ef33256e..470d9375 100755 --- a/tests/parsertest.sh +++ b/tests/parsertest.sh @@ -1,5 +1,13 @@ -echo TEST: parsertest.sh - various parser tests +echo TEST: \[parsertest.sh\]: various parser tests source $srcdir/diag.sh init source $srcdir/diag.sh nettester parse1 udp source $srcdir/diag.sh nettester parse1 tcp +source $srcdir/diag.sh nettester parse2 udp +source $srcdir/diag.sh nettester parse2 tcp + +echo \[parsertest.sh]: redoing tests in IPv4-only mode +source $srcdir/diag.sh nettester parse1 udp -4 +source $srcdir/diag.sh nettester parse1 tcp -4 +source $srcdir/diag.sh nettester parse2 udp -4 +source $srcdir/diag.sh nettester parse2 tcp -4 source $srcdir/diag.sh init diff --git a/tests/testsuites/parse2.conf b/tests/testsuites/parse2.conf new file mode 100644 index 00000000..04d910bc --- /dev/null +++ b/tests/testsuites/parse2.conf @@ -0,0 +1,8 @@ +$ModLoad ../plugins/omstdout/.libs/omstdout +$IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver! + +$ErrorMessagesToStderr off + +# use a special format that we can easily parse in expect +$template output,"%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%programname%,%syslogtag%,%msg%\n" +*.* :omstdout:;output diff --git a/tests/testsuites/reallife.parse1 b/tests/testsuites/reallife.parse1 new file mode 100644 index 00000000..a83d2dca --- /dev/null +++ b/tests/testsuites/reallife.parse1 @@ -0,0 +1,12 @@ +# New tests should be added to this file if there is no specific +# reason for not doing that. Initially, we could only handle one test +# case per file, but this restriction has been removed some time ago. +# So it is less troublesome (and easier to overlook) to have all related +# tests in a single file. +# This file contains a lot of real-life samples (of course mangled so +# that they can not be traced back to the original submitter). Note +# that IP addr 192.0.2.1 is specifically set aside for testing and +# documentation by IANA. +# rgerhards, 2009-10-19 +<29>Oct 16 20:47:24 example-p exam-pl[12345]: connect host= /192.0.2.1 +29,daemon,notice,Oct 16 20:47:24,example-p,exam-pl,exam-pl[12345]:, connect host= /192.0.2.1 diff --git a/tests/testsuites/reallife.parse2 b/tests/testsuites/reallife.parse2 new file mode 100644 index 00000000..c42f2526 --- /dev/null +++ b/tests/testsuites/reallife.parse2 @@ -0,0 +1,12 @@ +# New tests should be added to this file if there is no specific +# reason for not doing that. Initially, we could only handle one test +# case per file, but this restriction has been removed some time ago. +# So it is less troublesome (and easier to overlook) to have all related +# tests in a single file. +# This file contains a lot of real-life samples (of course mangled so +# that they can not be traced back to the original submitter). Note +# that IP addr 192.0.2.1 is specifically set aside for testing and +# documentation by IANA. +# rgerhards, 2009-10-19 +<175>Oct 16 23:47:31 #001 MSWinEventLog 0#011Security#01119023582#011Fri Oct 16 16:30:44 2009#011592#011Security#011rgabcde#011User#011Success Audit#011XSXSXSN01#011Detailed Tracking#011#0112572#01119013885 +175,local5,debug,Oct 16 23:47:31,#001,#001, MSWinEventLog 0#011Security#01119023582#011Fri Oct 16 16:30:44 2009#011592#011Security#011rgabcde#011User#011Success Audit#011XSXSXSN01#011Detailed Tracking#011#0112572#01119013885 diff --git a/tools/syslogd.c b/tools/syslogd.c index f8a78343..07829e46 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -1897,11 +1897,6 @@ init(void) struct sigaction sigAct; DEFiRet; - /* initialize some static variables */ - pDfltHostnameCmp = NULL; - pDfltProgNameCmp = NULL; - eDfltHostnameCmpMode = HN_NO_COMP; - DBGPRINTF("rsyslog %s - called init()\n", VERSION); /* construct the default ruleset */ @@ -1951,17 +1946,6 @@ init(void) legacyOptsHook(); - /* we are now done with reading the configuration. This is the right time to - * free some objects that were just needed for loading it. rgerhards 2005-10-19 - */ - if(pDfltHostnameCmp != NULL) { - rsCStrDestruct(&pDfltHostnameCmp); - } - - if(pDfltProgNameCmp != NULL) { - rsCStrDestruct(&pDfltProgNameCmp); - } - /* some checks */ if(iMainMsgQueueNumWorkers < 1) { errmsg.LogError(0, NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); |