summaryrefslogtreecommitdiffstats
path: root/runtime
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 /runtime
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 'runtime')
-rw-r--r--runtime/netstrm.c10
-rw-r--r--runtime/netstrm.h1
-rw-r--r--runtime/nsd.h3
-rw-r--r--runtime/nsd_gtls.c12
-rw-r--r--runtime/nsd_ptcp.c29
5 files changed, 54 insertions, 1 deletions
diff --git a/runtime/netstrm.c b/runtime/netstrm.c
index 786ba7f8..2f4a1964 100644
--- a/runtime/netstrm.c
+++ b/runtime/netstrm.c
@@ -234,6 +234,15 @@ Send(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf)
}
+/* check connection - slim wrapper for NSD driver function */
+static void
+CheckConnection(netstrm_t *pThis)
+{
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ pThis->Drvr.CheckConnection(pThis->pDrvrData);
+}
+
+
/* get remote hname - slim wrapper for NSD driver function */
static rsRetVal
GetRemoteHName(netstrm_t *pThis, uchar **ppsz)
@@ -314,6 +323,7 @@ CODESTARTobjQueryInterface(netstrm)
pIf->SetDrvrMode = SetDrvrMode;
pIf->SetDrvrAuthMode = SetDrvrAuthMode;
pIf->SetDrvrPermPeers = SetDrvrPermPeers;
+ pIf->CheckConnection = CheckConnection;
pIf->GetSock = GetSock;
finalize_it:
ENDobjQueryInterface(netstrm)
diff --git a/runtime/netstrm.h b/runtime/netstrm.h
index ae135beb..1a97ef23 100644
--- a/runtime/netstrm.h
+++ b/runtime/netstrm.h
@@ -52,6 +52,7 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetDrvrMode)(netstrm_t *pThis, int iMode);
rsRetVal (*SetDrvrAuthMode)(netstrm_t *pThis, uchar*);
rsRetVal (*SetDrvrPermPeers)(netstrm_t *pThis, permittedPeers_t*);
+ void (*CheckConnection)(netstrm_t *pThis); /* This is a trick mostly for plain tcp syslog */
/* the GetSock() below is a hack to make imgssapi work. In the long term,
* we should migrate imgssapi to a stream driver, which will relieve us of
* this problem. Please note that nobody else should use GetSock(). Using it
diff --git a/runtime/nsd.h b/runtime/nsd.h
index 53693b59..1811f078 100644
--- a/runtime/nsd.h
+++ b/runtime/nsd.h
@@ -53,6 +53,7 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetMode)(nsd_t *pThis, int mode); /* sets a driver specific mode - see driver doc for details */
rsRetVal (*SetAuthMode)(nsd_t *pThis, uchar*); /* sets a driver specific mode - see driver doc for details */
rsRetVal (*SetPermPeers)(nsd_t *pThis, permittedPeers_t*); /* sets driver permitted peers for auth needs */
+ void (*CheckConnection)(nsd_t *pThis); /* This is a trick mostly for plain tcp syslog */
rsRetVal (*GetSock)(nsd_t *pThis, int *pSock);
rsRetVal (*SetSock)(nsd_t *pThis, int sock);
/* GetSock() and SetSock() return an error if the driver does not use plain
@@ -60,7 +61,7 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
* those drivers that utilize the nsd_ptcp to do some of their work.
*/
ENDinterface(nsd)
-#define nsdCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
+#define nsdCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
/* interface for the select call */
BEGINinterface(nsdsel) /* name must also be changed in ENDinterface macro! */
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
index 0440f149..567701dc 100644
--- a/runtime/nsd_gtls.c
+++ b/runtime/nsd_gtls.c
@@ -1243,6 +1243,17 @@ finalize_it:
}
+/* This function checks if the connection is still alive - well, kind of...
+ * This is a dummy here. For details, check function common in ptcp driver.
+ * rgerhards, 2008-06-09
+ */
+static void
+CheckConnection(nsd_t __attribute__((unused)) *pNsd)
+{
+ /* dummy, do nothing */
+}
+
+
/* get the remote hostname. The returned hostname must be freed by the caller.
* rgerhards, 2008-04-25
*/
@@ -1507,6 +1518,7 @@ CODESTARTobjQueryInterface(nsd_gtls)
pIf->SetMode = SetMode;
pIf->SetAuthMode = SetAuthMode;
pIf->SetPermPeers =SetPermPeers;
+ pIf->CheckConnection = CheckConnection;
pIf->GetRemoteHName = GetRemoteHName;
pIf->GetRemoteIP = GetRemoteIP;
finalize_it:
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index 14c564a3..ff85619a 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -638,6 +638,34 @@ finalize_it:
}
+/* This function checks if the connection is still alive - well, kind of... It
+ * is primarily being used for plain TCP syslog and it is quite a hack. However,
+ * as it seems to work, it is worth supporting it. The bottom line is that it
+ * should not be called by anything else but a plain tcp syslog sender.
+ * In order for it to work, it must be called *immediately* *before* the send()
+ * call. For details about what is done, see here:
+ * http://blog.gerhards.net/2008/06/getting-bit-more-reliability-from-plain.html
+ * rgerhards, 2008-06-09
+ */
+static void
+CheckConnection(nsd_t *pNsd)
+{
+ int rc;
+ char msgbuf[1]; /* dummy */
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+
+ rc = recv(pThis->sock, msgbuf, 1, MSG_DONTWAIT | MSG_PEEK);
+ if(rc == 0) {
+ dbgprintf("CheckConnection detected broken connection - closing it\n");
+ /* in this case, the remote peer had shut down the connection and we
+ * need to close our side, too.
+ */
+ sockClose(&pThis->sock);
+ }
+}
+
+
/* get the remote host's IP address. The returned string must be freed by the
* caller.
* rgerhards, 2008-04-24
@@ -684,6 +712,7 @@ CODESTARTobjQueryInterface(nsd_ptcp)
pIf->Connect = Connect;
pIf->GetRemoteHName = GetRemoteHName;
pIf->GetRemoteIP = GetRemoteIP;
+ pIf->CheckConnection = CheckConnection;
finalize_it:
ENDobjQueryInterface(nsd_ptcp)