proxy: implement CLOSE and FIN relay protocol
- CLOSE: admin connection teardown (drain queues, shutdown, free) Server: handle_close — pause read, drain rq (discard), drain wq to socket, shutdown, free Client: handle_close — drain to_lwip/tx_buf (discard), tcp_close pcb, free ERROR calls handle_close on both sides - FIN: transparent relay event through ETCP (TCP_PROXY_SUBCMD_FIN=0x06) Server: on_fin_cb relays FIN_MSG to client, on_flushed_cb relays FIN_MSG Server: handle_fin relays FIN to remote socket via shutdown(SHUT_WR) Client: recv_cb relays FIN_MSG to exit, tx_waiter_cb relays FIN_MSG Client: handle_fin relays FIN to local TCP via tcp_shutdown(pcb,0,1) - new tcp_conn_pause_read() in tcp_io (EPOLLIN off + cancel waiter) - poll_cb simplified: remove tun_closed&&rem_closed wait block - conn_free drains close_pending before free on both sides - handle_data WARN→INFO for drops after close - tcp_shutdown declared in lwip_tcp.h
This commit is contained in:
1 parent
f8111f7f03
commit
58e45e9232
6 files changed
+117
-64
No files matched your search
@@ -94,6 +94,7 @@ static int tcp_proxy_client_send_data(struct tcp_proxy_client_conn* pc, const ui
|
||||
}
|
||||
|
||||
static int tcp_proxy_client_send_close(struct tcp_proxy_client_conn* pc) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_TRAFFIC, "PROXY SEND sid=%08x", pc->stream_id);
|
||||
int ret = tcp_proxy_client_send_msg(pc->proxy->inst, pc->proxy->via_node_id,
|
||||
TCP_PROXY_SUBCMD_CLOSE, pc->stream_id, NULL, 0, 1);
|
||||
if (ret < 0) { pc->close_pending = 1; return -1; }
|
||||
@@ -111,6 +112,12 @@ static int tcp_proxy_client_send_error(struct tcp_proxy_client_conn* pc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcp_proxy_client_send_fin(struct tcp_proxy_client_conn* pc) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_TRAFFIC, "PROXY FIN RELAY sid=%08x", pc->stream_id);
|
||||
return tcp_proxy_client_send_msg(pc->proxy->inst, pc->proxy->via_node_id,
|
||||
TCP_PROXY_SUBCMD_FIN, pc->stream_id, NULL, 0, 1);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// Вывод: lwIP TCP отправляет IP пакеты через этот callback
|
||||
// ====================================================================
|
||||
@@ -248,7 +255,7 @@ static void tcp_proxy_client_tx_waiter_cb(struct ll_queue* q, void* arg) {
|
||||
tcp_recved(pc->pcb, pc->tx_len);
|
||||
u_free(pc->tx_buf); pc->tx_buf = NULL; pc->tx_len = 0;
|
||||
if (pc->tun_closed && !pc->close_sent && !pc->close_pending)
|
||||
tcp_proxy_client_send_close(pc);
|
||||
tcp_proxy_client_send_fin(pc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,15 +264,13 @@ static err_t tcp_proxy_client_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbu
|
||||
if (!pc) { if (p) pbuf_free(p); return LERR_OK; }
|
||||
|
||||
if (p == NULL || err != LERR_OK) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FIN sid=%08x pcb_state=%u sndbuf=%u cwnd=%u unsent=%p unacked=%p close_sent=%d",
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FIN sid=%08x pcb_state=%u sndbuf=%u cwnd=%u unsent=%p unacked=%p",
|
||||
pc->stream_id, pcb->state, pcb->snd_buf, pcb->cwnd,
|
||||
(void*)pcb->unsent, (void*)pcb->unacked, pc->close_sent);
|
||||
(void*)pcb->unsent, (void*)pcb->unacked);
|
||||
{ uint16_t wnd_gap = TCP_WND_MAX(pcb) - pcb->rcv_wnd;
|
||||
if (wnd_gap > 0) tcp_recved(pcb, wnd_gap); }
|
||||
pc->tun_closed = 1;
|
||||
if (!pc->tx_buf && !pc->close_sent && !pc->close_pending) {
|
||||
if (tcp_proxy_client_send_close(pc) < 0) DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY FIN send_close failed sid=%08x", pc->stream_id);
|
||||
}
|
||||
if (!pc->tx_buf) tcp_proxy_client_send_fin(pc);
|
||||
return LERR_OK;
|
||||
}
|
||||
|
||||
@@ -314,35 +319,16 @@ static err_t tcp_proxy_client_poll_cb(void *arg, struct tcp_pcb *pcb) {
|
||||
if (!pc) return LERR_OK;
|
||||
|
||||
if (pc->error) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY CLEANUP error sid=%08x tun_closed=%d rem_closed=%d", pc->stream_id, pc->tun_closed, pc->rem_closed);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY CLEANUP error sid=%08x", pc->stream_id);
|
||||
if (pc->pcb) { tcp_arg(pc->pcb, NULL); tcp_abort(pc->pcb); pc->pcb = NULL; }
|
||||
tcp_proxy_client_conn_free(pc);
|
||||
return LERR_OK;
|
||||
}
|
||||
|
||||
/* Retry pending CLOSE/ERROR if previous send failed */
|
||||
if (pc->close_pending) {
|
||||
if (pc->error) tcp_proxy_client_send_error(pc);
|
||||
else tcp_proxy_client_send_close(pc);
|
||||
}
|
||||
|
||||
if (pc->tun_closed && pc->rem_closed && pc->pcb) {
|
||||
uint32_t pending = pc->to_lwip ? queue_entry_count(pc->to_lwip) : 0;
|
||||
int done = (pending == 0 && pcb->unsent == NULL && pcb->unacked == NULL);
|
||||
uint32_t sndbuf = tcp_sndbuf(pcb);
|
||||
if (done || sndbuf == 0) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY CLEANUP sid=%08x state=%u sndbuf=%u cwnd=%u pending=%u unsent=%p unacked=%p",
|
||||
pc->stream_id, pcb->state, pcb->snd_buf, pcb->cwnd,
|
||||
pending, (void*)pcb->unsent, (void*)pcb->unacked);
|
||||
struct tcp_pcb *save = pc->pcb; pc->pcb = NULL;
|
||||
tcp_arg(save, NULL);
|
||||
{ uint16_t wnd_gap = TCP_WND_MAX(save) - save->rcv_wnd;
|
||||
if (wnd_gap > 0) tcp_recved(save, wnd_gap); }
|
||||
while (save->unsent) { struct tcp_seg *seg = save->unsent; save->unsent = seg->next; u_free(seg); }
|
||||
tcp_close(save);
|
||||
tcp_proxy_client_conn_free(pc);
|
||||
}
|
||||
}
|
||||
return LERR_OK;
|
||||
}
|
||||
|
||||
@@ -403,6 +389,11 @@ static void tcp_proxy_client_conn_free(struct tcp_proxy_client_conn *pc) {
|
||||
uint32_t pending = pc->to_lwip ? queue_entry_count(pc->to_lwip) : 0;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FREE sid=%08x total_conns=%d to_lwip_q=%u",
|
||||
pc->stream_id, p->conn_count, pending);
|
||||
if (pc->close_pending && p && p->inst) {
|
||||
pc->close_pending = 0;
|
||||
uint8_t subcmd = pc->error ? TCP_PROXY_SUBCMD_ERROR : TCP_PROXY_SUBCMD_CLOSE;
|
||||
tcp_proxy_client_send_msg(p->inst, p->via_node_id, subcmd, pc->stream_id, NULL, 0, 1);
|
||||
}
|
||||
struct tcp_proxy_client_conn **prev = &p->conns;
|
||||
while (*prev) { if (*prev == pc) { *prev = pc->next; p->conn_count--; break; } prev = &(*prev)->next; }
|
||||
if (pc->to_lwip) {
|
||||
@@ -427,7 +418,7 @@ static struct tcp_proxy_client_conn* tcp_proxy_client_find_conn(struct tcp_proxy
|
||||
static void tcp_proxy_client_handle_data(struct tcp_proxy_client* p, struct ETCP_CONN* conn, uint32_t stream_id, struct ll_entry* entry) {
|
||||
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id);
|
||||
if (!pc || pc->rem_closed || pc->error || pc->tun_closed) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "PROXY DATA sid=%08x — no conn/closed, dropping", stream_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY DATA sid=%08x — no conn/closed, dropping", stream_id);
|
||||
queue_dgram_free(entry); queue_entry_free(entry); return;
|
||||
}
|
||||
size_t data_len = entry->len - TCP_PROXY_HDR_SIZE;
|
||||
@@ -442,24 +433,26 @@ static void tcp_proxy_client_handle_data(struct tcp_proxy_client* p, struct ETCP
|
||||
|
||||
static void tcp_proxy_client_handle_close(struct tcp_proxy_client* p, uint32_t stream_id) {
|
||||
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id);
|
||||
if (pc) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM_CLOSED sid=%08x tun_closed=%d",
|
||||
stream_id, pc->tun_closed);
|
||||
pc->rem_closed = 1;
|
||||
} else {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "PROXY CLOSE sid=%08x — no conn, dropping", stream_id);
|
||||
}
|
||||
if (!pc) { DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "PROXY CLOSE sid=%08x — no conn, dropping", stream_id); return; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM_CLOSED sid=%08x tun_closed=%d", stream_id, pc->tun_closed);
|
||||
pc->rem_closed = 1;
|
||||
if (pc->tx_buf) { u_free(pc->tx_buf); pc->tx_buf = NULL; pc->tx_len = 0; }
|
||||
etcp_router_waiter_cancel(pc->proxy->inst, pc->proxy->via_node_id, &pc->tx_waiter);
|
||||
if (pc->pcb) { tcp_arg(pc->pcb, NULL); tcp_close(pc->pcb); pc->pcb = NULL; }
|
||||
tcp_proxy_client_conn_free(pc);
|
||||
}
|
||||
|
||||
static void tcp_proxy_client_handle_error(struct tcp_proxy_client* p, uint32_t stream_id) {
|
||||
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id);
|
||||
if (pc) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY ERROR from exit sid=%08x tun_closed=%d rem_closed=%d",
|
||||
stream_id, pc->tun_closed, pc->rem_closed);
|
||||
if (!pc->error) { pc->error = 1; tcp_proxy_client_send_close(pc); }
|
||||
} else {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY ERROR sid=%08x — no conn, silent drop", stream_id);
|
||||
}
|
||||
if (!pc) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY ERROR sid=%08x — no conn, dropping", stream_id); return; }
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY ERROR from exit sid=%08x tun_closed=%d", stream_id, pc->tun_closed);
|
||||
tcp_proxy_client_handle_close(p, stream_id);
|
||||
}
|
||||
|
||||
static void tcp_proxy_client_handle_fin(struct tcp_proxy_client* p, uint32_t stream_id) {
|
||||
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id);
|
||||
if (!pc || !pc->pcb) return;
|
||||
tcp_shutdown(pc->pcb, 0, 1);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
@@ -506,13 +499,15 @@ void tcp_proxy_client_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entr
|
||||
if (rc) {
|
||||
if (subcmd == TCP_PROXY_SUBCMD_DATA) { tcp_proxy_server_handle_data(inst, conn, entry, stream_id); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { tcp_proxy_server_handle_close(inst, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_ERROR) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "RP ERROR recv sid=%08x", stream_id); tcp_proxy_server_conn_free(rc); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_ERROR) { tcp_proxy_server_handle_error(inst, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_FIN) { tcp_proxy_server_handle_fin(inst, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
}
|
||||
}
|
||||
if (proxy) {
|
||||
if (subcmd == TCP_PROXY_SUBCMD_DATA) { tcp_proxy_client_handle_data(proxy, conn, stream_id, entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { tcp_proxy_client_handle_close(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_ERROR) { tcp_proxy_client_handle_error(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { tcp_proxy_client_handle_close(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_ERROR) { tcp_proxy_client_handle_error(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
if (subcmd == TCP_PROXY_SUBCMD_FIN) { tcp_proxy_client_handle_fin(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; }
|
||||
}
|
||||
if (subcmd == TCP_PROXY_SUBCMD_ERROR) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY ERROR sid=%08x — conn not found, silent drop", stream_id);
|
||||
|
||||
@@ -99,6 +99,12 @@ static void send_error(struct tcp_proxy_server_conn* rc) {
|
||||
}
|
||||
}
|
||||
|
||||
static void send_fin(struct tcp_proxy_server_conn* rc) {
|
||||
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL;
|
||||
if (!inst) return;
|
||||
send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_FIN, rc->stream_id, NULL, 0, 1);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// Коллбэки tcp_io
|
||||
// ====================================================================
|
||||
@@ -108,14 +114,13 @@ static void on_fin_cb(struct tcp_conn* tc, void* arg) {
|
||||
if (write_pending(tc))
|
||||
tcp_conn_set_flushed(tc, on_flushed_cb);
|
||||
else
|
||||
send_close(rc);
|
||||
send_fin(rc);
|
||||
}
|
||||
|
||||
static void on_flushed_cb(struct tcp_conn* tc, void* arg) {
|
||||
(void)tc;
|
||||
struct tcp_proxy_server_conn* rc = (struct tcp_proxy_server_conn*)arg;
|
||||
if (rc->cli_closed) { tcp_proxy_server_conn_free(rc); return; }
|
||||
send_close(rc);
|
||||
if (rc->cli_closed) { shutdown(tc->sock, SHUT_WR); tcp_proxy_server_conn_free(rc); return; }
|
||||
send_fin(rc);
|
||||
}
|
||||
|
||||
static void on_error_cb(struct tcp_conn* tc, int err, void* arg) {
|
||||
@@ -161,6 +166,15 @@ static void read_queue_drain_cb(struct ll_queue* q, void* arg) {
|
||||
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL;
|
||||
struct ll_entry* e = queue_data_get(q);
|
||||
if (!e) { queue_resume_callback(q); return; }
|
||||
if (rc->cli_closed) {
|
||||
do {
|
||||
memory_pool_free(rc->tc->data_pool, e->dgram);
|
||||
queue_entry_free(e);
|
||||
e = queue_data_get(q);
|
||||
} while (e);
|
||||
queue_resume_callback(q);
|
||||
return;
|
||||
}
|
||||
int ret = send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_DATA, rc->stream_id, e->dgram, e->len, 0);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_SOCKET, "SOCK:RECV fd=%d sid=%08x len=%u total=%d",
|
||||
(int)rc->tc->sock, rc->stream_id, e->len, rc->ctx ? rc->ctx->conn_count : 0);
|
||||
@@ -205,6 +219,11 @@ void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) {
|
||||
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",
|
||||
rc->tc ? (int)rc->tc->sock : -1, rc->stream_id, total, rc->cli_closed, rc->tc ? rc->tc->fin : 0, rc->tc ? rc->tc->error : 0);
|
||||
if (rc->close_pending && rc->ctx && rc->ctx->inst) {
|
||||
rc->close_pending = 0;
|
||||
uint8_t subcmd = (rc->tc && rc->tc->error) ? TCP_PROXY_SUBCMD_ERROR : TCP_PROXY_SUBCMD_CLOSE;
|
||||
send_msg(rc->ctx->inst, rc->peer_node_id, subcmd, rc->stream_id, NULL, 0, 1);
|
||||
}
|
||||
if (rc->ctx) {
|
||||
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; }
|
||||
@@ -275,8 +294,8 @@ int tcp_proxy_server_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* c
|
||||
if (!inst) { queue_dgram_free(entry); queue_entry_free(entry); return -1; }
|
||||
struct tcp_proxy_server* ctx = &inst->tcp_proxy_server;
|
||||
struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, stream_id);
|
||||
if (!rc || !rc->tc || rc->tc->sock == SOCKET_INVALID || rc->tc->error) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "TPS handle_data: no/error conn for sid=%08x, dropping", stream_id);
|
||||
if (!rc || !rc->tc || rc->tc->sock == SOCKET_INVALID || rc->tc->error || rc->cli_closed) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "TPS handle_data: no/closed conn sid=%08x, dropping", stream_id);
|
||||
queue_dgram_free(entry); queue_entry_free(entry); return -1;
|
||||
}
|
||||
size_t data_len = entry->len - TCP_PROXY_HDR_SIZE;
|
||||
@@ -300,22 +319,47 @@ int tcp_proxy_server_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* c
|
||||
void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint32_t stream_id) {
|
||||
if (!inst) return;
|
||||
struct tcp_proxy_server* ctx = &inst->tcp_proxy_server;
|
||||
struct tcp_proxy_server_conn** prev = &ctx->conns;
|
||||
while (*prev) {
|
||||
struct tcp_proxy_server_conn* rc = *prev;
|
||||
if (rc->stream_id == stream_id) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:CLOSE_RECV fd=%d sid=%08x total=%d fin=%d write_pend=%d",
|
||||
rc->tc ? (int)rc->tc->sock : -1, stream_id, conn_total(rc), rc->tc ? rc->tc->fin : 0, rc->tc ? write_pending(rc->tc) : 0);
|
||||
rc->cli_closed = 1;
|
||||
if (rc->tc && rc->tc->connected && !write_pending(rc->tc))
|
||||
shutdown(rc->tc->sock, SHUT_WR);
|
||||
if (rc->tc && rc->tc->fin && !write_pending(rc->tc))
|
||||
tcp_proxy_server_conn_free(rc);
|
||||
return;
|
||||
struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, stream_id);
|
||||
if (!rc) { DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "TCP proxy server: CLOSE sid=%08x — no conn", stream_id); return; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:CLOSE_RECV fd=%d sid=%08x total=%d fin=%d write_pend=%d",
|
||||
rc->tc ? (int)rc->tc->sock : -1, stream_id, conn_total(rc),
|
||||
rc->tc ? rc->tc->fin : 0, rc->tc ? write_pending(rc->tc) : 0);
|
||||
rc->cli_closed = 1;
|
||||
if (!rc->tc) { tcp_proxy_server_conn_free(rc); return; }
|
||||
tcp_conn_pause_read(rc->tc);
|
||||
{
|
||||
struct ll_entry* e;
|
||||
while ((e = queue_data_get(rc->tc->read_queue))) {
|
||||
memory_pool_free(rc->tc->data_pool, e->dgram);
|
||||
queue_entry_free(e);
|
||||
}
|
||||
prev = &rc->next;
|
||||
queue_resume_callback(rc->tc->read_queue);
|
||||
}
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "TCP proxy server: CLOSE sid=%08x — no conn, dropping", stream_id);
|
||||
if (write_pending(rc->tc)) {
|
||||
tcp_conn_set_flushed(rc->tc, on_flushed_cb);
|
||||
} else {
|
||||
if (rc->tc->connected) shutdown(rc->tc->sock, SHUT_WR);
|
||||
tcp_proxy_server_conn_free(rc);
|
||||
}
|
||||
}
|
||||
|
||||
void tcp_proxy_server_handle_error(struct UTUN_INSTANCE* inst, uint32_t stream_id) {
|
||||
if (!inst) return;
|
||||
struct tcp_proxy_server* ctx = &inst->tcp_proxy_server;
|
||||
struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, stream_id);
|
||||
if (!rc) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "TCP proxy server: ERROR sid=%08x — no conn", stream_id); return; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:ERROR_RECV fd=%d sid=%08x total=%d fin=%d write_pend=%d",
|
||||
rc->tc ? (int)rc->tc->sock : -1, stream_id, conn_total(rc),
|
||||
rc->tc ? rc->tc->fin : 0, rc->tc ? write_pending(rc->tc) : 0);
|
||||
tcp_proxy_server_handle_close(inst, stream_id);
|
||||
}
|
||||
|
||||
void tcp_proxy_server_handle_fin(struct UTUN_INSTANCE* inst, uint32_t stream_id) {
|
||||
if (!inst) return;
|
||||
struct tcp_proxy_server* ctx = &inst->tcp_proxy_server;
|
||||
struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, stream_id);
|
||||
if (!rc || !rc->tc || !rc->tc->connected) return;
|
||||
shutdown(rc->tc->sock, SHUT_WR);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
|
||||
@@ -16,6 +16,7 @@ struct ETCP_CONN;
|
||||
#define TCP_PROXY_SUBCMD_DATA 0x03
|
||||
#define TCP_PROXY_SUBCMD_CLOSE 0x04
|
||||
#define TCP_PROXY_SUBCMD_ERROR 0x05
|
||||
#define TCP_PROXY_SUBCMD_FIN 0x06
|
||||
|
||||
#define TCP_PROXY_HDR_SIZE 6 // svc_id(1)+subcmd(1)+stream_id(4)
|
||||
#define TCP_PROXY_CONNECT_HDR_SIZE 12 // HDR_SIZE + dest_ip(4)+dest_port(2)
|
||||
@@ -58,5 +59,7 @@ int tcp_proxy_server_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry
|
||||
uint32_t stream_id, uint64_t src_node_id);
|
||||
int tcp_proxy_server_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn, struct ll_entry* entry, uint32_t stream_id);
|
||||
void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint32_t stream_id);
|
||||
void tcp_proxy_server_handle_error(struct UTUN_INSTANCE* inst, uint32_t stream_id);
|
||||
void tcp_proxy_server_handle_fin(struct UTUN_INSTANCE* inst, uint32_t stream_id);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user