summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-12-27 11:22:48 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-12-27 11:22:48 +0000
commit6388928e6903089a4a794283368cd7d98354e7f0 (patch)
tree488318a3e7bd3846a07815880c96a3707c5ec293
parentb39a751bbe832d98754cd3aa8cf08b53c85ca73c (diff)
downloadrsyslog-6388928e6903089a4a794283368cd7d98354e7f0.tar.gz
rsyslog-6388928e6903089a4a794283368cd7d98354e7f0.tar.xz
rsyslog-6388928e6903089a4a794283368cd7d98354e7f0.zip
added capability to have multiple UDP listeners running concurrently
-rw-r--r--ChangeLog1
-rw-r--r--plugins/imudp/imudp.c96
2 files changed, 73 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 598d1970..c18247ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
---------------------------------------------------------------------------
Version 3.0.0 (rgerhards), 2007-12-??
- added ability to specify listen IP address for UDP syslog server
+- added ability to run multiple UDP listeners concurrently
- license changed to GPLv3
- first implementation of loadable input module system
- mark messages are now provided by loadble module immark
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 404d3dbd..fdddf9eb 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -46,7 +46,6 @@ TERM_SYNC_TYPE(eTermSync_NONE)
DEF_IMOD_STATIC_DATA
static int *udpLstnSocks = NULL; /* Internet datagram sockets, first element is nbr of elements
* read-only after init(), but beware of restart! */
-static uchar *pszLstnPort = NULL;
static uchar *pszBindAddr = NULL; /* IP to bind socket to */
typedef struct _instanceData {
@@ -55,6 +54,69 @@ typedef struct _instanceData {
/* config settings */
+/* This function is called when a new listener shall be added. It takes
+ * the configured parameters, 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)
+{
+ DEFiRet;
+ uchar *bindAddr;
+ int *newSocks;
+ int *tmpSocks;
+ int iSrc, iDst;
+
+ /* 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)
+ bindAddr = NULL;
+ else if(pszBindAddr[0] == '*' && pszBindAddr[1] == '\0')
+ bindAddr = NULL;
+ else
+ bindAddr = pszBindAddr;
+
+ dbgprintf("Trying to open syslog UDP ports at %s:%s.\n",
+ (bindAddr == NULL) ? (uchar*)"*" : bindAddr, pNewVal);
+
+ newSocks = create_udp_socket(bindAddr, (pNewVal == NULL) ? (uchar*) "514" : pNewVal, 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;
+ } else {
+ /* we need to add them */
+ if((tmpSocks = malloc(sizeof(int) * 1 + newSocks[0] + udpLstnSocks[0])) == 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);
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ } else {
+ /* ready to copy */
+ iDst = 1;
+ for(iSrc = 1 ; iSrc <= udpLstnSocks[0] ; ++iSrc)
+ tmpSocks[iDst++] = udpLstnSocks[iSrc];
+ for(iSrc = 1 ; iSrc <= newSocks[0] ; ++iSrc)
+ tmpSocks[iDst++] = newSocks[iSrc];
+ tmpSocks[0] = udpLstnSocks[0] + newSocks[0];
+ free(newSocks);
+ free(udpLstnSocks);
+ udpLstnSocks = tmpSocks;
+ }
+ }
+ }
+
+finalize_it:
+ free(pNewVal); /* in any case, this is no longer needed */
+
+ return iRet;
+}
+
+
/* This function is called to gather input.
*/
BEGINrunInput
@@ -153,39 +215,25 @@ ENDrunInput
/* initialize and return if will run or not */
BEGINwillRun
- uchar *bindAddr;
CODESTARTwillRun
PrintAllowedSenders(1); /* UDP */
- /* 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
- */
-dbgprintf("pszBindAddr: '%s'\n", pszBindAddr);
- if(pszBindAddr == NULL)
- bindAddr = NULL;
- else if(pszBindAddr[0] == '*' && pszBindAddr[1] == '\0')
- bindAddr = NULL;
- else
- bindAddr = pszBindAddr;
-dbgprintf("bindAddr: '%s', pszLstPort: '%s'\n", bindAddr, pszLstnPort);
- if((udpLstnSocks = create_udp_socket(bindAddr, (pszLstnPort == NULL) ? (uchar*) "514" : pszLstnPort, 1)) != NULL)
- dbgprintf("Opened %d syslog UDP port(s).\n", *udpLstnSocks);
+ /* if we could not set up any listners, there is no point in running... */
+ if(udpLstnSocks == NULL)
+ iRet = RS_RET_NO_RUN;
ENDwillRun
BEGINafterRun
CODESTARTafterRun
/* do cleanup here */
-dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_UDP);
if (pAllowedSenders_UDP != NULL) {
clearAllowedSenders (pAllowedSenders_UDP);
pAllowedSenders_UDP = NULL;
}
if(udpLstnSocks != NULL)
closeUDPListenSockets(udpLstnSocks);
- if(pszLstnPort != NULL)
- free(pszLstnPort);
ENDafterRun
@@ -211,14 +259,14 @@ ENDqueryEtryPt
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- if(pszLstnPort != NULL) {
- free(pszLstnPort);
- pszLstnPort = NULL;
- }
if(pszBindAddr != NULL) {
free(pszBindAddr);
pszBindAddr = NULL;
}
+ if(udpLstnSocks != NULL) {
+ closeUDPListenSockets(udpLstnSocks);
+ udpLstnSocks = NULL;
+ }
return RS_RET_OK;
}
@@ -228,8 +276,8 @@ CODESTARTmodInit
*ipIFVersProvided = 1; /* so far, we only support the initial definition */
CODEmodInit_QueryRegCFSLineHdlr
/* register config file handlers */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"udplistenport", 0, eCmdHdlrGetWord,
- NULL, &pszLstnPort, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserverrun", 0, eCmdHdlrGetWord,
+ addListner, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"udpserveraddress", 0, eCmdHdlrGetWord,
NULL, &pszBindAddr, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,