proxy/tun: добавить DEBUG-логи диагностики застревания keep-alive (lwIP IN/OUT/RECVED/RTO/PERSIST + per-conn DIAG)

This commit is contained in:
evgeny committed 2026-09-25 22:12:47 +03:00
1 parent 4353daf913
commit a20d73d2be
6 files changed
+82 -2

No files matched your search

+40 -2
View File
@@ -49,6 +49,7 @@ static int tcp_proxy_client_send_data(struct tcp_proxy_client_conn* pc, const
static void tcp_proxy_client_tx_queue_drain_cb(struct ll_queue* q, void* arg);
static void tcp_proxy_client_pause_resume_cb(struct ll_queue* q, void* arg);
static void tcp_proxy_client_retry_timer_cb(void* arg);
static void tcp_proxy_client_diag_timer_cb(void* arg);
// ====================================================================
// Помощник ll_entry
@@ -191,13 +192,25 @@ static void tcp_proxy_client_feed_from_transport(struct tcp_proxy_client_conn *p
uint32_t q_pre = queue_entry_count(pc->to_lwip);
while (1) {
uint16_t space = tcp_sndbuf(pc->pcb);
if (space < TCP_MSS / 2) break;
if (space < TCP_MSS / 2) {
if (queue_entry_count(pc->to_lwip) > 0)
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG,
"PROXY FEED stalled sid=%08x snd_buf=%u to_lwip=%d snd_wnd=%u cwnd=%u",
pc->stream_id, space, queue_entry_count(pc->to_lwip),
pc->pcb->snd_wnd, pc->pcb->cwnd);
break;
}
struct ll_entry *e = queue_data_get(pc->to_lwip);
if (!e) break;
if (e->len <= space) {
err_t ret = tcp_write(pc->pcb, e->dgram, e->len, TCP_WRITE_FLAG_COPY);
if (ret == LERR_OK) { sent_any = 1; queue_dgram_free(e); queue_entry_free(e); }
else { queue_data_put_first(pc->to_lwip, e); break; }
else {
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG,
"PROXY FEED write fail sid=%08x len=%u ret=%d snd_buf=%u q=%d",
pc->stream_id, e->len, ret, space, queue_entry_count(pc->to_lwip) + 1);
queue_data_put_first(pc->to_lwip, e); break;
}
} else {
queue_data_put_first(pc->to_lwip, e);
break;
@@ -258,6 +271,7 @@ static err_t tcp_proxy_client_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t
if (tcp_proxy_client_send_connect(pc) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: send_connect failed sid=%08x to %d.%d.%d.%d:%d", pc->stream_id, pc->dest_ip[0], pc->dest_ip[1], pc->dest_ip[2], pc->dest_ip[3], ntohs(pc->dest_port)); tcp_arg(newpcb, NULL); tcp_abort(newpcb); queue_free(pc->to_lwip); u_free(pc); return LERR_MEM; }
pc->next = p->conns; p->conns = pc; p->conn_count++;
pc->diag_timer = uasync_set_timeout(p->ua, 5000, pc, tcp_proxy_client_diag_timer_cb, "tpc_diag");
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "TCP proxy client: new conn sid=%08x local_port=%u -> %d.%d.%d.%d:%d total_conns=%d snd_wnd=%u mss=%u",
pc->stream_id, newpcb->local_port, pc->dest_ip[0], pc->dest_ip[1], pc->dest_ip[2], pc->dest_ip[3], ntohs(pc->dest_port), p->conn_count, newpcb->snd_wnd, newpcb->mss);
return LERR_OK;
@@ -344,6 +358,28 @@ static void tcp_proxy_client_retry_timer_cb(void* arg) {
}
}
static void tcp_proxy_client_diag_timer_cb(void* arg) {
struct tcp_proxy_client_conn* pc = (struct tcp_proxy_client_conn*)arg;
if (!pc || !pc->proxy) return;
pc->diag_timer = NULL;
if (pc->rem_closed) return;
struct tcp_pcb* pcb = pc->pcb;
if (!pcb || pcb->state == CLOSED) return;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG,
"PROXY DIAG sid=%08x st=%s fin_l=%d fin_r=%d "
"rcv_wnd=%u rcv_ann=%u snd_wnd=%u snd_buf=%u cwnd=%u "
"unsent=%d unacked=%d ooseq=%d "
"tx_q=%d to_lwip=%d to_exit=%u from_exit=%u bp=%u err=%d rem_closed=%d",
pc->stream_id, tcp_debug_state_str(pcb->state),
pc->fin_local, pc->fin_remote,
pcb->rcv_wnd, pcb->rcv_ann_wnd, pcb->snd_wnd, (unsigned)tcp_sndbuf(pcb), pcb->cwnd,
tcp_seg_count(pcb->unsent), tcp_seg_count(pcb->unacked), tcp_seg_count(pcb->ooseq),
pc->tx_queue ? queue_entry_count(pc->tx_queue) : -1,
pc->to_lwip ? queue_entry_count(pc->to_lwip) : -1,
pc->bytes_to_exit, pc->bytes_from_exit, pc->bp_count, pc->error, pc->rem_closed);
pc->diag_timer = uasync_set_timeout(pc->proxy->ua, 5000, pc, tcp_proxy_client_diag_timer_cb, "tpc_diag");
}
static err_t tcp_proxy_client_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
struct tcp_proxy_client_conn *pc = (struct tcp_proxy_client_conn *)arg;
if (!pc || !pc->proxy || pc->rem_closed) { if (p) pbuf_free(p); return LERR_OK; }
@@ -513,6 +549,7 @@ static void tcp_proxy_client_conn_free(struct tcp_proxy_client_conn *pc) {
queue_free(pc->tx_queue); pc->tx_queue = NULL;
}
if (pc->tx_retry_timer) { uasync_cancel_timeout(p->ua, pc->tx_retry_timer); pc->tx_retry_timer = NULL; }
if (pc->diag_timer) { uasync_cancel_timeout(p->ua, pc->diag_timer); pc->diag_timer = NULL; }
if (p && p->inst) etcp_router_cancel_send_ready(p->inst, TOPO_GROUP_UTUN, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, &pc->tx_waiter);
u_free(pc);
}
@@ -794,6 +831,7 @@ void tcp_proxy_client_destroy(struct tcp_proxy_client* p) {
queue_free(pc->tx_queue); pc->tx_queue = NULL;
}
if (pc->tx_retry_timer) { uasync_cancel_timeout(p->ua, pc->tx_retry_timer); pc->tx_retry_timer = NULL; }
if (pc->diag_timer) { uasync_cancel_timeout(p->ua, pc->diag_timer); pc->diag_timer = NULL; }
if (p->inst) etcp_router_cancel_send_ready(p->inst, TOPO_GROUP_UTUN, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, &pc->tx_waiter);
u_free(pc); pc = next;
}
+2
View File
@@ -51,6 +51,8 @@ struct tcp_proxy_client_conn {
uint32_t bytes_from_exit; // байт получено от exit (в lwIP/TUN)
uint32_t bp_count; // счётчик backpressure (send fail)
void* diag_timer; // периодический снимок состояния (DEBUG-категория)
uint8_t dest_ip[4];
uint16_t dest_port;
};