summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--doc/imtcp.html9
-rw-r--r--doc/manual.html4
-rw-r--r--doc/rsyslog_conf_global.html2
-rw-r--r--doc/rsyslog_tls.html18
-rw-r--r--plugins/imtcp/imtcp.c7
-rw-r--r--runtime/msg.c232
-rw-r--r--runtime/ruleset.c4
-rw-r--r--tcps_sess.c3
-rw-r--r--tcpsrv.c14
-rw-r--r--tcpsrv.h5
-rw-r--r--tests/testsuites/random.conf5
12 files changed, 178 insertions, 140 deletions
diff --git a/ChangeLog b/ChangeLog
index 8537a08f..0196e3e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -149,6 +149,8 @@ expected that interfaces, even new ones, break during the initial
---------------------------------------------------------------------------
Version 5.9.0 [V5-DEVEL] (rgerhards), 2011-03-??
- this begins a new devel branch for v5
+- added new config directive $InputTCPFlowControl to select if tcp
+ received messages shall be flagged as light delayable or not.
- enhanced omhdfs to support batching mode. This permits to increase
performance, as we now call the HDFS API with much larger message
sizes and far more infrequently
@@ -156,7 +158,16 @@ Version 5.9.0 [V5-DEVEL] (rgerhards), 2011-03-??
affected directive was: $ActionExecOnlyWhenPreviousIsSuspended on
closes: http://bugzilla.adiscon.com/show_bug.cgi?id=236
---------------------------------------------------------------------------
-Version 5.8.0 [V5-stable] (rgerhards), 2011-04-??
+Version 5.8.0 [V5-stable] (rgerhards), 2011-04-12
+
+This is the new v5-stable branch, importing all feature from the 5.7.x
+versions. To see what has changed in regard to the previous v5-stable,
+check the Changelog for 5.7.x below.
+
+- bugfix: race condition in deferred name resolution
+ closes: http://bugzilla.adiscon.com/show_bug.cgi?id=238
+ Special thanks to Marcin for his persistence in helping to solve this
+ bug.
- bugfix: DA queue was never shutdown once it was started
closes: http://bugzilla.adiscon.com/show_bug.cgi?id=241
---------------------------------------------------------------------------
@@ -311,7 +322,7 @@ Version 5.7.0 [V5-DEVEL] (rgerhards), 2010-09-16
thanks to Lennart Poettering for this patch
* sd-systemd API added as part of rsyslog runtime library
---------------------------------------------------------------------------
-Version 5.6.5 [V5-STABLE] (rgerhards), 2011-03-??
+Version 5.6.5 [V5-STABLE] (rgerhards), 2011-03-22
- bugfix: failover did not work correctly if repeated msg reduction was on
affected directive was: $ActionExecOnlyWhenPreviousIsSuspended on
closes: http://bugzilla.adiscon.com/show_bug.cgi?id=236
diff --git a/doc/imtcp.html b/doc/imtcp.html
index 422bbd55..b0aaa3c1 100644
--- a/doc/imtcp.html
+++ b/doc/imtcp.html
@@ -57,6 +57,15 @@ instructs imtcp to emit a message if the remote peer closes a connection.<br>
after loading imtcp, otherwise it may have no effect.</li>
<li><b>$InputTCPServerRun</b> &lt;port&gt;<br>
Starts a TCP server on selected port</li>
+<li><b>$InputTCPFlowControl</b> &lt;<b>on</b>/off&gt;<br>
+This setting specifies whether some message flow control shall be exercised on the
+related TCP input. If set to on, messages are handled as "light delayable", which means
+the sender is throttled a bit when the queue becomes near-full. This is done in order
+to preserve some queue space for inputs that can not throttle (like UDP), but it
+may have some undesired effect in some configurations. Still, we consider this as
+a useful setting and thus it is the default. To turn the handling off, simply
+configure that explicitely.
+</li>
<li><b>$InputTCPMaxListeners</b> &lt;number&gt;<br>
Sets the maximum number of listeners (server ports) supported. Default is 20. This must be set before the first $InputTCPServerRun directive.</li>
<li><b>$InputTCPMaxSessions</b> &lt;number&gt;<br> Sets the maximum number of sessions supported. Default is 200. This must be set before the first $InputTCPServerRun directive</li>
diff --git a/doc/manual.html b/doc/manual.html
index 485f0e3f..45ad749d 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -111,5 +111,7 @@ any restriction as long as your license is GPLv3 compatible. If your license is
you may even be still permitted to use rsyslog source code. However, then you need to look at the way
<a href="licensing.html">rsyslog is licensed</a>.</p>
<p>Feedback is always welcome, but if you have a support question, please do not
-mail Rainer directly (<a href="free_support.html">why not?</a>).
+mail Rainer directly (<a href="free_support.html">why not?</a>) - use the
+<a href="http://lists.adiscon.net/mailman/listinfo/rsyslog">rsyslogmailing list</a>
+or <a href="http://kb.monitorware.com/rsyslog-f40.html">rsyslog formum</a> instead.
</body></html>
diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html
index 7d121a4a..a5d69f1d 100644
--- a/doc/rsyslog_conf_global.html
+++ b/doc/rsyslog_conf_global.html
@@ -93,7 +93,7 @@ default 60000 (1 minute)]</li>
<li>$ActionQueueWorkerThreadMinumumMessages &lt;number&gt;, default 100</li>
<li><a href="rsconf1_actionresumeinterval.html">$ActionResumeInterval</a></li>
<li>$ActionResumeRetryCount &lt;number&gt; [default 0, -1 means eternal]</li>
-<li>$ActionSendResendLastMsgOnReconn &lt;[on/<b>off</b>]&gt; specifies if the last message is to be resend when a connecition broken and has been reconnedcted. May increase reliability, but comes at the risk of message duplication.
+<li>$ActionSendResendLastMsgOnReconnect &lt;[on/<b>off</b>]&gt; specifies if the last message is to be resend when a connecition breaks and has been reconnected. May increase reliability, but comes at the risk of message duplication.
<li>$ActionSendStreamDriver &lt;driver basename&gt; just like $DefaultNetstreamDriver, but for the specific action</li>
<li>$ActionSendStreamDriverMode &lt;mode&gt;, default 0, mode to use with the stream driver (driver-specific)</li>
<li>$ActionSendStreamDriverAuthMode &lt;mode&gt;,&nbsp; authentication mode to use with the stream driver. Note that this directive requires TLS
diff --git a/doc/rsyslog_tls.html b/doc/rsyslog_tls.html
index bb312c77..286660d2 100644
--- a/doc/rsyslog_tls.html
+++ b/doc/rsyslog_tls.html
@@ -162,25 +162,11 @@ similar "smart" command on the client. It should show up in the
respective server log file. If you dig out your sniffer, you should see
that the traffic on the wire is actually protected.</p>
<h3>Limitations</h3>
-<p>The current implementation has a number of limitations. These
-are
-being worked on. Most importantly, neither the client nor the server
-are authenticated. So while the message transfer is encrypted, you can
-not be sure which peer you are talking to. Please note that this is a
-limitation found in most real-world SSL syslog systems. Of course, that
-is not an excuse for not yet providing this feature - but it tells you
-that it is acceptable and can be worked around by proper firewalling,
-ACLs and other organizational measures. Mutual authentication will be
-added shortly to rsyslog.</p>
-<p>Secondly, the plain tcp syslog listener
-can currently listen to a single port, in a single mode. So if you use
-a TLS-based listener, you can not run unencrypted syslog on the same
-instance at the same time. A work-around is to run a second rsyslogd
-instance. This limitation, too, is scheduled to be removed soon.</p>
<p>The
RELP transport can currently not be protected by TLS. A work-around is
to use stunnel. TLS support for RELP will be added once plain TCP
-syslog has sufficiently matured.</p>
+syslog has sufficiently matured and there either is some time left to do this
+or we find a sponsor ;).</p>
<h2>Certificates</h2>
<p>In order to be really secure, certificates are needed. This is
a short summary on how to generate the necessary certificates with
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index a383276f..24c0cd7e 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -3,7 +3,7 @@
*
* File begun on 2007-12-21 by RGerhards (extracted from syslogd.c)
*
- * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -88,6 +88,7 @@ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mos
static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */
static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */
static int bDisableLFDelim = 0; /* disbale standard LF delimiter */
+static int bUseFlowControl = 1; /* use flow control, what means indicate ourselfs a "light delayable" */
static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */
static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */
static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */
@@ -199,6 +200,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode));
+ CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, bUseFlowControl));
CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim));
CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, bDisableLFDelim));
CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, bEmitMsgOnClose));
@@ -289,6 +291,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
iTCPSessMax = 200;
iTCPLstnMax = 20;
iStrmDrvrMode = 0;
+ bUseFlowControl = 0;
bEmitMsgOnClose = 0;
iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
bDisableLFDelim = 0;
@@ -344,6 +347,8 @@ CODEmodInit_QueryRegCFSLineHdlr
eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID, eConfObjGlobal));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0,
eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0,
+ eCmdHdlrBinary, NULL, &bUseFlowControl, STD_LOADABLE_MODULE_ID, eConfObjGlobal));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal));
ENDmodInit
diff --git a/runtime/msg.c b/runtime/msg.c
index 8016068b..d2612437 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -288,6 +288,121 @@ static pthread_mutex_t mutTrimCtr; /* mutex to handle malloc trim */
static int getAPPNAMELen(msg_t *pM, sbool bLockMutex);
+/* The following functions will support advanced output module
+ * multithreading, once this is implemented. Currently, we
+ * include them as hooks only. The idea is that we need to guard
+ * some msg objects data fields against concurrent access if
+ * we run on multiple threads. Please note that in any case this
+ * is not necessary for calls from INPUT modules, because they
+ * construct the message object and do this serially. Only when
+ * the message is in the processing queue, multiple threads may
+ * access a single object. Consequently, there are no guard functions
+ * for "set" methods, as these are called during input. Only "get"
+ * functions that modify important structures have them.
+ * rgerhards, 2007-07-20
+ * We now support locked and non-locked operations, depending on
+ * the configuration of rsyslog. To support this, we use function
+ * pointers. Initially, we start in non-locked mode. There, all
+ * locking operations call into dummy functions. When locking is
+ * enabled, the function pointers are changed to functions doing
+ * actual work. We also introduced another MsgPrepareEnqueue() function
+ * which initializes the locking structures, if needed. This is
+ * necessary because internal messages during config file startup
+ * processing are always created in non-locking mode. So we can
+ * not initialize locking structures during constructions. We now
+ * postpone this until when the message is fully constructed and
+ * enqueued. Then we know the status of locking. This has a nice
+ * side effect, and that is that during the initial creation of
+ * the Msg object no locking needs to be done, which results in better
+ * performance. -- rgerhards, 2008-01-05
+ */
+static void (*funcLock)(msg_t *pMsg);
+static void (*funcUnlock)(msg_t *pMsg);
+static void (*funcDeleteMutex)(msg_t *pMsg);
+void (*funcMsgPrepareEnqueue)(msg_t *pMsg);
+#if 1 /* This is a debug aid */
+#define MsgLock(pMsg) funcLock(pMsg)
+#define MsgUnlock(pMsg) funcUnlock(pMsg)
+#else
+#define MsgLock(pMsg) {dbgprintf("MsgLock line %d\n - ", __LINE__); funcLock(pMsg);; }
+#define MsgUnlock(pMsg) {dbgprintf("MsgUnlock line %d - ", __LINE__); funcUnlock(pMsg); }
+#endif
+
+/* the next function is a dummy to be used by the looking functions
+ * when the class is not yet running in an environment where locking
+ * is necessary. Please note that the need to lock can (and will) change
+ * during a single run. Typically, this is depending on the operation mode
+ * of the message queues (which is operator-configurable). -- rgerhards, 2008-01-05
+ */
+static void MsgLockingDummy(msg_t __attribute__((unused)) *pMsg)
+{
+ /* empty be design */
+}
+
+
+/* The following function prepares a message for enqueue into the queue. This is
+ * where a message may be accessed by multiple threads. This implementation here
+ * is the version for multiple concurrent acces. It initializes the locking
+ * structures.
+ * TODO: change to an iRet interface! -- rgerhards, 2008-07-14
+ */
+static void MsgPrepareEnqueueLockingCase(msg_t *pThis)
+{
+ BEGINfunc
+ assert(pThis != NULL);
+ pthread_mutex_init(&pThis->mut, NULL);
+ pThis->bDoLock = 1;
+ ENDfunc
+}
+
+
+/* ... and now the locking and unlocking implementations: */
+static void MsgLockLockingCase(msg_t *pThis)
+{
+ /* DEV debug only! dbgprintf("MsgLock(0x%lx)\n", (unsigned long) pThis); */
+ assert(pThis != NULL);
+ if(pThis->bDoLock == 1) /* TODO: this is a testing hack, we should find a way with better performance! -- rgerhards, 2009-01-27 */
+ pthread_mutex_lock(&pThis->mut);
+}
+
+static void MsgUnlockLockingCase(msg_t *pThis)
+{
+ /* DEV debug only! dbgprintf("MsgUnlock(0x%lx)\n", (unsigned long) pThis); */
+ assert(pThis != NULL);
+ if(pThis->bDoLock == 1) /* TODO: this is a testing hack, we should find a way with better performance! -- rgerhards, 2009-01-27 */
+ pthread_mutex_unlock(&pThis->mut);
+}
+
+/* delete the mutex object on message destruction (locking case)
+ */
+static void MsgDeleteMutexLockingCase(msg_t *pThis)
+{
+ assert(pThis != NULL);
+ pthread_mutex_destroy(&pThis->mut);
+}
+
+/* enable multiple concurrent access on the message object
+ * This works on a class-wide basis and can bot be undone.
+ * That is, if it is once enabled, it can not be disabled during
+ * the same run. When this function is called, no other thread
+ * must manipulate message objects. Then we would have race conditions,
+ * but guarding against this is counter-productive because it
+ * would cost additional time. Plus, it would be a programming error.
+ * rgerhards, 2008-01-05
+ */
+rsRetVal MsgEnableThreadSafety(void)
+{
+ DEFiRet;
+ funcLock = MsgLockLockingCase;
+ funcUnlock = MsgUnlockLockingCase;
+ funcMsgPrepareEnqueue = MsgPrepareEnqueueLockingCase;
+ funcDeleteMutex = MsgDeleteMutexLockingCase;
+ RETiRet;
+}
+
+/* end locking functions */
+
+
static inline int getProtocolVersion(msg_t *pM)
{
return(pM->iProtocolVersion);
@@ -307,6 +422,7 @@ resolveDNS(msg_t *pMsg) {
uchar fromHostFQDN[NI_MAXHOST];
DEFiRet;
+ MsgLock(pMsg);
CHKiRet(objUse(net, CORE_COMPONENT));
if(pMsg->msgFlags & NEEDS_DNSRESOL) {
localRet = net.cvthname(pMsg->rcvFrom.pfrominet, fromHost, fromHostFQDN, fromHostIP);
@@ -316,6 +432,7 @@ resolveDNS(msg_t *pMsg) {
}
}
finalize_it:
+ MsgUnlock(pMsg);
if(iRet != RS_RET_OK) {
/* best we can do: remove property */
MsgSetRcvFromStr(pMsg, UCHAR_CONSTANT(""), 0, &propFromHost);
@@ -544,121 +661,6 @@ uchar *propIDToName(propid_t propID)
}
-/* The following functions will support advanced output module
- * multithreading, once this is implemented. Currently, we
- * include them as hooks only. The idea is that we need to guard
- * some msg objects data fields against concurrent access if
- * we run on multiple threads. Please note that in any case this
- * is not necessary for calls from INPUT modules, because they
- * construct the message object and do this serially. Only when
- * the message is in the processing queue, multiple threads may
- * access a single object. Consequently, there are no guard functions
- * for "set" methods, as these are called during input. Only "get"
- * functions that modify important structures have them.
- * rgerhards, 2007-07-20
- * We now support locked and non-locked operations, depending on
- * the configuration of rsyslog. To support this, we use function
- * pointers. Initially, we start in non-locked mode. There, all
- * locking operations call into dummy functions. When locking is
- * enabled, the function pointers are changed to functions doing
- * actual work. We also introduced another MsgPrepareEnqueue() function
- * which initializes the locking structures, if needed. This is
- * necessary because internal messages during config file startup
- * processing are always created in non-locking mode. So we can
- * not initialize locking structures during constructions. We now
- * postpone this until when the message is fully constructed and
- * enqueued. Then we know the status of locking. This has a nice
- * side effect, and that is that during the initial creation of
- * the Msg object no locking needs to be done, which results in better
- * performance. -- rgerhards, 2008-01-05
- */
-static void (*funcLock)(msg_t *pMsg);
-static void (*funcUnlock)(msg_t *pMsg);
-static void (*funcDeleteMutex)(msg_t *pMsg);
-void (*funcMsgPrepareEnqueue)(msg_t *pMsg);
-#if 1 /* This is a debug aid */
-#define MsgLock(pMsg) funcLock(pMsg)
-#define MsgUnlock(pMsg) funcUnlock(pMsg)
-#else
-#define MsgLock(pMsg) {dbgprintf("MsgLock line %d\n - ", __LINE__); funcLock(pMsg);; }
-#define MsgUnlock(pMsg) {dbgprintf("MsgUnlock line %d - ", __LINE__); funcUnlock(pMsg); }
-#endif
-
-/* the next function is a dummy to be used by the looking functions
- * when the class is not yet running in an environment where locking
- * is necessary. Please note that the need to lock can (and will) change
- * during a single run. Typically, this is depending on the operation mode
- * of the message queues (which is operator-configurable). -- rgerhards, 2008-01-05
- */
-static void MsgLockingDummy(msg_t __attribute__((unused)) *pMsg)
-{
- /* empty be design */
-}
-
-
-/* The following function prepares a message for enqueue into the queue. This is
- * where a message may be accessed by multiple threads. This implementation here
- * is the version for multiple concurrent acces. It initializes the locking
- * structures.
- * TODO: change to an iRet interface! -- rgerhards, 2008-07-14
- */
-static void MsgPrepareEnqueueLockingCase(msg_t *pThis)
-{
- BEGINfunc
- assert(pThis != NULL);
- pthread_mutex_init(&pThis->mut, NULL);
- pThis->bDoLock = 1;
- ENDfunc
-}
-
-
-/* ... and now the locking and unlocking implementations: */
-static void MsgLockLockingCase(msg_t *pThis)
-{
- /* DEV debug only! dbgprintf("MsgLock(0x%lx)\n", (unsigned long) pThis); */
- assert(pThis != NULL);
- if(pThis->bDoLock == 1) /* TODO: this is a testing hack, we should find a way with better performance! -- rgerhards, 2009-01-27 */
- pthread_mutex_lock(&pThis->mut);
-}
-
-static void MsgUnlockLockingCase(msg_t *pThis)
-{
- /* DEV debug only! dbgprintf("MsgUnlock(0x%lx)\n", (unsigned long) pThis); */
- assert(pThis != NULL);
- if(pThis->bDoLock == 1) /* TODO: this is a testing hack, we should find a way with better performance! -- rgerhards, 2009-01-27 */
- pthread_mutex_unlock(&pThis->mut);
-}
-
-/* delete the mutex object on message destruction (locking case)
- */
-static void MsgDeleteMutexLockingCase(msg_t *pThis)
-{
- assert(pThis != NULL);
- pthread_mutex_destroy(&pThis->mut);
-}
-
-/* enable multiple concurrent access on the message object
- * This works on a class-wide basis and can bot be undone.
- * That is, if it is once enabled, it can not be disabled during
- * the same run. When this function is called, no other thread
- * must manipulate message objects. Then we would have race conditions,
- * but guarding against this is counter-productive because it
- * would cost additional time. Plus, it would be a programming error.
- * rgerhards, 2008-01-05
- */
-rsRetVal MsgEnableThreadSafety(void)
-{
- DEFiRet;
- funcLock = MsgLockLockingCase;
- funcUnlock = MsgUnlockLockingCase;
- funcMsgPrepareEnqueue = MsgPrepareEnqueueLockingCase;
- funcDeleteMutex = MsgDeleteMutexLockingCase;
- RETiRet;
-}
-
-/* end locking functions */
-
-
/* This is common code for all Constructors. It is defined in an
* inline'able function so that we can save a function call in the
* actual constructors (otherwise, the msgConstruct would need
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index f48c2c2d..2d4f113e 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -223,7 +223,7 @@ processBatch(batch_t *pBatch)
DEFiRet;
assert(pBatch != NULL);
-dbgprintf("ZZZ: processBatch: batch of %d elements must be processed\n", pBatch->nElem);
+ DBGPRINTF("processBatch: batch of %d elements must be processed\n", pBatch->nElem);
if(pBatch->bSingleRuleset) {
pThis = batchGetRuleset(pBatch);
if(pThis == NULL)
@@ -235,7 +235,7 @@ dbgprintf("ZZZ: processBatch: batch of %d elements must be processed\n", pBatch-
}
finalize_it:
-dbgprintf("ruleset.ProcessMsg() returns %d\n", iRet);
+ DBGPRINTF("ruleset.ProcessMsg() returns %d\n", iRet);
RETiRet;
}
diff --git a/tcps_sess.c b/tcps_sess.c
index 8b944885..c64a9547 100644
--- a/tcps_sess.c
+++ b/tcps_sess.c
@@ -254,7 +254,8 @@ defaultDoSubmitMessage(tcps_sess_t *pThis, struct syslogTime *stTime, time_t ttG
CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime));
MsgSetRawMsg(pMsg, (char*)pThis->pMsg, pThis->iMsg);
MsgSetInputName(pMsg, pThis->pLstnInfo->pInputName);
- MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
+ MsgSetFlowControlType(pMsg, pThis->pSrv->bUseFlowControl
+ ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY);
pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME;
MsgSetRcvFrom(pMsg, pThis->fromHost);
CHKiRet(MsgSetRcvFromIP(pMsg, pThis->fromHostIP));
diff --git a/tcpsrv.c b/tcpsrv.c
index a87b4a1f..39cba5d1 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -874,6 +874,7 @@ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macr
pThis->addtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
pThis->bDisableLFDelim = 0;
pThis->OnMsgReceive = NULL;
+ pThis->bUseFlowControl = 1;
ENDobjConstruct(tcpsrv)
@@ -1149,6 +1150,18 @@ SetLstnMax(tcpsrv_t *pThis, int iMax)
}
+/* set if flow control shall be supported
+ */
+static rsRetVal
+SetUseFlowControl(tcpsrv_t *pThis, int bUseFlowControl)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+ pThis->bUseFlowControl = bUseFlowControl;
+ RETiRet;
+}
+
+
/* set max number of sessions
* this must be called before ConstructFinalize, or it will have no effect!
* rgerhards, 2009-04-09
@@ -1191,6 +1204,7 @@ CODESTARTobjQueryInterface(tcpsrv)
pIf->SetAddtlFrameDelim = SetAddtlFrameDelim;
pIf->SetbDisableLFDelim = SetbDisableLFDelim;
pIf->SetSessMax = SetSessMax;
+ pIf->SetUseFlowControl = SetUseFlowControl;
pIf->SetLstnMax = SetLstnMax;
pIf->SetDrvrMode = SetDrvrMode;
pIf->SetDrvrAuthMode = SetDrvrAuthMode;
diff --git a/tcpsrv.h b/tcpsrv.h
index d8669540..b5557d4e 100644
--- a/tcpsrv.h
+++ b/tcpsrv.h
@@ -56,6 +56,7 @@ struct tcpsrv_s {
permittedPeers_t *pPermPeers;/**< driver's permitted peers */
sbool bEmitMsgOnClose; /**< emit an informational message when the remote peer closes connection */
sbool bUsingEPoll; /**< are we in epoll mode (means we do not need to keep track of sessions!) */
+ sbool bUseFlowControl; /**< use flow control (make light delayable) */
int iLstnCurr; /**< max nbr of listeners currently supported */
netstrm_t **ppLstn; /**< our netstream listners */
tcpLstnPortList_t **ppLstnPort; /**< pointer to relevant listen port description */
@@ -133,8 +134,10 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetNotificationOnRemoteClose)(tcpsrv_t *pThis, int bNewVal); /* 2009-10-01 */
/* added v9 -- rgerhards, 2010-03-01 */
rsRetVal (*SetbDisableLFDelim)(tcpsrv_t*, int);
+ /* added v10 -- rgerhards, 2011-04-01 */
+ rsRetVal (*SetUseFlowControl)(tcpsrv_t*, int);
ENDinterface(tcpsrv)
-#define tcpsrvCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */
+#define tcpsrvCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */
/* change for v4:
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
* - SetInputName() added -- rgerhards, 2008-12-10
diff --git a/tests/testsuites/random.conf b/tests/testsuites/random.conf
index a7079df1..74ec61a8 100644
--- a/tests/testsuites/random.conf
+++ b/tests/testsuites/random.conf
@@ -4,6 +4,11 @@
# rgerhards, 2010-04-01
$IncludeConfig diag-common.conf
+# The random data will generate TCP framing error messages. We will
+# not clutter the test output with them. So we disable error messages
+# to stderr.
+$ErrorMessagesToStderr off
+
$ModLoad ../plugins/imtcp/.libs/imtcp
$MainMsgQueueTimeoutShutdown 10000
$InputTCPServerRun 13514