Browse Source

proxy: rename pcb guard, dedupe abort; tasks: FIN_WAIT_2 leak

master
evgeny 3 days ago
parent
commit
74ca98b38f
  1. 5
      doc/tasks.md
  2. 13
      src/proxy/tcp_proxy_client.c

5
doc/tasks.md

@ -220,6 +220,11 @@
в нескольких прогонах. В `test_dm_e2e` при teardown остаётся timer-leak (~68 узлов,
`router_no_route`), не влияет на результат — стоит разобрать отдельно.
[ ] **lwip/proxy: утечка pcb в FIN_WAIT_2** — `tcp_shutdown(pcb,0,1)` (half-close по FIN от
exit) не ставит `TF_RXCLOSED`, поэтому таймаут FIN_WAIT_2 в `tcp_slowtmr` не срабатывает:
если браузер никогда не пришлёт FIN, pcb навсегда остаётся в FIN_WAIT_2 (утечка, не crash).
Двойной free по TIME_WAIT уже закрыт (detach по локальному закрытию + guard abort).
## Открытые флаки
[+] **test_chat_join_e2e** — сделано. Причина: ложный критерий успеха джойнера J.
`wait_group_started()` проверял `senders_list` непуст в предположении «senders_list

13
src/proxy/tcp_proxy_client.c

@ -547,7 +547,7 @@ static void tcp_proxy_client_conn_detach(struct tcp_proxy_client_conn *pc) {
// Проверка, что pc->pcb ещё не освобождён пулом (защита от висячего указателя:
// таймер TIME_WAIT мог освободить pcb без err_cb). Возвращает 0 и сбрасывает
// pc->pcb, если pcb освобождён; иначе 1 (pcb валиден).
static int tcp_proxy_client_pcb_valid(struct tcp_proxy_client_conn *pc, const char* why) {
static int tcp_proxy_client_pcb_guard(struct tcp_proxy_client_conn *pc, const char* why) {
struct tcp_pcb* pcb = pc->pcb;
struct lwip_tcp_ctx* ctx = pc->proxy ? pc->proxy->lwip : NULL;
if (ctx && memory_pool_is_freed(ctx->pcb_pool, pcb)) {
@ -564,16 +564,11 @@ static int tcp_proxy_client_pcb_valid(struct tcp_proxy_client_conn *pc, const ch
static void tcp_proxy_client_abort_pcb(struct tcp_proxy_client_conn *pc, const char* why) {
if (!pc || !pc->pcb) return;
struct tcp_pcb* pcb = pc->pcb;
if (!tcp_proxy_client_pcb_valid(pc, why)) return;
if (!tcp_proxy_client_pcb_guard(pc, why)) return;
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY %s pcb=%p state=%s sid=%08x",
why, (void*)pcb, tcp_debug_state_str(pcb->state), pc->stream_id);
tcp_arg(pcb, NULL);
tcp_recv(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_err(pcb, NULL);
tcp_poll(pcb, NULL, 0);
tcp_proxy_client_conn_detach(pc);
tcp_abort(pcb);
pc->pcb = NULL;
}
// ====================================================================
@ -615,7 +610,7 @@ static void tcp_proxy_client_handle_close(struct tcp_proxy_client* p, uint32_t s
if (!pc) { DEBUG_WARN(DEBUG_CATEGORY_PROXY, "PROXY CLOSE sid=%08x — no conn, dropping", stream_id); return; }
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY REM_CLOSED sid=%08x fin_local=%d pcb=%p", stream_id, pc->fin_local, (void*)pc->pcb);
pc->rem_closed = 1;
if (pc->pcb && tcp_proxy_client_pcb_valid(pc, "CLOSE")) {
if (pc->pcb && tcp_proxy_client_pcb_guard(pc, "CLOSE")) {
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY CLOSE pcb=%p state=%s sid=%08x",
(void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), stream_id);
tcp_arg(pc->pcb, NULL);

Loading…
Cancel
Save