Bug #93 states that a connect() will hang if the remote port of a connection setup doesn't exist. The remote host will respond with the (RST | SYN | ACK) flags set, but we only relay the RST flag back to the local user. This causes the situation described above. We now add a check if the reset happens in the connection state TAP_SYN_RCVD, in which case we add the missing (SYN | ACK) flags. This solves the problem. Signed-off-by: Jon Maloy <jmaloy(a)redhat.com> --- tcp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tcp.c b/tcp.c index c89f323..46df6bd 100644 --- a/tcp.c +++ b/tcp.c @@ -1199,9 +1199,14 @@ static int tcp_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, */ void tcp_rst_do(const struct ctx *c, struct tcp_tap_conn *conn) { + int flags = RST; + if (conn->events == CLOSED) return; + if (conn->events == TAP_SYN_RCVD) + flags |= SYN | ACK; + if (!tcp_send_flag(c, conn, RST)) conn_event(c, conn, CLOSED); } -- 2.48.0
On Sat, 25 Jan 2025 15:16:47 -0500 Jon Maloy <jmaloy(a)redhat.com> wrote:Bug #93 states that a connect() will hang if the remote port of a connection setup doesn't exist. The remote host will respond with the (RST | SYN | ACK) flags set, but we only relay the RST flag back to the local user. This causes the situation described above.Thanks for looking into this.We now add a check if the reset happens in the connection state TAP_SYN_RCVD, in which case we add the missing (SYN | ACK) flags. This solves the problem.I guess that, actually, this part of the problem (or the whole bug #93? I'm not sure) was solved by commit db2c91ae86c7 ("tcp: Set ACK flag on *all* RST segments, even for client in SYN-SENT state").Signed-off-by: Jon Maloy <jmaloy(a)redhat.com> --- tcp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tcp.c b/tcp.c index c89f323..46df6bd 100644 --- a/tcp.c +++ b/tcp.c @@ -1199,9 +1199,14 @@ static int tcp_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, */ void tcp_rst_do(const struct ctx *c, struct tcp_tap_conn *conn) { + int flags = RST; + if (conn->events == CLOSED) return; + if (conn->events == TAP_SYN_RCVD) + flags |= SYN | ACK; +...flags is not used, though. Could it be that you tested this after rebasing on top of db2c91ae86c7?if (!tcp_send_flag(c, conn, RST)) conn_event(c, conn, CLOSED); }-- Stefano