summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-05-06 10:25:42 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2008-05-06 10:25:42 +0200
commit9e0af15a324cca5bd50ec3226c64ca9ddb2e8d40 (patch)
treed6db3c3908fcada54d916fd680c669ff0e4f36c0
parent4ec4f4ddae4285adf0a40618360ec5cea02d85c3 (diff)
parentfcbead3d4cbda4c79bb7110e65c85afad4131cb8 (diff)
downloadrsyslog-9e0af15a324cca5bd50ec3226c64ca9ddb2e8d40.tar.gz
rsyslog-9e0af15a324cca5bd50ec3226c64ca9ddb2e8d40.tar.xz
rsyslog-9e0af15a324cca5bd50ec3226c64ca9ddb2e8d40.zip
Merge branch 'tls'
-rw-r--r--Makefile.am3
-rw-r--r--action.c2
-rw-r--r--contrib/gnutls/ca.pem (renamed from ca.pem)0
-rw-r--r--contrib/gnutls/cert.pem33
-rw-r--r--contrib/gnutls/key.pem15
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/rsyslog_conf.html16
-rw-r--r--plugins/imgssapi/imgssapi.c27
-rw-r--r--plugins/imtcp/imtcp.c18
-rw-r--r--runtime/Makefile.am34
-rw-r--r--runtime/debug.c2
-rw-r--r--runtime/glbl.c70
-rw-r--r--runtime/glbl.h3
-rw-r--r--runtime/modules.c13
-rw-r--r--runtime/netstrm.c62
-rw-r--r--runtime/netstrm.h13
-rw-r--r--runtime/netstrms.c101
-rw-r--r--runtime/netstrms.h7
-rw-r--r--runtime/nsd.h1
-rw-r--r--runtime/nsd_gtls.c190
-rw-r--r--runtime/nsd_gtls.h10
-rw-r--r--runtime/nsd_ptcp.c28
-rw-r--r--runtime/nsdsel_gtls.c107
-rw-r--r--runtime/nsdsel_gtls.h3
-rw-r--r--runtime/nsdsel_ptcp.c30
-rw-r--r--runtime/nsdsel_ptcp.h3
-rw-r--r--runtime/nssel.c66
-rw-r--r--runtime/nssel.h7
-rw-r--r--runtime/obj.c6
-rw-r--r--runtime/rsyslog.h3
-rw-r--r--tcps_sess.c5
-rw-r--r--tcpsrv.c52
-rw-r--r--tcpsrv.h2
-rw-r--r--tools/omfile.c3
-rw-r--r--tools/omfwd.c42
35 files changed, 713 insertions, 266 deletions
diff --git a/Makefile.am b/Makefile.am
index a3e67bc8..ab344867 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -51,6 +51,9 @@ EXTRA_DIST = \
contrib/README \
rsyslog.conf \
COPYING.LESSER \
+ contrib/gnutls/ca.pem \
+ contrib/gnutls/cert.pem \
+ contrib/gnutls/key.pem \
$(man_MANS)
SUBDIRS = doc runtime .
diff --git a/action.c b/action.c
index 89ec3f74..216a7804 100644
--- a/action.c
+++ b/action.c
@@ -541,7 +541,7 @@ actionWriteToAction(action_t *pAction)
pAction->f_pMsg = pMsg; /* use the new msg (pointer will be restored below) */
}
- dbgprintf("Called action, logging to %s", module.GetStateName(pAction->pMod));
+ dbgprintf("Called action, logging to %s\n", module.GetStateName(pAction->pMod));
time(&now); /* we need this for message repeation processing AND $ActionExecOnlyOnceEveryInterval */
/* now check if we need to drop the message because otherwise the action would be too
diff --git a/ca.pem b/contrib/gnutls/ca.pem
index 747250ca..747250ca 100644
--- a/ca.pem
+++ b/contrib/gnutls/ca.pem
diff --git a/contrib/gnutls/cert.pem b/contrib/gnutls/cert.pem
new file mode 100644
index 00000000..88910725
--- /dev/null
+++ b/contrib/gnutls/cert.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIICmDCCAgOgAwIBAgIBAjALBgkqhkiG9w0BAQUwUjELMAkGA1UEBhMCR1IxDDAK
+BgNVBAoTA0ZTRjEPMA0GA1UECxMGR05VVExTMSQwIgYDVQQDExtHTlVUTFMgSU5U
+RVJNRURJQVRFIFRFU1QgQ0EwHhcNMDQwNjI4MjI0NzAwWhcNMDcwMzIyMjI0NzAw
+WjBJMQswCQYDVQQGEwJHUjEMMAoGA1UEChMDRlNGMQ8wDQYDVQQLEwZHTlVUTFMx
+GzAZBgNVBAMTEkdOVVRMUyBURVNUIFNFUlZFUjCBnDALBgkqhkiG9w0BAQEDgYwA
+MIGIAoGA1chUqA9ib8S5GKd29B9d1rwgUncFhJPu0+RK8kOyOsV3qBdtdWeBSiGW
+So1RHkcmV9BlbUtmuHioAUkZPSo8gtoEy3JpSemW221BsjwITjGeZxZsb+4C/U2X
+HUIlO+jqBK5VYbpNXkP/2ofMkWWAZyKnI+PMIfFvv/cASsI0k48CAwEAAaOBjTCB
+ijAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDATBgNVHSUEDDAK
+BggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDB6AAMB0GA1UdDgQWBBTIZD/hlqUB89OE
+AwonwqGflkHtijAfBgNVHSMEGDAWgBQ2tS+xHdrw3r4o20MwGkLdzh5UlDALBgkq
+hkiG9w0BAQUDgYEAWPpWlUlvzDZRbpneYw8d6Q8On/ZPmSYBCm38vTKPEoNA6lW1
+WIc3Vbw5zOeSfDLifIWV2W/MqyjDo9MeWvSKpcUfRfibpXBgbA4RAGW0j2K1JQmE
+gP3k1vMicYzn5EglhZjoa9I+36a90vJraqzHQ7DrKtW0FDfW2GREzSh9RV8=
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIICajCCAdWgAwIBAgIBATALBgkqhkiG9w0BAQUwRTELMAkGA1UEBhMCR1IxDDAK
+BgNVBAoTA0ZTRjEPMA0GA1UECxMGR05VVExTMRcwFQYDVQQDEw5HTlVUTFMgVEVT
+VCBDQTAeFw0wNDA2MjgyMjQ2MDBaFw0wNzAzMjMyMjQ2MDBaMFIxCzAJBgNVBAYT
+AkdSMQwwCgYDVQQKEwNGU0YxDzANBgNVBAsTBkdOVVRMUzEkMCIGA1UEAxMbR05V
+VExTIElOVEVSTUVESUFURSBURVNUIENBMIGcMAsGCSqGSIb3DQEBAQOBjAAwgYgC
+gYC0JKSLzHuiWK66XYOJk6AxDBo94hdCFnfIor7xnZkqTgiUQZhk9HDVmmz1+tLd
+yJk6r9PK+WMDDBkSOvT+SmQNd9mL2JzI+bJWwoB77aJ7vUI3/9+ugtffiapnX6wx
+vLyAxeJRyN0Q3oBHc6N2dJo9z1NHoFe8xipXXHOdxU1DAwIDAQABo2QwYjAPBgNV
+HRMBAf8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBAAwHQYDVR0OBBYEFDa1L7Ed2vDe
+vijbQzAaQt3OHlSUMB8GA1UdIwQYMBaAFHnrG2+jZuZ54dHitdvaJwZFKQpIMAsG
+CSqGSIb3DQEBBQOBgQCi/SI37DrGCeZhtGhU2AyZFaqskRoFt4zAb9UYaGZaYEh5
+0VUZsA/Ol8jiiQTtiCokZswhSsn+2McZmcspKigsY2aEBrry+TGFWMnYu5j5kcwP
+1nVuHxLRwLt2rIsjgkeSNdHr8XHKi9/Roz/Gj86OnBAHwPt8WHfHK+63cMX1WA==
+-----END CERTIFICATE-----
+
diff --git a/contrib/gnutls/key.pem b/contrib/gnutls/key.pem
new file mode 100644
index 00000000..1e80b2e5
--- /dev/null
+++ b/contrib/gnutls/key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQDVyFSoD2JvxLkYp3b0H13WvCBSdwWEk+7T5EryQ7I6xXeoF211
+Z4FKIZZKjVEeRyZX0GVtS2a4eKgBSRk9KjyC2gTLcmlJ6ZbbbUGyPAhOMZ5nFmxv
+7gL9TZcdQiU76OoErlVhuk1eQ//ah8yRZYBnIqcj48wh8W+/9wBKwjSTjwIDAQAB
+AoGAAn2Ueua++1Vb4K0mxh5NbhCAAeXwEwTULfTFaMAgJe4iADvRoyIDEBWHFjRC
+QyuKB1DetaDAwBprvqQW3q8MyGYD7P9h85Wfu/hpIYKTw9hNeph420aE8WXw2ygl
+TkJz3bzkMrXe/WjdhS1kTt8avCNQR/p0jM/UHvNze4oLc1ECQQDfammiczQFtj+F
+uf3CNcYwp5XNumF+pubdGb+UHUiHyCuVQxvm+LXgq8wXV/uXFLrp7FQFLCDQf0ji
+KDB2YQvRAkEA9PY/2AaGsU7j8ePwQbxCkwuj3hY6O6aNLIGxKxwZrzbob26c+tQk
+/++e0IXusIscBvcRV1Kg8Ff6fnw7/AdhXwJAG8qVbOuRmGk0BkwuFmPoeW3vNQgR
+X96O7po0qPBqVdRAU2rvzYtkCFxYqq0ilI0ekZtAfKxbeykaQaRkkKPaoQJAcifP
+yWJ/tu8z4DM7Ka+pFqTMwIllM1U3vFtv3LXezDE7AGDCyHKdB7MXcPXqj6nmCLMi
+swwiLLahAOBnUqk6xwJAJQ4pGcFFlCiIiVsq0wYSYmZUcRpSIInEQ0f8/xN6J22Z
+siP5vnJM3F7R6ciYTt2gzNci/W9cdZI2HxskkO5lbQ==
+-----END RSA PRIVATE KEY-----
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 90be2725..da2e2328 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -37,7 +37,7 @@ html_files = \
imklog.html \
professional_support.html \
queues.html \
- queueWorkerLogic.dia \
+ src/queueWorkerLogic.dia \
queueWorkerLogic.jpg \
queueWorkerLogic_small.jpg \
rainerscript.html \
diff --git a/doc/rsyslog_conf.html b/doc/rsyslog_conf.html
index 4dcef903..545bdbc2 100644
--- a/doc/rsyslog_conf.html
+++ b/doc/rsyslog_conf.html
@@ -116,19 +116,23 @@ default 60000 (1 minute)]</li>
<li>$ActionQueueType [FixedArray/LinkedList/<b>Direct</b>/Disk]</li>
<li>$ActionQueueSaveOnShutdown&nbsp; [on/<b>off</b>]
</li>
-<li>$ActionQueueWorkerThreads &lt;number&gt;, num
-worker threads, default 1, recommended 1</li>
-<li>$ActionQueueWorkerThreadMinumumMessages
-&lt;number&gt;, default 100</li>
+<li>$ActionQueueWorkerThreads &lt;number&gt;, num worker threads, default 1, recommended 1</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>$ActionResumeRetryCount &lt;number&gt; [default 0, -1 means eternal]</li>
+<li>$ActionSendStreamDriver &lt;driver basename&gt; just like $DefaultNetstreamDriver, but for the specific action
+<li>$ActionSendStreamDriverMode &lt;mode&gt;, default 0, mode to use with the stream driver
+(driver-specific)</li>
<li><a href="rsconf1_allowedsender.html">$AllowedSender</a></li>
<li><a href="rsconf1_controlcharacterescapeprefix.html">$ControlCharacterEscapePrefix</a></li>
<li><a href="rsconf1_debugprintcfsyslinehandlerlist.html">$DebugPrintCFSyslineHandlerList</a></li>
<li><a href="rsconf1_debugprintmodulelist.html">$DebugPrintModuleList</a></li>
<li><a href="rsconf1_debugprinttemplatelist.html">$DebugPrintTemplateList</a></li>
+<li>$DefaultNetstreamDriver &lt;drivername&gt;, default lmnsd_ptcp, use lmnsd_gtls for TLS protection</li>
+<li>$DefaultNetstreamDriverCAFile &lt;/path/to/cafile.pem&gt;</li>
+<li>$DefaultNetstreamDriverCertFile &lt;/path/to/certfile.pem&gt;</li>
+<li>$DefaultNetstreamDriverKeyFile &lt;/path/to/keyfile.pem&gt;</li>
<li><a href="rsconf1_dircreatemode.html">$DirCreateMode</a></li>
<li><a href="rsconf1_dirgroup.html">$DirGroup</a></li>
<li><a href="rsconf1_dirowner.html">$DirOwner</a></li>
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index c9ac45d1..48cc99a2 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -54,6 +54,7 @@
#include "tcpsrv.h"
#include "tcps_sess.h"
#include "errmsg.h"
+#include "netstrm.h"
MODULE_TYPE_INPUT
@@ -77,6 +78,7 @@ DEFobjCurrIf(tcpsrv)
DEFobjCurrIf(tcps_sess)
DEFobjCurrIf(gssutil)
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(netstrm)
DEFobjCurrIf(net)
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
@@ -241,11 +243,12 @@ onErrClose(tcps_sess_t *pSess)
/* open the listen sockets */
-static int*
+static rsRetVal
doOpenLstnSocks(tcpsrv_t *pSrv)
{
int *pRet = NULL;
gsssrv_t *pGSrv;
+ DEFiRet;
ISOBJ_TYPE_assert(pSrv, tcpsrv);
pGSrv = pSrv->pUsr;
@@ -261,20 +264,20 @@ doOpenLstnSocks(tcpsrv_t *pSrv)
}
if(pGSrv->allowedMethods) {
/* fallback to plain TCP */
- if((pRet = tcpsrv.create_tcp_socket(pSrv)) != NULL) {
- dbgprintf("Opened %d syslog TCP port(s).\n", *pRet);
- }
+ CHKiRet(tcpsrv.create_tcp_socket(pSrv));
+ dbgprintf("Opened %d syslog TCP port(s).\n", *pRet);
}
}
- return pRet;
+finalize_it:
+ RETiRet;
}
static int
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf)
{
- int state;
+ ssize_t state;
int allowedMethods;
gss_sess_t *pGSess;
@@ -285,8 +288,10 @@ doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf)
allowedMethods = pGSess->allowedMethods;
if(allowedMethods & ALLOWEDMETHOD_GSS)
state = TCPSessGSSRecv(pSess, buf, lenBuf);
- else
- state = recv(pSess->sock, buf, lenBuf, 0);
+ else {
+ if(netstrm.Rcv(pSess->pStrm, (uchar*) buf, &state) != RS_RET_OK)
+ state = -1; // TODO: move this function to an iRet interface! 2008-05-05
+ }
return state;
}
@@ -391,7 +396,7 @@ OnSessAcceptGSS(tcpsrv_t *pThis, tcps_sess_t *pSess)
dbgprintf("GSS-API Trying to accept TCP session %p\n", pSess);
- fdSess = pSess->sock; // TODO: method access!
+ CHKiRet(netstrm.GetSock(pSess->pStrm, &fdSess)); // TODO: method access!
if (allowedMethods & ALLOWEDMETHOD_TCP) {
int len;
fd_set fds;
@@ -537,7 +542,7 @@ int TCPSessGSSRecv(tcps_sess_t *pSess, void *buf, size_t buf_len)
assert(pSess->pUsr != NULL);
pGSess = (gss_sess_t*) pSess->pUsr;
- fdSess = pSess->sock;
+ netstrm.GetSock(pSess->pStrm, &fdSess); // TODO: method access, CHKiRet!
if ((state = gssutil.recv_token(fdSess, &xmit_buf)) <= 0)
return state;
@@ -638,6 +643,7 @@ CODESTARTmodExit
objRelease(tcpsrv, LM_TCPSRV_FILENAME);
objRelease(gssutil, LM_GSSUTIL_FILENAME);
objRelease(errmsg, CORE_COMPONENT);
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
objRelease(net, LM_NET_FILENAME);
ENDmodExit
@@ -684,6 +690,7 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME));
CHKiRet(objUse(gssutil, LM_GSSUTIL_FILENAME));
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
CHKiRet(objUse(net, LM_NET_FILENAME));
/* register config file handlers */
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 1e599d14..1bf30493 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -44,6 +44,7 @@
#include "module-template.h"
#include "net.h"
#include "netstrm.h"
+#include "errmsg.h"
#include "tcpsrv.h"
MODULE_TYPE_INPUT
@@ -54,12 +55,14 @@ DEFobjCurrIf(tcpsrv)
DEFobjCurrIf(tcps_sess)
DEFobjCurrIf(net)
DEFobjCurrIf(netstrm)
+DEFobjCurrIf(errmsg)
/* Module static data */
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
/* config settings */
static int iTCPSessMax = 200; /* max number of sessions */
+static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
/* callbacks */
@@ -129,11 +132,17 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks));
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
+ CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode));
tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal);
CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
}
finalize_it:
+ if(iRet != RS_RET_OK) {
+ errmsg.LogError(NO_ERRCODE, "error %d trying to add listener", iRet);
+ if(pOurTcpsrv != NULL)
+ tcpsrv.Destruct(&pOurTcpsrv);
+ }
RETiRet;
}
@@ -176,9 +185,10 @@ CODESTARTmodExit
/* release objects we used */
objRelease(net, LM_NET_FILENAME);
- objRelease(netstrm, LM_NETSTRM_FILENAME);
+ objRelease(netstrm, LM_NETSTRMS_FILENAME);
objRelease(tcps_sess, LM_TCPSRV_FILENAME);
objRelease(tcpsrv, LM_TCPSRV_FILENAME);
+ objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
@@ -186,6 +196,7 @@ static rsRetVal
resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
iTCPSessMax = 200;
+ iStrmDrvrMode = 0;
return RS_RET_OK;
}
@@ -204,15 +215,18 @@ CODEmodInit_QueryRegCFSLineHdlr
pOurTcpsrv = NULL;
/* request objects we use */
CHKiRet(objUse(net, LM_NET_FILENAME));
- CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME));
CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME));
CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord,
addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt,
NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID));
+ CHKiRet(regCfSysLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0,
+ eCmdHdlrInt, NULL, &iStrmDrvrMode, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index dcb475d8..a7a2b91e 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -81,7 +81,7 @@ lmregexp_la_LIBADD =
endif
if ENABLE_INET
-pkglib_LTLIBRARIES += lmnet.la lmnetstrms.la lmnetstrm.la lmnssel.la
+pkglib_LTLIBRARIES += lmnet.la lmnetstrms.la
#
# network support
#
@@ -91,38 +91,19 @@ lmnet_la_LDFLAGS = -module -avoid-version
lmnet_la_LIBADD =
# network stream master class and stream factory
-lmnetstrms_la_SOURCES = netstrms.c netstrms.h
+lmnetstrms_la_SOURCES = netstrms.c netstrms.h netstrm.c netstrm.h nssel.c nssel.h
lmnetstrms_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
lmnetstrms_la_LDFLAGS = -module -avoid-version
lmnetstrms_la_LIBADD =
-# individual network streams
-lmnetstrm_la_SOURCES = netstrm.c netstrm.h
-lmnetstrm_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
-lmnetstrm_la_LDFLAGS = -module -avoid-version
-lmnetstrm_la_LIBADD =
-
-# network stream select support (a helper class)
-lmnssel_la_SOURCES = nssel.c nssel.h
-lmnssel_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
-lmnssel_la_LDFLAGS = -module -avoid-version
-lmnssel_la_LIBADD =
-
# netstream drivers
# plain tcp driver - main driver
pkglib_LTLIBRARIES += lmnsd_ptcp.la
-lmnsd_ptcp_la_SOURCES = nsd_ptcp.c nsd_ptcp.h
+lmnsd_ptcp_la_SOURCES = nsd_ptcp.c nsd_ptcp.h nsdsel_ptcp.c nsdsel_ptcp.h
lmnsd_ptcp_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
lmnsd_ptcp_la_LDFLAGS = -module -avoid-version
lmnsd_ptcp_la_LIBADD =
-
-# select interface for ptcp driver
-pkglib_LTLIBRARIES += lmnsdsel_ptcp.la
-lmnsdsel_ptcp_la_SOURCES = nsdsel_ptcp.c nsdsel_ptcp.h
-lmnsdsel_ptcp_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
-lmnsdsel_ptcp_la_LDFLAGS = -module -avoid-version
-lmnsdsel_ptcp_la_LIBADD =
endif # if ENABLE_INET
#
@@ -130,16 +111,9 @@ endif # if ENABLE_INET
#
if ENABLE_GNUTLS
pkglib_LTLIBRARIES += lmnsd_gtls.la
-lmnsd_gtls_la_SOURCES = nsd_gtls.c nsd_gtls.h
+lmnsd_gtls_la_SOURCES = nsd_gtls.c nsd_gtls.h nsdsel_gtls.c nsdsel_gtls.h
lmnsd_gtls_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags) $(gnutls_cflags)
lmnsd_gtls_la_LDFLAGS = -module -avoid-version
lmnsd_gtls_la_LIBADD = $(gnutls_libs)
-#
-# select interface for gtls driver
-pkglib_LTLIBRARIES += lmnsdsel_gtls.la
-lmnsdsel_gtls_la_SOURCES = nsdsel_gtls.c nsdsel_gtls.h
-lmnsdsel_gtls_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
-lmnsdsel_gtls_la_LDFLAGS = -module -avoid-version
-lmnsdsel_gtls_la_LIBADD =
endif
diff --git a/runtime/debug.c b/runtime/debug.c
index 53624e38..f543efd8 100644
--- a/runtime/debug.c
+++ b/runtime/debug.c
@@ -1145,8 +1145,6 @@ dbgPrintNameAdd(uchar *pName, dbgPrintName_t **ppRoot)
pEntry->pNext = *ppRoot; /* we enqueue at the front */
}
*ppRoot = pEntry;
-
-printf("Name %s added to %p\n", pName, *ppRoot);
}
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 787b6ab7..20840318 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -40,9 +40,16 @@
/* some defaults */
#ifndef DFLT_NETSTRM_DRVR
-// TESTING ONLY# define DFLT_NETSTRM_DRVR ((uchar*)"lmnsd_ptcp")
-#warning "define must be restored for non-testing!"
-# define DFLT_NETSTRM_DRVR ((uchar*)"lmnsd_gtls")
+# define DFLT_NETSTRM_DRVR ((uchar*)"ptcp")
+#endif
+#ifndef DFLT_NETSTRM_DRVR_CAF
+# define DFLT_NETSTRM_DRVR_CAF ((uchar*)"ca.pem")
+#endif
+#ifndef DFLT_NETSTRM_DRVR_KEYFILE
+# define DFLT_NETSTRM_DRVR_KEYFILE ((uchar*)"key.pem")
+#endif
+#ifndef DFLT_NETSTRM_DRVR_CERTFILE
+# define DFLT_NETSTRM_DRVR_CERTFILE ((uchar*)"cert.pem")
#endif
/* static data */
@@ -62,6 +69,9 @@ static uchar *LocalDomain; /* our local domain name - read-only after startup *
static char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */
static char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */
static uchar *pszDfltNetstrmDrvr = NULL; /* module name of default netstream driver */
+static uchar *pszDfltNetstrmDrvrCAF = NULL; /* default CA file for the netstrm driver */
+static uchar *pszDfltNetstrmDrvrKeyFile = NULL; /* default key file for the netstrm driver (server) */
+static uchar *pszDfltNetstrmDrvrCertFile = NULL; /* default cert file for the netstrm driver (server) */
/* define a macro for the simple properties' set and get functions
@@ -93,6 +103,9 @@ SIMP_PROP(LocalHosts, LocalHosts, char**)
SIMP_PROP_SET(LocalHostName, LocalHostName, uchar*)
SIMP_PROP_SET(DfltNetstrmDrvr, pszDfltNetstrmDrvr, uchar*) // TODO: use custom function which frees existing value
+SIMP_PROP_SET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar*) // TODO: use custom function which frees existing value
+SIMP_PROP_SET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar*) // TODO: use custom function which frees existing value
+SIMP_PROP_SET(DfltNetstrmDrvrCertFile, pszDfltNetstrmDrvrCertFile, uchar*) // TODO: use custom function which frees existing value
#undef SIMP_PROP
#undef SIMP_PROP_SET
@@ -120,7 +133,31 @@ GetWorkDir(void)
static uchar*
GetDfltNetstrmDrvr(void)
{
- return(pszDfltNetstrmDrvr == NULL ? DFLT_NETSTRM_DRVR : pszWorkDir);
+ return(pszDfltNetstrmDrvr == NULL ? DFLT_NETSTRM_DRVR : pszDfltNetstrmDrvr);
+}
+
+
+/* return the current default netstream driver CA File */
+static uchar*
+GetDfltNetstrmDrvrCAF(void)
+{
+ return(pszDfltNetstrmDrvrCAF == NULL ? DFLT_NETSTRM_DRVR_CAF : pszDfltNetstrmDrvrCAF);
+}
+
+
+/* return the current default netstream driver key File */
+static uchar*
+GetDfltNetstrmDrvrKeyFile(void)
+{
+ return(pszDfltNetstrmDrvrKeyFile == NULL ? DFLT_NETSTRM_DRVR_KEYFILE : pszDfltNetstrmDrvrKeyFile);
+}
+
+
+/* return the current default netstream driver certificate File */
+static uchar*
+GetDfltNetstrmDrvrCertFile(void)
+{
+ return(pszDfltNetstrmDrvrCertFile == NULL ? DFLT_NETSTRM_DRVR_CERTFILE : pszDfltNetstrmDrvrCertFile);
}
@@ -151,6 +188,9 @@ CODESTARTobjQueryInterface(glbl)
SIMP_PROP(StripDomains)
SIMP_PROP(LocalHosts)
SIMP_PROP(DfltNetstrmDrvr)
+ SIMP_PROP(DfltNetstrmDrvrCAF)
+ SIMP_PROP(DfltNetstrmDrvrKeyFile)
+ SIMP_PROP(DfltNetstrmDrvrCertFile)
#undef SIMP_PROP
finalize_it:
ENDobjQueryInterface(glbl)
@@ -165,6 +205,18 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
free(pszDfltNetstrmDrvr);
pszDfltNetstrmDrvr = NULL;
}
+ if(pszDfltNetstrmDrvrCAF != NULL) {
+ free(pszDfltNetstrmDrvrCAF);
+ pszDfltNetstrmDrvrCAF = NULL;
+ }
+ if(pszDfltNetstrmDrvrKeyFile != NULL) {
+ free(pszDfltNetstrmDrvrKeyFile);
+ pszDfltNetstrmDrvrKeyFile = NULL;
+ }
+ if(pszDfltNetstrmDrvrCertFile != NULL) {
+ free(pszDfltNetstrmDrvrCertFile);
+ pszDfltNetstrmDrvrCertFile = NULL;
+ }
if(pszWorkDir != NULL) {
free(pszWorkDir);
pszWorkDir = NULL;
@@ -185,6 +237,10 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* register config handlers (TODO: we need to implement a way to unregister them) */
CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvr, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercafile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCAF, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrKeyFile, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCertFile, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
ENDObjClassInit(glbl)
@@ -195,6 +251,12 @@ ENDObjClassInit(glbl)
BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
if(pszDfltNetstrmDrvr != NULL)
free(pszDfltNetstrmDrvr);
+ if(pszDfltNetstrmDrvrCAF != NULL)
+ free(pszDfltNetstrmDrvrCAF);
+ if(pszDfltNetstrmDrvrKeyFile != NULL)
+ free(pszDfltNetstrmDrvrKeyFile);
+ if(pszDfltNetstrmDrvrCertFile != NULL)
+ free(pszDfltNetstrmDrvrCertFile);
if(pszWorkDir != NULL)
free(pszWorkDir);
if(LocalHostName != NULL)
diff --git a/runtime/glbl.h b/runtime/glbl.h
index b6864f3d..adfae27e 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -49,6 +49,9 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
SIMP_PROP(StripDomains, char**)
SIMP_PROP(LocalHosts, char**)
SIMP_PROP(DfltNetstrmDrvr, uchar*)
+ SIMP_PROP(DfltNetstrmDrvrCAF, uchar*)
+ SIMP_PROP(DfltNetstrmDrvrKeyFile, uchar*)
+ SIMP_PROP(DfltNetstrmDrvrCertFile, uchar*)
#undef SIMP_PROP
ENDinterface(glbl)
#define glblCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/runtime/modules.c b/runtime/modules.c
index c156fef2..1e59a5fc 100644
--- a/runtime/modules.c
+++ b/runtime/modules.c
@@ -522,11 +522,16 @@ modUnloadAndDestructAll(eModLinkType_t modLinkTypesToUnload)
if(modLinkTypesToUnload == eMOD_LINK_ALL || pModCurr->eLinkType == modLinkTypesToUnload) {
if(modUnlinkAndDestroy(&pModCurr) == RS_RET_MODULE_STILL_REFERENCED) {
pModCurr = GetNxt(pModCurr);
+ } else {
+ /* Note: if the module was successfully unloaded, it has updated the
+ * pModCurr pointer to the next module. However, the unload process may
+ * still have indirectly referenced the pointer list in a way that the
+ * unloaded module is not aware of. So we restart the unload process
+ * to make sure we do not fall into a trap (what we did ;)). The
+ * performance toll is minimal. -- rgerhards, 2008-04-28
+ */
+ pModCurr = GetNxt(NULL);
}
- /* Note: if the module was successfully unloaded, it has updated the
- * pModCurr pointer to the next module. So we do NOT need to advance
- * to the next module on successful unload.
- */
} else {
pModCurr = GetNxt(pModCurr);
}
diff --git a/runtime/netstrm.c b/runtime/netstrm.c
index be754aae..a1384a28 100644
--- a/runtime/netstrm.c
+++ b/runtime/netstrm.c
@@ -46,12 +46,9 @@
#include "module-template.h"
#include "obj.h"
#include "errmsg.h"
-//#include "nsd.h"
#include "netstrms.h"
#include "netstrm.h"
-MODULE_TYPE_LIB
-
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
@@ -119,6 +116,7 @@ AcceptConnReq(netstrm_t *pThis, netstrm_t **ppNew)
/* accept the new connection */
CHKiRet(pThis->Drvr.AcceptConnReq(pThis->pDrvrData, &pNewNsd));
/* construct our object so that we can use it... */
+ CHKiRet(objUse(netstrms, DONT_LOAD_LIB)); /* use netstrms obj if not already done so */
CHKiRet(netstrms.CreateStrm(pThis->pNS, ppNew));
(*ppNew)->pDrvrData = pNewNsd;
@@ -175,6 +173,19 @@ Rcv(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf)
}
+/* set the driver mode
+ * rgerhards, 2008-04-28
+ */
+static rsRetVal
+SetDrvrMode(netstrm_t *pThis, int iMode)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.SetMode(pThis->pDrvrData, iMode);
+ RETiRet;
+}
+
+
/* send a buffer. On entry, pLenBuf contains the number of octets to
* write. On exit, it contains the number of octets actually written.
* If this number is lower than on entry, only a partial buffer has
@@ -228,6 +239,22 @@ Connect(netstrm_t *pThis, int family, uchar *port, uchar *host)
}
+/* Provide access to the underlying OS socket. This is dirty
+ * and scheduled to be removed. Does not work with all nsd drivers.
+ * See comment in netstrm interface for details.
+ * rgerhards, 2008-05-05
+ */
+static rsRetVal
+GetSock(netstrm_t *pThis, int *pSock)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ assert(pSock != NULL);
+ iRet = pThis->Drvr.GetSock(pThis->pDrvrData, pSock);
+ RETiRet;
+}
+
+
/* queryInterface function
*/
BEGINobjQueryInterface(netstrm)
@@ -252,6 +279,8 @@ CODESTARTobjQueryInterface(netstrm)
pIf->AcceptConnReq = AcceptConnReq;
pIf->GetRemoteHName = GetRemoteHName;
pIf->GetRemoteIP = GetRemoteIP;
+ pIf->SetDrvrMode = SetDrvrMode;
+ pIf->GetSock = GetSock;
finalize_it:
ENDobjQueryInterface(netstrm)
@@ -262,7 +291,7 @@ BEGINObjClassExit(netstrm, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END M
CODESTARTObjClassExit(netstrm)
/* release objects we no longer need */
objRelease(errmsg, CORE_COMPONENT);
- objRelease(netstrms, LM_NETSTRMS_FILENAME);
+ objRelease(netstrms, DONT_LOAD_LIB);
ENDObjClassExit(netstrm)
@@ -273,33 +302,8 @@ ENDObjClassExit(netstrm)
BEGINAbstractObjClassInit(netstrm, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
/* set our own handlers */
ENDObjClassInit(netstrm)
-
-
-/* --------------- here now comes the plumbing that makes as a library module --------------- */
-
-
-BEGINmodExit
-CODESTARTmodExit
- netstrmClassExit();
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_LIB_QUERIES
-ENDqueryEtryPt
-
-
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-
- /* Initialize all classes that are in our module - this includes ourselfs */
- CHKiRet(netstrmClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
-ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/netstrm.h b/runtime/netstrm.h
index 160bbb0b..a15c1d9b 100644
--- a/runtime/netstrm.h
+++ b/runtime/netstrm.h
@@ -24,7 +24,7 @@
#ifndef INCLUDED_NETSTRM_H
#define INCLUDED_NETSTRM_H
-#include "nsd.h" /* we need our driver interface to be defined */
+#include "netstrms.h"
/* the netstrm object */
struct netstrm_s {
@@ -49,6 +49,15 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Connect)(netstrm_t *pThis, int family, unsigned char *port, unsigned char *host);
rsRetVal (*GetRemoteHName)(netstrm_t *pThis, uchar **pszName);
rsRetVal (*GetRemoteIP)(netstrm_t *pThis, uchar **pszIP);
+ rsRetVal (*SetDrvrMode)(netstrm_t *pThis, int iMode);
+ /* 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
+ * will also tie the caller to nsd_ptcp, because other drivers may not support
+ * it at all. Once the imgssapi problem is solved, GetSock should be removed from
+ * this interface. -- rgerhards, 2008-05-05
+ */
+ rsRetVal (*GetSock)(netstrm_t *pThis, int *pSock);
ENDinterface(netstrm)
#define netstrmCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
@@ -56,6 +65,6 @@ ENDinterface(netstrm)
PROTOTYPEObj(netstrm);
/* the name of our library binary */
-#define LM_NETSTRM_FILENAME "lmnetstrm"
+#define LM_NETSTRM_FILENAME LM_NETSTRMS_FILENAME
#endif /* #ifndef INCLUDED_NETSTRM_H */
diff --git a/runtime/netstrms.c b/runtime/netstrms.c
index 661234e4..fde0788d 100644
--- a/runtime/netstrms.c
+++ b/runtime/netstrms.c
@@ -23,6 +23,7 @@
* A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
*/
#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
@@ -31,9 +32,9 @@
#include "module-template.h"
#include "obj.h"
//#include "errmsg.h"
-//#include "net.h"
#include "nsd.h"
#include "netstrm.h"
+#include "nssel.h"
#include "netstrms.h"
MODULE_TYPE_LIB
@@ -43,24 +44,29 @@ DEFobjStaticHelpers
//DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
DEFobjCurrIf(netstrm)
-//DEFobjCurrIf(net)
/* load our low-level driver. This must be done before any
* driver-specific functions (allmost all...) can be carried
* out. Note that the driver's .ifIsLoaded is correctly
* initialized by calloc() and we depend on that.
+ * WARNING: this code is mostly identical to similar code in
+ * nssel.c - TODO: abstract it and move it to some common place.
* rgerhards, 2008-04-18
*/
static rsRetVal
loadDrvr(netstrms_t *pThis)
{
- uchar *pDrvrName;
DEFiRet;
+ uchar *pBaseDrvrName;
+ uchar szDrvrName[48]; /* 48 shall be large enough */
- pDrvrName = pThis->pDrvrName;
- if(pDrvrName == NULL) /* if no drvr name is set, use system default */
- pDrvrName = glbl.GetDfltNetstrmDrvr();
+ pBaseDrvrName = pThis->pBaseDrvrName;
+ if(pBaseDrvrName == NULL) /* if no drvr name is set, use system default */
+ pBaseDrvrName = glbl.GetDfltNetstrmDrvr();
+ if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmnsd_%s", pBaseDrvrName) == sizeof(szDrvrName))
+ ABORT_FINALIZE(RS_RET_DRVRNAME_TOO_LONG);
+ CHKmalloc(pThis->pDrvrName = (uchar*) strdup((char*)szDrvrName));
pThis->Drvr.ifVersion = nsdCURR_IF_VERSION;
/* The pDrvrName+2 below is a hack to obtain the object name. It
@@ -69,8 +75,14 @@ loadDrvr(netstrms_t *pThis)
* about this hack, but for the time being it is efficient and clean
* enough. -- rgerhards, 2008-04-18
*/
- CHKiRet(obj.UseObj(__FILE__, pDrvrName+2, pDrvrName, (void*) &pThis->Drvr));
+ CHKiRet(obj.UseObj(__FILE__, szDrvrName+2, szDrvrName, (void*) &pThis->Drvr));
+
finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pThis->pDrvrName != NULL)
+ free(pThis->pDrvrName);
+ pThis->pDrvrName = NULL;
+ }
RETiRet;
}
@@ -83,8 +95,18 @@ ENDobjConstruct(netstrms)
/* destructor for the netstrms object */
BEGINobjDestruct(netstrms) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(netstrms)
- if(pThis->pDrvrName != NULL)
+ /* and now we must release our driver, if we got one. We use the presence of
+ * a driver name string as load indicator (because we also need that string
+ * to release the driver
+ */
+ if(pThis->pDrvrName != NULL) {
+ obj.ReleaseObj(__FILE__, pThis->pDrvrName+2, pThis->pDrvrName, (void*) &pThis->Drvr);
free(pThis->pDrvrName);
+ }
+ if(pThis->pBaseDrvrName != NULL) {
+ free(pThis->pBaseDrvrName);
+ pThis->pBaseDrvrName = NULL;
+ }
ENDobjDestruct(netstrms)
@@ -100,6 +122,54 @@ finalize_it:
}
+/* set the base driver name. If the driver name
+ * is set to NULL, the previously set name is deleted but
+ * no name set again (which results in the system default being
+ * used)-- rgerhards, 2008-05-05
+ */
+static rsRetVal
+SetDrvrName(netstrms_t *pThis, uchar *pszName)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ if(pThis->pBaseDrvrName != NULL) {
+ free(pThis->pBaseDrvrName);
+ pThis->pBaseDrvrName = NULL;
+ }
+
+ if(pszName != NULL) {
+ CHKmalloc(pThis->pBaseDrvrName = (uchar*) strdup((char*) pszName));
+ }
+finalize_it:
+ RETiRet;
+}
+
+
+/* set the driver mode -- rgerhards, 2008-04-30
+ */
+static rsRetVal
+SetDrvrMode(netstrms_t *pThis, int iMode)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ pThis->iDrvrMode = iMode;
+ RETiRet;
+}
+
+
+/* return the driver mode
+ * We use non-standard calling conventions because it makes an awful lot
+ * of sense here.
+ * rgerhards, 2008-04-30
+ */
+static int
+GetDrvrMode(netstrms_t *pThis)
+{
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ return pThis->iDrvrMode;
+}
+
+
/* create an instance of a netstrm object. It is initialized with default
* values. The current driver is used. The caller may set netstrm properties
* and must call ConstructFinalize().
@@ -110,7 +180,7 @@ CreateStrm(netstrms_t *pThis, netstrm_t **ppStrm)
netstrm_t *pStrm = NULL;
DEFiRet;
- CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ CHKiRet(objUse(netstrm, DONT_LOAD_LIB));
CHKiRet(netstrm.Construct(&pStrm));
/* we copy over our driver structure. We could provide a pointer to
* ourselves, but that costs some performance on each driver invocation.
@@ -147,6 +217,9 @@ CODESTARTobjQueryInterface(netstrms)
pIf->ConstructFinalize = netstrmsConstructFinalize;
pIf->Destruct = netstrmsDestruct;
pIf->CreateStrm = CreateStrm;
+ pIf->SetDrvrName = SetDrvrName;
+ pIf->SetDrvrMode = SetDrvrMode;
+ pIf->GetDrvrMode = GetDrvrMode;
finalize_it:
ENDobjQueryInterface(netstrms)
@@ -155,9 +228,8 @@ ENDobjQueryInterface(netstrms)
BEGINObjClassExit(netstrms, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
CODESTARTObjClassExit(netstrms)
/* release objects we no longer need */
- //objRelease(net, CORE_COMPONENT);
objRelease(glbl, CORE_COMPONENT);
- objRelease(netstrm, LM_NETSTRM_FILENAME);
+ objRelease(netstrm, DONT_LOAD_LIB);
ENDObjClassExit(netstrms)
@@ -168,7 +240,6 @@ ENDObjClassExit(netstrms)
BEGINAbstractObjClassInit(netstrms, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
CHKiRet(objUse(glbl, CORE_COMPONENT));
- //CHKiRet(objUse(net, CORE_COMPONENT));
/* set our own handlers */
ENDObjClassInit(netstrms)
@@ -179,7 +250,9 @@ ENDObjClassInit(netstrms)
BEGINmodExit
CODESTARTmodExit
+ nsselClassExit();
netstrmsClassExit();
+ netstrmClassExit(); /* we use this object, so we must exit it after we are finished */
ENDmodExit
@@ -194,7 +267,9 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
/* Initialize all classes that are in our module - this includes ourselfs */
- CHKiRet(netstrmsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ CHKiRet(netstrmClassInit(pModInfo));
+ CHKiRet(nsselClassInit(pModInfo));
+ CHKiRet(netstrmsClassInit(pModInfo));
ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/netstrms.h b/runtime/netstrms.h
index 1e920304..1d1cc892 100644
--- a/runtime/netstrms.h
+++ b/runtime/netstrms.h
@@ -29,7 +29,9 @@
/* the netstrms object */
struct netstrms_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
- uchar *pDrvrName; /**< nsd driver name to use, or NULL if system default */
+ uchar *pBaseDrvrName; /**< nsd base driver name to use, or NULL if system default */
+ uchar *pDrvrName; /**< full base driver name (set when driver is loaded) */
+ int iDrvrMode; /**< current default driver mode */
nsd_if_t Drvr; /**< our stream driver */
};
@@ -40,6 +42,9 @@ BEGINinterface(netstrms) /* name must also be changed in ENDinterface macro! */
rsRetVal (*ConstructFinalize)(netstrms_t *pThis);
rsRetVal (*Destruct)(netstrms_t **ppThis);
rsRetVal (*CreateStrm)(netstrms_t *pThis, netstrm_t **ppStrm);
+ rsRetVal (*SetDrvrName)(netstrms_t *pThis, uchar *pszName);
+ rsRetVal (*SetDrvrMode)(netstrms_t *pThis, int iMode);
+ int (*GetDrvrMode)(netstrms_t *pThis);
ENDinterface(netstrms)
#define netstrmsCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/runtime/nsd.h b/runtime/nsd.h
index 1b3702a0..cc06c877 100644
--- a/runtime/nsd.h
+++ b/runtime/nsd.h
@@ -50,6 +50,7 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
rsRetVal (*AcceptConnReq)(nsd_t *pThis, nsd_t **ppThis);
rsRetVal (*GetRemoteHName)(nsd_t *pThis, uchar **pszName);
rsRetVal (*GetRemoteIP)(nsd_t *pThis, uchar **pszIP);
+ rsRetVal (*SetMode)(nsd_t *pThis, int mode); /* sets a driver specific mode - see driver doc for details */
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
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
index d59043f2..20de772a 100644
--- a/runtime/nsd_gtls.c
+++ b/runtime/nsd_gtls.c
@@ -30,11 +30,18 @@
#include "rsyslog.h"
#include "syslogd-types.h"
#include "module-template.h"
+#include "cfsysline.h"
#include "obj.h"
#include "errmsg.h"
#include "nsd_ptcp.h"
+#include "nsdsel_gtls.h"
#include "nsd_gtls.h"
+/* things to move to some better place/functionality - TODO */
+#define DH_BITS 1024
+#define CRLFILE "crl.pem"
+
+
MODULE_TYPE_LIB
/* static data */
@@ -43,25 +50,43 @@ DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
DEFobjCurrIf(nsd_ptcp)
+static int bGlblSrvrInitDone = 0; /**< 0 - server global init not yet done, 1 - already done */
/* a macro to check GnuTLS calls against unexpected errors */
#define CHKgnutls(x) \
if((gnuRet = (x)) != 0) { \
- dbgprintf("unexpected GnuTLS error %d in %s:%d\n", gnuRet, __FILE__, __LINE__); \
- gnutls_perror(gnuRet); /* TODO: can we do better? */ \
+ uchar *pErr = gtlsStrerror(gnuRet); \
+ dbgprintf("unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); \
+ free(pErr); \
ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \
}
-#define CAFILE "ca.pem" // TODO: allow to specify
/* ------------------------------ GnuTLS specifics ------------------------------ */
static gnutls_certificate_credentials xcred;
+static gnutls_dh_params dh_params;
+
+/* a thread-safe variant of gnutls_strerror - TODO: implement it!
+ * The caller must free the returned string.
+ * rgerhards, 2008-04-30
+ */
+uchar *gtlsStrerror(int error)
+{
+ uchar *pErr;
+
+ // TODO: guard by mutex!
+ pErr = (uchar*) strdup(gnutls_strerror(error));
+
+ return pErr;
+}
+
/* globally initialize GnuTLS */
static rsRetVal
gtlsGlblInit(void)
{
int gnuRet;
+ uchar *cafile;
DEFiRet;
CHKgnutls(gnutls_global_init());
@@ -70,7 +95,90 @@ gtlsGlblInit(void)
CHKgnutls(gnutls_certificate_allocate_credentials(&xcred));
/* sets the trusted cas file */
- gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM);
+ cafile = glbl.GetDfltNetstrmDrvrCAF();
+ dbgprintf("GTLS CA file: '%s'\n", cafile);
+ gnuRet = gnutls_certificate_set_x509_trust_file(xcred, (char*)cafile, GNUTLS_X509_FMT_PEM);
+ if(gnuRet < 0) {
+ /* TODO; a more generic error-tracking function (this one based on CHKgnutls()) */
+ uchar *pErr = gtlsStrerror(gnuRet);
+ dbgprintf("unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr);
+ free(pErr);
+ ABORT_FINALIZE(RS_RET_GNUTLS_ERR);
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+static rsRetVal
+gtlsInitSession(nsd_gtls_t *pThis)
+{
+ DEFiRet;
+ int gnuRet;
+ gnutls_session session;
+
+ gnutls_init(&session, GNUTLS_SERVER);
+ pThis->bHaveSess = 1;
+ pThis->bIsInitiator = 0;
+
+ /* avoid calling all the priority functions, since the defaults are adequate. */
+ CHKgnutls(gnutls_set_default_priority(session));
+ CHKgnutls(gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred));
+
+ /* request client certificate if any. */
+ gnutls_certificate_server_set_request( session, GNUTLS_CERT_REQUEST);
+ gnutls_dh_set_prime_bits(session, DH_BITS);
+
+ pThis->sess = session;
+
+finalize_it:
+ RETiRet;
+}
+
+
+
+static rsRetVal
+generate_dh_params(void)
+{
+ int gnuRet;
+ DEFiRet;
+ /* Generate Diffie Hellman parameters - for use with DHE
+ * kx algorithms. These should be discarded and regenerated
+ * once a day, once a week or once a month. Depending on the
+ * security requirements.
+ */
+ CHKgnutls(gnutls_dh_params_init( &dh_params));
+ CHKgnutls(gnutls_dh_params_generate2( dh_params, DH_BITS));
+finalize_it:
+ RETiRet;
+}
+
+
+/* set up all global things that are needed for server operations
+ * rgerhards, 2008-04-30
+ */
+static rsRetVal
+gtlsGlblInitLstn(void)
+{
+ int gnuRet;
+ uchar *keyFile;
+ uchar *certFile;
+ DEFiRet;
+
+ if(bGlblSrvrInitDone == 0) {
+ /* we do not use CRLs right now, and I doubt we'll ever do. This functionality is
+ * considered legacy. -- rgerhards, 2008-05-05
+ */
+ /*CHKgnutls(gnutls_certificate_set_x509_crl_file(xcred, CRLFILE, GNUTLS_X509_FMT_PEM));*/
+ certFile = glbl.GetDfltNetstrmDrvrCertFile();
+ keyFile = glbl.GetDfltNetstrmDrvrKeyFile();
+ dbgprintf("GTLS certificate file: '%s'\n", certFile);
+ dbgprintf("GTLS key file: '%s'\n", keyFile);
+ CHKgnutls(gnutls_certificate_set_x509_key_file(xcred, (char*)certFile, (char*)keyFile, GNUTLS_X509_FMT_PEM));
+ CHKiRet(generate_dh_params());
+ gnutls_certificate_set_dh_params(xcred, dh_params); /* this is void */
+ bGlblSrvrInitDone = 1; /* we are all set now */
+ }
finalize_it:
RETiRet;
@@ -100,9 +208,11 @@ gtlsEndSess(nsd_gtls_t *pThis)
DEFiRet;
if(pThis->bHaveSess) {
- gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR);
- while(gnuRet == GNUTLS_E_INTERRUPTED || gnuRet == GNUTLS_E_AGAIN) {
+ if(pThis->bIsInitiator) {
gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR);
+ while(gnuRet == GNUTLS_E_INTERRUPTED || gnuRet == GNUTLS_E_AGAIN) {
+ gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR);
+ }
}
gnutls_deinit(pThis->sess);
}
@@ -116,8 +226,6 @@ gtlsEndSess(nsd_gtls_t *pThis)
/* Standard-Constructor */
BEGINobjConstruct(nsd_gtls) /* be sure to specify the object type also in END macro! */
iRet = nsd_ptcp.Construct(&pThis->pTcp);
- pThis->iMode = 1; /* TODO: must be made configurable */
- pThis->iMode = 0; /* TODO: must be made configurable */
ENDobjConstruct(nsd_gtls)
@@ -134,6 +242,29 @@ CODESTARTobjDestruct(nsd_gtls)
ENDobjDestruct(nsd_gtls)
+/* Set the driver mode. For us, this has the following meaning:
+ * 0 - work in plain tcp mode, without tls (e.g. before a STARTTLS)
+ * 1 - work in TLS mode
+ * rgerhards, 2008-04-28
+ */
+static rsRetVal
+SetMode(nsd_t *pNsd, int mode)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+
+dbgprintf("SetMOde tries to set mode %d\n", mode);
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
+ if(mode != 0 && mode != 1)
+ ABORT_FINALIZE(RS_RET_INVAID_DRVR_MODE);
+
+ pThis->iMode = mode;
+
+finalize_it:
+ RETiRet;
+}
+
+
/* Provide access to the underlying OS socket. This is primarily
* useful for other drivers (like nsd_gtls) who utilize ourselfs
* for some of their functionality. -- rgerhards, 2008-04-18
@@ -184,7 +315,9 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
uchar *pLstnPort, uchar *pLstnIP, int iSessMax)
{
DEFiRet;
+ CHKiRet(gtlsGlblInitLstn());
iRet = nsd_ptcp.LstnInit(pNS, pUsr, fAddLstn, pLstnPort, pLstnIP, iSessMax);
+finalize_it:
RETiRet;
}
@@ -227,15 +360,38 @@ static rsRetVal
AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew)
{
DEFiRet;
+ int gnuRet;
nsd_gtls_t *pNew = NULL;
nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
ISOBJ_TYPE_assert((pThis), nsd_gtls);
- // TODO: method to construct without pTcp
CHKiRet(nsd_gtlsConstruct(&pNew));
CHKiRet(nsd_ptcp.Destruct(&pNew->pTcp));
CHKiRet(nsd_ptcp.AcceptConnReq(pThis->pTcp, &pNew->pTcp));
+ if(pThis->iMode == 0) {
+ /* we are in non-TLS mode, so we are done */
+ *ppNew = (nsd_t*) pNew;
+ FINALIZE;
+ }
+
+ /* if we reach this point, we are in TLS mode */
+ CHKiRet(gtlsInitSession(pNew));
+ gnutls_transport_set_ptr(pNew->sess, (gnutls_transport_ptr_t)((nsd_ptcp_t*) (pNew->pTcp))->sock);
+
+ /* we now do the handshake. This is a bit complicated, because we are
+ * on non-blocking sockets. Usually, the handshake will not complete
+ * immediately, so that we need to retry it some time later.
+ */
+ gnuRet = gnutls_handshake(pNew->sess);
+ if(gnuRet == GNUTLS_E_AGAIN || gnuRet == GNUTLS_E_INTERRUPTED) {
+ pNew->rtryCall = gtlsRtry_handshake;
+ dbgprintf("GnuTLS handshake does not complete immediately - setting to retry (this is OK and normal)\n");
+ } else if(gnuRet != 0) {
+ ABORT_FINALIZE(RS_RET_TLS_HANDSHAKE_ERR);
+ }
+ pNew->iMode = 1; /* this session is now in TLS mode! */
+
*ppNew = (nsd_t*) pNew;
finalize_it:
@@ -260,6 +416,8 @@ static rsRetVal
Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
{
DEFiRet;
+ int gnuRet;
+ ssize_t lenRcvd;
nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
ISOBJ_TYPE_assert(pThis, nsd_gtls);
@@ -269,6 +427,8 @@ Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
}
/* in TLS mode now */
+ lenRcvd = gnutls_record_recv(pThis->sess, pBuf, *pLenBuf);
+ *pLenBuf = lenRcvd;
finalize_it:
RETiRet;
@@ -301,8 +461,11 @@ Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
*pLenBuf = iSent;
break;
}
- if(iSent != GNUTLS_E_INTERRUPTED && iSent != GNUTLS_E_AGAIN)
+ if(iSent != GNUTLS_E_INTERRUPTED && iSent != GNUTLS_E_AGAIN) {
+ dbgprintf("unexpected GnuTLS error %d in %s:%d\n", iSent, __FILE__, __LINE__);
+ gnutls_perror(iSent); /* TODO: can we do better? */
ABORT_FINALIZE(RS_RET_GNUTLS_ERR);
+ }
}
finalize_it:
@@ -335,6 +498,7 @@ Connect(nsd_t *pNsd, int family, uchar *port, uchar *host)
/* we reach this point if in TLS mode */
CHKgnutls(gnutls_init(&pThis->sess, GNUTLS_CLIENT));
pThis->bHaveSess = 1;
+ pThis->bIsInitiator = 1;
/* Use default priorities */
CHKgnutls(gnutls_set_default_priority(pThis->sess));
@@ -345,7 +509,7 @@ Connect(nsd_t *pNsd, int family, uchar *port, uchar *host)
/* assign the socket to GnuTls */
CHKiRet(nsd_ptcp.GetSock(pThis->pTcp, &sock));
- gnutls_transport_set_ptr(pThis->sess, (gnutls_transport_ptr)sock);
+ gnutls_transport_set_ptr(pThis->sess, (gnutls_transport_ptr_t)sock);
/* and perform the handshake */
CHKgnutls(gnutls_handshake(pThis->sess));
@@ -384,6 +548,7 @@ CODESTARTobjQueryInterface(nsd_gtls)
pIf->Send = Send;
pIf->Connect = Connect;
pIf->SetSock = SetSock;
+ pIf->SetMode = SetMode;
pIf->GetRemoteHName = GetRemoteHName;
pIf->GetRemoteIP = GetRemoteIP;
finalize_it:
@@ -423,6 +588,7 @@ ENDObjClassInit(nsd_gtls)
BEGINmodExit
CODESTARTmodExit
+ nsdsel_gtlsClassExit();
nsd_gtlsClassExit();
ENDmodExit
@@ -439,6 +605,8 @@ CODESTARTmodInit
/* Initialize all classes that are in our module - this includes ourselfs */
CHKiRet(nsd_gtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ CHKiRet(nsdsel_gtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+
ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h
index c193f57c..83e15f29 100644
--- a/runtime/nsd_gtls.h
+++ b/runtime/nsd_gtls.h
@@ -26,6 +26,11 @@
#include "nsd.h"
+typedef enum {
+ gtlsRtry_None = 0, /**< no call needs to be retried */
+ gtlsRtry_handshake = 1
+} gtlsRtryCall_t; /**< IDs of calls that needs to be retried */
+
typedef nsd_if_t nsd_gtls_if_t; /* we just *implement* this interface */
/* the nsd_gtls object */
@@ -33,8 +38,11 @@ struct nsd_gtls_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
nsd_t *pTcp; /**< our aggregated nsd_ptcp data */
int iMode; /* 0 - plain tcp, 1 - TLS */
+ gtlsRtryCall_t rtryCall;/**< what must we retry? */
+ int bIsInitiator; /**< 0 if socket is the server end (listener), 1 if it is the initiator */
gnutls_session sess;
- int bHaveSess;
+ int bHaveSess; /* as we don't know exactly which gnutls_session values are invalid, we use this one
+ to flag whether or not we are in a session (same as -1 for a socket meaning no sess) */
};
/* interface is defined in nsd.h, we just implement it! */
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index 2a74e061..c5480a05 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -47,6 +47,7 @@
#include "net.h"
#include "netstrms.h"
#include "netstrm.h"
+#include "nsdsel_ptcp.h"
#include "nsd_ptcp.h"
MODULE_TYPE_LIB
@@ -109,6 +110,22 @@ GetSock(nsd_t *pNsd, int *pSock)
}
+/* Set the driver mode. We support no different modes, but allow mode
+ * 0 to be set to be compatible with config file defaults and the other
+ * drivers.
+ * rgerhards, 2008-04-28
+ */
+static rsRetVal
+SetMode(nsd_t __attribute__((unused)) *pNsd, int mode)
+{
+ DEFiRet;
+ if(mode != 0)
+ ABORT_FINALIZE(RS_RET_INVAID_DRVR_MODE);
+finalize_it:
+ RETiRet;
+}
+
+
/* Provide access to the underlying OS socket. This is primarily
* useful for other drivers (like nsd_gtls) who utilize ourselfs
* for some of their functionality.
@@ -415,13 +432,11 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
* construct a new netstrm obj and hand it over to the upper layers for inclusion
* into their socket array. -- rgerhards, 2008-04-23
*/
-RUNLOG_VAR("%d", sock);
CHKiRet(pNS->Drvr.Construct(&pNewNsd));
CHKiRet(pNS->Drvr.SetSock(pNewNsd, sock));
-RUNLOG;
+ CHKiRet(pNS->Drvr.SetMode(pNewNsd, netstrms.GetDrvrMode(pNS)));
CHKiRet(netstrms.CreateStrm(pNS, &pNewStrm));
pNewStrm->pDrvrData = (nsd_t*) pNewNsd;
-RUNLOG;
CHKiRet(fAddLstn(pUsr, pNewStrm));
pNewNsd = NULL;
pNewStrm = NULL;
@@ -609,6 +624,7 @@ CODESTARTobjQueryInterface(nsd_ptcp)
pIf->Abort = Abort;
pIf->GetSock = GetSock;
pIf->SetSock = SetSock;
+ pIf->SetMode = SetMode;
pIf->Rcv = Rcv;
pIf->Send = Send;
pIf->LstnInit = LstnInit;
@@ -628,7 +644,7 @@ CODESTARTObjClassExit(nsd_ptcp)
objRelease(net, CORE_COMPONENT);
objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
- objRelease(netstrm, LM_NETSTRM_FILENAME);
+ objRelease(netstrm, DONT_LOAD_LIB);
objRelease(netstrms, LM_NETSTRMS_FILENAME);
ENDObjClassExit(nsd_ptcp)
@@ -642,8 +658,8 @@ BEGINObjClassInit(nsd_ptcp, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(net, CORE_COMPONENT));
- CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
+ CHKiRet(objUse(netstrm, DONT_LOAD_LIB));
/* set our own handlers */
ENDObjClassInit(nsd_ptcp)
@@ -654,6 +670,7 @@ ENDObjClassInit(nsd_ptcp)
BEGINmodExit
CODESTARTmodExit
+ nsdsel_ptcpClassExit();
nsd_ptcpClassExit();
ENDmodExit
@@ -670,6 +687,7 @@ CODESTARTmodInit
/* Initialize all classes that are in our module - this includes ourselfs */
CHKiRet(nsd_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ CHKiRet(nsdsel_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c
index 7cafec49..8c1e705b 100644
--- a/runtime/nsdsel_gtls.c
+++ b/runtime/nsdsel_gtls.c
@@ -37,11 +37,10 @@
#include "errmsg.h"
#include "nsd.h"
#include "nsd_gtls.h"
+#include "nsd_ptcp.h"
#include "nsdsel_ptcp.h"
#include "nsdsel_gtls.h"
-MODULE_TYPE_LIB
-
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
@@ -74,7 +73,21 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls);
- iRet = nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, waitOp);
+ if(pNsdGTLS->iMode == 1) {
+ if(pNsdGTLS->rtryCall != gtlsRtry_None) {
+ if(gnutls_record_get_direction(pNsdGTLS->sess) == 0) {
+ CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, NSDSEL_RD));
+ } else {
+ CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, NSDSEL_WR));
+ }
+ FINALIZE;
+ }
+ }
+
+ /* if we reach this point, we need no special handling */
+ CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, waitOp));
+
+finalize_it:
RETiRet;
}
@@ -94,6 +107,47 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
}
+/* retry an interrupted GTLS operation
+ * rgerhards, 2008-04-30
+ */
+static rsRetVal
+doRetry(nsd_gtls_t *pNsd)
+{
+ DEFiRet;
+ int gnuRet;
+
+ dbgprintf("GnuTLS requested retry of %d operation - executing\n", pNsd->rtryCall);
+
+ /* We follow a common scheme here: first, we do the systen call and
+ * then we check the result. So far, the result is checked after the
+ * switch, because the result check is the same for all calls. Note that
+ * this may change once we deal with the read and write calls (but
+ * probably this becomes an issue only when we begin to work on TLS
+ * for relp). -- rgerhards, 2008-04-30
+ */
+ switch(pNsd->rtryCall) {
+ case gtlsRtry_handshake:
+ gnuRet = gnutls_handshake(pNsd->sess);
+ break;
+ default:
+ assert(0); /* this shall not happen! */
+ break;
+ }
+
+ if(gnuRet == 0) {
+ pNsd->rtryCall = gtlsRtry_None; /* we are done */
+ } else if(gnuRet != GNUTLS_E_AGAIN && gnuRet != GNUTLS_E_INTERRUPTED) {
+ ABORT_FINALIZE(RS_RET_GNUTLS_ERR);
+ }
+ /* if we are interrupted once again (else case), we do not need to
+ * change our status because we are already setup for retries.
+ */
+
+finalize_it:
+ RETiRet;
+}
+
+
/* check if a socket is ready for IO */
static rsRetVal
IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
@@ -104,7 +158,20 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls);
- iRet = nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady);
+ if(pNsdGTLS->iMode == 1) {
+ if(pNsdGTLS->rtryCall != gtlsRtry_None) {
+ CHKiRet(doRetry(pNsdGTLS));
+ /* we used this up for our own internal processing, so the socket
+ * is not ready from the upper layer point of view.
+ */
+ *pbIsReady = 0;
+ FINALIZE;
+ }
+ }
+
+ CHKiRet(nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady));
+
+finalize_it:
RETiRet;
}
@@ -135,12 +202,12 @@ ENDobjQueryInterface(nsdsel_gtls)
/* exit our class
*/
-BEGINObjClassExit(nsdsel_gtls, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+BEGINObjClassExit(nsdsel_gtls, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */
CODESTARTObjClassExit(nsdsel_gtls)
/* release objects we no longer need */
objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
- objRelease(nsdsel_ptcp, LM_NSDSEL_PTCP_FILENAME);
+ objRelease(nsdsel_ptcp, LM_NSD_PTCP_FILENAME);
ENDObjClassExit(nsdsel_gtls)
@@ -148,37 +215,13 @@ ENDObjClassExit(nsdsel_gtls)
* before anything else is called inside this class.
* rgerhards, 2008-02-19
*/
-BEGINObjClassInit(nsdsel_gtls, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
+BEGINObjClassInit(nsdsel_gtls, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
- CHKiRet(objUse(nsdsel_ptcp, LM_NSDSEL_PTCP_FILENAME));
+ CHKiRet(objUse(nsdsel_ptcp, LM_NSD_PTCP_FILENAME));
/* set our own handlers */
ENDObjClassInit(nsdsel_gtls)
-
-
-/* --------------- here now comes the plumbing that makes as a library module --------------- */
-
-
-BEGINmodExit
-CODESTARTmodExit
- nsdsel_gtlsClassExit();
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_LIB_QUERIES
-ENDqueryEtryPt
-
-
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-
- /* Initialize all classes that are in our module - this includes ourselfs */
- CHKiRet(nsdsel_gtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
-ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/nsdsel_gtls.h b/runtime/nsdsel_gtls.h
index a309d302..7c2df684 100644
--- a/runtime/nsdsel_gtls.h
+++ b/runtime/nsdsel_gtls.h
@@ -39,7 +39,4 @@ struct nsdsel_gtls_s {
/* prototypes */
PROTOTYPEObj(nsdsel_gtls);
-/* the name of our library binary */
-#define LM_NSDSEL_GTLS_FILENAME "lmnsdsel_gtls"
-
#endif /* #ifndef INCLUDED_NSDSEL_GTLS_H */
diff --git a/runtime/nsdsel_ptcp.c b/runtime/nsdsel_ptcp.c
index b439063a..41b85e0c 100644
--- a/runtime/nsdsel_ptcp.c
+++ b/runtime/nsdsel_ptcp.c
@@ -37,8 +37,6 @@
#include "nsd_ptcp.h"
#include "nsdsel_ptcp.h"
-MODULE_TYPE_LIB
-
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
@@ -175,7 +173,7 @@ ENDobjQueryInterface(nsdsel_ptcp)
/* exit our class
*/
-BEGINObjClassExit(nsdsel_ptcp, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+BEGINObjClassExit(nsdsel_ptcp, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */
CODESTARTObjClassExit(nsdsel_ptcp)
/* release objects we no longer need */
objRelease(glbl, CORE_COMPONENT);
@@ -187,36 +185,12 @@ ENDObjClassExit(nsdsel_ptcp)
* before anything else is called inside this class.
* rgerhards, 2008-02-19
*/
-BEGINObjClassInit(nsdsel_ptcp, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
+BEGINObjClassInit(nsdsel_ptcp, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
/* set our own handlers */
ENDObjClassInit(nsdsel_ptcp)
-
-
-/* --------------- here now comes the plumbing that makes as a library module --------------- */
-
-
-BEGINmodExit
-CODESTARTmodExit
- nsdsel_ptcpClassExit();
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_LIB_QUERIES
-ENDqueryEtryPt
-
-
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-
- /* Initialize all classes that are in our module - this includes ourselfs */
- CHKiRet(nsdsel_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
-ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/nsdsel_ptcp.h b/runtime/nsdsel_ptcp.h
index 93874e55..6c0c7fa7 100644
--- a/runtime/nsdsel_ptcp.h
+++ b/runtime/nsdsel_ptcp.h
@@ -41,7 +41,4 @@ struct nsdsel_ptcp_s {
/* prototypes */
PROTOTYPEObj(nsdsel_ptcp);
-/* the name of our library binary */
-#define LM_NSDSEL_PTCP_FILENAME "lmnsdsel_ptcp"
-
#endif /* #ifndef INCLUDED_NSDSEL_PTCP_H */
diff --git a/runtime/nssel.c b/runtime/nssel.c
index 5333fc75..d11d5fe1 100644
--- a/runtime/nssel.c
+++ b/runtime/nssel.c
@@ -44,8 +44,6 @@
#include "netstrm.h"
#include "nssel.h"
-MODULE_TYPE_LIB
-
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(glbl)
@@ -54,18 +52,28 @@ DEFobjCurrIf(glbl)
/* load our low-level driver. This must be done before any
* driver-specific functions (allmost all...) can be carried
* out. Note that the driver's .ifIsLoaded is correctly
- * initialized by calloc() and we depend on that.
- * rgerhards, 2008-04-18
+ * initialized by calloc() and we depend on that. Please note that
+ * we do some name-mangeling. We know that each nsd driver also needs
+ * a nssel driver. So we simply append "sel" to the nsd driver name: This,
+ * of course, means that the driver name must match these rules, but that
+ * shouldn't be a real problem.
+ * WARNING: this code is mostly identical to similar code in
+ * netstrms.c - TODO: abstract it and move it to some common place.
+ * rgerhards, 2008-04-28
*/
static rsRetVal
loadDrvr(nssel_t *pThis)
{
- uchar *pDrvrName;
DEFiRet;
+ uchar *pBaseDrvrName;
+ uchar szDrvrName[48]; /* 48 shall be large enough */
- pDrvrName = pThis->pDrvrName;
- if(pDrvrName == NULL) /* if no drvr name is set, use system default */
- pDrvrName = glbl.GetDfltNetstrmDrvr();
+ pBaseDrvrName = pThis->pBaseDrvrName;
+ if(pBaseDrvrName == NULL) /* if no drvr name is set, use system default */
+ pBaseDrvrName = glbl.GetDfltNetstrmDrvr();
+ if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmnsdsel_%s", pBaseDrvrName) == sizeof(szDrvrName))
+ ABORT_FINALIZE(RS_RET_DRVRNAME_TOO_LONG);
+ CHKmalloc(pThis->pDrvrName = (uchar*) strdup((char*)szDrvrName));
pThis->Drvr.ifVersion = nsdCURR_IF_VERSION;
/* The pDrvrName+2 below is a hack to obtain the object name. It
@@ -74,9 +82,14 @@ loadDrvr(nssel_t *pThis)
* about this hack, but for the time being it is efficient and clean
* enough. -- rgerhards, 2008-04-18
*/
- //CHKiRet(obj.UseObj(__FILE__, pDrvrName+2, pDrvrName, (void*) &pThis->Drvr));
- CHKiRet(obj.UseObj(__FILE__, "nsdsel_gtls", "lmnsdsel_gtls", (void*) &pThis->Drvr));
+ CHKiRet(obj.UseObj(__FILE__, szDrvrName+2, DONT_LOAD_LIB, (void*) &pThis->Drvr));
+
finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pThis->pDrvrName != NULL)
+ free(pThis->pDrvrName);
+ pThis->pDrvrName = NULL;
+ }
RETiRet;
}
@@ -91,6 +104,15 @@ BEGINobjDestruct(nssel) /* be sure to specify the object type also in END and CO
CODESTARTobjDestruct(nssel)
if(pThis->pDrvrData != NULL)
pThis->Drvr.Destruct(&pThis->pDrvrData);
+
+ /* and now we must release our driver, if we got one. We use the presence of
+ * a driver name string as load indicator (because we also need that string
+ * to release the driver
+ */
+ if(pThis->pDrvrName != NULL) {
+ obj.ReleaseObj(__FILE__, pThis->pDrvrName+2, DONT_LOAD_LIB, (void*) &pThis->Drvr);
+ free(pThis->pDrvrName);
+ }
ENDobjDestruct(nssel)
@@ -201,29 +223,5 @@ BEGINObjClassInit(nssel, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* set our own handlers */
ENDObjClassInit(nssel)
-
-
-/* --------------- here now comes the plumbing that makes us a library module --------------- */
-
-
-BEGINmodExit
-CODESTARTmodExit
- nsselClassExit();
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_LIB_QUERIES
-ENDqueryEtryPt
-
-
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-
- /* Initialize all classes that are in our module - this includes ourselfs */
- CHKiRet(nsselClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
-ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/nssel.h b/runtime/nssel.h
index 2f907caa..8cb34f5a 100644
--- a/runtime/nssel.h
+++ b/runtime/nssel.h
@@ -24,13 +24,14 @@
#ifndef INCLUDED_NSSEL_H
#define INCLUDED_NSSEL_H
-#include "nsd.h"
+#include "netstrms.h"
/* the nssel object */
struct nssel_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
nsd_t *pDrvrData; /**< the driver's data elements */
- uchar *pDrvrName; /**< nsd driver name to use, or NULL if system default */
+ uchar *pBaseDrvrName; /**< nsd base driver name to use, or NULL if system default */
+ uchar *pDrvrName; /**< full base driver name (set when driver is loaded) */
nsdsel_if_t Drvr; /**< our stream driver */
};
@@ -50,6 +51,6 @@ ENDinterface(nssel)
PROTOTYPEObj(nssel);
/* the name of our library binary */
-#define LM_NSSEL_FILENAME "lmnssel"
+#define LM_NSSEL_FILENAME LM_NETSTRMS_FILENAME
#endif /* #ifndef INCLUDED_NSSEL_H */
diff --git a/runtime/obj.c b/runtime/obj.c
index 18a4a726..312ed223 100644
--- a/runtime/obj.c
+++ b/runtime/obj.c
@@ -1192,15 +1192,14 @@ ReleaseObj(char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf)
objInfo_t *pObjInfo;
- dbgprintf("source file %s requests object '%s', ifIsLoaded %d\n", srcFile, pObjName, pIf->ifIsLoaded);
+ dbgprintf("source file %s releasing object '%s', ifIsLoaded %d\n", srcFile, pObjName, pIf->ifIsLoaded);
if(pObjFile == NULL)
FINALIZE; /* if it is not a lodable module, we do not need to do anything... */
if(pIf->ifIsLoaded == 0) {
ABORT_FINALIZE(RS_RET_OK); /* we are not loaded - this is perfectly OK... */
- }
- if(pIf->ifIsLoaded == 2) {
+ } else if(pIf->ifIsLoaded == 2) {
pIf->ifIsLoaded = 0; /* clean up */
ABORT_FINALIZE(RS_RET_OK); /* we had a load error and can not continue */
}
@@ -1209,7 +1208,6 @@ ReleaseObj(char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf)
CHKiRet(FindObjInfo(pStr, &pObjInfo));
/* if we reach this point, we have a valid pObjInfo */
- //if(pObjInfo->pModInfo != NULL) { /* NULL means core module */
module.Release(srcFile, &pObjInfo->pModInfo); /* decrease refcount */
pIf->ifIsLoaded = 0; /* indicated "no longer valid" */
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 19fda468..c32e190c 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -219,6 +219,9 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_GNUTLS_ERR = -2078, /**< (unexpected) error in GnuTLS call */
RS_RET_MAX_SESS_REACHED = -2079, /**< max nbr of sessions reached, can not create more */
RS_RET_MAX_LSTN_REACHED = -2080, /**< max nbr of listeners reached, can not create more */
+ RS_RET_INVAID_DRVR_MODE = -2081, /**< tried to set mode not supported by driver */
+ RS_RET_DRVRNAME_TOO_LONG = -2082, /**< driver name too long - should never happen */
+ RS_RET_TLS_HANDSHAKE_ERR = -2083, /**< TLS handshake failed */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/tcps_sess.c b/tcps_sess.c
index 33c13aa0..cf382db3 100644
--- a/tcps_sess.c
+++ b/tcps_sess.c
@@ -117,7 +117,6 @@ SetHost(tcps_sess_t *pThis, uchar *pszHost)
pThis->fromHost = pszHost;
-finalize_it:
RETiRet;
}
@@ -407,7 +406,7 @@ BEGINObjClassExit(tcps_sess, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END
CODESTARTObjClassExit(tcps_sess)
/* release objects we no longer need */
objRelease(errmsg, CORE_COMPONENT);
- objRelease(netstrm, LM_NETSTRM_FILENAME);
+ objRelease(netstrm, LM_NETSTRMS_FILENAME);
ENDObjClassExit(tcps_sess)
@@ -418,7 +417,7 @@ ENDObjClassExit(tcps_sess)
BEGINObjClassInit(tcps_sess, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME));
/* set our own handlers */
OBJSetMethodHandler(objMethod_DEBUGPRINT, tcps_sessDebugPrint);
diff --git a/tcpsrv.c b/tcpsrv.c
index 069c83c0..4501e834 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -181,12 +181,15 @@ TCPSessGetNxtSess(tcpsrv_t *pThis, int iCurr)
{
register int i;
+ BEGINfunc
ISOBJ_TYPE_assert(pThis, tcpsrv);
+ assert(pThis->pSessions != NULL);
for(i = iCurr + 1 ; i < pThis->iSessMax ; ++i) {
if(pThis->pSessions[i] != NULL)
break;
}
+ ENDfunc
return((i < pThis->iSessMax) ? i : -1);
}
@@ -202,20 +205,20 @@ static void deinit_tcp_listener(tcpsrv_t *pThis)
int i;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- assert(pThis->pSessions != NULL);
- /* close all TCP connections! */
- i = TCPSessGetNxtSess(pThis, -1);
- while(i != -1) {
- tcps_sess.Destruct(&pThis->pSessions[i]);
- /* now get next... */
- i = TCPSessGetNxtSess(pThis, i);
+ if(pThis->pSessions != NULL) {
+ /* close all TCP connections! */
+ i = TCPSessGetNxtSess(pThis, -1);
+ while(i != -1) {
+ tcps_sess.Destruct(&pThis->pSessions[i]);
+ /* now get next... */
+ i = TCPSessGetNxtSess(pThis, i);
+ }
+
+ /* we are done with the session table - so get rid of it... */
+ free(pThis->pSessions);
+ pThis->pSessions = NULL; /* just to make sure... */
}
-
- /* we are done with the session table - so get rid of it...
- */
- free(pThis->pSessions);
- pThis->pSessions = NULL; /* just to make sure... */
if(pThis->TCPLstnPort != NULL)
free(pThis->TCPLstnPort);
@@ -413,7 +416,6 @@ Run(tcpsrv_t *pThis)
/* Add the TCP listen sockets to the list of read descriptors. */
for(i = 0 ; i < pThis->iLstnMax ; ++i) {
-RUNLOG_VAR("%d", i);
CHKiRet(nssel.Add(pSel, pThis->ppLstn[i], NSDSEL_RD));
}
@@ -498,6 +500,7 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis)
/* prepare network stream subsystem */
CHKiRet(netstrms.Construct(&pThis->pNS));
+ CHKiRet(netstrms.SetDrvrMode(pThis->pNS, pThis->iDrvrMode));
// TODO: set driver!
CHKiRet(netstrms.ConstructFinalize(pThis->pNS));
@@ -622,6 +625,18 @@ SetUsrP(tcpsrv_t *pThis, void *pUsr)
pThis->pUsr = pUsr;
RETiRet;
}
+/* set the driver mode -- rgerhards, 2008-04-30
+ */
+static rsRetVal
+SetDrvrMode(tcpsrv_t *pThis, int iMode)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+ pThis->iDrvrMode = iMode;
+ RETiRet;
+}
+
+
/* queryInterface function
@@ -649,6 +664,7 @@ CODESTARTobjQueryInterface(tcpsrv)
pIf->Run = Run;
pIf->SetUsrP = SetUsrP;
+ pIf->SetDrvrMode = SetDrvrMode;
pIf->SetCBIsPermittedHost = SetCBIsPermittedHost;
pIf->SetCBOpenLstnSocks = SetCBOpenLstnSocks;
pIf->SetCBRcvData = SetCBRcvData;
@@ -674,9 +690,9 @@ CODESTARTObjClassExit(tcpsrv)
objRelease(conf, CORE_COMPONENT);
objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
- objRelease(nssel, LM_NSSEL_FILENAME);
- objRelease(netstrm, LM_NETSTRM_FILENAME);
- objRelease(netstrms, LM_NETSTRMS_FILENAME);
+ objRelease(netstrms, DONT_LOAD_LIB);
+ objRelease(nssel, DONT_LOAD_LIB);
+ objRelease(netstrm, LM_NETSTRMS_FILENAME);
objRelease(net, LM_NET_FILENAME);
ENDObjClassExit(tcpsrv)
@@ -690,8 +706,8 @@ BEGINObjClassInit(tcpsrv, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(net, LM_NET_FILENAME));
CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
- CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
- CHKiRet(objUse(nssel, LM_NSSEL_FILENAME));
+ CHKiRet(objUse(netstrm, DONT_LOAD_LIB));
+ CHKiRet(objUse(nssel, DONT_LOAD_LIB));
CHKiRet(objUse(tcps_sess, DONT_LOAD_LIB));
CHKiRet(objUse(conf, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
diff --git a/tcpsrv.h b/tcpsrv.h
index ada77aec..07826125 100644
--- a/tcpsrv.h
+++ b/tcpsrv.h
@@ -29,6 +29,7 @@
struct tcpsrv_s {
BEGINobjInstance; /**< Data to implement generic object - MUST be the first data element! */
netstrms_t *pNS; /**< pointer to network stream subsystem */
+ int iDrvrMode; /**< mode of the stream driver to use */
int iLstnMax; /**< max nbr of listeners currently supported */
netstrm_t **ppLstn; /**< our netstream listners */
int iSessMax; /**< max number of sessions supported */
@@ -69,6 +70,7 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetCBOnDestruct)(tcpsrv_t*, rsRetVal (*) (void*));
rsRetVal (*SetCBOnRegularClose)(tcpsrv_t*, rsRetVal (*) (tcps_sess_t*));
rsRetVal (*SetCBOnErrClose)(tcpsrv_t*, rsRetVal (*) (tcps_sess_t*));
+ rsRetVal (*SetDrvrMode)(tcpsrv_t *pThis, int iMode);
/* session specifics */
rsRetVal (*SetCBOnSessAccept)(tcpsrv_t*, rsRetVal (*) (tcpsrv_t*, tcps_sess_t*));
rsRetVal (*SetCBOnSessDestruct)(tcpsrv_t*, rsRetVal (*) (void*));
diff --git a/tools/omfile.c b/tools/omfile.c
index 4b5eb280..285e798d 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -840,6 +840,5 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(regCfSysLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
-/*
- * vi:set ai:
+/* vi:set ai:
*/
diff --git a/tools/omfwd.c b/tools/omfwd.c
index 719075c7..59245536 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -77,6 +77,8 @@ DEFobjCurrIf(tcpclt)
typedef struct _instanceData {
netstrms_t *pNS; /* netstream subsystem */
netstrm_t *pNetstrm; /* our output netstream */
+ uchar *pszStrmDrvr;
+ int iStrmDrvrMode;
char *f_hname;
int *pSockArray; /* sockets to use for UDP */
int bIsConnected; /* are we connected to remote host? 0 - no, 1 - yes, UDP means addr resolved */
@@ -91,7 +93,9 @@ typedef struct _instanceData {
} instanceData;
/* config data */
-static uchar *pszTplName = NULL; /* name of the default template to use */
+static uchar *pszTplName = NULL; /* name of the default template to use */
+static uchar *pszStrmDrvr = NULL; /* name of the stream driver to use */
+static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
/* get the syslog forward port from selector_t. The passed in
@@ -256,12 +260,14 @@ static rsRetVal TCPSendInit(void *pvData)
assert(pData != NULL);
if(pData->pNetstrm == NULL) {
CHKiRet(netstrms.Construct(&pData->pNS));
- /* here we may set another netstream driver (e.g. to do TLS) */
+ /* the stream driver must be set before the object is finalized! */
+ CHKiRet(netstrms.SetDrvrName(pData->pNS, pszStrmDrvr));
CHKiRet(netstrms.ConstructFinalize(pData->pNS));
/* now create the actual stream and connect to the server */
CHKiRet(netstrms.CreateStrm(pData->pNS, &pData->pNetstrm));
CHKiRet(netstrm.ConstructFinalize(pData->pNetstrm));
+ CHKiRet(netstrm.SetDrvrMode(pData->pNetstrm, pData->iStrmDrvrMode));
CHKiRet(netstrm.Connect(pData->pNetstrm, glbl.GetDefPFFamily(),
(uchar*)pData->port, (uchar*)pData->f_hname));
}
@@ -405,12 +411,9 @@ static rsRetVal
loadTCPSupport(void)
{
DEFiRet;
- if(!netstrms.ifIsLoaded)
- CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
- if(!netstrm.ifIsLoaded)
- CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
- if(!tcpclt.ifIsLoaded)
- CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
+ CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
+ CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME));
+ CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
finalize_it:
RETiRet;
@@ -563,6 +566,9 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame));
CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry));
CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing));
+ pData->iStrmDrvrMode = iStrmDrvrMode;
+ if(pData->pszStrmDrvr != NULL)
+ CHKmalloc(pData->pszStrmDrvr = (uchar*)strdup((char*)pszStrmDrvr));
}
CODE_STD_FINALIZERparseSelectorAct
@@ -575,17 +581,18 @@ CODESTARTmodExit
objRelease(errmsg, CORE_COMPONENT);
objRelease(glbl, CORE_COMPONENT);
objRelease(net, LM_NET_FILENAME);
- if(netstrm.ifIsLoaded)
- objRelease(netstrm, LM_NETSTRM_FILENAME);
- if(netstrms.ifIsLoaded)
- objRelease(netstrms, LM_NETSTRMS_FILENAME);
- if(!tcpclt.ifIsLoaded)
- objRelease(tcpclt, LM_TCPCLT_FILENAME);
+ objRelease(netstrm, LM_NETSTRMS_FILENAME);
+ objRelease(netstrms, LM_NETSTRMS_FILENAME);
+ objRelease(tcpclt, LM_TCPCLT_FILENAME);
if(pszTplName != NULL) {
free(pszTplName);
pszTplName = NULL;
}
+ if(pszStrmDrvr != NULL) {
+ free(pszStrmDrvr);
+ pszStrmDrvr = NULL;
+ }
ENDmodExit
@@ -604,6 +611,11 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
free(pszTplName);
pszTplName = NULL;
}
+ if(pszStrmDrvr != NULL) {
+ free(pszStrmDrvr);
+ pszStrmDrvr = NULL;
+ }
+ iStrmDrvrMode = 0;
return RS_RET_OK;
}
@@ -618,6 +630,8 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(net,LM_NET_FILENAME));
CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszStrmDrvr, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdrivermode", 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit