From 55e01da2ec3de1b5c6b15e4154235f0eedbb68da Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 9 Jun 2008 12:40:54 +0200 Subject: somewhat improved plain tcp syslog reliability ...by doing a connection check before sending. Credits to Martin Schuette for providing the idea. Details are available at http://blog.gerhards.net/2008/06/reliable-plain-tcp-syslog-once-again.html --- tcpclt.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'tcpclt.c') diff --git a/tcpclt.c b/tcpclt.c index 2bc2ea56..c53f00f7 100644 --- a/tcpclt.c +++ b/tcpclt.c @@ -305,16 +305,23 @@ Send(tcpclt_t *pThis, void *pData, char *msg, size_t len) /* we are done, we also use this as indication that the previous * message was succesfully received (it's not always the case, but its at * least our best shot at it -- rgerhards, 2008-03-12 + * As of 2008-06-09, we have implemented an algorithm which detects connection + * loss quite good in some (common) scenarios. Thus, the probability of + * message duplication due to the code below has increased. We so now have + * a config setting, default off, that enables the user to request retransmits. + * However, if not requested, we do NOT need to do all the stuff needed for it. */ - if(pThis->prevMsg != NULL) - free(pThis->prevMsg); - /* if we can not alloc a new buffer, we silently ignore it. The worst that - * happens is that we lose our message recovery buffer - anything else would - * be worse, so don't try anything ;) -- rgerhards, 2008-03-12 - */ - if((pThis->prevMsg = malloc(len)) != NULL) { - memcpy(pThis->prevMsg, msg, len); - pThis->lenPrevMsg = len; + if(pThis->bResendLastOnRecon == 1) { + if(pThis->prevMsg != NULL) + free(pThis->prevMsg); + /* if we can not alloc a new buffer, we silently ignore it. The worst that + * happens is that we lose our message recovery buffer - anything else would + * be worse, so don't try anything ;) -- rgerhards, 2008-03-12 + */ + if((pThis->prevMsg = malloc(len)) != NULL) { + memcpy(pThis->prevMsg, msg, len); + pThis->lenPrevMsg = len; + } } /* we are done with this record */ @@ -324,7 +331,8 @@ Send(tcpclt_t *pThis, void *pData, char *msg, size_t len) ++retry; CHKiRet(pThis->prepRetryFunc(pData)); /* try to recover */ /* now try to send our stored previous message (which most probably - * didn't make it + * didn't make it. Note that if bResendLastOnRecon is 0, prevMsg will + * never become non-NULL, so the check below covers all cases. */ if(pThis->prevMsg != NULL) { CHKiRet(pThis->initFunc(pData)); @@ -346,6 +354,13 @@ finalize_it: /* set functions */ static rsRetVal +SetResendLastOnRecon(tcpclt_t *pThis, int bResendLastOnRecon) +{ + DEFiRet; + pThis->bResendLastOnRecon = (short) bResendLastOnRecon; + RETiRet; +} +static rsRetVal SetSendInit(tcpclt_t *pThis, rsRetVal (*pCB)(void*)) { DEFiRet; @@ -425,6 +440,7 @@ CODESTARTobjQueryInterface(tcpclt) pIf->Send = Send; /* set functions */ + pIf->SetResendLastOnRecon = SetResendLastOnRecon; pIf->SetSendInit = SetSendInit; pIf->SetSendFrame = SetSendFrame; pIf->SetSendPrepRetry = SetSendPrepRetry; -- cgit