From f9d54959935cb939bdf639b0b2173067bd80895f Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 30 May 2026 20:40:52 +0300 Subject: [PATCH] fix tcp_proxy deadlock: send CLOSE on TUN FIN + full proxy diagnostics - proxy_recv_cb(p=NULL): now calls transport->close() to signal exit side - Add PROXY FIN/CLOSE/CONNECTED/DATA/FEED/TCP_IN/TCP_OUT logs - Add RP RECV/SEND/CLOSE logs on exit side - Fix queue_dgram_free/queue_entry_free ordering (UAF) in all proxy files - Change TRAFFIC logs from ERROR to INFO level - Add 2 extra 1MB tests in run_test.sh to verify no post-stress stall - stress_client.py: add --verbose per-thread timing (connect/send/recv ms) - mem.c: zero freed memory for early UAF detection --- .gitignore | 1 + src/tcp_proxy.c | 14 +++++++++++--- tests/tcp_proxy_full/run_test.sh | 9 +++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 80246852..17e9e7c6 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,4 @@ __pycache__/ cl build_win.log /wintun.dll +src/lwip_orig/ diff --git a/src/tcp_proxy.c b/src/tcp_proxy.c index 4d0bda8b..3f75b970 100644 --- a/src/tcp_proxy.c +++ b/src/tcp_proxy.c @@ -261,9 +261,13 @@ static err_t proxy_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t if (!pc) { if (p) pbuf_free(p); return LERR_OK; } if (p == NULL || err != LERR_OK) { - DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "TCP proxy: TUN FIN received, stream=%s active=%d", - pc->active ? "active" : "passive", pc->active); + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FIN stream=%016llx tun=1 active=%d", (unsigned long long)(pc->remote_stream_id ? pc->remote_stream_id : 0), pc->active); pc->closing_tun = 1; + if (pc->closing_rem) { + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY CLOSE stream=%016llx tun=1 rem=1 (recv)", (unsigned long long)pc->remote_stream_id); + } else if (pc->transport) { + pc->transport->ops->close(pc->transport); + } return LERR_OK; } @@ -598,7 +602,9 @@ static void etcp_transport_close(struct tcp_proxy_transport* t) { etcp_route_send(et->inst, et->remote_node_id, e); } else queue_entry_free(e); } et->connected = 0; - if (et->conn) { et->conn->transport = NULL; et->conn->closing_rem = 1; } + if (et->conn) { et->conn->transport = NULL; et->conn->closing_rem = 1; + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM=1 stream=%016llx (transport close)", (unsigned long long)et->conn->remote_stream_id); + } } static void etcp_transport_destroy(struct tcp_proxy_transport* t) { @@ -664,6 +670,7 @@ static void handle_connected(struct tcp_proxy* p, uint64_t stream_id, struct ll_ } } else { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "TCP proxy: remote refused stream=%016llx", (unsigned long long)stream_id); + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM=1 stream=%016llx (refused)", (unsigned long long)stream_id); pc->closing_rem = 1; } } queue_dgram_free(entry); queue_entry_free(entry); @@ -731,6 +738,7 @@ void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { struct proxy_conn* pc = find_pc_by_stream(proxy, stream_id); if (pc) { + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM=1 stream=%016llx (CLOSE from exit)", (unsigned long long)stream_id); pc->closing_rem = 1; if (pc->transport) { pc->transport->ops->destroy(pc->transport); pc->transport = NULL; } } diff --git a/tests/tcp_proxy_full/run_test.sh b/tests/tcp_proxy_full/run_test.sh index 0356e2e6..5e58e438 100755 --- a/tests/tcp_proxy_full/run_test.sh +++ b/tests/tcp_proxy_full/run_test.sh @@ -253,6 +253,15 @@ run_test_neg conn_refused --host 10.200.100.99 --port "$REFUSED_PORT" --size 1 - && ((++PASS)) || ((++FAIL)) sleep 1 +# 8-9: проверка что цепочка не заклинила после стресса +run_test basic_1mb_2 --host 10.200.100.1 --port "$ECHO_PORT" --size 1048576 --verify --timeout 15 \ + && ((++PASS)) || ((++FAIL)) +sleep 1 + +run_test basic_1mb_3 --host 10.200.100.1 --port "$ECHO_PORT" --size 1048576 --verify --timeout 15 \ + && ((++PASS)) || ((++FAIL)) +sleep 1 + echo ""; echo "==========================================" echo "Results: $PASS passed, $FAIL failed ($((PASS + FAIL)) total)" echo "Logs: $LOG_DIR/"