tcpsrv subsystem: better error messages

Most importantly, output os error messages on API failures.
Among others, this improves error messages in imtcp.

closes https://github.com/rsyslog/rsyslog/issues/1749
This commit is contained in:
Rainer Gerhards 2017-09-04 10:35:30 +02:00
parent 920c296bf9
commit 5c5a7a3ed5
11 changed files with 36 additions and 32 deletions

View File

@ -124,14 +124,14 @@ doOpenLstnSocks(tcpsrv_t *pSrv)
static rsRetVal
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd)
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd, int *oserr)
{
DEFiRet;
assert(pSess != NULL);
assert(piLenRcvd != NULL);
*piLenRcvd = lenBuf;
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd));
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd, oserr));
finalize_it:
RETiRet;
}

View File

@ -219,14 +219,14 @@ doOpenLstnSocks(tcpsrv_t *pSrv)
static rsRetVal
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd)
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd, int *const oserr)
{
DEFiRet;
assert(pSess != NULL);
assert(piLenRcvd != NULL);
*piLenRcvd = lenBuf;
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd));
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd, oserr));
finalize_it:
RETiRet;
}

View File

@ -161,16 +161,15 @@ finalize_it:
* never blocks, not even when called on a blocking socket. That is important
* for client sockets, which are set to block during send, but should not
* block when trying to read data. If *pLenBuf is -1, an error occured and
* errno holds the exact error cause.
* oserr holds the exact error cause.
* rgerhards, 2008-03-17
*/
static rsRetVal
Rcv(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf)
Rcv(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf, int *const oserr)
{
DEFiRet;
ISOBJ_TYPE_assert(pThis, netstrm);
//printf("Rcv %p\n", pThis);
iRet = pThis->Drvr.Rcv(pThis->pDrvrData, pBuf, pLenBuf);
iRet = pThis->Drvr.Rcv(pThis->pDrvrData, pBuf, pLenBuf, oserr);
RETiRet;
}

View File

@ -45,7 +45,7 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*LstnInit)(netstrms_t *pNS, void *pUsr, rsRetVal(*)(void*,netstrm_t*),
uchar *pLstnPort, uchar *pLstnIP, int iSessMax);
rsRetVal (*AcceptConnReq)(netstrm_t *pThis, netstrm_t **ppNew);
rsRetVal (*Rcv)(netstrm_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf);
rsRetVal (*Rcv)(netstrm_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf, int *oserr);
rsRetVal (*Send)(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf);
rsRetVal (*Connect)(netstrm_t *pThis, int family, unsigned char *port, unsigned char *host, char *device);
rsRetVal (*GetRemoteHName)(netstrm_t *pThis, uchar **pszName);
@ -77,7 +77,7 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetKeepAliveIntvl)(netstrm_t *pThis, int keepAliveIntvl);
rsRetVal (*SetGnutlsPriorityString)(netstrm_t *pThis, uchar *priorityString);
ENDinterface(netstrm)
#define netstrmCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */
#define netstrmCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */
/* interface version 3 added GetRemAddr()
* interface version 4 added EnableKeepAlive() -- rgerhards, 2009-06-02
* interface version 5 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
@ -85,6 +85,7 @@ ENDinterface(netstrm)
* interface version 7 added KeepAlive parameter set functions
* interface version 8 changed signature of Connect() -- dsa, 2016-11-14
* interface version 9 added SetGnutlsPriorityString -- PascalWithopf, 2017-08-08
* interface version 10 added oserr parameter to Rcv() -- rgerhards, 2017-09-04
* */
/* prototypes */

View File

@ -52,7 +52,7 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(nsd_t **ppThis);
rsRetVal (*Destruct)(nsd_t **ppThis);
rsRetVal (*Abort)(nsd_t *pThis);
rsRetVal (*Rcv)(nsd_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf);
rsRetVal (*Rcv)(nsd_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf, int *oserr);
rsRetVal (*Send)(nsd_t *pThis, uchar *pBuf, ssize_t *pLenBuf);
rsRetVal (*Connect)(nsd_t *pThis, int family, unsigned char *port, unsigned char *host, char *device);
rsRetVal (*LstnInit)(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
@ -85,7 +85,7 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetKeepAliveTime)(nsd_t *pThis, int keepAliveTime);
rsRetVal (*SetGnutlsPriorityString)(nsd_t *pThis, uchar *gnutlsPriorityString);
ENDinterface(nsd)
#define nsdCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */
#define nsdCURR_IF_VERSION 11 /* increment whenever you change the interface structure! */
/* interface version 4 added GetRemAddr()
* interface version 5 added EnableKeepAlive() -- rgerhards, 2009-06-02
* interface version 6 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
@ -93,6 +93,7 @@ ENDinterface(nsd)
* interface version 8 added keep alive parameter set functions
* interface version 9 changed signature of Connect() -- dsa, 2016-11-14
* interface version 10 added SetGnutlsPriorityString() -- PascalWithopf, 2017-08-08
* interface version 11 added oserr to Rcv() signature -- rgerhards, 2017-09-04
*/
/* interface for the select call */

