summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/im3195/im3195.c35
-rw-r--r--plugins/imdiag/imdiag.c32
-rw-r--r--plugins/imfile/imfile.c8
-rw-r--r--plugins/imgssapi/imgssapi.c32
-rw-r--r--plugins/imklog/bsd.c22
-rw-r--r--plugins/imklog/imklog.c198
-rw-r--r--plugins/imklog/imklog.h26
-rw-r--r--plugins/immark/immark.c66
-rw-r--r--plugins/impstats/impstats.c75
-rw-r--r--plugins/imptcp/imptcp.c495
-rw-r--r--plugins/imrelp/imrelp.c195
-rw-r--r--plugins/imsolaris/imsolaris.c30
-rw-r--r--plugins/imtcp/imtcp.c293
-rw-r--r--plugins/imtemplate/Makefile.am6
-rw-r--r--plugins/imtemplate/imtemplate.c436
-rw-r--r--plugins/imttcp/Makefile.am6
-rw-r--r--plugins/imttcp/imttcp.c1151
-rw-r--r--plugins/imudp/imudp.c521
-rw-r--r--plugins/imuxsock/imuxsock.c451
-rw-r--r--plugins/mmnormalize/Makefile.am8
-rw-r--r--plugins/mmnormalize/mmnormalize.c274
-rw-r--r--plugins/mmsnmptrapd/mmsnmptrapd.c10
-rw-r--r--plugins/omdbalerting/omdbalerting.c1
-rw-r--r--plugins/omgssapi/omgssapi.c72
-rw-r--r--plugins/omhdfs/omhdfs.c52
-rw-r--r--plugins/omlibdbi/omlibdbi.c110
-rw-r--r--plugins/ommail/ommail.c90
-rw-r--r--plugins/ommongodb/Makefile.am11
-rw-r--r--plugins/ommongodb/README23
-rw-r--r--plugins/ommongodb/ommongodb.c281
-rw-r--r--plugins/ommysql/ommysql.c49
-rw-r--r--plugins/omoracle/omoracle.c1
-rw-r--r--plugins/ompgsql/ompgsql.c11
-rw-r--r--plugins/omprog/omprog.c31
-rw-r--r--plugins/omrelp/omrelp.c11
-rw-r--r--plugins/omruleset/omruleset.c37
-rw-r--r--plugins/omsnmp/omsnmp.c178
-rw-r--r--plugins/omstdout/omstdout.c31
-rw-r--r--plugins/omtemplate/Makefile.am8
-rw-r--r--plugins/omtemplate/omtemplate.c221
-rw-r--r--plugins/omtesting/omtesting.c17
-rw-r--r--plugins/omudpspoof/omudpspoof.c85
-rw-r--r--plugins/omuxsock/omuxsock.c38
-rw-r--r--plugins/pmaixforwardedfrom/pmaixforwardedfrom.c1
-rw-r--r--plugins/pmcisconames/pmcisconames.c1
-rw-r--r--plugins/pmlastmsg/pmlastmsg.c1
-rw-r--r--plugins/pmrfc3164sd/pmrfc3164sd.c1
-rw-r--r--plugins/pmsnare/pmsnare.c1
-rw-r--r--plugins/sm_cust_bindcdr/sm_cust_bindcdr.c1
49 files changed, 4075 insertions, 1659 deletions
diff --git a/plugins/im3195/im3195.c b/plugins/im3195/im3195.c
index 28ca8856..c75e0e34 100644
--- a/plugins/im3195/im3195.c
+++ b/plugins/im3195/im3195.c
@@ -51,12 +51,18 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("im3195")
/* Module static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
/* configuration settings */
+
+struct modConfData_s {
+ EMPTY_STRUCT;
+};
+
static int listenPort = 601;
/* we use a global API object below, because this listener is
@@ -84,10 +90,37 @@ void OnReceive(srAPIObj __attribute__((unused)) *pMyAPI, srSLMGObj* pSLMG)
srSLMGGetRawMSG(pSLMG, &pszRawMsg);
parseAndSubmitMessage(fromHost, fromHostIP, pszRawMsg, strlen((char*)pszRawMsg),
- PARSE_HOSTNAME, eFLOWCTL_FULL_DELAY, (uchar*)"im3195", NULL, 0);
+ PARSE_HOSTNAME, eFLOWCTL_FULL_DELAY, (uchar*)"im3195", NULL, 0, NULL);
}
+#if 0
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+#endif
+
+
BEGINrunInput
CODESTARTrunInput
/* this is an endless loop - it is terminated when the thread is
diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c
index b3468921..48573853 100644
--- a/plugins/imdiag/imdiag.c
+++ b/plugins/imdiag/imdiag.c
@@ -57,6 +57,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imdiag")
/* static data */
DEF_IMOD_STATIC_DATA
@@ -77,6 +78,10 @@ static prop_t *pRcvIPDummy = NULL;
/* config settings */
+struct modConfData_s {
+ EMPTY_STRUCT;
+};
+
static int iTCPSessMax = 20; /* max number of sessions */
static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */
@@ -387,6 +392,33 @@ finalize_it:
RETiRet;
}
+
+#if 0 /* can be used to integrate into new config system */
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+#endif
+
/* This function is called to gather input.
*/
BEGINrunInput
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
index 632bf390..440f5991 100644
--- a/plugins/imfile/imfile.c
+++ b/plugins/imfile/imfile.c
@@ -51,6 +51,7 @@
MODULE_TYPE_INPUT /* must be present for input modules, do not remove */
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imfile")
/* defines */
@@ -85,6 +86,10 @@ typedef struct fileInfo_s {
static rsRetVal persistStrmState(fileInfo_t *pInfo);
/* config variables */
+struct modConfData_s {
+ EMPTY_STRUCT;
+};
+
static uchar *pszFileName = NULL;
static uchar *pszFileTag = NULL;
static uchar *pszStateFile = NULL;
@@ -335,6 +340,7 @@ ENDrunInput
* ------------------------------------------------------------------------------------------ */
+
/* The function is called by rsyslog before runInput() is called. It is a last chance
* to set up anything specific. Most importantly, it can be used to tell rsyslog if the
* input shall run or not. The idea is that if some config settings (or similiar things)
@@ -561,7 +567,7 @@ setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
rsRetVal localRet;
DEFiRet;
- localRet = ruleset.GetRuleset(&pRuleset, pszName);
+ localRet = ruleset.GetRuleset(ourConf, &pRuleset, pszName);
if(localRet == RS_RET_NOT_FOUND) {
errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName);
}
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index 446795d6..9668d1ac 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -63,6 +63,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imgssapi")
/* defines */
#define ALLOWEDMETHOD_GSS 2
@@ -104,6 +105,10 @@ typedef struct gss_sess_s {
/* config variables */
+struct modConfData_s {
+ EMPTY_STRUCT;
+};
+
static int iTCPSessMax = 200; /* max number of sessions */
static char *gss_listen_service_name = NULL;
static int bPermitPlainTcp = 0; /* plain tcp syslog allowed on GSSAPI port? */
@@ -640,6 +645,33 @@ TCPSessGSSDeinit(void)
RETiRet;
}
+
+#if 0 /* can be used to integrate into new config system */
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+#endif
+
/* This function is called to gather input.
*/
BEGINrunInput
diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c
index eaf8e5ca..80ff9494 100644
--- a/plugins/imklog/bsd.c
+++ b/plugins/imklog/bsd.c
@@ -151,37 +151,37 @@ submitSyslog(int pri, uchar *buf)
#endif /* #ifdef LINUX */
-static uchar *GetPath(void)
+static uchar *GetPath(modConfData_t *pModConf)
{
- return pszPath ? pszPath : (uchar*) _PATH_KLOG;
+ return pModConf->pszPath ? pModConf->pszPath : (uchar*) _PATH_KLOG;
}
/* open the kernel log - will be called inside the willRun() imklog
* entry point. -- rgerhards, 2008-04-09
*/
rsRetVal
-klogWillRun(void)
+klogWillRun(modConfData_t *pModConf)
{
char errmsg[2048];
int r;
DEFiRet;
- fklog = open((char*)GetPath(), O_RDONLY, 0);
+ fklog = open((char*)GetPath(pModConf), O_RDONLY, 0);
if (fklog < 0) {
imklogLogIntMsg(RS_RET_ERR_OPEN_KLOG, "imklog: cannot open kernel log(%s): %s.",
- GetPath(), rs_strerror_r(errno, errmsg, sizeof(errmsg)));
+ GetPath(pModConf), rs_strerror_r(errno, errmsg, sizeof(errmsg)));
ABORT_FINALIZE(RS_RET_ERR_OPEN_KLOG);
}
# ifdef OS_LINUX
/* Set level of kernel console messaging.. */
- if(console_log_level != -1) {
- r = klogctl(8, NULL, console_log_level);
+ if(pModConf->console_log_level != -1) {
+ r = klogctl(8, NULL, pModConf->console_log_level);
if(r != 0) {
imklogLogIntMsg(LOG_WARNING, "imklog: cannot set console log level: %s",
rs_strerror_r(errno, errmsg, sizeof(errmsg)));
/* make sure we do not try to re-set! */
- console_log_level = -1;
+ pModConf->console_log_level = -1;
}
}
# endif /* #ifdef OS_LINUX */
@@ -257,14 +257,14 @@ readklog(void)
/* to be called in the module's AfterRun entry point
* rgerhards, 2008-04-09
*/
-rsRetVal klogAfterRun(void)
+rsRetVal klogAfterRun(modConfData_t *pModConf)
{
DEFiRet;
if(fklog != -1)
close(fklog);
# ifdef OS_LINUX
/* Turn on logging of messages to console, but only if a log level was speficied */
- if(console_log_level != -1)
+ if(pModConf->console_log_level != -1)
klogctl(7, NULL, 0);
# endif
RETiRet;
@@ -276,7 +276,7 @@ rsRetVal klogAfterRun(void)
* "message pull" mechanism.
* rgerhards, 2008-04-09
*/
-rsRetVal klogLogKMsg(void)
+rsRetVal klogLogKMsg(modConfData_t __attribute__((unused)) *pModConf)
{
DEFiRet;
readklog();
diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c
index 40249273..b52b67af 100644
--- a/plugins/imklog/imklog.c
+++ b/plugins/imklog/imklog.c
@@ -62,6 +62,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imklog")
/* Module static data */
DEF_IMOD_STATIC_DATA
@@ -69,27 +70,43 @@ DEFobjCurrIf(datetime)
DEFobjCurrIf(glbl)
DEFobjCurrIf(prop)
-/* configuration settings */
-int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */
-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 */
-int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */
-uchar *pszPath = NULL;
-int console_log_level = -1;
-/* TODO: configuration for the following directives must be implemented. It
- * was not done yet because we either do not yet have a config handler for
- * that type or I thought it was acceptable to push it to a later stage when
- * I gained more handson experience with the input module interface (and the
- * changes resulting from that). -- rgerhards, 2007-12-20
- */
-char *symfile = NULL;
+/* config settings */
+typedef struct configSettings_s {
+ int dbgPrintSymbols; /* this one is extern so the helpers can access it! */
+ int symbols_twice;
+ int use_syscall;
+ int symbol_lookup; /* on recent kernels > 2.6, the kernel does this */
+ int bPermitNonKernel; /* permit logging of messages not having LOG_KERN facility */
+ int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */
+ uchar *pszPath;
+ int console_log_level;
+ char *symfile; /* TODO: actually unsued currently! */
+} configSettings_t;
+static configSettings_t cs;
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this module */
static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 */
+
+static inline void
+initConfigSettings(void)
+{
+ cs.dbgPrintSymbols = 0;
+ cs.symbols_twice = 0;
+ cs.use_syscall = 0;
+ cs.symbol_lookup = 0;
+ cs.bPermitNonKernel = 0;
+ cs.console_log_level = -1;
+ cs.pszPath = NULL;
+ cs.symfile = NULL;
+ cs.iFacilIntMsg = klogFacilIntMsg();
+}
+
+
/* enqueue the the kernel message into the message queue.
* The provided msg string is not freed - thus must be done
* by the caller.
@@ -182,8 +199,7 @@ rsRetVal imklogLogIntMsg(int priority, char *fmt, ...)
pLogMsg = msgBuf;
va_end(ap);
- iRet = enqMsg((uchar*)pLogMsg, (uchar*) ((iFacilIntMsg == LOG_KERN) ? "kernel:" : "imklog:"),
- iFacilIntMsg, LOG_PRI(priority), NULL);
+ logmsgInternal(NO_ERRCODE ,priority, msgBuf, 0);
RETiRet;
}
@@ -220,7 +236,7 @@ rsRetVal Syslog(int priority, uchar *pMsg, struct timeval *tp)
/* if we don't get the pri, we use whatever we were supplied */
/* ignore non-kernel messages if not permitted */
- if(bPermitNonKernel == 0 && LOG_FAC(priority) != LOG_KERN)
+ if(cs.bPermitNonKernel == 0 && LOG_FAC(priority) != LOG_KERN)
FINALIZE; /* silently ignore */
iRet = enqMsg((uchar*)pMsg, (uchar*) "kernel:", LOG_FAC(priority), LOG_PRI(priority), tp);
@@ -252,63 +268,123 @@ CODESTARTrunInput
* and then submits it to the rsyslog main queue.
* rgerhards, 2008-04-09
*/
- CHKiRet(klogLogKMsg());
+ CHKiRet(klogLogKMsg(runModConf));
}
finalize_it:
ENDrunInput
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init legacy config vars */
+ initConfigSettings();
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ /* persist module-specific settings from legacy config system */
+ loadModConf->dbgPrintSymbols = cs.dbgPrintSymbols;
+ loadModConf->symbols_twice = cs.symbols_twice;
+ loadModConf->use_syscall = cs.use_syscall;
+ loadModConf->bPermitNonKernel = cs.bPermitNonKernel;
+ loadModConf->iFacilIntMsg = cs.iFacilIntMsg;
+ loadModConf->console_log_level = cs.console_log_level;
+ if((cs.pszPath == NULL) || (cs.pszPath[0] == '\0')) {
+ loadModConf->pszPath = NULL;
+ if(cs.pszPath != NULL)
+ free(cs.pszPath);
+ } else {
+ loadModConf->pszPath = cs.pszPath;
+ }
+ cs.pszPath = NULL;
+ if((cs.symfile == NULL) || (cs.symfile[0] == '\0')) {
+ loadModConf->symfile = NULL;
+ if(cs.symfile != NULL)
+ free(cs.symfile);
+ } else {
+ loadModConf->symfile = cs.symfile;
+ }
+ cs.symfile = NULL;
+
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(cs.pszPath);
+ cs.pszPath = NULL;
+ free(cs.symfile);
+ cs.symfile = NULL;
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+
+BEGINactivateCnfPrePrivDrop
+CODESTARTactivateCnfPrePrivDrop
+ runModConf = pModConf;
+ iRet = klogWillRun(runModConf);
+ENDactivateCnfPrePrivDrop
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
+
BEGINwillRun
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));
-
- iRet = klogWillRun();
-finalize_it:
ENDwillRun
BEGINafterRun
CODESTARTafterRun
- iRet = klogAfterRun();
+ iRet = klogAfterRun(runModConf);
+ENDafterRun
+
+BEGINmodExit
+CODESTARTmodExit
if(pInputName != NULL)
prop.Destruct(&pInputName);
if(pLocalHostIP != NULL)
prop.Destruct(&pLocalHostIP);
-ENDafterRun
-
-BEGINmodExit
-CODESTARTmodExit
/* release objects we used */
objRelease(glbl, CORE_COMPONENT);
objRelease(datetime, CORE_COMPONENT);
objRelease(prop, CORE_COMPONENT);
- if(pszPath != NULL)
- free(pszPath);
ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- dbgPrintSymbols = 0;
- symbols_twice = 0;
- use_syscall = 0;
- symfile = NULL;
- symbol_lookup = 0;
- bPermitNonKernel = 0;
- if(pszPath != NULL) {
- free(pszPath);
- pszPath = NULL;
+ cs.dbgPrintSymbols = 0;
+ cs.symbols_twice = 0;
+ cs.use_syscall = 0;
+ cs.symfile = NULL;
+ cs.symbol_lookup = 0;
+ cs.bPermitNonKernel = 0;
+ if(cs.pszPath != NULL) {
+ free(cs.pszPath);
+ cs.pszPath = NULL;
}
- iFacilIntMsg = klogFacilIntMsg();
+ cs.iFacilIntMsg = klogFacilIntMsg();
return RS_RET_OK;
}
@@ -320,17 +396,31 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(prop, CORE_COMPONENT));
- iFacilIntMsg = klogFacilIntMsg();
-
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrBinary, NULL, &dbgPrintSymbols, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpath", 0, eCmdHdlrGetWord, NULL, &pszPath, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrBinary, NULL, &symbol_lookup, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrBinary, NULL, &symbols_twice, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrBinary, NULL, &use_syscall, STD_LOADABLE_MODULE_ID));
- 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 *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ /* 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));
+
+ /* init legacy config settings */
+ initConfigSettings();
+
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrBinary,
+ NULL, &cs.dbgPrintSymbols, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpath", 0, eCmdHdlrGetWord,
+ NULL, &cs.pszPath, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrBinary,
+ NULL, &cs.symbol_lookup, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrBinary,
+ NULL, &cs.symbols_twice, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrBinary,
+ NULL, &cs.use_syscall, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpermitnonkernelfacility", 0, eCmdHdlrBinary,
+ NULL, &cs.bPermitNonKernel, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogconsoleloglevel", 0, eCmdHdlrInt,
+ NULL, &cs.console_log_level, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloginternalmsgfacility", 0, eCmdHdlrFacility,
+ NULL, &cs.iFacilIntMsg, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
+ resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
/* vim:set ai:
*/
diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h
index 39bdeb5c..b0772711 100644
--- a/plugins/imklog/imklog.h
+++ b/plugins/imklog/imklog.h
@@ -30,22 +30,37 @@
#include "rsyslog.h"
#include "dirty.h"
+/* we need to have the modConf type present in all submodules */
+struct modConfData_s {
+ int dbgPrintSymbols;
+ int symbols_twice;
+ int use_syscall;
+ int symbol_lookup;
+ int bPermitNonKernel;
+ int iFacilIntMsg;
+ uchar *pszPath;
+ int console_log_level;
+ char *symfile;
+ rsconf_t *pConf;
+};
+
/* interface to "drivers"
* the platform specific drivers must implement these entry points. Only one
* driver may be active at any given time, thus we simply rely on the linker
* to resolve the addresses.
* rgerhards, 2008-04-09
*/
-rsRetVal klogLogKMsg(void);
-rsRetVal klogWillRun(void);
-rsRetVal klogAfterRun(void);
-int klogFacilIntMsg(void);
+rsRetVal klogLogKMsg(modConfData_t *pModConf);
+rsRetVal klogWillRun(modConfData_t *pModConf);
+rsRetVal klogAfterRun(modConfData_t *pModConf);
+int klogFacilIntMsg();
/* the following data members may be accessed by the "drivers"
* I admit this is not the cleanest way to doing things, but I honestly
* believe it is appropriate for the job that needs to be done.
* rgerhards, 2008-04-09
*/
+#if 0
extern int symbols_twice;
extern int use_syscall;
extern int symbol_lookup;
@@ -53,6 +68,7 @@ extern char *symfile;
extern int console_log_level;
extern int dbgPrintSymbols;
extern uchar *pszPath;
+#endif
/* the functions below may be called by the drivers */
rsRetVal imklogLogIntMsg(int priority, char *fmt, ...) __attribute__((format(printf,2, 3)));
@@ -60,7 +76,7 @@ rsRetVal Syslog(int priority, uchar *msg, struct timeval *tp);
/* prototypes */
extern int klog_getMaxLine(void); /* work-around for klog drivers to get configured max line size */
-extern int InitKsyms(char *);
+extern int InitKsyms(modConfData_t*);
extern void DeinitKsyms(void);
extern int InitMsyms(void);
extern void DeinitMsyms(void);
diff --git a/plugins/immark/immark.c b/plugins/immark/immark.c
index 358b3b18..273af021 100644
--- a/plugins/immark/immark.c
+++ b/plugins/immark/immark.c
@@ -46,6 +46,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("immark")
/* defines */
#define DEFAULT_MARK_PERIOD (20 * 60)
@@ -53,7 +54,12 @@ MODULE_TYPE_NOKEEP
/* Module static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(glbl)
+DEFobjCurrIf(errmsg)
+
static int iMarkMessagePeriod = DEFAULT_MARK_PERIOD;
+struct modConfData_s {
+ int iMarkMessagePeriod;
+};
BEGINisCompatibleWithFeature
CODESTARTisCompatibleWithFeature
@@ -62,6 +68,43 @@ CODESTARTisCompatibleWithFeature
ENDisCompatibleWithFeature
+BEGINafterRun
+CODESTARTafterRun
+ENDafterRun
+
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ pModConf->iMarkMessagePeriod = iMarkMessagePeriod;
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ if(pModConf->iMarkMessagePeriod == 0) {
+ errmsg.LogError(0, NO_ERRCODE, "immark: mark message period must not be 0, can not run");
+ ABORT_FINALIZE(RS_RET_NO_RUN); /* we can not run with this error */
+ }
+finalize_it:
+ENDcheckCnf
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ MarkInterval = pModConf->iMarkMessagePeriod;
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
+
/* This function is called to gather input. It must terminate only
* a) on failure (iRet set accordingly)
* b) on termination of the input module (as part of the unload process)
@@ -81,7 +124,7 @@ CODESTARTrunInput
* right into the sleep below.
*/
while(1) {
- srSleep(iMarkMessagePeriod, 0); /* seconds, micro seconds */
+ srSleep(MarkInterval, 0); /* seconds, micro seconds */
if(glbl.GetGlobalInputTermState() == 1)
break; /* terminate input! */
@@ -94,33 +137,25 @@ ENDrunInput
BEGINwillRun
CODESTARTwillRun
- /* We set the global MarkInterval to what is configured here -- rgerhards, 2008-07-15 */
- MarkInterval = iMarkMessagePeriod;
- if(iMarkMessagePeriod == 0)
- iRet = RS_RET_NO_RUN;
ENDwillRun
-BEGINafterRun
-CODESTARTafterRun
-ENDafterRun
-
-
BEGINmodExit
CODESTARTmodExit
+ objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
iMarkMessagePeriod = DEFAULT_MARK_PERIOD;
-
return RS_RET_OK;
}
@@ -129,8 +164,13 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(glbl, CORE_COMPONENT));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"markmessageperiod", 0, eCmdHdlrInt, NULL, &iMarkMessagePeriod, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+
+ /* legacy config handlers */
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"markmessageperiod", 0, eCmdHdlrInt, NULL,
+ &iMarkMessagePeriod, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
+ resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
/* vi:set ai:
*/
diff --git a/plugins/impstats/impstats.c b/plugins/impstats/impstats.c
index 3012136c..66c5fee6 100644
--- a/plugins/impstats/impstats.c
+++ b/plugins/impstats/impstats.c
@@ -40,6 +40,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("impstats")
/* defines */
#define DEFAULT_STATS_PERIOD (5 * 60)
@@ -59,6 +60,16 @@ typedef struct configSettings_s {
int iSeverity;
} configSettings_t;
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ int iStatsInterval;
+ int iFacility;
+ int iSeverity;
+};
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+
+
static configSettings_t cs;
static prop_t *pInputName = NULL;
@@ -95,8 +106,8 @@ doSubmitMsg(uchar *line)
MsgSetRcvFromIP(pMsg, pLocalHostIP);
MsgSetMSGoffs(pMsg, 0);
MsgSetTAG(pMsg, UCHAR_CONSTANT("rsyslogd-pstats:"), sizeof("rsyslogd-pstats:") - 1);
- pMsg->iFacility = cs.iFacility;
- pMsg->iSeverity = cs.iSeverity;
+ pMsg->iFacility = runModConf->iFacility;
+ pMsg->iSeverity = runModConf->iSeverity;
pMsg->msgFlags = 0;
submitMsg(pMsg);
@@ -129,6 +140,53 @@ generateStatsMsgs(void)
}
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init legacy config vars */
+ initConfigSettings();
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ /* persist module-specific settings from legacy config system */
+ loadModConf->iStatsInterval = cs.iStatsInterval;
+ loadModConf->iFacility = cs.iFacility;
+ loadModConf->iSeverity = cs.iSeverity;
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ if(pModConf->iStatsInterval == 0) {
+ errmsg.LogError(0, NO_ERRCODE, "impstats: stats interval zero not permitted, using "
+ "defaul of %d seconds", DEFAULT_STATS_PERIOD);
+ pModConf->iStatsInterval = DEFAULT_STATS_PERIOD;
+ }
+ENDcheckCnf
+
+
+BEGINactivateCnf
+ rsRetVal localRet;
+CODESTARTactivateCnf
+ runModConf = pModConf;
+ DBGPRINTF("impstats: stats interval %d seconds\n", runModConf->iStatsInterval);
+ localRet = statsobj.EnableStats();
+ if(localRet != RS_RET_OK) {
+ errmsg.LogError(0, localRet, "impstats: error enabling statistics gathering");
+ ABORT_FINALIZE(RS_RET_NO_RUN);
+ }
+finalize_it:
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
+
BEGINrunInput
CODESTARTrunInput
/* this is an endless loop - it is terminated when the thread is
@@ -136,7 +194,7 @@ CODESTARTrunInput
* right into the sleep below.
*/
while(1) {
- srSleep(cs.iStatsInterval, 0); /* seconds, micro seconds */
+ srSleep(runModConf->iStatsInterval, 0); /* seconds, micro seconds */
if(glbl.GetGlobalInputTermState() == 1)
break; /* terminate input! */
@@ -147,17 +205,7 @@ ENDrunInput
BEGINwillRun
- rsRetVal localRet;
CODESTARTwillRun
- DBGPRINTF("impstats: stats interval %d seconds\n", cs.iStatsInterval);
- if(cs.iStatsInterval == 0)
- ABORT_FINALIZE(RS_RET_NO_RUN);
- localRet = statsobj.EnableStats();
- if(localRet != RS_RET_OK) {
- errmsg.LogError(0, localRet, "impstat: error enabling statistics gathering");
- ABORT_FINALIZE(RS_RET_NO_RUN);
- }
-finalize_it:
ENDwillRun
@@ -182,6 +230,7 @@ ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
ENDqueryEtryPt
diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c
index a735b0b2..ec6836c1 100644
--- a/plugins/imptcp/imptcp.c
+++ b/plugins/imptcp/imptcp.c
@@ -75,6 +75,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imptcp")
/* static data */
DEF_IMOD_STATIC_DATA
@@ -86,6 +87,8 @@ DEFobjCurrIf(errmsg)
DEFobjCurrIf(ruleset)
DEFobjCurrIf(statsobj)
+/* forward references */
+static void * wrkr(void *myself);
/* config settings */
typedef struct configSettings_s {
@@ -97,11 +100,37 @@ typedef struct configSettings_s {
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? */
- ruleset_t *pRuleset; /* ruleset to bind listener to (use system default if unspecified) */
+ uchar *pszBindRuleset;
+ int wrkrMax; /* max number of workers (actually "helper workers") */
} configSettings_t;
-
static configSettings_t cs;
+struct instanceConf_s {
+ int bKeepAlive; /* support keep-alive packets */
+ int iKeepAliveIntvl;
+ int iKeepAliveProbes;
+ int iKeepAliveTime;
+ int bEmitMsgOnClose;
+ int iAddtlFrameDelim;
+ uchar *pszBindPort; /* port to bind to */
+ uchar *pszBindAddr; /* IP to bind socket to */
+ uchar *pszBindRuleset; /* name of ruleset to bind to */
+ uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
+ ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
+ struct instanceConf_s *next;
+};
+
+
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ instanceConf_t *root, *tail;
+ int wrkrMax;
+};
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+
+#include "im-helper.h" /* must be included AFTER the type definitions! */
/* data elements describing our running config */
typedef struct ptcpsrv_s ptcpsrv_t;
typedef struct ptcplstn_s ptcplstn_t;
@@ -125,6 +154,7 @@ struct ptcpsrv_s {
ruleset_t *pRuleset;
ptcplstn_t *pLstn; /* root of our listeners */
ptcpsess_t *pSess; /* root of our sessions */
+ pthread_mutex_t mutSessLst;
sbool bKeepAlive; /* support keep-alive packets */
sbool bEmitMsgOnClose;
};
@@ -167,6 +197,20 @@ struct ptcplstn_s {
};
+/* The following structure controls the worker threads. Global data is
+ * needed for their access.
+ */
+static struct wrkrInfo_s {
+ pthread_t tid; /* the worker's thread ID */
+ pthread_cond_t run;
+ struct epoll_event *event; /* event == NULL -> idle */
+ long long unsigned numCalled; /* how often was this called */
+} wrkrInfo[16];
+static pthread_mutex_t wrkrMut;
+static pthread_cond_t wrkrIdle;
+static int wrkrRunning;
+
+
/* type of object stored in epoll descriptor */
typedef enum {
epolld_lstn,
@@ -184,20 +228,10 @@ struct epolld_s {
/* global data */
-//static permittedPeers_t *pPermPeersRoot = NULL;
+pthread_attr_t wrkrThrdAttr; /* Attribute for session threads; read only after startup */
static ptcpsrv_t *pSrvRoot = NULL;
static int epollfd = -1; /* (sole) descriptor for epoll */
static int iMaxLine; /* maximum size of a single message */
-/* we use a single static receive buffer, as this module is not multi-threaded. Keeping
- * the buffer in the data segment is probably a little bit more efficient than on the stack
- * (but at least I can't believe it will ever be less efficient ;) -- rgerhards, 2010-08-10
- * Note that we do NOT (yet?) provide a config setting to set the buffer size. For usual
- * syslog traffic, it should be large enough. Also keep in mind that we run under a virtual
- * memory system, so if we do not use large parts of the buffer, that's no issue at
- * all -- it'll just use up address space. On the other hand, it would be silly to page in
- * or page out some data just to get space for the IO buffer.
- */
-static char rcvBuf[128*1024];
/* forward definitions */
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
@@ -222,6 +256,7 @@ static void
destructSrv(ptcpsrv_t *pSrv)
{
prop.Destruct(&pSrv->pInputName);
+ pthread_mutex_destroy(&pSrv->mutSessLst);
free(pSrv->port);
free(pSrv);
}
@@ -250,7 +285,7 @@ startupSrv(ptcpsrv_t *pSrv)
lstnIP = pSrv->lstnIP == NULL ? UCHAR_CONSTANT("") : pSrv->lstnIP;
- DBGPRINTF("imptcp creating listen socket on server '%s', port %s\n", lstnIP, pSrv->port);
+ DBGPRINTF("imptcp: creating listen socket on server '%s', port %s\n", lstnIP, pSrv->port);
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
@@ -769,9 +804,11 @@ static inline void
initConfigSettings(void)
{
cs.bEmitMsgOnClose = 0;
+ cs.wrkrMax = 2;
cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
cs.pszInputName = NULL;
- cs.pRuleset = NULL;
+ cs.pszBindRuleset = NULL;
+ cs.pszInputName = NULL;
cs.lstnIP = NULL;
}
@@ -893,10 +930,12 @@ addSess(ptcplstn_t *pLstn, int sock, prop_t *peerName, prop_t *peerIP)
/* add to start of server's listener list */
pSess->prev = NULL;
+ pthread_mutex_lock(&pSrv->mutSessLst);
pSess->next = pSrv->pSess;
if(pSrv->pSess != NULL)
pSrv->pSess->prev = pSess;
pSrv->pSess = pSess;
+ pthread_mutex_unlock(&pSrv->mutSessLst);
iRet = addEPollSock(epolld_sess, pSess, sock, &pSess->epd);
@@ -919,10 +958,8 @@ closeSess(ptcpsess_t *pSess)
CHKiRet(removeEPollSock(sock, pSess->epd));
close(sock);
+ pthread_mutex_lock(&pSess->pLstn->pSrv->mutSessLst);
/* finally unlink session from structures */
-//fprintf(stderr, "closing session %d next %p, prev %p\n", pSess->sock, pSess->next, pSess->prev);
-//DBGPRINTF("imptcp: pSess->next %p\n", pSess->next);
-//DBGPRINTF("imptcp: pSess->prev %p\n", pSess->prev);
if(pSess->next != NULL)
pSess->next->prev = pSess->prev;
if(pSess->prev == NULL) {
@@ -931,6 +968,7 @@ closeSess(ptcpsess_t *pSess)
} else {
pSess->prev->next = pSess->next;
}
+ pthread_mutex_unlock(&pSess->pLstn->pSrv->mutSessLst);
/* unlinked, now remove structure */
destructSess(pSess);
@@ -941,62 +979,86 @@ finalize_it:
}
-#if 0
-/* set permitted peer -- rgerhards, 2008-05-19
+/* This function is called when a new listener instace shall be added to
+ * the current config object via the legacy config system. It just shuffles
+ * all parameters to the listener in-memory instance.
*/
-static rsRetVal
-setPermittedPeer(void __attribute__((unused)) *pVal, uchar *pszID)
-{
- DEFiRet;
- CHKiRet(net.AddPermittedPeer(&pPermPeersRoot, pszID));
- free(pszID); /* no longer needed, but we need to free as of interface def */
-finalize_it:
- RETiRet;
-}
-#endif
-
-
-/* accept a new ruleset to bind. Checks if it exists and complains, if not */
-static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
+static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
{
- ruleset_t *pRuleset;
- rsRetVal localRet;
+ instanceConf_t *inst;
DEFiRet;
- localRet = ruleset.GetRuleset(&pRuleset, pszName);
- if(localRet == RS_RET_NOT_FOUND) {
- errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName);
+ CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
+ if(pNewVal == NULL || *pNewVal == '\0') {
+ errmsg.LogError(0, NO_ERRCODE, "imptcp: port number must be specified, listener ignored");
+ }
+ if((pNewVal == NULL) || (pNewVal == '\0')) {
+ inst->pszBindPort = NULL;
+ } else {
+ CHKmalloc(inst->pszBindPort = ustrdup(pNewVal));
+ }
+ if((cs.lstnIP == NULL) || (cs.lstnIP[0] == '\0')) {
+ inst->pszBindAddr = NULL;
+ } else {
+ CHKmalloc(inst->pszBindAddr = ustrdup(cs.lstnIP));
+ }
+ if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
+ inst->pszBindRuleset = NULL;
+ } else {
+ CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset));
+ }
+ if((cs.pszInputName == NULL) || (cs.pszInputName[0] == '\0')) {
+ inst->pszInputName = NULL;
+ } else {
+ CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName));
+ }
+ inst->pBindRuleset = NULL;
+ inst->bKeepAlive = cs.bKeepAlive;
+ inst->iKeepAliveIntvl = cs.iKeepAliveTime;
+ inst->iKeepAliveProbes = cs.iKeepAliveProbes;
+ inst->iKeepAliveTime = cs.iKeepAliveTime;
+ inst->bEmitMsgOnClose = cs.bEmitMsgOnClose;
+ inst->iAddtlFrameDelim = cs.iAddtlFrameDelim;
+ inst->next = NULL;
+
+ /* node created, let's add to config */
+ if(loadModConf->tail == NULL) {
+ loadModConf->tail = loadModConf->root = inst;
+ } else {
+ loadModConf->tail->next = inst;
+ loadModConf->tail = inst;
}
- CHKiRet(localRet);
- cs.pRuleset = pRuleset;
- DBGPRINTF("imptcp current bind ruleset %p: '%s'\n", pRuleset, pszName);
finalize_it:
- free(pszName); /* no longer needed */
+ free(pNewVal);
RETiRet;
}
-static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
+static inline rsRetVal
+addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst)
{
DEFiRet;
ptcpsrv_t *pSrv;
- CHKmalloc(pSrv = malloc(sizeof(ptcpsrv_t)));
+ CHKmalloc(pSrv = MALLOC(sizeof(ptcpsrv_t)));
+ pthread_mutex_init(&pSrv->mutSessLst, NULL);
pSrv->pSess = NULL;
pSrv->pLstn = NULL;
- pSrv->bKeepAlive = cs.bKeepAlive;
- pSrv->iKeepAliveIntvl = cs.iKeepAliveTime;
- pSrv->iKeepAliveProbes = cs.iKeepAliveProbes;
- pSrv->iKeepAliveTime = cs.iKeepAliveTime;
- 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;
+ pSrv->bKeepAlive = inst->bKeepAlive;
+ pSrv->iKeepAliveIntvl = inst->iKeepAliveTime;
+ pSrv->iKeepAliveProbes = inst->iKeepAliveProbes;
+ pSrv->iKeepAliveTime = inst->iKeepAliveTime;
+ pSrv->bEmitMsgOnClose = inst->bEmitMsgOnClose;
+ CHKmalloc(pSrv->port = ustrdup(inst->pszBindPort));
+ pSrv->iAddtlFrameDelim = inst->iAddtlFrameDelim;
+ if(inst->pszBindAddr == NULL)
+ pSrv->lstnIP = NULL;
+ else {
+ CHKmalloc(pSrv->lstnIP = ustrdup(inst->pszBindAddr));
+ }
+ pSrv->pRuleset = inst->pBindRuleset;
+ pSrv->pszInputName = (inst->pszInputName == NULL) ? UCHAR_CONSTANT("imptcp") : ustrdup(inst->pszInputName);
CHKiRet(prop.Construct(&pSrv->pInputName));
CHKiRet(prop.SetString(pSrv->pInputName, pSrv->pszInputName, ustrlen(pSrv->pszInputName)));
CHKiRet(prop.ConstructFinalize(pSrv->pInputName));
@@ -1018,6 +1080,46 @@ finalize_it:
}
+/* destroy worker pool structures and wait for workers to terminate
+ */
+static inline void
+startWorkerPool(void)
+{
+ int i;
+ wrkrRunning = 0;
+ if(runModConf->wrkrMax > 16)
+ runModConf->wrkrMax = 16; /* TODO: make dynamic? */
+ pthread_mutex_init(&wrkrMut, NULL);
+ pthread_cond_init(&wrkrIdle, NULL);
+ for(i = 0 ; i < runModConf->wrkrMax ; ++i) {
+ /* init worker info structure! */
+ pthread_cond_init(&wrkrInfo[i].run, NULL);
+ wrkrInfo[i].event = NULL;
+ wrkrInfo[i].numCalled = 0;
+ pthread_create(&wrkrInfo[i].tid, &wrkrThrdAttr, wrkr, &(wrkrInfo[i]));
+ }
+
+}
+
+/* destroy worker pool structures and wait for workers to terminate
+ */
+static inline void
+stopWorkerPool(void)
+{
+ int i;
+ for(i = 0 ; i < runModConf->wrkrMax ; ++i) {
+ pthread_cond_signal(&wrkrInfo[i].run); /* awake wrkr if not running */
+ pthread_join(wrkrInfo[i].tid, NULL);
+ DBGPRINTF("imptcp: info: worker %d was called %llu times\n", i, wrkrInfo[i].numCalled);
+ pthread_cond_destroy(&wrkrInfo[i].run);
+ }
+ pthread_cond_destroy(&wrkrIdle);
+ pthread_mutex_destroy(&wrkrMut);
+
+}
+
+
+
/* start up all listeners
* This is a one-time stop once the module is set to start.
*/
@@ -1025,15 +1127,29 @@ static inline rsRetVal
startupServers()
{
DEFiRet;
+ rsRetVal localRet, lastErr;
+ int iOK;
+ int iAll;
ptcpsrv_t *pSrv;
+ iAll = iOK = 0;
+ lastErr = RS_RET_ERR;
pSrv = pSrvRoot;
while(pSrv != NULL) {
- DBGPRINTF("Starting up ptcp server for port %s, name '%s'\n", pSrv->port, pSrv->pszInputName);
- startupSrv(pSrv);
+ DBGPRINTF("imptcp: starting up server for port %s, name '%s'\n", pSrv->port, pSrv->pszInputName);
+ localRet = startupSrv(pSrv);
+ if(localRet == RS_RET_OK)
+ iOK++;
+ else
+ lastErr = localRet;
+ ++iAll;
pSrv = pSrv->pNext;
}
+ DBGPRINTF("imptcp: %d out of %d servers started successfully\n", iOK, iAll);
+ if(iOK == 0) /* iff all fails, we report an error */
+ iRet = lastErr;
+
RETiRet;
}
@@ -1051,9 +1167,9 @@ lstnActivity(ptcplstn_t *pLstn)
DEFiRet;
DBGPRINTF("imptcp: new connection on listen socket %d\n", pLstn->sock);
- while(1) {
+ while(glbl.GetGlobalInputTermState() == 0) {
localRet = AcceptConnReq(pLstn, &newSock, &peerName, &peerIP);
- if(localRet == RS_RET_NO_MORE_DATA)
+ if(localRet == RS_RET_NO_MORE_DATA || glbl.GetGlobalInputTermState() == 1)
break;
CHKiRet(localRet);
CHKiRet(addSess(pLstn, newSock, peerName, peerIP));
@@ -1072,6 +1188,7 @@ sessActivity(ptcpsess_t *pSess)
{
int lenRcv;
int lenBuf;
+ char rcvBuf[128*1024];
DEFiRet;
DBGPRINTF("imptcp: new activity on session socket %d\n", pSess->sock);
@@ -1109,47 +1226,160 @@ finalize_it:
}
-/* This function is called to gather input.
+/* This function is called to process a single request. This may
+ * be carried out by the main worker or a helper. It can be run
+ * concurrently.
*/
-BEGINrunInput
- int i;
- int nfds;
- struct epoll_event events[1];
+static inline void
+processWorkItem(struct epoll_event *event)
+{
epolld_t *epd;
-CODESTARTrunInput
- DBGPRINTF("imptcp now beginning to process input data\n");
- /* v5 TODO: consentual termination mode */
- while(1) {
- DBGPRINTF("imptcp going on epoll_wait\n");
- nfds = epoll_wait(epollfd, events, sizeof(events)/sizeof(struct epoll_event), -1);
- for(i = 0 ; i < nfds ; ++i) { /* support for larger batches (later, TODO) */
- epd = (epolld_t*) events[i].data.ptr;
- switch(epd->typ) {
- case epolld_lstn:
- lstnActivity((ptcplstn_t *) epd->ptr);
- break;
- case epolld_sess:
- sessActivity((ptcpsess_t *) epd->ptr);
- break;
- default:
- errmsg.LogError(0, RS_RET_INTERNAL_ERROR,
- "error: invalid epolld_type_t %d after epoll", epd->typ);
- break;
+
+ epd = (epolld_t*) event->data.ptr;
+ switch(epd->typ) {
+ case epolld_lstn:
+ lstnActivity((ptcplstn_t *) epd->ptr);
+ break;
+ case epolld_sess:
+ sessActivity((ptcpsess_t *) epd->ptr);
+ break;
+ default:
+ errmsg.LogError(0, RS_RET_INTERNAL_ERROR,
+ "error: invalid epolld_type_t %d after epoll", epd->typ);
+ break;
+ }
+}
+
+
+/* This function is called to process a complete workset, that
+ * is a set of events returned from epoll.
+ */
+static inline void
+processWorkSet(int nEvents, struct epoll_event events[])
+{
+ int iEvt;
+ int i;
+ int remainEvents;
+
+ remainEvents = nEvents;
+ for(iEvt = 0 ; (iEvt < nEvents) && (glbl.GetGlobalInputTermState() == 0) ; ++iEvt) {
+ if(remainEvents == 1) {
+ /* process self, save context switch */
+ processWorkItem(events+iEvt);
+ } else {
+ pthread_mutex_lock(&wrkrMut);
+ /* check if there is a free worker */
+ for(i = 0 ; (i < runModConf->wrkrMax) && (wrkrInfo[i].event != NULL) ; ++i)
+ /*do search*/;
+ if(i < runModConf->wrkrMax) {
+ /* worker free -> use it! */
+ wrkrInfo[i].event = events+iEvt;
+ ++wrkrRunning;
+ pthread_cond_signal(&wrkrInfo[i].run);
+ pthread_mutex_unlock(&wrkrMut);
+ } else {
+ pthread_mutex_unlock(&wrkrMut);
+ /* no free worker, so we process this one ourselfs */
+ processWorkItem(events+iEvt);
}
}
+ --remainEvents;
}
-ENDrunInput
+ if(nEvents > 1) {
+ /* we now need to wait until all workers finish. This is because the
+ * rest of this module can not handle the concurrency introduced
+ * by workers running during the epoll call.
+ */
+ pthread_mutex_lock(&wrkrMut);
+ while(wrkrRunning > 0) {
+ pthread_cond_wait(&wrkrIdle, &wrkrMut);
+ }
+ pthread_mutex_unlock(&wrkrMut);
+ }
-/* initialize and return if will run or not */
-BEGINwillRun
-CODESTARTwillRun
- /* first apply some config settings */
- //net.PrintAllowedSenders(2); /* TCP */
+}
+
+
+/* worker to process incoming requests
+ */
+static void *
+wrkr(void *myself)
+{
+ struct wrkrInfo_s *me = (struct wrkrInfo_s*) myself;
+
+ pthread_mutex_lock(&wrkrMut);
+ while(1) {
+ while(me->event == NULL && glbl.GetGlobalInputTermState() == 0) {
+ pthread_cond_wait(&me->run, &wrkrMut);
+ }
+ if(glbl.GetGlobalInputTermState() == 1)
+ break;
+ pthread_mutex_unlock(&wrkrMut);
+
+ ++me->numCalled;
+ processWorkItem(me->event);
+
+ pthread_mutex_lock(&wrkrMut);
+ me->event = NULL; /* indicate we are free again */
+ --wrkrRunning;
+ pthread_cond_signal(&wrkrIdle);
+ }
+ pthread_mutex_unlock(&wrkrMut);
+
+ return NULL;
+}
+
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init legacy config vars */
+ initConfigSettings();
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ /* persist module-specific settings from legacy config system */
+ loadModConf->wrkrMax = cs.wrkrMax;
+
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(cs.pszInputName);
+ free(cs.lstnIP);
+ENDendCnfLoad
+
+
+/* function to generate error message if framework does not find requested ruleset */
+static inline void
+std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst)
+{
+ errmsg.LogError(0, NO_ERRCODE, "imptcp: ruleset '%s' for port %s not found - "
+ "using default ruleset instead", inst->pszBindRuleset,
+ inst->pszBindPort);
+}
+BEGINcheckCnf
+ instanceConf_t *inst;
+CODESTARTcheckCnf
+ for(inst = pModConf->root ; inst != NULL ; inst = inst->next) {
+ std_checkRuleset(pModConf, inst);
+ }
+ENDcheckCnf
+
+
+BEGINactivateCnfPrePrivDrop
+ instanceConf_t *inst;
+CODESTARTactivateCnfPrePrivDrop
iMaxLine = glbl.GetMaxLine(); /* get maximum size we currently support */
+ runModConf = pModConf;
+ for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
+ addListner(pModConf, inst);
+ }
if(pSrvRoot == NULL) {
- errmsg.LogError(0, RS_RET_NO_LSTN_DEFINED, "error: no ptcp server defined, module can not run.");
+ errmsg.LogError(0, RS_RET_NO_LSTN_DEFINED, "imptcp: no ptcp server defined, module can not run.");
ABORT_FINALIZE(RS_RET_NO_RUN);
}
@@ -1176,6 +1406,52 @@ CODESTARTwillRun
CHKiRet(startupServers());
DBGPRINTF("imptcp started up, but not yet receiving data\n");
finalize_it:
+ENDactivateCnfPrePrivDrop
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ /* nothing to do, all done pre priv drop */
+ENDactivateCnf
+
+
+BEGINfreeCnf
+ instanceConf_t *inst, *del;
+CODESTARTfreeCnf
+ for(inst = pModConf->root ; inst != NULL ; ) {
+ free(inst->pszBindPort);
+ free(inst->pszBindAddr);
+ free(inst->pszBindRuleset);
+ free(inst->pszInputName);
+ del = inst;
+ inst = inst->next;
+ free(del);
+ }
+ENDfreeCnf
+
+
+/* This function is called to gather input.
+ */
+BEGINrunInput
+ int nEvents;
+ struct epoll_event events[128];
+CODESTARTrunInput
+ startWorkerPool();
+ DBGPRINTF("imptcp: now beginning to process input data\n");
+ while(glbl.GetGlobalInputTermState() == 0) {
+ DBGPRINTF("imptcp going on epoll_wait\n");
+ nEvents = epoll_wait(epollfd, events, sizeof(events)/sizeof(struct epoll_event), -1);
+ DBGPRINTF("imptcp: epoll returned %d events\n", nEvents);
+ processWorkSet(nEvents, events);
+ }
+ DBGPRINTF("imptcp: successfully terminated\n");
+ /* we stop the worker pool in AfterRun, in case we get cancelled for some reason (old Interface) */
+ENDrunInput
+
+
+/* initialize and return if will run or not */
+BEGINwillRun
+CODESTARTwillRun
ENDwillRun
@@ -1216,8 +1492,8 @@ shutdownSrv(ptcpsrv_t *pSrv)
BEGINafterRun
ptcpsrv_t *pSrv, *srvDel;
CODESTARTafterRun
- /* do cleanup here */
- //net.clearAllowedSenders(UCHAR_CONSTANT("TCP"));
+ stopWorkerPool();
+
/* we need to close everything that is still open */
pSrv = pSrvRoot;
while(pSrv != NULL) {
@@ -1233,12 +1509,7 @@ ENDafterRun
BEGINmodExit
CODESTARTmodExit
-#if 0
- if(pPermPeersRoot != NULL) {
- net.DestructPermittedPeers(&pPermPeersRoot);
- }
-#endif
-
+ pthread_attr_destroy(&wrkrThrdAttr);
/* release objects we used */
objRelease(glbl, CORE_COMPONENT);
objRelease(statsobj, CORE_COMPONENT);
@@ -1254,6 +1525,7 @@ static rsRetVal
resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
cs.bEmitMsgOnClose = 0;
+ cs.wrkrMax = 2;
cs.bKeepAlive = 0;
cs.iKeepAliveProbes = 0;
cs.iKeepAliveTime = 0;
@@ -1267,10 +1539,19 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
}
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ if(eFeat == sFEATURENonCancelInputTermination)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
+CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
ENDqueryEtryPt
@@ -1278,7 +1559,6 @@ BEGINmodInit()
CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
- initConfigSettings();
/* request objects we use */
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(statsobj, CORE_COMPONENT));
@@ -1288,9 +1568,16 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(datetime, CORE_COMPONENT));
CHKiRet(objUse(ruleset, CORE_COMPONENT));
+ /* initialize "read-only" thread attributes */
+ pthread_attr_init(&wrkrThrdAttr);
+ pthread_attr_setstacksize(&wrkrThrdAttr, 2048*1024);
+
+ /* init legacy config settings */
+ initConfigSettings();
+
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverrun"), 0, eCmdHdlrGetWord,
- addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
+ addInstance, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive"), 0, eCmdHdlrBinary,
NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive_probes"), 0, eCmdHdlrInt,
@@ -1303,12 +1590,14 @@ CODEmodInit_QueryRegCFSLineHdlr
eCmdHdlrBinary, NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,
NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverhelperthreads"), 0, eCmdHdlrInt,
+ NULL, &cs.wrkrMax, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverinputname"), 0,
eCmdHdlrGetWord, NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverlistenip"), 0,
eCmdHdlrGetWord, NULL, &cs.lstnIP, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverbindruleset"), 0,
- eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID));
+ eCmdHdlrGetWord, NULL, cs.pszBindRuleset, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
index 602809ff..99fabd18 100644
--- a/plugins/imrelp/imrelp.c
+++ b/plugins/imrelp/imrelp.c
@@ -38,39 +38,56 @@
#include <librelp.h>
#include "rsyslog.h"
#include "dirty.h"
+#include "errmsg.h"
#include "cfsysline.h"
#include "module-template.h"
#include "net.h"
#include "msg.h"
#include "unicode-helper.h"
#include "prop.h"
+#include "ruleset.h"
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imrelp")
/* static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(net)
DEFobjCurrIf(prop)
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(ruleset)
+
+/* forward definitions */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
+
/* Module static data */
+/* config vars for legacy config system */
static relpEngine_t *pRelpEngine; /* our relp engine */
static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this module */
+static struct configSettings_s {
+ uchar *pszBindRuleset; /* name of Ruleset to bind to */
+} cs;
+struct instanceConf_s {
+ uchar *pszBindPort; /* port to bind to */
+ struct instanceConf_s *next;
+};
-/* config settings */
-/* ------------------------------ callbacks ------------------------------ */
-#if 0
-/* this shall go into a specific ACL module! */
-static int
-isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv,
- void __attribute__((unused)) *pUsrSess)
-{
- return net.isAllowedSender(net.pAllowedSenders_TCP, addr, fromHostFQDN);
-}
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ instanceConf_t *root, *tail;
+ uchar *pszBindRuleset; /* name of Ruleset to bind to */
+ ruleset_t *pBindRuleset; /* due to librelp limitation, we need to bind all listerns to the same set */
+};
-#endif // #if 0
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+
+
+/* ------------------------------ callbacks ------------------------------ */
/* callback for receiving syslog messages. This function is invoked from the
* RELP engine when a syslog message arrived. It must return a relpRetVal,
@@ -87,7 +104,7 @@ onSyslogRcv(uchar *pHostname, uchar *pIP, uchar *pMsg, size_t lenMsg)
{
DEFiRet;
parseAndSubmitMessage(pHostname, pIP, pMsg, lenMsg, PARSE_HOSTNAME,
- eFLOWCTL_LIGHT_DELAY, pInputName, NULL, 0);
+ eFLOWCTL_LIGHT_DELAY, pInputName, NULL, 0, runModConf->pBindRuleset);
RETiRet;
}
@@ -96,7 +113,48 @@ onSyslogRcv(uchar *pHostname, uchar *pIP, uchar *pMsg, size_t lenMsg)
/* ------------------------------ end callbacks ------------------------------ */
-static rsRetVal addListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
+/* modified to work for module, not instance (as usual) */
+static inline void
+std_checkRuleset_genErrMsg(modConfData_t *modConf, __attribute__((unused)) instanceConf_t *inst)
+{
+ errmsg.LogError(0, NO_ERRCODE, "imrelp: ruleset '%s' not found - "
+ "using default ruleset instead", modConf->pszBindRuleset);
+}
+
+
+/* This function is called when a new listener instace shall be added to
+ * the current config object via the legacy config system. It just shuffles
+ * all parameters to the listener in-memory instance.
+ * rgerhards, 2011-05-04
+ */
+static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
+{
+ instanceConf_t *inst;
+ DEFiRet;
+
+ CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
+
+ if(pNewVal == NULL || *pNewVal == '\0') {
+ errmsg.LogError(0, NO_ERRCODE, "imrelp: port number must be specified, listener ignored");
+ }
+ inst->pszBindPort = pNewVal;
+ inst->next = NULL;
+
+ /* node created, let's add to config */
+ if(loadModConf->tail == NULL) {
+ loadModConf->tail = loadModConf->root = inst;
+ } else {
+ loadModConf->tail->next = inst;
+ loadModConf->tail = inst;
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
+static rsRetVal
+addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst)
{
DEFiRet;
if(pRelpEngine == NULL) {
@@ -106,14 +164,78 @@ static rsRetVal addListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKiRet(relpEngineSetSyslogRcv(pRelpEngine, onSyslogRcv));
}
- CHKiRet(relpEngineAddListner(pRelpEngine, pNewVal));
-
- free(pNewVal); /* we do no longer need it */
+ CHKiRet(relpEngineAddListner(pRelpEngine, inst->pszBindPort));
finalize_it:
RETiRet;
}
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init legacy config variables */
+ cs.pszBindRuleset = NULL;
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
+ loadModConf->pszBindRuleset = NULL;
+ } else {
+ CHKmalloc(loadModConf->pszBindRuleset = ustrdup(cs.pszBindRuleset));
+ }
+ loadModConf->pBindRuleset = NULL;
+finalize_it:
+ free(cs.pszBindRuleset);
+ loadModConf = NULL; /* done loading */
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+ rsRetVal localRet;
+ ruleset_t *pRuleset;
+CODESTARTcheckCnf
+ /* we emulate the standard "ruleset query" code provided by the framework
+ * for *instances* (which we can currently not support due to librelp).
+ */
+ if(pModConf->pszBindRuleset == NULL) {
+ pModConf->pBindRuleset = NULL;
+ } else {
+ localRet = ruleset.GetRuleset(pModConf->pConf, &pRuleset, pModConf->pszBindRuleset);
+ if(localRet == RS_RET_NOT_FOUND) {
+ std_checkRuleset_genErrMsg(pModConf, NULL);
+ }
+ CHKiRet(localRet);
+ pModConf->pBindRuleset = pRuleset;
+ }
+finalize_it:
+ENDcheckCnf
+
+
+BEGINactivateCnfPrePrivDrop
+ instanceConf_t *inst;
+CODESTARTactivateCnfPrePrivDrop
+ runModConf = pModConf;
+ for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
+ addListner(pModConf, inst);
+ }
+ if(pRelpEngine == NULL)
+ ABORT_FINALIZE(RS_RET_NO_RUN);
+finalize_it:
+ENDactivateCnfPrePrivDrop
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
/* This function is called to gather input.
*/
BEGINrunInput
@@ -125,34 +247,14 @@ CODESTARTrunInput
ENDrunInput
-/* initialize and return if will run or not */
BEGINwillRun
CODESTARTwillRun
- /* first apply some config settings */
- //net.PrintAllowedSenders(2); /* TCP */
- if(pRelpEngine == NULL)
- ABORT_FINALIZE(RS_RET_NO_RUN);
-
- /* we need to create the inputName property (only once during our lifetime) */
- CHKiRet(prop.Construct(&pInputName));
- CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imrelp"), sizeof("imrelp") - 1));
- CHKiRet(prop.ConstructFinalize(pInputName));
-finalize_it:
ENDwillRun
BEGINafterRun
CODESTARTafterRun
/* do cleanup here */
-#if 0
- if(net.pAllowedSenders_TCP != NULL) {
- net.clearAllowedSenders(net.pAllowedSenders_TCP);
- net.pAllowedSenders_TCP = NULL;
- }
-#endif
-
- if(pInputName != NULL)
- prop.Destruct(&pInputName);
ENDafterRun
@@ -161,15 +263,23 @@ CODESTARTmodExit
if(pRelpEngine != NULL)
iRet = relpEngineDestruct(&pRelpEngine);
+ /* global variable cleanup */
+ if(pInputName != NULL)
+ prop.Destruct(&pInputName);
+
/* release objects we used */
+ objRelease(ruleset, CORE_COMPONENT);
objRelease(prop, CORE_COMPONENT);
objRelease(net, LM_NET_FILENAME);
+ objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
static rsRetVal
resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
+ free(cs.pszBindRuleset);
+ cs.pszBindRuleset = NULL;
return RS_RET_OK;
}
@@ -178,6 +288,8 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
ENDqueryEtryPt
@@ -188,13 +300,22 @@ CODEmodInit_QueryRegCFSLineHdlr
pRelpEngine = NULL;
/* request objects we use */
CHKiRet(objUse(prop, CORE_COMPONENT));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(net, LM_NET_FILENAME));
+ CHKiRet(objUse(ruleset, CORE_COMPONENT));
/* register config file handlers */
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrelpserverbindruleset", 0, eCmdHdlrGetWord,
+ NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrelpserverrun", 0, eCmdHdlrGetWord,
- addListener, NULL, STD_LOADABLE_MODULE_ID));
+ addInstance, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+
+ /* we need to create the inputName property (only once during our lifetime) */
+ CHKiRet(prop.Construct(&pInputName));
+ CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imrelp"), sizeof("imrelp") - 1));
+ CHKiRet(prop.ConstructFinalize(pInputName));
ENDmodInit
diff --git a/plugins/imsolaris/imsolaris.c b/plugins/imsolaris/imsolaris.c
index ee9ec5c6..8b607a84 100644
--- a/plugins/imsolaris/imsolaris.c
+++ b/plugins/imsolaris/imsolaris.c
@@ -86,6 +86,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imsolaris")
/* defines */
#define PATH_LOG "/dev/log"
@@ -99,6 +100,10 @@ DEFobjCurrIf(prop)
/* config settings */
+struct modConfData_s {
+ EMPTY_STRUCT;
+};
+
static prop_t *pInputName = NULL; /* our inputName currently is always "imuxsock", and this will hold it */
static char *LogName = NULL; /* the log socket name TODO: make configurable! */
@@ -302,6 +307,31 @@ finalize_it:
}
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
+
/* This function is called to gather input. */
BEGINrunInput
CODESTARTrunInput
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index e9961af7..15f9fa72 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -66,6 +66,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imtcp")
/* static data */
DEF_IMOD_STATIC_DATA
@@ -76,24 +77,55 @@ DEFobjCurrIf(netstrm)
DEFobjCurrIf(errmsg)
DEFobjCurrIf(ruleset)
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
+
/* Module static data */
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
static permittedPeers_t *pPermPeersRoot = NULL;
/* config settings */
-static int bKeepAlive = 0; /* support keep-alive packets */
-static int iTCPSessMax = 200; /* max number of sessions */
-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 */
-static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */
-static int bDisableLFDelim = 0; /* disbale standard LF delimiter */
-static int bUseFlowControl = 1; /* use flow control, what means indicate ourselfs a "light delayable" */
-static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */
-static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */
-static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */
-
+static struct configSettings_s {
+ int iTCPSessMax;
+ int iTCPLstnMax;
+ int iStrmDrvrMode;
+ int bKeepAlive;
+ int bEmitMsgOnClose;
+ int iAddtlFrameDelim;
+ int bDisableLFDelim;
+ int bUseFlowControl;
+ uchar *pszStrmDrvrAuthMode;
+ uchar *pszInputName;
+ uchar *pszBindRuleset;
+} cs;
+
+struct instanceConf_s {
+ uchar *pszBindPort; /* port to bind to */
+ uchar *pszBindRuleset; /* name of ruleset to bind to */
+ ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
+ uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
+ struct instanceConf_s *next;
+};
+
+
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ instanceConf_t *root, *tail;
+ int iTCPSessMax; /* max number of sessions */
+ int iTCPLstnMax; /* max number of sessions */
+ int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
+ int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
+ sbool bDisableLFDelim; /* disable standard LF delimiter */
+ sbool bUseFlowControl; /* use flow control, what means indicate ourselfs a "light delayable" */
+ sbool bKeepAlive;
+ sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */
+ uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
+};
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+
+#include "im-helper.h" /* must be included AFTER the type definitions! */
/* callbacks */
/* this shall go into a specific ACL module! */
@@ -166,49 +198,71 @@ finalize_it:
}
-/* accept a new ruleset to bind. Checks if it exists and complains, if not */
-static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
+/* This function is called when a new listener instace shall be added to
+ * the current config object via the legacy config system. It just shuffles
+ * all parameters to the listener in-memory instance.
+ * rgerhards, 2011-05-04
+ */
+static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
{
- ruleset_t *pRuleset;
- rsRetVal localRet;
+ instanceConf_t *inst;
DEFiRet;
- localRet = ruleset.GetRuleset(&pRuleset, pszName);
- if(localRet == RS_RET_NOT_FOUND) {
- errmsg.LogError(0, RS_RET_RULESET_NOT_FOUND, "error: ruleset '%s' not found - ignored", pszName);
+ CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
+
+ CHKmalloc(inst->pszBindPort = ustrdup((pNewVal == NULL || *pNewVal == '\0')
+ ? (uchar*) "10514" : pNewVal));
+ if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
+ inst->pszBindRuleset = NULL;
+ } else {
+ CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset));
+ }
+ if((cs.pszInputName == NULL) || (cs.pszInputName[0] == '\0')) {
+ inst->pszInputName = NULL;
+ } else {
+ CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName));
+ }
+ inst->next = NULL;
+
+ /* node created, let's add to config */
+ if(loadModConf->tail == NULL) {
+ loadModConf->tail = loadModConf->root = inst;
+ } else {
+ loadModConf->tail->next = inst;
+ loadModConf->tail = inst;
}
- CHKiRet(localRet);
- pBindRuleset = pRuleset;
- DBGPRINTF("imtcp current bind ruleset %p: '%s'\n", pRuleset, pszName);
finalize_it:
- free(pszName); /* no longer needed */
+ free(pNewVal);
RETiRet;
}
-static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
+static rsRetVal
+addListner(modConfData_t *modConf, instanceConf_t *inst)
{
DEFiRet;
if(pOurTcpsrv == NULL) {
CHKiRet(tcpsrv.Construct(&pOurTcpsrv));
- CHKiRet(tcpsrv.SetKeepAlive(pOurTcpsrv, bKeepAlive));
- CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax));
- CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, iTCPLstnMax));
+ /* callbacks */
CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost));
CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData));
CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks));
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
- CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode));
- CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, bUseFlowControl));
- CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim));
- CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, bDisableLFDelim));
- CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, bEmitMsgOnClose));
+ /* params */
+ CHKiRet(tcpsrv.SetKeepAlive(pOurTcpsrv, modConf->bKeepAlive));
+ CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax));
+ CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax));
+ CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode));
+ CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, modConf->bUseFlowControl));
+ CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, modConf->iAddtlFrameDelim));
+ CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, modConf->bDisableLFDelim));
+ CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, modConf->bEmitMsgOnClose));
/* now set optional params, but only if they were actually configured */
- if(pszStrmDrvrAuthMode != NULL) {
- CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode));
+ if(modConf->pszStrmDrvrAuthMode != NULL) {
+ CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, modConf->pszStrmDrvrAuthMode));
}
if(pPermPeersRoot != NULL) {
CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
@@ -216,41 +270,112 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
}
/* initialized, now add socket and listener params */
- CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, pBindRuleset));
- CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ?
- UCHAR_CONSTANT("imtcp") : pszInputName));
- tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal);
+ DBGPRINTF("imtcp: trying to add port *:%s\n", inst->pszBindPort);
+ CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, inst->pBindRuleset));
+ CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->pszInputName == NULL ?
+ UCHAR_CONSTANT("imtcp") : inst->pszInputName));
+ tcpsrv.configureTCPListen(pOurTcpsrv, inst->pszBindPort);
finalize_it:
if(iRet != RS_RET_OK) {
- errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet);
- if(pOurTcpsrv != NULL)
- tcpsrv.Destruct(&pOurTcpsrv);
+ errmsg.LogError(0, NO_ERRCODE, "imtcp: error %d trying to add listener", iRet);
}
RETiRet;
}
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init legacy config variables */
+ cs.pszStrmDrvrAuthMode = NULL;
+ resetConfigVariables(NULL, NULL); /* dummy parameters just to fulfill interface def */
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ /* persist module-specific settings from legacy config system */
+ pModConf->iTCPSessMax = cs.iTCPSessMax;
+ pModConf->iTCPLstnMax = cs.iTCPLstnMax;
+ pModConf->iStrmDrvrMode = cs.iStrmDrvrMode;
+ pModConf->bEmitMsgOnClose = cs.bEmitMsgOnClose;
+ pModConf->iAddtlFrameDelim = cs.iAddtlFrameDelim;
+ pModConf->bDisableLFDelim = cs.bDisableLFDelim;
+ pModConf->bUseFlowControl = cs.bUseFlowControl;
+ pModConf->bKeepAlive = cs.bKeepAlive;
+ if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) {
+ loadModConf->pszStrmDrvrAuthMode = NULL;
+ free(cs.pszStrmDrvrAuthMode);
+ } else {
+ loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode;
+ }
+ cs.pszStrmDrvrAuthMode = NULL;
+
+ loadModConf = NULL; /* done loading */
+ENDendCnfLoad
+
+
+/* function to generate error message if framework does not find requested ruleset */
+static inline void
+std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst)
+{
+ errmsg.LogError(0, NO_ERRCODE, "imtcp: ruleset '%s' for port %s not found - "
+ "using default ruleset instead", inst->pszBindRuleset,
+ inst->pszBindPort);
+}
+
+BEGINcheckCnf
+ instanceConf_t *inst;
+CODESTARTcheckCnf
+ for(inst = pModConf->root ; inst != NULL ; inst = inst->next) {
+ std_checkRuleset(pModConf, inst);
+ }
+ if(pModConf->root == NULL) {
+ errmsg.LogError(0, RS_RET_NO_LISTNERS , "imtcp: module loaded, but "
+ "no listeners defined - no input will be gathered");
+ iRet = RS_RET_NO_LISTNERS;
+ }
+ENDcheckCnf
+
+
+BEGINactivateCnfPrePrivDrop
+ instanceConf_t *inst;
+CODESTARTactivateCnfPrePrivDrop
+ runModConf = pModConf;
+ for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
+ addListner(pModConf, inst);
+ }
+ if(pOurTcpsrv == NULL)
+ ABORT_FINALIZE(RS_RET_NO_RUN);
+ CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
+finalize_it:
+ENDactivateCnfPrePrivDrop
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ /* sorry, nothing to do here... */
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
/* This function is called to gather input.
*/
BEGINrunInput
CODESTARTrunInput
- /* TODO: we must be careful to start the listener here. Currently, tcpsrv.c seems to
- * do that in ConstructFinalize
- */
- CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
iRet = tcpsrv.Run(pOurTcpsrv);
-finalize_it:
ENDrunInput
/* initialize and return if will run or not */
BEGINwillRun
CODESTARTwillRun
- /* first apply some config settings */
net.PrintAllowedSenders(2); /* TCP */
- if(pOurTcpsrv == NULL)
- ABORT_FINALIZE(RS_RET_NO_RUN);
-finalize_it:
ENDwillRun
@@ -290,18 +415,18 @@ ENDmodExit
static rsRetVal
resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- iTCPSessMax = 200;
- bKeepAlive = 0;
- iTCPLstnMax = 20;
- iStrmDrvrMode = 0;
- bUseFlowControl = 0;
- bEmitMsgOnClose = 0;
- iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
- bDisableLFDelim = 0;
- free(pszInputName);
- pszInputName = NULL;
- free(pszStrmDrvrAuthMode);
- pszStrmDrvrAuthMode = NULL;
+ cs.iTCPSessMax = 200;
+ cs.iTCPLstnMax = 20;
+ cs.iStrmDrvrMode = 0;
+ cs.bUseFlowControl = 0;
+ cs.bKeepAlive = 0;
+ cs.bEmitMsgOnClose = 0;
+ cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
+ cs.bDisableLFDelim = 0;
+ free(cs.pszInputName);
+ cs.pszInputName = NULL;
+ free(cs.pszStrmDrvrAuthMode);
+ cs.pszStrmDrvrAuthMode = NULL;
return RS_RET_OK;
}
@@ -310,6 +435,8 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
ENDqueryEtryPt
@@ -329,33 +456,33 @@ CODEmodInit_QueryRegCFSLineHdlr
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord,
- addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
+ addInstance, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary,
- NULL, &bKeepAlive, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt,
- NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.iTCPSessMax, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt,
- NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0,
- eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0,
- eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0,
- eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0,
- eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.iTCPLstnMax, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, eCmdHdlrBinary,
+ NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt,
+ NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord,
+ NULL, &cs.pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord,
+ setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,
- NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary,
- NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0,
- eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0,
- eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0,
- eCmdHdlrBinary, NULL, &bUseFlowControl, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bDisableLFDelim, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord,
+ NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, eCmdHdlrGetWord,
+ NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, eCmdHdlrBinary,
+ NULL, &cs.bUseFlowControl, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
- resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/imtemplate/Makefile.am b/plugins/imtemplate/Makefile.am
deleted file mode 100644
index 1825b5bc..00000000
--- a/plugins/imtemplate/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-pkglib_LTLIBRARIES = imtemplate.la
-
-imtemplate_la_SOURCES = imtemplate.c
-imtemplate_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
-imtemplate_la_LDFLAGS = -module -avoid-version
-imtemplate_la_LIBADD =
diff --git a/plugins/imtemplate/imtemplate.c b/plugins/imtemplate/imtemplate.c
deleted file mode 100644
index 0e2cac11..00000000
--- a/plugins/imtemplate/imtemplate.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* imtemplate.c
- *
- * This is NOT a real input module but a (copy)-template to create one. Please
- * do NOT edit this file directly. Rather, copy it, together with the rest of
- * the directory, to a new location ./plugins/im<yourname>, then replace
- * all references to imtemplate in Makefile.am to im<yourname>. Be sure to
- * fix the copyright notices to gain proper credit ;) Any derived version,
- * however, needs to be placed under GPLv3 (see GPLv3 for details). If you
- * do not like that policy, do not use this template or any of the header
- * files. The rsyslog project greatly appreciates module contributions, so
- * please consider contributing your work - even if you may think it only
- * server a single very special purpose. It has turned out that at least some
- * folks have similiar special purposes ;)
- *
- * IMPORTANT
- * The comments in this file are actually the interface specification. I decided
- * not to put it into a separate file as it is much simpler to keep it up to
- * date when it is part of the actual template module.
- *
- * NAMING
- * All input modules shall be named im<something>. While this is not a hard
- * requirement, it helps keeping track of things.
- *
- * Global variables and functions should have a prefix - use as somewhat
- * longer one to prevent conflicts with rsyslog itself and other modules
- * (OK, hopefully I'll have some more precise advise in the future...).
- *
- * INCLUDE MODULE IN THE MAIN MAKE SCRIPT
- * If the module shall be provided as part of rsyslog (or simply as a build aid,
- * you need to add it to the main autoconf files). To do so, you need to edit
- * Makefile.am and configure.ac in the main directory. Search for imtemplate
- * and copy/modify the relevant code for your plugin.
- *
- * DEBUGGING
- * While you develop your code, you may want to add
- * --enable-debug --enable-rtinst
- * to your ./configure settings. These enable extra run-time checks, which cost
- * a lot of performance but can help detect some of the most frequently made
- * bugs. These settings will also provide you with a nice stack dump if something
- * goes really wrong.
- *
- * MORE SAMPLES
- * Remember that rsyslog ships with a number of input modules (./plugins/im*). It
- * is always a good idea to have a look at them before starting your own. imudp
- * may be a good, relatively trivial, sample.
- *
- * --------------------------------------------------------------------------------
- *
- * This template was cretead on 2008-02-01 by Rainer Gerhards.
- *
- * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h" /* this is for autotools and always must be the first include */
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#include <pthread.h> /* do NOT remove: will soon be done by the module generation macros */
-#include "rsyslog.h" /* error codes etc... */
-#include "cfsysline.h" /* access to config file objects */
-#include "module-template.h" /* generic module interface code - very important, read it! */
-#include "srUtils.h" /* some utility functions */
-#include "debug.h" /* some debug helper functions */
-
-MODULE_TYPE_INPUT /* must be present for input modules, do not remove */
-MODULE_TYPE_NOKEEP
-
-/* defines */
-
-/* Module static data */
-DEF_IMOD_STATIC_DATA /* must be present, starts static data */
-
-/* Here, define whatever static data is needed. Is it suggested that static variables only are
- * used (not externally visible). If you need externally visible variables, make sure you use a
- * prefix in order not to conflict with other modules or rsyslogd itself (also see comment
- * at file header).
- */
-/* static int imtemplateWhateverVar = 0; */
-
-/* config settings */
-
-
-/* You may add any functions that you feel are useful for your needs. No specific restrictions
- * apply, but we suggest that you use the "iRet" call order, which enables you to use debug
- * support for your own functions and which also makes it easy to communicate exceptions back
- * to the upstream caller (rsyslog framework, for example.
- *
- * The function below is a sample of how one of your functions may look like. Again, the sample
- * below is *not* needed to be present in order to meet the interface requirements.
- *
- * Be sure to use static functions (suggested) or prefixes to prevent name conflicts -- see file
- * header for more information.
- */
-static rsRetVal /* rsRetVal is our generic error-reporting return type */
-imtemplateMyFunc(int iMyParam)
-{
- DEFiRet; /* define iRet, the return code and other plumbing */
- /* define your local variables here */
-
- /* code whatever you need to code here. The "iRet" system can be helpful:
- *
- * CHKiRet(function(param1, param2, ...));
- * calls a function and checks if it returns RS_RET_OK. If so, work
- * proceeds. If some other code is returned, the function is aborted
- * and control transferred to finalize_it (which you need to define)
- *
- * CHKiRet_Hdlr(function(param1, param2, ...))
- * much like CHKiRet, but allows you to specify your own code that is
- * executed if the function does not return RS_RET_OK, e.g.:
- * CHKiRet_Hdlr(function(a, b)) {
- * ... some error handling here ...
- * }
- * control is not transferred to finalize_it, except if you use one
- * of the relevant macros (described below)
- *
- * FINALIZE
- * immediately transfers control to finalize_it, using the current
- * value of iRet, e.g.
- * if(bDone)
- * FINALIZE;
- *
- * ABORT_FINALIZE(retcode)
- * just like FINALIZE, except that iRet is set to the provided error
- * code before control is transferred, e.g.
- * if((ptr = MALLOC(20)) == NULL)
- * ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- *
- * In order for all this to work, you need to define finalize_it, e.g.
- *
- * finalize_it:
- * RETiRet;
- *
- * RETiRet does some housekeeping and then does a "return iRet" to transfer
- * control back to the caller. There shall only be one function exit and
- * it shall be via RETiRet, preferrably at the end of the function code.
- *
- */
-
-finalize_it:
- /* clean up anything that needs to be cleaned up if processing did not
- * go well, for example:
- */
- if(iRet != RS_RET_OK) {
- /* cleanup, e.g.
- * free(somePtr);
- */
- }
-
- RETiRet;
-}
-
-
-/* This function is the cancel cleanup handler. It is called when rsyslog decides the
- * module must be stopped, what most probably happens during shutdown of rsyslogd. When
- * this function is called, the runInput() function (below) is already terminated - somewhere
- * in the middle of what it was doing. The cancel cleanup handler below should take
- * care of any locked mutexes and such, things that really need to be cleaned up
- * before processing continues. In general, many plugins do not need to provide
- * any code at all here.
- *
- * IMPORTANT: the calling interface of this function can NOT be modified. It actually is
- * called by pthreads. The provided argument is currently not being used.
- */
-/* ------------------------------------------------------------------------------------------ *
- * DO NOT TOUCH the following code - it will soon be part of the module generation macros! */
-static void
-inputModuleCleanup(void *arg)
-{
- BEGINfunc
-/* END no-touch zone *
- * ------------------------------------------------------------------------------------------ */
-
-
-
- /* your code here */
-
-
-
-/* ------------------------------------------------------------------------------------------ *
- * DO NOT TOUCH the following code - it will soon be part of the module generation macros! */
- ENDfunc
-}
-/* END no-touch zone *
- * ------------------------------------------------------------------------------------------ */
-
-
-/* This function is called by the framework to gather the input. The module stays
- * most of its lifetime inside this function. It MUST NEVER exit this function. Doing
- * so would end module processing and rsyslog would NOT reschedule the module. If
- * you exit from this function, you violate the interface specification!
- *
- * So how is it terminated? When it is time to terminate, rsyslog actually cancels
- * the threads. This may sound scary, but is not. There is a cancel cleanup handler
- * defined (the function directly above). See comments there for specifics.
- *
- * runInput is always called on a single thread. If the module neees multiple threads,
- * it is free to create them. HOWEVER, it must make sure that any threads created
- * are killed and joined in the cancel cleanup handler.
- */
-BEGINrunInput
- /* define any local variables you need here */
-CODESTARTrunInput
- /* ------------------------------------------------------------------------------------------ *
- * DO NOT TOUCH the following code - it will soon be part of the module generation macros! */
- pthread_cleanup_push(inputModuleCleanup, NULL);
- while(1) { /* endless loop - do NOT break; out of it! */
- /* END no-touch zone *
- * ------------------------------------------------------------------------------------------ */
-
- /* your code here */
-
- /* All rsyslog objects (see other modules, e.g. msg.c) are available
- * to your here. Some useful things are:
- *
- * errmsg.LogError(NO_ERRCODE, format-string, ... params ...);
- * logs an error message as syslogd, just as printf, e.g.
- * errmsg.LogError(NO_ERRCODE, "Error %d occured during %s", 1, "test");
- *
- * To submit the message to the queue engine, we must create the message
- * object and fill it with data. If it contains a syslog message that must
- * be parsed, we can add a flag that requests parsing. Otherwise, we must
- * fill the properties ourselves. That is appropriate if the message
- * does not need to be parsed, for example when reading text (log) files. In that way,
- * we can set the message properties as of our liking. This is how it works:
- *
- msg_t *pMsg;
- CHKiRet(msgConstruct(&pMsg));
- MsgSetRawMsg(pMsg, msg);
- MsgSetHOSTNAME(pMsg, LocalHostName);
- MsgSetTAG(pMsg, "rsyslogd:");
- pMsg->iFacility = LOG_FAC(pri);
- pMsg->iSeverity = LOG_PRI(pri);
- flags |= INTERNAL_MSG;
- logmsg(pMsg, flags); / * some time, CHKiRet() will work here, too [today NOT!] * /
- *
- * NOTE: for up-to-date usage samples, see the other provided input modules.
- * A good starting point is probably imuxsock.
- *
- * This example probably does not set all message properties (but the ones
- * that are of practical importance). If you need all, check msg.h. Use
- * method access functions whereever possible, unfortunately not all structure
- * members are currently exposed in that clean way - so you sometimes need
- * to access them directly (it goes without saying that we will fix that
- * over time ;)).
- */
-
- /* ------------------------------------------------------------------------------------------ *
- * DO NOT TOUCH the following code - it will soon be part of the module generation macros! */
- }
- /*NOTREACHED*/
-
- pthread_cleanup_pop(0); /* just for completeness, but never called... */
- RETiRet; /* use it to make sure the housekeeping is done! */
-ENDrunInput
- /* END no-touch zone *
- * ------------------------------------------------------------------------------------------ */
-
-
-/* The function is called by rsyslog before runInput() is called. It is a last chance
- * to set up anything specific. Most importantly, it can be used to tell rsyslog if the
- * input shall run or not. The idea is that if some config settings (or similiar things)
- * are not OK, the input can tell rsyslog it will not execute. To do so, return
- * RS_RET_NO_RUN or a specific error code. If RS_RET_OK is returned, rsyslog will
- * proceed and call the runInput() entry point. If you do not return anything
- * specific, RS_RET_OK is automatically returned (as in all functions).
- */
-BEGINwillRun
- /* place any variables needed here */
-CODESTARTwillRun
-
- /* ... your code here ... */
-
- /* Just to give you an idea, here are some samples (from the actual imudp module:
- *
- if(udpLstnSocks == NULL)
- ABORT_FINALIZE(RS_RET_NO_RUN);
-
- if((pRcvBuf = MALLOC(glbl.GetMaxLine * sizeof(char))) == NULL) {
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- }
- *
- */
-finalize_it:
-ENDwillRun
-
-
-/* This function is called by the framework after runInput() has been terminated. It
- * shall free any resources and prepare the module for unload.
- *
- * So it is important that runInput() keeps track of what needs to be cleaned up.
- * Objects to think about are files (must be closed), network connections, threads (must
- * be stopped and joined) and memory (must be freed). Of course, there are a myriad
- * of other things, so use your own judgement what you need to do.
- *
- * Another important chore of this function is to persist whatever state the module
- * needs to persist. Unfortunately, there is currently no standard way of doing that.
- * Future version of the module interface will probably support it, but that doesn't
- * help you right at the moment. In general, it is suggested that anything that needs
- * to be persisted is saved in a file, whose name and location is passed in by a
- * module-specific config directive.
- */
-BEGINafterRun
- /* place any variables needed here */
-CODESTARTafterRun
-
- /* ... do cleanup here ... */
-
- /* if you have a string config variable, remember to free its content:
- *
- if(pszStr != NULL) {
- free(pszStr);
- pszStr = NULL;
- }
- */
-ENDafterRun
-
-
-/* The following entry points are defined in module-template.h.
- * In general, they need to be present, but you do NOT need to provide
- * any code here.
- */
-BEGINmodExit
-CODESTARTmodExit
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_IMOD_QUERIES
-ENDqueryEtryPt
-
-
-/* The following function shall reset all configuration variables to their
- * default values. The code provided in modInit() below registers it to be
- * called on "$ResetConfigVariables". You may also call it from other places,
- * but in general this is not necessary. Once runInput() has been called, this
- * function here is never again called.
- */
-static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
-{
- DEFiRet;
-
- /* if you have string variables in you config settings, you need to do this:
- if(pszStr != NULL) {
- free(pszStr);
- pszStr = NULL;
- }
- * Note that it is vitally important that the pointer is set to NULL, because
- * otherwise the framework handler will try to free it a second time when
- * a new value is set!
- */
-
-
- /* ... your code here ... */
-
-
- RETiRet;
-}
-
-
-/* modInit() is called once the module is loaded. It must perform all module-wide
- * initialization tasks. There are also a number of housekeeping tasks that the
- * framework requires. These are handled by the macros. Please note that the
- * complexity of processing is depending on the actual module. However, only
- * thing absolutely necessary should be done here. Actual app-level processing
- * is to be performed in runInput(). A good sample of what to do here may be to
- * set some variable defaults. The most important thing probably is registration
- * of config command handlers.
- */
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = 1; /* interface spec version this module is written to (currently always 1) */
-CODEmodInit_QueryRegCFSLineHdlr
- /* register config file handlers
- * For details, see cfsysline.c/.h. The config file is automatically handled. In general,
- * a pointer to a variable receiving the value and the config directive is to be supplied.
- * A custom function pointer can only be provided, which then is called when the config
- * directive appears. Limit this to cases where it is absolutely necessary. The
- * STD_LOADABLE_MODULE_ID is a value that identifies the module. It is use to automatically
- * unregister the module's config file handlers upon module unload. Do NOT use any other
- * value for this parameter! Available Syntaxes (supported types) can be seen in cfsysline.h,
- * the ecslCmdHdrlType enum has all that are currently defined.
- *
- * Config file directives should always be along the lines of
- *
- * $Input<moduleobject>ObjObjName
- *
- * An example would be $InputImtemplateRetriesMax. This is currently not enforced,
- * but when we get to our new config file format and reader, this becomes quite
- * important.
- *
- * Please note that config directives must be provided in lower case. The engine
- * makes the mapping (what currently means case-insensitive comparison). The dollar
- * sign is NOT part of the directive and thus not specified.
- *
- * Some samples:
- *
- * A hypothetical integer variable:
- * CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputimtemplatemessagenumber", 0, eCmdHdlrInt,
- NULL, &intVariable, STD_LOADABLE_MODULE_ID));
- *
- * and a hypothetical string variable:
- * CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputimtemplatemessagetext", 0, eCmdHdlrGetWord,
- * NULL, &pszBindAddr, STD_LOADABLE_MODULE_ID));
- */
-
- /* whenever config variables exist, they should be resettable via $ResetConfigVariables.
- * The following line adds our handler for that. Note that if you do not have any config
- * variables at all (unlikely, I think...), you can remove this handler.
- */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
- resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
-
- /* ... do whatever else you need to do, but keep it brief ... */
-
-ENDmodInit
-/*
- * vim:set ai:
- */
diff --git a/plugins/imttcp/Makefile.am b/plugins/imttcp/Makefile.am
new file mode 100644
index 00000000..9b09b4bf
--- /dev/null
+++ b/plugins/imttcp/Makefile.am
@@ -0,0 +1,6 @@
+pkglib_LTLIBRARIES = imttcp.la
+
+imttcp_la_SOURCES = imttcp.c
+imttcp_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
+imttcp_la_LDFLAGS = -module -avoid-version
+imttcp_la_LIBADD =
diff --git a/plugins/imttcp/imttcp.c b/plugins/imttcp/imttcp.c
new file mode 100644
index 00000000..5ed714fa
--- /dev/null
+++ b/plugins/imttcp/imttcp.c
@@ -0,0 +1,1151 @@
+/* imttcp.c
+ * This is an experimental plain tcp input module which follows the
+ * multiple thread paradigm.
+ *
+ * WARNING
+ * This module is unfinished. It seems to work, but there also seems to be a problem
+ * if it is under large stress (e.g. tcpflood with more than 500 to 1000 concurrent
+ * connections). I quickly put together this module after I worked on a larger paper
+ * and read [1], which claims that using massively threaded applications is
+ * preferrable to an event driven approach. So I put this to test, especially as
+ * that would also lead to a much simpler programming paradigm. Unfortuantely, the
+ * performance results are devastive: while there is a very slight speedup with
+ * a low connection number (close to the number of cores on the system), there
+ * is a dramatic negative speedup if running with many threads. Even at only 50
+ * connections, rsyslog is dramatically slower (80 seconds for the same workload
+ * which was processed in 60 seconds with traditional imtcp or when running on
+ * a single connection). At 1,000 connections, the run was *extremely* slow. So
+ * this is definitely a dead-end. To be honest, Behren, condit and Brewer claim
+ * that the problem lies in the current implementation of thread libraries.
+ * As one cure, they propose user-level threads. However, as far as I could
+ * find out, User-Level threads seem not to be much faster under Linux than
+ * Kernel-Level threads (which I used in my approach).
+ *
+ * Even more convincing is, from the rsyslog PoV, that there are clear reasons
+ * why the highly threaded input must be slower:
+ * o batch sizes are smaller, leading to much more overhead
+ * o many more context switches are needed to switch between the various
+ * i/o handlers
+ * o more OS API calls are required because in this model we get more
+ * frequent wakeups on new incoming data, so we have less data available
+ * to read at each instant
+ * o more lock contention because many more threads compete on the
+ * main queue mutex
+ *
+ * All in all, this means that the approach is not the right one, at least
+ * not for rsyslog (it may work better if the input can be processed
+ * totally independent, but I have note evaluated this). So I will look into
+ * an enhanced event-based model with a small set of input workers pulling
+ * off data (I assume this is useful for e.g. TLS, as TLS transport is much
+ * more computebound than other inputs, and this computation becomes a
+ * limiting factor for the overall processing speed under some
+ * circumstances - see [2]).
+ *
+ * For obvious reasons, I will not try to finish imttcp. However, I have
+ * decided to leave it included in the source tree, so that
+ * a) someone else can build on it, if he sees value in that
+ * b) I may use it for some other tests in the future
+ *
+ * But if you intend to actually use this module unmodified, be prepared
+ * for problems.
+ *
+ * [1] R. Von Behren, J. Condit, and E. Brewer. Why events are a bad idea
+ * (for high-concurrency servers). In Proceedings of the 9th conference on Hot
+ * Topics in Operating Systems-Volume 9, page 4. USENIX Association, 2003.
+ *
+ * [2] http://kb.monitorware.com/tls-limited-17800-messages-per-second-t10598.html
+ *
+ * File begun on 2011-01-24 by RGerhards
+ *
+ * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#if !defined(HAVE_EPOLL_CREATE)
+# error imttcp requires OS support for epoll - can not build
+ /* imttcp gains speed by using modern Linux capabilities. As such,
+ * it can only be build on platforms supporting the epoll API.
+ */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include "rsyslog.h"
+#include "cfsysline.h"
+#include "prop.h"
+#include "dirty.h"
+#include "module-template.h"
+#include "unicode-helper.h"
+#include "glbl.h"
+#include "prop.h"
+#include "errmsg.h"
+#include "srUtils.h"
+#include "datetime.h"
+#include "ruleset.h"
+#include "msg.h"
+#include "net.h" /* for permittedPeers, may be removed when this is removed */
+
+/* the define is from tcpsrv.h, we need to find a new (but easier!!!) abstraction layer some time ... */
+#define TCPSRV_NO_ADDTL_DELIMITER -1 /* specifies that no additional delimiter is to be used in TCP framing */
+
+
+MODULE_TYPE_INPUT
+MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imttcp")
+
+/* static data */
+DEF_IMOD_STATIC_DATA
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(net)
+DEFobjCurrIf(prop)
+DEFobjCurrIf(datetime)
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(ruleset)
+
+
+
+/* config settings */
+struct modConfData_s {
+ EMPTY_STRUCT;
+};
+
+typedef struct configSettings_s {
+ int bEmitMsgOnClose; /* emit an informational message on close by remote peer */
+ 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? */
+ ruleset_t *pRuleset; /* ruleset to bind listener to (use system default if unspecified) */
+} configSettings_t;
+
+static configSettings_t cs;
+
+/* data elements describing our running config */
+typedef struct ttcpsrv_s ttcpsrv_t;
+typedef struct ttcplstn_s ttcplstn_t;
+typedef struct ttcpsess_s ttcpsess_t;
+typedef struct epolld_s epolld_t;
+
+/* the ttcp server (listener) object
+ * Note that the object contains support for forming a linked list
+ * of them. It does not make sense to do this seperately.
+ */
+struct ttcpsrv_s {
+ ttcpsrv_t *pNext; /* linked list maintenance */
+ uchar *port; /* Port to listen to */
+ uchar *lstnIP; /* which IP we should listen on? */
+ int bEmitMsgOnClose;
+ int iAddtlFrameDelim;
+ uchar *pszInputName;
+ prop_t *pInputName; /* InputName in (fast to process) property format */
+ ruleset_t *pRuleset;
+ ttcplstn_t *pLstn; /* root of our listeners */
+ ttcpsess_t *pSess; /* root of our sessions */
+ pthread_mutex_t mutSess; /* mutex for session list updates */
+};
+
+/* the ttcp session object. Describes a single active session.
+ * includes support for doubly-linked list.
+ */
+struct ttcpsess_s {
+ ttcpsrv_t *pSrv; /* our server */
+ ttcpsess_t *prev, *next;
+ int sock;
+ pthread_t tid;
+//--- 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? */
+ enum {
+ eAtStrtFram,
+ eInOctetCnt,
+ eInMsg
+ } inputState; /* our current state */
+ int iOctetsRemain; /* Number of Octets remaining in message */
+ TCPFRAMINGMODE eFraming;
+ uchar *pMsg; /* message (fragment) received */
+ prop_t *peerName; /* host name we received messages from */
+ prop_t *peerIP;
+//--- END from tcps_sess.h
+};
+
+
+/* the ttcp listener object. Describes a single active listener.
+ */
+struct ttcplstn_s {
+ ttcpsrv_t *pSrv; /* our server */
+ ttcplstn_t *prev, *next;
+ int sock;
+ pthread_t tid; /* ID of our listener thread */
+};
+
+
+/* type of object stored in epoll descriptor */
+typedef enum {
+ epolld_lstn,
+ epolld_sess
+} epolld_type_t;
+
+/* an epoll descriptor. contains all information necessary to process
+ * the result of epoll.
+ */
+struct epolld_s {
+ epolld_type_t typ;
+ void *ptr;
+ struct epoll_event ev;
+};
+
+
+/* global data */
+static ttcpsrv_t *pSrvRoot = NULL;
+static int iMaxLine; /* maximum size of a single message */
+pthread_attr_t sessThrdAttr; /* Attribute for session threads; read only after startup */
+
+/* forward definitions */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
+static rsRetVal addLstn(ttcpsrv_t *pSrv, int sock);
+static void * sessThrd(void *arg);
+
+
+/* some simple constructors/destructors */
+static void
+destructSess(ttcpsess_t *pSess)
+{
+ free(pSess->pMsg);
+ prop.Destruct(&pSess->peerName);
+ prop.Destruct(&pSess->peerIP);
+ /* TODO: make these inits compile-time switch depending: */
+ pSess->pMsg = NULL;
+ free(pSess);
+}
+
+static void
+destructSrv(ttcpsrv_t *pSrv)
+{
+ prop.Destruct(&pSrv->pInputName);
+ free(pSrv->port);
+ free(pSrv);
+}
+
+
+/* common initialisation for new threads */
+static inline void
+initThrd(void)
+{
+ /* block all signals */
+ sigset_t sigSet;
+ sigfillset(&sigSet);
+ pthread_sigmask(SIG_BLOCK, &sigSet, NULL);
+
+ /* but ignore SIGTTN, which we (ab)use to signal the thread to shutdown -- rgerhards, 2009-07-20 */
+ sigemptyset(&sigSet);
+ sigaddset(&sigSet, SIGTTIN);
+ pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL);
+
+}
+
+
+
+/****************************************** TCP SUPPORT FUNCTIONS ***********************************/
+/* We may later think about moving this into a helper library again. But the whole point
+ * so far was to keep everything related close togehter. -- rgerhards, 2010-08-10
+ */
+
+
+/* Start up a server. That means all of its listeners are created.
+ * Does NOT yet accept/process any incoming data (but binds ports). Hint: this
+ * code is to be executed before dropping privileges.
+ */
+static rsRetVal
+createSrv(ttcpsrv_t *pSrv)
+{
+ DEFiRet;
+ int error, maxs, on = 1;
+ int sock = -1;
+ int numSocks;
+ struct addrinfo hints, *res = NULL, *r;
+ uchar *lstnIP;
+
+ lstnIP = pSrv->lstnIP == NULL ? UCHAR_CONSTANT("") : pSrv->lstnIP;
+
+ DBGPRINTF("imttcp creating listen socket on server '%s', port %s\n", lstnIP, pSrv->port);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = glbl.GetDefPFFamily();
+ hints.ai_socktype = SOCK_STREAM;
+
+ error = getaddrinfo((char*)pSrv->lstnIP, (char*) pSrv->port, &hints, &res);
+ if(error) {
+ DBGPRINTF("error %d querying server '%s', port '%s'\n", error, pSrv->lstnIP, pSrv->port);
+ ABORT_FINALIZE(RS_RET_INVALID_PORT);
+ }
+
+ /* Count max number of sockets we may open */
+ for(maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++)
+ /* EMPTY */;
+
+ numSocks = 0; /* num of sockets counter at start of array */
+ for(r = res; r != NULL ; r = r->ai_next) {
+ sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+ if(sock < 0) {
+ if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT))
+ DBGPRINTF("error %d creating tcp listen socket", errno);
+ /* it is debatable if PF_INET with EAFNOSUPPORT should
+ * also be ignored...
+ */
+ continue;
+ }
+
+#ifdef IPV6_V6ONLY
+ if(r->ai_family == AF_INET6) {
+ int iOn = 1;
+ if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ (char *)&iOn, sizeof (iOn)) < 0) {
+ close(sock);
+ sock = -1;
+ continue;
+ }
+ }
+#endif
+ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0 ) {
+ DBGPRINTF("error %d setting tcp socket option\n", errno);
+ close(sock);
+ sock = -1;
+ continue;
+ }
+
+ /* We need to enable BSD compatibility. Otherwise an attacker
+ * could flood our log files by sending us tons of ICMP errors.
+ */
+#ifndef BSD
+ if(net.should_use_so_bsdcompat()) {
+ if (setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
+ (char *) &on, sizeof(on)) < 0) {
+ errmsg.LogError(errno, NO_ERRCODE, "TCP setsockopt(BSDCOMPAT)");
+ close(sock);
+ sock = -1;
+ continue;
+ }
+ }
+#endif
+
+ if( (bind(sock, r->ai_addr, r->ai_addrlen) < 0)
+#ifndef IPV6_V6ONLY
+ && (errno != EADDRINUSE)
+#endif
+ ) {
+ /* TODO: check if *we* bound the socket - else we *have* an error! */
+ DBGPRINTF("error %d while binding tcp socket", errno);
+ close(sock);
+ sock = -1;
+ continue;
+ }
+
+ if(listen(sock, 511) < 0) {
+ DBGPRINTF("tcp listen error %d, suspending\n", errno);
+ close(sock);
+ sock = -1;
+ continue;
+ }
+
+ /* if we reach this point, we were able to obtain a valid socket, so we can
+ * create our listener object. -- rgerhards, 2010-08-10
+ */
+ CHKiRet(addLstn(pSrv, sock));
+ ++numSocks;
+ }
+
+ if(numSocks != maxs)
+ DBGPRINTF("We could initialize %d TCP listen sockets out of %d we received "
+ "- this may or may not be an error indication.\n", numSocks, maxs);
+
+ if(numSocks == 0) {
+ DBGPRINTF("No TCP listen sockets could successfully be initialized");
+ ABORT_FINALIZE(RS_RET_COULD_NOT_BIND);
+ }
+
+finalize_it:
+ if(res != NULL)
+ freeaddrinfo(res);
+
+ if(iRet != RS_RET_OK) {
+ if(sock != -1)
+ close(sock);
+ }
+
+ RETiRet;
+}
+
+
+/* Set pRemHost based on the address provided. This is to be called upon accept()ing
+ * a connection request. It must be provided by the socket we received the
+ * message on as well as a NI_MAXHOST size large character buffer for the FQDN.
+ * Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats)
+ * for some explanation of the code found below. If we detect a malicious
+ * hostname, we return RS_RET_MALICIOUS_HNAME and let the caller decide
+ * on how to deal with that.
+ * rgerhards, 2008-03-31
+ */
+static rsRetVal
+getPeerNames(prop_t **peerName, prop_t **peerIP, struct sockaddr *pAddr)
+{
+ int error;
+ uchar szIP[NI_MAXHOST] = "";
+ uchar szHname[NI_MAXHOST] = "";
+ struct addrinfo hints, *res;
+
+ DEFiRet;
+
+ error = getnameinfo(pAddr, SALEN(pAddr), (char*)szIP, sizeof(szIP), NULL, 0, NI_NUMERICHOST);
+
+ if(error) {
+ DBGPRINTF("Malformed from address %s\n", gai_strerror(error));
+ strcpy((char*)szHname, "???");
+ strcpy((char*)szIP, "???");
+ ABORT_FINALIZE(RS_RET_INVALID_HNAME);
+ }
+
+ if(!glbl.GetDisableDNS()) {
+ error = getnameinfo(pAddr, SALEN(pAddr), (char*)szHname, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
+ if(error == 0) {
+ memset (&hints, 0, sizeof (struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_socktype = SOCK_STREAM;
+ /* we now do a lookup once again. This one should fail,
+ * because we should not have obtained a non-numeric address. If
+ * we got a numeric one, someone messed with DNS!
+ */
+ if(getaddrinfo((char*)szHname, NULL, &hints, &res) == 0) {
+ freeaddrinfo (res);
+ /* OK, we know we have evil, so let's indicate this to our caller */
+ snprintf((char*)szHname, NI_MAXHOST, "[MALICIOUS:IP=%s]", szIP);
+ DBGPRINTF("Malicious PTR record, IP = \"%s\" HOST = \"%s\"", szIP, szHname);
+ iRet = RS_RET_MALICIOUS_HNAME;
+ }
+ } else {
+ strcpy((char*)szHname, (char*)szIP);
+ }
+ } else {
+ strcpy((char*)szHname, (char*)szIP);
+ }
+
+ /* We now have the names, so now let's allocate memory and store them permanently. */
+ CHKiRet(prop.Construct(peerName));
+ CHKiRet(prop.SetString(*peerName, szHname, ustrlen(szHname)));
+ CHKiRet(prop.ConstructFinalize(*peerName));
+ CHKiRet(prop.Construct(peerIP));
+ CHKiRet(prop.SetString(*peerIP, szIP, ustrlen(szIP)));
+ CHKiRet(prop.ConstructFinalize(*peerIP));
+
+finalize_it:
+ RETiRet;
+}
+
+
+
+/* accept an incoming connection request
+ * rgerhards, 2008-04-22
+ */
+static rsRetVal
+AcceptConnReq(int sock, int *newSock, prop_t **peerName, prop_t **peerIP)
+{
+ struct sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ int iNewSock = -1;
+
+ DEFiRet;
+
+ iNewSock = accept(sock, (struct sockaddr*) &addr, &addrlen);
+ if(iNewSock < 0) {
+ if(errno == EAGAIN || errno == EWOULDBLOCK)
+ ABORT_FINALIZE(RS_RET_NO_MORE_DATA);
+ ABORT_FINALIZE(RS_RET_ACCEPT_ERR);
+ }
+
+ CHKiRet(getPeerNames(peerName, peerIP, (struct sockaddr*) &addr));
+
+ *newSock = iNewSock;
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ /* the close may be redundant, but that doesn't hurt... */
+ if(iNewSock != -1)
+ close(iNewSock);
+ }
+
+ RETiRet;
+}
+
+
+/* This is a helper for submitting the message to the rsyslog core.
+ * It does some common processing, including resetting the various
+ * state variables to a "processed" state.
+ * Note that this function is also called if we had a buffer overflow
+ * due to a too-long message. So far, there is no indication this
+ * happened and it may be worth thinking about different handling
+ * of this case (what obviously would require a change to this
+ * function or some related code).
+ * rgerhards, 2009-04-23
+ * EXTRACT from tcps_sess.c
+ */
+static rsRetVal
+doSubmitMsg(ttcpsess_t *pThis, struct syslogTime *stTime, time_t ttGenTime, multi_submit_t *pMultiSub)
+{
+ msg_t *pMsg;
+ DEFiRet;
+
+ if(pThis->iMsg == 0) {
+ DBGPRINTF("discarding zero-sized message\n");
+ FINALIZE;
+ }
+
+ /* we now create our own message object and submit it to the queue */
+ CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime));
+ MsgSetRawMsg(pMsg, (char*)pThis->pMsg, pThis->iMsg);
+ MsgSetInputName(pMsg, pThis->pSrv->pInputName);
+ MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
+ pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME;
+ MsgSetRcvFrom(pMsg, pThis->peerName);
+ CHKiRet(MsgSetRcvFromIP(pMsg, pThis->peerIP));
+ MsgSetRuleset(pMsg, pThis->pSrv->pRuleset);
+
+ if(pMultiSub == NULL) {
+ CHKiRet(submitMsg(pMsg));
+ } else {
+ pMultiSub->ppMsgs[pMultiSub->nElem++] = pMsg;
+ if(pMultiSub->nElem == pMultiSub->maxElem)
+ CHKiRet(multiSubmitMsg(pMultiSub));
+ }
+
+
+finalize_it:
+ /* reset status variables */
+ pThis->bAtStrtOfFram = 1;
+ pThis->iMsg = 0;
+
+ RETiRet;
+}
+
+
+/* process the data received. As TCP is stream based, we need to process the
+ * data inside a state machine. The actual data received is passed in byte-by-byte
+ * from DataRcvd, and this function here compiles messages from them and submits
+ * the end result to the queue. Introducing this function fixes a long-term bug ;)
+ * rgerhards, 2008-03-14
+ * EXTRACT from tcps_sess.c
+ */
+static inline rsRetVal
+processDataRcvd(ttcpsess_t *pThis, char c, struct syslogTime *stTime, time_t ttGenTime, multi_submit_t *pMultiSub)
+{
+ DEFiRet;
+
+ if(pThis->inputState == eAtStrtFram) {
+ if(isdigit((int) c)) {
+ pThis->inputState = eInOctetCnt;
+ pThis->iOctetsRemain = 0;
+ pThis->eFraming = TCP_FRAMING_OCTET_COUNTING;
+ } else {
+ pThis->inputState = eInMsg;
+ pThis->eFraming = TCP_FRAMING_OCTET_STUFFING;
+ }
+ }
+
+ if(pThis->inputState == eInOctetCnt) {
+ if(isdigit(c)) {
+ pThis->iOctetsRemain = pThis->iOctetsRemain * 10 + c - '0';
+ } else { /* done with the octet count, so this must be the SP terminator */
+ DBGPRINTF("TCP Message with octet-counter, size %d.\n", pThis->iOctetsRemain);
+ if(c != ' ') {
+ errmsg.LogError(0, NO_ERRCODE, "Framing Error in received TCP message: "
+ "delimiter is not SP but has ASCII value %d.\n", c);
+ }
+ if(pThis->iOctetsRemain < 1) {
+ /* TODO: handle the case where the octet count is 0! */
+ DBGPRINTF("Framing Error: invalid octet count\n");
+ errmsg.LogError(0, NO_ERRCODE, "Framing Error in received TCP message: "
+ "invalid octet count %d.\n", pThis->iOctetsRemain);
+ } else if(pThis->iOctetsRemain > iMaxLine) {
+ /* while we can not do anything against it, we can at least log an indication
+ * that something went wrong) -- rgerhards, 2008-03-14
+ */
+ DBGPRINTF("truncating message with %d octets - max msg size is %d\n",
+ pThis->iOctetsRemain, iMaxLine);
+ errmsg.LogError(0, NO_ERRCODE, "received oversize message: size is %d bytes, "
+ "max msg size is %d, truncating...\n", pThis->iOctetsRemain, iMaxLine);
+ }
+ pThis->inputState = eInMsg;
+ }
+ } else {
+ assert(pThis->inputState == eInMsg);
+ if(pThis->iMsg >= iMaxLine) {
+ /* emergency, we now need to flush, no matter if we are at end of message or not... */
+ DBGPRINTF("error: message received is larger than max msg size, we split it\n");
+ doSubmitMsg(pThis, stTime, ttGenTime, pMultiSub);
+ /* we might think if it is better to ignore the rest of the
+ * message than to treat it as a new one. Maybe this is a good
+ * candidate for a configuration parameter...
+ * rgerhards, 2006-12-04
+ */
+ }
+
+ if(( (c == '\n')
+ || ((pThis->pSrv->iAddtlFrameDelim != TCPSRV_NO_ADDTL_DELIMITER) && (c == pThis->pSrv->iAddtlFrameDelim))
+ ) && pThis->eFraming == TCP_FRAMING_OCTET_STUFFING) { /* record delimiter? */
+ doSubmitMsg(pThis, stTime, ttGenTime, pMultiSub);
+ pThis->inputState = eAtStrtFram;
+ } else {
+ /* IMPORTANT: here we copy the actual frame content to the message - for BOTH framing modes!
+ * If we have a message that is larger than the max msg size, we truncate it. This is the best
+ * we can do in light of what the engine supports. -- rgerhards, 2008-03-14
+ */
+ if(pThis->iMsg < iMaxLine) {
+ *(pThis->pMsg + pThis->iMsg++) = c;
+ }
+ }
+
+ if(pThis->eFraming == TCP_FRAMING_OCTET_COUNTING) {
+ /* do we need to find end-of-frame via octet counting? */
+ pThis->iOctetsRemain--;
+ if(pThis->iOctetsRemain < 1) {
+ /* we have end of frame! */
+ doSubmitMsg(pThis, stTime, ttGenTime, pMultiSub);
+ pThis->inputState = eAtStrtFram;
+ }
+ }
+ }
+
+ RETiRet;
+}
+
+
+/* Processes the data received via a TCP session. If there
+ * is no other way to handle it, data is discarded.
+ * Input parameter data is the data received, iLen is its
+ * len as returned from recv(). iLen must be 1 or more (that
+ * is errors must be handled by caller!). iTCPSess must be
+ * the index of the TCP session that received the data.
+ * rgerhards 2005-07-04
+ * And another change while generalizing. We now return either
+ * RS_RET_OK, which means the session should be kept open
+ * or anything else, which means it must be closed.
+ * rgerhards, 2008-03-01
+ * As a performance optimization, we pick up the timestamp here. Acutally,
+ * this *is* the *correct* reception step for all the data we received, because
+ * we have just received a bunch of data! -- rgerhards, 2009-06-16
+ * EXTRACT from tcps_sess.c
+ */
+#define NUM_MULTISUB 1024
+static rsRetVal
+DataRcvd(ttcpsess_t *pThis, char *pData, size_t iLen)
+{
+ multi_submit_t multiSub;
+ msg_t *pMsgs[NUM_MULTISUB];
+ struct syslogTime stTime;
+ time_t ttGenTime;
+ char *pEnd;
+ DEFiRet;
+
+ assert(pData != NULL);
+ assert(iLen > 0);
+
+ datetime.getCurrTime(&stTime, &ttGenTime);
+ multiSub.ppMsgs = pMsgs;
+ multiSub.maxElem = NUM_MULTISUB;
+ multiSub.nElem = 0;
+
+ /* We now copy the message to the session buffer. */
+ pEnd = pData + iLen; /* this is one off, which is intensional */
+
+ while(pData < pEnd) {
+ CHKiRet(processDataRcvd(pThis, *pData++, &stTime, ttGenTime, &multiSub));
+ }
+
+ if(multiSub.nElem > 0) {
+ /* submit anything that was not yet submitted */
+ CHKiRet(multiSubmitMsg(&multiSub));
+ }
+
+finalize_it:
+ RETiRet;
+}
+#undef NUM_MULTISUB
+
+
+/****************************************** --END-- TCP SUPPORT FUNCTIONS ***********************************/
+
+
+static inline void
+initConfigSettings(void)
+{
+ cs.bEmitMsgOnClose = 0;
+ cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
+ cs.pszInputName = NULL;
+ cs.pRuleset = NULL;
+ cs.lstnIP = NULL;
+}
+
+
+/* add a listener to the server
+ */
+static rsRetVal
+addLstn(ttcpsrv_t *pSrv, int sock)
+{
+ DEFiRet;
+ ttcplstn_t *pLstn;
+
+ CHKmalloc(pLstn = malloc(sizeof(ttcplstn_t)));
+ pLstn->pSrv = pSrv;
+ pLstn->sock = sock;
+
+ /* add to start of server's listener list */
+ pLstn->prev = NULL;
+ pLstn->next = pSrv->pLstn;
+ if(pSrv->pLstn != NULL)
+ pSrv->pLstn->prev = pLstn;
+ pSrv->pLstn = pLstn;
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* add a session to the server
+ */
+static rsRetVal
+addSess(ttcpsrv_t *pSrv, int sock, prop_t *peerName, prop_t *peerIP)
+{
+ DEFiRet;
+ ttcpsess_t *pSess = NULL;
+
+ CHKmalloc(pSess = malloc(sizeof(ttcpsess_t)));
+ CHKmalloc(pSess->pMsg = malloc(iMaxLine * sizeof(uchar)));
+ pSess->pSrv = pSrv;
+ pSess->sock = sock;
+ pSess->inputState = eAtStrtFram;
+ pSess->iMsg = 0;
+ pSess->bAtStrtOfFram = 1;
+ pSess->peerName = peerName;
+ pSess->peerIP = peerIP;
+
+ /* add to start of server's listener list */
+ pSess->prev = NULL;
+ pthread_mutex_lock(&pSrv->mutSess);
+ pSess->next = pSrv->pSess;
+ if(pSrv->pSess != NULL)
+ pSrv->pSess->prev = pSess;
+ pSrv->pSess = pSess;
+ pthread_mutex_unlock(&pSrv->mutSess);
+
+ /* finally run session handler */
+ pthread_create(&pSess->tid, &sessThrdAttr, sessThrd, (void*) pSess);
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* close/remove a session
+ * NOTE: we must first remove the fd from the epoll set and then close it -- else we
+ * get an error "bad file descriptor" from epoll.
+ */
+static inline rsRetVal
+closeSess(ttcpsess_t *pSess)
+{
+ int sock;
+ DEFiRet;
+
+ sock = pSess->sock;
+ close(sock);
+
+ /* finally unlink session from structures */
+ pthread_mutex_lock(&pSess->pSrv->mutSess);
+ if(pSess->next != NULL)
+ pSess->next->prev = pSess->prev;
+ if(pSess->prev == NULL) {
+ /* need to update root! */
+ pSess->pSrv->pSess = pSess->next;
+ } else {
+ pSess->prev->next = pSess->next;
+ }
+ pthread_mutex_unlock(&pSess->pSrv->mutSess);
+
+ /* unlinked, now remove structure */
+ destructSess(pSess);
+
+ RETiRet;
+}
+
+
+/* accept a new ruleset to bind. Checks if it exists and complains, if not */
+static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
+{
+ ruleset_t *pRuleset;
+ rsRetVal localRet;
+ DEFiRet;
+
+ localRet = ruleset.GetRuleset(ourConf, &pRuleset, pszName);
+ if(localRet == RS_RET_NOT_FOUND) {
+ errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName);
+ }
+ CHKiRet(localRet);
+ cs.pRuleset = pRuleset;
+ DBGPRINTF("imttcp current bind ruleset %p: '%s'\n", pRuleset, pszName);
+
+finalize_it:
+ free(pszName); /* no longer needed */
+ RETiRet;
+}
+
+
+static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
+{
+ DEFiRet;
+ ttcpsrv_t *pSrv;
+
+ CHKmalloc(pSrv = malloc(sizeof(ttcpsrv_t)));
+ pthread_mutex_init(&pSrv->mutSess, NULL);
+ pSrv->pSess = NULL;
+ pSrv->pLstn = NULL;
+ 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("imttcp") : cs.pszInputName;
+ CHKiRet(prop.Construct(&pSrv->pInputName));
+ CHKiRet(prop.SetString(pSrv->pInputName, pSrv->pszInputName, ustrlen(pSrv->pszInputName)));
+ CHKiRet(prop.ConstructFinalize(pSrv->pInputName));
+
+ /* add to linked list */
+ pSrv->pNext = pSrvRoot;
+ pSrvRoot = pSrv;
+
+ /* all config vars are auto-reset -- this also is very useful with the
+ * new config format effort (v6).
+ */
+ resetConfigVariables(NULL, NULL);
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet);
+ }
+ RETiRet;
+}
+
+
+/* create up all listeners
+ * This is a one-time stop once the module is set to start.
+ */
+static inline rsRetVal
+createServers()
+{
+ DEFiRet;
+ ttcpsrv_t *pSrv;
+
+ pSrv = pSrvRoot;
+ while(pSrv != NULL) {
+ DBGPRINTF("Starting up ttcp server for port %s, name '%s'\n", pSrv->port, pSrv->pszInputName);
+ createSrv(pSrv);
+ pSrv = pSrv->pNext;
+ }
+
+ RETiRet;
+}
+
+
+/* This function implements the thread to be used for listeners.
+ * The function terminates if shutdown is required.
+ */
+static void *
+lstnThrd(void *arg)
+{
+ ttcplstn_t *pLstn = (ttcplstn_t *) arg;
+ rsRetVal iRet = RS_RET_OK;
+ int newSock;
+ prop_t *peerName;
+ prop_t *peerIP;
+ rsRetVal localRet;
+
+ initThrd();
+
+ while(glbl.GetGlobalInputTermState() == 0) {
+ localRet = AcceptConnReq(pLstn->sock, &newSock, &peerName, &peerIP);
+ if(glbl.GetGlobalInputTermState() == 1)
+ break; /* terminate input! */
+ CHKiRet(localRet);
+ DBGPRINTF("imttcp: new connection %d on listen socket %d\n", newSock, pLstn->sock);
+ CHKiRet(addSess(pLstn->pSrv, newSock, peerName, peerIP));
+ }
+
+finalize_it:
+ close(pLstn->sock);
+ DBGPRINTF("imttcp shutdown listen socket %d\n", pLstn->sock);
+ /* Note: we do NOT unlink the deleted session. While this sounds not 100% clean,
+ * it is fine with the current implementation as we will never reuse these elements.
+ * However, it make sense (and not cost notable performance) to do it "right"...
+ */
+ return NULL;
+}
+
+
+/* This function implements the thread to be used for a session
+ * The function terminates if shutdown is required.
+ */
+static void *
+sessThrd(void *arg)
+{
+ ttcpsess_t *pSess = (ttcpsess_t*) arg;
+ rsRetVal iRet = RS_RET_OK;
+ int lenRcv;
+ int lenBuf;
+ char rcvBuf[64*1024];
+
+ initThrd();
+
+ while(glbl.GetGlobalInputTermState() == 0) {
+ lenBuf = sizeof(rcvBuf);
+ lenRcv = recv(pSess->sock, rcvBuf, lenBuf, 0);
+
+ if(glbl.GetGlobalInputTermState() == 1)
+ ABORT_FINALIZE(RS_RET_FORCE_TERM);
+
+ if(lenRcv > 0) {
+ /* have data, process it */
+ DBGPRINTF("imttcp: data(%d) on socket %d: %s\n", lenRcv, pSess->sock, rcvBuf);
+ CHKiRet(DataRcvd(pSess, rcvBuf, lenRcv));
+ } else if (lenRcv == 0) {
+ /* session was closed, do clean-up */
+ if(pSess->pSrv->bEmitMsgOnClose) {
+ uchar *peerName;
+ int lenPeer;
+ prop.GetString(pSess->peerName, &peerName, &lenPeer);
+ errmsg.LogError(0, RS_RET_PEER_CLOSED_CONN, "imttcp session %d closed by remote peer %s.\n",
+ pSess->sock, peerName);
+ }
+ break;
+ } else {
+ if(errno == EAGAIN)
+ break;
+ DBGPRINTF("imttcp: error on session socket %d - closing.\n", pSess->sock);
+ break;
+ }
+ }
+
+finalize_it:
+ DBGPRINTF("imttcp: session thread terminates, socket %d\n", pSess->sock);
+ closeSess(pSess); /* try clean-up by dropping session */
+ return NULL;
+}
+
+/* startup all listeners
+ */
+static inline rsRetVal
+startupListeners()
+{
+ DEFiRet;
+ ttcpsrv_t *pSrv;
+ ttcplstn_t *pLstn;
+
+ pSrv = pSrvRoot;
+ while(pSrv != NULL) {
+ for(pLstn = pSrv->pLstn ; pLstn != NULL ; pLstn = pLstn->next) {
+ pthread_create(&pLstn->tid, NULL, lstnThrd, (void*) pLstn);
+ }
+ pSrv = pSrv->pNext;
+ }
+
+ RETiRet;
+}
+
+
+/* This function is called to gather input.
+ */
+BEGINrunInput
+ struct timeval tvSelectTimeout;
+CODESTARTrunInput
+ DBGPRINTF("imttcp: now beginning to process input data\n");
+ CHKiRet(startupListeners());
+
+ // TODO: this loop is a quick hack, do it right!
+ while(glbl.GetGlobalInputTermState() == 0) {
+ tvSelectTimeout.tv_sec = 86400 /*1 day*/;
+ tvSelectTimeout.tv_usec = 0;
+ select(1, NULL, NULL, NULL, &tvSelectTimeout);
+ }
+finalize_it: ;
+ENDrunInput
+
+
+/* initialize and return if will run or not */
+BEGINwillRun
+CODESTARTwillRun
+ /* first apply some config settings */
+ iMaxLine = glbl.GetMaxLine(); /* get maximum size we currently support */
+
+ if(pSrvRoot == NULL) {
+ errmsg.LogError(0, RS_RET_NO_LSTN_DEFINED, "error: no ttcp server defined, module can not run.");
+ ABORT_FINALIZE(RS_RET_NO_RUN);
+ }
+
+ /* start up servers, but do not yet read input data */
+ CHKiRet(createServers());
+ DBGPRINTF("imttcp started up, but not yet receiving data\n");
+finalize_it:
+ENDwillRun
+
+
+/* completely shut down a server. All we need to do is unblock the
+ * various session and listerner threads as they then check the termination
+ * praedicate themselves.
+ */
+static inline void
+shutdownSrv(ttcpsrv_t *pSrv)
+{
+ ttcplstn_t *pLstn;
+ ttcplstn_t *pLstnDel;
+ ttcpsess_t *pSess;
+ pthread_t tid;
+
+ pLstn = pSrv->pLstn;
+ while(pLstn != NULL) {
+ tid = pLstn->tid; /* pSess will be destructed! */
+ pthread_kill(tid, SIGTTIN);
+ DBGPRINTF("imttcp: termination request for listen thread %x\n", (unsigned) tid);
+ pthread_join(tid, NULL);
+ DBGPRINTF("imttcp: listen thread %x terminated \n", (unsigned) tid);
+ pLstnDel = pLstn;
+ pLstn = pLstn->next;
+ free(pLstnDel);
+ }
+
+ pSess = pSrv->pSess;
+ while(pSess != NULL) {
+ tid = pSess->tid; /* pSess will be destructed! */
+ pSess = pSess->next;
+ pthread_kill(tid, SIGTTIN);
+ DBGPRINTF("imttcp: termination request for session thread %x\n", (unsigned) tid);
+ //pthread_join(tid, NULL);
+ DBGPRINTF("imttcp: session thread %x terminated \n", (unsigned) tid);
+ }
+}
+
+
+BEGINafterRun
+ ttcpsrv_t *pSrv, *srvDel;
+CODESTARTafterRun
+ /* do cleanup here */
+ /* we need to close everything that is still open */
+ pSrv = pSrvRoot;
+ while(pSrv != NULL) {
+ srvDel = pSrv;
+ pSrv = pSrv->pNext;
+ shutdownSrv(srvDel);
+ destructSrv(srvDel);
+ }
+ENDafterRun
+
+
+BEGINmodExit
+CODESTARTmodExit
+ pthread_attr_destroy(&sessThrdAttr);
+
+ /* release objects we used */
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(prop, CORE_COMPONENT);
+ objRelease(net, LM_NET_FILENAME);
+ objRelease(datetime, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+ objRelease(ruleset, CORE_COMPONENT);
+ENDmodExit
+
+
+static rsRetVal
+resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ cs.bEmitMsgOnClose = 0;
+ cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
+ free(cs.pszInputName);
+ cs.pszInputName = NULL;
+ free(cs.lstnIP);
+ cs.lstnIP = NULL;
+ return RS_RET_OK;
+}
+
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_IMOD_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ initConfigSettings();
+ /* request objects we use */
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(prop, CORE_COMPONENT));
+ CHKiRet(objUse(net, LM_NET_FILENAME));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(datetime, CORE_COMPONENT));
+ CHKiRet(objUse(ruleset, CORE_COMPONENT));
+
+ /* initialize "read-only" thread attributes */
+ pthread_attr_init(&sessThrdAttr);
+ pthread_attr_setdetachstate(&sessThrdAttr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setstacksize(&sessThrdAttr, 200*1024);
+
+ /* register config file handlers */
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputttcpserverrun"), 0, eCmdHdlrGetWord,
+ addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputttcpservernotifyonconnectionclose"), 0,
+ eCmdHdlrBinary, NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputttcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,
+ NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputttcpserverinputname"), 0,
+ eCmdHdlrGetWord, NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputttcpserverlistenip"), 0,
+ eCmdHdlrGetWord, NULL, &cs.lstnIP, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputttcpserverbindruleset"), 0,
+ eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
+ resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ENDmodInit
+
+
+/* vim:set ai:
+ */
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 0db6bf9a..48cb2774 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -57,6 +57,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imudp")
/* defines */
@@ -85,117 +86,92 @@ static time_t ttLastDiscard = 0; /* timestamp when a message from a non-permitte
* This shall prevent remote DoS when the "discard on disallowed sender"
* message is configured to be logged on occurance of such a case.
*/
-
-static uchar *pszBindAddr = NULL; /* IP to bind socket to */
static uchar *pRcvBuf = NULL; /* receive buffer (for a single packet). We use a global and alloc
* it so that we can check available memory in willRun() and request
* termination if we can not get it. -- rgerhards, 2007-12-27
*/
static prop_t *pInputName = NULL; /* our inputName currently is always "imudp", and this will hold it */
-static uchar *pszSchedPolicy = NULL; /* scheduling policy string */
-static int iSchedPolicy; /* scheduling policy as SCHED_xxx */
-static int iSchedPrio; /* scheduling priority */
-static int seen_iSchedPrio = 0; /* have we seen scheduling priority in the config file? */
-static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */
-#define TIME_REQUERY_DFLT 2
-static int iTimeRequery = TIME_REQUERY_DFLT;/* how often is time to be queried inside tight recv loop? 0=always */
-
-/* config settings */
-
-static rsRetVal check_scheduling_priority(int report_error)
-{
- DEFiRet;
-
-#ifdef HAVE_SCHED_GET_PRIORITY_MAX
- if (iSchedPrio < sched_get_priority_min(iSchedPolicy) ||
- iSchedPrio > sched_get_priority_max(iSchedPolicy)) {
- if (report_error)
- errmsg.LogError(errno, NO_ERRCODE,
- "imudp: scheduling priority %d out of range (%d - %d)"
- " for scheduling policy '%s' - ignoring settings",
- iSchedPrio,
- sched_get_priority_min(iSchedPolicy),
- sched_get_priority_max(iSchedPolicy),
- pszSchedPolicy);
- ABORT_FINALIZE(RS_RET_VALIDATION_RUN);
- }
-#endif
-finalize_it:
- RETiRet;
-}
-
-/* Set scheduling priority in the supplied variable (will be iSchedPrio)
- * and record that we have seen the directive (in seen_iSchedPrio).
+#define TIME_REQUERY_DFLT 2
+#define SCHED_PRIO_UNSET -12345678 /* a value that indicates that the scheduling priority has not been set */
+/* config vars for legacy config system */
+static struct configSettings_s {
+ uchar *pszBindAddr; /* IP to bind socket to */
+ uchar *pszSchedPolicy; /* scheduling policy string */
+ uchar *pszBindRuleset; /* name of Ruleset to bind to */
+ int iSchedPrio; /* scheduling priority */
+ int iTimeRequery; /* how often is time to be queried inside tight recv loop? 0=always */
+} cs;
+
+struct instanceConf_s {
+ uchar *pszBindAddr; /* IP to bind socket to */
+ uchar *pszBindPort; /* Port to bind socket to */
+ uchar *pszBindRuleset; /* name of ruleset to bind to */
+ ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
+ struct instanceConf_s *next;
+};
+
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ instanceConf_t *root, *tail;
+ uchar *pszSchedPolicy; /* scheduling policy string */
+ int iSchedPolicy; /* scheduling policy as SCHED_xxx */
+ int iSchedPrio; /* scheduling priority */
+ int iTimeRequery; /* how often is time to be queried inside tight recv loop? 0=always */
+};
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+
+#include "im-helper.h" /* must be included AFTER the type definitions! */
+
+
+
+/* This function is called when a new listener instace shall be added to
+ * the current config object via the legacy config system. It just shuffles
+ * all parameters to the listener in-memory instance.
+ * rgerhards, 2011-05-04
*/
-static rsRetVal set_scheduling_priority(void *pVal, int value)
+static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
{
+ instanceConf_t *inst;
DEFiRet;
- if (seen_iSchedPrio) {
- errmsg.LogError(0, NO_ERRCODE, "directive already seen");
- ABORT_FINALIZE(RS_RET_VALIDATION_RUN);
- }
- *(int *)pVal = value;
- seen_iSchedPrio = 1;
- if (pszSchedPolicy != NULL)
- CHKiRet(check_scheduling_priority(1));
-
-finalize_it:
- RETiRet;
-}
-
-/* Set scheduling policy in iSchedPolicy */
-static rsRetVal set_scheduling_policy(void *pVal, uchar *pNewVal)
-{
- int have_sched_policy = 0;
- DEFiRet;
-
- if (pszSchedPolicy != NULL) {
- errmsg.LogError(0, NO_ERRCODE, "directive already seen");
- ABORT_FINALIZE(RS_RET_VALIDATION_RUN);
+ CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
+ CHKmalloc(inst->pszBindPort = ustrdup((pNewVal == NULL || *pNewVal == '\0')
+ ? (uchar*) "514" : pNewVal));
+ if((cs.pszBindAddr == NULL) || (cs.pszBindAddr[0] == '\0')) {
+ inst->pszBindAddr = NULL;
+ } else {
+ CHKmalloc(inst->pszBindAddr = ustrdup(cs.pszBindAddr));
}
- *((uchar**)pVal) = pNewVal; /* pVal is pszSchedPolicy */
- if (0) { /* trick to use conditional compilation */
-#ifdef SCHED_FIFO
- } else if (!strcasecmp((char*)pszSchedPolicy, "fifo")) {
- iSchedPolicy = SCHED_FIFO;
- have_sched_policy = 1;
-#endif
-#ifdef SCHED_RR
- } else if (!strcasecmp((char*)pszSchedPolicy, "rr")) {
- iSchedPolicy = SCHED_RR;
- have_sched_policy = 1;
-#endif
-#ifdef SCHED_OTHER
- } else if (!strcasecmp((char*)pszSchedPolicy, "other")) {
- iSchedPolicy = SCHED_OTHER;
- have_sched_policy = 1;
-#endif
+ if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
+ inst->pszBindRuleset = NULL;
} else {
- errmsg.LogError(errno, NO_ERRCODE,
- "imudp: invalid scheduling policy '%s' "
- "- ignoring setting", pszSchedPolicy);
+ CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset));
}
- if (have_sched_policy == 0) {
- free(pszSchedPolicy);
- pszSchedPolicy = NULL;
- ABORT_FINALIZE(RS_RET_VALIDATION_RUN);
+ inst->pBindRuleset = NULL;
+ inst->next = NULL;
+
+ /* node created, let's add to config */
+ if(loadModConf->tail == NULL) {
+ loadModConf->tail = loadModConf->root = inst;
+ } else {
+ loadModConf->tail->next = inst;
+ loadModConf->tail = inst;
}
- if (seen_iSchedPrio)
- CHKiRet(check_scheduling_priority(1));
finalize_it:
+ free(pNewVal);
RETiRet;
}
/* This function is called when a new listener shall be added. It takes
- * the configured parameters, tries to bind the socket and, if that
+ * the instance config description, tries to bind the socket and, if that
* succeeds, adds it to the list of existing listen sockets.
- * rgerhards, 2007-12-27
*/
-static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal)
+static inline rsRetVal
+addListner(instanceConf_t *inst)
{
DEFiRet;
uchar *bindAddr;
@@ -209,17 +185,63 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal)
/* check which address to bind to. We could do this more compact, but have not
* done so in order to make the code more readable. -- rgerhards, 2007-12-27
*/
- if(pszBindAddr == NULL)
+#if 0 //<<<<<<< HEAD
+
+ DBGPRINTF("imudp: trying to open port at %s:%s.\n",
+ (inst->pszBindAddr == NULL) ? (uchar*)"*" : inst->pszBindAddr, inst->pszBindPort);
+
+ newSocks = net.create_udp_socket(inst->pszBindAddr, inst->pszBindPort, 1);
+ if(newSocks != NULL) {
+ /* we now need to add the new sockets to the existing set */
+ if(udpLstnSocks == NULL) {
+ /* esay, we can just replace it */
+ udpLstnSocks = newSocks;
+ CHKmalloc(udpRulesets = (ruleset_t**) MALLOC(sizeof(ruleset_t*) * (newSocks[0] + 1)));
+ for(iDst = 1 ; iDst <= newSocks[0] ; ++iDst)
+ udpRulesets[iDst] = inst->pBindRuleset;
+ } else {
+ /* we need to add them */
+ tmpSocks = (int*) MALLOC(sizeof(int) * (1 + newSocks[0] + udpLstnSocks[0]));
+ tmpRulesets = (ruleset_t**) MALLOC(sizeof(ruleset_t*) * (1 + newSocks[0] + udpLstnSocks[0]));
+ if(tmpSocks == NULL || tmpRulesets == NULL) {
+ DBGPRINTF("out of memory trying to allocate udp listen socket array\n");
+ /* in this case, we discard the new sockets but continue with what we
+ * already have
+ */
+ free(newSocks);
+ free(tmpSocks);
+ free(tmpRulesets);
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ } else {
+ /* ready to copy */
+ iDst = 1;
+ for(iSrc = 1 ; iSrc <= udpLstnSocks[0] ; ++iSrc, ++iDst) {
+ tmpSocks[iDst] = udpLstnSocks[iSrc];
+ tmpRulesets[iDst] = udpRulesets[iSrc];
+ }
+ for(iSrc = 1 ; iSrc <= newSocks[0] ; ++iSrc, ++iDst) {
+ tmpSocks[iDst] = newSocks[iSrc];
+ tmpRulesets[iDst] = inst->pBindRuleset;
+ }
+ tmpSocks[0] = udpLstnSocks[0] + newSocks[0];
+ free(newSocks);
+ free(udpLstnSocks);
+ udpLstnSocks = tmpSocks;
+ free(udpRulesets);
+ udpRulesets = tmpRulesets;
+ }
+#else //=======
+ if(inst->pszBindAddr == NULL)
bindAddr = NULL;
- else if(pszBindAddr[0] == '*' && pszBindAddr[1] == '\0')
+ else if(inst->pszBindAddr[0] == '*' && inst->pszBindAddr[1] == '\0')
bindAddr = NULL;
else
- bindAddr = pszBindAddr;
+ bindAddr = inst->pszBindAddr;
bindName = (bindAddr == NULL) ? (uchar*)"*" : bindAddr;
+ port = (inst->pszBindPort == NULL || *inst->pszBindPort == '\0') ? (uchar*) "514" : inst->pszBindPort;
- DBGPRINTF("Trying to open syslog UDP ports at %s:%s.\n", bindName, pNewVal);
+ DBGPRINTF("Trying to open syslog UDP ports at %s:%s.\n", bindName, inst->pszBindPort);
- port = (pNewVal == NULL || *pNewVal == '\0') ? (uchar*) "514" : pNewVal;
newSocks = net.create_udp_socket(bindAddr, port, 1);
if(newSocks != NULL) {
/* we now need to add the new sockets to the existing set */
@@ -228,7 +250,7 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKmalloc(newlcnfinfo = (struct lstn_s*) MALLOC(sizeof(struct lstn_s)));
newlcnfinfo->next = NULL;
newlcnfinfo->sock = newSocks[iSrc];
- newlcnfinfo->pRuleset = pBindRuleset;
+ newlcnfinfo->pRuleset = inst->pBindRuleset;
/* support statistics gathering */
CHKiRet(statsobj.Construct(&(newlcnfinfo->stats)));
snprintf((char*)statname, sizeof(statname), "imudp(%s:%s)", bindName, port);
@@ -246,36 +268,23 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal)
lcnfLast = newlcnfinfo;
else
lcnfLast->next = newlcnfinfo;
+#endif //>>>>>>> ef34821a2737799f48c3032b9616418e4f7fa34f
}
}
finalize_it:
- free(pNewVal); /* in any case, this is no longer needed */
free(newSocks);
-
RETiRet;
}
-/* accept a new ruleset to bind. Checks if it exists and complains, if not */
-static rsRetVal
-setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
+static inline void
+std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst)
{
- ruleset_t *pRuleset;
- rsRetVal localRet;
- DEFiRet;
-
- localRet = ruleset.GetRuleset(&pRuleset, pszName);
- if(localRet == RS_RET_NOT_FOUND) {
- errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName);
- }
- CHKiRet(localRet);
- pBindRuleset = pRuleset;
- DBGPRINTF("imudp current bind ruleset %p: '%s'\n", pRuleset, pszName);
-
-finalize_it:
- free(pszName); /* no longer needed */
- RETiRet;
+ errmsg.LogError(0, NO_ERRCODE, "imudp: ruleset '%s' for %s:%s not found - "
+ "using default ruleset instead", inst->pszBindRuleset,
+ inst->pszBindAddr == NULL ? "*" : (char*) inst->pszBindAddr,
+ inst->pszBindPort);
}
@@ -362,7 +371,7 @@ processSocket(thrdInfo_t *pThrd, struct lstn_s *lstn, struct sockaddr_storage *f
DBGPRINTF("recv(%d,%d),acl:%d,msg:%s\n", lstn->sock, (int) lenRcvBuf, *pbIsPermitted, pRcvBuf);
if(*pbIsPermitted != 0) {
- if((iTimeRequery == 0) || (iNbrTimeUsed++ % iTimeRequery) == 0) {
+ if((runModConf->iTimeRequery == 0) || (iNbrTimeUsed++ % runModConf->iTimeRequery) == 0) {
datetime.getCurrTime(&stTime, &ttGenTime);
}
/* we now create our own message object and submit it to the queue */
@@ -389,42 +398,128 @@ finalize_it:
RETiRet;
}
-static void set_thread_schedparam(void)
+
+/* check configured scheduling priority.
+ * Precondition: iSchedPolicy must have been set
+ */
+static inline rsRetVal
+checkSchedulingPriority(modConfData_t *modConf)
{
- struct sched_param sparam;
+ DEFiRet;
- if (pszSchedPolicy != NULL && seen_iSchedPrio == 0) {
+#ifdef HAVE_SCHED_GET_PRIORITY_MAX
+ if( modConf->iSchedPrio < sched_get_priority_min(modConf->iSchedPolicy)
+ || modConf->iSchedPrio > sched_get_priority_max(modConf->iSchedPolicy)) {
errmsg.LogError(0, NO_ERRCODE,
+ "imudp: scheduling priority %d out of range (%d - %d)"
+ " for scheduling policy '%s' - ignoring settings",
+ modConf->iSchedPrio,
+ sched_get_priority_min(modConf->iSchedPolicy),
+ sched_get_priority_max(modConf->iSchedPolicy),
+ modConf->pszSchedPolicy);
+ ABORT_FINALIZE(RS_RET_VALIDATION_RUN);
+ }
+#endif
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* check scheduling policy string and, if valid, set its
+ * numeric equivalent in current load config
+ */
+static rsRetVal
+checkSchedulingPolicy(modConfData_t *modConf)
+{
+ DEFiRet;
+
+ if (0) { /* trick to use conditional compilation */
+#ifdef SCHED_FIFO
+ } else if (!strcasecmp((char*)modConf->pszSchedPolicy, "fifo")) {
+ modConf->iSchedPolicy = SCHED_FIFO;
+#endif
+#ifdef SCHED_RR
+ } else if (!strcasecmp((char*)modConf->pszSchedPolicy, "rr")) {
+ modConf->iSchedPolicy = SCHED_RR;
+#endif
+#ifdef SCHED_OTHER
+ } else if (!strcasecmp((char*)modConf->pszSchedPolicy, "other")) {
+ modConf->iSchedPolicy = SCHED_OTHER;
+#endif
+ } else {
+ errmsg.LogError(errno, NO_ERRCODE,
+ "imudp: invalid scheduling policy '%s' "
+ "- ignoring setting", modConf->pszSchedPolicy);
+ ABORT_FINALIZE(RS_RET_ERR_SCHED_PARAMS);
+ }
+finalize_it:
+ RETiRet;
+}
+
+/* checks scheduling parameters during config check phase */
+static rsRetVal
+checkSchedParam(modConfData_t *modConf)
+{
+ DEFiRet;
+
+ if(modConf->pszSchedPolicy != NULL && modConf->iSchedPrio == SCHED_PRIO_UNSET) {
+ errmsg.LogError(0, RS_RET_ERR_SCHED_PARAMS,
"imudp: scheduling policy set, but without priority - ignoring settings");
- } else if (pszSchedPolicy == NULL && seen_iSchedPrio != 0) {
- errmsg.LogError(0, NO_ERRCODE,
+ ABORT_FINALIZE(RS_RET_ERR_SCHED_PARAMS);
+ } else if(modConf->pszSchedPolicy == NULL && modConf->iSchedPrio != SCHED_PRIO_UNSET) {
+ errmsg.LogError(0, RS_RET_ERR_SCHED_PARAMS,
"imudp: scheduling priority set, but without policy - ignoring settings");
- } else if (pszSchedPolicy != NULL && seen_iSchedPrio != 0 &&
- check_scheduling_priority(0) == 0) {
+ ABORT_FINALIZE(RS_RET_ERR_SCHED_PARAMS);
+ } else if(modConf->pszSchedPolicy != NULL && modConf->iSchedPrio != SCHED_PRIO_UNSET) {
+ /* we have parameters set, so check them */
+ CHKiRet(checkSchedulingPolicy(modConf));
+ CHKiRet(checkSchedulingPriority(modConf));
+ } else { /* nothing set */
+ modConf->iSchedPrio = SCHED_PRIO_UNSET; /* prevents doing the activation call */
+ }
#ifndef HAVE_PTHREAD_SETSCHEDPARAM
- errmsg.LogError(0, NO_ERRCODE,
- "imudp: cannot set thread scheduling policy, "
- "pthread_setschedparam() not available");
-#else
- int err;
-
- memset(&sparam, 0, sizeof sparam);
- sparam.sched_priority = iSchedPrio;
- dbgprintf("imudp trying to set sched policy to '%s', prio %d\n",
- pszSchedPolicy, iSchedPrio);
- err = pthread_setschedparam(pthread_self(), iSchedPolicy, &sparam);
- if (err != 0) {
- errmsg.LogError(err, NO_ERRCODE, "imudp: pthread_setschedparam() failed");
- }
+ errmsg.LogError(0, NO_ERRCODE,
+ "imudp: cannot set thread scheduling policy, "
+ "pthread_setschedparam() not available");
+ ABORT_FINALIZE(RS_RET_ERR_SCHED_PARAMS);
#endif
- }
- if (pszSchedPolicy != NULL) {
- free(pszSchedPolicy);
- pszSchedPolicy = NULL;
+finalize_it:
+ if(iRet != RS_RET_OK)
+ modConf->iSchedPrio = SCHED_PRIO_UNSET; /* prevents doing the activation call */
+
+ RETiRet;
+}
+
+/* set the configured scheduling policy (if possible) */
+static rsRetVal
+setSchedParams(modConfData_t *modConf)
+{
+ DEFiRet;
+
+# ifdef HAVE_PTHREAD_SETSCHEDPARAM
+ int err;
+ struct sched_param sparam;
+
+ if(modConf->iSchedPrio == SCHED_PRIO_UNSET)
+ FINALIZE;
+
+ memset(&sparam, 0, sizeof sparam);
+ sparam.sched_priority = modConf->iSchedPrio;
+ dbgprintf("imudp trying to set sched policy to '%s', prio %d\n",
+ modConf->pszSchedPolicy, modConf->iSchedPrio);
+ err = pthread_setschedparam(pthread_self(), modConf->iSchedPolicy, &sparam);
+ if(err != 0) {
+ errmsg.LogError(err, NO_ERRCODE, "imudp: pthread_setschedparam() failed - ignoring");
}
+# endif
+
+finalize_it:
+ RETiRet;
}
+
/* This function implements the main reception loop. Depending on the environment,
* we either use the traditional (but slower) select() or the Linux-specific epoll()
* interface. ./configure settings control which one is used.
@@ -449,7 +544,6 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd)
/* start "name caching" algo by making sure the previous system indicator
* is invalidated.
*/
- set_thread_schedparam();
bIsPermitted = 0;
memset(&frominetPrev, 0, sizeof(frominetPrev));
@@ -525,7 +619,6 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd)
/* start "name caching" algo by making sure the previous system indicator
* is invalidated.
*/
- set_thread_schedparam();
bIsPermitted = 0;
memset(&frominetPrev, 0, sizeof(frominetPrev));
DBGPRINTF("imudp uses select()\n");
@@ -571,6 +664,93 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd)
}
#endif /* #if HAVE_EPOLL_CREATE1 */
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init legacy config vars */
+ cs.pszBindRuleset = NULL;
+ cs.pszSchedPolicy = NULL;
+ cs.pszBindAddr = NULL;
+ cs.iSchedPrio = SCHED_PRIO_UNSET;
+ cs.iTimeRequery = TIME_REQUERY_DFLT;
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ /* persist module-specific settings from legacy config system
+ * TODO: when we add the new config system, we must decide on priority
+ * already-set module options should not be overwritable by the legacy
+ * system (though this is debatable and should at least trigger an error
+ * message if the equivalent legacy option is selected as well)
+ * rgerhards, 2011-05-04
+ */
+ loadModConf->iSchedPrio = cs.iSchedPrio;
+ loadModConf->iTimeRequery = cs.iTimeRequery;
+ if((cs.pszSchedPolicy == NULL) || (cs.pszSchedPolicy[0] == '\0')) {
+ loadModConf->pszSchedPolicy = NULL;
+ } else {
+ CHKmalloc(loadModConf->pszSchedPolicy = ustrdup(cs.pszSchedPolicy));
+ }
+
+finalize_it:
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(cs.pszBindRuleset);
+ free(cs.pszSchedPolicy);
+ free(cs.pszBindAddr);
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+ instanceConf_t *inst;
+CODESTARTcheckCnf
+ checkSchedParam(pModConf); /* this can not cause fatal errors */
+ for(inst = pModConf->root ; inst != NULL ; inst = inst->next) {
+ std_checkRuleset(pModConf, inst);
+ }
+ if(pModConf->root == NULL) {
+ errmsg.LogError(0, RS_RET_NO_LISTNERS , "imudp: module loaded, but "
+ "no listeners defined - no input will be gathered");
+ iRet = RS_RET_NO_LISTNERS;
+ }
+ENDcheckCnf
+
+
+BEGINactivateCnfPrePrivDrop
+ instanceConf_t *inst;
+CODESTARTactivateCnfPrePrivDrop
+ runModConf = pModConf;
+ for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
+ addListner(inst);
+ }
+ /* if we could not set up any listners, there is no point in running... */
+ if(lcnfRoot == NULL) {
+ errmsg.LogError(0, NO_ERRCODE, "imudp: no listeners could be started, "
+ "input not activated.\n");
+ ABORT_FINALIZE(RS_RET_NO_RUN);
+ }
+
+ setSchedParams(pModConf);
+finalize_it:
+ENDactivateCnfPrePrivDrop
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ /* caching various settings */
+ iMaxLine = glbl.GetMaxLine();
+ CHKmalloc(pRcvBuf = MALLOC((iMaxLine + 1) * sizeof(char)));
+finalize_it:
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
/* This function is called to gather input.
* Note that sock must be non-NULL because otherwise we would not have
* indicated that we want to run (or we have a programming error ;)). -- rgerhards, 2008-10-02
@@ -584,24 +764,8 @@ ENDrunInput
/* initialize and return if will run or not */
BEGINwillRun
CODESTARTwillRun
- /* we need to create the inputName property (only once during our lifetime) */
- CHKiRet(prop.Construct(&pInputName));
- CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imudp"), sizeof("imudp") - 1));
- CHKiRet(prop.ConstructFinalize(pInputName));
-
net.PrintAllowedSenders(1); /* UDP */
net.HasRestrictions(UCHAR_CONSTANT("UDP"), &bDoACLCheck); /* UDP */
-
- /* if we could not set up any listners, there is no point in running... */
- if(lcnfRoot == NULL) {
- DBGPRINTF("imudp: no listeners configured, will not run\n");
- ABORT_FINALIZE(RS_RET_NO_RUN);
- }
-
- iMaxLine = glbl.GetMaxLine();
-
- CHKmalloc(pRcvBuf = MALLOC((iMaxLine + 1) * sizeof(char)));
-finalize_it:
ENDwillRun
@@ -622,13 +786,14 @@ CODESTARTafterRun
free(pRcvBuf);
pRcvBuf = NULL;
}
- if(pInputName != NULL)
- prop.Destruct(&pInputName);
ENDafterRun
BEGINmodExit
CODESTARTmodExit
+ if(pInputName != NULL)
+ prop.Destruct(&pInputName);
+
/* release what we no longer need */
objRelease(errmsg, CORE_COMPONENT);
objRelease(glbl, CORE_COMPONENT);
@@ -650,16 +815,27 @@ ENDisCompatibleWithFeature
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- if(pszBindAddr != NULL) {
- free(pszBindAddr);
- pszBindAddr = NULL;
+ if(cs.pszBindAddr != NULL) {
+ free(cs.pszBindAddr);
+ cs.pszBindAddr = NULL;
+ }
+ if(cs.pszSchedPolicy != NULL) {
+ free(cs.pszSchedPolicy);
+ cs.pszSchedPolicy = NULL;
+ }
+ if(cs.pszBindRuleset != NULL) {
+ free(cs.pszBindRuleset);
+ cs.pszBindRuleset = NULL;
}
- iTimeRequery = TIME_REQUERY_DFLT;/* the default is to query only every second time */
+ cs.iSchedPrio = SCHED_PRIO_UNSET;
+ cs.iTimeRequery = TIME_REQUERY_DFLT;/* the default is to query only every second time */
return RS_RET_OK;
}
@@ -676,19 +852,24 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(ruleset, CORE_COMPONENT));
CHKiRet(objUse(net, LM_NET_FILENAME));
+ /* we need to create the inputName property (only once during our lifetime) */
+ CHKiRet(prop.Construct(&pInputName));
+ CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imudp"), sizeof("imudp") - 1));
+ CHKiRet(prop.ConstructFinalize(pInputName));
+
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputudpserverbindruleset", 0, eCmdHdlrGetWord,
- setRuleset, NULL, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserverrun", 0, eCmdHdlrGetWord,
- addListner, NULL, STD_LOADABLE_MODULE_ID));
+ addInstance, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserveraddress", 0, eCmdHdlrGetWord,
- NULL, &pszBindAddr, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.pszBindAddr, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"imudpschedulingpolicy", 0, eCmdHdlrGetWord,
- &set_scheduling_policy, &pszSchedPolicy, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.pszSchedPolicy, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"imudpschedulingpriority", 0, eCmdHdlrInt,
- &set_scheduling_priority, &iSchedPrio, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.iSchedPrio, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpservertimerequery", 0, eCmdHdlrInt,
- NULL, &iTimeRequery, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.iTimeRequery, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c
index 403173e1..3e477ea0 100644
--- a/plugins/imuxsock/imuxsock.c
+++ b/plugins/imuxsock/imuxsock.c
@@ -58,6 +58,7 @@
MODULE_TYPE_INPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("imuxsock")
/* defines */
#define MAXFUNIX 50
@@ -69,6 +70,9 @@ MODULE_TYPE_NOKEEP
#endif
#endif
+/* forward definitions */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
+
/* emulate struct ucred for platforms that do not have it */
#ifndef HAVE_SCM_CREDENTIALS
struct ucred { int pid; };
@@ -88,6 +92,7 @@ DEFobjCurrIf(parser)
DEFobjCurrIf(datetime)
DEFobjCurrIf(statsobj)
+
statsobj_t *modStats;
STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit)
STATSCOUNTER_DEF(ctrLostRatelimit, mutCtrLostRatelimit)
@@ -151,30 +156,64 @@ static int startIndexUxLocalSockets; /* process fd from that index on (used to
static int nfd = 1; /* number of Unix sockets open / read-only after startup */
static int sd_fds = 0; /* number of systemd activated sockets */
-/* config settings */
-static int bOmitLocalLogging = 0;
-static uchar *pLogSockName = 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? */
-static int bWritePid = 0; /* use credentials from recvmsg() and fixup PID in TAG */
-static int bWritePidSysSock = 0; /* use credentials from recvmsg() and fixup PID in TAG */
-static int bUseSysTimeStamp = 1; /* use timestamp from system (rather than from message) */
-static int bUseSysTimeStampSysSock = 1; /* same, for system log socket */
-static int bAnnotate = 0; /* annotate trusted properties */
-static int bAnnotateSysSock = 0; /* same, for system log socket */
+/* config vars for legacy config system */
#define DFLT_bCreatePath 0
-static int bCreatePath = DFLT_bCreatePath; /* auto-create socket path? */
#define DFLT_ratelimitInterval 0
-static int ratelimitInterval = DFLT_ratelimitInterval; /* interval in seconds, 0 = off */
-static int ratelimitIntervalSysSock = DFLT_ratelimitInterval;
#define DFLT_ratelimitBurst 200
-static int ratelimitBurst = DFLT_ratelimitBurst; /* max nbr of messages in interval */
-static int ratelimitBurstSysSock = DFLT_ratelimitBurst; /* max nbr of messages in interval */
#define DFLT_ratelimitSeverity 1 /* do not rate-limit emergency messages */
-static int ratelimitSeverity = DFLT_ratelimitSeverity;
-static int ratelimitSeveritySysSock = DFLT_ratelimitSeverity;
+static struct configSettings_s {
+ int bOmitLocalLogging;
+ uchar *pLogSockName;
+ uchar *pLogHostName; /* host name to use with this socket */
+ int bUseFlowCtl; /* use flow control or not (if yes, only LIGHT is used! */
+ int bIgnoreTimestamp; /* ignore timestamps present in the incoming message? */
+ int bUseSysTimeStamp; /* use timestamp from system (rather than from message) */
+ int bUseSysTimeStampSysSock; /* same, for system log socket */
+ int bWritePid; /* use credentials from recvmsg() and fixup PID in TAG */
+ int bWritePidSysSock; /* use credentials from recvmsg() and fixup PID in TAG */
+ int bCreatePath; /* auto-create socket path? */
+ int ratelimitInterval; /* interval in seconds, 0 = off */
+ int ratelimitIntervalSysSock;
+ int ratelimitBurst; /* max nbr of messages in interval */
+ int ratelimitBurstSysSock;
+ int ratelimitSeverity;
+ int ratelimitSeveritySysSock;
+ int bAnnotate; /* annotate trusted properties */
+ int bAnnotateSysSock; /* same, for system log socket */
+} cs;
+
+struct instanceConf_s {
+ uchar *sockName;
+ uchar *pLogHostName; /* host name to use with this socket */
+ sbool bUseFlowCtl; /* use flow control or not (if yes, only LIGHT is used! */
+ sbool bIgnoreTimestamp; /* ignore timestamps present in the incoming message? */
+ sbool bWritePid; /* use credentials from recvmsg() and fixup PID in TAG */
+ sbool bUseSysTimeStamp; /* use timestamp from system (instead of from message) */
+ int bCreatePath; /* auto-create socket path? */
+ int ratelimitInterval; /* interval in seconds, 0 = off */
+ int ratelimitBurst; /* max nbr of messages in interval */
+ int ratelimitSeverity;
+ int bAnnotate; /* annotate trusted properties */
+ struct instanceConf_s *next;
+};
+
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ instanceConf_t *root, *tail;
+ uchar *pLogSockName;
+ int ratelimitIntervalSysSock;
+ int ratelimitBurstSysSock;
+ int ratelimitSeveritySysSock;
+ sbool bOmitLocalLogging;
+ sbool bWritePidSysSock;
+ int bAnnotateSysSock;
+ sbool bUseSysTimeStamp;
+};
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+/* we do not use this, because we do not bind to a ruleset so far
+ * enable when this is changed: #include "im-helper.h" */ /* must be included AFTER the type definitions! */
static void
@@ -263,6 +302,55 @@ static rsRetVal setSystemLogFlowControl(void __attribute__((unused)) *pVal, int
RETiRet;
}
+
+/* This function is called when a new listen socket instace shall be added to
+ * the current config object via the legacy config system. It just shuffles
+ * all parameters to the listener in-memory instance.
+ * rgerhards, 2011-05-12
+ */
+static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
+{
+ instanceConf_t *inst;
+ DEFiRet;
+
+ if(pNewVal == NULL || pNewVal[0] == '\0') {
+ errmsg.LogError(0, RS_RET_SOCKNAME_MISSING , "imuxsock: socket name must be specified, "
+ "but is not - listener not created\n");
+ if(pNewVal != NULL)
+ free(pNewVal);
+ ABORT_FINALIZE(RS_RET_SOCKNAME_MISSING);
+ }
+
+ CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
+ inst->sockName = pNewVal;
+ inst->ratelimitInterval = cs.ratelimitInterval;
+ inst->ratelimitBurst = cs.ratelimitBurst;
+ inst->ratelimitSeverity = cs.ratelimitSeverity;
+ inst->bUseFlowCtl = cs.bUseFlowCtl;
+ inst->bIgnoreTimestamp = cs.bIgnoreTimestamp;
+ inst->bCreatePath = cs.bCreatePath;
+ inst->bUseSysTimeStamp = cs.bUseSysTimeStamp;
+ inst->bWritePid = cs.bWritePid;
+ inst->bAnnotate = cs.bAnnotate;
+ inst->next = NULL;
+
+ /* node created, let's add to config */
+ if(loadModConf->tail == NULL) {
+ loadModConf->tail = loadModConf->root = inst;
+ } else {
+ loadModConf->tail->next = inst;
+ loadModConf->tail = inst;
+ }
+
+ /* some legacy conf processing */
+ free(cs.pLogHostName); /* reset hostname for next socket */
+ cs.pLogHostName = NULL;
+
+finalize_it:
+ RETiRet;
+}
+
+
/* add an additional listen socket. Socket names are added
* until the array is filled up. It is never reset, only at
* module unload.
@@ -272,49 +360,47 @@ static rsRetVal setSystemLogFlowControl(void __attribute__((unused)) *pVal, int
* added capability to specify hostname for socket -- rgerhards, 2008-08-01
*/
static rsRetVal
-addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNewVal)
+addListner(instanceConf_t *inst)
{
DEFiRet;
if(nfd < MAXFUNIX) {
- if(*pNewVal == ':') {
+ if(*inst->sockName == ':') {
listeners[nfd].bParseHost = 1;
} 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())));
+ if(inst->pLogHostName == NULL) {
+ CHKiRet(prop.SetString(listeners[nfd].hostName, glbl.GetLocalHostName(),
+ ustrlen(glbl.GetLocalHostName())));
} else {
- CHKiRet(prop.SetString(listeners[nfd].hostName, pLogHostName, ustrlen(pLogHostName)));
- /* reset hostname for next socket */
- free(pLogHostName);
- pLogHostName = NULL;
+ CHKiRet(prop.SetString(listeners[nfd].hostName, inst->pLogHostName, ustrlen(inst->pLogHostName)));
}
CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName));
- if(ratelimitInterval > 0) {
+ 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 of rate-limiting */
+ /* in this case, we simply turn off rate-limiting */
dbgprintf("imuxsock: turning off rate limiting because we could not "
"create hash table\n");
- ratelimitInterval = 0;
+ inst->ratelimitInterval = 0;
}
}
- listeners[nfd].ratelimitInterval = ratelimitInterval;
- listeners[nfd].ratelimitBurst = ratelimitBurst;
- listeners[nfd].ratelimitSev = ratelimitSeverity;
- listeners[nfd].flowCtl = bUseFlowCtl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY;
- listeners[nfd].flags = bIgnoreTimestamp ? IGNDATE : NOFLAG;
- listeners[nfd].bCreatePath = bCreatePath;
- listeners[nfd].sockName = pNewVal;
- listeners[nfd].bUseCreds = (bWritePid || ratelimitInterval || bAnnotate) ? 1 : 0;
- listeners[nfd].bAnnotate = bAnnotate;
- listeners[nfd].bWritePid = bWritePid;
- listeners[nfd].bUseSysTimeStamp = bUseSysTimeStamp;
+ listeners[nfd].ratelimitInterval = inst->ratelimitInterval;
+ listeners[nfd].ratelimitBurst = inst->ratelimitBurst;
+ listeners[nfd].ratelimitSev = inst->ratelimitSeverity;
+ listeners[nfd].flowCtl = inst->bUseFlowCtl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY;
+ listeners[nfd].flags = inst->bIgnoreTimestamp ? IGNDATE : NOFLAG;
+ listeners[nfd].bCreatePath = inst->bCreatePath;
+ listeners[nfd].sockName = ustrdup(inst->sockName);
+ listeners[nfd].bUseCreds = (inst->bWritePid || inst->ratelimitInterval || inst->bAnnotate) ? 1 : 0;
+ listeners[nfd].bAnnotate = inst->bAnnotate;
+ listeners[nfd].bWritePid = inst->bWritePid;
+ listeners[nfd].bUseSysTimeStamp = inst->bUseSysTimeStamp;
nfd++;
} else {
errmsg.LogError(0, NO_ERRCODE, "Out of unix socket name descriptors, ignoring %s\n",
- pNewVal);
+ inst->sockName);
}
finalize_it:
@@ -875,6 +961,121 @@ finalize_it:
}
+/* activate current listeners */
+static inline rsRetVal
+activateListeners()
+{
+ register int i;
+ int actSocks;
+ DEFiRet;
+
+ /* first apply some config settings */
+# ifdef OS_SOLARIS
+ /* under solaris, we must NEVER process the local log socket, because
+ * it is implemented there differently. If we used it, we would actually
+ * delete it and render the system partly unusable. So don't do that.
+ * rgerhards, 2010-03-26
+ */
+ startIndexUxLocalSockets = 1;
+# else
+ startIndexUxLocalSockets = runModConf->bOmitLocalLogging ? 1 : 0;
+# endif
+ if(runModConf->pLogSockName != NULL)
+ listeners[0].sockName = runModConf->pLogSockName;
+ if(runModConf->ratelimitIntervalSysSock > 0) {
+ if((listeners[0].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) {
+ /* in this case, we simply turn of rate-limiting */
+ errmsg.LogError(0, NO_ERRCODE, "imuxsock: turning off rate limiting because we could not "
+ "create hash table\n");
+ runModConf->ratelimitIntervalSysSock = 0;
+ }
+ }
+ listeners[0].ratelimitInterval = runModConf->ratelimitIntervalSysSock;
+ listeners[0].ratelimitBurst = runModConf->ratelimitBurstSysSock;
+ listeners[0].ratelimitSev = runModConf->ratelimitSeveritySysSock;
+ listeners[0].bUseCreds = (runModConf->bWritePidSysSock || runModConf->ratelimitIntervalSysSock) ? 1 : 0;
+ listeners[0].bWritePid = runModConf->bWritePidSysSock;
+ listeners[0].bAnnotate = runModConf->bAnnotateSysSock;
+ listeners[0].bUseSysTimeStamp = runModConf->bUseSysTimeStamp;
+
+ sd_fds = sd_listen_fds(0);
+ if(sd_fds < 0) {
+ errmsg.LogError(-sd_fds, NO_ERRCODE, "imuxsock: Failed to acquire systemd socket");
+ ABORT_FINALIZE(RS_RET_ERR_CRE_AFUX);
+ }
+
+ /* initialize and return if will run or not */
+ actSocks = 0;
+ for (i = startIndexUxLocalSockets ; i < nfd ; i++) {
+ if(openLogSocket(&(listeners[i])) == RS_RET_OK) {
+ ++actSocks;
+ dbgprintf("imuxsock: Opened UNIX socket '%s' (fd %d).\n",
+ listeners[i].sockName, listeners[i].fd);
+ }
+ }
+
+ if(actSocks == 0) {
+ errmsg.LogError(0, NO_ERRCODE, "imuxsock does not run because we could not aquire any socket\n");
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* reset legacy config vars */
+ resetConfigVariables(NULL, NULL);
+ENDbeginCnfLoad
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ /* persist module-specific settings from legacy config system */
+ loadModConf->bOmitLocalLogging = cs.bOmitLocalLogging;
+ loadModConf->pLogSockName = cs.pLogSockName;
+
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(cs.pLogHostName);
+ cs.pLogSockName = NULL;
+ cs.pLogHostName = NULL;
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+
+BEGINactivateCnfPrePrivDrop
+ instanceConf_t *inst;
+CODESTARTactivateCnfPrePrivDrop
+ runModConf = pModConf;
+ for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
+ addListner(inst);
+ }
+ CHKiRet(activateListeners());
+finalize_it:
+ENDactivateCnfPrePrivDrop
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ free(pModConf->pLogSockName);
+ENDfreeCnf
+
+
/* This function is called to gather input. */
BEGINrunInput
int maxfds;
@@ -942,70 +1143,12 @@ ENDrunInput
BEGINwillRun
CODESTARTwillRun
- register int i;
- int actSocks;
-
- /* first apply some config settings */
-# ifdef OS_SOLARIS
- /* under solaris, we must NEVER process the local log socket, because
- * it is implemented there differently. If we used it, we would actually
- * delete it and render the system partly unusable. So don't do that.
- * rgerhards, 2010-03-26
- */
- startIndexUxLocalSockets = 1;
-# else
- startIndexUxLocalSockets = bOmitLocalLogging ? 1 : 0;
-# endif
- if(pLogSockName != NULL)
- listeners[0].sockName = pLogSockName;
- if(ratelimitIntervalSysSock > 0) {
- if((listeners[0].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) {
- /* in this case, we simply turn of rate-limiting */
- dbgprintf("imuxsock: turning off rate limiting because we could not "
- "create hash table\n");
- ratelimitIntervalSysSock = 0;
- }
- }
- listeners[0].ratelimitInterval = ratelimitIntervalSysSock;
- listeners[0].ratelimitBurst = ratelimitBurstSysSock;
- listeners[0].ratelimitSev = ratelimitSeveritySysSock;
- listeners[0].bUseCreds = (bWritePidSysSock || ratelimitIntervalSysSock || bAnnotateSysSock) ? 1 : 0;
- listeners[0].bWritePid = bWritePidSysSock;
- listeners[0].bAnnotate = bAnnotateSysSock;
- listeners[0].bUseSysTimeStamp = bUseSysTimeStampSysSock;
-
- sd_fds = sd_listen_fds(0);
- if (sd_fds < 0) {
- errmsg.LogError(-sd_fds, NO_ERRCODE, "imuxsock: Failed to acquire systemd socket");
- ABORT_FINALIZE(RS_RET_ERR_CRE_AFUX);
- }
-
- /* initialize and return if will run or not */
- actSocks = 0;
- for (i = startIndexUxLocalSockets ; i < nfd ; i++) {
- if(openLogSocket(&(listeners[i])) == RS_RET_OK) {
- ++actSocks;
- dbgprintf("imuxsock: Opened UNIX socket '%s' (fd %d).\n", listeners[i].sockName, listeners[i].fd);
- }
- }
-
- if(actSocks == 0) {
- errmsg.LogError(0, NO_ERRCODE, "imuxsock does not run because we could not aquire any socket\n");
- ABORT_FINALIZE(RS_RET_ERR);
- }
-
- /* we need to create the inputName property (only once during our lifetime) */
- CHKiRet(prop.Construct(&pInputName));
- CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1));
- CHKiRet(prop.ConstructFinalize(pInputName));
-
-finalize_it:
ENDwillRun
BEGINafterRun
-CODESTARTafterRun
int i;
+CODESTARTafterRun
/* do cleanup here */
/* Close the UNIX sockets. */
for (i = 0; i < nfd; i++)
@@ -1027,21 +1170,17 @@ CODESTARTafterRun
DBGPRINTF("imuxsock: unlinking unix socket file[%d] %s\n", i, listeners[i].sockName);
unlink((char*) listeners[i].sockName);
}
- /* free no longer needed string */
- free(pLogSockName);
- free(pLogHostName);
discardLogSockets();
nfd = 1;
-
- if(pInputName != NULL)
- prop.Destruct(&pInputName);
-
ENDafterRun
BEGINmodExit
CODESTARTmodExit
+ if(pInputName != NULL)
+ prop.Destruct(&pInputName);
+
statsobj.Destruct(&modStats);
objRelease(parser, CORE_COMPONENT);
@@ -1063,36 +1202,33 @@ ENDisCompatibleWithFeature
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- bOmitLocalLogging = 0;
- if(pLogSockName != NULL) {
- free(pLogSockName);
- pLogSockName = NULL;
- }
- if(pLogHostName != NULL) {
- free(pLogHostName);
- pLogHostName = NULL;
- }
-
- discardLogSockets();
- nfd = 1;
- bIgnoreTimestamp = 1;
- bUseFlowCtl = 0;
- bWritePid = 0;
- bWritePidSysSock = 0;
- bUseSysTimeStamp = 1;
- bUseSysTimeStampSysSock = 1;
- bCreatePath = DFLT_bCreatePath;
- ratelimitInterval = DFLT_ratelimitInterval;
- ratelimitIntervalSysSock = DFLT_ratelimitInterval;
- ratelimitBurst = DFLT_ratelimitBurst;
- ratelimitBurstSysSock = DFLT_ratelimitBurst;
- ratelimitSeverity = DFLT_ratelimitSeverity;
- ratelimitSeveritySysSock = DFLT_ratelimitSeverity;
+ free(cs.pLogSockName);
+ cs.pLogSockName = NULL;
+ free(cs.pLogHostName);
+ cs.bOmitLocalLogging = 0;
+ cs.pLogHostName = NULL;
+ cs.bIgnoreTimestamp = 1;
+ cs.bUseFlowCtl = 0;
+ cs.bUseSysTimeStamp = 1;
+ cs.bUseSysTimeStampSysSock = 1;
+ cs.bWritePid = 0;
+ cs.bWritePidSysSock = 0;
+ cs.bAnnotate = 0;
+ cs.bAnnotateSysSock = 0;
+ cs.bCreatePath = DFLT_bCreatePath;
+ cs.ratelimitInterval = DFLT_ratelimitInterval;
+ cs.ratelimitIntervalSysSock = DFLT_ratelimitInterval;
+ cs.ratelimitBurst = DFLT_ratelimitBurst;
+ cs.ratelimitBurstSysSock = DFLT_ratelimitBurst;
+ cs.ratelimitSeverity = DFLT_ratelimitSeverity;
+ cs.ratelimitSeveritySysSock = DFLT_ratelimitSeverity;
return RS_RET_OK;
}
@@ -1112,6 +1248,15 @@ CODEmodInit_QueryRegCFSLineHdlr
dbgprintf("imuxsock version %s initializing\n", PACKAGE_VERSION);
+ /* init legacy config vars */
+ cs.pLogSockName = NULL;
+ cs.pLogHostName = NULL; /* host name to use with this socket */
+
+ /* we need to create the inputName property (only once during our lifetime) */
+ CHKiRet(prop.Construct(&pInputName));
+ CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1));
+ CHKiRet(prop.ConstructFinalize(pInputName));
+
/* init system log socket settings */
listeners[0].flags = IGNDATE;
listeners[0].sockName = UCHAR_CONSTANT(_PATH_LOG);
@@ -1141,31 +1286,31 @@ CODEmodInit_QueryRegCFSLineHdlr
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary,
- NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bOmitLocalLogging, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketignoremsgtimestamp", 0, eCmdHdlrBinary,
- NULL, &bIgnoreTimestamp, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bIgnoreTimestamp, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketname", 0, eCmdHdlrGetWord,
- NULL, &pLogSockName, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.pLogSockName, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensockethostname", 0, eCmdHdlrGetWord,
- NULL, &pLogHostName, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.pLogHostName, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketflowcontrol", 0, eCmdHdlrBinary,
- NULL, &bUseFlowCtl, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bUseFlowCtl, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketannotate", 0, eCmdHdlrBinary,
- NULL, &bAnnotate, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bAnnotate, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketcreatepath", 0, eCmdHdlrBinary,
- NULL, &bCreatePath, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketusepidfromsystem", 0, eCmdHdlrBinary,
- NULL, &bWritePid, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bCreatePath, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketusesystimestamp", 0, eCmdHdlrBinary,
- NULL, &bUseSysTimeStamp, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bUseSysTimeStamp, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"addunixlistensocket", 0, eCmdHdlrGetWord,
- addLstnSocketName, NULL, STD_LOADABLE_MODULE_ID));
+ addInstance, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketusepidfromsystem", 0, eCmdHdlrBinary,
+ NULL, &cs.bWritePid, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"imuxsockratelimitinterval", 0, eCmdHdlrInt,
- NULL, &ratelimitInterval, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.ratelimitInterval, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"imuxsockratelimitburst", 0, eCmdHdlrInt,
- NULL, &ratelimitBurst, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.ratelimitBurst, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"imuxsockratelimitseverity", 0, eCmdHdlrInt,
- NULL, &ratelimitSeverity, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.ratelimitSeverity, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
/* the following one is a (dirty) trick: the system log socket is not added via
@@ -1179,17 +1324,17 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketflowcontrol", 0, eCmdHdlrBinary,
setSystemLogFlowControl, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogusesystimestamp", 0, eCmdHdlrBinary,
- NULL, &bUseSysTimeStampSysSock, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bUseSysTimeStampSysSock, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketannotate", 0, eCmdHdlrBinary,
- NULL, &bAnnotateSysSock, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bAnnotateSysSock, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogusepidfromsystem", 0, eCmdHdlrBinary,
- NULL, &bWritePidSysSock, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.bWritePidSysSock, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogratelimitinterval", 0, eCmdHdlrInt,
- NULL, &ratelimitIntervalSysSock, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.ratelimitIntervalSysSock, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogratelimitburst", 0, eCmdHdlrInt,
- NULL, &ratelimitBurstSysSock, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.ratelimitBurstSysSock, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogratelimitseverity", 0, eCmdHdlrInt,
- NULL, &ratelimitSeveritySysSock, STD_LOADABLE_MODULE_ID));
+ NULL, &cs.ratelimitSeveritySysSock, STD_LOADABLE_MODULE_ID));
/* support statistics gathering */
CHKiRet(statsobj.Construct(&modStats));
diff --git a/plugins/mmnormalize/Makefile.am b/plugins/mmnormalize/Makefile.am
new file mode 100644
index 00000000..0a3b5ba5
--- /dev/null
+++ b/plugins/mmnormalize/Makefile.am
@@ -0,0 +1,8 @@
+pkglib_LTLIBRARIES = mmnormalize.la
+
+mmnormalize_la_SOURCES = mmnormalize.c
+mmnormalize_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(LIBLOGNORM_CFLAGS) $(LIBEE_CFLAGS)
+mmnormalize_la_LDFLAGS = -module -avoid-version $(LIBLOGNORM_LIBS) $(LIBEE_LIBS)
+mmnormalize_la_LIBADD =
+
+EXTRA_DIST =
diff --git a/plugins/mmnormalize/mmnormalize.c b/plugins/mmnormalize/mmnormalize.c
new file mode 100644
index 00000000..7b92d820
--- /dev/null
+++ b/plugins/mmnormalize/mmnormalize.c
@@ -0,0 +1,274 @@
+/* mmnormalize.c
+ * This is a message modification module. It normalizes the input message with
+ * the help of liblognorm. The messages EE event structure is updated.
+ *
+ * NOTE: read comments in module-template.h for details on the calling interface!
+ *
+ * File begun on 2010-01-01 by RGerhards
+ *
+ * Copyright 2010 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <libestr.h>
+#include <libee/libee.h>
+#include <liblognorm.h>
+#include "conf.h"
+#include "syslogd-types.h"
+#include "template.h"
+#include "module-template.h"
+#include "errmsg.h"
+#include "cfsysline.h"
+#include "dirty.h"
+
+MODULE_TYPE_OUTPUT
+MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("mmnormalize")
+
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
+
+/* static data */
+DEFobjCurrIf(errmsg);
+
+/* internal structures
+ */
+DEF_OMOD_STATIC_DATA
+
+typedef struct _instanceData {
+ sbool bUseRawMsg; /**< use %rawmsg% instead of %msg% */
+ ln_ctx ctxln; /**< context to be used for liblognorm */
+ ee_ctx ctxee; /**< context to be used for libee */
+} instanceData;
+
+typedef struct configSettings_s {
+ uchar *rulebase; /**< name of normalization rulebase to use */
+ sbool bUseRawMsg; /**< use %rawmsg% instead of %msg% */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ resetConfigVariables(NULL, NULL);
+ENDinitConfVars
+
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ENDisCompatibleWithFeature
+
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ ee_exitCtx(pData->ctxee);
+ ln_exitCtx(pData->ctxln);
+ENDfreeInstance
+
+
+BEGINdbgPrintInstInfo
+CODESTARTdbgPrintInstInfo
+ dbgprintf("mmnormalize\n");
+ENDdbgPrintInstInfo
+
+
+BEGINtryResume
+CODESTARTtryResume
+ENDtryResume
+
+BEGINdoAction
+ msg_t *pMsg;
+ es_str_t *str;
+ uchar *buf;
+ int len;
+ int r;
+CODESTARTdoAction
+ pMsg = (msg_t*) ppString[0];
+ /* note that we can performance-optimize the interface, but this also
+ * requires changes to the libraries. For now, we accept message
+ * duplication. -- rgerhards, 2010-12-01
+ */
+ if(pData->bUseRawMsg) {
+ getRawMsg(pMsg, &buf, &len);
+ } else {
+ buf = getMSG(pMsg);
+ len = getMSGLen(pMsg);
+ }
+ str = es_newStrFromCStr((char*)buf, len);
+ r = ln_normalize(pData->ctxln, str, &pMsg->event);
+ if(r != 0) {
+ DBGPRINTF("error %d during ln_normalize\n", r);
+ }
+ es_deleteStr(str);
+ /***DEBUG***/ // TODO: remove after initial testing - 2010-12-01
+ {
+ char *cstr;
+ ee_fmtEventToJSON(pMsg->event, &str);
+ cstr = es_str2cstr(str, NULL);
+ dbgprintf("mmnormalize generated: %s\n", cstr);
+ free(cstr);
+ es_deleteStr(str);
+ }
+ /***END DEBUG***/
+ENDdoAction
+
+
+BEGINparseSelectorAct
+CODESTARTparseSelectorAct
+CODE_STD_STRING_REQUESTparseSelectorAct(1)
+ /* first check if this config line is actually for us */
+ if(strncmp((char*) p, ":mmnormalize:", sizeof(":mmnormalize:") - 1)) {
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+ }
+
+ if(cs.rulebase == NULL) {
+ errmsg.LogError(0, RS_RET_NO_RULESET, "error: no normalization rulebase was specified, use "
+ "$MMNormalizeSampleDB directive first!");
+ ABORT_FINALIZE(RS_RET_NO_RULESET);
+ }
+
+ /* ok, if we reach this point, we have something for us */
+ p += sizeof(":mmnormalize:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
+ CHKiRet(createInstance(&pData));
+
+ /* check if a non-standard template is to be applied */
+ if(*(p-1) == ';')
+ --p;
+ /* we call the function below because we need to call it via our interface definition. However,
+ * the format specified (if any) is always ignored.
+ */
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_MSG, (uchar*) "RSYSLOG_FileFormat"));
+
+ /* finally build the instance */
+ if((pData->ctxee = ee_initCtx()) == NULL) {
+ errmsg.LogError(0, RS_RET_NO_RULESET, "error: could not initialize libee ctx, cannot "
+ "activate action");
+ ABORT_FINALIZE(RS_RET_ERR_LIBEE_INIT);
+ }
+
+ if((pData->ctxln = ln_initCtx()) == NULL) {
+ errmsg.LogError(0, RS_RET_NO_RULESET, "error: could not initialize liblognorm ctx, cannot "
+ "activate action");
+ ee_exitCtx(pData->ctxee);
+ ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_INIT);
+ }
+ ln_setEECtx(pData->ctxln, pData->ctxee);
+ if(ln_loadSamples(pData->ctxln, (char*) cs.rulebase) != 0) {
+ errmsg.LogError(0, RS_RET_NO_RULESET, "error: normalization rulebase '%s' could not be loaded "
+ "cannot activate action", cs.rulebase);
+ ee_exitCtx(pData->ctxee);
+ ln_exitCtx(pData->ctxln);
+ ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD);
+ }
+ pData->bUseRawMsg = cs.bUseRawMsg;
+
+ /* all config vars auto-reset! */
+ cs.bUseRawMsg = 0;
+ free(cs.rulebase);
+ cs.rulebase = NULL;
+CODE_STD_FINALIZERparseSelectorAct
+ENDparseSelectorAct
+
+
+BEGINmodExit
+CODESTARTmodExit
+ objRelease(errmsg, CORE_COMPONENT);
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+
+
+/* Reset config variables for this module to default values.
+ */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ DEFiRet;
+ cs.rulebase = NULL;
+ cs.bUseRawMsg = 0;
+ RETiRet;
+}
+
+/* set the rulebase name */
+static rsRetVal
+setRuleBase(void __attribute__((unused)) *pVal, uchar *pszName)
+{
+ DEFiRet;
+ cs.rulebase = pszName;
+ pszName = NULL;
+ RETiRet;
+}
+
+BEGINmodInit()
+ rsRetVal localRet;
+ rsRetVal (*pomsrGetSupportedTplOpts)(unsigned long *pOpts);
+ unsigned long opts;
+ int bMsgPassingSupported;
+CODESTARTmodInit
+INITLegCnfVars
+ *ipIFVersProvided = CURR_MOD_IF_VERSION;
+ /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ /* check if the rsyslog core supports parameter passing code */
+ bMsgPassingSupported = 0;
+ localRet = pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts",
+ &pomsrGetSupportedTplOpts);
+ if(localRet == RS_RET_OK) {
+ /* found entry point, so let's see if core supports msg passing */
+ CHKiRet((*pomsrGetSupportedTplOpts)(&opts));
+ if(opts & OMSR_TPL_AS_MSG)
+ bMsgPassingSupported = 1;
+ } else if(localRet != RS_RET_ENTRY_POINT_NOT_FOUND) {
+ ABORT_FINALIZE(localRet); /* Something else went wrong, not acceptable */
+ }
+
+ if(!bMsgPassingSupported) {
+ DBGPRINTF("mmnormalize: msg-passing is not supported by rsyslog core, "
+ "can not continue.\n");
+ ABORT_FINALIZE(RS_RET_NO_MSG_PASSING);
+ }
+
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"mmnormalizerulebase", 0, eCmdHdlrGetWord,
+ setRuleBase, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"mmnormalizeuserawmsg", 0, eCmdHdlrInt,
+ NULL, &cs.bUseRawMsg, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
+ resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ENDmodInit
+
+/* vi:set ai:
+ */
diff --git a/plugins/mmsnmptrapd/mmsnmptrapd.c b/plugins/mmsnmptrapd/mmsnmptrapd.c
index b78046ee..b1ac2f64 100644
--- a/plugins/mmsnmptrapd/mmsnmptrapd.c
+++ b/plugins/mmsnmptrapd/mmsnmptrapd.c
@@ -49,6 +49,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("mmsnmptrapd")
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
@@ -76,11 +77,7 @@ typedef struct configSettings_s {
uchar *pszTagName; /**< name of tag start value that indicates snmptrapd initiated message */
uchar *pszSeverityMapping; /**< severitystring to numerical code mapping for snmptrapd string */
} configSettings_t;
-configSettings_t cs;
-
-//TODO: enable for v6
-#if 0
-SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */
+static configSettings_t cs;
BEGINinitConfVars /* (re)set config variables to default values */
CODESTARTinitConfVars
@@ -88,7 +85,6 @@ CODESTARTinitConfVars
cs.pszSeverityMapping = NULL;
resetConfigVariables(NULL, NULL);
ENDinitConfVars
-#endif
BEGINcreateInstance
@@ -389,7 +385,7 @@ BEGINmodInit()
unsigned long opts;
int bMsgPassingSupported;
CODESTARTmodInit
-//TODO v6: add SCOPINGmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION;
/* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
diff --git a/plugins/omdbalerting/omdbalerting.c b/plugins/omdbalerting/omdbalerting.c
index 35de5818..ec9cf346 100644
--- a/plugins/omdbalerting/omdbalerting.c
+++ b/plugins/omdbalerting/omdbalerting.c
@@ -45,6 +45,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omdbalerting")
/* internal structures
*/
diff --git a/plugins/omgssapi/omgssapi.c b/plugins/omgssapi/omgssapi.c
index 21c540b7..089e8b41 100644
--- a/plugins/omgssapi/omgssapi.c
+++ b/plugins/omgssapi/omgssapi.c
@@ -59,8 +59,11 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omgssapi")
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
+
/* internal structures
*/
DEF_OMOD_STATIC_DATA
@@ -86,12 +89,24 @@ typedef struct _instanceData {
} instanceData;
/* config data */
-static uchar *pszTplName = NULL; /* name of the default template to use */
-static char *gss_base_service_name = NULL;
-static enum gss_mode_t {
+
+typedef enum gss_mode_e {
GSSMODE_MIC,
GSSMODE_ENC
-} gss_mode = GSSMODE_ENC;
+} gss_mode_t;
+
+typedef struct configSettings_s {
+ uchar *pszTplName; /* name of the default template to use */
+ char *gss_base_service_name;
+ gss_mode_t gss_mode;
+} configSettings_t;
+
+SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ resetConfigVariables(NULL, NULL);
+ENDinitConfVars
/* get the syslog forward port from selector_t. The passed in
* struct must be one that is setup for forwarding.
@@ -142,10 +157,8 @@ CODESTARTfreeInstance
/* this is meant to be done when module is unloaded,
but since this module is static...
*/
- if (gss_base_service_name != NULL) {
- free(gss_base_service_name);
- gss_base_service_name = NULL;
- }
+ free(cs.gss_base_service_name);
+ cs.gss_base_service_name = NULL;
/* final cleanup */
tcpclt.Destruct(&pData->pTCPClt);
@@ -192,7 +205,7 @@ static rsRetVal TCPSendGSSInit(void *pvData)
if(pData->sock > 0)
ABORT_FINALIZE(RS_RET_OK);
- base = (gss_base_service_name == NULL) ? "host" : gss_base_service_name;
+ base = (cs.gss_base_service_name == NULL) ? "host" : cs.gss_base_service_name;
out_tok.length = strlen(pData->f_hname) + strlen(base) + 2;
CHKmalloc(out_tok.value = MALLOC(out_tok.length));
strcpy(out_tok.value, base);
@@ -216,10 +229,10 @@ static rsRetVal TCPSendGSSInit(void *pvData)
sess_flags = &pData->gss_flags;
*sess_flags = GSS_C_MUTUAL_FLAG;
- if (gss_mode == GSSMODE_MIC) {
+ if (cs.gss_mode == GSSMODE_MIC) {
*sess_flags |= GSS_C_INTEG_FLAG;
}
- if (gss_mode == GSSMODE_ENC) {
+ if (cs.gss_mode == GSSMODE_ENC) {
*sess_flags |= GSS_C_CONF_FLAG;
}
dbgprintf("GSS-API requested context flags:\n");
@@ -300,7 +313,7 @@ static rsRetVal TCPSendGSSSend(void *pvData, char *msg, size_t len)
context = &pData->gss_context;
in_buf.value = msg;
in_buf.length = len;
- maj_stat = gss_wrap(&min_stat, *context, (gss_mode == GSSMODE_ENC) ? 1 : 0, GSS_C_QOP_DEFAULT,
+ maj_stat = gss_wrap(&min_stat, *context, (cs.gss_mode == GSSMODE_ENC) ? 1 : 0, GSS_C_QOP_DEFAULT,
&in_buf, NULL, &out_buf);
if (maj_stat != GSS_S_COMPLETE) {
gssutil.display_status("wrapping message", maj_stat, min_stat);
@@ -602,7 +615,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
/* process template */
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName));
+ (cs.pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : cs.pszTplName));
/* first set the pData->eDestState */
memset(&hints, 0, sizeof(hints));
@@ -639,9 +652,9 @@ CODESTARTmodExit
objRelease(gssutil, LM_GSSUTIL_FILENAME);
objRelease(tcpclt, LM_TCPCLT_FILENAME);
- if(pszTplName != NULL) {
- free(pszTplName);
- pszTplName = NULL;
+ if(cs.pszTplName != NULL) {
+ free(cs.pszTplName);
+ cs.pszTplName = NULL;
}
ENDmodExit
@@ -658,10 +671,10 @@ static rsRetVal setGSSMode(void __attribute__((unused)) *pVal, uchar *mode)
DEFiRet;
if (!strcmp((char *) mode, "integrity")) {
- gss_mode = GSSMODE_MIC;
+ cs.gss_mode = GSSMODE_MIC;
dbgprintf("GSS-API gssmode set to GSSMODE_MIC\n");
} else if (!strcmp((char *) mode, "encryption")) {
- gss_mode = GSSMODE_ENC;
+ cs.gss_mode = GSSMODE_ENC;
dbgprintf("GSS-API gssmode set to GSSMODE_ENC\n");
} else {
errmsg.LogError(0, RS_RET_INVALID_PARAMS, "unknown gssmode parameter: %s", (char *) mode);
@@ -675,21 +688,18 @@ static rsRetVal setGSSMode(void __attribute__((unused)) *pVal, uchar *mode)
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- gss_mode = GSSMODE_ENC;
- if (gss_base_service_name != NULL) {
- free(gss_base_service_name);
- gss_base_service_name = NULL;
- }
- if(pszTplName != NULL) {
- free(pszTplName);
- pszTplName = NULL;
- }
+ cs.gss_mode = GSSMODE_ENC;
+ free(cs.gss_base_service_name);
+ cs.gss_base_service_name = NULL;
+ free(cs.pszTplName);
+ cs.pszTplName = NULL;
return RS_RET_OK;
}
BEGINmodInit()
CODESTARTmodInit
+SCOPINGmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
@@ -697,10 +707,10 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(gssutil, LM_GSSUTIL_FILENAME));
CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"gssforwardservicename", 0, eCmdHdlrGetWord, NULL, &gss_base_service_name, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"gssmode", 0, eCmdHdlrGetWord, setGSSMode, &gss_mode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"actiongssforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"gssforwardservicename", 0, eCmdHdlrGetWord, NULL, &cs.gss_base_service_name, STD_LOADABLE_MODULE_ID, eConfObjAction));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"gssmode", 0, eCmdHdlrGetWord, setGSSMode, &cs.gss_mode, STD_LOADABLE_MODULE_ID, eConfObjAction));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actiongssforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &cs.pszTplName, STD_LOADABLE_MODULE_ID, eConfObjAction));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjAction));
ENDmodInit
#endif /* #ifdef USE_GSSAPI */
diff --git a/plugins/omhdfs/omhdfs.c b/plugins/omhdfs/omhdfs.c
index 76128a4e..cd14d03c 100644
--- a/plugins/omhdfs/omhdfs.c
+++ b/plugins/omhdfs/omhdfs.c
@@ -51,6 +51,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omhdfs")
/* internal structures
*/
@@ -60,12 +61,18 @@ DEFobjCurrIf(errmsg)
/* global data */
static struct hashtable *files; /* holds all file objects that we know */
-/* globals for default values */
-static uchar *fileName = NULL;
-static uchar *hdfsHost = NULL;
-static uchar *dfltTplName = NULL; /* default template name to use */
-int hdfsPort = 0;
-/* end globals for default values */
+typedef struct configSettings_s {
+ uchar *fileName;
+ uchar *hdfsHost;
+ uchar *dfltTplName; /* default template name to use */
+ int hdfsPort;
+} configSettings_t;
+
+SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ENDinitConfVars
typedef struct {
uchar *name;
@@ -439,22 +446,22 @@ CODESTARTparseSelectorAct
CHKiRet(createInstance(&pData));
CODE_STD_STRING_REQUESTparseSelectorAct(1)
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0,
- (dfltTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : dfltTplName));
+ (cs.dfltTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : cs.dfltTplName));
- if(fileName == NULL) {
+ if(cs.fileName == NULL) {
errmsg.LogError(0, RS_RET_ERR_HDFS_OPEN, "omhdfs: no file name specified, can not continue");
ABORT_FINALIZE(RS_RET_FILE_NOT_SPECIFIED);
}
- pFile = hashtable_search(files, fileName);
+ pFile = hashtable_search(files, cs.fileName);
if(pFile == NULL) {
/* we need a new file object, this one not seen before */
CHKiRet(fileObjConstruct(&pFile));
- CHKmalloc(pFile->name = fileName);
- CHKmalloc(keybuf = ustrdup(fileName));
- fileName = NULL; /* re-set, data passed to file object */
- CHKmalloc(pFile->hdfsHost = strdup((hdfsHost == NULL) ? "default" : (char*) hdfsHost));
- pFile->hdfsPort = hdfsPort;
+ CHKmalloc(pFile->name = cs.fileName);
+ CHKmalloc(keybuf = ustrdup(cs.fileName));
+ cs.fileName = NULL; /* re-set, data passed to file object */
+ CHKmalloc(pFile->hdfsHost = strdup((cs.hdfsHost == NULL) ? "default" : (char*) cs.hdfsHost));
+ pFile->hdfsPort = cs.hdfsPort;
fileOpen(pFile);
if(pFile->fh == NULL){
errmsg.LogError(0, RS_RET_ERR_HDFS_OPEN, "omhdfs: failed to open %s - "
@@ -497,8 +504,12 @@ ENDdoHUP
*/
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- hdfsHost = NULL;
- hdfsPort = 0;
+ cs.hdfsHost = NULL;
+ cs.hdfsPort = 0;
+ free(cs.fileName);
+ cs.fileName = NULL;
+ free(cs.dfltTplName);
+ cs.dfltTplName = NULL;
return RS_RET_OK;
}
@@ -519,6 +530,7 @@ CODEqueryEtryPt_doHUP
ENDqueryEtryPt
+
BEGINmodInit()
CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION;
@@ -527,10 +539,10 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKmalloc(files = create_hashtable(20, hash_from_string, key_equals_string,
fileObjDestruct4Hashtable));
- CHKiRet(regCfSysLineHdlr((uchar *)"omhdfsfilename", 0, eCmdHdlrGetWord, NULL, &fileName, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"omhdfshost", 0, eCmdHdlrGetWord, NULL, &hdfsHost, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"omhdfsport", 0, eCmdHdlrInt, NULL, &hdfsPort, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"omhdfsdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &dfltTplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"omhdfsfilename", 0, eCmdHdlrGetWord, NULL, &cs.fileName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"omhdfshost", 0, eCmdHdlrGetWord, NULL, &cs.hdfsHost, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"omhdfsport", 0, eCmdHdlrInt, NULL, &cs.hdfsPort, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"omhdfsdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &cs.dfltTplName, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
DBGPRINTF("omhdfs: module compiled with rsyslog version %s.\n", VERSION);
CODEmodInit_QueryRegCFSLineHdlr
diff --git a/plugins/omlibdbi/omlibdbi.c b/plugins/omlibdbi/omlibdbi.c
index 4b97da86..44e635c1 100644
--- a/plugins/omlibdbi/omlibdbi.c
+++ b/plugins/omlibdbi/omlibdbi.c
@@ -48,9 +48,11 @@
#include "module-template.h"
#include "debug.h"
#include "errmsg.h"
+#include "conf.h"
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omlibdbi")
/* internal structures
*/
@@ -68,14 +70,28 @@ typedef struct _instanceData {
unsigned uLastDBErrno; /* last errno returned by libdbi or 0 if all is well */
} instanceData;
+typedef struct configSettings_s {
+ uchar *dbiDrvrDir; /* global: where do the dbi drivers reside? */
+ uchar *drvrName; /* driver to use */
+ uchar *host; /* host to connect to */
+ uchar *usrName; /* user name for connect */
+ uchar *pwd; /* password for connect */
+ uchar *dbName; /* database to use */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.dbiDrvrDir = NULL;
+ cs.drvrName = NULL;
+ cs.host = NULL;
+ cs.usrName = NULL;
+ cs.pwd = NULL;
+ cs.dbName = NULL;
+ENDinitConfVars
+
/* config settings */
-static uchar *dbiDrvrDir = NULL;/* global: where do the dbi drivers reside? */
-static uchar *drvrName = NULL; /* driver to use */
-static uchar *host = NULL; /* host to connect to */
-static uchar *usrName = NULL; /* user name for connect */
-static uchar *pwd = NULL; /* password for connect */
-static uchar *dbName = NULL; /* database to use */
#ifdef HAVE_DBI_R
static dbi_inst dbiInst;
#endif
@@ -168,9 +184,9 @@ static rsRetVal initConn(instanceData *pData, int bSilent)
if(bDbiInitialized == 0) {
/* we need to init libdbi first */
# ifdef HAVE_DBI_R
- iDrvrsLoaded = dbi_initialize_r((char*) dbiDrvrDir, &dbiInst);
+ iDrvrsLoaded = dbi_initialize_r((char*) cs.dbiDrvrDir, &dbiInst);
# else
- iDrvrsLoaded = dbi_initialize((char*) dbiDrvrDir);
+ iDrvrsLoaded = dbi_initialize((char*) cs.dbiDrvrDir);
# endif
if(iDrvrsLoaded == 0) {
errmsg.LogError(0, RS_RET_SUSPENDED, "libdbi error: libdbi or libdbi drivers not present on this system - suspending.");
@@ -278,23 +294,23 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
CHKiRet(createInstance(&pData));
/* no create the instance based on what we currently have */
- if(drvrName == NULL) {
+ if(cs.drvrName == NULL) {
errmsg.LogError(0, RS_RET_NO_DRIVERNAME, "omlibdbi: no db driver name given - action can not be created");
ABORT_FINALIZE(RS_RET_NO_DRIVERNAME);
}
- if((pData->drvrName = (uchar*) strdup((char*)drvrName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ if((pData->drvrName = (uchar*) strdup((char*)cs.drvrName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
/* NULL values are supported because drivers have different needs.
* They will err out on connect. -- rgerhards, 2008-02-15
*/
- if(host != NULL)
- if((pData->host = (uchar*) strdup((char*)host)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- if(usrName != NULL)
- if((pData->usrName = (uchar*) strdup((char*)usrName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- if(dbName != NULL)
- if((pData->dbName = (uchar*) strdup((char*)dbName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- if(pwd != NULL)
- if((pData->pwd = (uchar*) strdup((char*)pwd)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ if(cs.host != NULL)
+ if((pData->host = (uchar*) strdup((char*)cs.host)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ if(cs.usrName != NULL)
+ if((pData->usrName = (uchar*) strdup((char*)cs.usrName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ if(cs.dbName != NULL)
+ if((pData->dbName = (uchar*) strdup((char*)cs.dbName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ if(cs.pwd != NULL)
+ if((pData->pwd = (uchar*) strdup((char*)cs.pwd)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_RQD_TPL_OPT_SQL, (uchar*) " StdDBFmt"));
@@ -326,53 +342,35 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
-
- if(dbiDrvrDir != NULL) {
- free(dbiDrvrDir);
- dbiDrvrDir = NULL;
- }
-
- if(drvrName != NULL) {
- free(drvrName);
- drvrName = NULL;
- }
-
- if(host != NULL) {
- free(host);
- host = NULL;
- }
-
- if(usrName != NULL) {
- free(usrName);
- usrName = NULL;
- }
-
- if(pwd != NULL) {
- free(pwd);
- pwd = NULL;
- }
-
- if(dbName != NULL) {
- free(dbName);
- dbName = NULL;
- }
-
+ free(cs.dbiDrvrDir);
+ cs.dbiDrvrDir = NULL;
+ free(cs.drvrName);
+ cs.drvrName = NULL;
+ free(cs.host);
+ cs.host = NULL;
+ free(cs.usrName);
+ cs.usrName = NULL;
+ free(cs.pwd);
+ cs.pwd = NULL;
+ free(cs.dbName);
+ cs.dbName = NULL;
RETiRet;
}
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionlibdbidriverdirectory", 0, eCmdHdlrGetWord, NULL, &dbiDrvrDir, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionlibdbidriver", 0, eCmdHdlrGetWord, NULL, &drvrName, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionlibdbihost", 0, eCmdHdlrGetWord, NULL, &host, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionlibdbiusername", 0, eCmdHdlrGetWord, NULL, &usrName, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionlibdbipassword", 0, eCmdHdlrGetWord, NULL, &pwd, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionlibdbidbname", 0, eCmdHdlrGetWord, NULL, &dbName, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionlibdbidriverdirectory", 0, eCmdHdlrGetWord, NULL, &cs.dbiDrvrDir, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionlibdbidriver", 0, eCmdHdlrGetWord, NULL, &cs.drvrName, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionlibdbihost", 0, eCmdHdlrGetWord, NULL, &cs.host, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionlibdbiusername", 0, eCmdHdlrGetWord, NULL, &cs.usrName, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionlibdbipassword", 0, eCmdHdlrGetWord, NULL, &cs.pwd, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionlibdbidbname", 0, eCmdHdlrGetWord, NULL, &cs.dbName, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
DBGPRINTF("omlibdbi compiled with version %s loaded, libdbi version %s\n", VERSION, dbi_version());
ENDmodInit
diff --git a/plugins/ommail/ommail.c b/plugins/ommail/ommail.c
index 468d8db2..d70fa30a 100644
--- a/plugins/ommail/ommail.c
+++ b/plugins/ommail/ommail.c
@@ -54,6 +54,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("ommail")
/* internal structures
*/
@@ -70,12 +71,6 @@ struct toRcpt_s {
uchar *pszTo;
toRcpt_t *pNext;
};
-static toRcpt_t *lstRcpt = NULL;
-static uchar *pszSrv = NULL;
-static uchar *pszSrvPort = NULL;
-static uchar *pszFrom = NULL;
-static uchar *pszSubject = NULL;
-static int bEnableBody = 1; /* should a mail body be generated? (set to 0 eg for SMS gateways) */
typedef struct _instanceData {
int iMode; /* 0 - smtp, 1 - sendmail */
@@ -95,6 +90,26 @@ typedef struct _instanceData {
} md; /* mode-specific data */
} instanceData;
+typedef struct configSettings_s {
+ toRcpt_t *lstRcpt;
+ uchar *pszSrv;
+ uchar *pszSrvPort;
+ uchar *pszFrom;
+ uchar *pszSubject;
+ int bEnableBody; /* should a mail body be generated? (set to 0 eg for SMS gateways) */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.lstRcpt = NULL;
+ cs.pszSrv = NULL;
+ cs.pszSrvPort = NULL;
+ cs.pszFrom = NULL;
+ cs.pszSubject = NULL;
+ cs.bEnableBody = 1; /* should a mail body be generated? (set to 0 eg for SMS gateways) */
+ENDinitConfVars
+
/* forward definitions (as few as possible) */
static rsRetVal Send(int sock, char *msg, size_t len);
static rsRetVal readResponse(instanceData *pData, int *piState, int iExpected);
@@ -128,8 +143,8 @@ addRcpt(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKmalloc(pNew = calloc(1, sizeof(toRcpt_t)));
pNew->pszTo = pNewVal;
- pNew->pNext = lstRcpt;
- lstRcpt = pNew;
+ pNew->pNext = cs.lstRcpt;
+ cs.lstRcpt = pNew;
dbgprintf("ommail::addRcpt adds recipient %s\n", pNewVal);
@@ -608,32 +623,32 @@ CODESTARTparseSelectorAct
/* TODO: check strdup() result */
- if(pszFrom == NULL) {
+ if(cs.pszFrom == NULL) {
errmsg.LogError(0, RS_RET_MAIL_NO_FROM, "no sender address given - specify $ActionMailFrom");
ABORT_FINALIZE(RS_RET_MAIL_NO_FROM);
}
- if(lstRcpt == NULL) {
+ if(cs.lstRcpt == NULL) {
errmsg.LogError(0, RS_RET_MAIL_NO_TO, "no recipient address given - specify $ActionMailTo");
ABORT_FINALIZE(RS_RET_MAIL_NO_TO);
}
- pData->md.smtp.pszFrom = (uchar*) strdup((char*)pszFrom);
- pData->md.smtp.lstRcpt = lstRcpt; /* we "hand over" this memory */
- lstRcpt = NULL; /* note: this is different from pre-3.21.2 versions! */
+ pData->md.smtp.pszFrom = (uchar*) strdup((char*)cs.pszFrom);
+ pData->md.smtp.lstRcpt = cs.lstRcpt; /* we "hand over" this memory */
+ cs.lstRcpt = NULL; /* note: this is different from pre-3.21.2 versions! */
- if(pszSubject == NULL) {
+ if(cs.pszSubject == NULL) {
/* if no subject is configured, we need just one template string */
CODE_STD_STRING_REQUESTparseSelectorAct(1)
} else {
CODE_STD_STRING_REQUESTparseSelectorAct(2)
pData->bHaveSubject = 1;
- CHKiRet(OMSRsetEntry(*ppOMSR, 1, (uchar*)strdup((char*) pszSubject), OMSR_NO_RQD_TPL_OPTS));
+ CHKiRet(OMSRsetEntry(*ppOMSR, 1, (uchar*)strdup((char*) cs.pszSubject), OMSR_NO_RQD_TPL_OPTS));
}
- if(pszSrv != NULL)
- pData->md.smtp.pszSrv = (uchar*) strdup((char*)pszSrv);
- if(pszSrvPort != NULL)
- pData->md.smtp.pszSrvPort = (uchar*) strdup((char*)pszSrvPort);
- pData->bEnableBody = bEnableBody;
+ if(cs.pszSrv != NULL)
+ pData->md.smtp.pszSrv = (uchar*) strdup((char*)cs.pszSrv);
+ if(cs.pszSrvPort != NULL)
+ pData->md.smtp.pszSrvPort = (uchar*) strdup((char*)cs.pszSrvPort);
+ pData->bEnableBody = cs.bEnableBody;
/* process template */
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar*) "RSYSLOG_FileFormat"));
@@ -646,20 +661,14 @@ static rsRetVal freeConfigVariables(void)
{
DEFiRet;
- if(pszSrv != NULL) {
- free(pszSrv);
- pszSrv = NULL;
- }
- if(pszSrvPort != NULL) {
- free(pszSrvPort);
- pszSrvPort = NULL;
- }
- if(pszFrom != NULL) {
- free(pszFrom);
- pszFrom = NULL;
- }
- lstRcptDestruct(lstRcpt);
- lstRcpt = NULL;
+ free(cs.pszSrv);
+ cs.pszSrv = NULL;
+ free(cs.pszSrvPort);
+ cs.pszSrvPort = NULL;
+ free(cs.pszFrom);
+ cs.pszFrom = NULL;
+ lstRcptDestruct(cs.lstRcpt);
+ cs.lstRcpt = NULL;
RETiRet;
}
@@ -688,7 +697,7 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
- bEnableBody = 1;
+ cs.bEnableBody = 1;
iRet = freeConfigVariables();
RETiRet;
}
@@ -696,6 +705,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
/* tell which objects we need */
@@ -705,12 +715,12 @@ CODEmodInit_QueryRegCFSLineHdlr
dbgprintf("ommail version %s initializing\n", VERSION);
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsmtpserver", 0, eCmdHdlrGetWord, NULL, &pszSrv, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsmtpport", 0, eCmdHdlrGetWord, NULL, &pszSrvPort, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailfrom", 0, eCmdHdlrGetWord, NULL, &pszFrom, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsmtpserver", 0, eCmdHdlrGetWord, NULL, &cs.pszSrv, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsmtpport", 0, eCmdHdlrGetWord, NULL, &cs.pszSrvPort, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailfrom", 0, eCmdHdlrGetWord, NULL, &cs.pszFrom, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailto", 0, eCmdHdlrGetWord, addRcpt, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsubject", 0, eCmdHdlrGetWord, NULL, &pszSubject, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailenablebody", 0, eCmdHdlrBinary, NULL, &bEnableBody, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsubject", 0, eCmdHdlrGetWord, NULL, &cs.pszSubject, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailenablebody", 0, eCmdHdlrBinary, NULL, &cs.bEnableBody, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr( (uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/ommongodb/Makefile.am b/plugins/ommongodb/Makefile.am
new file mode 100644
index 00000000..1b0e23a1
--- /dev/null
+++ b/plugins/ommongodb/Makefile.am
@@ -0,0 +1,11 @@
+mongodir = ./mongo-c-driver/src
+pkglib_LTLIBRARIES = ommongodb.la
+
+ommongodb_la_SOURCES = ommongodb.c
+ommongodb_la_SOURCES += $(mongodir)/bson.c $(mongodir)/mongo.c $(mongodir)/md5.c $(mongodir)/numbers.c
+
+ommongodb_la_CPPFLAGS = -DMONGO_HAVE_STDINT -Imongo-c-driver/src $(RSRT_CFLAGS) $(PTHREADS_CFLAGS)
+ommongodb_la_LDFLAGS = -module -avoid-version
+ommongodb_la_LIBADD =
+
+EXTRA_DIST =
diff --git a/plugins/ommongodb/README b/plugins/ommongodb/README
new file mode 100644
index 00000000..cea3f3bc
--- /dev/null
+++ b/plugins/ommongodb/README
@@ -0,0 +1,23 @@
+plugin to use MongoDB as backend.
+
+tested in ubuntu 10.04 and ubuntu 10.10
+
+configuration:
+
+in your /etc/rsyslog.conf, together with other modules:
+$ModLoad ommongodb # provides mongodb support
+
+then in your /etc/rsyslog.d (check your distribution way to organize the configuration..) you create a file 10-mongodb.conf with the following content:
+
+#the format for the driver is :ommongodb:ip:db:collection;StdMongoDBFmt
+#if you want to change what is logged in the db, the template, you must change the source code since the keys are hardcoded
+$template StdMongoDBFmt,"%msg%%syslogfacility%%HOSTNAME%%syslogpriority%"
+*.* :ommongodb:127.0.0.1,syslog,logs;StdMongoDBFmt
+
+
+TODO
+we must ensure that the collection is a capped collection
+refactor my code :-)
+
+email Victor Pereira <victor.pereira@bigrails.com>
+twitter twitter.com/vpereira
diff --git a/plugins/ommongodb/ommongodb.c b/plugins/ommongodb/ommongodb.c
new file mode 100644
index 00000000..07050c14
--- /dev/null
+++ b/plugins/ommongodb/ommongodb.c
@@ -0,0 +1,281 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include <time.h>
+#include "bson.h"
+#include "mongo.h"
+#include "config.h"
+#include "rsyslog.h"
+#include "conf.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "template.h"
+#include "module-template.h"
+#include "errmsg.h"
+#include "cfsysline.h"
+#include "mongo-c-driver/src/mongo.h"
+
+#define countof(X) ( (size_t) ( sizeof(X)/sizeof*(X) ) )
+
+#define DEFAULT_SERVER "127.0.0.1"
+#define DEFAULT_DATABASE "syslog"
+#define DEFAULT_COLLECTION "log"
+#define DEFAULT_DB_COLLECTION "syslog.log"
+
+//i just defined some constants, i couldt not find the limit
+#define MONGO_DB_NAME_SIZE 128
+#define MONGO_COLLECTION_NAME_SIZE 128
+
+MODULE_TYPE_OUTPUT
+MODULE_CNFNAME("ommongodb")
+/* internal structures
+ */
+DEF_OMOD_STATIC_DATA
+DEFobjCurrIf(errmsg)
+
+typedef struct _instanceData {
+ mongo_connection conn[1]; /* ptr */
+ mongo_connection_options opts[1];
+ mongo_conn_return status;
+ char db[MONGO_DB_NAME_SIZE];
+ char collection[MONGO_COLLECTION_NAME_SIZE];
+ char dbcollection[MONGO_DB_NAME_SIZE + MONGO_COLLECTION_NAME_SIZE + 1];
+ unsigned uLastMongoDBErrno;
+ //unsigned iSrvPort; /* sample: server port */
+} instanceData;
+
+char db[_DB_MAXDBLEN+2];
+static int iSrvPort = 27017;
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ /* use this to specify if select features are supported by this
+ * plugin. If not, the framework will handle that. Currently, only
+ * RepeatedMsgReduction ("last message repeated n times") is optional.
+ */
+ if(eFeat == sFEATURERepeatedMsgReduction)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
+static void closeMongoDB(instanceData *pData)
+{
+ ASSERT(pData != NULL);
+
+ if(pData->conn != NULL) {
+ mongo_destroy( pData->conn );
+ memset(pData->conn,0x00,sizeof(mongo_connection));
+ }
+}
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ closeMongoDB(pData);
+ENDfreeInstance
+
+BEGINdbgPrintInstInfo
+CODESTARTdbgPrintInstInfo
+ /* nothing special here */
+ENDdbgPrintInstInfo
+
+/* log a database error with descriptive message.
+ * We check if we have a valid MongoDB handle. If not, we simply
+ * report an error
+ */
+static void reportDBError(instanceData *pData, int bSilent)
+{
+ char errMsg[512];
+ bson ErrObj;
+
+ ASSERT(pData != NULL);
+
+ /* output log message */
+ errno = 0;
+ if(pData->conn == NULL) {
+ errmsg.LogError(0, NO_ERRCODE, "unknown DB error occured - could not obtain MongoDB handle");
+ } else { /* we can ask mysql for the error description... */
+ //we should handle the error. if bSilent is set then we should print as debug
+ mongo_cmd_get_last_error(pData->conn, pData->db, &ErrObj);
+ bson_destroy(&ErrObj);
+ }
+
+ return;
+}
+
+/* The following function is responsible for initializing a
+ * MySQL connection.
+ * Initially added 2004-10-28 mmeckelein
+ */
+static rsRetVal initMongoDB(instanceData *pData, int bSilent)
+{
+ DEFiRet;
+
+ ASSERT(pData != NULL);
+ ASSERT(pData->conn == NULL);
+
+ //I'm trying to fallback to a default here
+ if(pData->opts->port == 0)
+ pData->opts->port = 27017;
+
+ if(pData->opts->host == 0x00)
+ strcpy(pData->opts->host,DEFAULT_SERVER);
+
+ if(pData->dbcollection == 0x00)
+ strcpy(pData->dbcollection,DEFAULT_DB_COLLECTION);
+
+ pData->status = mongo_connect(pData->conn, pData->opts );
+
+ switch (pData->status) {
+ case mongo_conn_success:
+ fprintf(stderr, "connection succeeded\n" );
+ iRet = RS_RET_OK;
+ break;
+ case mongo_conn_bad_arg:
+ errmsg.LogError(0, RS_RET_SUSPENDED, "can not initialize MongoDB handle");
+ fprintf(stderr, "bad arguments\n" );
+ iRet = RS_RET_SUSPENDED;
+ break;
+ case mongo_conn_no_socket:
+ errmsg.LogError(0, RS_RET_SUSPENDED, "can not initialize MongoDB handle");
+ fprintf(stderr, "no socket\n" );
+ iRet = RS_RET_SUSPENDED;
+ break;
+ case mongo_conn_fail:
+ errmsg.LogError(0, RS_RET_SUSPENDED, "can not initialize MongoDB handle");
+ fprintf(stderr, "connection failed\n" );
+ iRet = RS_RET_SUSPENDED;
+ break;
+ case mongo_conn_not_master:
+ errmsg.LogError(0, RS_RET_SUSPENDED, "can not initialize MongoDB handle");
+ fprintf(stderr, "not master\n" );
+ iRet = RS_RET_SUSPENDED;
+ break;
+ }
+ RETiRet;
+}
+
+//we must implement it
+rsRetVal writeMongoDB(uchar *psz, instanceData *pData)
+{
+ char mydate[32];
+ char **szParams;
+ bson b[1];
+ bson_buffer buf[1];
+ bson_buffer_init( buf );
+ bson_append_new_oid(buf, "_id" );
+ memset(mydate,0x00,32);
+
+
+ DEFiRet;
+
+ ASSERT(psz != NULL);
+ ASSERT(pData != NULL);
+
+
+ /* see if we are ready to proceed */
+ if(pData->conn == NULL) {
+ CHKiRet(initMongoDB(pData, 0));
+ }
+
+szParams = (char**)(void*) psz;
+//We can make it beter
+//if you change the fields in your template, we must update it here
+//there is any C_metaprogramming_ninja there? :-)
+if(countof(szParams) > 0)
+{
+ bson_append_string( buf, "msg", szParams[0]);
+ bson_append_string( buf, "facility",szParams[1]);
+ bson_append_string( buf, "hostname", szParams[2] );
+ bson_append_string(buf, "priority",szParams[3]);
+ bson_append_int(buf,"count",countof(szParams));
+ bson_from_buffer( b, buf );
+ mongo_insert(pData->conn, pData->dbcollection, b );
+}
+
+if(b)
+ bson_destroy(b);
+
+
+ finalize_it:
+ if(iRet == RS_RET_OK) {
+ pData->uLastMongoDBErrno = 0; /* reset error for error supression */
+ }
+
+
+ RETiRet;
+}
+
+BEGINtryResume
+CODESTARTtryResume
+ if(pData->conn == NULL) {
+ iRet = initMongoDB(pData, 1);
+ }
+ENDtryResume
+
+BEGINdoAction
+CODESTARTdoAction
+ iRet = writeMongoDB(ppString[0], pData);
+ENDdoAction
+
+BEGINparseSelectorAct
+ //int iMongoDBPropErr = 0;
+CODESTARTparseSelectorAct
+CODE_STD_STRING_REQUESTparseSelectorAct(1)
+
+ if(!strncmp((char*) p, ":ommongodb:", sizeof(":ommongodb:") - 1)) {
+ p += sizeof(":ommongodb:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
+ } else {
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+ }
+
+ CHKiRet(createInstance(&pData));
+
+ if(getSubString(&p, pData->opts->host, MAXHOSTNAMELEN+1, ','))
+ strcpy(pData->opts->host,DEFAULT_SERVER);
+
+ //we must define the max db name
+ if(getSubString(&p,pData->db,255,','))
+ strcpy(pData->db,DEFAULT_DATABASE);
+ if(getSubString(&p,pData->collection,255,';'))
+ strcpy(pData->collection,DEFAULT_COLLECTION);
+ if(*(p-1) == ';')
+ --p;
+
+
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_ARRAY, (uchar*) " StdMongoDBFmt"));
+
+
+ pData->opts->port = (unsigned) iSrvPort; /* set configured port */
+ sprintf(pData->dbcollection,"%s.%s",pData->db,pData->collection);
+ CHKiRet(initMongoDB(pData, 0));
+
+CODE_STD_FINALIZERparseSelectorAct
+ENDparseSelectorAct
+
+
+BEGINmodExit
+CODESTARTmodExit
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING);
+ DBGPRINTF("ompgsql: module compiled with rsyslog version %s.\n", VERSION);
+ DBGPRINTF("ompgsql: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not ");
+ENDmodInit
diff --git a/plugins/ommysql/ommysql.c b/plugins/ommysql/ommysql.c
index f8bb4aa6..50ebf3a3 100644
--- a/plugins/ommysql/ommysql.c
+++ b/plugins/ommysql/ommysql.c
@@ -47,6 +47,9 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("ommysql")
+
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
/* internal structures
*/
@@ -54,21 +57,28 @@ DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
typedef struct _instanceData {
- MYSQL *f_hmysql; /* handle to MySQL */
+ MYSQL *f_hmysql; /* handle to MySQL */
char f_dbsrv[MAXHOSTNAMELEN+1]; /* IP or hostname of DB server*/
unsigned int f_dbsrvPort; /* port of MySQL server */
char f_dbname[_DB_MAXDBLEN+1]; /* DB name */
char f_dbuid[_DB_MAXUNAMELEN+1]; /* DB user */
char f_dbpwd[_DB_MAXPWDLEN+1]; /* DB user's password */
- unsigned uLastMySQLErrno; /* last errno returned by MySQL or 0 if all is well */
- uchar * f_configfile; /* MySQL Client Configuration File */
- uchar * f_configsection; /* MySQL Client Configuration Section */
+ unsigned uLastMySQLErrno; /* last errno returned by MySQL or 0 if all is well */
+ uchar * f_configfile; /* MySQL Client Configuration File */
+ uchar * f_configsection; /* MySQL Client Configuration Section */
} instanceData;
-/* config variables */
-static uchar * pszMySQLConfigFile = NULL; /* MySQL Client Configuration File */
-static uchar * pszMySQLConfigSection = NULL; /* MySQL Client Configuration Section */
-static int iSrvPort = 0; /* database server port */
+typedef struct configSettings_s {
+ int iSrvPort; /* database server port */
+ uchar *pszMySQLConfigFile; /* MySQL Client Configuration File */
+ uchar *pszMySQLConfigSection; /* MySQL Client Configuration Section */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ resetConfigVariables(NULL, NULL);
+ENDinitConfVars
BEGINcreateInstance
@@ -309,9 +319,9 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
errmsg.LogError(0, RS_RET_INVALID_PARAMS, "Trouble with MySQL connection properties. -MySQL logging disabled");
ABORT_FINALIZE(RS_RET_INVALID_PARAMS);
} else {
- pData->f_dbsrvPort = (unsigned) iSrvPort; /* set configured port */
- pData->f_configfile = pszMySQLConfigFile;
- pData->f_configsection = pszMySQLConfigSection;
+ pData->f_dbsrvPort = (unsigned) cs.iSrvPort; /* set configured port */
+ pData->f_configfile = cs.pszMySQLConfigFile;
+ pData->f_configsection = cs.pszMySQLConfigSection;
pData->f_hmysql = NULL; /* initialize, but connect only on first message (important for queued mode!) */
}
@@ -335,24 +345,25 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
- iSrvPort = 0; /* zero is the default port */
- free(pszMySQLConfigFile);
- pszMySQLConfigFile = NULL;
- free(pszMySQLConfigSection);
- pszMySQLConfigSection = NULL;
+ cs.iSrvPort = 0; /* zero is the default port */
+ free(cs.pszMySQLConfigFile);
+ cs.pszMySQLConfigFile = NULL;
+ free(cs.pszMySQLConfigSection);
+ cs.pszMySQLConfigSection = NULL;
RETiRet;
}
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
/* register our config handlers */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionommysqlserverport", 0, eCmdHdlrInt, NULL, &iSrvPort, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionommysqlserverport", 0, eCmdHdlrInt, NULL, &cs.iSrvPort, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"ommysqlconfigfile",0,eCmdHdlrGetWord,NULL,&cs.pszMySQLConfigFile,STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"ommysqlconfigsection",0,eCmdHdlrGetWord,NULL,&cs.pszMySQLConfigSection,STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"ommysqlconfigfile",0,eCmdHdlrGetWord,NULL,&pszMySQLConfigFile,STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"ommysqlconfigsection",0,eCmdHdlrGetWord,NULL,&pszMySQLConfigSection,STD_LOADABLE_MODULE_ID));
ENDmodInit
/* vi:set ai:
diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c
index a37533ee..736629a6 100644
--- a/plugins/omoracle/omoracle.c
+++ b/plugins/omoracle/omoracle.c
@@ -83,6 +83,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omoracle")
/** */
DEF_OMOD_STATIC_DATA
diff --git a/plugins/ompgsql/ompgsql.c b/plugins/ompgsql/ompgsql.c
index ea4b4b75..11f346f6 100644
--- a/plugins/ompgsql/ompgsql.c
+++ b/plugins/ompgsql/ompgsql.c
@@ -50,6 +50,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("ompgsql")
/* internal structures
*/
@@ -65,6 +66,15 @@ typedef struct _instanceData {
ConnStatusType eLastPgSQLStatus; /* last status from postgres */
} instanceData;
+typedef struct configSettings_s {
+ EMPTY_STRUCT
+} configSettings_t;
+static configSettings_t __attribute__((unused)) cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ENDinitConfVars
+
static rsRetVal writePgSQL(uchar *psz, instanceData *pData);
@@ -357,6 +367,7 @@ ENDqueryEtryPt
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
diff --git a/plugins/omprog/omprog.c b/plugins/omprog/omprog.c
index db461a00..1f6bb62f 100644
--- a/plugins/omprog/omprog.c
+++ b/plugins/omprog/omprog.c
@@ -45,6 +45,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omprog")
/* internal structures
*/
@@ -58,8 +59,17 @@ typedef struct _instanceData {
int bIsRunning; /* is binary currently running? 0-no, 1-yes */
} instanceData;
+typedef struct configSettings_s {
+ uchar *szBinary; /* name of binary to call */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.szBinary = NULL; /* name of binary to call */
+ENDinitConfVars
+
/* config settings */
-static uchar *szBinary = NULL; /* name of binary to call */
BEGINcreateInstance
CODESTARTcreateInstance
@@ -300,7 +310,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
p += sizeof(":omprog:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
CHKiRet(createInstance(&pData));
- CHKmalloc(pData->szBinary = (uchar*) strdup((char*)szBinary));
+ CHKmalloc(pData->szBinary = (uchar*) strdup((char*)cs.szBinary));
/* check if a non-standard template is to be applied */
if(*(p-1) == ';')
--p;
@@ -311,10 +321,8 @@ ENDparseSelectorAct
BEGINmodExit
CODESTARTmodExit
- if(szBinary != NULL) {
- free(szBinary);
- szBinary = NULL;
- }
+ free(cs.szBinary);
+ cs.szBinary = NULL;
CHKiRet(objRelease(errmsg, CORE_COMPONENT));
finalize_it:
ENDmodExit
@@ -332,22 +340,19 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
-
- if(szBinary != NULL) {
- free(szBinary);
- szBinary = NULL;
- }
-
+ free(cs.szBinary);
+ cs.szBinary = NULL;
RETiRet;
}
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomprogbinary", 0, eCmdHdlrGetWord, NULL, &szBinary, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomprogbinary", 0, eCmdHdlrGetWord, NULL, &cs.szBinary, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
CODEmodInit_QueryRegCFSLineHdlr
ENDmodInit
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index 95c15f5d..39ffe7fb 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -46,6 +46,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omrelp")
/* internal structures
*/
@@ -64,6 +65,15 @@ typedef struct _instanceData {
relpClt_t *pRelpClt; /* relp client for this instance */
} instanceData;
+typedef struct configSettings_s {
+ EMPTY_STRUCT
+} configSettings_t;
+static configSettings_t __attribute__((unused)) cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ENDinitConfVars
+
/* get the syslog forward port from selector_t. The passed in
* struct must be one that is setup for forwarding.
* rgerhards, 2007-06-28
@@ -336,6 +346,7 @@ ENDqueryEtryPt
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
/* create our relp engine */
diff --git a/plugins/omruleset/omruleset.c b/plugins/omruleset/omruleset.c
index c439bd83..67aee97e 100644
--- a/plugins/omruleset/omruleset.c
+++ b/plugins/omruleset/omruleset.c
@@ -50,6 +50,9 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omruleset")
+
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
/* static data */
DEFobjCurrIf(ruleset);
@@ -60,8 +63,6 @@ DEFobjCurrIf(errmsg);
DEF_OMOD_STATIC_DATA
/* config variables */
-ruleset_t *pRuleset = NULL; /* ruleset to enqueue message to (NULL = Default, not recommended) */
-uchar *pszRulesetName = NULL;
typedef struct _instanceData {
@@ -69,6 +70,17 @@ typedef struct _instanceData {
uchar *pszRulesetName; /* primarily for debugging/display purposes */
} instanceData;
+typedef struct configSettings_s {
+ ruleset_t *pRuleset; /* ruleset to enqueue message to (NULL = Default, not recommended) */
+ uchar *pszRulesetName;
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ resetConfigVariables(NULL, NULL);
+ENDinitConfVars
+
BEGINcreateInstance
CODESTARTcreateInstance
@@ -119,12 +131,12 @@ setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
rsRetVal localRet;
DEFiRet;
- localRet = ruleset.GetRuleset(&pRuleset, pszName);
+ localRet = ruleset.GetRuleset(ourConf, &cs.pRuleset, pszName);
if(localRet == RS_RET_NOT_FOUND) {
errmsg.LogError(0, RS_RET_RULESET_NOT_FOUND, "error: ruleset '%s' not found - ignored", pszName);
}
CHKiRet(localRet);
- pszRulesetName = pszName; /* save for later display purposes */
+ cs.pszRulesetName = pszName; /* save for later display purposes */
finalize_it:
if(iRet != RS_RET_OK) { /* cleanup needed? */
@@ -143,7 +155,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
}
- if(pRuleset == NULL) {
+ if(cs.pRuleset == NULL) {
errmsg.LogError(0, RS_RET_NO_RULESET, "error: no ruleset was specified, use "
"$ActionOmrulesetRulesetName directive first!");
ABORT_FINALIZE(RS_RET_NO_RULESET);
@@ -161,17 +173,17 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
* the format specified (if any) is always ignored.
*/
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, iTplOpts, (uchar*) "RSYSLOG_FileFormat"));
- pData->pRuleset = pRuleset;
- pData->pszRulesetName = pszRulesetName;
- pRuleset = NULL; /* re-set, because there is a high risk of unwanted behavior if we leave it in! */
- pszRulesetName = NULL; /* note: we must not free, as we handed over this pointer to the instanceDat to the instanceDataa! */
+ pData->pRuleset = cs.pRuleset;
+ pData->pszRulesetName = cs.pszRulesetName;
+ cs.pRuleset = NULL; /* re-set, because there is a high risk of unwanted behavior if we leave it in! */
+ cs.pszRulesetName = NULL; /* note: we must not free, as we handed over this pointer to the instanceDat to the instanceDataa! */
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
BEGINmodExit
CODESTARTmodExit
- free(pszRulesetName);
+ free(cs.pszRulesetName);
objRelease(errmsg, CORE_COMPONENT);
objRelease(ruleset, CORE_COMPONENT);
ENDmodExit
@@ -189,7 +201,9 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
- pRuleset = NULL;
+ cs.pRuleset = NULL;
+ free(cs.pszRulesetName);
+ cs.pszRulesetName = NULL;
RETiRet;
}
@@ -200,6 +214,7 @@ BEGINmodInit()
unsigned long opts;
int bMsgPassingSupported; /* does core support template passing as an array? */
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
/* check if the rsyslog core supports parameter passing code */
diff --git a/plugins/omsnmp/omsnmp.c b/plugins/omsnmp/omsnmp.c
index 11870579..80230789 100644
--- a/plugins/omsnmp/omsnmp.c
+++ b/plugins/omsnmp/omsnmp.c
@@ -44,6 +44,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omsnmp")
/* internal structures
*/
@@ -58,27 +59,6 @@ static oid objid_sysdescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
static oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
static oid objid_sysuptime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
-static uchar* pszTransport = NULL; /* default transport */
-static uchar* pszTarget = NULL;
-/* note using an unsigned for a port number is not a good idea from an IPv6 point of view */
-static int iPort = 0;
-static int iSNMPVersion = 1; /* 0 Means SNMPv1, 1 Means SNMPv2c */
-static uchar* pszCommunity = NULL;
-static uchar* pszEnterpriseOID = NULL;
-static uchar* pszSnmpTrapOID = NULL;
-static uchar* pszSyslogMessageOID = NULL;
-static int iSpecificType = 0;
-static int iTrapType = SNMP_TRAP_ENTERPRISESPECIFIC;/*Default is SNMP_TRAP_ENTERPRISESPECIFIC */
-/*
- Possible Values
- SNMP_TRAP_COLDSTART (0)
- SNMP_TRAP_WARMSTART (1)
- SNMP_TRAP_LINKDOWN (2)
- SNMP_TRAP_LINKUP (3)
- SNMP_TRAP_AUTHFAIL (4)
- SNMP_TRAP_EGPNEIGHBORLOSS (5)
- SNMP_TRAP_ENTERPRISESPECIFIC (6)
-*/
typedef struct _instanceData {
uchar szTransport[OMSNMP_MAXTRANSPORLENGTH+1]; /* Transport - Can be udp, tcp, udp6, tcp6 and other types supported by NET-SNMP */
@@ -103,6 +83,46 @@ typedef struct _instanceData {
netsnmp_session *snmpsession; /* Holds to SNMP Session, NULL if not initialized */
} instanceData;
+typedef struct configSettings_s {
+ uchar* pszTransport; /* default transport */
+ uchar* pszTarget;
+ /* note using an unsigned for a port number is not a good idea from an IPv6 point of view */
+ int iPort;
+ int iSNMPVersion; /* 0 Means SNMPv1, 1 Means SNMPv2c */
+ uchar* pszCommunity;
+ uchar* pszEnterpriseOID;
+ uchar* pszSnmpTrapOID;
+ uchar* pszSyslogMessageOID;
+ int iSpecificType;
+ int iTrapType; /*Default is SNMP_TRAP_ENTERPRISESPECIFIC */
+ /*
+ Possible Values
+ SNMP_TRAP_COLDSTART (0)
+ SNMP_TRAP_WARMSTART (1)
+ SNMP_TRAP_LINKDOWN (2)
+ SNMP_TRAP_LINKUP (3)
+ SNMP_TRAP_AUTHFAIL (4)
+ SNMP_TRAP_EGPNEIGHBORLOSS (5)
+ SNMP_TRAP_ENTERPRISESPECIFIC (6)
+ */
+} configSettings_t;
+
+SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.pszTransport = NULL;
+ cs.pszTarget = NULL;
+ cs.iPort = 0;
+ cs.iSNMPVersion = 1;
+ cs.pszCommunity = NULL;
+ cs.pszEnterpriseOID = NULL;
+ cs.pszSnmpTrapOID = NULL;
+ cs.pszSyslogMessageOID = NULL;
+ cs.iSpecificType = 0;
+ cs.iTrapType = SNMP_TRAP_ENTERPRISESPECIFIC;
+ENDinitConfVars
+
BEGINcreateInstance
CODESTARTcreateInstance
ENDcreateInstance
@@ -349,72 +369,72 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
FINALIZE;
/* Check Transport */
- if (pszTransport == NULL) {
+ if (cs.pszTransport == NULL) {
/*
* Default transport is UDP. Other values supported by NETSNMP are possible as well
*/
strncpy( (char*) pData->szTransport, "udp", sizeof("udp") );
} else {
/* Copy Transport */
- strncpy( (char*) pData->szTransport, (char*) pszTransport, strlen((char*) pszTransport) );
+ strncpy( (char*) pData->szTransport, (char*) cs.pszTransport, strlen((char*) cs.pszTransport) );
}
/* Check Target */
- if (pszTarget == NULL) {
+ if (cs.pszTarget == NULL) {
ABORT_FINALIZE( RS_RET_PARAM_ERROR );
} else {
/* Copy Target */
- CHKmalloc(pData->szTarget = (uchar*) strdup((char*)pszTarget));
+ CHKmalloc(pData->szTarget = (uchar*) strdup((char*)cs.pszTarget));
}
/* Copy Community */
- if (pszCommunity == NULL) /* Failsave */
+ if (cs.pszCommunity == NULL) /* Failsave */
strncpy( (char*) pData->szCommunity, "public", sizeof("public") );
else /* Copy Target */
- strncpy( (char*) pData->szCommunity, (char*) pszCommunity, strlen((char*) pszCommunity) );
+ strncpy( (char*) pData->szCommunity, (char*) cs.pszCommunity, strlen((char*) cs.pszCommunity) );
/* Copy Enterprise OID */
- if (pszEnterpriseOID == NULL) /* Failsave */
+ if (cs.pszEnterpriseOID == NULL) /* Failsave */
strncpy( (char*) pData->szEnterpriseOID, "1.3.6.1.4.1.3.1.1", sizeof("1.3.6.1.4.1.3.1.1") );
else /* Copy Target */
- strncpy( (char*) pData->szEnterpriseOID, (char*) pszEnterpriseOID, strlen((char*) pszEnterpriseOID) );
+ strncpy( (char*) pData->szEnterpriseOID, (char*) cs.pszEnterpriseOID, strlen((char*) cs.pszEnterpriseOID) );
/* Copy SnmpTrap OID */
- if (pszSnmpTrapOID == NULL) /* Failsave */
+ if (cs.pszSnmpTrapOID == NULL) /* Failsave */
strncpy( (char*) pData->szSnmpTrapOID, "1.3.6.1.4.1.19406.1.2.1", sizeof("1.3.6.1.4.1.19406.1.2.1") );
else /* Copy Target */
- strncpy( (char*) pData->szSnmpTrapOID, (char*) pszSnmpTrapOID, strlen((char*) pszSnmpTrapOID) );
+ strncpy( (char*) pData->szSnmpTrapOID, (char*) cs.pszSnmpTrapOID, strlen((char*) cs.pszSnmpTrapOID) );
/* Copy SyslogMessage OID */
- if (pszSyslogMessageOID == NULL) /* Failsave */
+ if (cs.pszSyslogMessageOID == NULL) /* Failsave */
strncpy( (char*) pData->szSyslogMessageOID, "1.3.6.1.4.1.19406.1.1.2.1", sizeof("1.3.6.1.4.1.19406.1.1.2.1") );
else /* Copy Target */
- strncpy( (char*) pData->szSyslogMessageOID, (char*) pszSyslogMessageOID, strlen((char*) pszSyslogMessageOID) );
+ strncpy( (char*) pData->szSyslogMessageOID, (char*) cs.pszSyslogMessageOID, strlen((char*) cs.pszSyslogMessageOID) );
/* Copy Port */
- if ( iPort == 0) /* If no Port is set we use the default Port 162 */
+ if ( cs.iPort == 0) /* If no Port is set we use the default Port 162 */
pData->iPort = 162;
else
- pData->iPort = iPort;
+ pData->iPort = cs.iPort;
/* Set SNMPVersion */
- if ( iSNMPVersion < 0 || iSNMPVersion > 1) /* Set default to 1 if out of range */
+ if ( cs.iSNMPVersion < 0 || cs.iSNMPVersion > 1) /* Set default to 1 if out of range */
pData->iSNMPVersion = 1;
else
- pData->iSNMPVersion = iSNMPVersion;
+ pData->iSNMPVersion = cs.iSNMPVersion;
/* Copy SpecificType */
- if ( iSpecificType == 0) /* If no iSpecificType is set, we use the default 0 */
+ if ( cs.iSpecificType == 0) /* If no iSpecificType is set, we use the default 0 */
pData->iSpecificType = 0;
else
- pData->iSpecificType = iSpecificType;
+ pData->iSpecificType = cs.iSpecificType;
/* Copy TrapType */
- if ( iTrapType < 0 && iTrapType >= 6) /* Only allow values from 0 to 6 !*/
+ if ( cs.iTrapType < 0 && cs.iTrapType >= 6) /* Only allow values from 0 to 6 !*/
pData->iTrapType = SNMP_TRAP_ENTERPRISESPECIFIC;
else
- pData->iTrapType = iTrapType;
+ pData->iTrapType = cs.iTrapType;
/* Create string for session peername! */
snprintf((char*)szTargetAndPort, sizeof(szTargetAndPort), "%s:%s:%d", pData->szTransport, pData->szTarget, pData->iPort);
@@ -453,48 +473,31 @@ ENDparseSelectorAct
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
-
- if (pszTarget != NULL)
- free(pszTarget);
- pszTarget = NULL;
-
- if (pszCommunity != NULL)
- free(pszCommunity);
- pszCommunity = NULL;
-
- if (pszEnterpriseOID != NULL)
- free(pszEnterpriseOID);
- pszEnterpriseOID = NULL;
-
- if (pszSnmpTrapOID != NULL)
- free(pszSnmpTrapOID);
- pszSnmpTrapOID = NULL;
-
- if (pszSyslogMessageOID != NULL)
- free(pszSyslogMessageOID);
- pszSyslogMessageOID = NULL;
-
- iPort = 0;
- iSNMPVersion = 1;
- iSpecificType = 0;
- iTrapType = SNMP_TRAP_ENTERPRISESPECIFIC;
-
+ free(cs.pszTarget);
+ cs.pszTarget = NULL;
+ free(cs.pszCommunity);
+ cs.pszCommunity = NULL;
+ free(cs.pszEnterpriseOID);
+ cs.pszEnterpriseOID = NULL;
+ free(cs.pszSnmpTrapOID);
+ cs.pszSnmpTrapOID = NULL;
+ free(cs.pszSyslogMessageOID);
+ cs.pszSyslogMessageOID = NULL;
+ cs.iPort = 0;
+ cs.iSNMPVersion = 1;
+ cs.iSpecificType = 0;
+ cs.iTrapType = SNMP_TRAP_ENTERPRISESPECIFIC;
RETiRet;
}
BEGINmodExit
CODESTARTmodExit
- if (pszTarget != NULL)
- free(pszTarget);
- if (pszCommunity != NULL)
- free(pszCommunity);
- if (pszEnterpriseOID != NULL)
- free(pszEnterpriseOID);
- if (pszSnmpTrapOID != NULL)
- free(pszSnmpTrapOID);
- if (pszSyslogMessageOID != NULL)
- free(pszSyslogMessageOID);
+ free(cs.pszTarget);
+ free(cs.pszCommunity);
+ free(cs.pszEnterpriseOID);
+ free(cs.pszSnmpTrapOID);
+ free(cs.pszSyslogMessageOID);
/* release what we no longer need */
objRelease(errmsg, CORE_COMPONENT);
@@ -509,20 +512,21 @@ ENDqueryEtryPt
BEGINmodInit()
CODESTARTmodInit
+SCOPINGmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptransport", 0, eCmdHdlrGetWord, NULL, &pszTransport, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptarget", 0, eCmdHdlrGetWord, NULL, &pszTarget, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptargetport", 0, eCmdHdlrInt, NULL, &iPort, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpversion", 0, eCmdHdlrInt, NULL, &iSNMPVersion, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpcommunity", 0, eCmdHdlrGetWord, NULL, &pszCommunity, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpenterpriseoid", 0, eCmdHdlrGetWord, NULL, &pszEnterpriseOID, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptrapoid", 0, eCmdHdlrGetWord, NULL, &pszSnmpTrapOID, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpsyslogmessageoid", 0, eCmdHdlrGetWord, NULL, &pszSyslogMessageOID, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpspecifictype", 0, eCmdHdlrInt, NULL, &iSpecificType, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptraptype", 0, eCmdHdlrInt, NULL, &iTrapType, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptransport", 0, eCmdHdlrGetWord, NULL, &cs.pszTransport, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptarget", 0, eCmdHdlrGetWord, NULL, &cs.pszTarget, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptargetport", 0, eCmdHdlrInt, NULL, &cs.iPort, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpversion", 0, eCmdHdlrInt, NULL, &cs.iSNMPVersion, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpcommunity", 0, eCmdHdlrGetWord, NULL, &cs.pszCommunity, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpenterpriseoid", 0, eCmdHdlrGetWord, NULL, &cs.pszEnterpriseOID, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptrapoid", 0, eCmdHdlrGetWord, NULL, &cs.pszSnmpTrapOID, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpsyslogmessageoid", 0, eCmdHdlrGetWord, NULL, &cs.pszSyslogMessageOID, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmpspecifictype", 0, eCmdHdlrInt, NULL, &cs.iSpecificType, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionsnmptraptype", 0, eCmdHdlrInt, NULL, &cs.iTrapType, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr( (uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
/*
diff --git a/plugins/omstdout/omstdout.c b/plugins/omstdout/omstdout.c
index cd689765..fb95e951 100644
--- a/plugins/omstdout/omstdout.c
+++ b/plugins/omstdout/omstdout.c
@@ -44,14 +44,15 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omstdout")
+
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
/* internal structures
*/
DEF_OMOD_STATIC_DATA
/* config variables */
-static int bUseArrayInterface = 0; /* shall action use array instead of string template interface? */
-static int bEnsureLFEnding = 1; /* shall action use array instead of string template interface? */
typedef struct _instanceData {
@@ -59,6 +60,17 @@ typedef struct _instanceData {
int bEnsureLFEnding; /* ensure that a linefeed is written at the end of EACH record (test aid for nettester) */
} instanceData;
+typedef struct configSettings_s {
+ int bUseArrayInterface; /* shall action use array instead of string template interface? */
+ int bEnsureLFEnding; /* shall action use array instead of string template interface? */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ resetConfigVariables(NULL, NULL);
+ENDinitConfVars
+
BEGINcreateInstance
CODESTARTcreateInstance
ENDcreateInstance
@@ -147,10 +159,10 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
/* check if a non-standard template is to be applied */
if(*(p-1) == ';')
--p;
- iTplOpts = (bUseArrayInterface == 0) ? 0 : OMSR_TPL_AS_ARRAY;
+ iTplOpts = (cs.bUseArrayInterface == 0) ? 0 : OMSR_TPL_AS_ARRAY;
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, iTplOpts, (uchar*) "RSYSLOG_FileFormat"));
- pData->bUseArrayInterface = bUseArrayInterface;
- pData->bEnsureLFEnding = bEnsureLFEnding;
+ pData->bUseArrayInterface = cs.bUseArrayInterface;
+ pData->bEnsureLFEnding = cs.bEnsureLFEnding;
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
@@ -172,8 +184,8 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
DEFiRet;
- bUseArrayInterface = 0;
- bEnsureLFEnding = 1;
+ cs.bUseArrayInterface = 0;
+ cs.bEnsureLFEnding = 1;
RETiRet;
}
@@ -184,6 +196,7 @@ BEGINmodInit()
unsigned long opts;
int bArrayPassingSupported; /* does core support template passing as an array? */
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
/* check if the rsyslog core supports parameter passing code */
@@ -202,10 +215,10 @@ CODEmodInit_QueryRegCFSLineHdlr
if(bArrayPassingSupported) {
/* enable config comand only if core supports it */
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutarrayinterface", 0, eCmdHdlrBinary, NULL,
- &bUseArrayInterface, STD_LOADABLE_MODULE_ID));
+ &cs.bUseArrayInterface, STD_LOADABLE_MODULE_ID));
}
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomstdoutensurelfending", 0, eCmdHdlrBinary, NULL,
- &bEnsureLFEnding, STD_LOADABLE_MODULE_ID));
+ &cs.bEnsureLFEnding, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/omtemplate/Makefile.am b/plugins/omtemplate/Makefile.am
deleted file mode 100644
index e816c7c6..00000000
--- a/plugins/omtemplate/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-pkglib_LTLIBRARIES = omtemplate.la
-
-omtemplate_la_SOURCES = omtemplate.c
-omtemplate_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS)
-omtemplate_la_LDFLAGS = -module -avoid-version
-omtemplate_la_LIBADD =
-
-EXTRA_DIST =
diff --git a/plugins/omtemplate/omtemplate.c b/plugins/omtemplate/omtemplate.c
deleted file mode 100644
index 1472ebeb..00000000
--- a/plugins/omtemplate/omtemplate.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* omtemplate.c
- * This is a template for an output module. It implements a very
- * simple single-threaded output, just as thought of by the output
- * plugin interface.
- *
- * NOTE: read comments in module-template.h for more specifics!
- *
- * File begun on 2009-03-16 by RGerhards
- *
- * Copyright 2009 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h"
-#include "rsyslog.h"
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include "conf.h"
-#include "syslogd-types.h"
-#include "srUtils.h"
-#include "template.h"
-#include "module-template.h"
-#include "errmsg.h"
-#include "cfsysline.h"
-
-MODULE_TYPE_OUTPUT
-MODULE_TYPE_NOKEEP
-
-/* internal structures
- */
-DEF_OMOD_STATIC_DATA
-DEFobjCurrIf(errmsg)
-
-typedef struct _instanceData {
- /* here you need to define all action-specific data. A record of type
- * instanceData will be handed over to each instance of the action. Keep
- * in mind that there may be several invocations of the same type of action
- * inside rsyslog.conf, and this is what keeps them apart. Do NOT use
- * static data for this!
- */
- unsigned iSrvPort; /* sample: server port */
-} instanceData;
-
-/* config variables
- * For the configuration interface, we need to keep track of some settings. This
- * is done in global variables. It works as follows: when configuration statements
- * are entered, the config file handler (or custom function) sets the global
- * variable here. When the action then actually is instantiated, this handler
- * copies over to instanceData whatever configuration settings (from the global
- * variables) apply. The global variables are NEVER used inside an action
- * instance (at least this is how it is supposed to work ;)
- */
-static int iSrvPort = 0; /* sample: server port */
-
-
-BEGINcreateInstance
-CODESTARTcreateInstance
-ENDcreateInstance
-
-
-BEGINisCompatibleWithFeature
-CODESTARTisCompatibleWithFeature
- /* use this to specify if select features are supported by this
- * plugin. If not, the framework will handle that. Currently, only
- * RepeatedMsgReduction ("last message repeated n times") is optional.
- */
- if(eFeat == sFEATURERepeatedMsgReduction)
- iRet = RS_RET_OK;
-ENDisCompatibleWithFeature
-
-
-BEGINfreeInstance
-CODESTARTfreeInstance
- /* this is a cleanup callback. All dynamically-allocated resources
- * in instance data must be cleaned up here. Prime examples are
- * malloc()ed memory, file & database handles and the like.
- */
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
- /* permits to spit out some debug info */
-ENDdbgPrintInstInfo
-
-
-BEGINtryResume
-CODESTARTtryResume
- /* this is called when an action has been suspended and the
- * rsyslog core tries to resume it. The action must then
- * retry (if possible) and report RS_RET_OK if it succeeded
- * or RS_RET_SUSPENDED otherwise.
- * Note that no data can be written in this callback, as it is
- * not present. Prime examples of what can be retried are
- * reconnects to remote hosts, reconnects to database,
- * opening of files and the like.
- * If there is no retry-type of operation, the action may
- * return RS_RET_OK, so that it will get called on its doAction
- * entry point (where it receives data), retries there, and
- * immediately returns RS_RET_SUSPENDED if that does not work
- * out. This disables some optimizations in the core's retry logic,
- * but is a valid and expected behaviour. Note that it is also OK
- * for the retry entry point to return OK but the immediately following
- * doAction call to fail. In real life, for example, a buggy com line
- * may cause such behaviour.
- * Note that there is no guarantee that the core will very quickly
- * call doAction after the retry succeeded. Today, it does, but that may
- * not always be the case.
- */
-ENDtryResume
-
-BEGINdoAction
-CODESTARTdoAction
- /* this is where you receive the message and need to carry out the
- * action. Data is provided in ppString[i] where 0 <= i <= num of strings
- * requested.
- * Return RS_RET_OK if all goes well, RS_RET_SUSPENDED if the action can
- * currently not complete, or an error code or RS_RET_DISABLED. The later
- * two should only be returned if there is no hope that the action can be
- * restored unless an rsyslog restart (prime example is an invalid config).
- * Error code or RS_RET_DISABLED permanently disables the action, up to
- * the next restart.
- */
-ENDdoAction
-
-
-BEGINparseSelectorAct
-CODESTARTparseSelectorAct
-CODE_STD_STRING_REQUESTparseSelectorAct(1)
- /* first check if this config line is actually for us
- * This is a clumpsy interface. We receive the action-part of the selector line
- * and need to look at the first characters. If they match our signature
- * ":omtemplate:", then we need to instantiate an action. It is recommended that
- * newer actions just watch for the template and all other parameters are passed in
- * via $-config-lines, this will hopefully be compatbile with future config syntaxes.
- * If we do not detect our signature, we must return with RS_RET_CONFLINE_UNPROCESSED
- * and NOT do anything else.
- */
- if(strncmp((char*) p, ":omtemplate:", sizeof(":omtemplate:") - 1)) {
- ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
- }
-
- /* ok, if we reach this point, we have something for us */
- p += sizeof(":omtemplate:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
- CHKiRet(createInstance(&pData));
-
- /* check if a non-standard template is to be applied */
- if(*(p-1) == ';')
- --p;
- /* if we have, call rsyslog runtime to get us template. Note that StdFmt below is
- * the standard name. Currently, we may need to patch tools/syslogd.c if we need
- * to add a new standard template.
- */
- CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_RQD_TPL_OPT_SQL, (uchar*) " StdFmt"));
-
- /* if we reach this point, all went well, and we can copy over to instanceData
- * those configuration elements that we need.
- */
- pData->iSrvPort = (unsigned) iSrvPort; /* set configured port */
-
-CODE_STD_FINALIZERparseSelectorAct
-ENDparseSelectorAct
-
-
-BEGINmodExit
-CODESTARTmodExit
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_OMOD_QUERIES
-ENDqueryEtryPt
-
-
-/* Reset config variables for this module to default values.
- */
-static rsRetVal
-resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
-{
- DEFiRet;
- iSrvPort = 0; /* zero is the default port */
- RETiRet;
-}
-
-
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-CODEmodInit_QueryRegCFSLineHdlr
- CHKiRet(objUse(errmsg, CORE_COMPONENT));
- /* register our config handlers */
- /* confguration parameters MUST always be specified in lower case! */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomtemplteserverport", 0, eCmdHdlrInt, NULL, &iSrvPort, STD_LOADABLE_MODULE_ID));
- /* "resetconfigvariables" should be provided. Notat that it is a chained directive */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
-ENDmodInit
-
-/* vi:set ai:
- */
diff --git a/plugins/omtesting/omtesting.c b/plugins/omtesting/omtesting.c
index 909ff29a..ff290c94 100644
--- a/plugins/omtesting/omtesting.c
+++ b/plugins/omtesting/omtesting.c
@@ -57,12 +57,12 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omtesting")
/* internal structures
*/
DEF_OMOD_STATIC_DATA
-static int bEchoStdout = 0; /* echo non-failed messages to stdout */
typedef struct _instanceData {
enum { MD_SLEEP, MD_FAIL, MD_RANDFAIL, MD_ALWAYS_SUSPEND }
@@ -76,6 +76,16 @@ typedef struct _instanceData {
int iCurrRetries;
} instanceData;
+typedef struct configSettings_s {
+ int bEchoStdout; /* echo non-failed messages to stdout */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.bEchoStdout = 0;
+ENDinitConfVars
+
BEGINcreateInstance
CODESTARTcreateInstance
pData->iWaitSeconds = 1;
@@ -287,7 +297,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
dbgprintf("invalid mode '%s', doing 'sleep 1 0' - fix your config\n", szBuf);
}
- pData->bEchoStdout = bEchoStdout;
+ pData->bEchoStdout = cs.bEchoStdout;
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
(uchar*)"RSYSLOG_TraditionalForwardFormat"));
@@ -308,10 +318,11 @@ ENDqueryEtryPt
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomtestingechostdout", 0, eCmdHdlrBinary, NULL,
- &bEchoStdout, STD_LOADABLE_MODULE_ID));
+ &cs.bEchoStdout, STD_LOADABLE_MODULE_ID));
/* we seed the random-number generator in any case... */
srand(time(NULL));
ENDmodInit
diff --git a/plugins/omudpspoof/omudpspoof.c b/plugins/omudpspoof/omudpspoof.c
index 48d7a68e..506fca77 100644
--- a/plugins/omudpspoof/omudpspoof.c
+++ b/plugins/omudpspoof/omudpspoof.c
@@ -83,6 +83,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omudpspoof")
/* internal structures
*/
@@ -105,14 +106,27 @@ typedef struct _instanceData {
#define DFLT_SOURCE_PORT_START 32000
#define DFLT_SOURCE_PORT_END 42000
-/* config data */
-static uchar *pszTplName = NULL; /* name of the default template to use */
-static uchar *pszSourceNameTemplate = NULL; /* name of the template containing the spoofing address */
-static uchar *pszTargetHost = NULL;
-static uchar *pszTargetPort = NULL;
-static int iCompressionLevel = 0; /* zlib compressionlevel, the usual values */
-static int iSourcePortStart = DFLT_SOURCE_PORT_START;
-static int iSourcePortEnd = DFLT_SOURCE_PORT_END;
+typedef struct configSettings_s {
+ uchar *pszTplName; /* name of the default template to use */
+ uchar *pszSourceNameTemplate; /* name of the template containing the spoofing address */
+ uchar *pszTargetHost;
+ uchar *pszTargetPort;
+ int iCompressionLevel; /* zlib compressionlevel, the usual values */
+ int iSourcePortStart;
+ int iSourcePortEnd;
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.pszTplName = NULL;
+ cs.pszSourceNameTemplate = NULL;
+ cs.pszTargetHost = NULL;
+ cs.pszTargetPort = NULL;
+ cs.iCompressionLevel = 0;
+ cs.iSourcePortStart = DFLT_SOURCE_PORT_START;
+ cs.iSourcePortEnd = DFLT_SOURCE_PORT_END;
+ENDinitConfVars
/* add some variables needed for libnet */
@@ -394,28 +408,28 @@ CODE_STD_STRING_REQUESTparseSelectorAct(2)
p += sizeof(":omudpspoof:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
CHKiRet(createInstance(&pData));
- sourceTpl = (pszSourceNameTemplate == NULL) ? UCHAR_CONSTANT("RSYSLOG_omudpspoofDfltSourceTpl")
- : pszSourceNameTemplate;
+ sourceTpl = (cs.pszSourceNameTemplate == NULL) ? UCHAR_CONSTANT("RSYSLOG_omudpspoofDfltSourceTpl")
+ : cs.pszSourceNameTemplate;
- if(pszTargetHost == NULL) {
+ if(cs.pszTargetHost == NULL) {
errmsg.LogError(0, NO_ERRCODE, "No $ActionOMUDPSpoofTargetHost given, can not continue with this action.");
ABORT_FINALIZE(RS_RET_HOST_NOT_SPECIFIED);
}
/* fill instance properties */
- CHKmalloc(pData->host = ustrdup(pszTargetHost));
- if(pszTargetPort == NULL)
+ CHKmalloc(pData->host = ustrdup(cs.pszTargetHost));
+ if(cs.pszTargetPort == NULL)
pData->port = NULL;
else
- CHKmalloc(pData->port = ustrdup(pszTargetPort));
- CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(sourceTpl), OMSR_NO_RQD_TPL_OPTS));
- pData->compressionLevel = iCompressionLevel;
- pData->sourcePort = pData->sourcePortStart = iSourcePortStart;
- pData->sourcePortEnd = iSourcePortEnd;
+ CHKmalloc(pData->port = ustrdup(cs.pszTargetPort));
+ CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(cs.pszSourceNameTemplate), OMSR_NO_RQD_TPL_OPTS));
+ pData->compressionLevel = cs.iCompressionLevel;
+ pData->sourcePort = pData->sourcePortStart = cs.iSourcePortStart;
+ pData->sourcePortEnd = cs.iSourcePortEnd;
/* process template */
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName));
+ (cs.pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : cs.pszTplName));
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
@@ -427,12 +441,12 @@ ENDparseSelectorAct
static void
freeConfigVars(void)
{
- free(pszTplName);
- pszTplName = NULL;
- free(pszTargetHost);
- pszTargetHost = NULL;
- free(pszTargetPort);
- pszTargetPort = NULL;
+ free(cs.pszTplName);
+ cs.pszTplName = NULL;
+ free(cs.pszTargetHost);
+ cs.pszTargetHost = NULL;
+ free(cs.pszTargetPort);
+ cs.pszTargetPort = NULL;
}
@@ -461,15 +475,16 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
{
freeConfigVars();
/* we now must reset all non-string values */
- iCompressionLevel = 0;
- iSourcePortStart = DFLT_SOURCE_PORT_START;
- iSourcePortEnd = DFLT_SOURCE_PORT_END;
+ cs.iCompressionLevel = 0;
+ cs.iSourcePortStart = DFLT_SOURCE_PORT_START;
+ cs.iSourcePortEnd = DFLT_SOURCE_PORT_END;
return RS_RET_OK;
}
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(glbl, CORE_COMPONENT));
@@ -489,13 +504,13 @@ CODEmodInit_QueryRegCFSLineHdlr
ABORT_FINALIZE(RS_RET_ERR_LIBNET_INIT);
}
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourcenametemplate", 0, eCmdHdlrGetWord, NULL, &pszSourceNameTemplate, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargethost", 0, eCmdHdlrGetWord, NULL, &pszTargetHost, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargetport", 0, eCmdHdlrGetWord, NULL, &pszTargetPort, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportstart", 0, eCmdHdlrInt, NULL, &iSourcePortStart, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportend", 0, eCmdHdlrInt, NULL, &iSourcePortEnd, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpcompressionlevel", 0, eCmdHdlrInt, NULL, &iCompressionLevel, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &cs.pszTplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourcenametemplate", 0, eCmdHdlrGetWord, NULL, &cs.pszSourceNameTemplate, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargethost", 0, eCmdHdlrGetWord, NULL, &cs.pszTargetHost, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargetport", 0, eCmdHdlrGetWord, NULL, &cs.pszTargetPort, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportstart", 0, eCmdHdlrInt, NULL, &cs.iSourcePortStart, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportend", 0, eCmdHdlrInt, NULL, &cs.iSourcePortEnd, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpcompressionlevel", 0, eCmdHdlrInt, NULL, &cs.iCompressionLevel, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/omuxsock/omuxsock.c b/plugins/omuxsock/omuxsock.c
index b29276f9..cf27c93c 100644
--- a/plugins/omuxsock/omuxsock.c
+++ b/plugins/omuxsock/omuxsock.c
@@ -46,6 +46,7 @@
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("omuxsock")
/* internal structures
*/
@@ -64,8 +65,18 @@ typedef struct _instanceData {
} instanceData;
/* config data */
-static uchar *tplName = NULL; /* name of the default template to use */
-static uchar *sockName = NULL; /* name of the default template to use */
+typedef struct configSettings_s {
+ uchar *tplName; /* name of the default template to use */
+ uchar *sockName; /* name of the default template to use */
+} configSettings_t;
+static configSettings_t cs;
+
+BEGINinitConfVars /* (re)set config variables to default values */
+CODESTARTinitConfVars
+ cs.tplName = NULL;
+ cs.sockName = NULL;
+ENDinitConfVars
+
static rsRetVal doTryResume(instanceData *pData);
@@ -239,16 +250,16 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
/* check if a non-standard template is to be applied */
if(*(p-1) == ';')
--p;
- CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, tplName == NULL ? UCHAR_CONSTANT("RSYSLOG_TraditionalForwardFormat")
- : tplName ));
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, cs.tplName == NULL ? UCHAR_CONSTANT("RSYSLOG_TraditionalForwardFormat")
+ : cs.tplName ));
- if(sockName == NULL) {
+ if(cs.sockName == NULL) {
errmsg.LogError(0, RS_RET_NO_SOCK_CONFIGURED, "No output socket configured for omuxsock\n");
ABORT_FINALIZE(RS_RET_NO_SOCK_CONFIGURED);
}
- pData->sockName = sockName;
- sockName = NULL; /* pData is now owner and will fee it */
+ pData->sockName = cs.sockName;
+ cs.sockName = NULL; /* pData is now owner and will fee it */
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
@@ -260,10 +271,10 @@ ENDparseSelectorAct
static inline void
freeConfigVars(void)
{
- free(tplName);
- tplName = NULL;
- free(sockName);
- sockName = NULL;
+ free(cs.tplName);
+ cs.tplName = NULL;
+ free(cs.sockName);
+ cs.sockName = NULL;
}
@@ -295,13 +306,14 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
BEGINmodInit()
CODESTARTmodInit
+INITLegCnfVars
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(regCfSysLineHdlr((uchar *)"omuxsockdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &tplName, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"omuxsocksocket", 0, eCmdHdlrGetWord, NULL, &sockName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"omuxsockdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &cs.tplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"omuxsocksocket", 0, eCmdHdlrGetWord, NULL, &cs.sockName, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/pmaixforwardedfrom/pmaixforwardedfrom.c b/plugins/pmaixforwardedfrom/pmaixforwardedfrom.c
index fe3e85fa..76198e9c 100644
--- a/plugins/pmaixforwardedfrom/pmaixforwardedfrom.c
+++ b/plugins/pmaixforwardedfrom/pmaixforwardedfrom.c
@@ -42,6 +42,7 @@
MODULE_TYPE_PARSER
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("pmaixforwardedfrom")
PARSER_NAME("rsyslog.aixforwardedfrom")
/* internal structures
diff --git a/plugins/pmcisconames/pmcisconames.c b/plugins/pmcisconames/pmcisconames.c
index 61688cbf..d8235752 100644
--- a/plugins/pmcisconames/pmcisconames.c
+++ b/plugins/pmcisconames/pmcisconames.c
@@ -42,6 +42,7 @@
MODULE_TYPE_PARSER
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("pmcisconames")
PARSER_NAME("rsyslog.cisconames")
/* internal structures
diff --git a/plugins/pmlastmsg/pmlastmsg.c b/plugins/pmlastmsg/pmlastmsg.c
index 259c5d41..a290c446 100644
--- a/plugins/pmlastmsg/pmlastmsg.c
+++ b/plugins/pmlastmsg/pmlastmsg.c
@@ -48,6 +48,7 @@
MODULE_TYPE_PARSER
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("pmlastmsg")
PARSER_NAME("rsyslog.lastline")
/* internal structures
diff --git a/plugins/pmrfc3164sd/pmrfc3164sd.c b/plugins/pmrfc3164sd/pmrfc3164sd.c
index 53204ece..de5805bc 100644
--- a/plugins/pmrfc3164sd/pmrfc3164sd.c
+++ b/plugins/pmrfc3164sd/pmrfc3164sd.c
@@ -46,6 +46,7 @@
MODULE_TYPE_PARSER
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("pmrfc3164sd")
PARSER_NAME("contrib.rfc3164sd")
/* internal structures
diff --git a/plugins/pmsnare/pmsnare.c b/plugins/pmsnare/pmsnare.c
index f3658d11..aca0271f 100644
--- a/plugins/pmsnare/pmsnare.c
+++ b/plugins/pmsnare/pmsnare.c
@@ -59,6 +59,7 @@
MODULE_TYPE_PARSER
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("pmsnare")
PARSER_NAME("rsyslog.snare")
/* internal structures
diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c
index baad667e..acf1bfad 100644
--- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c
+++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c
@@ -52,6 +52,7 @@
MODULE_TYPE_STRGEN
MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("sm_cust_bindcdr")
STRGEN_NAME("Custom_BindCDR,sql")
/* internal structures