summaryrefslogtreecommitdiffstats
path: root/tcpclt.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-06-09 12:40:54 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2008-06-09 12:40:54 +0200
commit55e01da2ec3de1b5c6b15e4154235f0eedbb68da (patch)
treefe7b9b9b114c982d1453a363499bad9fa323fd1a /tcpclt.c
parentcf51333f7617e586ca1d4cf5202e3d42f14c96ea (diff)
downloadrsyslog-55e01da2ec3de1b5c6b15e4154235f0eedbb68da.tar.gz
rsyslog-55e01da2ec3de1b5c6b15e4154235f0eedbb68da.tar.xz
rsyslog-55e01da2ec3de1b5c6b15e4154235f0eedbb68da.zip
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
Diffstat (limited to 'tcpclt.c')
-rw-r--r--tcpclt.c36
1 files changed, 26 insertions, 10 deletions
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;