From f7575cb9a81ed80848e21ea0cb31b6657f908f5d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 13 Oct 2009 09:08:40 +0200 Subject: added multi-ruleset support to imudp also bumped version number and corrected ChangeLog, where I merged some post 5.3.1 changes into the 5.3.1 section. --- ChangeLog | 11 +++++--- configure.ac | 2 +- doc/imtcp.html | 47 ++++++++++++++++++--------------- doc/imudp.html | 58 ++++++++++++++++++++++++++++++++++++++++ doc/manual.html | 2 +- doc/rsyslog_conf_global.html | 13 --------- doc/rsyslog_conf_modules.html | 2 +- plugins/imudp/imudp.c | 61 +++++++++++++++++++++++-------------------- runtime/ruleset.c | 7 +---- 9 files changed, 128 insertions(+), 75 deletions(-) create mode 100644 doc/imudp.html diff --git a/ChangeLog b/ChangeLog index 7b6e1fc1..c66220fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,6 @@ --------------------------------------------------------------------------- -Version 5.3.1 [DEVEL] (rgerhards), 2009-10-05 -- added $AbortOnUncleanConfig directive - permits to prevent startup when - there are problems with the configuration file. See it's doc for - details. +Version 5.3.2 [DEVEL] (rgerhards), 2009-10-?? +- added multi-ruleset support to imudp - re-enabled input thread termination handling that does avoid thread cancellation where possible. This provides a more reliable mode of rsyslogd termination (canceling threads my result in not properly @@ -23,6 +21,11 @@ Version 5.3.1 [DEVEL] (rgerhards), 2009-10-05 used together with the new interface. The removal also enables us to drop a lot of duplicate code, reducing complexity and increasing maintainibility. +--------------------------------------------------------------------------- +Version 5.3.1 [DEVEL] (rgerhards), 2009-10-05 +- added $AbortOnUncleanConfig directive - permits to prevent startup when + there are problems with the configuration file. See it's doc for + details. - included some important fixes from v4-stable: * bugfix: invalid handling of zero-sized messages * bugfix: zero-sized UDP messages are no longer processed diff --git a/configure.ac b/configure.ac index 07fd0dac..e3f60b5c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.3.1],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.3.2],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/doc/imtcp.html b/doc/imtcp.html index 0ccdecc7..0671d6d5 100644 --- a/doc/imtcp.html +++ b/doc/imtcp.html @@ -1,21 +1,23 @@ - -TCP Syslog Input Module + + + +TCP Syslog Input Module + + -back +back to rsyslog module overview

TCP Syslog Input Module

Module Name:    imtcp

-

Author: Rainer Gerhards -<rgerhards@adiscon.com>

+

Author: Rainer Gerhards <rgerhards@adiscon.com>

+

Multi-Ruleset Support: since 4.5.0 and 5.1.1

Description:

Provides the ability to receive syslog messages via TCP. -Encryption can be provided by using stunnel -(an alternative is the use -the imgssapi -modul).

-

Multiple receivers may be configured by -specifying +Encryption is natively provided by selecting the approprioate network stream driver and +can also be provided by using stunnel +(an alternative is the use the imgssapi module).

+

Multiple receivers may be configured by specifying $InputTCPServerRun multiple times. This is available since version 4.3.1, earlier versions do NOT support it.