View File

@ -1566,7 +1566,7 @@ finalize_it:
* buffer. -- rgerhards, 2008-06-23
*/
static rsRetVal
Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf, int *const oserr)
{
DEFiRet;
ssize_t iBytesCopy; /* how many bytes are to be copied to the client buffer? */
@ -1577,7 +1577,7 @@ Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ);
if(pThis->iMode == 0) {
CHKiRet(nsd_ptcp.Rcv(pThis->pTcp, pBuf, pLenBuf));
CHKiRet(nsd_ptcp.Rcv(pThis->pTcp, pBuf, pLenBuf, oserr));
FINALIZE;
}
@ -1605,6 +1605,7 @@ Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
}
if(pThis->lenRcvBuf == 0) { /* EOS */
*oserr = errno;
ABORT_FINALIZE(RS_RET_CLOSED);
}

View File

@ -575,22 +575,24 @@ finalize_it:
* never blocks, not even when called on a blocking socket. That is important
* for client sockets, which are set to block during send, but should not
* block when trying to read data. If *pLenBuf is -1, an error occured and
* errno holds the exact error cause.
* oserr holds the exact error cause.
* rgerhards, 2008-03-17
*/
static rsRetVal
Rcv(nsd_t *pNsd, uchar *pRcvBuf, ssize_t *pLenBuf)
Rcv(nsd_t *pNsd, uchar *pRcvBuf, ssize_t *pLenBuf, int *const oserr)
{
char errStr[1024];
DEFiRet;
nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
ISOBJ_TYPE_assert(pThis, nsd_ptcp);
assert(oserr != NULL);
/* AIXPORT : MSG_DONTWAIT not supported */
#if defined (_AIX)
#define MSG_DONTWAIT MSG_NONBLOCK
#endif
*pLenBuf = recv(pThis->sock, pRcvBuf, *pLenBuf, MSG_DONTWAIT);
*oserr = errno;
if(*pLenBuf == 0) {
ABORT_FINALIZE(RS_RET_CLOSED);

View File

@ -120,14 +120,14 @@ doOpenLstnSocks(strmsrv_t *pSrv)
static rsRetVal
doRcvData(strms_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd)
doRcvData(strms_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd, int *const oserr)
{
DEFiRet;
assert(pSess != NULL);
assert(piLenRcvd != NULL);
*piLenRcvd = lenBuf;
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd));
CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd, oserr));
finalize_it:
RETiRet;
}
@ -536,6 +536,7 @@ Run(strmsrv_t *pThis)
nssel_t *pSel;
ssize_t iRcvd;
rsRetVal localRet;
int oserr;
ISOBJ_TYPE_assert(pThis, strmsrv);
@ -584,7 +585,7 @@ Run(strmsrv_t *pThis)
dbgprintf("netstream %p with new data\n", pThis->pSessions[iSTRMSess]->pStrm);
/* Receive message */
iRet = pThis->pRcvData(pThis->pSessions[iSTRMSess], buf, sizeof(buf), &iRcvd);
iRet = pThis->pRcvData(pThis->pSessions[iSTRMSess], buf, sizeof(buf), &iRcvd, &oserr);
switch(iRet) {
case RS_RET_CLOSED:
pThis->pOnRegularClose(pThis->pSessions[iSTRMSess]);
@ -607,9 +608,8 @@ Run(strmsrv_t *pThis)
}
break;
default:
errno = 0;
errmsg.LogError(0, iRet, "netstream session %p will be closed due to error\n",
pThis->pSessions[iSTRMSess]->pStrm);
LogError(oserr, iRet, "netstream session %p will be closed due to error\n",
pThis->pSessions[iSTRMSess]->pStrm);
pThis->pOnErrClose(pThis->pSessions[iSTRMSess]);
strms_sess.Destruct(&pThis->pSessions[iSTRMSess]);
break;

View File

