|
|
|
|
@ -55,6 +55,18 @@ static int send_msg(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t dst,
|
|
|
|
|
return proxy_send(inst, dst, ETCP_RT_ID_TCP_PROXY_CLIENT, subcmd, sid, data, len, force); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CLOSE может синхронно освободить rc через on_closed: резервируем состояние до push.
|
|
|
|
|
static void server_queue_close(struct tcp_proxy_server_conn* rc) { |
|
|
|
|
if (rc->close_queued) return; |
|
|
|
|
rc->close_queued = 1; |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_PROXY, "proxy exit: queue CLOSE peer=%016llx sid=%08x fd=%d", |
|
|
|
|
(unsigned long long)rc->peer_node_id, rc->stream_id, (int)rc->tc->sock); |
|
|
|
|
if (tcp_conn_push_close(rc->tc) == 0) return; |
|
|
|
|
rc->close_queued = 0; |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "proxy exit: queue CLOSE failed peer=%016llx sid=%08x", |
|
|
|
|
(unsigned long long)rc->peer_node_id, rc->stream_id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FIN относится только к прочитанному направлению: сначала передаём весь read_queue.
|
|
|
|
|
static void server_maybe_finish(struct tcp_proxy_server_conn* rc) { |
|
|
|
|
struct tcp_conn* tc = rc->tc; |
|
|
|
|
@ -64,7 +76,7 @@ static void server_maybe_finish(struct tcp_proxy_server_conn* rc) {
|
|
|
|
|
proxy_flow_flush(&rc->flow); |
|
|
|
|
} |
|
|
|
|
if (rc->flow.fin_sent && rc->flow.fin_received && tc->fin_local) { |
|
|
|
|
if (tcp_conn_push_close(tc) == 0) rc->close_queued = 1; |
|
|
|
|
server_queue_close(rc); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -377,7 +389,7 @@ void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint64_t peer, ui
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (rc->tc->connected) { |
|
|
|
|
if (!rc->close_queued && tcp_conn_push_close(rc->tc) == 0) rc->close_queued = 1; |
|
|
|
|
server_queue_close(rc); |
|
|
|
|
} else tcp_proxy_server_conn_free(rc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|