Browse Source

fix: restore conn_free cleanup — tcp_conn_destroy, timers, waiters were lost

Previous edit accidentally removed tcp_conn_destroy, timer cancellations,
and etcp_router_cancel_send_ready from conn_free. Without tcp_conn_destroy
the socket was never removed from uasync, causing repeated EPOLLERR →
repeated conn_free on freed memory → double-free crash.

Added debug logs for freed guard entry and u_free.
etcp-inflight-fix
Evgeny 4 months ago
parent
commit
3c036ecc4c
  1. 11
      src/proxy/tcp_proxy_server.c

11
src/proxy/tcp_proxy_server.c

@ -196,7 +196,11 @@ static int conn_total(struct tcp_proxy_server_conn* rc) {
void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) {
if (!rc) return;
if (rc->freed) return;
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE enter rc=%p freed=%d sid=%08x", (void*)rc, rc->freed, rc->stream_id);
if (rc->freed) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "SOCK:FREE double rc=%p — IGNORED", (void*)rc);
return;
}
rc->freed = 1;
int total = conn_total(rc);
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE fd=%d sid=%08x total=%d cli_closed=%d fin=%d error=%d",
@ -205,6 +209,11 @@ void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) {
struct tcp_proxy_server_conn** prev = &rc->ctx->conns;
while (*prev) { if (*prev == rc) { *prev = rc->next; rc->ctx->conn_count--; break; } prev = &(*prev)->next; }
}
if (rc->tc) { tcp_conn_destroy(rc->tc); rc->tc = NULL; }
if (rc->close_timer) { uasync_cancel_timeout(rc->ua, rc->close_timer); rc->close_timer = NULL; }
if (rc->diag_timer) { uasync_cancel_timeout(rc->ua, rc->diag_timer); rc->diag_timer = NULL; }
if (rc->ctx && rc->ctx->inst) etcp_router_cancel_send_ready(rc->ctx->inst, rc->peer_node_id, ETCP_ID_TCP_PROXY, &rc->pause_waiter);
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE u_free rc=%p", (void*)rc);
u_free(rc);
}

Loading…
Cancel
Save