Browse Source

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
congestion
Evgeny 4 months ago
parent
commit
f9d5495993
  1. 1
      .gitignore
  2. 14
      src/tcp_proxy.c
  3. 9
      tests/tcp_proxy_full/run_test.sh

1
.gitignore vendored

@ -107,3 +107,4 @@ __pycache__/
cl
build_win.log
/wintun.dll
src/lwip_orig/

14
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; }
}

9
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/"

Loading…
Cancel
Save