diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-05-29 17:25:16 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-05-29 17:25:16 +0200 |
commit | 36fe8d92f8bad4ddc1f24ede14405129ec46c0d8 (patch) | |
tree | bfbf446e88f7d0b008ea2b6bbcaa767a3fccd43f | |
parent | eafafc63597a600fceda5ac9ada90acd6e2f037e (diff) | |
download | rsyslog-36fe8d92f8bad4ddc1f24ede14405129ec46c0d8.tar.gz rsyslog-36fe8d92f8bad4ddc1f24ede14405129ec46c0d8.tar.xz rsyslog-36fe8d92f8bad4ddc1f24ede14405129ec46c0d8.zip |
added ability for the UDP output action to rebind its send socket after sending n messages
New config directive $ActionSendUDPRebindInterval
added for the purpose. By default, rebinding is disabled. This is
considered useful for load balancers.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | doc/rsyslog_conf_global.html | 3 | ||||
-rw-r--r-- | runtime/conf.c | 3 | ||||
-rw-r--r-- | tools/omfwd.c | 69 |
4 files changed, 60 insertions, 21 deletions
@@ -1,5 +1,9 @@ --------------------------------------------------------------------------- -Version 4.3.? [DEVEL] (rgerhards), 2009-??-?? +Version 4.3.2 [DEVEL] (rgerhards), 2009-??-?? +- added ability for the UDP output action to rebind its send socket after + sending n messages. New config directive $ActionSendUDPRebindInterval + added for the purpose. By default, rebinding is disabled. This is + considered useful for load balancers. - bugfix: imdiag/imtcp had a race condition - improved testbench (now much better code design and reuse) --------------------------------------------------------------------------- diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index fe76912d..778e18f8 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -96,6 +96,9 @@ default 60000 (1 minute)]</li> (driver-specific)</li><li>$ActionSendStreamDriverAuthMode <mode>, authentication mode to use with the stream driver (driver-specific)</li><li>$ActionSendStreamDriverPermittedPeer <ID>, accepted fingerprint (SHA1) or name of remote peer (driver-specific) -<span style="font-weight: bold;"> directive may go away</span>!</li> +<li><b>$ActionSendUDPRebindInterval</b> nbr</a>- [available since 4.3.2] - instructs the UDP send +action to rebind the send socket every nbr of messages sent. Zero, the default, means +that no rebind is done. This directive is useful for use with load-balancers.</li> <li><a href="rsconf1_allowedsender.html">$AllowedSender</a></li> <li><a href="rsconf1_controlcharacterescapeprefix.html">$ControlCharacterEscapePrefix</a></li> <li><a href="rsconf1_debugprintcfsyslinehandlerlist.html">$DebugPrintCFSyslineHandlerList</a></li> diff --git a/runtime/conf.c b/runtime/conf.c index 602a5eb1..bb1fa282 100644 --- a/runtime/conf.c +++ b/runtime/conf.c @@ -484,7 +484,8 @@ finalize_it: } if(bHadAnError && (iRet == RS_RET_OK)) { /* a bit dirty, enhance in future releases */ - iRet = RS_RET_ERR; +// TODO: fix regression! + // iRet = RS_RET_ERR; } RETiRet; } diff --git a/tools/omfwd.c b/tools/omfwd.c index 88a382e0..c8fedfc9 100644 --- a/tools/omfwd.c +++ b/tools/omfwd.c @@ -82,12 +82,14 @@ typedef struct _instanceData { permittedPeers_t *pPermPeers; int iStrmDrvrMode; char *f_hname; - int *pSockArray; /* sockets to use for UDP */ + int *pSockArray; /* sockets to use for UDP */ int bIsConnected; /* are we connected to remote host? 0 - no, 1 - yes, UDP means addr resolved */ struct addrinfo *f_addr; - int compressionLevel; /* 0 - no compression, else level for zlib */ + int compressionLevel; /* 0 - no compression, else level for zlib */ char *port; int protocol; + int iUDPRebindInterval; /* rebind interval */ + int nXmit; /* number of transmissions since last (re-)bind */ # define FORW_UDP 0 # define FORW_TCP 1 /* following fields for TCP-based delivery */ @@ -100,9 +102,31 @@ static uchar *pszStrmDrvr = NULL; /* name of the stream driver to use */ static short iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static short bResendLastOnRecon = 0; /* should the last message be re-sent on a successful reconnect? */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ +static int iUDPRebindInterval = 0; /* support for automatic re-binding (load balancers!). 0 - no rebind */ static permittedPeers_t *pPermPeers = NULL; +static rsRetVal doTryResume(instanceData *pData); + +/* Close the UDP sockets. + * rgerhards, 2009-05-29 + */ +static rsRetVal +closeUDPSockets(instanceData *pData) +{ + DEFiRet; + assert(pData != NULL); + if(pData->pSockArray != NULL) { + net.closeUDPListenSockets(pData->pSockArray); + pData->pSockArray = NULL; + freeaddrinfo(pData->f_addr); + pData->f_addr = NULL; + } +pData->bIsConnected = 0; // TODO: remove this variable altogether + RETiRet; +} + + /* get the syslog forward port from selector_t. The passed in * struct must be one that is setup for forwarding. * rgerhards, 2007-06-28 @@ -148,30 +172,19 @@ ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance - if(pData->f_addr != NULL) { /* TODO: is the check ok? */ - freeaddrinfo(pData->f_addr); - pData->f_addr = NULL; - } - if(pData->port != NULL) - free(pData->port); - /* final cleanup */ DestructTCPInstanceData(pData); - if(pData->pSockArray != NULL) - net.closeUDPListenSockets(pData->pSockArray); + closeUDPSockets(pData); if(pData->protocol == FORW_TCP) { tcpclt.Destruct(&pData->pTCPClt); } - if(pData->f_hname != NULL) - free(pData->f_hname); - if(pData->pszStrmDrvr != NULL) - free(pData->pszStrmDrvr); - if(pData->pszStrmDrvrAuthMode != NULL) - free(pData->pszStrmDrvrAuthMode); - if(pData->pPermPeers != NULL) - net.DestructPermittedPeers(&pData->pPermPeers); + free(pData->port); + free(pData->f_hname); + free(pData->pszStrmDrvr); + free(pData->pszStrmDrvrAuthMode); + net.DestructPermittedPeers(&pData->pPermPeers); ENDfreeInstance @@ -192,6 +205,18 @@ static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len) unsigned lsent = 0; int bSendSuccess; +dbgprintf("rebind logic: interval %d, curr %d, mod %d, if %d\n", pData->iUDPRebindInterval, pData->nXmit, + (pData->nXmit % pData->iUDPRebindInterval), ((pData->nXmit % pData->iUDPRebindInterval) == 0)); + if(pData->iUDPRebindInterval && (pData->nXmit++ % pData->iUDPRebindInterval == 0)) { + dbgprintf("omfwd dropping UDP 'connection' (as configured)\n"); + pData->nXmit = 1; /* else we have an addtl wrap at 2^31-1 */ + CHKiRet(closeUDPSockets(pData)); + } + + if(pData->pSockArray == NULL) { + CHKiRet(doTryResume(pData)); + } + if(pData->pSockArray != NULL) { /* we need to track if we have success sending to the remote * peer. Success is indicated by at least one sendto() call @@ -224,6 +249,7 @@ static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len) } } +finalize_it: RETiRet; } @@ -616,6 +642,9 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) CHKmalloc(pData->f_hname = strdup((char*) q)); } + /* copy over config data as needed */ + pData->iUDPRebindInterval = iUDPRebindInterval; + /* process template */ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName)); @@ -699,6 +728,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a /* we now must reset all non-string values */ iStrmDrvrMode = 0; bResendLastOnRecon = 0; + iUDPRebindInterval = 0; return RS_RET_OK; } @@ -713,6 +743,7 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(net,LM_NET_FILENAME)); CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionsendudprebindinterval", 0, eCmdHdlrInt, NULL, &iUDPRebindInterval, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszStrmDrvr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdrivermode", 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriverauthmode", 0, eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, NULL)); |