summaryrefslogtreecommitdiffstats
path: root/tcpsrv.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-05-22 17:06:52 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2009-05-22 17:06:52 +0200
commitaba90e82484118f3568ec51c01de5ba845da589a (patch)
treedee21fce32d09af5ab80ccbad8c51772e7645dd8 /tcpsrv.c
parent2aca3c2d33dd1a19daf44168e90a5f64bd4095b0 (diff)
downloadrsyslog-aba90e82484118f3568ec51c01de5ba845da589a.tar.gz
rsyslog-aba90e82484118f3568ec51c01de5ba845da589a.tar.xz
rsyslog-aba90e82484118f3568ec51c01de5ba845da589a.zip
added capability to run multiple tcp listeners (on different ports)
Well, actually this and a lot of related things. I improved the testbench so that the new capabilities are automatically tested and also did some general cleanup. The current multiple tcp listener solution will probably receive some further cleanup, too, but looks quite OK so far. I also reviewed the way tcpsrv et all work, in preparation of using this code for imdiag. I need to document the findings, especially as the code is rather complicated "thanks" to the combination of plain tcp and gssapi transport modes.
Diffstat (limited to 'tcpsrv.c')
-rw-r--r--tcpsrv.c150
1 files changed, 104 insertions, 46 deletions
diff --git a/tcpsrv.c b/tcpsrv.c
index 7af45d3c..bbd95058 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -66,6 +66,7 @@
#include "netstrm.h"
#include "nssel.h"
#include "errmsg.h"
+#include "unicode-helper.h"
MODULE_TYPE_LIB
@@ -85,43 +86,61 @@ DEFobjCurrIf(netstrm)
DEFobjCurrIf(nssel)
-/* configure TCP listener settings. This is called during command
- * line parsing. The argument following -t is supplied as an argument.
- * The format of this argument is
- * "<port-to-use>, <nbr-of-sessions>"
- * Typically, there is no whitespace between port and session number.
- * (but it may be...).
- * NOTE: you can not use dbgprintf() in here - the dbgprintf() system is
- * not yet initilized when this function is called.
- * rgerhards, 2007-06-21
- * The port in cOptarg is handed over to us - the caller MUST NOT free it!
+/* add new listener port to listener port list
+ * rgerhards, 2009-05-21
+ */
+static inline rsRetVal
+addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort)
+{
+ tcpLstnPortList_t *pEntry;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+
+dbgprintf("XXX: tcpsrv.c add port %s, name '%s'\n", pszPort, pThis->pszInputName);
+ /* create entry */
+ CHKmalloc(pEntry = malloc(sizeof(tcpLstnPortList_t)));
+ pEntry->pszPort = pszPort;
+ pEntry->pSrv = pThis;
+ CHKmalloc(pEntry->pszInputName = ustrdup(pThis->pszInputName));
+
+ /* and add to list */
+ pEntry->pNext = pThis->pLstnPorts;
+ pThis->pLstnPorts = pEntry;
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* configure TCP listener settings.
+ * Note: pszPort is handed over to us - the caller MUST NOT free it!
* rgerhards, 2008-03-20
*/
-static void
-configureTCPListen(tcpsrv_t *pThis, char *cOptarg)
+static rsRetVal
+configureTCPListen(tcpsrv_t *pThis, uchar *pszPort)
{
- register int i;
- register char *pArg = cOptarg;
+ int i;
+ uchar *pPort = pszPort;
+ DEFiRet;
- assert(cOptarg != NULL);
+ assert(pszPort != NULL);
ISOBJ_TYPE_assert(pThis, tcpsrv);
/* extract port */
i = 0;
- while(isdigit((int) *pArg)) {
- i = i * 10 + *pArg++ - '0';
+ while(isdigit((int) *pPort)) {
+ i = i * 10 + *pPort++ - '0';
}
- if(pThis->TCPLstnPort != NULL) {
- free(pThis->TCPLstnPort);
- pThis->TCPLstnPort = NULL;
- }
-
- if( i >= 0 && i <= 65535) {
- pThis->TCPLstnPort = cOptarg;
+ if(i >= 0 && i <= 65535) {
+ CHKiRet(addNewLstnPort(pThis, pszPort));
} else {
- errmsg.LogError(0, NO_ERRCODE, "Invalid TCP listen port %s - changed to 514.\n", cOptarg);
+ errmsg.LogError(0, NO_ERRCODE, "Invalid TCP listen port %s - ignored.\n", pszPort);
}
+
+finalize_it:
+ RETiRet;
}
@@ -202,6 +221,8 @@ TCPSessGetNxtSess(tcpsrv_t *pThis, int iCurr)
static void deinit_tcp_listener(tcpsrv_t *pThis)
{
int i;
+ tcpLstnPortList_t *pEntry;
+ tcpLstnPortList_t *pDel;
ISOBJ_TYPE_assert(pThis, tcpsrv);
@@ -219,7 +240,15 @@ static void deinit_tcp_listener(tcpsrv_t *pThis)
pThis->pSessions = NULL; /* just to make sure... */
}
- free(pThis->TCPLstnPort);
+ /* free list of tcp listen ports */
+ pEntry = pThis->pLstnPorts;
+ while(pEntry != NULL) {
+ free(pEntry->pszPort);
+ free(pEntry->pszInputName);
+ pDel = pEntry;
+ pEntry = pEntry->pNext;
+ free(pDel);
+ }
/* finally close our listen streams */
for(i = 0 ; i < pThis->iLstnMax ; ++i) {
@@ -234,9 +263,11 @@ static void deinit_tcp_listener(tcpsrv_t *pThis)
static rsRetVal
addTcpLstn(void *pUsr, netstrm_t *pLstn)
{
- tcpsrv_t *pThis = (tcpsrv_t*) pUsr;
+ tcpLstnPortList_t *pPortList = (tcpLstnPortList_t *) pUsr;
+ tcpsrv_t *pThis = pPortList->pSrv;
DEFiRet;
+dbgprintf("XXX: addTcpLst name %s\n", pPortList->pszInputName);
ISOBJ_TYPE_assert(pThis, tcpsrv);
ISOBJ_TYPE_assert(pLstn, netstrm);
@@ -244,6 +275,7 @@ addTcpLstn(void *pUsr, netstrm_t *pLstn)
ABORT_FINALIZE(RS_RET_MAX_LSTN_REACHED);
pThis->ppLstn[pThis->iLstnMax] = pLstn;
+ pThis->ppLstnPort[pThis->iLstnMax] = pPortList;
++pThis->iLstnMax;
finalize_it:
@@ -251,19 +283,20 @@ finalize_it:
}
-/* Initialize TCP sockets (for listener) and listens on them */
-static rsRetVal
-create_tcp_socket(tcpsrv_t *pThis)
+/* Initialize TCP listener socket for a single port
+ * rgerhards, 2009-05-21
+ */
+static inline rsRetVal
+initTCPListener(tcpsrv_t *pThis, tcpLstnPortList_t *pPortEntry)
{
DEFiRet;
uchar *TCPLstnPort;
ISOBJ_TYPE_assert(pThis, tcpsrv);
+ assert(pPortEntry != NULL);
- if(!strcmp((char*)pThis->TCPLstnPort, "0"))
- TCPLstnPort = (uchar*)"514";
- // TODO: we need to enable the caller to set a port (based on who is
- // using this, 514 may be totally unsuitable... --- rgerhards, 2008-04-22
+ if(!ustrcmp(pPortEntry->pszPort, UCHAR_CONSTANT("0")))
+ TCPLstnPort = UCHAR_CONSTANT("514");
/* use default - we can not do service db update, because there is
* no IANA-assignment for syslog/tcp. In the long term, we might
* re-use RFC 3195 port of 601, but that would probably break to
@@ -271,10 +304,32 @@ create_tcp_socket(tcpsrv_t *pThis)
* rgerhards, 2007-06-28
*/
else
- TCPLstnPort = (uchar*)pThis->TCPLstnPort;
+ TCPLstnPort = pPortEntry->pszPort;
/* TODO: add capability to specify local listen address! */
- CHKiRet(netstrm.LstnInit(pThis->pNS, (void*)pThis, addTcpLstn, TCPLstnPort, NULL, pThis->iSessMax));
+ CHKiRet(netstrm.LstnInit(pThis->pNS, (void*)pPortEntry, addTcpLstn, TCPLstnPort, NULL, pThis->iSessMax));
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* Initialize TCP sockets (for listener) and listens on them */
+static rsRetVal
+create_tcp_socket(tcpsrv_t *pThis)
+{
+ tcpLstnPortList_t *pEntry;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+
+ /* init all configured ports */
+ pEntry = pThis->pLstnPorts;
+ while(pEntry != NULL) {
+dbgprintf("XXX: tcpsrv.c create_tcp_socket do port %s\n", pEntry->pszPort);
+ CHKiRet(initTCPListener(pThis, pEntry));
+ pEntry = pEntry->pNext;
+ }
/* OK, we had success. Now it is also time to
* initialize our connections
@@ -296,7 +351,7 @@ finalize_it:
/* Accept new TCP connection; make entry in session table. If there
* is no more space left in the connection table, the new TCP
* connection is immediately dropped.
- * ppSess has a pointer to the newly created session, if it succeds.
+ * ppSess has a pointer to the newly created session, if it succeeds.
* If it does not succeed, no session is created and ppSess is
* undefined. If the user has provided an OnSessAccept Callback,
* this one is executed immediately after creation of the
@@ -304,7 +359,7 @@ finalize_it:
* rgerhards, 2008-03-02
*/
static rsRetVal
-SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm)
+SessAccept(tcpsrv_t *pThis, tcpLstnPortList_t *pLstnInfo, tcps_sess_t **ppSess, netstrm_t *pStrm)
{
DEFiRet;
tcps_sess_t *pSess = NULL;
@@ -315,6 +370,7 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm)
uchar *fromHostIP = NULL;
ISOBJ_TYPE_assert(pThis, tcpsrv);
+ assert(pLstnInfo != NULL);
CHKiRet(netstrm.AcceptConnReq(pStrm, &pNewStrm));
@@ -328,6 +384,7 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm)
/* we found a free spot and can construct our session object */
CHKiRet(tcps_sess.Construct(&pSess));
CHKiRet(tcps_sess.SetTcpsrv(pSess, pThis));
+ CHKiRet(tcps_sess.SetLstnInfo(pSess, pLstnInfo));
}
/* OK, we have a "good" index... */
@@ -375,12 +432,10 @@ finalize_it:
if(iRet != RS_RET_OK) {
if(pSess != NULL)
tcps_sess.Destruct(&pSess);
- if(fromHostFQDN != NULL)
- free(fromHostFQDN);
- if(fromHostIP != NULL)
- free(fromHostIP);
if(pNewStrm != NULL)
netstrm.Destruct(&pNewStrm);
+ free(fromHostFQDN);
+ free(fromHostIP);
}
RETiRet;
@@ -444,7 +499,7 @@ Run(tcpsrv_t *pThis)
CHKiRet(nssel.IsReady(pSel, pThis->ppLstn[i], NSDSEL_RD, &bIsReady, &nfds));
if(bIsReady) {
dbgprintf("New connect on NSD %p.\n", pThis->ppLstn[i]);
- SessAccept(pThis, &pNewSess, pThis->ppLstn[i]);
+ SessAccept(pThis, pThis->ppLstnPort[i], &pNewSess, pThis->ppLstn[i]);
--nfds; /* indicate we have processed one */
}
}
@@ -535,6 +590,7 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis)
/* set up listeners */
CHKmalloc(pThis->ppLstn = calloc(TCPLSTN_MAX_DEFAULT, sizeof(netstrm_t*)));
+ CHKmalloc(pThis->ppLstnPort = calloc(TCPLSTN_MAX_DEFAULT, sizeof(tcpLstnPortList_t*)));
iRet = pThis->OpenLstnSocks(pThis);
finalize_it:
@@ -558,6 +614,7 @@ CODESTARTobjDestruct(tcpsrv)
netstrms.Destruct(&pThis->pNS);
free(pThis->pszDrvrAuthMode);
free(pThis->ppLstn);
+ free(pThis->ppLstnPort);
free(pThis->pszInputName);
ENDobjDestruct(tcpsrv)
@@ -674,11 +731,12 @@ SetInputName(tcpsrv_t *pThis, uchar *name)
{
uchar *pszName;
DEFiRet;
+dbgprintf("XXX: SetInputName: %s\n", name);
ISOBJ_TYPE_assert(pThis, tcpsrv);
if(name == NULL)
pszName = NULL;
else
- CHKmalloc(pszName = (uchar*)strdup((char*)name));
+ CHKmalloc(pszName = ustrdup(name));
free(pThis->pszInputName);
pThis->pszInputName = pszName;
finalize_it:
@@ -708,7 +766,7 @@ SetDrvrAuthMode(tcpsrv_t *pThis, uchar *mode)
{
DEFiRet;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- CHKmalloc(pThis->pszDrvrAuthMode = (uchar*)strdup((char*)mode));
+ CHKmalloc(pThis->pszDrvrAuthMode = ustrdup(mode));
finalize_it:
RETiRet;
}
@@ -763,7 +821,7 @@ CODESTARTobjQueryInterface(tcpsrv)
pIf->ConstructFinalize = tcpsrvConstructFinalize;
pIf->Destruct = tcpsrvDestruct;
- pIf->SessAccept = SessAccept;
+ //pIf->SessAccept = SessAccept;
pIf->configureTCPListen = configureTCPListen;
pIf->create_tcp_socket = create_tcp_socket;
pIf->Run = Run;