Merge pull request #7109 from rgerhards/codex/i6663-omfwd-rebind-leak

omfwd: avoid tcpclt leak on rebind
This commit is contained in:
Rainer Gerhards 2026-05-29 10:45:08 +02:00 committed by GitHub
commit 6c6b3ad92e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 53 additions and 4 deletions

View File

@ -663,6 +663,7 @@ TESTS_IMTCP = \
imtcp-netns.sh \
imtcp-NUL.sh \
imtcp-NUL-rawmsg.sh \
omfwd-rebind-tcp.sh \
imtcp_incomplete_frame_at_end.sh \
imtcp-multiport.sh \
imtcp-bigmessage-octetcounting.sh \
@ -683,7 +684,8 @@ TESTS_IMTCP_YAML = \
imtcp-persource-ratelimit.sh
TESTS_IMTCP_VALGRIND = \
imtcp-octet-framing-too-long-vg.sh
imtcp-octet-framing-too-long-vg.sh \
omfwd-rebind-tcp-vg.sh
TESTS_RATELIMIT = \
ratelimit_exclusivity.sh \

5
tests/omfwd-rebind-tcp-vg.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
# Valgrind wrapper for omfwd-rebind-tcp.sh. Keep the scenario in the base
# test so the normal and Valgrind registrations exercise the same logic.
export USE_VALGRIND="YES"
. ${srcdir:=.}/omfwd-rebind-tcp.sh

41
tests/omfwd-rebind-tcp.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
# Verify that TCP rebind preserves forwarding while repeatedly tearing down
# and reconnecting the target transport. The tiny rebind interval forces the
# rebind path for every message; the receiver sequence check proves all data
# still arrives. When sourced by the -vg wrapper, Valgrind is the oracle for
# leaked rebind-side allocations. This guards
# https://github.com/rsyslog/rsyslog/issues/6663.
. ${srcdir:=.}/diag.sh init
export NUMMESSAGES=40
export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
generate_conf
add_conf '
module(load="../plugins/imtcp/.libs/imtcp")
input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
template(name="outfmt" type="string" string="%msg:F,58:2%\n")
if $msg contains "msgnum:" then {
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
}
'
startup
export RCVR_PORT=$TCPFLOOD_PORT
generate_conf 2
add_conf '
action(type="omfwd" target="127.0.0.1" protocol="tcp" port="'$RCVR_PORT'"
rebindinterval="1")
' 2
startup 2
injectmsg2
shutdown_when_empty 2
wait_shutdown 2
shutdown_when_empty
wait_shutdown
seq_check
exit_test

View File

@ -1703,15 +1703,16 @@ BEGINcommitTransaction
char namebuf[264]; /* 256 for FQDN, 5 for port and 3 for transport => 264 */
CODESTARTcommitTransaction;
/* if needed, rebind first. This ensure we can deliver to the rebound addresses.
* Note that rebind requires reconnect (TCP) or socket recreation (UDP) to the
* new targets. This is done by the poolTryResume(), which needs to be made in any case.
* Note that rebind requires reconnect (TCP) or socket recreation (UDP) to
* the new targets. DestructInstanceData() drops the transport state and
* poolTryResume() creates the next connection. The per-worker tcpclt
* objects stay valid across rebinds and must not be reallocated here.
*/
if (pWrkrData->pData->iRebindInterval && (pWrkrData->nXmit++ >= pWrkrData->pData->iRebindInterval)) {
dbgprintf("REBIND (sent %d, interval %d) - omfwd dropping target connection (as configured)\n",
pWrkrData->nXmit, pWrkrData->pData->iRebindInterval);
pWrkrData->nXmit = 0; /* else we have an addtl wrap at 2^31-1 */
DestructInstanceData(pWrkrData, 1);
initTCP(pWrkrData);
LogMsg(0, RS_RET_PARAM_ERROR, LOG_WARNING, "omfwd: dropped connections due to configured rebind interval");
}