summaryrefslogtreecommitdiffstats
path: root/tools/omfwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/omfwd.c')
-rw-r--r--tools/omfwd.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/tools/omfwd.c b/tools/omfwd.c
index e91387c8..4d730f4b 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));