diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | doc/imtcp.html | 10 | ||||
-rw-r--r-- | plugins/imtcp/imtcp.c | 5 | ||||
-rw-r--r-- | runtime/stream.c | 10 | ||||
-rw-r--r-- | tcpsrv.c | 44 | ||||
-rw-r--r-- | tcpsrv.h | 7 |
6 files changed, 61 insertions, 19 deletions
@@ -80,10 +80,14 @@ Version 4.5.2 [DEVEL] (rgerhards), 2009-07-?? - legacy syslog parser changed so that it now accepts date stamps in wrong case. Some devices seem to create them and I do not see any harm in supporting that. +- added $InputTCPMaxListeners directive - permits to specify how many + TCP servers shall be possible (default is 20). - bugfix: memory leak with some input modules. Those inputs that use parseAndSubmitMsg() leak two small memory blocks with every message. Typically, those process only relatively few messages, so the issue does most probably not have any effect in practice. +- bugfix: if tcp listen port could not be created, no error message was + emitted --------------------------------------------------------------------------- Version 4.5.1 [DEVEL] (rgerhards), 2009-07-15 - CONFIG CHANGE: $HUPisRestart default is now "off". We are doing this diff --git a/doc/imtcp.html b/doc/imtcp.html index 9ea7efa1..5217634e 100644 --- a/doc/imtcp.html +++ b/doc/imtcp.html @@ -43,15 +43,19 @@ can be found at the <a href="http://www.rsyslog.com/Article321.phtml">Cisco tcp page. <li>$InputTCPServerRun <port><br> Starts a TCP server on selected port</li> -<li><ul><li>$InputTCPMaxSessions <number></li></ul> -Sets the maximum number of sessions supported</li><li>$InputTCPServerStreamDriverMode <number><br> +<li>$InputTCPMaxListeners <number><br> +Sets the maximum number of listeners (server ports) supported. Default is 20. This must be set before the first $InputTCPServerRun directive.</li> +<li>$InputTCPMaxSessions <number><br> +Sets the maximum number of sessions supported. Default is 200. This must be set before the first $InputTCPServerRun directive</li> +<li>$InputTCPServerStreamDriverMode <number><br> Sets the driver mode for the currently selected <a href="netstream.html">network stream driver</a>. <number> is driver specifc.</li> <li>$InputTCPServerInputName <name><br> Sets a name for the inputname property. If no name is set "imtcp" is used by default. Setting a name is not strictly necessary, but can be useful to apply filtering based on which input the message was received from. <li>$InputTCPServerStreamDriverAuthMode <mode-string><br> -Sets the authentication mode for the currently selected <a href="netstream.html">network stream driver</a>. <mode-string> is driver specifc.</li><li>$InputTCPServerStreamDriverPermittedPeer <id-string><br> +Sets the authentication mode for the currently selected <a href="netstream.html">network stream driver</a>. <mode-string> is driver specifc.</li> +<li>$InputTCPServerStreamDriverPermittedPeer <id-string><br> Sets permitted peer IDs. Only these peers are able to connect to the listener. <id-string> semantics depend on the currently selected AuthMode and <a href="netstream.html">network stream driver</a>. PermittedPeers may not be set in anonymous modes.</li> diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 1f111ef3..0bd064e6 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -82,6 +82,7 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ +static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ @@ -188,6 +189,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax)); + CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, iTCPLstnMax)); CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); @@ -280,6 +282,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iTCPSessMax = 200; + iTCPLstnMax = 20; iStrmDrvrMode = 0; iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; free(pszInputName); @@ -316,6 +319,8 @@ CODEmodInit_QueryRegCFSLineHdlr addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, + NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, diff --git a/runtime/stream.c b/runtime/stream.c index 7c96324a..8d76780c 100644 --- a/runtime/stream.c +++ b/runtime/stream.c @@ -628,7 +628,8 @@ static rsRetVal strmConstructFinalize(strm_t *pThis) pthread_cond_init(&pThis->notEmpty, 0); pthread_cond_init(&pThis->isEmpty, 0); pThis->iCnt = pThis->iEnq = pThis->iDeq = 0; - for(i = 0 ; i < STREAM_ASYNC_NUMBUFS ; ++i) { + //for(i = 0 ; i < STREAM_ASYNC_NUMBUFS ; ++i) { + for(i = 0 ; i < 1 ; ++i) { // HOTFIX!!! CHKmalloc(pThis->asyncBuf[i].pBuf = (uchar*) malloc(sizeof(uchar) * pThis->sIOBufSize)); } pThis->pIOBuf = pThis->asyncBuf[0].pBuf; @@ -843,7 +844,10 @@ doAsyncWriteInternal(strm_t *pThis, size_t lenBuf) d_pthread_cond_wait(&pThis->notFull, &pThis->mut); pThis->asyncBuf[pThis->iEnq % STREAM_ASYNC_NUMBUFS].lenBuf = lenBuf; - pThis->pIOBuf = pThis->asyncBuf[++pThis->iEnq % STREAM_ASYNC_NUMBUFS].pBuf; + pThis->asyncBuf[pThis->iEnq % STREAM_ASYNC_NUMBUFS].pBuf = pThis->pIOBuf; + //pThis->pIOBuf = pThis->asyncBuf[++pThis->iEnq % STREAM_ASYNC_NUMBUFS].pBuf; + ++pThis->iEnq; + CHKmalloc(pThis->pIOBuf = (uchar*) malloc(sizeof(uchar) * pThis->sIOBufSize)); pThis->bDoTimedWait = 0; /* everything written, no need to timeout partial buffer writes */ if(++pThis->iCnt == 1) @@ -936,6 +940,8 @@ asyncWriterThread(void *pPtr) iDeq = pThis->iDeq++ % STREAM_ASYNC_NUMBUFS; doWriteInternal(pThis, pThis->asyncBuf[iDeq].pBuf, pThis->asyncBuf[iDeq].lenBuf); // TODO: error check????? 2009-07-06 + free(pThis->asyncBuf[iDeq].pBuf); + pThis->asyncBuf[iDeq].pBuf = NULL; --pThis->iCnt; if(pThis->iCnt < STREAM_ASYNC_NUMBUFS) { @@ -261,7 +261,7 @@ static void deinit_tcp_listener(tcpsrv_t *pThis) } /* finally close our listen streams */ - for(i = 0 ; i < pThis->iLstnMax ; ++i) { + for(i = 0 ; i < pThis->iLstnCurr ; ++i) { netstrm.Destruct(pThis->ppLstn + i); } } @@ -280,12 +280,12 @@ addTcpLstn(void *pUsr, netstrm_t *pLstn) ISOBJ_TYPE_assert(pThis, tcpsrv); ISOBJ_TYPE_assert(pLstn, netstrm); - if(pThis->iLstnMax >= TCPLSTN_MAX_DEFAULT) + if(pThis->iLstnCurr >= pThis->iLstnMax) ABORT_FINALIZE(RS_RET_MAX_LSTN_REACHED); - pThis->ppLstn[pThis->iLstnMax] = pLstn; - pThis->ppLstnPort[pThis->iLstnMax] = pPortList; - ++pThis->iLstnMax; + pThis->ppLstn[pThis->iLstnCurr] = pLstn; + pThis->ppLstnPort[pThis->iLstnCurr] = pPortList; + ++pThis->iLstnCurr; finalize_it: RETiRet; @@ -327,15 +327,19 @@ finalize_it: static rsRetVal create_tcp_socket(tcpsrv_t *pThis) { - tcpLstnPortList_t *pEntry; DEFiRet; + rsRetVal localRet; + tcpLstnPortList_t *pEntry; ISOBJ_TYPE_assert(pThis, tcpsrv); /* init all configured ports */ pEntry = pThis->pLstnPorts; while(pEntry != NULL) { - CHKiRet(initTCPListener(pThis, pEntry)); + localRet = initTCPListener(pThis, pEntry); + if(localRet != RS_RET_OK) { + errmsg.LogError(0, localRet, "Could not create tcp listener, ignoring port %s.", pEntry->pszPort); + } pEntry = pEntry->pNext; } @@ -534,7 +538,7 @@ Run(tcpsrv_t *pThis) CHKiRet(nssel.ConstructFinalize(pSel)); /* Add the TCP listen sockets to the list of read descriptors. */ - for(i = 0 ; i < pThis->iLstnMax ; ++i) { + for(i = 0 ; i < pThis->iLstnCurr ; ++i) { CHKiRet(nssel.Add(pSel, pThis->ppLstn[i], NSDSEL_RD)); } @@ -552,7 +556,7 @@ Run(tcpsrv_t *pThis) if(glbl.GetGlobalInputTermState() == 1) break; /* terminate input! */ - for(i = 0 ; i < pThis->iLstnMax ; ++i) { + for(i = 0 ; i < pThis->iLstnCurr ; ++i) { CHKiRet(nssel.IsReady(pSel, pThis->ppLstn[i], NSDSEL_RD, &bIsReady, &nfds)); if(bIsReady) { DBGPRINTF("New connect on NSD %p.\n", pThis->ppLstn[i]); @@ -591,7 +595,8 @@ finalize_it: /* this is a very special case - this time only we do not exit the /* Standard-Constructor */ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macro! */ - pThis->iSessMax = TCPSESS_MAX_DEFAULT; /* TODO: useful default ;) */ + pThis->iSessMax = TCPSESS_MAX_DEFAULT; + pThis->iLstnMax = TCPLSTN_MAX_DEFAULT; pThis->addtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; pThis->OnMsgReceive = NULL; ENDobjConstruct(tcpsrv) @@ -615,8 +620,8 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis) CHKiRet(netstrms.ConstructFinalize(pThis->pNS)); /* set up listeners */ - CHKmalloc(pThis->ppLstn = calloc(TCPLSTN_MAX_DEFAULT, sizeof(netstrm_t*))); - CHKmalloc(pThis->ppLstnPort = calloc(TCPLSTN_MAX_DEFAULT, sizeof(tcpLstnPortList_t*))); + CHKmalloc(pThis->ppLstn = calloc(pThis->iLstnMax, sizeof(netstrm_t*))); + CHKmalloc(pThis->ppLstnPort = calloc(pThis->iLstnMax, sizeof(tcpLstnPortList_t*))); iRet = pThis->OpenLstnSocks(pThis); finalize_it: @@ -833,6 +838,20 @@ SetDrvrPermPeers(tcpsrv_t *pThis, permittedPeers_t *pPermPeers) * -------------------------------------------------------------------------- */ +/* set max number of listeners + * this must be called before ConstructFinalize, or it will have no effect! + * rgerhards, 2009-08-17 + */ +static rsRetVal +SetLstnMax(tcpsrv_t *pThis, int iMax) +{ + DEFiRet; + ISOBJ_TYPE_assert(pThis, tcpsrv); + pThis->iLstnMax = iMax; + RETiRet; +} + + /* set max number of sessions * this must be called before ConstructFinalize, or it will have no effect! * rgerhards, 2009-04-09 @@ -875,6 +894,7 @@ CODESTARTobjQueryInterface(tcpsrv) pIf->SetInputName = SetInputName; pIf->SetAddtlFrameDelim = SetAddtlFrameDelim; pIf->SetSessMax = SetSessMax; + pIf->SetLstnMax = SetLstnMax; pIf->SetDrvrMode = SetDrvrMode; pIf->SetDrvrAuthMode = SetDrvrAuthMode; pIf->SetDrvrPermPeers = SetDrvrPermPeers; @@ -54,9 +54,10 @@ struct tcpsrv_s { uchar *pszInputName; /**< value to be used as input name */ ruleset_t *pRuleset; /**< ruleset to bind to */ permittedPeers_t *pPermPeers;/**< driver's permitted peers */ - int iLstnMax; /**< max nbr of listeners currently supported */ + int iLstnCurr; /**< max nbr of listeners currently supported */ netstrm_t **ppLstn; /**< our netstream listners */ tcpLstnPortList_t **ppLstnPort; /**< pointer to relevant listen port description */ + int iLstnMax; /**< max number of listners supported */ int iSessMax; /**< max number of sessions supported */ tcpLstnPortList_t *pLstnPorts; /**< head pointer for listen ports */ int addtlFrameDelim; /**< additional frame delimiter for plain TCP syslog framing (e.g. to handle NetScreen) */ @@ -111,8 +112,10 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */ /* added v6 */ rsRetVal (*SetOnMsgReceive)(tcpsrv_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t*, uchar*, int)); /* 2009-05-24 */ rsRetVal (*SetRuleset)(tcpsrv_t *pThis, ruleset_t*); /* 2009-06-12 */ + /* added v7 */ + rsRetVal (*SetLstnMax)(tcpsrv_t *pThis, int iMaxLstn); /* 2009-08-17 */ ENDinterface(tcpsrv) -#define tcpsrvCURR_IF_VERSION 6 /* increment whenever you change the interface structure! */ +#define tcpsrvCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */ /* change for v4: * - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10 * - SetInputName() added -- rgerhards, 2008-12-10 |