From 793155415708271d94f1238d5294c08ad3831d3a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 31 Jan 2012 17:14:23 +0100 Subject: stats: generate friendly name for action queues, if possible --- action.c | 9 +++++++-- configure.ac | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/action.c b/action.c index f16146c1..e465b826 100644 --- a/action.c +++ b/action.c @@ -348,8 +348,13 @@ actionConstructFinalize(action_t *pThis) CHKiRet(statsobj.ConstructFinalize(pThis->statsobj)); /* create our queue */ - /* find a name for our queue */ - snprintf((char*) pszAName, sizeof(pszAName)/sizeof(uchar), "action %d queue", iActionNbr); + /* find a (friendly) name for our queue */ + if(pThis->pszName == NULL) { + snprintf((char*) pszAName, sizeof(pszAName)/sizeof(uchar), "action %d queue", iActionNbr); + } else { + snprintf((char*) pszAName, sizeof(pszAName)/sizeof(uchar), "%s queue", pThis->pszName); + } + pszAName[63] = '\0'; /* to be on the save side */ /* now check if we can run the action in "firehose mode" during stage one of * its processing (that is before messages are enqueued into the action q). diff --git a/configure.ac b/configure.ac index c6d775af..5bfaf42c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.6-newstats6],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.7-newstats7],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -- cgit From 19a80194032b4bbdf6ad98bd00a89528137b4883 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 31 Jan 2012 17:35:41 +0100 Subject: stats: added unique (and friendly) name for ruleset queues --- runtime/ruleset.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/ruleset.c b/runtime/ruleset.c index 5ee2a55a..69968a52 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -500,6 +500,7 @@ debugPrintAll(void) static rsRetVal rulesetCreateQueue(void __attribute__((unused)) *pVal, int *pNewVal) { + uchar *rulesetMainQName; DEFiRet; if(pCurrRuleset == NULL) { @@ -518,7 +519,9 @@ rulesetCreateQueue(void __attribute__((unused)) *pVal, int *pNewVal) FINALIZE; /* if it is turned off, we do not need to change anything ;) */ dbgprintf("adding a ruleset-specific \"main\" queue"); - CHKiRet(createMainQueue(&pCurrRuleset->pQueue, UCHAR_CONSTANT("ruleset"))); + rulesetMainQName = (pCurrRuleset->pszName == NULL)? UCHAR_CONSTANT("ruleset") : + pCurrRuleset->pszName; + CHKiRet(createMainQueue(&pCurrRuleset->pQueue, rulesetMainQName)); finalize_it: RETiRet; -- cgit From 6cfa853457b190193ba68f77d27e000f2567481e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 20 Feb 2012 12:48:17 +0100 Subject: bugfix: imptcp stats sometimes incorrectly reported socket as IPv6 --- configure.ac | 2 +- plugins/imptcp/imptcp.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 5bfaf42c..67c38ade 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.7-newstats7],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.7-newstats8],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 103da210..e191c64f 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -281,7 +281,9 @@ startupSrv(ptcpsrv_t *pSrv) continue; } #endif - } + } else { + isIPv6 = 0; + } if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0 ) { DBGPRINTF("error %d setting tcp socket option\n", errno); close(sock); -- cgit From f9b6b94b802c653e6c588f42af0997682e75f267 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 21 Feb 2012 16:52:36 +0100 Subject: added configuration directives to customize queue light delay marks $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both specify number of messages starting at which a delay happens. --- ChangeLog | 3 +++ action.c | 4 ++++ configure.ac | 2 +- runtime/queue.c | 1 + runtime/queue.h | 1 + tools/syslogd.c | 8 ++++++-- 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c02d397b..7afe453d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +- added configuration directives to customize queue light delay marks + $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both + specify number of messages starting at which a delay happens. --------------------------------------------------------------------------- Version 5.8.8 [V5-stable] 2012-0?-?? - bugfix: omprog made rsyslog abort on startup if not binary to diff --git a/action.c b/action.c index e465b826..f85b1c46 100644 --- a/action.c +++ b/action.c @@ -144,6 +144,7 @@ static queueType_t ActionQueType = QUEUETYPE_DIRECT; /* type of the main messag static int iActionQueueSize = 1000; /* size of the main message queue above */ static int iActionQueueDeqBatchSize = 16; /* batch size for action queues */ static int iActionQHighWtrMark = 800; /* high water mark for disk-assisted queues */ +static int iActionQLightDlyMrk = 700; /* light delay mark for disk-assisted queues */ static int iActionQLowWtrMark = 200; /* low water mark for disk-assisted queues */ static int iActionQDiscardMark = 9800; /* begin to discard messages */ static int iActionQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ @@ -226,6 +227,7 @@ actionResetQueueParams(void) iActionQueueSize = 1000; /* size of the main message queue above */ iActionQueueDeqBatchSize = 16; /* default batch size */ iActionQHighWtrMark = 800; /* high water mark for disk-assisted queues */ + iActionQLightDlyMrk = 700; iActionQLowWtrMark = 200; /* low water mark for disk-assisted queues */ iActionQDiscardMark = 9800; /* begin to discard messages */ iActionQDiscardSeverity = 8; /* discard warning and above */ @@ -422,6 +424,7 @@ actionConstructFinalize(action_t *pThis) setQPROP(qqueueSettoWrkShutdown, "$ActionQueueWorkerTimeoutThreadShutdown", iActionQtoWrkShutdown); setQPROP(qqueueSettoEnq, "$ActionQueueTimeoutEnqueue", iActionQtoEnq); setQPROP(qqueueSetiHighWtrMrk, "$ActionQueueHighWaterMark", iActionQHighWtrMark); + setQPROP(qqueueSetiLightDlyMrk, "$ActionQueueLightDelayMark", iActionQLightDlyMrk); setQPROP(qqueueSetiLowWtrMrk, "$ActionQueueLowWaterMark", iActionQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$ActionQueueDiscardMark", iActionQDiscardMark); setQPROP(qqueueSetiDiscardSeverity, "$ActionQueueDiscardSeverity", iActionQDiscardSeverity); @@ -1883,6 +1886,7 @@ rsRetVal actionClassInit(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iActionQHighWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iActionQLowWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuediscardmark", 0, eCmdHdlrInt, NULL, &iActionQDiscardMark, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuelightdelaymark", 0, eCmdHdlrInt, NULL, &iActionQLightDlyMrk, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuediscardseverity", 0, eCmdHdlrInt, NULL, &iActionQDiscardSeverity, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iActionQPersistUpdCnt, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bActionQSyncQeueFiles, NULL)); diff --git a/configure.ac b/configure.ac index 67c38ade..393b778b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.7-newstats8],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.7-newstats9],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/runtime/queue.c b/runtime/queue.c index e97d78e8..523ae0fc 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -2438,6 +2438,7 @@ DEFpropSetMeth(qqueue, iLowWtrMrk, int) DEFpropSetMeth(qqueue, iDiscardMrk, int) DEFpropSetMeth(qqueue, iFullDlyMrk, int) DEFpropSetMeth(qqueue, iDiscardSeverity, int) +DEFpropSetMeth(qqueue, iLightDlyMrk, int) DEFpropSetMeth(qqueue, bIsDA, int) DEFpropSetMeth(qqueue, iMinMsgsPerWrkr, int) DEFpropSetMeth(qqueue, bSaveOnShutdown, int) diff --git a/runtime/queue.h b/runtime/queue.h index 06a58229..dbd6f249 100644 --- a/runtime/queue.h +++ b/runtime/queue.h @@ -201,6 +201,7 @@ PROTOTYPEpropSetMeth(qqueue, toQShutdown, long); PROTOTYPEpropSetMeth(qqueue, toActShutdown, long); PROTOTYPEpropSetMeth(qqueue, toWrkShutdown, long); PROTOTYPEpropSetMeth(qqueue, toEnq, long); +PROTOTYPEpropSetMeth(qqueue, iLightDlyMrk, int); PROTOTYPEpropSetMeth(qqueue, iHighWtrMrk, int); PROTOTYPEpropSetMeth(qqueue, iLowWtrMrk, int); PROTOTYPEpropSetMeth(qqueue, iDiscardMrk, int); diff --git a/tools/syslogd.c b/tools/syslogd.c index 0b7bbc96..4c537570 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -262,6 +262,7 @@ static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL mea qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ +static int iMainMsgQLightDlyMark = 7000; /* light delay mark for disk-assisted queues */ static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */ static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ @@ -300,6 +301,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a pszMainMsgQFName = NULL; iMainMsgQueueSize = 10000; iMainMsgQHighWtrMark = 8000; + iMainMsgQLightDlyMark = 7000; iMainMsgQLowWtrMark = 2000; iMainMsgQDiscardMark = 9800; iMainMsgQDiscardSeverity = 8; @@ -1457,8 +1459,8 @@ static void dbgPrintInitInfo(void) iMainMsgQueueNumWorkers, iMainMsgQtoWrkShutdown, iMainMsgQPersistUpdCnt); DBGPRINTF("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq); - DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", - iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity); + DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d, light-delay %d\n", + iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity, iMainMsgQLightDlyMark); DBGPRINTF("Main queue save on shutdown %d, max disk space allowed %lld\n", bMainMsgQSaveOnShutdown, iMainMsgQueMaxDiskSpace); /* TODO: add @@ -1574,6 +1576,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); + setQPROP(qqueueSetiLightDlyMrk, "$MainMsgQueueLightDelayMark", iMainMsgQLightDlyMark); setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); @@ -2051,6 +2054,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelightdelaymark", 0, eCmdHdlrInt, NULL, &iMainMsgQLightDlyMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &bMainMsgQSyncQeueFiles, NULL)); -- cgit From 5c09faee34befd6c2fa117055928c810ccf86f91 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 22 Feb 2012 09:43:25 +0100 Subject: queue: lightdelay config: keep default of 70% until mark is explicitely set --- action.c | 8 +++++--- tools/syslogd.c | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/action.c b/action.c index f85b1c46..7de10d49 100644 --- a/action.c +++ b/action.c @@ -144,7 +144,7 @@ static queueType_t ActionQueType = QUEUETYPE_DIRECT; /* type of the main messag static int iActionQueueSize = 1000; /* size of the main message queue above */ static int iActionQueueDeqBatchSize = 16; /* batch size for action queues */ static int iActionQHighWtrMark = 800; /* high water mark for disk-assisted queues */ -static int iActionQLightDlyMrk = 700; /* light delay mark for disk-assisted queues */ +static int iActionQLightDlyMrk = -1; /* light delay mark for disk-assisted queues */ static int iActionQLowWtrMark = 200; /* low water mark for disk-assisted queues */ static int iActionQDiscardMark = 9800; /* begin to discard messages */ static int iActionQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ @@ -227,7 +227,7 @@ actionResetQueueParams(void) iActionQueueSize = 1000; /* size of the main message queue above */ iActionQueueDeqBatchSize = 16; /* default batch size */ iActionQHighWtrMark = 800; /* high water mark for disk-assisted queues */ - iActionQLightDlyMrk = 700; + iActionQLightDlyMrk = -1; iActionQLowWtrMark = 200; /* low water mark for disk-assisted queues */ iActionQDiscardMark = 9800; /* begin to discard messages */ iActionQDiscardSeverity = 8; /* discard warning and above */ @@ -424,7 +424,9 @@ actionConstructFinalize(action_t *pThis) setQPROP(qqueueSettoWrkShutdown, "$ActionQueueWorkerTimeoutThreadShutdown", iActionQtoWrkShutdown); setQPROP(qqueueSettoEnq, "$ActionQueueTimeoutEnqueue", iActionQtoEnq); setQPROP(qqueueSetiHighWtrMrk, "$ActionQueueHighWaterMark", iActionQHighWtrMark); - setQPROP(qqueueSetiLightDlyMrk, "$ActionQueueLightDelayMark", iActionQLightDlyMrk); + if(iActionQLightDlyMrk > 0) { + setQPROP(qqueueSetiLightDlyMrk, "$ActionQueueLightDelayMark", iActionQLightDlyMrk); + } setQPROP(qqueueSetiLowWtrMrk, "$ActionQueueLowWaterMark", iActionQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$ActionQueueDiscardMark", iActionQDiscardMark); setQPROP(qqueueSetiDiscardSeverity, "$ActionQueueDiscardSeverity", iActionQDiscardSeverity); diff --git a/tools/syslogd.c b/tools/syslogd.c index 4c537570..c0e663d2 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -262,7 +262,7 @@ static uchar *pszConfDAGFile = NULL; /* name of config DAG file, non-NULL mea qqueue_t *pMsgQueue = NULL; /* the main message queue */ static int iMainMsgQueueSize = 10000; /* size of the main message queue above */ static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */ -static int iMainMsgQLightDlyMark = 7000; /* light delay mark for disk-assisted queues */ +static int iMainMsgQLightDlyMark = -1; /* light delay mark for disk-assisted queues */ static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */ static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */ static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */ @@ -301,7 +301,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a pszMainMsgQFName = NULL; iMainMsgQueueSize = 10000; iMainMsgQHighWtrMark = 8000; - iMainMsgQLightDlyMark = 7000; + iMainMsgQLightDlyMark = -1; iMainMsgQLowWtrMark = 2000; iMainMsgQDiscardMark = 9800; iMainMsgQDiscardSeverity = 8; @@ -1576,7 +1576,9 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark); setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark); - setQPROP(qqueueSetiLightDlyMrk, "$MainMsgQueueLightDelayMark", iMainMsgQLightDlyMark); + if(iMainMsgQLightDlyMark > 0) { + setQPROP(qqueueSetiLightDlyMrk, "$MainMsgQueueLightDelayMark", iMainMsgQLightDlyMark); + } setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity); setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); -- cgit From aafa9b41a5f06b88f11df5c837427e171e1048d7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 1 Mar 2012 12:16:59 +0100 Subject: bugfix: imklog invalidly computed facility and severity closes: http://bugzilla.adiscon.com/show_bug.cgi?id=313 --- ChangeLog | 4 ++++ plugins/imklog/imklog.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index be4f97c8..76a4686f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ --------------------------------------------------------------------------- +Version 5.9.6 [V5-DEVEL], 2012-03-?? +- bugfix: imklog invalidly computed facility and severity + closes: http://bugzilla.adiscon.com/show_bug.cgi?id=313 +--------------------------------------------------------------------------- Version 5.9.5 [V5-DEVEL], 2012-01-27 - improved impstats subsystem, added many new counters - enhanced module loader to not rely on PATH_MAX diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 40249273..e82dd1f4 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -119,8 +119,8 @@ enqMsg(uchar *msg, uchar* pszTag, int iFacility, int iSeverity, struct timeval * MsgSetRcvFromIP(pMsg, pLocalHostIP); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetTAG(pMsg, pszTag, ustrlen(pszTag)); - pMsg->iFacility = LOG_FAC(iFacility); - pMsg->iSeverity = LOG_PRI(iSeverity); + pMsg->iFacility = iFacility; + pMsg->iSeverity = iSeverity; CHKiRet(submitMsg(pMsg)); finalize_it: -- cgit From 9601b181cf5d2166e2c813973e82a4b48002e83f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 6 Mar 2012 17:26:04 +0100 Subject: added capability to use a local interface IP address as fromhost-ip for imuxsock new config directives: $IMUXSockLocalIPIF --- ChangeLog | 3 +++ doc/imuxsock.html | 7 +++++- plugins/imuxsock/imuxsock.c | 35 ++++++++++++++++++++++++----- runtime/net.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- runtime/net.h | 6 +++-- tools/syslogd.c | 1 + 6 files changed, 97 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99e324ab..78f74695 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +- added capability to use a local interface IP address as fromhost-ip for + imuxsock + new config directives: $IMUXSockLocalIPIF - added configuration directives to customize queue light delay marks $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both specify number of messages starting at which a delay happens. diff --git a/doc/imuxsock.html b/doc/imuxsock.html index ee5db22d..1b79dd0d 100644 --- a/doc/imuxsock.html +++ b/doc/imuxsock.html @@ -64,6 +64,11 @@ burst in number of messages. Default is 200.
  • $IMUXSockRateLimitSeverity [numerical severity] - specifies the severity of messages that shall be rate-limited.
  • +
  • $IMUXSockLocalIPIF [interface name] - if provided, the IP of the specified +interface (e.g. "eth0") shall be used as fromhost-ip for imuxsock-originating messages. +If this directive is not given OR the interface cannot be found (or has no IP address), +the default of "127.0.0.1" is used. +
  • $InputUnixListenSocketUsePIDFromSystem [on/off] - specifies if the pid being logged shall be obtained from the log socket itself. If so, the TAG part of the message is rewritten. It is recommended to turn this option on, but the default is "off" to keep compatible @@ -150,7 +155,7 @@ $SystemLogRateLimitInterval 0 # turn off rate limiting

    This documentation is part of the rsyslog project.
    -Copyright © 2008-2010 by Rainer +Copyright © 2008-2012 by Rainer Gerhards and Adiscon. Released under the GNU GPL version 3 or higher.

    diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 4523798f..ad8c81e7 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -89,6 +89,7 @@ DEF_IMOD_STATIC_DATA DEFobjCurrIf(errmsg) DEFobjCurrIf(glbl) DEFobjCurrIf(prop) +DEFobjCurrIf(net) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) DEFobjCurrIf(statsobj) @@ -157,6 +158,7 @@ static int sd_fds = 0; /* number of systemd activated sockets */ /* config settings */ static int bOmitLocalLogging = 0; static uchar *pLogSockName = NULL; +static uchar *pLocalIPIF = NULL; static uchar *pLogHostName = NULL; /* host name to use with this socket */ static int bUseFlowCtl = 0; /* use flow control or not (if yes, only LIGHT is used! */ static int bIgnoreTimestamp = 1; /* ignore timestamps present in the incoming message? */ @@ -764,6 +766,8 @@ ENDrunInput BEGINwillRun + uchar myIP[128]; + rsRetVal localRet; CODESTARTwillRun register int i; int actSocks; @@ -784,7 +788,7 @@ CODESTARTwillRun else if(sd_booted()) { struct stat st; if(stat(SYSTEMD_JOURNAL, &st) != -1 && S_ISDIR(st.st_mode)) { - listeners[0].sockName = SYSTEMD_PATH_LOG; + listeners[0].sockName = (uchar*)SYSTEMD_PATH_LOG; } } if(ratelimitIntervalSysSock > 0) { @@ -826,6 +830,23 @@ CODESTARTwillRun CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); + if(pLocalIPIF == NULL) { + strcpy((char*)myIP, "127.0.0.1"); + } else { + localRet = net.GetIFIPAddr((uchar*)"eth0", AF_UNSPEC, myIP, (int) sizeof(myIP)); + if(localRet != RS_RET_OK) { + DBGPRINTF("imuxsock: could not obtain my IP, using 127.0.0.1 instead\n"); + strcpy((char*)myIP, "127.0.0.1"); + } + } + + DBGPRINTF("imuxsock: using '%s' as localhost IP\n", myIP); + + CHKiRet(prop.Construct(&pLocalHostIP)); + CHKiRet(prop.SetString(pLocalHostIP, myIP, ustrlen(myIP))); + CHKiRet(prop.ConstructFinalize(pLocalHostIP)); + + finalize_it: ENDwillRun @@ -857,6 +878,7 @@ CODESTARTafterRun } /* free no longer needed string */ free(pLogSockName); + free(pLocalIPIF); free(pLogHostName); discardLogSockets(); @@ -901,6 +923,10 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a free(pLogSockName); pLogSockName = NULL; } + if(pLocalIPIF != NULL) { + free(pLocalIPIF); + pLocalIPIF = NULL; + } if(pLogHostName != NULL) { free(pLogHostName); pLogHostName = NULL; @@ -931,6 +957,7 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(errmsg, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(net, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); @@ -954,10 +981,6 @@ CODEmodInit_QueryRegCFSLineHdlr listeners[i].fd = -1; } - CHKiRet(prop.Construct(&pLocalHostIP)); - CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); - CHKiRet(prop.ConstructFinalize(pLocalHostIP)); - /* now init listen socket zero, the local log socket */ CHKiRet(prop.Construct(&(listeners[0].hostName))); CHKiRet(prop.SetString(listeners[0].hostName, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()))); @@ -988,6 +1011,8 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &ratelimitSeverity, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"imuxsocklocalipif", 0, eCmdHdlrGetWord, + NULL, &pLocalIPIF, STD_LOADABLE_MODULE_ID)); /* the following one is a (dirty) trick: the system log socket is not added via * an "addUnixListenSocket" config format. As such, it's properties can not be modified * via $InputUnixListenSocket*". So we need to add a special directive diff --git a/runtime/net.c b/runtime/net.c index 4781739f..1264b2cb 100644 --- a/runtime/net.c +++ b/runtime/net.c @@ -12,7 +12,7 @@ * long term, but it is good to have it out of syslogd.c. Maybe this here is * an interim location ;) * - * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * rgerhards, 2008-04-16: I changed this code to LGPL today. I carefully analyzed * that it does not borrow code from the original sysklogd and that I have @@ -54,6 +54,9 @@ #include #include #include +#include +#include +#include #include "syslogd-types.h" #include "module-template.h" @@ -1581,6 +1584,54 @@ finalize_it: } +/* return the IP address (IPv4/6) for the provided interface. Returns + * RS_RET_NOT_FOUND if interface can not be found in interface list. + * The family must be correct (AF_INET vs. AF_INET6, AF_UNSPEC means + * either of *these two*). + * The function re-queries the interface list (at least in theory). + * However, it caches entries in order to avoid too-frequent requery. + * rgerhards, 2012-03-06 + */ +static rsRetVal +getIFIPAddr(uchar *szif, int family, uchar *pszbuf, int lenBuf) +{ + struct ifaddrs * ifaddrs = NULL; + struct ifaddrs * ifa; + void * pAddr; + DEFiRet; + + if(getifaddrs(&ifaddrs) != 0) { + ABORT_FINALIZE(RS_RET_ERR); + } + + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + if(strcmp(ifa->ifa_name, (char*)szif)) + continue; + if( (family == AF_INET6 || family == AF_UNSPEC) + && ifa->ifa_addr->sa_family == AF_INET6) { + pAddr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; + inet_ntop(AF_INET6, pAddr, (char*)pszbuf, lenBuf); + break; + } else if(/* (family == AF_INET || family == AF_UNSPEC) + &&*/ ifa->ifa_addr->sa_family == AF_INET) { + pAddr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + inet_ntop(AF_INET, pAddr, (char*)pszbuf, lenBuf); + break; + } + } + + if(ifaddrs != NULL) + freeifaddrs(ifaddrs); + + if(ifa == NULL) + iRet = RS_RET_NOT_FOUND; + +finalize_it: + RETiRet; + +} + + /* queryInterface function * rgerhards, 2008-03-05 */ @@ -1612,6 +1663,7 @@ CODESTARTobjQueryInterface(net) pIf->PermittedPeerWildcardMatch = PermittedPeerWildcardMatch; pIf->CmpHost = CmpHost; pIf->HasRestrictions = HasRestrictions; + pIf->GetIFIPAddr = getIFIPAddr; /* data members */ pIf->pACLAddHostnameOnFail = &ACLAddHostnameOnFail; pIf->pACLDontResolve = &ACLDontResolve; diff --git a/runtime/net.h b/runtime/net.h index 101ce79d..1b41c81c 100644 --- a/runtime/net.h +++ b/runtime/net.h @@ -1,6 +1,6 @@ /* Definitions for network-related stuff. * - * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -151,11 +151,13 @@ BEGINinterface(net) /* name must also be changed in ENDinterface macro! */ /* v6 interface additions - 2009-11-16 */ rsRetVal (*HasRestrictions)(uchar *, int *bHasRestrictions); int (*isAllowedSender2)(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost, int bChkDNS); + /* v7 interface additions - 2012-03-06 */ + rsRetVal (*GetIFIPAddr)(uchar *szif, int family, uchar *pszbuf, int lenBuf); /* data members - these should go away over time... TODO */ int *pACLAddHostnameOnFail; /* add hostname to acl when DNS resolving has failed */ int *pACLDontResolve; /* add hostname to acl instead of resolving it to IP(s) */ ENDinterface(net) -#define netCURR_IF_VERSION 6 /* increment whenever you change the interface structure! */ +#define netCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(net); diff --git a/tools/syslogd.c b/tools/syslogd.c index c0e663d2..02a0dad6 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2712,6 +2712,7 @@ int realMain(int argc, char **argv) CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); } else { CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + int i; } if((p = (uchar*)strchr((char*)LocalHostName, '.'))) -- cgit From f993008207811affe8fc52800e408bea241e78e3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 9 Mar 2012 16:39:08 +0100 Subject: bugfix: imudp: only two listeners were activated no matter how many were defined. Note that IPv4 and IPv6 count as two! --- plugins/imudp/imudp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 0db6bf9a..112738b4 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -244,8 +244,10 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal) lcnfRoot = newlcnfinfo; if(lcnfLast == NULL) lcnfLast = newlcnfinfo; - else + else { lcnfLast->next = newlcnfinfo; + lcnfLast = newlcnfinfo; + } } } -- cgit From 68301c98db00dc1b6bc7e09c5f5e47286a16ab95 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 10 Mar 2012 18:22:14 +0100 Subject: imuxsock did ignore configured IP if - always used eth0 if one was set ;) --- plugins/imuxsock/imuxsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index ad8c81e7..2f76ed87 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -833,7 +833,7 @@ CODESTARTwillRun if(pLocalIPIF == NULL) { strcpy((char*)myIP, "127.0.0.1"); } else { - localRet = net.GetIFIPAddr((uchar*)"eth0", AF_UNSPEC, myIP, (int) sizeof(myIP)); + localRet = net.GetIFIPAddr((uchar*)pLocalIPIF, AF_UNSPEC, myIP, (int) sizeof(myIP)); if(localRet != RS_RET_OK) { DBGPRINTF("imuxsock: could not obtain my IP, using 127.0.0.1 instead\n"); strcpy((char*)myIP, "127.0.0.1"); -- cgit From 50a94aa1c72ba8aab5443ecc04b51190da0df513 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 10 Mar 2012 18:29:40 +0100 Subject: added capability to use a local interface IP address as fromhost-ip for imklog --- ChangeLog | 4 ++-- doc/imklog.html | 5 +++++ doc/imuxsock.html | 2 +- plugins/imklog/imklog.c | 27 ++++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 78f74695..9fb59495 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ - added capability to use a local interface IP address as fromhost-ip for - imuxsock - new config directives: $IMUXSockLocalIPIF + imuxsock imklog + new config directives: $IMUXSockLocalIPIF, $klogLocalIPIF - added configuration directives to customize queue light delay marks $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both specify number of messages starting at which a delay happens. diff --git a/doc/imklog.html b/doc/imklog.html index f273753f..2e3b3bc2 100644 --- a/doc/imklog.html +++ b/doc/imklog.html @@ -36,6 +36,11 @@ processing.
  • $DebugPrintKernelSymbols [on/off]
    Linux only, ignored on other platforms (but may be specified)
  • +
  • $klogLocalIPIF [interface name] - (available since 5.9.6) - if provided, the IP of the specified +interface (e.g. "eth0") shall be used as fromhost-ip for imklog-originating messages. +If this directive is not given OR the interface cannot be found (or has no IP address), +the default of "127.0.0.1" is used. +
  • $klogSymbolLookup [on/off] -- disables imklog kernel symbol translation (former klogd -x option). NOTE that this option is counter-productive on recent kernels (>= 2.6) because the diff --git a/doc/imuxsock.html b/doc/imuxsock.html index 1b79dd0d..f54b5564 100644 --- a/doc/imuxsock.html +++ b/doc/imuxsock.html @@ -64,7 +64,7 @@ burst in number of messages. Default is 200.
  • $IMUXSockRateLimitSeverity [numerical severity] - specifies the severity of messages that shall be rate-limited.
  • -
  • $IMUXSockLocalIPIF [interface name] - if provided, the IP of the specified +
  • $IMUXSockLocalIPIF [interface name] - (available since 5.9.6) - if provided, the IP of the specified interface (e.g. "eth0") shall be used as fromhost-ip for imuxsock-originating messages. If this directive is not given OR the interface cannot be found (or has no IP address), the default of "127.0.0.1" is used. diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 16adbc21..66d7d143 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "dirty.h" #include "cfsysline.h" @@ -52,6 +53,7 @@ #include "module-template.h" #include "datetime.h" #include "imklog.h" +#include "net.h" #include "glbl.h" #include "prop.h" #include "unicode-helper.h" @@ -64,6 +66,7 @@ DEF_IMOD_STATIC_DATA DEFobjCurrIf(datetime) DEFobjCurrIf(glbl) DEFobjCurrIf(prop) +DEFobjCurrIf(net) /* configuration settings */ int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */ @@ -71,6 +74,7 @@ int symbols_twice = 0; int use_syscall = 0; int symbol_lookup = 0; /* on recent kernels > 2.6, the kernel does this */ int bPermitNonKernel = 0; /* permit logging of messages not having LOG_KERN facility */ +static uchar *pLocalIPIF = NULL; int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */ uchar *pszPath = NULL; int console_log_level = -1; @@ -233,10 +237,22 @@ ENDrunInput BEGINwillRun + uchar myIP[128]; + rsRetVal localRet; CODESTARTwillRun /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.CreateStringProp(&pInputName, UCHAR_CONSTANT("imklog"), sizeof("imklog") - 1)); - CHKiRet(prop.CreateStringProp(&pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); + if(pLocalIPIF == NULL) { + strcpy((char*)myIP, "127.0.0.1"); + } else { + localRet = net.GetIFIPAddr(pLocalIPIF, AF_UNSPEC, myIP, (int) sizeof(myIP)); + if(localRet != RS_RET_OK) { + DBGPRINTF("imuxsock: could not obtain my IP, using 127.0.0.1 instead\n"); + strcpy((char*)myIP, "127.0.0.1"); + } + } + DBGPRINTF("imklog: using '%s' as localhost IP\n", myIP); + CHKiRet(prop.CreateStringProp(&pLocalHostIP, myIP, ustrlen(myIP))); iRet = klogWillRun(); finalize_it: @@ -251,6 +267,7 @@ CODESTARTafterRun prop.Destruct(&pInputName); if(pLocalHostIP != NULL) prop.Destruct(&pLocalHostIP); + free(pLocalIPIF); ENDafterRun @@ -258,6 +275,7 @@ BEGINmodExit CODESTARTmodExit /* release objects we used */ objRelease(glbl, CORE_COMPONENT); + objRelease(net, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); if(pszPath != NULL) @@ -282,6 +300,10 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a free(pszPath); pszPath = NULL; } + if(pLocalIPIF != NULL) { + free(pLocalIPIF); + pLocalIPIF = NULL; + } iFacilIntMsg = klogFacilIntMsg(); return RS_RET_OK; } @@ -293,6 +315,7 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(net, CORE_COMPONENT)); iFacilIntMsg = klogFacilIntMsg(); @@ -304,6 +327,8 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpermitnonkernelfacility", 0, eCmdHdlrBinary, NULL, &bPermitNonKernel, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogconsoleloglevel", 0, eCmdHdlrInt, NULL, &console_log_level, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloginternalmsgfacility", 0, eCmdHdlrFacility, NULL, &iFacilIntMsg, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloglocalipif", 0, eCmdHdlrGetWord, + NULL, &pLocalIPIF, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit /* vim:set ai: -- cgit From 5ecfdad17e395570edb78698b4805992368c61b1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 12 Mar 2012 16:56:51 +0100 Subject: bumped version number (of temp branch) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2e070386..b38a1955 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.8-newstats9],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.8-newstats10],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -- cgit From 2c7604f45b1c416180794f2c4f29ba25504f8d47 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 12 Mar 2012 17:01:44 +0100 Subject: cosmetic: removed stray definition --- tools/syslogd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/syslogd.c b/tools/syslogd.c index 92c539c7..33330a95 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2725,7 +2725,6 @@ int realMain(int argc, char **argv) CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); } else { CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - int i; } if((p = (uchar*)strchr((char*)LocalHostName, '.'))) -- cgit From 7d516b0a6c46177c18aea30b4617f1d2712d48fd Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 14 Mar 2012 13:51:18 +0100 Subject: added missing initialization of stats counters this was necessary due to refactoring of the stats subsystem ... but should have been done in the first place when this code was written. Thanks to Kaiwang Chen for his analysis of the stats subsystem, which ultimately lead to this patch! --- plugins/imptcp/imptcp.c | 1 + plugins/imudp/imudp.c | 1 + tcpsrv.c | 1 + 3 files changed, 3 insertions(+) diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index e191c64f..9c6c64e4 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -775,6 +775,7 @@ addLstn(ptcpsrv_t *pSrv, int sock, int isIPv6) isIPv6 ? "IPv6" : "IPv4"); statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */ CHKiRet(statsobj.SetName(pLstn->stats, statname)); + STATSCOUNTER_INIT(pLstn->ctrSubmit, pLstn->mutCtrSubmit); CHKiRet(statsobj.AddCounter(pLstn->stats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, &(pLstn->ctrSubmit))); CHKiRet(statsobj.ConstructFinalize(pLstn->stats)); diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 112738b4..46631e97 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -234,6 +234,7 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal) snprintf((char*)statname, sizeof(statname), "imudp(%s:%s)", bindName, port); statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */ CHKiRet(statsobj.SetName(newlcnfinfo->stats, statname)); + STATSCOUNTER_INIT(newlcnfinfo->ctrSubmit, newlcnfinfo->mutCtrSubmit); CHKiRet(statsobj.AddCounter(newlcnfinfo->stats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, &(newlcnfinfo->ctrSubmit))); CHKiRet(statsobj.ConstructFinalize(newlcnfinfo->stats)); diff --git a/tcpsrv.c b/tcpsrv.c index 86175ff4..dcf407c0 100644 --- a/tcpsrv.c +++ b/tcpsrv.c @@ -128,6 +128,7 @@ addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort) snprintf((char*)statname, sizeof(statname), "%s(%s)", pThis->pszInputName, pszPort); statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */ CHKiRet(statsobj.SetName(pEntry->stats, statname)); + STATSCOUNTER_INIT(pEntry->ctrSubmit, pEntry->mutCtrSubmit); CHKiRet(statsobj.AddCounter(pEntry->stats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, &(pEntry->ctrSubmit))); CHKiRet(statsobj.ConstructFinalize(pEntry->stats)); -- cgit From 4fb7ba113c4d4afd485feb2729c5ff67bc8ddd4a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 19 Mar 2012 15:28:25 +0100 Subject: added configuration directive to disable octet-counted framing ... for imtcp, directive is $InputTCPServerSupportOctetCountedFraming --- ChangeLog | 2 ++ doc/imtcp.html | 6 ++++++ plugins/imdiag/imdiag.c | 3 ++- plugins/imgssapi/imgssapi.c | 2 +- plugins/imtcp/imtcp.c | 6 +++++- tcps_sess.c | 4 +++- tcps_sess.h | 3 ++- tcpsrv.c | 7 ++++--- tcpsrv.h | 6 ++++-- 9 files changed, 29 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48ef8884..775e7e3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +- added configuration directive to disable octet-counted framing + for imtcp, directive is $InputTCPServerSupportOctetCountedFraming - added capability to use a local interface IP address as fromhost-ip for imuxsock imklog new config directives: $IMUXSockLocalIPIF, $klogLocalIPIF diff --git a/doc/imtcp.html b/doc/imtcp.html index 422bbd55..cd10f712 100644 --- a/doc/imtcp.html +++ b/doc/imtcp.html @@ -74,6 +74,12 @@ listener. <id-string> semantics depend on the currently selected AuthMode and  network stream driver. PermittedPeers may not be set in anonymous modes.
  • $InputTCPServerBindRuleset <ruleset>
    Binds the listener to a specific ruleset.
  • +
  • $InputTCPSupportOctetCountedFraming <on|off>
    +If set to "on", the legacy octed-counted framing (similar to RFC5425 framing) is +activated. This is the default and should be left unchanged until you know +very well what you do. It may be useful to turn it off, if you know this framing +is not used and some senders emit multi-line messages into the message stream. +
  • Caveats/Known Bugs:
      diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c index b3468921..bcbbab09 100644 --- a/plugins/imdiag/imdiag.c +++ b/plugins/imdiag/imdiag.c @@ -376,7 +376,8 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa /* initialized, now add socket */ CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? UCHAR_CONSTANT("imdiag") : pszInputName)); - tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); + /* we support octect-cuunted frame (constant 1 below) */ + tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal, 1); finalize_it: if(iRet != RS_RET_OK) { diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c index 446795d6..cc969aa5 100644 --- a/plugins/imgssapi/imgssapi.c +++ b/plugins/imgssapi/imgssapi.c @@ -335,7 +335,7 @@ addGSSListener(void __attribute__((unused)) *pVal, uchar *pNewVal) CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, UCHAR_CONSTANT("imgssapi"))); - tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); + tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal, 1); CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); } diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 6ab39477..2239d0f4 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -83,6 +83,7 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ +static int bSuppOctetFram = 1; /* octet counted TCP framing supported? */ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */ @@ -215,7 +216,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, pBindRuleset)); CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : pszInputName)); - tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); + tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal, bSuppOctetFram); finalize_it: if(iRet != RS_RET_OK) { @@ -287,6 +288,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iTCPSessMax = 200; + bSuppOctetFram = 1; iTCPLstnMax = 20; iStrmDrvrMode = 0; bEmitMsgOnClose = 0; @@ -324,6 +326,8 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary, + NULL, &bSuppOctetFram, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, diff --git a/tcps_sess.c b/tcps_sess.c index 854d3742..87de6c01 100644 --- a/tcps_sess.c +++ b/tcps_sess.c @@ -199,6 +199,8 @@ SetLstnInfo(tcps_sess_t *pThis, tcpLstnPortList_t *pLstnInfo) ISOBJ_TYPE_assert(pThis, tcps_sess); assert(pLstnInfo != NULL); pThis->pLstnInfo = pLstnInfo; + /* set cached elements */ + pThis->bSuppOctetFram = pLstnInfo->bSuppOctetFram; RETiRet; } @@ -363,7 +365,7 @@ processDataRcvd(tcps_sess_t *pThis, char c, struct syslogTime *stTime, time_t tt ISOBJ_TYPE_assert(pThis, tcps_sess); if(pThis->inputState == eAtStrtFram) { - if(isdigit((int) c)) { + if(pThis->bSuppOctetFram && isdigit((int) c)) { pThis->inputState = eInOctetCnt; pThis->iOctetsRemain = 0; pThis->eFraming = TCP_FRAMING_OCTET_COUNTING; diff --git a/tcps_sess.h b/tcps_sess.h index 0799db99..054ce397 100644 --- a/tcps_sess.h +++ b/tcps_sess.h @@ -35,7 +35,8 @@ struct tcps_sess_s { tcpLstnPortList_t *pLstnInfo; /* pointer back to listener info */ netstrm_t *pStrm; int iMsg; /* index of next char to store in msg */ - int bAtStrtOfFram; /* are we at the very beginning of a new frame? */ + sbool bAtStrtOfFram; /* are we at the very beginning of a new frame? */ + sbool bSuppOctetFram; /**< copy from listener, to speed up access */ enum { eAtStrtFram, eInOctetCnt, diff --git a/tcpsrv.c b/tcpsrv.c index dcf407c0..d5853477 100644 --- a/tcpsrv.c +++ b/tcpsrv.c @@ -100,7 +100,7 @@ DEFobjCurrIf(statsobj) * rgerhards, 2009-05-21 */ static inline rsRetVal -addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort) +addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort, int bSuppOctetFram) { tcpLstnPortList_t *pEntry; uchar statname[64]; @@ -113,6 +113,7 @@ addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort) pEntry->pszPort = pszPort; pEntry->pSrv = pThis; pEntry->pRuleset = pThis->pRuleset; + pEntry->bSuppOctetFram = bSuppOctetFram; /* we need to create a property */ CHKiRet(prop.Construct(&pEntry->pInputName)); @@ -143,7 +144,7 @@ finalize_it: * rgerhards, 2008-03-20 */ static rsRetVal -configureTCPListen(tcpsrv_t *pThis, uchar *pszPort) +configureTCPListen(tcpsrv_t *pThis, uchar *pszPort, int bSuppOctetFram) { int i; uchar *pPort = pszPort; @@ -159,7 +160,7 @@ configureTCPListen(tcpsrv_t *pThis, uchar *pszPort) } if(i >= 0 && i <= 65535) { - CHKiRet(addNewLstnPort(pThis, pszPort)); + CHKiRet(addNewLstnPort(pThis, pszPort, bSuppOctetFram)); } else { errmsg.LogError(0, NO_ERRCODE, "Invalid TCP listen port %s - ignored.\n", pszPort); } diff --git a/tcpsrv.h b/tcpsrv.h index f958f917..0b405306 100644 --- a/tcpsrv.h +++ b/tcpsrv.h @@ -41,6 +41,7 @@ struct tcpLstnPortList_s { tcpsrv_t *pSrv; /**< pointer to higher-level server instance */ ruleset_t *pRuleset; /**< associated ruleset */ statsobj_t *stats; /**< associated stats object */ + sbool bSuppOctetFram; /**< do we support octect-counted framing? (if no->legay only!)*/ STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) tcpLstnPortList_t *pNext; /**< next port or NULL */ }; @@ -91,7 +92,7 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(tcpsrv_t **ppThis); rsRetVal (*ConstructFinalize)(tcpsrv_t __attribute__((unused)) *pThis); rsRetVal (*Destruct)(tcpsrv_t **ppThis); - rsRetVal (*configureTCPListen)(tcpsrv_t*, uchar *pszPort); + rsRetVal (*configureTCPListen)(tcpsrv_t*, uchar *pszPort, int bSuppOctetFram); //rsRetVal (*SessAccept)(tcpsrv_t *pThis, tcpLstnPortList_t*, tcps_sess_t **ppSess, netstrm_t *pStrm); rsRetVal (*create_tcp_socket)(tcpsrv_t *pThis); rsRetVal (*Run)(tcpsrv_t *pThis); @@ -124,11 +125,12 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */ /* added v9 -- rgerhards, 2010-03-01 */ rsRetVal (*SetbDisableLFDelim)(tcpsrv_t*, int); ENDinterface(tcpsrv) -#define tcpsrvCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */ +#define tcpsrvCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */ /* change for v4: * - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10 * - SetInputName() added -- rgerhards, 2008-12-10 * change for v5 and up: see above + * for v10: param bSuppOctetFram added to configureTCPListen */ -- cgit From c6714bc496a2aaf356d8625784f10168d33859a3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 20 Mar 2012 14:11:18 +0100 Subject: added configuration directive to disable octet-counted framing for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming --- ChangeLog | 1 + doc/imptcp.html | 6 ++++++ plugins/imptcp/imptcp.c | 17 ++++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 775e7e3f..f2a4e865 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ - added configuration directive to disable octet-counted framing for imtcp, directive is $InputTCPServerSupportOctetCountedFraming + for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming - added capability to use a local interface IP address as fromhost-ip for imuxsock imklog new config directives: $IMUXSockLocalIPIF, $klogLocalIPIF diff --git a/doc/imptcp.html b/doc/imptcp.html index d4228185..87d81a0c 100644 --- a/doc/imptcp.html +++ b/doc/imptcp.html @@ -43,6 +43,12 @@ very limited interest in fixing this issue. This directive can not fix th That would require much more code changes, which I was unable to do so far. Full details can be found at the Cisco tcp syslog anomaly page. +
    • $InputPTCPSupportOctetCountedFraming <on|off>
      +If set to "on", the legacy octed-counted framing (similar to RFC5425 framing) is +activated. This is the default and should be left unchanged until you know +very well what you do. It may be useful to turn it off, if you know this framing +is not used and some senders emit multi-line messages into the message stream. +
    • $InputPTCPServerNotifyOnConnectionClose [on/off]
      instructs imptcp to emit a message if the remote peer closes a connection.
    • $InputPTCPServerRun <port>
      diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 9c6c64e4..3973041b 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -89,6 +89,7 @@ DEFobjCurrIf(statsobj) /* config settings */ typedef struct configSettings_s { int bEmitMsgOnClose; /* emit an informational message on close by remote peer */ + int bSuppOctetFram; /* support octet-counted framing? */ int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */ uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */ uchar *lstnIP; /* which IP we should listen on? */ @@ -111,7 +112,8 @@ struct ptcpsrv_s { ptcpsrv_t *pNext; /* linked list maintenance */ uchar *port; /* Port to listen to */ uchar *lstnIP; /* which IP we should listen on? */ - int bEmitMsgOnClose; + sbool bEmitMsgOnClose; + sbool bSuppOctetFram; int iAddtlFrameDelim; uchar *pszInputName; prop_t *pInputName; /* InputName in (fast to process) property format */ @@ -132,6 +134,7 @@ struct ptcpsess_s { //--- from tcps_sess.h int iMsg; /* index of next char to store in msg */ int bAtStrtOfFram; /* are we at the very beginning of a new frame? */ + sbool bSuppOctetFram; /**< copy from listener, to speed up access */ enum { eAtStrtFram, eInOctetCnt, @@ -152,6 +155,7 @@ struct ptcplstn_s { ptcpsrv_t *pSrv; /* our server */ ptcplstn_t *prev, *next; int sock; + sbool bSuppOctetFram; epolld_t *epd; statsobj_t *stats; /* listener stats */ STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) @@ -551,7 +555,7 @@ processDataRcvd(ptcpsess_t *pThis, char c, struct syslogTime *stTime, time_t ttG DEFiRet; if(pThis->inputState == eAtStrtFram) { - if(isdigit((int) c)) { + if(pThis->bSuppOctetFram && isdigit((int) c)) { pThis->inputState = eInOctetCnt; pThis->iOctetsRemain = 0; pThis->eFraming = TCP_FRAMING_OCTET_COUNTING; @@ -690,6 +694,7 @@ static inline void initConfigSettings(void) { cs.bEmitMsgOnClose = 0; + cs.bSuppOctetFram = 1; cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; cs.pszInputName = NULL; cs.pRuleset = NULL; @@ -705,7 +710,7 @@ addEPollSock(epolld_type_t typ, void *ptr, int sock, epolld_t **pEpd) DEFiRet; epolld_t *epd = NULL; - CHKmalloc(epd = malloc(sizeof(epolld_t))); + CHKmalloc(epd = calloc(sizeof(epolld_t), 1)); epd->typ = typ; epd->ptr = ptr; *pEpd = epd; @@ -767,6 +772,7 @@ addLstn(ptcpsrv_t *pSrv, int sock, int isIPv6) CHKmalloc(pLstn = malloc(sizeof(ptcplstn_t))); pLstn->pSrv = pSrv; + pLstn->bSuppOctetFram = pSrv->bSuppOctetFram; pLstn->sock = sock; /* support statistics gathering */ CHKiRet(statsobj.Construct(&(pLstn->stats))); @@ -807,6 +813,7 @@ addSess(ptcplstn_t *pLstn, int sock, prop_t *peerName, prop_t *peerIP) CHKmalloc(pSess->pMsg = malloc(iMaxLine * sizeof(uchar))); pSess->pLstn = pLstn; pSess->sock = sock; + pSess->bSuppOctetFram = pLstn->bSuppOctetFram; pSess->inputState = eAtStrtFram; pSess->iMsg = 0; pSess->bAtStrtOfFram = 1; @@ -907,6 +914,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKmalloc(pSrv = malloc(sizeof(ptcpsrv_t))); pSrv->pSess = NULL; pSrv->pLstn = NULL; + pSrv->bSuppOctetFram = cs.bSuppOctetFram; pSrv->bEmitMsgOnClose = cs.bEmitMsgOnClose; pSrv->port = pNewVal; pSrv->iAddtlFrameDelim = cs.iAddtlFrameDelim; @@ -1172,6 +1180,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { cs.bEmitMsgOnClose = 0; + cs.bSuppOctetFram = 1; cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; free(cs.pszInputName); cs.pszInputName = NULL; @@ -1205,6 +1214,8 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverrun"), 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary, + NULL, &cs.bSuppOctetFram, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpservernotifyonconnectionclose"), 0, eCmdHdlrBinary, NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, -- cgit From dbc2efa6bea0a0ca7ded6d4a5f0378da0aab6936 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 21 Mar 2012 11:35:23 +0100 Subject: do not provide weblink with meaningless (generic) error code --- runtime/errmsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/errmsg.c b/runtime/errmsg.c index 09246944..e3555c1f 100644 --- a/runtime/errmsg.c +++ b/runtime/errmsg.c @@ -84,13 +84,13 @@ LogError(int iErrno, int iErrCode, char *fmt, ... ) if(iErrno != 0) { rs_strerror_r(iErrno, errStr, sizeof(errStr)); - if(iErrCode == NO_ERRCODE) { + if(iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) { snprintf(msg, sizeof(msg), "%s: %s", buf, errStr); } else { snprintf(msg, sizeof(msg), "%s: %s [try http://www.rsyslog.com/e/%d ]", buf, errStr, iErrCode * -1); } } else { - if(iErrCode == NO_ERRCODE) { + if(iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) { snprintf(msg, sizeof(msg), "%s", buf); } else { snprintf(msg, sizeof(msg), "%s [try http://www.rsyslog.com/e/%d ]", buf, iErrCode * -1); -- cgit From 49ec54d36984b9e91da7bd41e56e65dac22ce830 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 21 Mar 2012 11:43:45 +0100 Subject: milestone: added capability to use a local interface IP address as fromhost-ip ... for locally originating messages. New directive $LocalHostIPIF. Note that not all modules yet support this new directive - next step... --- ChangeLog | 3 +- doc/rsyslog_conf_global.html | 13 +++++ plugins/impstats/impstats.c | 8 +-- runtime/glbl.c | 128 ++++++++++++++++++++++++++++++++----------- runtime/glbl.h | 32 +++++------ tools/syslogd.c | 11 +--- 6 files changed, 130 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index f2a4e865..b9e56ec2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,8 +2,7 @@ for imtcp, directive is $InputTCPServerSupportOctetCountedFraming for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming - added capability to use a local interface IP address as fromhost-ip for - imuxsock imklog - new config directives: $IMUXSockLocalIPIF, $klogLocalIPIF + locally originating messages. New directive $LocalHostIPIF - added configuration directives to customize queue light delay marks $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both specify number of messages starting at which a delay happens. diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index 21786a7f..86e4bab2 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -301,6 +301,19 @@ the value, the less precise the timestamp.
    • $Sleep <seconds> - puts the rsyslog main thread to sleep for the specified number of seconds immediately when the directive is encountered. You should have a good reason for using this directive!
    • +
    • $LocalHostIPIF <interface name> - (available since 5.9.6) - if provided, the IP of the specified +interface (e.g. "eth0") shall be used as fromhost-ip for locall-originating messages. +If this directive is not given OR the interface cannot be found (or has no IP address), +the default of "127.0.0.1" is used. Note that this directive can be given only +once. Trying to reset will result in an error message and the new value will +be ignored. Please note that modules must have support for obtaining the local +IP address set via this directive. While this is the case for rsyslog-provided +modules, it may not always be the case for contributed plugins. +
      Important: This directive shall be placed right at the top of +rsyslog.conf. Otherwise, if error messages are triggered before this directive +is processed, rsyslog will fix the local host IP to "127.0.0.1", what than can +not be reset. +
    • $UMASK

    Where <size_nbr> is specified above, diff --git a/plugins/impstats/impstats.c b/plugins/impstats/impstats.c index 3012136c..ba497e01 100644 --- a/plugins/impstats/impstats.c +++ b/plugins/impstats/impstats.c @@ -62,7 +62,6 @@ typedef struct configSettings_s { static configSettings_t cs; static prop_t *pInputName = NULL; -static prop_t *pLocalHostIP = NULL; BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature @@ -92,7 +91,7 @@ doSubmitMsg(uchar *line) MsgSetRawMsgWOSize(pMsg, (char*)line); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); - MsgSetRcvFromIP(pMsg, pLocalHostIP); + MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); MsgSetTAG(pMsg, UCHAR_CONSTANT("rsyslogd-pstats:"), sizeof("rsyslogd-pstats:") - 1); pMsg->iFacility = cs.iFacility; @@ -169,7 +168,6 @@ ENDafterRun BEGINmodExit CODESTARTmodExit prop.Destruct(&pInputName); - prop.Destruct(&pLocalHostIP); /* release objects we used */ objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); @@ -212,10 +210,6 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("impstats"), sizeof("impstats") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); - - CHKiRet(prop.Construct(&pLocalHostIP)); - CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); - CHKiRet(prop.ConstructFinalize(pLocalHostIP)); ENDmodInit /* vi:set ai: */ diff --git a/runtime/glbl.c b/runtime/glbl.c index dea5a17b..134e6c6e 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -7,25 +7,23 @@ * * Module begun 2008-04-16 by Rainer Gerhards * - * Copyright 2008 Rainer Gerhards and Adiscon GmbH. + * Copyright 2008-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * - * The rsyslog runtime library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The rsyslog runtime library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the rsyslog runtime library. If not, see . - * - * A copy of the GPL can be found in the file "COPYING" in this distribution. - * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include "config.h" @@ -44,6 +42,7 @@ #include "prop.h" #include "atomic.h" #include "errmsg.h" +#include "net.h" /* some defaults */ #ifndef DFLT_NETSTRM_DRVR @@ -54,6 +53,7 @@ DEFobjStaticHelpers DEFobjCurrIf(prop) DEFobjCurrIf(errmsg) +DEFobjCurrIf(net) /* static data * For this object, these variables are obviously what makes the "meat" of the @@ -68,6 +68,7 @@ static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */ static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */ static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */ +static prop_t *propLocalIPIF = NULL;/* IP address to report for the local host (default is 127.0.0.1) */ static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */ static uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */ @@ -152,6 +153,60 @@ static void SetGlobalInputTermination(void) } +/* set the local host IP address to a specific string. Helper to + * small set of functions. No checks done, caller must ensure it is + * ok to call. Most importantly, the IP address must not already have + * been set. -- rgerhards, 2012-03-21 + */ +static inline rsRetVal +storeLocalHostIPIF(uchar *myIP) +{ + DEFiRet; + CHKiRet(prop.Construct(&propLocalIPIF)); + CHKiRet(prop.SetString(propLocalIPIF, myIP, ustrlen(myIP))); + CHKiRet(prop.ConstructFinalize(propLocalIPIF)); + DBGPRINTF("rsyslog/glbl: using '%s' as localhost IP\n", myIP); +finalize_it: + RETiRet; +} + + +/* This function is used to set the IP address that is to be + * reported for the local host. Note that in order to ease things + * for the v6 config interface, we do not allow to set this more + * than once. + * rgerhards, 2012-03-21 + */ +static rsRetVal +setLocalHostIPIF(void __attribute__((unused)) *pVal, uchar *pNewVal) +{ + uchar myIP[128]; + rsRetVal localRet; + DEFiRet; + + CHKiRet(objUse(net, CORE_COMPONENT)); + + if(propLocalIPIF != NULL) { + errmsg.LogError(0, RS_RET_ERR, "$LocalHostIPIF is already set " + "and cannot be reset; place it at TOP OF rsyslog.conf!"); + ABORT_FINALIZE(RS_RET_ERR_WRKDIR); + } + + localRet = net.GetIFIPAddr(pNewVal, AF_UNSPEC, myIP, (int) sizeof(myIP)); + if(localRet != RS_RET_OK) { + errmsg.LogError(0, RS_RET_ERR, "$LocalIPIF: IP address for interface " + "'%s' cannnot be obtained - ignoring directive", pNewVal); + } else { + storeLocalHostIPIF(myIP); + } + + +finalize_it: + free(pNewVal); /* no longer needed -> is in prop! */ + RETiRet; +} + + /* This function is used to set the global work directory name. * It verifies that the provided directory actually exists and * emits an error message if not. @@ -202,6 +257,22 @@ finalize_it: RETiRet; } +/* return our local IP. + * If no local IP is set, "127.0.0.1" is selected *and* set. This + * is an intensional side effect that we do in order to keep things + * consistent and avoid config errors (this will make us not accept + * setting the local IP address once a module has obtained it - so + * it forces the $LocalHostIPIF directive high up in rsyslog.conf) + * rgerhards, 2012-03-21 + */ +static prop_t* +GetLocalHostIP(void) +{ + if(propLocalIPIF == NULL) + storeLocalHostIPIF((uchar*)"127.0.0.1"); + return(propLocalIPIF); +} + /* return our local hostname. if it is not set, "[localhost]" is returned */ static uchar* @@ -338,6 +409,7 @@ CODESTARTobjQueryInterface(glbl) pIf->GetWorkDir = GetWorkDir; pIf->GenerateLocalHostNameProperty = GenerateLocalHostNameProperty; pIf->GetLocalHostNameProp = GetLocalHostNameProp; + pIf->GetLocalHostIP = GetLocalHostIP; pIf->SetGlobalInputTermination = SetGlobalInputTermination; pIf->GetGlobalInputTermState = GetGlobalInputTermState; #define SIMP_PROP(name) \ @@ -417,7 +489,7 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */ CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); - /* register config handlers (TODO: we need to implement a way to unregister them) */ + /* config handlers are never unregistered and need not be - we are always loaded ;) */ CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, setWorkDir, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvr, NULL)); @@ -425,6 +497,7 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */ CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrKeyFile, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCertFile, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"localhostname", 0, eCmdHdlrGetWord, NULL, &LocalHostNameOverride, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"localhostipif", 0, eCmdHdlrGetWord, setLocalHostIPIF, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrBinary, NULL, &bOptimizeUniProc, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"preservefqdn", 0, eCmdHdlrBinary, NULL, &bPreserveFQDN, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); @@ -437,21 +510,14 @@ ENDObjClassInit(glbl) * rgerhards, 2008-04-17 */ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */ - if(pszDfltNetstrmDrvr != NULL) - free(pszDfltNetstrmDrvr); - if(pszDfltNetstrmDrvrCAF != NULL) - free(pszDfltNetstrmDrvrCAF); - if(pszDfltNetstrmDrvrKeyFile != NULL) - free(pszDfltNetstrmDrvrKeyFile); - if(pszDfltNetstrmDrvrCertFile != NULL) - free(pszDfltNetstrmDrvrCertFile); - if(pszWorkDir != NULL) - free(pszWorkDir); - if(LocalHostName != NULL) - free(LocalHostName); + free(pszDfltNetstrmDrvr); + free(pszDfltNetstrmDrvrCAF); + free(pszDfltNetstrmDrvrKeyFile); + free(pszDfltNetstrmDrvrCertFile); + free(pszWorkDir); + free(LocalHostName); free(LocalHostNameOverride); - if(LocalFQDNName != NULL) - free(LocalFQDNName); + free(LocalFQDNName); objRelease(prop, CORE_COMPONENT); DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs); ENDObjClassExit(glbl) diff --git a/runtime/glbl.h b/runtime/glbl.h index 4b4bdf83..3c5e8501 100644 --- a/runtime/glbl.h +++ b/runtime/glbl.h @@ -8,25 +8,23 @@ * Please note that there currently is no glbl.c file as we do not yet * have any implementations. * - * Copyright 2008, 2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2008-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * - * The rsyslog runtime library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The rsyslog runtime library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the rsyslog runtime library. If not, see . - * - * A copy of the GPL can be found in the file "COPYING" in this distribution. - * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #ifndef GLBL_H_INCLUDED @@ -77,6 +75,8 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */ SIMP_PROP(FdSetSize, int) /* v7: was neeeded to mean v5+v6 - do NOT add anything else for that version! */ /* next change is v8! */ + /* v8 - 2012-03-21 */ + prop_t* (*GetLocalHostIP)(void); #undef SIMP_PROP ENDinterface(glbl) #define glblCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */ diff --git a/tools/syslogd.c b/tools/syslogd.c index 02a0dad6..9cd3c9ca 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -199,7 +199,6 @@ static rsRetVal GlobalClassExit(void); #endif static prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */ -static prop_t *pLocalHostIP = NULL; /* there is only one global IP for all internally-generated messages */ static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */ static char *PidFile = _PATH_LOGPID; /* read-only after startup */ @@ -545,7 +544,8 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) MsgSetRawMsgWOSize(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); - MsgSetRcvFromIP(pMsg, pLocalHostIP); +dbgprintf("ZZZZ: pLocalHostIPIF used!\n"); + MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); /* check if we have an error code associated and, if so, * adjust the tag. -- rgerhards, 2008-06-27 @@ -1109,8 +1109,6 @@ die(int sig) /* destruct our global properties */ if(pInternalInputName != NULL) prop.Destruct(&pInternalInputName); - if(pLocalHostIP != NULL) - prop.Destruct(&pLocalHostIP); /* terminate the remaining classes */ GlobalClassExit(); @@ -2660,10 +2658,6 @@ int realMain(int argc, char **argv) CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); - CHKiRet(prop.Construct(&pLocalHostIP)); - CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); - CHKiRet(prop.ConstructFinalize(pLocalHostIP)); - /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ @@ -2712,7 +2706,6 @@ int realMain(int argc, char **argv) CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); } else { CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - int i; } if((p = (uchar*)strchr((char*)LocalHostName, '.'))) -- cgit From 1d6d534df2368c906a2d80663634b2eef5535ef7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 22 Mar 2012 16:06:57 +0100 Subject: unified use of $LocalHostIPIF among all locally-emitting inputs with the exception of imdiag, which I humbly do not think needs this capabilit (even counter-productive for testbench use). --- plugins/imklog/imklog.c | 24 +----------------------- plugins/imuxsock/imuxsock.c | 27 +-------------------------- runtime/glbl.c | 2 +- 3 files changed, 3 insertions(+), 50 deletions(-) diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 66d7d143..b6fd7c79 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -74,7 +74,6 @@ int symbols_twice = 0; int use_syscall = 0; int symbol_lookup = 0; /* on recent kernels > 2.6, the kernel does this */ int bPermitNonKernel = 0; /* permit logging of messages not having LOG_KERN facility */ -static uchar *pLocalIPIF = NULL; int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */ uchar *pszPath = NULL; int console_log_level = -1; @@ -237,22 +236,10 @@ ENDrunInput BEGINwillRun - uchar myIP[128]; - rsRetVal localRet; CODESTARTwillRun /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.CreateStringProp(&pInputName, UCHAR_CONSTANT("imklog"), sizeof("imklog") - 1)); - if(pLocalIPIF == NULL) { - strcpy((char*)myIP, "127.0.0.1"); - } else { - localRet = net.GetIFIPAddr(pLocalIPIF, AF_UNSPEC, myIP, (int) sizeof(myIP)); - if(localRet != RS_RET_OK) { - DBGPRINTF("imuxsock: could not obtain my IP, using 127.0.0.1 instead\n"); - strcpy((char*)myIP, "127.0.0.1"); - } - } - DBGPRINTF("imklog: using '%s' as localhost IP\n", myIP); - CHKiRet(prop.CreateStringProp(&pLocalHostIP, myIP, ustrlen(myIP))); + pLocalHostIP = glbl.GetLocalHostIP(); iRet = klogWillRun(); finalize_it: @@ -265,9 +252,6 @@ CODESTARTafterRun if(pInputName != NULL) prop.Destruct(&pInputName); - if(pLocalHostIP != NULL) - prop.Destruct(&pLocalHostIP); - free(pLocalIPIF); ENDafterRun @@ -300,10 +284,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a free(pszPath); pszPath = NULL; } - if(pLocalIPIF != NULL) { - free(pLocalIPIF); - pLocalIPIF = NULL; - } iFacilIntMsg = klogFacilIntMsg(); return RS_RET_OK; } @@ -327,8 +307,6 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpermitnonkernelfacility", 0, eCmdHdlrBinary, NULL, &bPermitNonKernel, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogconsoleloglevel", 0, eCmdHdlrInt, NULL, &console_log_level, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloginternalmsgfacility", 0, eCmdHdlrFacility, NULL, &iFacilIntMsg, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloglocalipif", 0, eCmdHdlrGetWord, - NULL, &pLocalIPIF, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit /* vim:set ai: diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 0e91a977..ad290331 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -158,7 +158,6 @@ static int sd_fds = 0; /* number of systemd activated sockets */ /* config settings */ static int bOmitLocalLogging = 0; static uchar *pLogSockName = NULL; -static uchar *pLocalIPIF = NULL; static uchar *pLogHostName = NULL; /* host name to use with this socket */ static int bUseFlowCtl = 0; /* use flow control or not (if yes, only LIGHT is used! */ static int bIgnoreTimestamp = 1; /* ignore timestamps present in the incoming message? */ @@ -766,8 +765,6 @@ ENDrunInput BEGINwillRun - uchar myIP[128]; - rsRetVal localRet; CODESTARTwillRun register int i; int actSocks; @@ -830,22 +827,7 @@ CODESTARTwillRun CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); - if(pLocalIPIF == NULL) { - strcpy((char*)myIP, "127.0.0.1"); - } else { - localRet = net.GetIFIPAddr((uchar*)pLocalIPIF, AF_UNSPEC, myIP, (int) sizeof(myIP)); - if(localRet != RS_RET_OK) { - DBGPRINTF("imuxsock: could not obtain my IP, using 127.0.0.1 instead\n"); - strcpy((char*)myIP, "127.0.0.1"); - } - } - - DBGPRINTF("imuxsock: using '%s' as localhost IP\n", myIP); - - CHKiRet(prop.Construct(&pLocalHostIP)); - CHKiRet(prop.SetString(pLocalHostIP, myIP, ustrlen(myIP))); - CHKiRet(prop.ConstructFinalize(pLocalHostIP)); - + pLocalHostIP = glbl.GetLocalHostIP(); finalize_it: ENDwillRun @@ -878,7 +860,6 @@ CODESTARTafterRun } /* free no longer needed string */ free(pLogSockName); - free(pLocalIPIF); free(pLogHostName); discardLogSockets(); @@ -923,10 +904,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a free(pLogSockName); pLogSockName = NULL; } - if(pLocalIPIF != NULL) { - free(pLocalIPIF); - pLocalIPIF = NULL; - } if(pLogHostName != NULL) { free(pLogHostName); pLogHostName = NULL; @@ -1011,8 +988,6 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &ratelimitSeverity, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"imuxsocklocalipif", 0, eCmdHdlrGetWord, - NULL, &pLocalIPIF, STD_LOADABLE_MODULE_ID)); /* the following one is a (dirty) trick: the system log socket is not added via * an "addUnixListenSocket" config format. As such, it's properties can not be modified * via $InputUnixListenSocket*". So we need to add a special directive diff --git a/runtime/glbl.c b/runtime/glbl.c index 134e6c6e..4f2ee377 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -194,7 +194,7 @@ setLocalHostIPIF(void __attribute__((unused)) *pVal, uchar *pNewVal) localRet = net.GetIFIPAddr(pNewVal, AF_UNSPEC, myIP, (int) sizeof(myIP)); if(localRet != RS_RET_OK) { - errmsg.LogError(0, RS_RET_ERR, "$LocalIPIF: IP address for interface " + errmsg.LogError(0, RS_RET_ERR, "$LocalHostIPIF: IP address for interface " "'%s' cannnot be obtained - ignoring directive", pNewVal); } else { storeLocalHostIPIF(myIP); -- cgit From da2039614ffd93b8fb1ebddf2ed3eb6dc873c1a5 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 22 Mar 2012 18:13:11 +0100 Subject: cosmetic: pushing temp version up --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b38a1955..1200294b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.8-newstats10],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.8-newstats11],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -- cgit From 948d8231c7d4d47bb25ef6fc83d9a5ac6c8576a6 Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Thu, 5 Apr 2012 13:55:20 +0200 Subject: bugfix: segfault if disk-queue was started up with old queue file Signed-off-by: Rainer Gerhards --- ChangeLog | 2 ++ runtime/queue.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83e7f4ee..b19dba0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ --------------------------------------------------------------------------- Version 5.8.10 [V5-stable] 2012-??-?? +- bugfix: segfault if disk-queue was started up with old queue file + Thanks to Tomas Heinrich for the patch. - bugfix: memory leak in array passing output module mode --------------------------------------------------------------------------- Version 5.8.9 [V5-stable] 2012-03-15 diff --git a/runtime/queue.c b/runtime/queue.c index 621a4eed..137c9547 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -2018,13 +2018,16 @@ static rsRetVal qqueuePersist(qqueue_t *pThis, int bIsCheckpoint) CHKiRet(obj.EndSerialize(psQIF)); /* now persist the stream info */ - CHKiRet(strm.Serialize(pThis->tVars.disk.pWrite, psQIF)); - CHKiRet(strm.Serialize(pThis->tVars.disk.pReadDel, psQIF)); + if(pThis->tVars.disk.pWrite != NULL) + CHKiRet(strm.Serialize(pThis->tVars.disk.pWrite, psQIF)); + if(pThis->tVars.disk.pReadDel != NULL) + CHKiRet(strm.Serialize(pThis->tVars.disk.pReadDel, psQIF)); /* tell the input file object that it must not delete the file on close if the queue * is non-empty - but only if we are not during a simple checkpoint */ - if(bIsCheckpoint != QUEUE_CHECKPOINT) { + if(bIsCheckpoint != QUEUE_CHECKPOINT + && pThis->tVars.disk.pReadDel != NULL) { CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 0)); } -- cgit From 2b76241630aa93218c8853a110251dd71478429e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 5 Apr 2012 13:57:26 +0200 Subject: doc: noted disk queue format change from v4->v5 --- doc/v5compatibility.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/v5compatibility.html b/doc/v5compatibility.html index 6d60062f..cc875b7b 100644 --- a/doc/v5compatibility.html +++ b/doc/v5compatibility.html @@ -16,6 +16,11 @@ available. This processing was redundant and had a lot a drawbacks. For details, please see the rsyslog v4 compatibility notes which elaborate on the reasons and the (few) things you may need to change. +

    Queue on-disk format

    +

    The queue information file format has been changed. When upgrading from v4 to +v5, make sure that the queue is emptied and no on-disk structure present. We did +not go great length in understanding the old format, as there was too little demand +for that (and it being quite some effort if done right).

    Queue Worker Thread Shutdown

    Previous rsyslog versions had the capability to "run" on zero queue worker if no work was required. This was done to save a very limited number of resources. However, -- cgit From a192300aa26484c88aedd306fdb92d7752eee427 Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Thu, 5 Apr 2012 14:18:11 +0200 Subject: bugfix: segfault on startup if $actionqueuefilename was missing for disk queue config Signed-off-by: Rainer Gerhards --- ChangeLog | 3 +++ runtime/queue.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b19dba0e..908dfda9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ --------------------------------------------------------------------------- Version 5.8.10 [V5-stable] 2012-??-?? +- bugfix: segfault on startup if $actionqueuefilename was missing for disk + queue config + Thanks to Tomas Heinrich for the patch. - bugfix: segfault if disk-queue was started up with old queue file Thanks to Tomas Heinrich for the patch. - bugfix: memory leak in array passing output module mode diff --git a/runtime/queue.c b/runtime/queue.c index 137c9547..9f318523 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -2119,7 +2119,8 @@ CODESTARTobjDestruct(qqueue) * direct queue - because in both cases we have none... ;) * with a child! -- rgerhards, 2008-01-28 */ - if(pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL) + if(pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL + && pThis->pWtpReg != NULL) ShutdownWorkers(pThis); if(pThis->bIsDA && getPhysicalQueueSize(pThis) > 0 && pThis->bSaveOnShutdown) { -- cgit From 7b620dc671b6e00aef511448a5191bb5f7e0b03f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 7 Apr 2012 14:30:27 +0200 Subject: doc: fix typo in ChangeLog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4e2d0468..69cc5872 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ --------------------------------------------------------------------------- Version 6.3.8 [DEVEL] 2012-02-?? -- added $PStatsJSON directive to permit stats records in JSON format +- added $PStatJSON directive to permit stats records in JSON format - added "date-unixtimestamp" property replacer option to format as a unix timestamp (seconds since epoch) - added "json" property replacer option to support JSON encoding on a -- cgit From eef1701be28f8f8b00134e6c20a8a493d0e69f80 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 7 Apr 2012 14:35:57 +0200 Subject: preparing for 5.8.10 --- ChangeLog | 2 +- configure.ac | 2 +- doc/manual.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 908dfda9..de33a6ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,5 @@ --------------------------------------------------------------------------- -Version 5.8.10 [V5-stable] 2012-??-?? +Version 5.8.10 [V5-stable] 2012-04-05 - bugfix: segfault on startup if $actionqueuefilename was missing for disk queue config Thanks to Tomas Heinrich for the patch. diff --git a/configure.ac b/configure.ac index 1f72bcce..e7a2619c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.9],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.10],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/doc/manual.html b/doc/manual.html index 690143de..29ac1ad5 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support available directly from the source!

    Please visit the rsyslog sponsor's page to honor the project sponsors or become one yourself! We are very grateful for any help towards the project goals.

    -

    This documentation is for version 5.8.9 (v5-stable branch) of rsyslog. +

    This documentation is for version 5.8.10 (v5-stable branch) of rsyslog. Visit the rsyslog status page to obtain current version information and project status.

    If you like rsyslog, you might -- cgit From c64203c7f2c886712c33c21de7e0e53b7939a883 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 7 Apr 2012 15:10:21 +0200 Subject: permit size modifiers (k,m,g,...) in integer config parameters Thanks to Jo Rhett for the suggestion. --- ChangeLog | 2 ++ doc/rsyslog_conf_global.html | 4 +-- runtime/cfsysline.c | 69 ++++++++++++++++++++++++-------------------- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35ff376d..524d9bfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ --------------------------------------------------------------------------- Version 5.9.6 [V5-DEVEL], 2012-03-?? +- permit size modifiers (k,m,g,...) in integer config parameters + Thanks to Jo Rhett for the suggestion. - bugfix: imklog invalidly computed facility and severity closes: http://bugzilla.adiscon.com/show_bug.cgi?id=313 - added configuration directive to disable octet-counted framing diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index e24b0c15..8cfdd303 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -317,7 +317,7 @@ not be reset.

  • $UMASK
  • -

    Where <size_nbr> is specified above, +

    Where <size_nbr> or integers are specified above, modifiers can be used after the number part. For example, 1k means 1024. Supported are k(ilo), m(ega), g(iga), t(era), p(eta) and e(xa). Lower case letters refer to the traditional binary defintion (e.g. 1m @@ -325,7 +325,7 @@ equals 1,048,576) whereas upper case letters refer to their new 1000-based definition (e.g 1M equals 1,000,000).

    Numbers may include '.' and ',' for readability. So you can for example specify either "1000" or "1,000" with the same result. -Please note that rsyslogd simply ignores the punctuation. Form it's +Please note that rsyslogd simply ignores the punctuation. From it's point of view, "1,,0.0.,.,0" also has the value 1000.

    [manual index] diff --git a/runtime/cfsysline.c b/runtime/cfsysline.c index 4997e0fb..36e586c1 100644 --- a/runtime/cfsysline.c +++ b/runtime/cfsysline.c @@ -154,36 +154,6 @@ finalize_it: } -/* Parse a number from the configuration line. - * rgerhards, 2007-07-31 - */ -static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal) -{ - uchar *p; - DEFiRet; - int64 i; - - assert(pp != NULL); - assert(*pp != NULL); - - CHKiRet(parseIntVal(pp, &i)); - p = *pp; - - if(pSetHdlr == NULL) { - /* we should set value directly to var */ - *((int*)pVal) = (int) i; - } else { - /* we set value via a set function */ - CHKiRet(pSetHdlr(pVal, (int) i)); - } - - *pp = p; - -finalize_it: - RETiRet; -} - - /* Parse a size from the configuration line. This is basically an integer * syntax, but modifiers may be added after the integer (e.g. 1k to mean * 1024). The size must immediately follow the number. Note that the @@ -237,7 +207,44 @@ finalize_it: } -/* Parse and interpet a $FileCreateMode and $umask line. This function +/* Parse a number from the configuration line. + * rgerhards, 2007-07-31 + */ +static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal) +{ + uchar *p; + DEFiRet; + int64 i; + uchar errMsg[256]; /* for dynamic error messages */ + + assert(pp != NULL); + assert(*pp != NULL); + + CHKiRet(doGetSize(pp, NULL,&i)); + p = *pp; + if(i > 2147483648ll) { /*2^31*/ + snprintf((char*) errMsg, sizeof(errMsg)/sizeof(uchar), + "value %lld too large for integer argument.", i); + errmsg.LogError(0, RS_RET_INVALID_VALUE, "%s", errMsg); + ABORT_FINALIZE(RS_RET_INVALID_VALUE); + } + + if(pSetHdlr == NULL) { + /* we should set value directly to var */ + *((int*)pVal) = (int) i; + } else { + /* we set value via a set function */ + CHKiRet(pSetHdlr(pVal, (int) i)); + } + + *pp = p; + +finalize_it: + RETiRet; +} + + +/* Parse and interpret a $FileCreateMode and $umask line. This function * pulls the creation mode and, if successful, stores it * into the global variable so that the rest of rsyslogd * opens files with that mode. Any previous value will be -- cgit From d0a73d3449511392b115ca078517ff659aafe23d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 11 Apr 2012 11:18:41 +0200 Subject: bugfix: hostname was not requeried on HUP Thanks to Marius Tomaschewski for reporting this bug. --- ChangeLog | 4 ++ doc/rsyslog_conf_global.html | 9 --- doc/v5compatibility.html | 1 + runtime/glbl.c | 107 ++++++++++++++++------------ tools/syslogd.c | 165 ++++++++++++++++++++++++------------------- 5 files changed, 161 insertions(+), 125 deletions(-) diff --git a/ChangeLog b/ChangeLog index de33a6ca..31f5fe94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ --------------------------------------------------------------------------- +Version 5.8.11 [V5-stable] 2012-04-?? +- bugfix: hostname was not requeried on HUP + Thanks to Marius Tomaschewski for reporting this bug. +--------------------------------------------------------------------------- Version 5.8.10 [V5-stable] 2012-04-05 - bugfix: segfault on startup if $actionqueuefilename was missing for disk queue config diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index 21786a7f..83eb876b 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -152,15 +152,6 @@ our paper on using multiple rule sets in rsyslog$GssForwardServiceName

  • $GssListenServiceName
  • $GssMode
  • -
  • $HUPisRestart [on/off] - if set to on, a HUP is a full daemon restart. This means any queued messages are discarded (depending -on queue configuration, of course) all modules are unloaded and reloaded. This mode keeps compatible with sysklogd, but is -not recommended for use with rsyslog. To do a full restart, simply stop and start the daemon. The default (since 4.5.1) is "off". -If it is set to "off", a HUP will only close open files. This is a much quicker action and usually -the only one that is needed e.g. for log rotation. Restart-type HUPs (value "on") are depricated -and will go away in rsyslog v5. So it is a good idea to change anything that needs it, now. -Usually that should not be a big issue, as the restart-type HUP can easily be replaced by -something along the lines of "/etc/init.d/rsyslog restart". -
  • $IncludeConfig
  • MainMsgQueueCheckpointInterval <number>
  • $LocalHostName [name] - this directive permits to overwrite the system hostname with the one specified in the directive. If the directive is given diff --git a/doc/v5compatibility.html b/doc/v5compatibility.html index cc875b7b..fc4289c5 100644 --- a/doc/v5compatibility.html +++ b/doc/v5compatibility.html @@ -16,6 +16,7 @@ available. This processing was redundant and had a lot a drawbacks. For details, please see the rsyslog v4 compatibility notes which elaborate on the reasons and the (few) things you may need to change. +

    Please note that starting with 5.8.11 HUP will also requery the local hostname.

    Queue on-disk format

    The queue information file format has been changed. When upgrading from v4 to v5, make sure that the queue is emptied and no on-disk structure present. We did diff --git a/runtime/glbl.c b/runtime/glbl.c index dea5a17b..b6dc7286 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -69,10 +69,10 @@ static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */ static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */ static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */ -static uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ +static uchar *LocalHostName = NULL;/* our hostname - read-only after startup, except HUP */ static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */ -static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup */ -static uchar *LocalDomain; /* our local domain name - read-only after startup */ +static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup, except HUP */ +static uchar *LocalDomain = NULL;/* our local domain name - read-only after startup, except HUP */ static char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */ static char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */ static uchar *pszDfltNetstrmDrvr = NULL; /* module name of default netstream driver */ @@ -115,15 +115,12 @@ SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may chec SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int) SIMP_PROP(Option_DisallowWarning, option_DisallowWarning, int) SIMP_PROP(DisableDNS, bDisableDNS, int) -SIMP_PROP(LocalDomain, LocalDomain, uchar*) SIMP_PROP(StripDomains, StripDomains, char**) SIMP_PROP(LocalHosts, LocalHosts, char**) #ifdef USE_UNLIMITED_SELECT SIMP_PROP(FdSetSize, iFdSetSize, int) #endif -SIMP_PROP_SET(LocalFQDNName, LocalFQDNName, uchar*) -SIMP_PROP_SET(LocalHostName, LocalHostName, uchar*) SIMP_PROP_SET(DfltNetstrmDrvr, pszDfltNetstrmDrvr, uchar*) /* TODO: use custom function which frees existing value */ SIMP_PROP_SET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar*) /* TODO: use custom function which frees existing value */ SIMP_PROP_SET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar*) /* TODO: use custom function which frees existing value */ @@ -202,6 +199,19 @@ finalize_it: RETiRet; } +/* set our local hostname. Free previous hostname, if it was already set. + * Note that we do now do this in a thread + * "once in a lifetime" action which can not be undone. -- gerhards, 2009-07-20 + */ +static rsRetVal +SetLocalHostName(uchar *newname) +{ + free(LocalHostName); + LocalHostName = newname; + return RS_RET_OK; +} + + /* return our local hostname. if it is not set, "[localhost]" is returned */ static uchar* @@ -227,6 +237,26 @@ done: } +/* set our local domain name. Free previous domain, if it was already set. + */ +static rsRetVal +SetLocalDomain(uchar *newname) +{ + free(LocalDomain); + LocalDomain = newname; + return RS_RET_OK; +} + + +/* return our local hostname. if it is not set, "[localhost]" is returned + */ +static uchar* +GetLocalDomain(void) +{ + return LocalDomain; +} + + /* generate the local hostname property. This must be done after the hostname info * has been set as well as PreserveFQDN. * rgerhards, 2009-06-30 @@ -271,6 +301,14 @@ GetLocalHostNameProp(void) } +static rsRetVal +SetLocalFQDNName(uchar *newname) +{ + free(LocalFQDNName); + LocalFQDNName = newname; + return RS_RET_OK; +} + /* return the current localhost name as FQDN (requires FQDN to be set) * TODO: we should set the FQDN ourselfs in here! */ @@ -373,30 +411,18 @@ ENDobjQueryInterface(glbl) */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - if(pszDfltNetstrmDrvr != NULL) { - free(pszDfltNetstrmDrvr); - pszDfltNetstrmDrvr = NULL; - } - if(pszDfltNetstrmDrvrCAF != NULL) { - free(pszDfltNetstrmDrvrCAF); - pszDfltNetstrmDrvrCAF = NULL; - } - if(pszDfltNetstrmDrvrKeyFile != NULL) { - free(pszDfltNetstrmDrvrKeyFile); - pszDfltNetstrmDrvrKeyFile = NULL; - } - if(pszDfltNetstrmDrvrCertFile != NULL) { - free(pszDfltNetstrmDrvrCertFile); - pszDfltNetstrmDrvrCertFile = NULL; - } - if(LocalHostNameOverride != NULL) { - free(LocalHostNameOverride); - LocalHostNameOverride = NULL; - } - if(pszWorkDir != NULL) { - free(pszWorkDir); - pszWorkDir = NULL; - } + free(pszDfltNetstrmDrvr); + pszDfltNetstrmDrvr = NULL; + free(pszDfltNetstrmDrvrCAF); + pszDfltNetstrmDrvrCAF = NULL; + free(pszDfltNetstrmDrvrKeyFile); + pszDfltNetstrmDrvrKeyFile = NULL; + free(pszDfltNetstrmDrvrCertFile); + pszDfltNetstrmDrvrCertFile = NULL; + free(LocalHostNameOverride); + LocalHostNameOverride = NULL; + free(pszWorkDir); + pszWorkDir = NULL; bDropMalPTRMsgs = 0; bOptimizeUniProc = 1; bPreserveFQDN = 0; @@ -437,21 +463,14 @@ ENDObjClassInit(glbl) * rgerhards, 2008-04-17 */ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */ - if(pszDfltNetstrmDrvr != NULL) - free(pszDfltNetstrmDrvr); - if(pszDfltNetstrmDrvrCAF != NULL) - free(pszDfltNetstrmDrvrCAF); - if(pszDfltNetstrmDrvrKeyFile != NULL) - free(pszDfltNetstrmDrvrKeyFile); - if(pszDfltNetstrmDrvrCertFile != NULL) - free(pszDfltNetstrmDrvrCertFile); - if(pszWorkDir != NULL) - free(pszWorkDir); - if(LocalHostName != NULL) - free(LocalHostName); + free(pszDfltNetstrmDrvr); + free(pszDfltNetstrmDrvrCAF); + free(pszDfltNetstrmDrvrKeyFile); + free(pszDfltNetstrmDrvrCertFile); + free(pszWorkDir); + free(LocalHostName); free(LocalHostNameOverride); - if(LocalFQDNName != NULL) - free(LocalFQDNName); + free(LocalFQDNName); objRelease(prop, CORE_COMPONENT); DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs); ENDObjClassExit(glbl) diff --git a/tools/syslogd.c b/tools/syslogd.c index 0b7bbc96..183decb1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -154,6 +154,7 @@ DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); +static rsRetVal queryLocalHostname(void); #ifndef _PATH_LOGCONF @@ -1897,6 +1898,11 @@ DEFFUNC_llExecFunc(doHUPActions) * is *NOT* the sighup handler. The signal is recorded by the handler, that record * detected inside the mainloop and then this function is called to do the * real work. -- rgerhards, 2008-10-22 + * Note: there is a VERY slim chance of a data race when the hostname is reset. + * We prefer to take this risk rather than sync all accesses, because to the best + * of my analysis it can not really hurt (the actual property is reference-counted) + * but the sync would require some extra CPU for *each* message processed. + * rgerhards, 2012-04-11 */ static inline void doHUP(void) @@ -1912,6 +1918,7 @@ doHUP(void) logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } + queryLocalHostname(); /* re-read our name */ ruleset.IterateAllActions(doHUPActions, NULL); } @@ -2329,6 +2336,90 @@ GlobalClassExit(void) } +/* query our host and domain names - we need to do this early as we may emit + * rgerhards, 2012-04-11 + */ +static rsRetVal +queryLocalHostname(void) +{ + uchar *LocalHostName; + uchar *LocalDomain; + uchar *LocalFQDNName; + uchar *p; + struct hostent *hent; + DEFiRet; + + net.getLocalHostname(&LocalFQDNName); + CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); + glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = (uchar*)""; + + /* It's not clearly defined whether gethostname() + * should return the simple hostname or the fqdn. A + * good piece of software should be aware of both and + * we want to distribute good software. Joey + * + * Good software also always checks its return values... + * If syslogd starts up before DNS is up & /etc/hosts + * doesn't have LocalHostName listed, gethostbyname will + * return NULL. + */ + /* TODO: gethostbyname() is not thread-safe, but replacing it is + * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 + */ + hent = gethostbyname((char*)LocalHostName); + if(hent) { + int i = 0; + + if(hent->h_aliases) { + size_t hnlen; + + hnlen = strlen((char *) LocalHostName); + + for (i = 0; hent->h_aliases[i]; i++) { + if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) + && hent->h_aliases[i][hnlen] == '.') { + /* found a matching hostname */ + break; + } + } + } + + free(LocalHostName); + if(hent->h_aliases && hent->h_aliases[i]) { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); + } else { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + } + + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) + { + *p++ = '\0'; + LocalDomain = p; + } + } + } + + /* Convert to lower case to recognize the correct domain laterly */ + for(p = LocalDomain ; *p ; p++) + *p = (char)tolower((int)*p); + + /* we now have our hostname and can set it inside the global vars. + * TODO: think if all of this would better be a runtime function + * rgerhards, 2008-04-17 + */ + glbl.SetLocalHostName(LocalHostName); + glbl.SetLocalDomain(LocalDomain); + glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ +finalize_it: + RETiRet; +} + + /* some support for command line option parsing. Any non-trivial options must be * buffered until the complete command line has been parsed. This is necessary to * prevent dependencies between the options. That, in turn, means we need to have @@ -2530,9 +2621,7 @@ int realMain(int argc, char **argv) { DEFiRet; - register uchar *p; int ch; - struct hostent *hent; extern int optind; extern char *optarg; int bEOptionWasGiven = 0; @@ -2541,9 +2630,6 @@ int realMain(int argc, char **argv) int bChDirRoot = 1; /* change the current working directory to "/"? */ char *arg; /* for command line option processing */ uchar legacyConfLine[80]; - uchar *LocalHostName; - uchar *LocalDomain; - uchar *LocalFQDNName; char cwdbuf[128]; /* buffer to obtain/display current working directory */ /* first, parse the command line options. We do not carry out any actual work, just @@ -2651,7 +2737,7 @@ int realMain(int argc, char **argv) /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInternalInputName)); - CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1)); + CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); CHKiRet(prop.Construct(&pLocalHostIP)); @@ -2661,72 +2747,7 @@ int realMain(int argc, char **argv) /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ - net.getLocalHostname(&LocalFQDNName); - CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); - glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ - if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { - *p++ = '\0'; - LocalDomain = p; - } else { - LocalDomain = (uchar*)""; - - /* It's not clearly defined whether gethostname() - * should return the simple hostname or the fqdn. A - * good piece of software should be aware of both and - * we want to distribute good software. Joey - * - * Good software also always checks its return values... - * If syslogd starts up before DNS is up & /etc/hosts - * doesn't have LocalHostName listed, gethostbyname will - * return NULL. - */ - /* TODO: gethostbyname() is not thread-safe, but replacing it is - * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 - */ - hent = gethostbyname((char*)LocalHostName); - if(hent) { - int i = 0; - - if(hent->h_aliases) { - size_t hnlen; - - hnlen = strlen((char *) LocalHostName); - - for (i = 0; hent->h_aliases[i]; i++) { - if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) - && hent->h_aliases[i][hnlen] == '.') { - /* found a matching hostname */ - break; - } - } - } - - free(LocalHostName); - if(hent->h_aliases && hent->h_aliases[i]) { - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); - } else { - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - } - - if((p = (uchar*)strchr((char*)LocalHostName, '.'))) - { - *p++ = '\0'; - LocalDomain = p; - } - } - } - - /* Convert to lower case to recognize the correct domain laterly */ - for(p = LocalDomain ; *p ; p++) - *p = (char)tolower((int)*p); - - /* we now have our hostname and can set it inside the global vars. - * TODO: think if all of this would better be a runtime function - * rgerhards, 2008-04-17 - */ - glbl.SetLocalHostName(LocalHostName); - glbl.SetLocalDomain(LocalDomain); - glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ + queryLocalHostname(); /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { -- cgit From 6e6bf2ded8b7478772fe9e30a9643844fb320ad4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 11 Apr 2012 12:56:03 +0200 Subject: doc: credits update for last bugfix --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 31f5fe94..8a0d8474 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,8 @@ --------------------------------------------------------------------------- Version 5.8.11 [V5-stable] 2012-04-?? - bugfix: hostname was not requeried on HUP - Thanks to Marius Tomaschewski for reporting this bug. + Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for + his help in testing the fix. --------------------------------------------------------------------------- Version 5.8.10 [V5-stable] 2012-04-05 - bugfix: segfault on startup if $actionqueuefilename was missing for disk -- cgit From a3a0acadb4aa9d09bde3a6951557939b0a0eeda6 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Wed, 11 Apr 2012 14:39:42 +0200 Subject: Allocate LocalDomain as new string LocalDomain points to "" or the domain in LocalHostName, allocate as new string before passing to SetLocalDomain or free will fail later. Signed-off-by: Marius Tomaschewski --- tools/syslogd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/syslogd.c b/tools/syslogd.c index 183decb1..5e94beab 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -2404,6 +2404,9 @@ queryLocalHostname(void) } } + /* LocalDomain is "" or part of LocalHostName, allocate a new string */ + CHKmalloc(LocalDomain = (uchar*)strdup(LocalDomain)); + /* Convert to lower case to recognize the correct domain laterly */ for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); -- cgit From b498a00e7805fbbc2fd1004b47ae2492e9c3da2f Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Wed, 11 Apr 2012 14:53:07 +0200 Subject: Free also LocalDomain in glbl class destructor Signed-off-by: Marius Tomaschewski --- runtime/glbl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/glbl.c b/runtime/glbl.c index b6dc7286..38e1f953 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -468,6 +468,7 @@ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */ free(pszDfltNetstrmDrvrKeyFile); free(pszDfltNetstrmDrvrCertFile); free(pszWorkDir); + free(LocalDomain); free(LocalHostName); free(LocalHostNameOverride); free(LocalFQDNName); -- cgit From e2978cd396551280274bd7a17ec3034e4a0dab9e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 11 Apr 2012 15:37:14 +0200 Subject: imuxsock: fixed regression from last merge thanks to Brian Knox for alerting me and the initial analysis --- plugins/imuxsock/imuxsock.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 39d239b7..4a7e7b42 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -1271,6 +1271,13 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); + /* right now, glbl does not permit per-instance IP address notation. As long as this + * is the case, it is OK to query the HostIP once here at this location. HOWEVER, the + * whole concept is not 100% clean and needs to be addressed on a higher layer. + * TODO / rgerhards, 2012-04-11 + */ + pLocalHostIP = glbl.GetLocalHostIP(); + /* init system log socket settings */ listeners[0].flags = IGNDATE; listeners[0].sockName = UCHAR_CONSTANT(_PATH_LOG); -- cgit From d749dadcc30e35448894a152fb0ddf77d60b8300 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Apr 2012 10:14:32 +0200 Subject: imuxsock: do not cache hostname --- plugins/imuxsock/imuxsock.c | 14 ++++---------- tools/syslogd.c | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 5867f1c9..9ad24213 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -281,16 +281,16 @@ addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNewVal) } else { listeners[nfd].bParseHost = 0; } - CHKiRet(prop.Construct(&(listeners[nfd].hostName))); if(pLogHostName == NULL) { - CHKiRet(prop.SetString(listeners[nfd].hostName, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()))); + listeners[nfd].hostName = NULL; } else { + CHKiRet(prop.Construct(&(listeners[nfd].hostName))); CHKiRet(prop.SetString(listeners[nfd].hostName, pLogHostName, ustrlen(pLogHostName))); + CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); /* reset hostname for next socket */ free(pLogHostName); pLogHostName = NULL; } - CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); if(ratelimitInterval > 0) { if((listeners[nfd].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { /* in this case, we simply turn of rate-limiting */ @@ -602,7 +602,7 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred) pMsg->msgFlags = pLstn->flags; } - MsgSetRcvFrom(pMsg, pLstn->hostName); + MsgSetRcvFrom(pMsg, pLstn->hostName == NULL ? glbl.GetLocalHostNameProp() : pLstn->hostName); CHKiRet(MsgSetRcvFromIP(pMsg, pLocalHostIP)); CHKiRet(submitMsg(pMsg)); @@ -864,7 +864,6 @@ CODESTARTafterRun if(pInputName != NULL) prop.Destruct(&pInputName); - ENDafterRun @@ -958,11 +957,6 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); CHKiRet(prop.ConstructFinalize(pLocalHostIP)); - /* now init listen socket zero, the local log socket */ - CHKiRet(prop.Construct(&(listeners[0].hostName))); - CHKiRet(prop.SetString(listeners[0].hostName, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()))); - CHKiRet(prop.ConstructFinalize(listeners[0].hostName)); - /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary, NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID)); diff --git a/tools/syslogd.c b/tools/syslogd.c index 5e94beab..af63b111 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -21,7 +21,7 @@ * For further information, please see http://www.rsyslog.com * * rsyslog - An Enhanced syslogd Replacement. - * Copyright 2003-2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2003-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * -- cgit From 80d62d6bb7fe19c50f10732f98c8de90094845b0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Apr 2012 14:58:42 +0200 Subject: preparing for 5.9.6 --- ChangeLog | 7 +++++-- configure.ac | 2 +- doc/manual.html | 11 +++++++---- doc/version_naming.html | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35b0656f..2d817343 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,11 @@ --------------------------------------------------------------------------- -Version 5.9.6 [V5-DEVEL], 2012-03-?? +Version 5.9.6 [V5-BETA], 2012-04-12 +- added configuration directives to customize queue light delay marks - permit size modifiers (k,m,g,...) in integer config parameters Thanks to Jo Rhett for the suggestion. +- bugfix: hostname was not requeried on HUP + Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for + his help in testing the fix. - bugfix: imklog invalidly computed facility and severity closes: http://bugzilla.adiscon.com/show_bug.cgi?id=313 - added configuration directive to disable octet-counted framing @@ -9,7 +13,6 @@ Version 5.9.6 [V5-DEVEL], 2012-03-?? for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming - added capability to use a local interface IP address as fromhost-ip for locally originating messages. New directive $LocalHostIPIF -- added configuration directives to customize queue light delay marks --------------------------------------------------------------------------- Version 5.9.5 [V5-DEVEL], 2012-01-27 - improved impstats subsystem, added many new counters diff --git a/configure.ac b/configure.ac index ccb2c47a..6e140b31 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.9.5],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.9.6],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/doc/manual.html b/doc/manual.html index fdeb2980..55809f3e 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support available directly from the source!

    Please visit the rsyslog sponsor's page to honor the project sponsors or become one yourself! We are very grateful for any help towards the project goals.

    -

    This documentation is for version 5.9.4 (stable branch) of rsyslog. +

    This documentation is for version 5.9.6 (stable branch) of rsyslog. Visit the rsyslog status page to obtain current version information and project status.

    If you like rsyslog, you might @@ -46,8 +46,9 @@ if you do not read the doc, but doing so will definitely improve your experience

  • backgrounder on generic syslog application design
  • description of rsyslog modules
  • rsyslog packages
  • -
  • the rsyslog "cookbook" - a set of configurations ready to use
  • +

    To keep current on rsyslog development, follow +Rainer's twitter feed.

    We have some in-depth papers on

    • installing rsyslog
    • @@ -103,14 +104,16 @@ online documentation (most current version only) mailing list. If you are interested in the "backstage", you may find Rainer's -blog an +blog an interesting read (filter on syslog and rsyslog tags). +Or meet Rainer Gerhards at Facebook +or Google+. If you would like to use rsyslog source code inside your open source project, you can do that without any restriction as long as your license is GPLv3 compatible. If your license is incompatible to GPLv3, you may even be still permitted to use rsyslog source code. However, then you need to look at the way rsyslog is licensed.

      Feedback is always welcome, but if you have a support question, please do not mail Rainer directly (why not?) - use the -rsyslogmailing list +rsyslog mailing list or rsyslog formum instead. diff --git a/doc/version_naming.html b/doc/version_naming.html index 8c1b9187..3bfa19bb 100644 --- a/doc/version_naming.html +++ b/doc/version_naming.html @@ -105,7 +105,7 @@ versions. It applies to versions 1.0.0 and above. Versions below that are all unstable and have a different naming schema.

      Please note that version naming is currently being changed. There is a -blog +blog post about future rsyslog versions.

      The major version is incremented whenever a considerate, major features have been added. This is expected to happen quite infrequently.

      @@ -127,4 +127,4 @@ expected to happen quite infrequently.

      In general, the unstable branch carries all new development. Once it concludes with a sufficiently-enhanced, quite stable version, a new major stable version is assigned.

      - \ No newline at end of file + -- cgit From bbefbee0d02e49326ff5757061cde2f26ad088d4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 13 Apr 2012 12:13:50 +0200 Subject: imuxsock: mini bugfix: closed fd was tried to close a second time --- plugins/imuxsock/imuxsock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index ca762d64..c97e6b28 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -458,7 +458,8 @@ createLogSocket(lstn_t *pLstn) chmod((char*)pLstn->sockName, 0666) < 0) { errmsg.LogError(errno, NO_ERRCODE, "cannot create '%s'", pLstn->sockName); dbgprintf("cannot create %s (%d).\n", pLstn->sockName, errno); - close(pLstn->fd); + if(pLstn->fd != -1) + close(pLstn->fd); pLstn->fd = -1; ABORT_FINALIZE(RS_RET_ERR_CRE_AFUX); } @@ -528,8 +529,10 @@ openLogSocket(lstn_t *pLstn) finalize_it: if(iRet != RS_RET_OK) { - close(pLstn->fd); - pLstn->fd = -1; + if(pLstn->fd != -1) { + close(pLstn->fd); + pLstn->fd = -1; + } } RETiRet; -- cgit From 85759e244dc81fa153098e0c5070c1f7aa815a0d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 13 Apr 2012 12:17:08 +0200 Subject: bugfix: report error if module tries to request more strings than supported --- runtime/objomsr.c | 5 ++++- runtime/rsyslog.h | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/runtime/objomsr.c b/runtime/objomsr.c index a1dad1c8..7241fa27 100644 --- a/runtime/objomsr.c +++ b/runtime/objomsr.c @@ -60,11 +60,14 @@ rsRetVal OMSRdestruct(omodStringRequest_t *pThis) */ rsRetVal OMSRconstruct(omodStringRequest_t **ppThis, int iNumEntries) { - omodStringRequest_t *pThis; + omodStringRequest_t *pThis = NULL; DEFiRet; assert(ppThis != NULL); assert(iNumEntries >= 0); + if(iNumEntries > CONF_OMOD_NUMSTRINGS_MAXSIZE) { + ABORT_FINALIZE(RS_RET_MAX_OMSR_REACHED); + } CHKmalloc(pThis = calloc(1, sizeof(omodStringRequest_t))); /* got the structure, so fill it */ diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index ef43efd9..fb0da2d2 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -60,12 +60,12 @@ * rgerhards, 2006-11-30 */ -#define CONF_OMOD_NUMSTRINGS_MAXSIZE 2 /* cache for pointers to output module buffer pointers. All - * rsyslog-provided plugins do NOT need more than two buffers. If +#define CONF_OMOD_NUMSTRINGS_MAXSIZE 3 /* cache for pointers to output module buffer pointers. All + * rsyslog-provided plugins do NOT need more than three buffers. If * more are needed (future developments, third-parties), rsyslog * must be recompiled with a larger parameter. Hardcoding this * saves us some overhead, both in runtime in code complexity. As - * it is doubtful if ever more than 2 parameters are needed, the + * it is doubtful if ever more than 3 parameters are needed, the * approach taken here is considered appropriate. * rgerhards, 2010-06-24 */ @@ -372,6 +372,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_INVLD_PROTOCOL = -2213, /**< invalid protocol specified in config file */ RS_RET_CNF_INVLD_FRAMING = -2214, /**< invalid framing specified in config file */ RS_RET_LEGA_ACT_NOT_SUPPORTED = -2215, /**< the module (no longer) supports legacy action syntax */ + RS_RET_MAX_OMSR_REACHED = -2216, /**< max nbr of string requests reached, not supported by core */ /* RainerScript error messages (range 1000.. 1999) */ RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */ -- cgit From d4c048af3e275e90683ae6c49f9c0b2aea9f2f03 Mon Sep 17 00:00:00 2001 From: "Steven A. Falco" Date: Fri, 13 Apr 2012 15:14:31 +0200 Subject: Add a system property, PROP_SYS_UPTIME, to place up-time markers into rsyslog output. Here is an example template, where this is used: $template CoincidentFileFormat,"[UP=%$uptime%sec] %TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" and here is an example line of output using the above template: [UP=20sec] Apr 12 21:50:00 atom kernel: imklog 5.8.7, log source = /proc/kmsg started. --- runtime/msg.c | 20 ++++++++++++++++++++ runtime/rsyslog.h | 1 + 2 files changed, 21 insertions(+) diff --git a/runtime/msg.c b/runtime/msg.c index a52d0cce..e1b3b0da 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #if HAVE_MALLOC_H @@ -568,6 +569,8 @@ rsRetVal propNameToID(cstr_t *pCSPropName, propid_t *pPropID) *pPropID = PROP_CEE; } else if(!strcmp((char*) pName, "$bom")) { *pPropID = PROP_SYS_BOM; + } else if(!strcmp((char*) pName, "$uptime")) { + *pPropID = PROP_SYS_UPTIME; } else { *pPropID = PROP_INVALID; iRet = RS_RET_VAR_NOT_FOUND; @@ -2548,6 +2551,23 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, pRes = (uchar*) "\xEF\xBB\xBF"; *pbMustBeFreed = 0; break; + case PROP_SYS_UPTIME: + { + struct sysinfo s_info; + + if((pRes = (uchar*) MALLOC(sizeof(uchar) * 32)) == NULL) { + RET_OUT_OF_MEMORY; + } + *pbMustBeFreed = 1; + + if(sysinfo(&s_info) < 0) { + *pPropLen = sizeof("**SYSCALL FAILED**") - 1; + return(UCHAR_CONSTANT("**SYSCALL FAILED**")); + } + + snprintf((char*) pRes, sizeof(uchar) * 32, "%ld", s_info.uptime); + } + break; default: /* there is no point in continuing, we may even otherwise render the * error message unreadable. rgerhards, 2007-07-10 diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 0922c1bb..baadf322 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -140,6 +140,7 @@ typedef uintTiny propid_t; #define PROP_CEE 200 #define PROP_CEE_ALL_JSON 201 #define PROP_SYS_BOM 159 +#define PROP_SYS_UPTIME 160 /* The error codes below are orginally "borrowed" from -- cgit From 838f34dd2bc201b2718e0f94f2e285b3ddb1cc17 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 13 Apr 2012 15:15:09 +0200 Subject: doc: added new $uptime property --- doc/property_replacer.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/property_replacer.html b/doc/property_replacer.html index 6456296a..f4c4238e 100644 --- a/doc/property_replacer.html +++ b/doc/property_replacer.html @@ -160,6 +160,10 @@ than messages generated somewhere. in templates for RFC5424 support, when the character set is know to be Unicode. +$uptime +system-uptime in seconds (as reported by operating system). + + $now The current date stamp in the format YYYY-MM-DD -- cgit From 55e0bf4a6d6f054b92facaff77d763ffabf1b4ac Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 16 Apr 2012 14:50:11 +0200 Subject: preparing for 6.3.8 release --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 35a7edc2..4b795656 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,5 @@ --------------------------------------------------------------------------- -Version 6.3.8 [DEVEL] 2012-02-?? +Version 6.3.8 [DEVEL] 2012-04-16 - added $PStatJSON directive to permit stats records in JSON format - added "date-unixtimestamp" property replacer option to format as a unix timestamp (seconds since epoch) -- cgit From 1acde66c3274c57d084146621d4124eaaef9ccf9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 16 Apr 2012 17:46:46 +0200 Subject: make "old" omelasticsearch compile this module is to be replaced by branch currently in development. But I want to be able to compile the previous one, at least ;) --- plugins/omelasticsearch/omelasticsearch.c | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/omelasticsearch/omelasticsearch.c b/plugins/omelasticsearch/omelasticsearch.c index 3bec1838..2b451eb4 100644 --- a/plugins/omelasticsearch/omelasticsearch.c +++ b/plugins/omelasticsearch/omelasticsearch.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit From 7a8b99ebe9a0aea956f44fbe6e584597445b6a7a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 16 Apr 2012 18:57:51 +0200 Subject: bugfix/imuxsock: solving abort if hostname was not set --- ChangeLog | 3 +++ plugins/imuxsock/imuxsock.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b795656..d9491ca6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,7 @@ --------------------------------------------------------------------------- +Version 6.3.9 [DEVEL] 2012-04-?? +- bugfix/imuxsock: solving abort if hostname was not set +--------------------------------------------------------------------------- Version 6.3.8 [DEVEL] 2012-04-16 - added $PStatJSON directive to permit stats records in JSON format - added "date-unixtimestamp" property replacer option to format as a diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index c97e6b28..1c8a05e5 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -377,13 +377,13 @@ addListner(instanceConf_t *inst) } else { listeners[nfd].bParseHost = 0; } - CHKiRet(prop.Construct(&(listeners[nfd].hostName))); if(inst->pLogHostName == NULL) { listeners[nfd].hostName = NULL; } else { + CHKiRet(prop.Construct(&(listeners[nfd].hostName))); CHKiRet(prop.SetString(listeners[nfd].hostName, inst->pLogHostName, ustrlen(inst->pLogHostName))); + CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); } - CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); if(inst->ratelimitInterval > 0) { if((listeners[nfd].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { /* in this case, we simply turn off rate-limiting */ -- cgit From fba7f66590c6c60c1c08585d210734884654c912 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 16 Apr 2012 19:05:11 +0200 Subject: bugfix/imuxsock: configured hostname was not used --- ChangeLog | 3 ++- plugins/imuxsock/imuxsock.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d9491ca6..28ab327a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ --------------------------------------------------------------------------- Version 6.3.9 [DEVEL] 2012-04-?? -- bugfix/imuxsock: solving abort if hostname was not set +- bugfix/imuxsock: solving abort if hostname was not set; configured + hostname was not used (both merge regressions) --------------------------------------------------------------------------- Version 6.3.8 [DEVEL] 2012-04-16 - added $PStatJSON directive to permit stats records in JSON format diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 1c8a05e5..2d26e652 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -331,6 +331,7 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal) CHKmalloc(inst = MALLOC(sizeof(instanceConf_t))); inst->sockName = pNewVal; inst->ratelimitInterval = cs.ratelimitInterval; + inst->pLogHostName = cs.pLogHostName; inst->ratelimitBurst = cs.ratelimitBurst; inst->ratelimitSeverity = cs.ratelimitSeverity; inst->bUseFlowCtl = cs.bUseFlowCtl; -- cgit From 68538a9013c59036d8825ef97a0a91552a9e7e99 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 18 Apr 2012 15:13:27 +0200 Subject: bugfix: assigned ruleset was lost when using disk queues This looked quite hard to diagnose for disk-assisted queues, as the pure memory part worked well, but ruleset info was lost for messages stored inside the disk queue. --- ChangeLog | 4 ++++ runtime/msg.c | 24 +++++++++++++++++++++--- runtime/ruleset.c | 10 +++++----- runtime/ruleset.h | 15 +++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8a0d8474..bdf714bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ --------------------------------------------------------------------------- Version 5.8.11 [V5-stable] 2012-04-?? +- bugfix: assigned ruleset was lost when using disk queues + This looked quite hard to diagnose for disk-assisted queues, as the + pure memory part worked well, but ruleset info was lost for messages + stored inside the disk queue. - bugfix: hostname was not requeried on HUP Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for his help in testing the fix. diff --git a/runtime/msg.c b/runtime/msg.c index 31863b2d..5eab751d 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -1057,6 +1057,12 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm) objSerializePTR(pStrm, pCSAPPNAME, CSTR); objSerializePTR(pStrm, pCSPROCID, CSTR); objSerializePTR(pStrm, pCSMSGID, CSTR); + + if(pThis->pRuleset != NULL) { + rulesetGetName(pThis->pRuleset)); + CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRuleset"), PROPTYPE_PSZ, + rulesetGetName(pThis->pRuleset))); + } /* offset must be serialized after pszRawMsg, because we need that to obtain the correct * MSG size. @@ -1663,6 +1669,16 @@ void MsgSetRuleset(msg_t *pMsg, ruleset_t *pRuleset) } +/* rgerhards 2012-04-18: set associated ruleset (by ruleset name) + * If ruleset cannot be found, no update is done. + */ +static void +MsgSetRulesetByName(msg_t *pMsg, cstr_t *rulesetName) +{ + rulesetGetRuleset(&(pMsg->pRuleset), rsCStrGetSzStrNoNULL(rulesetName)); +} + + /* set TAG in msg object * (rewritten 2009-06-18 rgerhards) */ @@ -1671,8 +1687,6 @@ void MsgSetTAG(msg_t *pMsg, uchar* pszBuf, size_t lenBuf) uchar *pBuf; assert(pMsg != NULL); -dbgprintf("MsgSetTAG in: len %d, pszBuf: %s\n", lenBuf, pszBuf); - freeTAG(pMsg); pMsg->iLenTAG = lenBuf; @@ -1692,7 +1706,6 @@ dbgprintf("MsgSetTAG in: len %d, pszBuf: %s\n", lenBuf, pszBuf); memcpy(pBuf, pszBuf, pMsg->iLenTAG); pBuf[pMsg->iLenTAG] = '\0'; /* this also works with truncation! */ -dbgprintf("MsgSetTAG exit: pMsg->iLenTAG %d, pMsg->TAG.szBuf: %s\n", pMsg->iLenTAG, pMsg->TAG.szBuf); } @@ -3200,8 +3213,13 @@ rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp) memcpy(&pThis->tRcvdAt, &pProp->val.vSyslogTime, sizeof(struct syslogTime)); } else if(isProp("tTIMESTAMP")) { memcpy(&pThis->tTIMESTAMP, &pProp->val.vSyslogTime, sizeof(struct syslogTime)); + } else if(isProp("pszRuleset")) { + MsgSetRulesetByName(pThis, pProp->val.pStr); } else if(isProp("pszMSG")) { dbgprintf("no longer supported property pszMSG silently ignored\n"); + } else { + dbgprintf("unknown supported property '%s' silently ignored\n", + rsCStrGetSzStrNoNULL(pProp->pcsName)); } finalize_it: diff --git a/runtime/ruleset.c b/runtime/ruleset.c index 5ee2a55a..8e241c8a 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -315,8 +315,8 @@ GetRulesetQueue(ruleset_t *pThis) /* Find the ruleset with the given name and return a pointer to its object. */ -static rsRetVal -GetRuleset(ruleset_t **ppRuleset, uchar *pszName) +rsRetVal +rulesetGetRuleset(ruleset_t **ppRuleset, uchar *pszName) { DEFiRet; assert(ppRuleset != NULL); @@ -338,7 +338,7 @@ SetDefaultRuleset(uchar *pszName) DEFiRet; assert(pszName != NULL); - CHKiRet(GetRuleset(&pRuleset, pszName)); + CHKiRet(rulesetGetRuleset(&pRuleset, pszName)); pDfltRuleset = pRuleset; dbgprintf("default rule set changed to %p: '%s'\n", pRuleset, pszName); @@ -356,7 +356,7 @@ SetCurrRuleset(uchar *pszName) DEFiRet; assert(pszName != NULL); - CHKiRet(GetRuleset(&pRuleset, pszName)); + CHKiRet(rulesetGetRuleset(&pRuleset, pszName)); pCurrRuleset = pRuleset; dbgprintf("current rule set changed to %p: '%s'\n", pRuleset, pszName); @@ -591,7 +591,7 @@ CODESTARTobjQueryInterface(ruleset) pIf->SetName = setName; pIf->DebugPrintAll = debugPrintAll; pIf->GetCurrent = GetCurrent; - pIf->GetRuleset = GetRuleset; + pIf->GetRuleset = rulesetGetRuleset; pIf->SetDefaultRuleset = SetDefaultRuleset; pIf->SetCurrRuleset = SetCurrRuleset; pIf->GetRulesetQueue = GetRulesetQueue; diff --git a/runtime/ruleset.h b/runtime/ruleset.h index b055a71d..52e633eb 100644 --- a/runtime/ruleset.h +++ b/runtime/ruleset.h @@ -54,6 +54,7 @@ BEGINinterface(ruleset) /* name must also be changed in ENDinterface macro! */ qqueue_t* (*GetRulesetQueue)(ruleset_t*); /* v3, 2009-11-04 */ parserList_t* (*GetParserList)(msg_t *); + /* v4 */ ENDinterface(ruleset) #define rulesetCURR_IF_VERSION 4 /* increment whenever you change the interface structure! */ @@ -61,4 +62,18 @@ ENDinterface(ruleset) /* prototypes */ PROTOTYPEObj(ruleset); + +/* Get name associated to ruleset. This function cannot fail (except, + * of course, if previously something went really wrong). Returned + * pointer is read-only. + * rgerhards, 2012-04-18 + */ +static inline uchar* +rulesetGetName(ruleset_t *pRuleset) +{ + return pRuleset->pszName; +} + + +rsRetVal rulesetGetRuleset(ruleset_t **ppRuleset, uchar *pszName); #endif /* #ifndef INCLUDED_RULESET_H */ -- cgit From 7cb5f0cb8c98408bc46f2c07d8480b70d816de7a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 18 Apr 2012 16:21:15 +0200 Subject: fixed compile bug actually a regression from last bugfix - I just wonder why the other machine did not complain :-S --- runtime/msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/msg.c b/runtime/msg.c index 5eab751d..7b94228c 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -1059,7 +1059,7 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm) objSerializePTR(pStrm, pCSMSGID, CSTR); if(pThis->pRuleset != NULL) { - rulesetGetName(pThis->pRuleset)); + rulesetGetName(pThis->pRuleset); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRuleset"), PROPTYPE_PSZ, rulesetGetName(pThis->pRuleset))); } -- cgit From 7f0cd8c8b93ca395949e5d28c3a8f422e6695c8d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Apr 2012 15:20:16 +0200 Subject: added the "jsonf" property replacer option (and fieldname) & bugfix bugfix: property replacer option "json" could lead to content loss message was truncated if escaping was necessary --- ChangeLog | 3 ++ doc/property_replacer.html | 30 +++++++++-- runtime/msg.c | 130 ++++++++++++++++++++++++++++++++------------- template.c | 73 ++++++++++++++++++------- template.h | 4 +- 5 files changed, 181 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 732bb8bb..1532c9db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ --------------------------------------------------------------------------- Version 6.3.9 [DEVEL] 2012-04-?? +- added the "jsonf" property replacer option (and fieldname) +- bugfix: property replacer option "json" could lead to content loss + message was truncated if escaping was necessary - bugfix: assigned ruleset was lost when using disk queues This looked quite hard to diagnose for disk-assisted queues, as the pure memory part worked well, but ruleset info was lost for messages diff --git a/doc/property_replacer.html b/doc/property_replacer.html index 1178b4ca..5ee1d096 100644 --- a/doc/property_replacer.html +++ b/doc/property_replacer.html @@ -13,7 +13,7 @@ the value, e.g. by converting all characters to lower case.

      Syslog message properties are used inside templates. They are accessed by putting them between percent signs. Properties can be modified by the property replacer. The full syntax is as follows:

      -
      %propname:fromChar:toChar:options%
      +
      %propname:fromChar:toChar:options:fieldname%

      Available Properties

      propname is the name of the property to access. It is case-insensitive (prior to 3.17.0, they were case-senstive). @@ -349,7 +349,24 @@ case-insensitive. Currently, the following options are defined: json encode the value so that it can be used inside a JSON field. This means that several characters (according to the JSON spec) are being escaped, for -example US-ASCII LF is replaced by "\n". +example US-ASCII LF is replaced by "\n". +The json option cannot be used together with either jsonf or csv options. + + + +jsonf +(available in 6.3.9+) +This signifies that the property should be expressed as a json field. +That means not only the property is written, but rather a complete json field in +the format
      +"fieldname"="value"
      +where "filedname" is the assigend field name (or the property name if none was assigned) +and value is the end result of property replacer operation. Note that value supports +all property replacer options, like substrings, case converson and the like. +Values are properly json-escaped. However, field names are (currently) not. It is +expected that proper field names are configured. +The jsonf option cannot be used together with either json or csv options. + csv @@ -360,6 +377,7 @@ text, you need to define a proper template. An example is this one:
      $template csvline,"%syslogtag:::csv%,%msg:::csv%"
      Most importantly, you need to provide the commas between the fields inside the template. +The csv option cannot be used together with either json or jsonf options.
      This feature was introduced in rsyslog 4.1.6. @@ -465,13 +483,19 @@ Useful for secure pathname generation (with dynafiles). them. For example "escape-cc,sp-if-no-1st-sp". If you use conflicting options together, the last one will override the previous one. For example, using "escape-cc,drop-cc" will use drop-cc and "drop-cc,escape-cc" will use escape-cc mode. +

      Fieldname

      +

      (available in 6.3.9+) +

      This field permits to specify a field name for structured-data emitting property replacer +options. It was initially introduced to support the "jsonf" option, for which it provides +the capability to set an alternative field name. If it is not specified, it defaults to +the property name.

      Further Links

      [manual index] [rsyslog.conf] diff --git a/runtime/msg.c b/runtime/msg.c index 1cc5f6b4..9c7a2203 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -263,6 +263,9 @@ static struct { { UCHAR_CONSTANT("190"), 5}, { UCHAR_CONSTANT("191"), 5} }; +static char hexdigit[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /*syslog facility names (as of RFC5424) */ static char *syslog_fac_names[24] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", @@ -423,7 +426,6 @@ resolveDNS(msg_t *pMsg) { uchar fromHostFQDN[NI_MAXHOST]; DEFiRet; -dbgprintf("XXXX: in msg/resolveDNS (dnscache)\n"); MsgLock(pMsg); CHKiRet(objUse(net, CORE_COMPONENT)); if(pMsg->msgFlags & NEEDS_DNSRESOL) { @@ -2371,81 +2373,67 @@ finalize_it: } -/* encode a property in JSON escaped format. This is a helper - * to MsgGetProp. It needs to update all provided parameters. - * Note: Code is borrowed from libee (my own code, so ASL 2.0 - * is fine with it); this function may later be replaced by - * some "better" and more complete implementation (maybe from - * libee or its helpers). - * For performance reasons, we begin to copy the string only - * when we recognice that we actually need to do some escaping. - * rgerhards, 2012-03-16 +/* Encode a JSON value and add it to provided string. Note that + * the string object may be NULL. In this case, it is created + * if and only if escaping is needed. */ static rsRetVal -jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) +jsonAddVal(uchar *pSrc, unsigned buflen, es_str_t **dst) { - static char hexdigit[16] = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', - '9', 'A', 'B', 'C', 'D', 'E', 'F' }; unsigned char c; es_size_t i; char numbuf[4]; int j; - unsigned buflen; - uchar *pSrc; - es_str_t *dst = NULL; DEFiRet; - pSrc = *ppRes; - buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen; for(i = 0 ; i < buflen ; ++i) { c = pSrc[i]; if( (c >= 0x23 && c <= 0x5b) || (c >= 0x5d /* && c <= 0x10FFFF*/) || c == 0x20 || c == 0x21) { /* no need to escape */ - if(dst != NULL) - es_addChar(&dst, c); + if(*dst != NULL) + es_addChar(dst, c); } else { - if(dst == NULL) { + if(*dst == NULL) { if(i == 0) { /* we hope we have only few escapes... */ - dst = es_newStr(buflen+10); + *dst = es_newStr(buflen+10); } else { - dst = es_newStrFromBuf((char*)pSrc, i-1); + *dst = es_newStrFromBuf((char*)pSrc, i-1); } - if(dst == NULL) { + if(*dst == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } } /* we must escape, try RFC4627-defined special sequences first */ switch(c) { case '\0': - es_addBuf(&dst, "\\u0000", 6); + es_addBuf(dst, "\\u0000", 6); break; case '\"': - es_addBuf(&dst, "\\\"", 2); + es_addBuf(dst, "\\\"", 2); break; case '/': - es_addBuf(&dst, "\\/", 2); + es_addBuf(dst, "\\/", 2); break; case '\\': - es_addBuf(&dst, "\\\\", 2); + es_addBuf(dst, "\\\\", 2); break; case '\010': - es_addBuf(&dst, "\\b", 2); + es_addBuf(dst, "\\b", 2); break; case '\014': - es_addBuf(&dst, "\\f", 2); + es_addBuf(dst, "\\f", 2); break; case '\n': - es_addBuf(&dst, "\\n", 2); + es_addBuf(dst, "\\n", 2); break; case '\r': - es_addBuf(&dst, "\\r", 2); + es_addBuf(dst, "\\r", 2); break; case '\t': - es_addBuf(&dst, "\\t", 2); + es_addBuf(dst, "\\t", 2); break; default: /* TODO : proper Unicode encoding (see header comment) */ @@ -2453,12 +2441,38 @@ jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) numbuf[3-j] = hexdigit[c % 16]; c = c / 16; } - es_addBuf(&dst, "\\u", 2); - es_addBuf(&dst, numbuf, 4); + es_addBuf(dst, "\\u", 2); + es_addBuf(dst, numbuf, 4); break; } } } +finalize_it: + RETiRet; +} + + +/* encode a property in JSON escaped format. This is a helper + * to MsgGetProp. It needs to update all provided parameters. + * Note: Code is borrowed from libee (my own code, so ASL 2.0 + * is fine with it); this function may later be replaced by + * some "better" and more complete implementation (maybe from + * libee or its helpers). + * For performance reasons, we begin to copy the string only + * when we recognice that we actually need to do some escaping. + * rgerhards, 2012-03-16 + */ +static rsRetVal +jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) +{ + unsigned buflen; + uchar *pSrc; + es_str_t *dst = NULL; + DEFiRet; + + pSrc = *ppRes; + buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen; + CHKiRet(jsonAddVal(pSrc, buflen, &dst)); if(dst != NULL) { /* we updated the string and need to replace the @@ -2468,6 +2482,7 @@ jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) free(*ppRes); *ppRes = (uchar*)es_str2cstr(dst, NULL); *pbMustBeFreed = 1; + *pBufLen = -1; es_deleteStr(dst); } @@ -2476,6 +2491,46 @@ finalize_it: } +/* Format a property as JSON field, that means + * "name"="value" + * where value is JSON-escaped (here we assume that the name + * only contains characters from the valid character set). + * Note: this function duplicates code from jsonEncode(). + * TODO: these two functions should be combined, at least if + * that makes any sense from a performance PoV - definitely + * something to consider at a later stage. rgerhards, 2012-04-19 + */ +static rsRetVal +jsonField(struct templateEntry *pTpe, uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) +{ + unsigned buflen; + uchar *pSrc; + es_str_t *dst = NULL; + DEFiRet; + + pSrc = *ppRes; + buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen; + /* we hope we have only few escapes... */ + dst = es_newStr(buflen+es_strlen(pTpe->data.field.fieldName)+15); + es_addChar(&dst, '"'); + es_addStr(&dst, pTpe->data.field.fieldName); + es_addBufConstcstr(&dst, "\"=\""); + CHKiRet(jsonAddVal(pSrc, buflen, &dst)); + es_addChar(&dst, '"'); + + if(*pbMustBeFreed) + free(*ppRes); + /* we know we do not have \0 chars - so the size does not change */ + *pBufLen = es_strlen(dst); + *ppRes = (uchar*)es_str2cstr(dst, NULL); + *pbMustBeFreed = 1; + es_deleteStr(dst); + +finalize_it: + RETiRet; +} + + /* This function returns a string-representation of the * requested message property. This is a generic function used * to abstract properties so that these can be easier @@ -3301,6 +3356,8 @@ dbgprintf("prop repl 4, pRes='%s', len %d\n", pRes, bufLen); *pbMustBeFreed = 1; } else if(pTpe->data.field.options.bJSON) { jsonEncode(&pRes, pbMustBeFreed, &bufLen); + } else if(pTpe->data.field.options.bJSONf) { + jsonField(pTpe, &pRes, pbMustBeFreed, &bufLen); } if(bufLen == -1) @@ -3369,7 +3426,6 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) propNameStrToID(name, &propid); pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed); -dbgprintf("ZZZZ: var %s returns '%s'\n", name, pszProp); estr = es_newStrFromCStr((char*)pszProp, propLen); if(bMustBeFreed) free(pszProp); diff --git a/template.c b/template.c index 2326819c..c6878459 100644 --- a/template.c +++ b/template.c @@ -493,18 +493,18 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe) p = *pp; - while(*p && *p != '%') { + while(*p && *p != '%' && *p != ':') { /* outer loop - until end of options */ i = 0; while((i < sizeof(Buf) / sizeof(char)) && - *p && *p != '%' && *p != ',') { + *p && *p != '%' && *p != ':' && *p != ',') { /* inner loop - until end of ONE option */ Buf[i++] = tolower((int)*p); ++p; } Buf[i] = '\0'; /* terminate */ /* check if we need to skip oversize option */ - while(*p && *p != '%' && *p != ',') + while(*p && *p != '%' && *p != ':' && *p != ',') ++p; /* just skip */ if(*p == ',') ++p; /* eat ',' */ @@ -544,19 +544,26 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe) } else if(!strcmp((char*)Buf, "secpath-replace")) { pTpe->data.field.options.bSecPathReplace = 1; } else if(!strcmp((char*)Buf, "csv")) { - if(pTpe->data.field.options.bJSON) { - errmsg.LogError(0, NO_ERRCODE, "error: can not specify " - "both csv and json options - csv ignored"); + if(pTpe->data.field.options.bJSON || pTpe->data.field.options.bJSONf) { + errmsg.LogError(0, NO_ERRCODE, "error: can only specify " + "one option out of (json, jsonf, csv) - csv ignored"); } else { pTpe->data.field.options.bCSV = 1; } } else if(!strcmp((char*)Buf, "json")) { - if(pTpe->data.field.options.bCSV) { - errmsg.LogError(0, NO_ERRCODE, "error: can not specify " - "both csv and json options - json ignored"); + if(pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON) { + errmsg.LogError(0, NO_ERRCODE, "error: can only specify " + "one option out of (json, jsonf, csv) - json ignored"); } else { pTpe->data.field.options.bJSON = 1; } + } else if(!strcmp((char*)Buf, "jsonf")) { + if(pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON) { + errmsg.LogError(0, NO_ERRCODE, "error: can only specify " + "one option out of (json, jsonf, csv) - jsonf ignored"); + } else { + pTpe->data.field.options.bJSONf = 1; + } } else { dbgprintf("Invalid field option '%s' specified - ignored.\n", Buf); } @@ -573,7 +580,8 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe) static int do_Parameter(unsigned char **pp, struct template *pTpl) { unsigned char *p; - cstr_t *pStrB; + cstr_t *pStrProp; + cstr_t *pStrField = NULL; struct templateEntry *pTpe; int iNum; /* to compute numbers */ #ifdef FEATURE_REGEXP @@ -590,7 +598,7 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl) p = (unsigned char*) *pp; - if(cstrConstruct(&pStrB) != RS_RET_OK) + if(cstrConstruct(&pStrProp) != RS_RET_OK) return 1; if((pTpe = tpeConstruct(pTpl)) == NULL) { @@ -601,25 +609,24 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl) pTpe->eEntryType = FIELD; while(*p && *p != '%' && *p != ':') { - cstrAppendChar(pStrB, tolower(*p)); + cstrAppendChar(pStrProp, tolower(*p)); ++p; /* do NOT do this in tolower()! */ } /* got the name */ - cstrFinalize(pStrB); + cstrFinalize(pStrProp); - if(propNameToID(pStrB, &pTpe->data.field.propid) != RS_RET_OK) { - cstrDestruct(&pStrB); + if(propNameToID(pStrProp, &pTpe->data.field.propid) != RS_RET_OK) { + cstrDestruct(&pStrProp); return 1; } if(pTpe->data.field.propid == PROP_CEE) { /* in CEE case, we need to preserve the actual property name */ - if((pTpe->data.field.propName = es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrB)+2, cstrLen(pStrB)-2)) == NULL) { - cstrDestruct(&pStrB); + if((pTpe->data.field.propName = es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrProp)+2, cstrLen(pStrProp)-2)) == NULL) { + cstrDestruct(&pStrProp); return 1; } } - cstrDestruct(&pStrB); /* Check frompos, if it has an R, then topos should be a regex */ if(*p == ':') { @@ -873,6 +880,34 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl) doOptions(&p, pTpe); } + /* check field name */ + if(*p == ':') { + ++p; /* eat ':' */ + if(cstrConstruct(&pStrField) != RS_RET_OK) + return 1; + while(*p != ':' && *p != '%' && *p != '\0') { + cstrAppendChar(pStrField, *p); + ++p; + } + cstrFinalize(pStrField); + } + + /* save field name - if none was given, use the property name instead */ + if(pStrField == NULL) { + if((pTpe->data.field.fieldName = + es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrProp), cstrLen(pStrProp))) == NULL) { + return 1; + } + } else { + if((pTpe->data.field.fieldName = + es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrField), cstrLen(pStrField))) == NULL) { + return 1; + } + cstrDestruct(&pStrField); + } + + cstrDestruct(&pStrProp); + if(*p) ++p; /* eat '%' */ *pp = p; @@ -1130,6 +1165,8 @@ void tplDeleteAll(rsconf_t *conf) } if(pTpeDel->data.field.propName != NULL) es_deleteStr(pTpeDel->data.field.propName); + if(pTpeDel->data.field.fieldName != NULL) + es_deleteStr(pTpeDel->data.field.fieldName); #endif break; } diff --git a/template.h b/template.h index a9eff6b1..f55f64b3 100644 --- a/template.h +++ b/template.h @@ -91,6 +91,7 @@ struct templateEntry { int field_expand; /* use multiple instances of the field delimiter as a single one? */ es_str_t *propName; /**< property name (currently being used for CEE only) */ + es_str_t *fieldName; /**< field name to be used for structured output */ enum tplFormatTypes eDateFormat; enum tplFormatCaseConvTypes eCaseConv; @@ -101,9 +102,10 @@ struct templateEntry { unsigned bDropLastLF: 1; /* drop last LF char in msg (PIX!) */ unsigned bSecPathDrop: 1; /* drop slashes, replace dots, empty string */ unsigned bSecPathReplace: 1; /* replace slashes, replace dots, empty string */ - unsigned bSPIffNo1stSP: 1; /* replace slashes, replace dots, empty string */ + unsigned bSPIffNo1stSP: 1; /* be a space if 1st pos if field is no space*/ unsigned bCSV: 1; /* format field in CSV (RFC 4180) format */ unsigned bJSON: 1; /* format field JSON escaped */ + unsigned bJSONf: 1; /* format field JSON *field* (n/v pair) */ } options; /* options as bit fields */ } field; } data; -- cgit From 72dbce1a9454a1efcbb1e729d81c1e94681ede4f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Apr 2012 17:54:52 +0200 Subject: bugfix: imptcp input name could not be set config directive was accepted, but had no effect --- plugins/imptcp/imptcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 3973041b..477d25e1 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -918,14 +918,14 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa pSrv->bEmitMsgOnClose = cs.bEmitMsgOnClose; pSrv->port = pNewVal; pSrv->iAddtlFrameDelim = cs.iAddtlFrameDelim; - cs.pszInputName = NULL; /* moved over to pSrv, we do not own */ pSrv->lstnIP = cs.lstnIP; - cs.lstnIP = NULL; /* moved over to pSrv, we do not own */ pSrv->pRuleset = cs.pRuleset; pSrv->pszInputName = (cs.pszInputName == NULL) ? UCHAR_CONSTANT("imptcp") : cs.pszInputName; CHKiRet(prop.Construct(&pSrv->pInputName)); CHKiRet(prop.SetString(pSrv->pInputName, pSrv->pszInputName, ustrlen(pSrv->pszInputName))); CHKiRet(prop.ConstructFinalize(pSrv->pInputName)); + cs.pszInputName = NULL; /* moved over to pSrv, we do not own */ + cs.lstnIP = NULL; /* moved over to pSrv, we do not own */ /* add to linked list */ pSrv->pNext = pSrvRoot; -- cgit From 8eca897124f1d3116fd00291bbbc80aee9f7ae5a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Apr 2012 17:55:19 +0200 Subject: doc: add last bugfix to changelog and bump up version --- ChangeLog | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 95e22671..602b13dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +- bugfix: imptcp input name could not be set + config directive was accepted, but had no effect - added configuration directive to disable octet-counted framing for imtcp, directive is $InputTCPServerSupportOctetCountedFraming for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming diff --git a/configure.ac b/configure.ac index b626da66..6ad79bcc 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.9-newstats12],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.9-newstats13],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -- cgit From 42eb952e08fda74035f79d86bad9abf9bb535420 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Apr 2012 15:54:52 +0200 Subject: bugfix: imptcp input name could not be set bugfix: imptcp input name could not be set config directive was accepted, but had no effect --- plugins/imptcp/imptcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 65fe703c..91bdf8b3 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -885,14 +885,14 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa pSrv->bEmitMsgOnClose = cs.bEmitMsgOnClose; pSrv->port = pNewVal; pSrv->iAddtlFrameDelim = cs.iAddtlFrameDelim; - cs.pszInputName = NULL; /* moved over to pSrv, we do not own */ pSrv->lstnIP = cs.lstnIP; - cs.lstnIP = NULL; /* moved over to pSrv, we do not own */ pSrv->pRuleset = cs.pRuleset; pSrv->pszInputName = (cs.pszInputName == NULL) ? UCHAR_CONSTANT("imptcp") : cs.pszInputName; CHKiRet(prop.Construct(&pSrv->pInputName)); CHKiRet(prop.SetString(pSrv->pInputName, pSrv->pszInputName, ustrlen(pSrv->pszInputName))); CHKiRet(prop.ConstructFinalize(pSrv->pInputName)); + cs.pszInputName = NULL; /* moved over to pSrv, we do not own */ + cs.lstnIP = NULL; /* moved over to pSrv, we do not own */ /* add to linked list */ pSrv->pNext = pSrvRoot; -- cgit From 6d0250b75fe35e8c20d4a8b4155065c8244b0439 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 19 Apr 2012 18:02:44 +0200 Subject: doc: added last bugfix to ChangeLog --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index bdf714bf..07f746a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ --------------------------------------------------------------------------- Version 5.8.11 [V5-stable] 2012-04-?? +- bugfix: imptcp input name could not be set + config directive was accepted, but had no effect - bugfix: assigned ruleset was lost when using disk queues This looked quite hard to diagnose for disk-assisted queues, as the pure memory part worked well, but ruleset info was lost for messages -- cgit