final RST fix: tcp_recved before closing_tun, feed stop after CLOSE, free unsent before tcp_close, proxy_try_close helper

- proxy_recv_cb(p==NULL): tcp_recved(pcb,gap) before closing_tun
- proxy_feed_from_transport: stop when closing_sent
- proxy_poll_cb cleanup: free unsent before tcp_close
- proxy_try_close helper: shared between poll_cb (500ms) and recv_cb
- pending_out check: don't close if data still queued for exit
- Configs: traffic=info, tun=info for diagnostics
This commit is contained in:
Evgeny committed 2026-05-31 00:02:01 +03:00
1 parent 40d35ee2a5
commit 4b7a1656fc
4 files changed
+22 -17

No files matched your search

+17 -11
View File
@@ -52,6 +52,7 @@ static int etcp_transport_send(struct tcp_proxy_transport* t, const uint8_t* da
static void etcp_transport_close(struct tcp_proxy_transport* t);
static void etcp_transport_destroy(struct tcp_proxy_transport* t);
static void sock_transport_connect(struct sock_transport* st);
static void proxy_try_close(struct proxy_conn *pc);
static struct sock_transport* sock_transport_create(struct proxy_conn* pc, struct UASYNC* ua);
static struct etcp_transport* etcp_transport_create(struct proxy_conn* pc, struct UTUN_INSTANCE* inst, uint64_t remote_node_id);
@@ -308,20 +309,25 @@ static void proxy_err_cb(void *arg, err_t err) {
if (pc->transport && !pc->closing_sent) pc->transport->ops->close(pc->transport);
}
static void proxy_try_close(struct proxy_conn *pc) {
if (!pc->closing_tun || pc->closing_sent || pc->closing_rem) return;
if (!pc->transport || !pc->pcb) return;
uint32_t pending = pc->transport_to_uip ? queue_entry_count(pc->transport_to_uip) : 0;
uint32_t pending_out = pc->uip_to_transport ? queue_entry_count(pc->uip_to_transport) : 0;
int done = (pending == 0 && pending_out == 0 && pc->pcb->unsent == NULL && pc->pcb->unacked == NULL);
uint32_t sndbuf = tcp_sndbuf(pc->pcb);
if (done || sndbuf == 0) {
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY CLOSE stream=%016llx tun=1 pending=%u pending_out=%u done=%d sndbuf=%u cwnd=%u unsent=%p unacked=%p",
(unsigned long long)pc->remote_stream_id, pending, pending_out, done, sndbuf,
pc->pcb->cwnd, (void*)pc->pcb->unsent, (void*)pc->pcb->unacked);
pc->transport->ops->close(pc->transport);
}
}
static err_t proxy_poll_cb(void *arg, struct tcp_pcb *pcb) {
struct proxy_conn *pc = (struct proxy_conn *)arg;
if (!pc) return LERR_OK;
if (pc->closing_tun && !pc->closing_sent && !pc->closing_rem && pc->transport && pc->pcb) {
uint32_t pending = pc->transport_to_uip ? queue_entry_count(pc->transport_to_uip) : 0;
int done = (pending == 0 && pc->pcb->unsent == NULL && pc->pcb->unacked == NULL);
uint32_t sndbuf = tcp_sndbuf(pc->pcb);
if (done || sndbuf == 0) {
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY CLOSE stream=%016llx tun=1 pending=%u done=%d sndbuf=%u cwnd=%u unsent=%p unacked=%p",
(unsigned long long)pc->remote_stream_id, pending, done, sndbuf,
pc->pcb->cwnd, (void*)pc->pcb->unsent, (void*)pc->pcb->unacked);
pc->transport->ops->close(pc->transport);
}
}
proxy_try_close(pc);
if (pc->closing_tun && (pc->closing_rem || pc->closing_sent) && pc->pcb) {
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY CLEANUP stream=%016llx tun=1 rem=%d sent=%d cwnd=%u sndbuf=%u unsent=%p unacked=%p",
(unsigned long long)pc->remote_stream_id, pc->closing_rem, pc->closing_sent,