@ -55,7 +55,7 @@ struct strmsrv_s {
void *pUsr; /**< a user-settable pointer (provides extensibility for "derived classes")*/
/* callbacks */
int (*pIsPermittedHost)(struct sockaddr *addr, char *fromHostFQDN, void*pUsrSrv, void*pUsrSess);
rsRetVal (*pRcvData)(strms_sess_t*, char*, size_t, ssize_t *);
rsRetVal (*pRcvData)(strms_sess_t*, char*, size_t, ssize_t *, int *);
rsRetVal (*OpenLstnSocks)(struct strmsrv_s*);
rsRetVal (*pOnListenDeinit)(void*);
rsRetVal (*OnDestruct)(void*);

View File

@ -574,11 +574,12 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t **ppSess, nspoll_t *pPoll)
DEFiRet;
uchar *pszPeer;
int lenPeer;
int oserr = 0;
ISOBJ_TYPE_assert(pThis, tcpsrv);
DBGPRINTF("netstream %p with new data\n", (*ppSess)->pStrm);
/* Receive message */
iRet = pThis->pRcvData(*ppSess, buf, sizeof(buf), &iRcvd);
iRet = pThis->pRcvData(*ppSess, buf, sizeof(buf), &iRcvd, &oserr);
switch(iRet) {
case RS_RET_CLOSED:
if(pThis->bEmitMsgOnClose) {
@ -600,15 +601,13 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t **ppSess, nspoll_t *pPoll)
* We are instructed to terminate the session.
*/
prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer);
errmsg.LogError(0, localRet, "Tearing down TCP Session from %s - see "
"previous messages for reason(s)\n", pszPeer);
LogError(oserr, localRet, "Tearing down TCP Session from %s", pszPeer);
CHKiRet(closeSess(pThis, ppSess, pPoll));
}
break;
default:
errno = 0;
prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer);
errmsg.LogError(0, iRet, "netstream session %p from %s will be closed due to error\n",
errmsg.LogError(oserr, iRet, "netstream session %p from %s will be closed due to error",
(*ppSess)->pStrm, pszPeer);
CHKiRet(closeSess(pThis, ppSess, pPoll));
break;
@ -1051,7 +1050,7 @@ SetCBIsPermittedHost(tcpsrv_t *pThis, int (*pCB)(struct sockaddr *addr, char *fr
}
static rsRetVal
SetCBRcvData(tcpsrv_t *pThis, rsRetVal (*pRcvData)(tcps_sess_t*, char*, size_t, ssize_t*))
SetCBRcvData(tcpsrv_t *pThis, rsRetVal (*pRcvData)(tcps_sess_t*, char*, size_t, ssize_t*, int*))
{
DEFiRet;
pThis->pRcvData = pRcvData;

View File

@ -90,7 +90,7 @@ struct tcpsrv_s {
void *pUsr; /**< a user-settable pointer (provides extensibility for "derived classes")*/
/* callbacks */
int (*pIsPermittedHost)(struct sockaddr *addr, char *fromHostFQDN, void*pUsrSrv, void*pUsrSess);
rsRetVal (*pRcvData)(tcps_sess_t*, char*, size_t, ssize_t *);
rsRetVal (*pRcvData)(tcps_sess_t*, char*, size_t, ssize_t *, int*);
rsRetVal (*OpenLstnSocks)(struct tcpsrv_s*);
rsRetVal (*pOnListenDeinit)(void*);
rsRetVal (*OnDestruct)(void*);
@ -132,7 +132,7 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetUsrP)(tcpsrv_t*, void*);
rsRetVal (*SetCBIsPermittedHost)(tcpsrv_t*, int (*) (struct sockaddr *addr, char*, void*, void*));
rsRetVal (*SetCBOpenLstnSocks)(tcpsrv_t *, rsRetVal (*)(tcpsrv_t*));
rsRetVal (*SetCBRcvData)(tcpsrv_t *pThis, rsRetVal (*pRcvData)(tcps_sess_t*, char*, size_t, ssize_t*));
rsRetVal (*SetCBRcvData)(tcpsrv_t *pThis, rsRetVal (*pRcvData)(tcps_sess_t*, char*, size_t, ssize_t*, int*));
rsRetVal (*SetCBOnListenDeinit)(tcpsrv_t*, rsRetVal (*)(void*));
rsRetVal (*SetCBOnDestruct)(tcpsrv_t*, rsRetVal (*) (void*));
rsRetVal (*SetCBOnRegularClose)(tcpsrv_t*, rsRetVal (*) (tcps_sess_t*));
@ -176,12 +176,13 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
/* added v19 -- PascalWithopf, 2017-08-08 */
rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*);
ENDinterface(tcpsrv)
#define tcpsrvCURR_IF_VERSION 19 /* increment whenever you change the interface structure! */
#define tcpsrvCURR_IF_VERSION 20 /* increment whenever you change the interface structure! */
/* change for v4:
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
* - SetInputName() added -- rgerhards, 2008-12-10
* change for v5 and up: see above
* for v12: param bSuppOctetFram added to configureTCPListen
* for v20: add oserr to setCBRcvData signature -- rgerhards, 2017-09-04
*/