@@ -49,8 +51,7 @@ after loading imtcp, otherwise it may have no effect. Starts a TCP server on selected port
  • $InputTCPMaxListeners <number>
    Sets the maximum number of listeners (server ports) supported. Default is 20. This must be set before the first $InputTCPServerRun directive.
  • -
  • $InputTCPMaxSessions <number>
    -Sets the maximum number of sessions supported. Default is 200. This must be set before the first $InputTCPServerRun directive
  • +
  • $InputTCPMaxSessions <number>
    Sets the maximum number of sessions supported. Default is 200. This must be set before the first $InputTCPServerRun directive
  • $InputTCPServerStreamDriverMode <number>
    Sets the driver mode for the currently selected network stream driver. <number> is driver specifc.
  • $InputTCPServerInputName <name>
    @@ -63,6 +64,8 @@ Sets the authentication mode for the currently selected network stream driver. PermittedPeers may not be set in anonymous modes.
  • +
  • $InputTCPServerBindRuleset <ruleset>
    +Binds the listener to a specific ruleset.
  • Caveats/Known Bugs:

    Sample:

    -

    This sets up a TCP server on port 514:
    +

    This sets up a TCP server on port 514 and permits it to accept up to 500 connections:

    - +

    Note that the parameters (here: max sessions) need to be set before the listener +is activated. Otherwise, the parameters will not apply. +

    [rsyslog.conf overview] [manual index] [rsyslog site]

    -

    This documentation is part of the -rsyslog +

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

    - + + diff --git a/doc/imudp.html b/doc/imudp.html new file mode 100644 index 00000000..f0e86307 --- /dev/null +++ b/doc/imudp.html @@ -0,0 +1,58 @@ + + + + +TCP Syslog Input Module + + + +back to rsyslog module overview + +

    UDP Syslog Input Module

    +

    Module Name:    imudp

    +

    Author: Rainer Gerhards <rgerhards@adiscon.com>

    +

    Multi-Ruleset Support: since 5.3.2 +

    Description:

    +

    Provides the ability to receive syslog messages via UDP. +

    Multiple receivers may be configured by specifying +$UDPServerRun multiple times. +

    +

    Configuration Directives:

    + +Caveats/Known Bugs: + +

    Sample:

    +

    This sets up an UPD server on port 514:
    +

    + +

    [rsyslog.conf overview] +[manual index] [rsyslog site]

    +

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

    + diff --git a/doc/manual.html b/doc/manual.html index 6b96d94c..a6d64872 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support available directly from the source!

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

    -

    This documentation is for version 5.3.1 (devel branch) of rsyslog. +

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

    If you like rsyslog, you might diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index 874ad30e..885dbdc7 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -260,19 +260,6 @@ default may change as uniprocessor systems become less common. [available since to sysklogd), the domain part from a name that is within the same domain as the receiving system is stripped. If set to on, full names are always used.

  • $WorkDirectory <name> (directory for spool and other work files)
  • -
  • $UDPServerAddress <IP> (imudp) -- local IP -address (or name) the UDP listens should bind to
  • -
  • $UDPServerRun <port> (imudp) -- former --r<port> option, default 514, start UDP server on this -port, "*" means all addresses
  • -
  • $UDPServerTimeRequery <nbr-of-times> (imudp) -- this is a performance -optimization. Getting the system time is very costly. With this setting, imudp can -be instructed to obtain the precise time only once every n-times. This logic is -only activated if messages come in at a very fast rate, so doing less frequent -time calls should usually be acceptable. The default value is two, because we have -seen that even without optimization the kernel often returns twice the identical time. -You can set this value as high as you like, but do so at your own risk. The higher -the value, the less precise the timestamp.
  • $PrivDropToGroup
  • $PrivDropToGroupID
  • $PrivDropToUser
  • diff --git a/doc/rsyslog_conf_modules.html b/doc/rsyslog_conf_modules.html index f9bdad4a..d408fc60 100644 --- a/doc/rsyslog_conf_modules.html +++ b/doc/rsyslog_conf_modules.html @@ -25,7 +25,7 @@ permits rsyslog to alert folks by mail if something important happens -  input module for text files
  • imrelp - RELP input module
  • -
  • imudp - udp syslog message input
  • +
  • imudp - udp syslog message input
  • imtcp - input plugin for plain tcp syslog
  • imgssapi - diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 4f05cd12..12946c39 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -47,6 +47,7 @@ #include "parser.h" #include "datetime.h" #include "prop.h" +#include "ruleset.h" #include "unicode-helper.h" MODULE_TYPE_INPUT @@ -60,6 +61,7 @@ DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(datetime) DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) static int iMaxLine; /* maximum UDP message size supported */ static time_t ttLastDiscard = 0; /* timestamp when a message from a non-permitted sender was last discarded @@ -68,13 +70,14 @@ static time_t ttLastDiscard = 0; /* timestamp when a message from a non-permitte */ static int *udpLstnSocks = NULL; /* Internet datagram sockets, first element is nbr of elements * read-only after init(), but beware of restart! */ +static ruleset_t **udpRulesets = NULL; /* ruleset to be used with sockets in question (entry 0 is empty) */ 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 */ -// TODO: static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */ +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 */ @@ -93,6 +96,7 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal) int *newSocks; int *tmpSocks; int iSrc, iDst; + ruleset_t **tmpRulesets; /* 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 @@ -113,26 +117,39 @@ static rsRetVal addListner(void __attribute__((unused)) *pVal, uchar *pNewVal) 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] = pBindRuleset; } else { /* we need to add them */ - if((tmpSocks = malloc(sizeof(int) * (1 + newSocks[0] + udpLstnSocks[0]))) == NULL) { + 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) + for(iSrc = 1 ; iSrc <= udpLstnSocks[0] ; ++iSrc) { tmpSocks[iDst++] = udpLstnSocks[iSrc]; - for(iSrc = 1 ; iSrc <= newSocks[0] ; ++iSrc) + tmpRulesets[iDst++] = udpRulesets[iSrc]; + } + for(iSrc = 1 ; iSrc <= newSocks[0] ; ++iSrc) { tmpSocks[iDst++] = newSocks[iSrc]; + tmpRulesets[iDst++] = pBindRuleset; + } tmpSocks[0] = udpLstnSocks[0] + newSocks[0]; free(newSocks); free(udpLstnSocks); udpLstnSocks = tmpSocks; + free(udpRulesets); + udpRulesets = tmpRulesets; } } } @@ -144,7 +161,6 @@ finalize_it: } -#if 0 /* TODO: implement when tehre is time, requires restructure of socket array! */ /* accept a new ruleset to bind. Checks if it exists and complains, if not */ static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName) @@ -165,7 +181,6 @@ finalize_it: free(pszName); /* no longer needed */ RETiRet; } -#endif /* This function is a helper to runInput. I have extracted it @@ -184,7 +199,7 @@ finalize_it: */ static inline rsRetVal processSocket(int fd, struct sockaddr_storage *frominetPrev, int *pbIsPermitted, - uchar *fromHost, uchar *fromHostFQDN, uchar *fromHostIP) + uchar *fromHost, uchar *fromHostFQDN, uchar *fromHostIP, ruleset_t *pRuleset) { DEFiRet; int iNbrTimeUsed; @@ -254,6 +269,7 @@ processSocket(int fd, struct sockaddr_storage *frominetPrev, int *pbIsPermitted, CHKiRet(msgConstructWithTime(&pMsg, &stTime, ttGenTime)); MsgSetRawMsg(pMsg, (char*)pRcvBuf, lenRcvBuf); MsgSetInputName(pMsg, pInputName); + MsgSetRuleset(pMsg, pRuleset); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; MsgSetRcvFromStr(pMsg, fromHost, ustrlen(fromHost), &propFromHost); @@ -282,11 +298,9 @@ finalize_it: rsRetVal rcvMainLoop() { DEFiRet; - int maxfds; int nfds; int efd; int i; - fd_set readfds; struct sockaddr_storage frominetPrev; int bIsPermitted; uchar fromHost[NI_MAXHOST]; @@ -307,21 +321,16 @@ rsRetVal rcvMainLoop() efd = epoll_create1(EPOLL_CLOEXEC); if(efd < 0) { DBGPRINTF("epoll_create1() could not create fd\n"); - // TODO: "good" error message ABORT_FINALIZE(RS_RET_IO_ERROR); } /* fill the epoll set - we need to do this only once, as the set * can not change dyamically. */ - maxfds = 0; - FD_ZERO (&readfds); - - /* Add the UDP listen sockets to the list of read descriptors. */ for (i = 0; i < *udpLstnSocks; i++) { if (udpLstnSocks[i+1] != -1) { udpEPollEvt[i].events = EPOLLIN | EPOLLET; - udpEPollEvt[i].data.fd = udpLstnSocks[i+1]; + udpEPollEvt[i].data.u64 = i+1; if(epoll_ctl(efd, EPOLL_CTL_ADD, udpLstnSocks[i+1], &(udpEPollEvt[i])) < 0) { rs_strerror_r(errno, errStr, sizeof(errStr)); errmsg.LogError(errno, NO_ERRCODE, "epoll_ctrl failed on fd %d with %s\n", @@ -339,8 +348,8 @@ rsRetVal rcvMainLoop() break; /* terminate input! */ for(i = 0 ; i < nfds ; ++i) { - processSocket(currEvt[i].data.fd, &frominetPrev, &bIsPermitted, - fromHost, fromHostFQDN, fromHostIP); + processSocket(udpLstnSocks[currEvt[i].data.u64], &frominetPrev, &bIsPermitted, + fromHost, fromHostFQDN, fromHostIP, udpRulesets[currEvt[i].data.u64]); } } @@ -406,7 +415,7 @@ rsRetVal rcvMainLoop() for(i = 0; nfds && i < *udpLstnSocks; i++) { if(FD_ISSET(udpLstnSocks[i+1], &readfds)) { processSocket(udpLstnSocks[i+1], &frominetPrev, &bIsPermitted, - fromHost, fromHostFQDN, fromHostIP); + fromHost, fromHostFQDN, fromHostIP, udpRulesets[i+1]); --nfds; /* indicate we have processed one descriptor */ } } @@ -447,9 +456,7 @@ CODESTARTwillRun iMaxLine = glbl.GetMaxLine(); - if((pRcvBuf = malloc((iMaxLine + 1) * sizeof(char))) == NULL) { - ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); - } + CHKmalloc(pRcvBuf = malloc((iMaxLine + 1) * sizeof(char))); finalize_it: ENDwillRun @@ -461,6 +468,8 @@ CODESTARTafterRun if(udpLstnSocks != NULL) { net.closeUDPListenSockets(udpLstnSocks); udpLstnSocks = NULL; + free(udpRulesets); + udpRulesets = NULL; } if(pRcvBuf != NULL) { free(pRcvBuf); @@ -478,6 +487,7 @@ CODESTARTmodExit objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); objRelease(net, LM_NET_FILENAME); ENDmodExit @@ -501,10 +511,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a free(pszBindAddr); pszBindAddr = NULL; } - if(udpLstnSocks != NULL) { - net.closeUDPListenSockets(udpLstnSocks); - udpLstnSocks = NULL; - } iTimeRequery = TIME_REQUERY_DFLT;/* the default is to query only every second time */ return RS_RET_OK; } @@ -518,13 +524,12 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(net, LM_NET_FILENAME)); /* register config file handlers */ - /* TODO: add - but this requires more changes, no time right now... - CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserverbindruleset", 0, eCmdHdlrGetWord, + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputudpserverbindruleset", 0, eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID)); - */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserverrun", 0, eCmdHdlrGetWord, addListner, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserveraddress", 0, eCmdHdlrGetWord, diff --git a/runtime/ruleset.c b/runtime/ruleset.c index 5ac9a8fd..0f4bc46d 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -46,8 +46,6 @@ #include "errmsg.h" #include "unicode-helper.h" -static rsRetVal debugPrintAll(void); // TODO: remove! - /* static data */ DEFobjStaticHelpers DEFobjCurrIf(errmsg) @@ -161,13 +159,10 @@ processMsg(msg_t *pMsg) CHKiRet(llExecFunc(&pThis->llRules, processMsgDoRules, pMsg)); finalize_it: - - //if(iRet == RS_RET_DISCARDMSG) - //iRet = RS_RET_OK; - RETiRet; } + /* Add a new rule to the end of the current rule set. We do a number * of checks and ignore the rule if it does not pass them. */ -- cgit v1.2.3