作者:DooDleZz
项目:rsyslo
/* Prepare a module for unloading.
* This is currently a dummy, to be filled when we have a plug-in
* interface - rgerhards, 2007-08-09
* rgerhards, 2007-11-21:
* When this function is called, all instance-data must already have
* been destroyed. In the case of output modules, this happens when the
* rule set is being destroyed. When we implement other module types, we
* need to think how we handle it there (and if we have any instance data).
* rgerhards, 2008-03-10: reject unload request if the module has a reference
* count > 0.
*/
static rsRetVal
modPrepareUnload(modInfo_t *pThis)
{
DEFiRet;
void *pModCookie;
assert(pThis != NULL);
if(pThis->uRefCnt > 0) {
dbgprintf("rejecting unload of module '%s' because it has a refcount of %d\n",
pThis->pszName, pThis->uRefCnt);
ABORT_FINALIZE(RS_RET_MODULE_STILL_REFERENCED);
}
CHKiRet(pThis->modGetID(&pModCookie));
pThis->modExit(); /* tell the module to get ready for unload */
CHKiRet(unregCfSysLineHdlrs4Owner(pModCookie));
finalize_it:
RETiRet;
}
作者:vii5ar
项目:rsyslo
/* sets the correct allow root pointer based on provided type
* rgerhards, 2008-12-01
*/
static rsRetVal
setAllowRoot(struct AllowedSenders **ppAllowRoot, uchar *pszType)
{
DEFiRet;
if(!strcmp((char*)pszType, "UDP"))
*ppAllowRoot = pAllowedSenders_UDP;
else if(!strcmp((char*)pszType, "TCP"))
*ppAllowRoot = pAllowedSenders_TCP;
#ifdef USE_GSSAPI
else if(!strcmp((char*)pszType, "GSS"))
*ppAllowRoot = pAllowedSenders_GSS;
#endif
else {
dbgprintf("program error: invalid allowed sender ID '%s', denying...\n", pszType);
ABORT_FINALIZE(RS_RET_CODE_ERR); /* everything is invalid for an invalid type */
}
finalize_it:
RETiRet;
}
作者:Whiss
项目:rsyslo
/* add a counter to an object
* ctrName is duplicated, caller must free it if requried
* NOTE: The counter is READ-ONLY and MUST NOT be modified (most
* importantly, it must not be initialized, so the caller must
* ensure the counter is properly initialized before AddCounter()
* is called.
*/
static rsRetVal
addManagedCounter(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags, void *pCtr,
ctr_t **entryRef, int8_t linked)
{
ctr_t *ctr;
DEFiRet;
*entryRef = NULL;
CHKmalloc(ctr = calloc(1, sizeof(ctr_t)));
ctr->next = NULL;
ctr->prev = NULL;
if((ctr->name = ustrdup(ctrName)) == NULL) {
DBGPRINTF("addCounter: OOM in strdup()\n");
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
ctr->flags = flags;
ctr->ctrType = ctrType;
switch(ctrType) {
case ctrType_IntCtr:
ctr->val.pIntCtr = (intctr_t*) pCtr;
break;
case ctrType_Int:
ctr->val.pInt = (int*) pCtr;
break;
}
if (linked) {
addCtrToList(pThis, ctr);
}
*entryRef = ctr;
finalize_it:
if (iRet != RS_RET_OK) {
if (ctr != NULL) {
free(ctr->name);
free(ctr);
}
}
RETiRet;
}
作者:janmeja
项目:rsyslo
static rsRetVal
doLastMessageRepeatedNTimes(ratelimit_t *ratelimit, smsg_t *pMsg, smsg_t **ppRepMsg)
{
int bNeedUnlockMutex = 0;
DEFiRet;
if(ratelimit->bThreadSafe) {
pthread_mutex_lock(&ratelimit->mut);
bNeedUnlockMutex = 1;
}
if( ratelimit->pMsg != NULL &&
getMSGLen(pMsg) == getMSGLen(ratelimit->pMsg) &&
!ustrcmp(getMSG(pMsg), getMSG(ratelimit->pMsg)) &&
!strcmp(getHOSTNAME(pMsg), getHOSTNAME(ratelimit->pMsg)) &&
!strcmp(getPROCID(pMsg, LOCK_MUTEX), getPROCID(ratelimit->pMsg, LOCK_MUTEX)) &&
!strcmp(getAPPNAME(pMsg, LOCK_MUTEX), getAPPNAME(ratelimit->pMsg, LOCK_MUTEX))) {
ratelimit->nsupp++;
DBGPRINTF("msg repeated %d times\n", ratelimit->nsupp);
/* use current message, so we have the new timestamp
* (means we need to discard previous one) */
msgDestruct(&ratelimit->pMsg);
ratelimit->pMsg = pMsg;
ABORT_FINALIZE(RS_RET_DISCARDMSG);
} else {/* new message, do "repeat processing" & save it */
if(ratelimit->pMsg != NULL) {
if(ratelimit->nsupp > 0) {
*ppRepMsg = ratelimitGenRepMsg(ratelimit);
ratelimit->nsupp = 0;
}
msgDestruct(&ratelimit->pMsg);
}
ratelimit->pMsg = MsgAddRef(pMsg);
}
finalize_it:
if(bNeedUnlockMutex)
pthread_mutex_unlock(&ratelimit->mut);
RETiRet;
}
作者:madedotco
项目:rsyslo
/* init function (must be called once) */
rsRetVal
dnscacheInit(void)
{
DEFiRet;
if((dnsCache.ht = create_hashtable(100, hash_from_key_fn, key_equals_fn,
(void(*)(void*))entryDestruct)) == NULL) {
DBGPRINTF("dnscache: error creating hash table!\n");
ABORT_FINALIZE(RS_RET_ERR); // TODO: make this degrade, but run!
}
dnsCache.nEntries = 0;
pthread_rwlock_init(&dnsCache.rwlock, NULL);
CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(prop, CORE_COMPONENT));
prop.Construct(&staticErrValue);
prop.SetString(staticErrValue, (uchar*)"???", 3);
prop.ConstructFinalize(staticErrValue);
finalize_it:
RETiRet;
}
作者:JosephGreg
项目:rsyslo
/* TODO: handle multiple blocks
* test-read END record; if present, store offset, else unbounded (current active block)
* when decrypting, check if bound is reached. If yes, split into two blocks, get new IV for
* second one.
*/
rsRetVal
rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len)
{
gcry_error_t gcryError;
DEFiRet;
if(pF->bytesToBlkEnd != -1)
pF->bytesToBlkEnd -= *len;
gcryError = gcry_cipher_decrypt(pF->chd, buf, *len, NULL, 0);
if(gcryError) {
DBGPRINTF("gcry_cipher_decrypt failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
ABORT_FINALIZE(RS_RET_ERR);
}
removePadding(buf, len);
// TODO: remove dbgprintf once things are sufficently stable -- rgerhards, 2013-05-16
dbgprintf("libgcry: decrypted, bytesToBlkEnd %lld, buffer is now '%50.50s'\n", (long long) pF->bytesToBlkEnd, buf);
finalize_it:
RETiRet;
}
作者:vii5ar
项目:rsyslo
/* Problem with the warnings: they seem to stem back from the way the API is structured */
static rsRetVal
getIFIPAddr(uchar *szif, int family, uchar *pszbuf, int lenBuf)
{
struct ifaddrs * ifaddrs = NULL;
struct ifaddrs * ifa;
void * pAddr;
DEFiRet;
if(getifaddrs(&ifaddrs) != 0) {
ABORT_FINALIZE(RS_RET_ERR);
}
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if(strcmp(ifa->ifa_name, (char*)szif))
continue;
if( (family == AF_INET6 || family == AF_UNSPEC)
&& ifa->ifa_addr->sa_family == AF_INET6) {
pAddr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
inet_ntop(AF_INET6, pAddr, (char*)pszbuf, lenBuf);
break;
} else if(/* (family == AF_INET || family == AF_UNSPEC)
&&*/ ifa->ifa_addr->sa_family == AF_INET) {
pAddr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
inet_ntop(AF_INET, pAddr, (char*)pszbuf, lenBuf);
break;
}
}
if(ifaddrs != NULL)
freeifaddrs(ifaddrs);
if(ifa == NULL)
iRet = RS_RET_NOT_FOUND;
finalize_it:
RETiRet;
}
作者:TheodoreLizar
项目:rsyslo
/* construct from CStr object. only the counted string is
* copied, not the szString.
* rgerhards 2005-10-18
*/
rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, cstr_t *pFrom)
{
DEFiRet;
cstr_t *pThis;
assert(ppThis != NULL);
rsCHECKVALIDOBJECT(pFrom, OIDrsCStr);
CHKiRet(rsCStrConstruct(&pThis));
pThis->iBufSize = pThis->iStrLen = pFrom->iStrLen;
if((pThis->pBuf = (uchar*) MALLOC(sizeof(uchar) * pThis->iStrLen)) == NULL) {
RSFREEOBJ(pThis);
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
/* copy properties */
memcpy(pThis->pBuf, pFrom->pBuf, pThis->iStrLen);
*ppThis = pThis;
finalize_it:
RETiRet;
}
作者:TheodoreLizar
项目:rsyslo
/* construct from sz string
* rgerhards 2005-09-15
*/
rsRetVal rsCStrConstructFromszStr(cstr_t **ppThis, uchar *sz)
{
DEFiRet;
cstr_t *pThis;
assert(ppThis != NULL);
CHKiRet(rsCStrConstruct(&pThis));
pThis->iBufSize = pThis->iStrLen = strlen((char *) sz);
if((pThis->pBuf = (uchar*) MALLOC(sizeof(uchar) * pThis->iStrLen)) == NULL) {
RSFREEOBJ(pThis);
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
/* we do NOT need to copy the \0! */
memcpy(pThis->pBuf, sz, pThis->iStrLen);
*ppThis = pThis;
finalize_it:
RETiRet;
}
作者:JosephGreg
项目:rsyslo
eiWriteIV(gcryfile gf, const uchar *const iv)
{
static const char hexchars[16] =
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
unsigned iSrc, iDst;
char hex[4096];
DEFiRet;
if(gf->blkLength > sizeof(hex)/2) {
DBGPRINTF("eiWriteIV: crypto block len way too large, aborting "
"write");
ABORT_FINALIZE(RS_RET_ERR);
}
for(iSrc = iDst = 0 ; iSrc < gf->blkLength ; ++iSrc) {
hex[iDst++] = hexchars[iv[iSrc]>>4];
hex[iDst++] = hexchars[iv[iSrc]&0x0f];
}
iRet = eiWriteRec(gf, "IV:", 3, hex, gf->blkLength*2);
finalize_it:
RETiRet;
}
作者:DooDleZz
项目:rsyslo
/* find a function inside the function registry
* The caller provides a cstr_t with the function name and receives
* a function pointer back. If no function is found, an RS_RET_UNKNW_FUNC
* error is returned. So if the function returns with RS_RET_OK, the caller
* can savely assume the function pointer is valid.
* rgerhards, 2009-04-06
*/
static rsRetVal
findRSFunction(cstr_t *pcsName, prsf_t *prsf)
{
rsf_entry_t *pEntry;
rsf_entry_t *pFound;
DEFiRet;
assert(prsf != NULL);
/* find function by list walkthrough. */
pFound = NULL;
for(pEntry = funcRegRoot ; pEntry != NULL && pFound == NULL ; pEntry = pEntry->pNext)
if(!rsCStrCStrCmp(pEntry->pName, pcsName))
pFound = pEntry;
if(pFound == NULL)
ABORT_FINALIZE(RS_RET_UNKNW_FUNC);
*prsf = pFound->rsf;
finalize_it:
RETiRet;
}
作者:JosephGreg
项目:rsyslo
/* construct from es_str_t string
* rgerhards 2010-12-03
*/
rsRetVal
cstrConstructFromESStr(cstr_t **ppThis, es_str_t *str)
{
DEFiRet;
cstr_t *pThis;
CHKiRet(rsCStrConstruct(&pThis));
pThis->iStrLen = es_strlen(str);
pThis->iBufSize = pThis->iStrLen + 1;
if((pThis->pBuf = (uchar*) MALLOC(pThis->iBufSize)) == NULL) {
RSFREEOBJ(pThis);
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
/* we do NOT need to copy the \0! */
memcpy(pThis->pBuf, es_getBufAddr(str), pThis->iStrLen);
*ppThis = pThis;
finalize_it:
RETiRet;
}
作者:Werko
项目:rsyslo
/* extract a username and return its uid.
* rgerhards, 2007-07-17
*/
static rsRetVal doGetUID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
{
struct passwd *ppwBuf;
struct passwd pwBuf;
DEFiRet;
uchar szName[256];
char stringBuf[2048]; /* I hope this is large enough... */
assert(pp != NULL);
assert(*pp != NULL);
if(getSubString(pp, (char*) szName, sizeof(szName), ' ') != 0) {
errmsg.LogError(0, RS_RET_NOT_FOUND, "could not extract user name");
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
getpwnam_r((char*)szName, &pwBuf, stringBuf, sizeof(stringBuf), &ppwBuf);
if(ppwBuf == NULL) {
errmsg.LogError(0, RS_RET_NOT_FOUND, "ID for user '%s' could not be found or error", (char*)szName);
iRet = RS_RET_NOT_FOUND;
} else {
if(pSetHdlr == NULL) {
/* we should set value directly to var */
*((uid_t*)pVal) = ppwBuf->pw_uid;
} else {
/* we set value via a set function */
CHKiRet(pSetHdlr(pVal, ppwBuf->pw_uid));
}
dbgprintf("uid %d obtained for user '%s'\n", (int) ppwBuf->pw_uid, szName);
}
skipWhiteSpace(pp); /* skip over any whitespace */
finalize_it:
RETiRet;
}
作者:methodmissin
项目:librel
/** Construct a RELP sess instance
* the pSrv parameter may be set to NULL if the session object is for a client.
*/
relpRetVal
relpSessConstruct(relpSess_t **ppThis, relpEngine_t *pEngine, relpSrv_t *pSrv)
{
relpSess_t *pThis;
ENTER_RELPFUNC;
assert(ppThis != NULL);
RELPOBJ_assert(pEngine, Engine);
if((pThis = calloc(1, sizeof(relpSess_t))) == NULL) {
ABORT_FINALIZE(RELP_RET_OUT_OF_MEMORY);
}
RELP_CORE_CONSTRUCTOR(pThis, Sess);
pThis->pEngine = pEngine;
/* use Engine's command enablement states as default */
pThis->stateCmdSyslog = pEngine->stateCmdSyslog;
pThis->pSrv = pSrv;
pThis->txnr = 1; /* txnr start at 1 according to spec */
pThis->timeout = 10; /* TODO: make configurable */
pThis->sizeWindow = RELP_DFLT_WINDOW_SIZE; /* TODO: make configurable */
pThis->maxDataSize = RELP_DFLT_MAX_DATA_SIZE;
CHKRet(relpSendqConstruct(&pThis->pSendq, pThis->pEngine));
pthread_mutex_init(&pThis->mutSend, NULL);
*ppThis = pThis;
finalize_it:
if(iRet != RELP_RET_OK) {
if(pThis != NULL) {
relpSessDestruct(&pThis);
}
}
LEAVE_RELPFUNC;
}
作者:daemon1
项目:rsyslo
/* The following function writes the current log entry
* to an established database connection.
*/
rsRetVal writeDB(uchar *psz, instanceData *pData)
{
DEFiRet;
dbi_result dbiRes = NULL;
ASSERT(psz != NULL);
ASSERT(pData != NULL);
/* see if we are ready to proceed */
if(pData->conn == NULL) {
CHKiRet(initConn(pData, 0));
}
/* try insert */
if((dbiRes = dbi_conn_query(pData->conn, (const char*)psz)) == NULL) {
/* error occured, try to re-init connection and retry */
closeConn(pData); /* close the current handle */
CHKiRet(initConn(pData, 0)); /* try to re-open */
if((dbiRes = dbi_conn_query(pData->conn, (const char*)psz)) == NULL) { /* re-try insert */
/* we failed, giving up for now */
reportDBError(pData, 0);
closeConn(pData); /* free ressources */
ABORT_FINALIZE(RS_RET_SUSPENDED);
}
}
finalize_it:
if(iRet == RS_RET_OK) {
pData->uLastDBErrno = 0; /* reset error for error supression */
}
if(dbiRes != NULL)
dbi_result_free(dbiRes);
RETiRet;
}
作者:JosephGreg
项目:rsyslo
/* llDestroyRootElt - destroy the root element but otherwise
* keeps this list intact. -- rgerhards, 2007-08-03
*/
rsRetVal llDestroyRootElt(linkedList_t *pThis)
{
DEFiRet;
llElt_t *pPrev;
if(pThis->pRoot == NULL) {
ABORT_FINALIZE(RS_RET_EMPTY_LIST);
}
pPrev = pThis->pRoot;
if(pPrev->pNext == NULL) {
/* it was the only list element */
pThis->pLast = NULL;
pThis->pRoot = NULL;
} else {
/* there are other list elements */
pThis->pRoot = pPrev->pNext;
}
CHKiRet(llDestroyElt(pThis, pPrev));
finalize_it:
RETiRet;
}
作者:schiel
项目:rsyslo
rsRetVal
lookupProcessCnf(struct cnfobj *o)
{
struct cnfparamvals *pvals;
lookup_t *lu;
short i;
DEFiRet;
pvals = nvlstGetParams(o->nvlst, &modpblk, NULL);
if(pvals == NULL) {
ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
}
DBGPRINTF("lookupProcessCnf params:\n");
cnfparamsPrint(&modpblk, pvals);
CHKiRet(lookupNew(&lu));
for(i = 0 ; i < modpblk.nParams ; ++i) {
if(!pvals[i].bUsed)
continue;
if(!strcmp(modpblk.descr[i].name, "file")) {
CHKmalloc(lu->filename = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL));
} else if(!strcmp(modpblk.descr[i].name, "name")) {
CHKmalloc(lu->name = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL));
} else {
dbgprintf("lookup_table: program error, non-handled "
"param '%s'\n", modpblk.descr[i].name);
}
}
CHKiRet(lookupReadFile(lu));
DBGPRINTF("lookup table '%s' loaded from file '%s'\n", lu->name, lu->filename);
finalize_it:
cnfparamvalsDestruct(pvals, &modpblk);
RETiRet;
}
作者:adruc
项目:rsyslo
static inline rsRetVal
RunSelect(tcpsrv_t *pThis, nsd_epworkset_t workset[], size_t sizeWorkset)
{
DEFiRet;
int nfds;
int i;
int iWorkset;
int iTCPSess;
int bIsReady;
nssel_t *pSel = NULL;
rsRetVal localRet;
ISOBJ_TYPE_assert(pThis, tcpsrv);
/* this is an endless loop - it is terminated by the framework canelling
* this thread. Thus, we also need to instantiate a cancel cleanup handler
* to prevent us from leaking anything. -- rgerhards, 20080-04-24
*/
pthread_cleanup_push(RunCancelCleanup, (void*) &pSel);
while(1) {
CHKiRet(nssel.Construct(&pSel));
if(pThis->pszDrvrName != NULL)
CHKiRet(nssel.SetDrvrName(pSel, pThis->pszDrvrName));
CHKiRet(nssel.ConstructFinalize(pSel));
/* Add the TCP listen sockets to the list of read descriptors. */
for(i = 0 ; i < pThis->iLstnCurr ; ++i) {
CHKiRet(nssel.Add(pSel, pThis->ppLstn[i], NSDSEL_RD));
}
/* do the sessions */
iTCPSess = TCPSessGetNxtSess(pThis, -1);
while(iTCPSess != -1) {
/* TODO: access to pNsd is NOT really CLEAN, use method... */
CHKiRet(nssel.Add(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD));
/* now get next... */
iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
}
/* wait for io to become ready */
CHKiRet(nssel.Wait(pSel, &nfds));
if(glbl.GetGlobalInputTermState() == 1)
break; /* terminate input! */
iWorkset = 0;
for(i = 0 ; i < pThis->iLstnCurr ; ++i) {
if(glbl.GetGlobalInputTermState() == 1)
ABORT_FINALIZE(RS_RET_FORCE_TERM);
CHKiRet(nssel.IsReady(pSel, pThis->ppLstn[i], NSDSEL_RD, &bIsReady, &nfds));
if(bIsReady) {
workset[iWorkset].id = i;
workset[iWorkset].pUsr = (void*) pThis->ppLstn; /* this is a flag to indicate listen sock */
++iWorkset;
if(iWorkset >= (int) sizeWorkset) {
processWorkset(pThis, NULL, iWorkset, workset);
iWorkset = 0;
}
//DBGPRINTF("New connect on NSD %p.\n", pThis->ppLstn[i]);
//SessAccept(pThis, pThis->ppLstnPort[i], &pNewSess, pThis->ppLstn[i]);
--nfds; /* indicate we have processed one */
}
}
/* now check the sessions */
iTCPSess = TCPSessGetNxtSess(pThis, -1);
while(nfds && iTCPSess != -1) {
if(glbl.GetGlobalInputTermState() == 1)
ABORT_FINALIZE(RS_RET_FORCE_TERM);
localRet = nssel.IsReady(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD, &bIsReady, &nfds);
if(bIsReady || localRet != RS_RET_OK) {
workset[iWorkset].id = iTCPSess;
workset[iWorkset].pUsr = (void*) pThis->pSessions[iTCPSess];
++iWorkset;
if(iWorkset >= (int) sizeWorkset) {
processWorkset(pThis, NULL, iWorkset, workset);
iWorkset = 0;
}
--nfds; /* indicate we have processed one */
}
iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
}
if(iWorkset > 0)
processWorkset(pThis, NULL, iWorkset, workset);
/* we need to copy back close descriptors */
CHKiRet(nssel.Destruct(&pSel));
finalize_it: /* this is a very special case - this time only we do not exit the function,
* because that would not help us either. So we simply retry it. Let's see
* if that actually is a better idea. Exiting the loop wasn't we always
* crashed, which made sense (the rest of the engine was not prepared for
* that) -- rgerhards, 2008-05-19
*/
if(pSel != NULL) { /* cleanup missing? happens during err exit! */
nssel.Destruct(&pSel);
}
}
/* note that this point is usually not reached */
pthread_cleanup_pop(1); /* remove cleanup handler */
//.........这里部分代码省略.........
作者:adruc
项目:rsyslo
/* 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 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
* session object, so that it can do its own initialization.
* rgerhards, 2008-03-02
*/
static rsRetVal
SessAccept(tcpsrv_t *pThis, tcpLstnPortList_t *pLstnInfo, tcps_sess_t **ppSess, netstrm_t *pStrm)
{
DEFiRet;
tcps_sess_t *pSess = NULL;
netstrm_t *pNewStrm = NULL;
int iSess = -1;
struct sockaddr_storage *addr;
uchar *fromHostFQDN = NULL;
prop_t *fromHostIP;
ISOBJ_TYPE_assert(pThis, tcpsrv);
assert(pLstnInfo != NULL);
CHKiRet(netstrm.AcceptConnReq(pStrm, &pNewStrm));
/* Add to session list */
iSess = TCPSessTblFindFreeSpot(pThis);
if(iSess == -1) {
errno = 0;
errmsg.LogError(0, RS_RET_MAX_SESS_REACHED, "too many tcp sessions - dropping incoming request");
ABORT_FINALIZE(RS_RET_MAX_SESS_REACHED);
}
if(pThis->bUseKeepAlive) {
CHKiRet(netstrm.SetKeepAliveProbes(pNewStrm, pThis->iKeepAliveProbes));
CHKiRet(netstrm.SetKeepAliveTime(pNewStrm, pThis->iKeepAliveTime));
CHKiRet(netstrm.SetKeepAliveIntvl(pNewStrm, pThis->iKeepAliveIntvl));
CHKiRet(netstrm.EnableKeepAlive(pNewStrm));
}
/* 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));
if(pThis->OnMsgReceive != NULL)
CHKiRet(tcps_sess.SetOnMsgReceive(pSess, pThis->OnMsgReceive));
/* get the host name */
CHKiRet(netstrm.GetRemoteHName(pNewStrm, &fromHostFQDN));
CHKiRet(netstrm.GetRemoteIP(pNewStrm, &fromHostIP));
CHKiRet(netstrm.GetRemAddr(pNewStrm, &addr));
/* TODO: check if we need to strip the domain name here -- rgerhards, 2008-04-24 */
/* Here we check if a host is permitted to send us messages. If it isn't, we do not further
* process the message but log a warning (if we are configured to do this).
* rgerhards, 2005-09-26
*/
if(!pThis->pIsPermittedHost((struct sockaddr*) addr, (char*) fromHostFQDN, pThis->pUsr, pSess->pUsr)) {
DBGPRINTF("%s is not an allowed sender\n", fromHostFQDN);
if(glbl.GetOption_DisallowWarning()) {
errno = 0;
errmsg.LogError(0, RS_RET_HOST_NOT_PERMITTED, "TCP message from disallowed sender %s discarded", fromHostFQDN);
}
ABORT_FINALIZE(RS_RET_HOST_NOT_PERMITTED);
}
/* OK, we have an allowed sender, so let's continue, what
* means we can finally fill in the session object.
*/
CHKiRet(tcps_sess.SetHost(pSess, fromHostFQDN));
fromHostFQDN = NULL; /* we handed this string over */
CHKiRet(tcps_sess.SetHostIP(pSess, fromHostIP));
CHKiRet(tcps_sess.SetStrm(pSess, pNewStrm));
pNewStrm = NULL; /* prevent it from being freed in error handler, now done in tcps_sess! */
CHKiRet(tcps_sess.SetMsgIdx(pSess, 0));
CHKiRet(tcps_sess.ConstructFinalize(pSess));
/* check if we need to call our callback */
if(pThis->pOnSessAccept != NULL) {
CHKiRet(pThis->pOnSessAccept(pThis, pSess));
}
*ppSess = pSess;
if(!pThis->bUsingEPoll)
pThis->pSessions[iSess] = pSess;
pSess = NULL; /* this is now also handed over */
finalize_it:
if(iRet != RS_RET_OK) {
if(pSess != NULL)
tcps_sess.Destruct(&pSess);
if(pNewStrm != NULL)
netstrm.Destruct(&pNewStrm);
free(fromHostFQDN);
}
RETiRet;
}
作者:bobthesecuritygu
项目:rsyslo
/**
* Parse a TIMESTAMP-3164. The pTime parameter
* is guranteed to be updated only if a new valid timestamp
* could be obtained (restriction added 2008-09-16 by rgerhards). This
* also means the caller *must* provide a valid (probably current)
* timstamp in pTime when calling this function. a 3164 timestamp contains
* only partial information and only that partial information is updated.
* So the "output timestamp" is a valid timestamp only if the "input
* timestamp" was valid, too. The is actually an optimization, as it
* permits us to use a pre-aquired timestamp and thus avoids to do
* a (costly) time() call. Thanks to David Lang for insisting on
* time() call reduction ;).
* This method now also checks the maximum string length it is passed.
* If a *valid* timestamp is found, the string length is decremented
* by the number of characters processed. If it is not a valid timestamp,
* the length is kept unmodified. -- rgerhards, 2009-09-23
*/
static rsRetVal
ParseTIMESTAMP3164(struct syslogTime *pTime, uchar** ppszTS, int *pLenStr)
{
/* variables to temporarily hold time information while we parse */
int month;
int day;
int year = 0; /* 0 means no year provided */
int hour; /* 24 hour clock */
int minute;
int second;
/* end variables to temporarily hold time information while we parse */
int lenStr;
uchar *pszTS;
DEFiRet;
assert(ppszTS != NULL);
pszTS = *ppszTS;
assert(pszTS != NULL);
assert(pTime != NULL);
assert(pLenStr != NULL);
lenStr = *pLenStr;
/* If we look at the month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec),
* we may see the following character sequences occur:
*
* J(an/u(n/l)), Feb, Ma(r/y), A(pr/ug), Sep, Oct, Nov, Dec
*
* We will use this for parsing, as it probably is the
* fastest way to parse it.
*
* 2009-08-17: we now do case-insensitive comparisons, as some devices obviously do not
* obey to the RFC-specified case. As we need to guess in any case, we can ignore case
* in the first place -- rgerhards
*
* 2005-07-18, well sometimes it pays to be a bit more verbose, even in C...
* Fixed a bug that lead to invalid detection of the data. The issue was that
* we had an if(++pszTS == 'x') inside of some of the consturcts below. However,
* there were also some elseifs (doing the same ++), which than obviously did not
* check the orginal character but the next one. Now removed the ++ and put it
* into the statements below. Was a really nasty bug... I didn't detect it before
* june, when it first manifested. This also lead to invalid parsing of the rest
* of the message, as the time stamp was not detected to be correct. - rgerhards
*/
if(lenStr < 3)
ABORT_FINALIZE(RS_RET_INVLD_TIME);
switch(*pszTS++)
{
case 'j':
case 'J':
if(*pszTS == 'a' || *pszTS == 'A') {
++pszTS;
if(*pszTS == 'n' || *pszTS == 'N') {
++pszTS;
month = 1;
} else
ABORT_FINALIZE(RS_RET_INVLD_TIME);
} else if(*pszTS == 'u' || *pszTS == 'U') {
++pszTS;
if(*pszTS == 'n' || *pszTS == 'N') {
++pszTS;
month = 6;
} else if(*pszTS == 'l' || *pszTS == 'L') {
++pszTS;
month = 7;
} else
ABORT_FINALIZE(RS_RET_INVLD_TIME);
} else
ABORT_FINALIZE(RS_RET_INVLD_TIME);
break;
case 'f':
case 'F':
if(*pszTS == 'e' || *pszTS == 'E') {
++pszTS;
if(*pszTS == 'b' || *pszTS == 'B') {
++pszTS;
month = 2;
} else
ABORT_FINALIZE(RS_RET_INVLD_TIME);
} else
ABORT_FINALIZE(RS_RET_INVLD_TIME);
break;
case 'm':
//.........这里部分代码省略.........