summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-05-13 11:07:20 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2011-05-13 11:07:20 +0200
commit0f5186ad01d1c429c9ed78a2a3ed3e28e1e67d00 (patch)
tree726ed8f34ffcdf51458a01c05831f91ed57ee496
parent1d39d21c62efacb39862d89755ae49ecf0cb7e23 (diff)
downloadrsyslog-0f5186ad01d1c429c9ed78a2a3ed3e28e1e67d00.tar.gz
rsyslog-0f5186ad01d1c429c9ed78a2a3ed3e28e1e67d00.tar.xz
rsyslog-0f5186ad01d1c429c9ed78a2a3ed3e28e1e67d00.zip
added support to control KEEPALIVE settings in imptcp
this has not yet been added to imtcp, but could be done on request
-rw-r--r--ChangeLog2
-rw-r--r--doc/imptcp.html15
-rw-r--r--plugins/imptcp/imptcp.c68
3 files changed, 83 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 69a91ce0..a9084201 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@ Version 5.9.0 [V5-DEVEL] (rgerhards), 2011-03-??
at the socket layer. This has not been added to imttcp, as the latter is
only an experimental module, and one which did not prove to be useful.
reference: http://kb.monitorware.com/post20791.html
+- added support to control KEEPALIVE settings in imptcp
+ this has not yet been added to imtcp, but could be done on request.
- bugfix: do not open files with full privileges, if privs will be dropped
This make the privilege drop code more bulletproof, but breaks Ubuntu's
work-around for log files created by external programs with the wrong
diff --git a/doc/imptcp.html b/doc/imptcp.html
index 8784391e..386e691a 100644
--- a/doc/imptcp.html
+++ b/doc/imptcp.html
@@ -48,6 +48,21 @@ instructs imptcp to emit a message if the remote peer closes a connection.<br>
<li><b>$InputPTCPServerKeepAlive</b> &lt;on/<b>off</b>&gt;<br>
enable of disable keep-alive packets at the tcp socket layer. The default is
to disable them.</li>
+<li><b>$InputPTCPServerKeepAlive_probes</b> &lt;number&gt;<br>
+The number of unacknowledged probes to send before considering the connection dead and notifying the application layer.
+The default, 0, means that the operating system defaults are used. This has only
+effect if keep-alive is enabled. The functionality may not be available on
+all platforms.
+<li><b>$InputPTCPServerKeepAlive_intvl</b> &lt;number&gt;<br>
+The interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime.
+The default, 0, means that the operating system defaults are used. This has only
+effect if keep-alive is enabled. The functionality may not be available on
+all platforms.
+<li><b>$InputPTCPServerKeepAlive_time</b> &lt;number&gt;<br>
+The interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further.
+The default, 0, means that the operating system defaults are used. This has only
+effect if keep-alive is enabled. The functionality may not be available on
+all platforms.
<li><b>$InputPTCPServerRun</b> &lt;port&gt;<br>
Starts a TCP server on selected port</li>
<li>$InputPTCPServerInputName &lt;name&gt;<br>
diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c
index 8333e050..8751637d 100644
--- a/plugins/imptcp/imptcp.c
+++ b/plugins/imptcp/imptcp.c
@@ -50,6 +50,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
+#include <netinet/tcp.h>
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
@@ -89,6 +90,9 @@ DEFobjCurrIf(ruleset)
/* config settings */
typedef struct configSettings_s {
int bKeepAlive; /* support keep-alive packets */
+ int iKeepAliveIntvl;
+ int iKeepAliveProbes;
+ int iKeepAliveTime;
int bEmitMsgOnClose; /* emit an informational message on close by remote peer */
int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
@@ -113,6 +117,9 @@ struct ptcpsrv_s {
uchar *port; /* Port to listen to */
uchar *lstnIP; /* which IP we should listen on? */
int iAddtlFrameDelim;
+ int iKeepAliveIntvl;
+ int iKeepAliveProbes;
+ int iKeepAliveTime;
uchar *pszInputName;
prop_t *pInputName; /* InputName in (fast to process) property format */
ruleset_t *pRuleset;
@@ -433,7 +440,7 @@ finalize_it:
/* Enable KEEPALIVE handling on the socket. */
static inline rsRetVal
-EnableKeepAlive(int sock)
+EnableKeepAlive(ptcplstn_t *pLstn, int sock)
{
int ret;
int optval;
@@ -448,6 +455,51 @@ EnableKeepAlive(int sock)
ABORT_FINALIZE(RS_RET_ERR);
}
+# if defined(TCP_KEEPCNT)
+ if(pLstn->pSrv->iKeepAliveProbes > 0) {
+ optval = pLstn->pSrv->iKeepAliveProbes;
+ optlen = sizeof(optval);
+ ret = setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &optval, optlen);
+ } else {
+ ret = 0;
+ }
+# else
+ ret = -1;
+# endif
+ if(ret < 0) {
+ errmsg.LogError(ret, NO_ERRCODE, "imptcp cannot set keepalive probes - ignored");
+ }
+
+# if defined(TCP_KEEPCNT)
+ if(pLstn->pSrv->iKeepAliveTime > 0) {
+ optval = pLstn->pSrv->iKeepAliveTime;
+ optlen = sizeof(optval);
+ ret = setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &optval, optlen);
+ } else {
+ ret = 0;
+ }
+# else
+ ret = -1;
+# endif
+ if(ret < 0) {
+ errmsg.LogError(ret, NO_ERRCODE, "imptcp cannot set keepalive time - ignored");
+ }
+
+# if defined(TCP_KEEPCNT)
+ if(pLstn->pSrv->iKeepAliveIntvl > 0) {
+ optval = pLstn->pSrv->iKeepAliveIntvl;
+ optlen = sizeof(optval);
+ ret = setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &optval, optlen);
+ } else {
+ ret = 0;
+ }
+# else
+ ret = -1;
+# endif
+ if(ret < 0) {
+ errmsg.LogError(errno, NO_ERRCODE, "imptcp cannot set keepalive intvl - ignored");
+ }
+
dbgprintf("KEEPALIVE enabled for socket %d\n", sock);
finalize_it:
@@ -476,7 +528,7 @@ AcceptConnReq(ptcplstn_t *pLstn, int *newSock, prop_t **peerName, prop_t **peerI
}
if(pLstn->pSrv->bKeepAlive)
- EnableKeepAlive(iNewSock); /* we ignore errors, best to do! */
+ EnableKeepAlive(pLstn, iNewSock);/* we ignore errors, best to do! */
CHKiRet(getPeerNames(peerName, peerIP, (struct sockaddr*) &addr));
@@ -913,6 +965,9 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
pSrv->pSess = NULL;
pSrv->pLstn = NULL;
pSrv->bKeepAlive = cs.bKeepAlive;
+ pSrv->iKeepAliveIntvl = cs.iKeepAliveTime;
+ pSrv->iKeepAliveProbes = cs.iKeepAliveProbes;
+ pSrv->iKeepAliveTime = cs.iKeepAliveTime;
pSrv->bEmitMsgOnClose = cs.bEmitMsgOnClose;
pSrv->port = pNewVal;
pSrv->iAddtlFrameDelim = cs.iAddtlFrameDelim;
@@ -1176,6 +1231,9 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
{
cs.bEmitMsgOnClose = 0;
cs.bKeepAlive = 0;
+ cs.iKeepAliveProbes = 0;
+ cs.iKeepAliveTime = 0;
+ cs.iKeepAliveIntvl = 0;
cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
free(cs.pszInputName);
cs.pszInputName = NULL;
@@ -1210,6 +1268,12 @@ CODEmodInit_QueryRegCFSLineHdlr
addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive"), 0, eCmdHdlrBinary,
NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive_probes"), 0, eCmdHdlrInt,
+ NULL, &cs.iKeepAliveProbes, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive_time"), 0, eCmdHdlrInt,
+ NULL, &cs.iKeepAliveTime, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive_intvl"), 0, eCmdHdlrInt,
+ NULL, &cs.iKeepAliveIntvl, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpservernotifyonconnectionclose"), 0,
eCmdHdlrBinary, NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,