summaryrefslogtreecommitdiffstats
path: root/tcpclt.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-03-12 14:50:35 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-03-12 14:50:35 +0000
commit1bc3337f004712e791abedeae8b08b2b9bd83e90 (patch)
tree70703e64c742e3b5b7210c168497de92752a0b90 /tcpclt.c
parent618a7f6a220563a50909d0e15eb90ce222aced31 (diff)
downloadrsyslog-1bc3337f004712e791abedeae8b08b2b9bd83e90.zip
rsyslog-1bc3337f004712e791abedeae8b08b2b9bd83e90.tar.gz
rsyslog-1bc3337f004712e791abedeae8b08b2b9bd83e90.tar.xz
improved session recovery when outbound tcp connection breaks, reduces
probability of message loss at the price of a highly unlikely potential (single) message duplication
Diffstat (limited to 'tcpclt.c')
-rw-r--r--tcpclt.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/tcpclt.c b/tcpclt.c
index 7262737..35daccc 100644
--- a/tcpclt.c
+++ b/tcpclt.c
@@ -303,12 +303,39 @@ Send(tcpclt_t *pThis, void *pData, char *msg, size_t len)
CHKiRet(pThis->initFunc(pData));
iRet = pThis->sendFunc(pData, msg, len);
- if(iRet == RS_RET_OK || retry > 0) {
- /* we are done - either we succeeded or the retry failed */
+ if(iRet == RS_RET_OK) {
+ /* 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
+ */
+ 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 */
bDone = 1;
- } else { /* OK, one retry */
- ++retry;
- CHKiRet(pThis->prepRetryFunc(pData)); /* try to recover */
+ } else {
+ if(retry == 0) { /* OK, one retry */
+ ++retry;
+ CHKiRet(pThis->prepRetryFunc(pData)); /* try to recover */
+ /* now try to send our stored previous message (which most probably
+ * didn't make it
+ */
+ if(pThis->prevMsg != NULL) {
+ CHKiRet(pThis->initFunc(pData));
+ CHKiRet(pThis->sendFunc(pData, pThis->prevMsg, pThis->lenPrevMsg));
+ }
+ } else {
+ /* OK, max number of retries reached, nothing we can do */
+ bDone = 1;
+ }
}
}
@@ -414,7 +441,6 @@ ENDobjQueryInterface(tcpclt)
BEGINObjClassExit(tcpclt, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
CODESTARTObjClassExit(tcpclt)
/* release objects we no longer need */
-//objRelease(net, LM_NET_FILENAME);
ENDObjClassExit(tcpclt)
@@ -424,7 +450,6 @@ ENDObjClassExit(tcpclt)
*/
BEGINObjClassInit(tcpclt, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
/* request objects we use */
-//CHKiRet(objUse(net, LM_NET_FILENAME));
/* set our own handlers */
OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, tcpcltConstructFinalize);