diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-04-24 09:57:43 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-04-24 09:57:43 +0200 |
commit | bf3d2c1b392af1383a3cdc247f2280fd31a12699 (patch) | |
tree | 532f3de6ec3b7fc7557c4e3a60f142a07a29580a | |
parent | 721b9ee252143d182c3c145380e5dbec8c3b0102 (diff) | |
download | rsyslog-bf3d2c1b392af1383a3cdc247f2280fd31a12699.tar.gz rsyslog-bf3d2c1b392af1383a3cdc247f2280fd31a12699.tar.bz2 rsyslog-bf3d2c1b392af1383a3cdc247f2280fd31a12699.zip |
message reception via TCP work again
... at least in some cases ;) I assume there are still a couple
of bugs inside the code. But at least we have something from
where we can continue to work on.
-rw-r--r-- | runtime/netstrm.c | 25 | ||||
-rw-r--r-- | runtime/netstrm.h | 20 | ||||
-rw-r--r-- | runtime/netstrms.c | 21 | ||||
-rw-r--r-- | runtime/nsd.h | 2 | ||||
-rw-r--r-- | runtime/nsd_ptcp.c | 53 | ||||
-rw-r--r-- | runtime/nsdsel_ptcp.c | 9 | ||||
-rw-r--r-- | runtime/nssel.c | 4 | ||||
-rw-r--r-- | runtime/obj-types.h | 8 | ||||
-rw-r--r-- | runtime/obj.c | 2 | ||||
-rw-r--r-- | tcps_sess.c | 9 | ||||
-rw-r--r-- | tcpsrv.c | 25 |
11 files changed, 108 insertions, 70 deletions
diff --git a/runtime/netstrm.c b/runtime/netstrm.c index 83e91c2d..670899ef 100644 --- a/runtime/netstrm.c +++ b/runtime/netstrm.c @@ -117,6 +117,7 @@ AcceptConnReq(netstrm_t *pThis, netstrm_t **ppNew) assert(ppNew != NULL); /* accept the new connection */ +RUNLOG_VAR("%p", pThis->pDrvrData); CHKiRet(pThis->Drvr.AcceptConnReq(pThis->pDrvrData, &pNewNsd)); /* construct our object so that we can use it... */ CHKiRet(netstrms.CreateStrm(pThis->pNS, ppNew)); @@ -191,6 +192,28 @@ Send(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf) } +/* get remote hname - slim wrapper for NSD driver function */ +static rsRetVal +GetRemoteHName(netstrm_t *pThis, uchar **ppsz) +{ + DEFiRet; + ISOBJ_TYPE_assert(pThis, netstrm); + iRet = pThis->Drvr.GetRemoteHName(pThis->pDrvrData, ppsz); + RETiRet; +} + + +/* get remote IP - slim wrapper for NSD driver function */ +static rsRetVal +GetRemoteIP(netstrm_t *pThis, uchar **ppsz) +{ + DEFiRet; + ISOBJ_TYPE_assert(pThis, netstrm); + iRet = pThis->Drvr.GetRemoteIP(pThis->pDrvrData, ppsz); + RETiRet; +} + + /* open a connection to a remote host (server). * rgerhards, 2008-03-19 */ @@ -228,6 +251,8 @@ CODESTARTobjQueryInterface(netstrm) pIf->Connect = Connect; pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; + pIf->GetRemoteHName = GetRemoteHName; + pIf->GetRemoteIP = GetRemoteIP; finalize_it: ENDobjQueryInterface(netstrm) diff --git a/runtime/netstrm.h b/runtime/netstrm.h index 33d166ea..f4205f80 100644 --- a/runtime/netstrm.h +++ b/runtime/netstrm.h @@ -32,13 +32,7 @@ struct netstrm_s { nsd_t *pDrvrData; /**< the driver's data elements (at most other places, this is called pNsd) */ uchar *pDrvrName; /**< nsd driver name to use, or NULL if system default */ nsd_if_t Drvr; /**< our stream driver */ - netstrms_t *pNS; /**< pointer to our netstream subsystem object */ - /* for listeners, we need to have the capablity to listen on multiple "sockets". This - * is needed to support IPv6. We do this by specifying an array of nsd_t objects to - * handle this case. - */ - //int isizeLstnArr; - //nsd_t **parrLstn; + netstrms_t *pNS; /**< pointer to our netstream subsystem object */ }; @@ -54,11 +48,13 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Rcv)(netstrm_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf); rsRetVal (*Send)(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf); rsRetVal (*Connect)(netstrm_t *pThis, int family, unsigned char *port, unsigned char *host); - rsRetVal (*SelectInit)(nsdsel_t **ppSel, netstrm_t *pThis); - rsRetVal (*SelectAdd)(nsdsel_t *pSel, netstrm_t *pThis); - rsRetVal (*SelectWait)(nsdsel_t *pSel, int *piNumReady); - rsRetVal (*SelectIsReady)(nsdsel_t *pSel, int *piNumReady); - rsRetVal (*SelectExit)(nsdsel_t **ppSel); + //rsRetVal (*SelectInit)(nsdsel_t **ppSel, netstrm_t *pThis); + //rsRetVal (*SelectAdd)(nsdsel_t *pSel, netstrm_t *pThis); + //rsRetVal (*SelectWait)(nsdsel_t *pSel, int *piNumReady); + //rsRetVal (*SelectIsReady)(nsdsel_t *pSel, int *piNumReady); + //rsRetVal (*SelectExit)(nsdsel_t **ppSel); + rsRetVal (*GetRemoteHName)(netstrm_t *pThis, uchar **pszName); + rsRetVal (*GetRemoteIP)(netstrm_t *pThis, uchar **pszIP); ENDinterface(netstrm) #define netstrmCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ diff --git a/runtime/netstrms.c b/runtime/netstrms.c index 46e740ab..661234e4 100644 --- a/runtime/netstrms.c +++ b/runtime/netstrms.c @@ -100,22 +100,6 @@ finalize_it: } -/* load the netstrm interface, but only if needed (if we load it always, we get - * into a circular dependency, because netstrm also needs ourselfs in some cases - * rgerhards, 2008-04-23 - */ -static inline rsRetVal -loadNetstrm(void) -{ - DEFiRet; - if(!netstrm.ifIsLoaded) { - CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME)); - } -finalize_it: - RETiRet; -} - - /* 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(). @@ -126,7 +110,7 @@ CreateStrm(netstrms_t *pThis, netstrm_t **ppStrm) netstrm_t *pStrm = NULL; DEFiRet; - CHKiRet(loadNetstrm()); + CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME)); 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. @@ -173,8 +157,7 @@ CODESTARTObjClassExit(netstrms) /* release objects we no longer need */ //objRelease(net, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); - if(netstrm.ifIsLoaded) - objRelease(netstrm, LM_NETSTRM_FILENAME); + objRelease(netstrm, LM_NETSTRM_FILENAME); ENDObjClassExit(netstrms) diff --git a/runtime/nsd.h b/runtime/nsd.h index c32e284e..ff12ecb0 100644 --- a/runtime/nsd.h +++ b/runtime/nsd.h @@ -49,6 +49,8 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */ rsRetVal (*LstnInit)(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*), uchar *pLstnPort, uchar *pLstnIP, int iSessMax); rsRetVal (*AcceptConnReq)(nsd_t *pThis, nsd_t **ppThis); + rsRetVal (*GetRemoteHName)(nsd_t *pThis, uchar **pszName); + rsRetVal (*GetRemoteIP)(nsd_t *pThis, uchar **pszIP); ENDinterface(nsd) #define nsdCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c index 40b11ad4..8dbc80d9 100644 --- a/runtime/nsd_ptcp.c +++ b/runtime/nsd_ptcp.c @@ -207,7 +207,7 @@ AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew) DEFiRet; assert(ppNew != NULL); - ISOBJ_TYPE_assert(pThis, nsd_ptcp_t); + ISOBJ_TYPE_assert(pThis, nsd_ptcp); iNewSock = accept(pThis->sock, (struct sockaddr*) &addr, &addrlen); if(iNewSock < 0) { @@ -294,6 +294,7 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*), numSocks = 0; /* num of sockets counter at start of array */ for(r = res; r != NULL ; r = r->ai_next) { sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol); +RUNLOG_VAR("%d", sock); if(sock < 0) { if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT)) dbgprintf("error %d creating tcp listen socket", errno); @@ -386,11 +387,9 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*), CHKiRet(fAddLstn(pUsr, pNewStrm)); pNewNsd = NULL; pNewStrm = NULL; + ++numSocks; } - if(res != NULL) - freeaddrinfo(res); - if(numSocks != maxs) dbgprintf("We could initialize %d TCP listen sockets out of %d we received " "- this may or may not be an error indication.\n", numSocks, maxs); @@ -401,9 +400,10 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*), } finalize_it: + if(res != NULL) + freeaddrinfo(res); + if(iRet != RS_RET_OK) { - if(res != NULL) - freeaddrinfo(res); if(pNewStrm != NULL) netstrm.Destruct(&pNewStrm); if(pNewNsd != NULL) @@ -515,6 +515,45 @@ finalize_it: } +/* get the remote hostname. The returned hostname must be freed by the + * caller. + * rgerhards, 2008-04-24 + */ +static rsRetVal +GetRemoteHName(nsd_t *pNsd, uchar **ppszHName) +{ + DEFiRet; + nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd; + ISOBJ_TYPE_assert(pThis, nsd_ptcp); + assert(ppszHName != NULL); + + // TODO: how can the RemHost be empty? + CHKmalloc(*ppszHName = (uchar*)strdup(pThis->pRemHostName == NULL ? "" : (char*) pThis->pRemHostName)); + +finalize_it: + RETiRet; +} + + +/* get the remote host's IP address. The returned string must be freed by the + * caller. + * rgerhards, 2008-04-24 + */ +static rsRetVal +GetRemoteIP(nsd_t *pNsd, uchar **ppszIP) +{ + DEFiRet; + nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd; + ISOBJ_TYPE_assert(pThis, nsd_ptcp); + assert(ppszIP != NULL); + + CHKmalloc(*ppszIP = (uchar*)strdup(pThis->pRemHostIP == NULL ? "" : (char*) pThis->pRemHostIP)); + +finalize_it: + RETiRet; +} + + /* queryInterface function */ BEGINobjQueryInterface(nsd_ptcp) CODESTARTobjQueryInterface(nsd_ptcp) @@ -535,6 +574,8 @@ CODESTARTobjQueryInterface(nsd_ptcp) pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; pIf->Connect = Connect; + pIf->GetRemoteHName = GetRemoteHName; + pIf->GetRemoteIP = GetRemoteIP; finalize_it: ENDobjQueryInterface(nsd_ptcp) diff --git a/runtime/nsdsel_ptcp.c b/runtime/nsdsel_ptcp.c index c5864809..b439063a 100644 --- a/runtime/nsdsel_ptcp.c +++ b/runtime/nsdsel_ptcp.c @@ -24,19 +24,10 @@ */ #include "config.h" -#include "rsyslog.h" -#include <stdio.h> -#include <stdarg.h> #include <stdlib.h> #include <assert.h> #include <errno.h> #include <string.h> -#include <signal.h> -#include <ctype.h> -#include <netdb.h> -#include <fnmatch.h> -#include <fcntl.h> -#include <unistd.h> #include <sys/select.h> #include "rsyslog.h" diff --git a/runtime/nssel.c b/runtime/nssel.c index 0cbda9b9..c4f6691e 100644 --- a/runtime/nssel.c +++ b/runtime/nssel.c @@ -74,7 +74,8 @@ 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__, pDrvrName+2, pDrvrName, (void*) &pThis->Drvr)); + CHKiRet(obj.UseObj(__FILE__, "nsdsel_ptcp", "lmnsdsel_ptcp", (void*) &pThis->Drvr)); finalize_it: RETiRet; } @@ -152,6 +153,7 @@ IsReady(nssel_t *pThis, netstrm_t *pStrm, nsdsel_waitOp_t waitOp, int *pbIsReady ISOBJ_TYPE_assert(pStrm, netstrm); assert(pbIsReady != NULL); assert(piNumReady != NULL); + iRet = pThis->Drvr.IsReady(pThis->pDrvrData, pStrm->pDrvrData, waitOp, pbIsReady); RETiRet; } diff --git a/runtime/obj-types.h b/runtime/obj-types.h index acdc757d..2d0e0f14 100644 --- a/runtime/obj-types.h +++ b/runtime/obj-types.h @@ -106,8 +106,12 @@ struct obj_s { /* the dummy struct that each derived class can be casted to */ do { \ ASSERT(pObj != NULL); \ ASSERT((unsigned) ((obj_t*) (pObj))->iObjCooCKiE == (unsigned) 0xBADEFEE); \ - ASSERT(!strcmp((char*)(((obj_t*)pObj)->pObjInfo->pszID), #objType)); \ - } while(0); + if(strcmp((char*)(((obj_t*)pObj)->pObjInfo->pszID), #objType)) { \ + dbgprintf("ISOBJ assert failure: invalid object type, expected '%s' " \ + "actual '%s'\n", #objType, (((obj_t*)pObj)->pObjInfo->pszID)); \ + assert(0); /* trigger assertion, messge we already have */ \ + } \ + } while(0) #else /* non-debug mode, no checks but much faster */ # define BEGINobjInstance obj_t objData # define ISOBJ_TYPE_assert(pObj, objType) diff --git a/runtime/obj.c b/runtime/obj.c index 8ab606f9..18a4a726 100644 --- a/runtime/obj.c +++ b/runtime/obj.c @@ -1198,7 +1198,7 @@ ReleaseObj(char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf) 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 already set */ /* TODO: flag an error? */ + ABORT_FINALIZE(RS_RET_OK); /* we are not loaded - this is perfectly OK... */ } if(pIf->ifIsLoaded == 2) { pIf->ifIsLoaded = 0; /* clean up */ diff --git a/tcps_sess.c b/tcps_sess.c index 5f5e993a..27bdbf89 100644 --- a/tcps_sess.c +++ b/tcps_sess.c @@ -119,16 +119,15 @@ finalize_it: RETiRet; } -#if 0 // TODO: don't we need this any longer? static rsRetVal -SetSock(tcps_sess_t *pThis, int sock) +SetStrm(tcps_sess_t *pThis, netstrm_t *pStrm) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); - pThis->sock = sock; + pThis->pStrm = pStrm; RETiRet; } -#endif + static rsRetVal SetMsgIdx(tcps_sess_t *pThis, int idx) @@ -393,7 +392,7 @@ CODESTARTobjQueryInterface(tcps_sess) pIf->SetUsrP = SetUsrP; pIf->SetTcpsrv = SetTcpsrv; pIf->SetHost = SetHost; - //pIf->SetSock = SetSock; + pIf->SetStrm = SetStrm; pIf->SetMsgIdx = SetMsgIdx; finalize_it: ENDobjQueryInterface(tcps_sess) @@ -182,9 +182,10 @@ TCPSessGetNxtSess(tcpsrv_t *pThis, int iCurr) register int i; ISOBJ_TYPE_assert(pThis, tcpsrv); - for(i = iCurr + 1 ; i < pThis->iSessMax ; ++i) + for(i = iCurr + 1 ; i < pThis->iSessMax ; ++i) { if(pThis->pSessions[i] != NULL) break; + } return((i < pThis->iSessMax) ? i : -1); } @@ -241,6 +242,7 @@ addTcpLstn(void *pUsr, netstrm_t *pLstn) if(pThis->iLstnMax >= TCPLSTN_MAX_DEFAULT) ABORT_FINALIZE(RS_RET_MAX_LSTN_REACHED); +RUNLOG_VAR("%d", pThis->iLstnMax); pThis->ppLstn[pThis->iLstnMax] = pLstn; ++pThis->iLstnMax; @@ -310,8 +312,7 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm) netstrm_t *pNewStrm = NULL; int iSess = -1; struct sockaddr_storage addr; - uchar fromHost[NI_MAXHOST]; - uchar fromHostFQDN[NI_MAXHOST]; + uchar *fromHostFQDN; ISOBJ_TYPE_assert(pThis, tcpsrv); @@ -331,13 +332,8 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm) /* OK, we have a "good" index... */ /* get the host name */ - if(net.cvthname(&addr, fromHost, fromHostFQDN) != RS_RET_OK) { - /* we seem to have something malicous - at least we - * are now told to discard the connection request. - * Error message has been generated by cvthname. - */ - ABORT_FINALIZE(RS_RET_ERR); // TODO: better error code - } + CHKiRet(netstrm.GetRemoteHName(pStrm, &fromHostFQDN)); + /* 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 * syslog messages. If it isn't, we do not further @@ -346,10 +342,10 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm) * rgerhards, 2005-09-26 */ if(!pThis->pIsPermittedHost((struct sockaddr*) &addr, (char*) fromHostFQDN, pThis->pUsr, pSess->pUsr)) { - dbgprintf("%s is not an allowed sender\n", (char *) fromHostFQDN); + dbgprintf("%s is not an allowed sender\n", fromHostFQDN); if(glbl.GetOption_DisallowWarning()) { errno = 0; - errmsg.LogError(NO_ERRCODE, "TCP message from disallowed sender %s discarded", fromHost); + errmsg.LogError(NO_ERRCODE, "TCP message from disallowed sender %s discarded", fromHostFQDN); } ABORT_FINALIZE(RS_RET_HOST_NOT_PERMITTED); } @@ -357,7 +353,7 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm) /* 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, fromHost)); + CHKiRet(tcps_sess.SetHost(pSess, fromHostFQDN)); 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)); @@ -480,7 +476,6 @@ finalize_it: // TODO: think: is it really good to exit the loop? /* Standard-Constructor */ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macro! */ pThis->iSessMax = TCPSESS_MAX_DEFAULT; /* TODO: useful default ;) */ - pThis->iLstnMax = TCPLSTN_MAX_DEFAULT; /* TODO: useful default ;) */ ENDobjConstruct(tcpsrv) @@ -497,7 +492,7 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis) CHKiRet(netstrms.ConstructFinalize(pThis->pNS)); /* set up listeners */ - CHKmalloc(pThis->ppLstn = calloc(pThis->iLstnMax, sizeof(netstrm_t*))); + CHKmalloc(pThis->ppLstn = calloc(TCPLSTN_MAX_DEFAULT, sizeof(netstrm_t*))); iRet = pThis->OpenLstnSocks(pThis); finalize_it: |