mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-20 12:00:43 +01:00
764 lines
25 KiB
C
764 lines
25 KiB
C
/* imtcp.c
|
|
* This is the implementation of the TCP input module.
|
|
*
|
|
* File begun on 2007-12-21 by RGerhards (extracted from syslogd.c,
|
|
* which at the time of the rsyslog fork was BSD-licensed)
|
|
*
|
|
* Copyright 2007-2013 Adiscon GmbH.
|
|
*
|
|
* This file is part of rsyslog.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
* -or-
|
|
* see COPYING.ASL20 in the source distribution
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/* This note shall explain the calling sequence while we do not have
|
|
* have full RainerScript support for (TLS) sender authentication:
|
|
*
|
|
* imtcp --> tcpsrv --> netstrms (this sequence stored pPermPeers in netstrms class)
|
|
* then a callback (doOpenLstnSocks) into imtcp happens, which in turn calls
|
|
* into tcpsrv.create_tcp_socket(),
|
|
* which calls into netstrm.LstnInit(), which receives a pointer to netstrms obj
|
|
* which calls into the driver function LstnInit (again, netstrms obj passed)
|
|
* which finally calls back into netstrms obj's get functions to obtain the auth
|
|
* parameters and then applies them to the driver object instance
|
|
*
|
|
* rgerhards, 2008-05-19
|
|
*/
|
|
#include "config.h"
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <stdarg.h>
|
|
#include <ctype.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#if HAVE_FCNTL_H
|
|
#include <fcntl.h>
|
|
#endif
|
|
#include "rsyslog.h"
|
|
#include "dirty.h"
|
|
#include "cfsysline.h"
|
|
#include "module-template.h"
|
|
#include "unicode-helper.h"
|
|
#include "net.h"
|
|
#include "netstrm.h"
|
|
#include "errmsg.h"
|
|
#include "tcpsrv.h"
|
|
#include "ruleset.h"
|
|
#include "rainerscript.h"
|
|
#include "net.h" /* for permittedPeers, may be removed when this is removed */
|
|
|
|
MODULE_TYPE_INPUT
|
|
MODULE_TYPE_NOKEEP
|
|
MODULE_CNFNAME("imtcp")
|
|
|
|
/* static data */
|
|
DEF_IMOD_STATIC_DATA
|
|
DEFobjCurrIf(tcpsrv)
|
|
DEFobjCurrIf(tcps_sess)
|
|
DEFobjCurrIf(net)
|
|
DEFobjCurrIf(netstrm)
|
|
DEFobjCurrIf(errmsg)
|
|
DEFobjCurrIf(ruleset)
|
|
|
|
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
|
|
|
|
/* Module static data */
|
|
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
|
|
static permittedPeers_t *pPermPeersRoot = NULL;
|
|
|
|
#define FRAMING_UNSET -1
|
|
|
|
/* config settings */
|
|
static struct configSettings_s {
|
|
int iTCPSessMax;
|
|
int iTCPLstnMax;
|
|
int bSuppOctetFram;
|
|
int iStrmDrvrMode;
|
|
int bKeepAlive;
|
|
int iKeepAliveIntvl;
|
|
int iKeepAliveProbes;
|
|
int iKeepAliveTime;
|
|
int bEmitMsgOnClose;
|
|
int iAddtlFrameDelim;
|
|
int bDisableLFDelim;
|
|
int bUseFlowControl;
|
|
uchar *pszStrmDrvrAuthMode;
|
|
uchar *pszInputName;
|
|
uchar *pszBindRuleset;
|
|
} cs;
|
|
|
|
struct instanceConf_s {
|
|
uchar *pszBindPort; /* port to bind to */
|
|
uchar *pszBindRuleset; /* name of ruleset to bind to */
|
|
ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
|
|
uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
|
|
uchar *dfltTZ;
|
|
int ratelimitInterval;
|
|
int ratelimitBurst;
|
|
int bSuppOctetFram;
|
|
struct instanceConf_s *next;
|
|
};
|
|
|
|
|
|
struct modConfData_s {
|
|
rsconf_t *pConf; /* our overall config object */
|
|
instanceConf_t *root, *tail;
|
|
int iTCPSessMax; /* max number of sessions */
|
|
int iTCPLstnMax; /* max number of sessions */
|
|
int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
|
|
int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
|
|
int bSuppOctetFram;
|
|
sbool bDisableLFDelim; /* disable standard LF delimiter */
|
|
sbool bUseFlowControl; /* use flow control, what means indicate ourselfs a "light delayable" */
|
|
sbool bKeepAlive;
|
|
int iKeepAliveIntvl;
|
|
int iKeepAliveProbes;
|
|
int iKeepAliveTime;
|
|
sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */
|
|
uchar *pszStrmDrvrName; /* stream driver to use */
|
|
uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
|
|
struct cnfarray *permittedPeers;
|
|
sbool configSetViaV2Method;
|
|
};
|
|
|
|
static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
|
|
static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
|
|
|
|
/* module-global parameters */
|
|
static struct cnfparamdescr modpdescr[] = {
|
|
{ "flowcontrol", eCmdHdlrBinary, 0 },
|
|
{ "disablelfdelimiter", eCmdHdlrBinary, 0 },
|
|
{ "octetcountedframing", eCmdHdlrBinary, 0 },
|
|
{ "notifyonconnectionclose", eCmdHdlrBinary, 0 },
|
|
{ "addtlframedelimiter", eCmdHdlrNonNegInt, 0 },
|
|
{ "maxsessions", eCmdHdlrPositiveInt, 0 },
|
|
{ "maxlistners", eCmdHdlrPositiveInt, 0 },
|
|
{ "maxlisteners", eCmdHdlrPositiveInt, 0 },
|
|
{ "streamdriver.mode", eCmdHdlrPositiveInt, 0 },
|
|
{ "streamdriver.authmode", eCmdHdlrString, 0 },
|
|
{ "streamdriver.name", eCmdHdlrString, 0 },
|
|
{ "permittedpeer", eCmdHdlrArray, 0 },
|
|
{ "keepalive", eCmdHdlrBinary, 0 },
|
|
{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
|
|
{ "keepalive.time", eCmdHdlrPositiveInt, 0 },
|
|
{ "keepalive.interval", eCmdHdlrPositiveInt, 0 }
|
|
};
|
|
static struct cnfparamblk modpblk =
|
|
{ CNFPARAMBLK_VERSION,
|
|
sizeof(modpdescr)/sizeof(struct cnfparamdescr),
|
|
modpdescr
|
|
};
|
|
|
|
/* input instance parameters */
|
|
static struct cnfparamdescr inppdescr[] = {
|
|
{ "port", eCmdHdlrString, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */
|
|
{ "name", eCmdHdlrString, 0 },
|
|
{ "defaulttz", eCmdHdlrString, 0 },
|
|
{ "ruleset", eCmdHdlrString, 0 },
|
|
{ "supportoctetcountedframing", eCmdHdlrBinary, 0 },
|
|
{ "ratelimit.interval", eCmdHdlrInt, 0 },
|
|
{ "ratelimit.burst", eCmdHdlrInt, 0 }
|
|
};
|
|
static struct cnfparamblk inppblk =
|
|
{ CNFPARAMBLK_VERSION,
|
|
sizeof(inppdescr)/sizeof(struct cnfparamdescr),
|
|
inppdescr
|
|
};
|
|
|
|
#include "im-helper.h" /* must be included AFTER the type definitions! */
|
|
|
|
static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */
|
|
|
|
/* callbacks */
|
|
/* this shall go into a specific ACL module! */
|
|
static int
|
|
isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv,
|
|
void __attribute__((unused)) *pUsrSess)
|
|
{
|
|
return net.isAllowedSender2(UCHAR_CONSTANT("TCP"), addr, fromHostFQDN, 1);
|
|
}
|
|
|
|
|
|
static rsRetVal
|
|
doOpenLstnSocks(tcpsrv_t *pSrv)
|
|
{
|
|
ISOBJ_TYPE_assert(pSrv, tcpsrv);
|
|
return tcpsrv.create_tcp_socket(pSrv);
|
|
}
|
|
|
|
|
|
static rsRetVal
|
|
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd)
|
|
{
|
|
DEFiRet;
|
|
assert(pSess != NULL);
|
|
assert(piLenRcvd != NULL);
|
|
|
|
*piLenRcvd = lenBuf;
|
|
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd));
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
onRegularClose(tcps_sess_t *pSess)
|
|
{
|
|
DEFiRet;
|
|
assert(pSess != NULL);
|
|
|
|
/* process any incomplete frames left over */
|
|
tcps_sess.PrepareClose(pSess);
|
|
/* Session closed */
|
|
tcps_sess.Close(pSess);
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
static rsRetVal
|
|
onErrClose(tcps_sess_t *pSess)
|
|
{
|
|
DEFiRet;
|
|
assert(pSess != NULL);
|
|
|
|
tcps_sess.Close(pSess);
|
|
RETiRet;
|
|
}
|
|
|
|
/* ------------------------------ end callbacks ------------------------------ */
|
|
|
|
|
|
/* set permitted peer -- rgerhards, 2008-05-19
|
|
*/
|
|
static rsRetVal
|
|
setPermittedPeer(void __attribute__((unused)) *pVal, uchar *pszID)
|
|
{
|
|
DEFiRet;
|
|
CHKiRet(net.AddPermittedPeer(&pPermPeersRoot, pszID));
|
|
free(pszID); /* no longer needed, but we need to free as of interface def */
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* create input instance, set default paramters, and
|
|
* add it to the list of instances.
|
|
*/
|
|
static rsRetVal
|
|
createInstance(instanceConf_t **pinst)
|
|
{
|
|
instanceConf_t *inst;
|
|
DEFiRet;
|
|
CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
|
|
inst->next = NULL;
|
|
inst->pszBindRuleset = NULL;
|
|
inst->pszInputName = NULL;
|
|
inst->dfltTZ = NULL;
|
|
inst->bSuppOctetFram = -1; /* unset */
|
|
inst->ratelimitInterval = 0;
|
|
inst->ratelimitBurst = 10000;
|
|
|
|
/* node created, let's add to config */
|
|
if(loadModConf->tail == NULL) {
|
|
loadModConf->tail = loadModConf->root = inst;
|
|
} else {
|
|
loadModConf->tail->next = inst;
|
|
loadModConf->tail = inst;
|
|
}
|
|
|
|
*pinst = inst;
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* This function is called when a new listener instace shall be added to
|
|
* the current config object via the legacy config system. It just shuffles
|
|
* all parameters to the listener in-memory instance.
|
|
* rgerhards, 2011-05-04
|
|
*/
|
|
static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
|
|
{
|
|
instanceConf_t *inst;
|
|
DEFiRet;
|
|
|
|
CHKiRet(createInstance(&inst));
|
|
|
|
CHKmalloc(inst->pszBindPort = ustrdup((pNewVal == NULL || *pNewVal == '\0')
|
|
? (uchar*) "10514" : pNewVal));
|
|
if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
|
|
inst->pszBindRuleset = NULL;
|
|
} else {
|
|
CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset));
|
|
}
|
|
if((cs.pszInputName == NULL) || (cs.pszInputName[0] == '\0')) {
|
|
inst->pszInputName = NULL;
|
|
} else {
|
|
CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName));
|
|
}
|
|
inst->bSuppOctetFram = cs.bSuppOctetFram;
|
|
|
|
finalize_it:
|
|
free(pNewVal);
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
static rsRetVal
|
|
addListner(modConfData_t *modConf, instanceConf_t *inst)
|
|
{
|
|
DEFiRet;
|
|
|
|
if(pOurTcpsrv == NULL) {
|
|
CHKiRet(tcpsrv.Construct(&pOurTcpsrv));
|
|
/* callbacks */
|
|
CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost));
|
|
CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData));
|
|
CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks));
|
|
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
|
|
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
|
|
/* params */
|
|
CHKiRet(tcpsrv.SetKeepAlive(pOurTcpsrv, modConf->bKeepAlive));
|
|
CHKiRet(tcpsrv.SetKeepAliveIntvl(pOurTcpsrv, modConf->iKeepAliveIntvl));
|
|
CHKiRet(tcpsrv.SetKeepAliveProbes(pOurTcpsrv, modConf->iKeepAliveProbes));
|
|
CHKiRet(tcpsrv.SetKeepAliveTime(pOurTcpsrv, modConf->iKeepAliveTime));
|
|
CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax));
|
|
CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax));
|
|
CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode));
|
|
CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, modConf->bUseFlowControl));
|
|
CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, modConf->iAddtlFrameDelim));
|
|
CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, modConf->bDisableLFDelim));
|
|
CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, modConf->bEmitMsgOnClose));
|
|
/* now set optional params, but only if they were actually configured */
|
|
if(modConf->pszStrmDrvrName != NULL) {
|
|
CHKiRet(tcpsrv.SetDrvrName(pOurTcpsrv, modConf->pszStrmDrvrName));
|
|
}
|
|
if(modConf->pszStrmDrvrAuthMode != NULL) {
|
|
CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, modConf->pszStrmDrvrAuthMode));
|
|
}
|
|
if(pPermPeersRoot != NULL) {
|
|
CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
|
|
}
|
|
}
|
|
|
|
/* initialized, now add socket and listener params */
|
|
DBGPRINTF("imtcp: trying to add port *:%s\n", inst->pszBindPort);
|
|
CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, inst->pBindRuleset));
|
|
CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->pszInputName == NULL ?
|
|
UCHAR_CONSTANT("imtcp") : inst->pszInputName));
|
|
CHKiRet(tcpsrv.SetOrigin(pOurTcpsrv, (uchar*)"imtcp"));
|
|
CHKiRet(tcpsrv.SetDfltTZ(pOurTcpsrv, (inst->dfltTZ == NULL) ? (uchar*)"" : inst->dfltTZ));
|
|
CHKiRet(tcpsrv.SetLinuxLikeRatelimiters(pOurTcpsrv, inst->ratelimitInterval, inst->ratelimitBurst));
|
|
tcpsrv.configureTCPListen(pOurTcpsrv, inst->pszBindPort, inst->bSuppOctetFram);
|
|
|
|
finalize_it:
|
|
if(iRet != RS_RET_OK) {
|
|
errmsg.LogError(0, NO_ERRCODE, "imtcp: error %d trying to add listener", iRet);
|
|
}
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
BEGINnewInpInst
|
|
struct cnfparamvals *pvals;
|
|
instanceConf_t *inst;
|
|
int i;
|
|
CODESTARTnewInpInst
|
|
DBGPRINTF("newInpInst (imtcp)\n");
|
|
|
|
pvals = nvlstGetParams(lst, &inppblk, NULL);
|
|
if(pvals == NULL) {
|
|
errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS,
|
|
"imtcp: required parameter are missing\n");
|
|
ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
|
|
}
|
|
|
|
if(Debug) {
|
|
dbgprintf("input param blk in imtcp:\n");
|
|
cnfparamsPrint(&inppblk, pvals);
|
|
}
|
|
|
|
CHKiRet(createInstance(&inst));
|
|
|
|
for(i = 0 ; i < inppblk.nParams ; ++i) {
|
|
if(!pvals[i].bUsed)
|
|
continue;
|
|
if(!strcmp(inppblk.descr[i].name, "port")) {
|
|
inst->pszBindPort = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(inppblk.descr[i].name, "name")) {
|
|
inst->pszInputName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(inppblk.descr[i].name, "defaulttz")) {
|
|
inst->dfltTZ = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(inppblk.descr[i].name, "ruleset")) {
|
|
inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(inppblk.descr[i].name, "supportoctetcountedframing")) {
|
|
inst->bSuppOctetFram = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(inppblk.descr[i].name, "ratelimit.burst")) {
|
|
inst->ratelimitBurst = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(inppblk.descr[i].name, "ratelimit.interval")) {
|
|
inst->ratelimitInterval = (int) pvals[i].val.d.n;
|
|
} else {
|
|
dbgprintf("imtcp: program error, non-handled "
|
|
"param '%s'\n", inppblk.descr[i].name);
|
|
}
|
|
}
|
|
finalize_it:
|
|
CODE_STD_FINALIZERnewInpInst
|
|
cnfparamvalsDestruct(pvals, &inppblk);
|
|
ENDnewInpInst
|
|
|
|
|
|
BEGINbeginCnfLoad
|
|
CODESTARTbeginCnfLoad
|
|
loadModConf = pModConf;
|
|
pModConf->pConf = pConf;
|
|
/* init our settings */
|
|
loadModConf->iTCPSessMax = 200;
|
|
loadModConf->iTCPLstnMax = 20;
|
|
loadModConf->bSuppOctetFram = 1;
|
|
loadModConf->iStrmDrvrMode = 0;
|
|
loadModConf->bUseFlowControl = 1;
|
|
loadModConf->bKeepAlive = 0;
|
|
loadModConf->iKeepAliveIntvl = 0;
|
|
loadModConf->iKeepAliveProbes = 0;
|
|
loadModConf->iKeepAliveTime = 0;
|
|
loadModConf->bEmitMsgOnClose = 0;
|
|
loadModConf->iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
|
|
loadModConf->bDisableLFDelim = 0;
|
|
loadModConf->pszStrmDrvrName = NULL;
|
|
loadModConf->pszStrmDrvrAuthMode = NULL;
|
|
loadModConf->permittedPeers = NULL;
|
|
loadModConf->configSetViaV2Method = 0;
|
|
bLegacyCnfModGlobalsPermitted = 1;
|
|
/* init legacy config variables */
|
|
cs.pszStrmDrvrAuthMode = NULL;
|
|
resetConfigVariables(NULL, NULL); /* dummy parameters just to fulfill interface def */
|
|
ENDbeginCnfLoad
|
|
|
|
|
|
BEGINsetModCnf
|
|
struct cnfparamvals *pvals = NULL;
|
|
int i;
|
|
CODESTARTsetModCnf
|
|
pvals = nvlstGetParams(lst, &modpblk, NULL);
|
|
if(pvals == NULL) {
|
|
errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS, "imtcp: error processing module "
|
|
"config parameters [module(...)]");
|
|
ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
|
|
}
|
|
|
|
if(Debug) {
|
|
dbgprintf("module (global) param blk for imtcp:\n");
|
|
cnfparamsPrint(&modpblk, pvals);
|
|
}
|
|
|
|
for(i = 0 ; i < modpblk.nParams ; ++i) {
|
|
if(!pvals[i].bUsed)
|
|
continue;
|
|
if(!strcmp(modpblk.descr[i].name, "flowcontrol")) {
|
|
loadModConf->bUseFlowControl = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "disablelfdelimiter")) {
|
|
loadModConf->bDisableLFDelim = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "octetcountedframing")) {
|
|
loadModConf->bSuppOctetFram = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "notifyonconnectionclose")) {
|
|
loadModConf->bEmitMsgOnClose = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "addtlframedelimiter")) {
|
|
loadModConf->iAddtlFrameDelim = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "maxsessions")) {
|
|
loadModConf->iTCPSessMax = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "maxlisteners") ||
|
|
!strcmp(modpblk.descr[i].name, "maxlistners")) { /* keep old name for a while */
|
|
loadModConf->iTCPLstnMax = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "keepalive")) {
|
|
loadModConf->bKeepAlive = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "keepalive.probes")) {
|
|
loadModConf->iKeepAliveProbes = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "keepalive.time")) {
|
|
loadModConf->iKeepAliveTime = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "keepalive.interval")) {
|
|
loadModConf->iKeepAliveIntvl = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.mode")) {
|
|
loadModConf->iStrmDrvrMode = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.authmode")) {
|
|
loadModConf->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.name")) {
|
|
loadModConf->pszStrmDrvrName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(modpblk.descr[i].name, "permittedpeer")) {
|
|
loadModConf->permittedPeers = cnfarrayDup(pvals[i].val.d.ar);
|
|
} else {
|
|
dbgprintf("imtcp: program error, non-handled "
|
|
"param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
|
|
}
|
|
}
|
|
|
|
/* remove all of our legacy handlers, as they can not used in addition
|
|
* the the new-style config method.
|
|
*/
|
|
bLegacyCnfModGlobalsPermitted = 0;
|
|
loadModConf->configSetViaV2Method = 1;
|
|
|
|
finalize_it:
|
|
if(pvals != NULL)
|
|
cnfparamvalsDestruct(pvals, &modpblk);
|
|
ENDsetModCnf
|
|
|
|
|
|
BEGINendCnfLoad
|
|
CODESTARTendCnfLoad
|
|
if(!loadModConf->configSetViaV2Method) {
|
|
/* persist module-specific settings from legacy config system */
|
|
pModConf->iTCPSessMax = cs.iTCPSessMax;
|
|
pModConf->iTCPLstnMax = cs.iTCPLstnMax;
|
|
pModConf->iStrmDrvrMode = cs.iStrmDrvrMode;
|
|
pModConf->bEmitMsgOnClose = cs.bEmitMsgOnClose;
|
|
pModConf->bSuppOctetFram = cs.bSuppOctetFram;
|
|
pModConf->iAddtlFrameDelim = cs.iAddtlFrameDelim;
|
|
pModConf->bDisableLFDelim = cs.bDisableLFDelim;
|
|
pModConf->bUseFlowControl = cs.bUseFlowControl;
|
|
pModConf->bKeepAlive = cs.bKeepAlive;
|
|
pModConf->iKeepAliveProbes = cs.iKeepAliveProbes;
|
|
pModConf->iKeepAliveIntvl = cs.iKeepAliveIntvl;
|
|
pModConf->iKeepAliveTime = cs.iKeepAliveTime;
|
|
if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) {
|
|
loadModConf->pszStrmDrvrAuthMode = NULL;
|
|
} else {
|
|
loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode;
|
|
cs.pszStrmDrvrAuthMode = NULL;
|
|
}
|
|
}
|
|
free(cs.pszStrmDrvrAuthMode);
|
|
cs.pszStrmDrvrAuthMode = NULL;
|
|
|
|
loadModConf = NULL; /* done loading */
|
|
ENDendCnfLoad
|
|
|
|
|
|
/* function to generate error message if framework does not find requested ruleset */
|
|
static inline void
|
|
std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst)
|
|
{
|
|
errmsg.LogError(0, NO_ERRCODE, "imtcp: ruleset '%s' for port %s not found - "
|
|
"using default ruleset instead", inst->pszBindRuleset,
|
|
inst->pszBindPort);
|
|
}
|
|
|
|
BEGINcheckCnf
|
|
instanceConf_t *inst;
|
|
CODESTARTcheckCnf
|
|
for(inst = pModConf->root ; inst != NULL ; inst = inst->next) {
|
|
std_checkRuleset(pModConf, inst);
|
|
if(inst->bSuppOctetFram == FRAMING_UNSET)
|
|
inst->bSuppOctetFram = pModConf->bSuppOctetFram;
|
|
}
|
|
if(pModConf->root == NULL) {
|
|
errmsg.LogError(0, RS_RET_NO_LISTNERS , "imtcp: module loaded, but "
|
|
"no listeners defined - no input will be gathered");
|
|
iRet = RS_RET_NO_LISTNERS;
|
|
}
|
|
ENDcheckCnf
|
|
|
|
|
|
BEGINactivateCnfPrePrivDrop
|
|
instanceConf_t *inst;
|
|
int i;
|
|
CODESTARTactivateCnfPrePrivDrop
|
|
runModConf = pModConf;
|
|
if(runModConf->permittedPeers != NULL) {
|
|
for(i = 0 ; i < runModConf->permittedPeers->nmemb ; ++i) {
|
|
setPermittedPeer(NULL, (uchar*)
|
|
es_str2cstr(runModConf->permittedPeers->arr[i], NULL));
|
|
}
|
|
}
|
|
for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
|
|
addListner(pModConf, inst);
|
|
}
|
|
if(pOurTcpsrv == NULL)
|
|
ABORT_FINALIZE(RS_RET_NO_RUN);
|
|
CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
|
|
finalize_it:
|
|
ENDactivateCnfPrePrivDrop
|
|
|
|
|
|
BEGINactivateCnf
|
|
CODESTARTactivateCnf
|
|
/* sorry, nothing to do here... */
|
|
ENDactivateCnf
|
|
|
|
|
|
BEGINfreeCnf
|
|
instanceConf_t *inst, *del;
|
|
CODESTARTfreeCnf
|
|
free(pModConf->pszStrmDrvrName);
|
|
free(pModConf->pszStrmDrvrAuthMode);
|
|
if(pModConf->permittedPeers != NULL) {
|
|
cnfarrayContentDestruct(pModConf->permittedPeers);
|
|
free(pModConf->permittedPeers);
|
|
}
|
|
for(inst = pModConf->root ; inst != NULL ; ) {
|
|
free(inst->pszBindPort);
|
|
free(inst->pszInputName);
|
|
free(inst->dfltTZ);
|
|
del = inst;
|
|
inst = inst->next;
|
|
free(del);
|
|
}
|
|
ENDfreeCnf
|
|
|
|
/* This function is called to gather input.
|
|
*/
|
|
BEGINrunInput
|
|
CODESTARTrunInput
|
|
iRet = tcpsrv.Run(pOurTcpsrv);
|
|
ENDrunInput
|
|
|
|
|
|
/* initialize and return if will run or not */
|
|
BEGINwillRun
|
|
CODESTARTwillRun
|
|
net.PrintAllowedSenders(2); /* TCP */
|
|
ENDwillRun
|
|
|
|
|
|
BEGINafterRun
|
|
CODESTARTafterRun
|
|
if(pOurTcpsrv != NULL)
|
|
iRet = tcpsrv.Destruct(&pOurTcpsrv);
|
|
|
|
net.clearAllowedSenders(UCHAR_CONSTANT("TCP"));
|
|
ENDafterRun
|
|
|
|
|
|
BEGINisCompatibleWithFeature
|
|
CODESTARTisCompatibleWithFeature
|
|
if(eFeat == sFEATURENonCancelInputTermination)
|
|
iRet = RS_RET_OK;
|
|
ENDisCompatibleWithFeature
|
|
|
|
|
|
BEGINmodExit
|
|
CODESTARTmodExit
|
|
if(pPermPeersRoot != NULL) {
|
|
net.DestructPermittedPeers(&pPermPeersRoot);
|
|
}
|
|
|
|
/* release objects we used */
|
|
objRelease(net, LM_NET_FILENAME);
|
|
objRelease(netstrm, LM_NETSTRMS_FILENAME);
|
|
objRelease(tcps_sess, LM_TCPSRV_FILENAME);
|
|
objRelease(tcpsrv, LM_TCPSRV_FILENAME);
|
|
objRelease(errmsg, CORE_COMPONENT);
|
|
objRelease(ruleset, CORE_COMPONENT);
|
|
ENDmodExit
|
|
|
|
|
|
static rsRetVal
|
|
resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
|
|
{
|
|
cs.iTCPSessMax = 200;
|
|
cs.iTCPLstnMax = 20;
|
|
cs.bSuppOctetFram = 1;
|
|
cs.iStrmDrvrMode = 0;
|
|
cs.bUseFlowControl = 1;
|
|
cs.bKeepAlive = 0;
|
|
cs.iKeepAliveProbes = 0;
|
|
cs.iKeepAliveTime = 0;
|
|
cs.iKeepAliveIntvl = 0;
|
|
cs.bEmitMsgOnClose = 0;
|
|
cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
|
|
cs.bDisableLFDelim = 0;
|
|
free(cs.pszInputName);
|
|
cs.pszInputName = NULL;
|
|
free(cs.pszStrmDrvrAuthMode);
|
|
cs.pszStrmDrvrAuthMode = NULL;
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
|
|
|
|
BEGINqueryEtryPt
|
|
CODESTARTqueryEtryPt
|
|
CODEqueryEtryPt_STD_IMOD_QUERIES
|
|
CODEqueryEtryPt_STD_CONF2_QUERIES
|
|
CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
|
|
CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
|
|
CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES
|
|
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
|
|
ENDqueryEtryPt
|
|
|
|
|
|
BEGINmodInit()
|
|
CODESTARTmodInit
|
|
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
|
|
CODEmodInit_QueryRegCFSLineHdlr
|
|
pOurTcpsrv = NULL;
|
|
/* request objects we use */
|
|
CHKiRet(objUse(net, LM_NET_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));
|
|
CHKiRet(objUse(ruleset, CORE_COMPONENT));
|
|
|
|
/* register config file handlers */
|
|
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord,
|
|
addInstance, NULL, STD_LOADABLE_MODULE_ID));
|
|
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord,
|
|
NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID));
|
|
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, eCmdHdlrGetWord,
|
|
NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID));
|
|
/* module-global config params - will be disabled in configs that are loaded
|
|
* via module(...).
|
|
*/
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord,
|
|
setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord,
|
|
NULL, &cs.pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary,
|
|
NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverkeepalive_probes"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iKeepAliveProbes, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverkeepalive_intvl"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iKeepAliveTime, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverkeepalive_time"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iKeepAliveIntvl, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, eCmdHdlrBinary,
|
|
NULL, &cs.bUseFlowControl, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary,
|
|
NULL, &cs.bDisableLFDelim, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary,
|
|
NULL, &cs.bSuppOctetFram, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iTCPSessMax, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iTCPLstnMax, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, eCmdHdlrBinary,
|
|
NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt,
|
|
NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
|
|
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
|
|
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
|
|
ENDmodInit
|
|
|
|
/* vim:set ai:
|
|
*/
|