mirror of
https://github.com/rsyslog/rsyslog.git
synced 2026-06-19 11:42:55 +02:00
tcp: log pre-truncated oversize frames
Why: TCP inputs can detect oversized frames before the core submit path sees a raw message larger than maxMessageSize. That left oversizemsg.errorfile unwritten for truncated TCP input. Impact: Configured oversize error logs now receive a JSON record for imtcp and imptcp frames that are truncated before core submit. Before/After: Before, pre-truncated TCP frames only emitted the normal warning; after, they also honor oversizemsg.errorfile. Technical Overview: Add a per-session flag that marks the current TCP frame as oversized when imtcp or imptcp detects the condition before submit. When the truncated message object is created, write the configured oversize JSON record before handing it to the ratelimit/submit path. Reset the flag when the message is submitted or a new frame starts. Add an imptcp regression test for oversizemsg.input.mode=truncate with oversizemsg.errorfile. Closes: https://github.com/rsyslog/rsyslog/issues/5228 With the help of AI-Agents: Codex
This commit is contained in:
parent
e722703739
commit
d0bd66241f
@ -295,6 +295,7 @@ struct ptcpsess_s {
|
||||
sbool bSuppOctetFram; /**< copy from listener, to speed up access */
|
||||
sbool bSPFramingFix;
|
||||
enum { eAtStrtFram, eInOctetCnt, eInMsg, eInMsgTruncation } inputState; /* our current state */
|
||||
sbool bFrameOversize; /* current frame exceeded maxMessageSize before submit */
|
||||
int iOctetsRemain; /* Number of Octets remaining in message */
|
||||
TCPFRAMINGMODE eFraming;
|
||||
uchar *pMsg; /* message (fragment) received */
|
||||
@ -971,6 +972,9 @@ static rsRetVal doSubmitMsg(ptcpsess_t *pThis, struct syslogTime *stTime, time_t
|
||||
MsgSetRcvFrom(pMsg, pThis->peerName);
|
||||
CHKiRet(MsgSetRcvFromIP(pMsg, pThis->peerIP));
|
||||
MsgSetRuleset(pMsg, pSrv->pRuleset);
|
||||
if (pThis->bFrameOversize) {
|
||||
writeOversizeMessageLog(pMsg);
|
||||
}
|
||||
localRet = ratelimitAddMsg(pSrv->ratelimiter, pMultiSub, pMsg);
|
||||
if (localRet == RS_RET_OK) {
|
||||
STATSCOUNTER_INC(pThis->pLstn->ctrSubmit, pThis->pLstn->mutCtrSubmit);
|
||||
@ -987,6 +991,7 @@ finalize_it:
|
||||
/* reset status variables */
|
||||
pThis->bAtStrtOfFram = 1;
|
||||
pThis->iMsg = 0;
|
||||
pThis->bFrameOversize = 0;
|
||||
|
||||
RETiRet;
|
||||
}
|
||||
@ -1070,6 +1075,7 @@ static rsRetVal ATTR_NONNULL(1, 2) processDataRcvd(ptcpsess_t *const __restrict_
|
||||
if (pThis->inputState == eAtStrtFram) {
|
||||
if (pThis->bSuppOctetFram && isdigit((int)c)) {
|
||||
pThis->inputState = eInOctetCnt;
|
||||
pThis->bFrameOversize = 0;
|
||||
pThis->iOctetsRemain = 0;
|
||||
pThis->eFraming = TCP_FRAMING_OCTET_COUNTING;
|
||||
} else if (pThis->bSPFramingFix && c == ' ') {
|
||||
@ -1081,6 +1087,7 @@ static rsRetVal ATTR_NONNULL(1, 2) processDataRcvd(ptcpsess_t *const __restrict_
|
||||
FINALIZE;
|
||||
} else {
|
||||
pThis->inputState = eInMsg;
|
||||
pThis->bFrameOversize = 0;
|
||||
pThis->eFraming = TCP_FRAMING_OCTET_STUFFING;
|
||||
}
|
||||
}
|
||||
@ -1116,6 +1123,7 @@ static rsRetVal ATTR_NONNULL(1, 2) processDataRcvd(ptcpsess_t *const __restrict_
|
||||
propPeerName, propPeerIP, pThis->iOctetsRemain);
|
||||
pThis->eFraming = TCP_FRAMING_OCTET_STUFFING;
|
||||
} else if (pThis->iOctetsRemain > iMaxLine) {
|
||||
pThis->bFrameOversize = 1;
|
||||
/* while we can not do anything against it, we can at least log an indication
|
||||
* that something went wrong) -- rgerhards, 2008-03-14
|
||||
*/
|
||||
@ -1159,6 +1167,7 @@ static rsRetVal ATTR_NONNULL(1, 2) processDataRcvd(ptcpsess_t *const __restrict_
|
||||
"imptcp %s: message received is at least %d byte larger than "
|
||||
"max msg size; message will be split starting at: \"%.*s\"\n",
|
||||
pThis->pLstn->pSrv->pszInputName, i, (i < 32) ? i : 32, *buff);
|
||||
pThis->bFrameOversize = 1;
|
||||
doSubmitMsg(pThis, stTime, ttGenTime, pMultiSub);
|
||||
iMsg = 0;
|
||||
++(*pnMsgs);
|
||||
|
||||
@ -357,6 +357,9 @@ static rsRetVal defaultDoSubmitMessage(tcps_sess_t *pThis,
|
||||
CHKiRet(MsgSetRcvFromIP(pMsg, pThis->fromHostIP));
|
||||
CHKiRet(MsgSetRcvFromPort(pMsg, pThis->fromHostPort));
|
||||
MsgSetRuleset(pMsg, cnf_params->pRuleset);
|
||||
if (pThis->bFrameOversize) {
|
||||
writeOversizeMessageLog(pMsg);
|
||||
}
|
||||
|
||||
if (pThis->pLstnInfo->ratelimiter->pShared != NULL && pThis->pLstnInfo->ratelimiter->pShared->per_source_enabled) {
|
||||
const char *per_source_key = NULL;
|
||||
@ -456,6 +459,7 @@ static rsRetVal defaultDoSubmitMessage(tcps_sess_t *pThis,
|
||||
finalize_it:
|
||||
/* reset status variables */
|
||||
pThis->iMsg = 0;
|
||||
pThis->bFrameOversize = 0;
|
||||
|
||||
RETiRet;
|
||||
}
|
||||
@ -630,6 +634,7 @@ static rsRetVal ATTR_NONNULL(1) processDataRcvd(tcps_sess_t *pThis,
|
||||
if (pThis->inputState == eAtStrtFram) {
|
||||
if (c >= '0' && c <= '9' && pThis->bSuppOctetFram) {
|
||||
pThis->inputState = eInOctetCnt;
|
||||
pThis->bFrameOversize = 0;
|
||||
pThis->iOctetsRemain = 0;
|
||||
pThis->eFraming = TCP_FRAMING_OCTET_COUNTING;
|
||||
} else if (c == ' ' && pThis->bSPFramingFix) {
|
||||
@ -641,6 +646,7 @@ static rsRetVal ATTR_NONNULL(1) processDataRcvd(tcps_sess_t *pThis,
|
||||
FINALIZE;
|
||||
} else {
|
||||
pThis->inputState = eInMsg;
|
||||
pThis->bFrameOversize = 0;
|
||||
pThis->eFraming = TCP_FRAMING_OCTET_STUFFING;
|
||||
}
|
||||
}
|
||||
@ -686,6 +692,7 @@ static rsRetVal ATTR_NONNULL(1) processDataRcvd(tcps_sess_t *pThis,
|
||||
/* emergency, we now need to flush, no matter if we are at end of message or not... */
|
||||
DBGPRINTF("error: message received is larger than max msg size, we %s it - c=%x\n",
|
||||
pThis->pSrv->discardTruncatedMsg == 1 ? "truncate" : "split", c);
|
||||
pThis->bFrameOversize = 1;
|
||||
defaultDoSubmitMessage(pThis, stTime, ttGenTime, pMultiSub);
|
||||
++(*pnMsgs);
|
||||
if (pThis->pSrv->discardTruncatedMsg == 1) {
|
||||
@ -754,6 +761,7 @@ static rsRetVal ATTR_NONNULL(1) processDataRcvd(tcps_sess_t *pThis,
|
||||
cnf_params->pszInputName, peerName, peerIP, peerPort, pThis->iOctetsRemain);
|
||||
pThis->eFraming = TCP_FRAMING_OCTET_STUFFING;
|
||||
} else if (pThis->iOctetsRemain > pThis->iMaxLine) {
|
||||
pThis->bFrameOversize = 1;
|
||||
/* while we can not do anything against it, we can at least log an indication
|
||||
* that something went wrong) -- rgerhards, 2008-03-14
|
||||
*/
|
||||
|
||||
@ -46,6 +46,7 @@ struct tcps_sess_s {
|
||||
eInMsgTruncating,
|
||||
eInMsgCheckMultiLine
|
||||
} inputState; /* our current state */
|
||||
sbool bFrameOversize; /* current frame exceeded maxMessageSize before submit */
|
||||
int iOctetsRemain; /* Number of Octets remaining in message */
|
||||
TCPFRAMINGMODE eFraming;
|
||||
uchar *pMsg; /* message (fragment) received */
|
||||
|
||||
@ -1193,6 +1193,7 @@ TESTS_IMPTCP = \
|
||||
imptcp_addtlframedelim.sh \
|
||||
imptcp_conndrop.sh \
|
||||
imptcp_no_octet_counted.sh \
|
||||
imptcp-oversize-errorfile-truncate.sh \
|
||||
imptcp_multi_line.sh \
|
||||
imptcp_spframingfix.sh \
|
||||
imptcp_maxsessions.sh \
|
||||
|
||||
33
tests/imptcp-oversize-errorfile-truncate.sh
Executable file
33
tests/imptcp-oversize-errorfile-truncate.sh
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# Regression test for oversizemsg.errorfile with imptcp truncation.
|
||||
# imptcp can detect and truncate an oversized TCP frame before core
|
||||
# submission sees rawmsg > maxMessageSize. The test passes only if that
|
||||
# pre-submit oversize detection still writes the configured JSON errorfile.
|
||||
. ${srcdir:=.}/diag.sh init
|
||||
generate_conf
|
||||
add_conf '
|
||||
$MaxMessageSize 128
|
||||
global(processInternalMessages="on"
|
||||
oversizemsg.input.mode="truncate"
|
||||
oversizemsg.errorfile="'$RSYSLOG2_OUT_LOG'")
|
||||
module(load="../plugins/imptcp/.libs/imptcp")
|
||||
input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
|
||||
|
||||
action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
|
||||
'
|
||||
startup
|
||||
msg="<120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncated test1 test2 test3 test4 test5 abcdefghijklmnopqrstuvwxyz"
|
||||
printf '%s %s' "${#msg}" "$msg" > $RSYSLOG_DYNNAME.inputfile
|
||||
tcpflood -I $RSYSLOG_DYNNAME.inputfile
|
||||
shutdown_when_empty
|
||||
wait_shutdown
|
||||
|
||||
grep '"rawmsg":.*way too long message.*"input": "imptcp"' "$RSYSLOG2_OUT_LOG" > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo
|
||||
echo "FAIL: expected oversize JSON record not found. $RSYSLOG2_OUT_LOG is:"
|
||||
cat "$RSYSLOG2_OUT_LOG"
|
||||
error_exit 1
|
||||
fi
|
||||
|
||||
exit_test
|
||||
Loading…
x
Reference in New Issue
Block a user