Browse Source

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
etcp-inflight-fix
Evgeny 4 months ago
parent
commit
58e45e9232
  1. 7
      lib/tcp_io.c
  2. 3
      lib/tcp_io.h
  3. 1
      src/lwip_tcp/lwip_tcp.h
  4. 83
      src/proxy/tcp_proxy_client.c
  5. 84
      src/proxy/tcp_proxy_server.c
  6. 3
      src/proxy/tcp_proxy_server.h

7
lib/tcp_io.c

@ -329,3 +329,10 @@ void tcp_conn_set_flushed(struct tcp_conn* tc, void (*on_flushed)(struct tcp_con
if (!tc) return;
tc->on_flushed = on_flushed;
}
void tcp_conn_pause_read(struct tcp_conn* tc) {
if (!tc || tc->sock == SOCKET_INVALID) return;
uasync_set_socket_read(tc->ua, tc->socket_id, 0);
queue_waiter_cancel(tc->read_queue, &tc->read_waiter);
tc->read_paused = 1;
}

3
lib/tcp_io.h

@ -94,4 +94,7 @@ void tcp_conn_destroy(struct tcp_conn* tc);
// После вызова сбрасывается. Установить повторно можно в любой момент.
void tcp_conn_set_flushed(struct tcp_conn* tc, void (*on_flushed)(struct tcp_conn* tc, void* arg));
// Принудительная остановка чтения: убирает EPOLLIN и отменяет read_waiter.
void tcp_conn_pause_read(struct tcp_conn* tc);
#endif

1
src/lwip_tcp/lwip_tcp.h

@ -247,6 +247,7 @@ err_t tcp_connect(struct tcp_pcb *pcb, uint32_t ip, uint16_t port, tcp_connected
err_t tcp_write(struct tcp_pcb *pcb, const void *data, uint16_t len, uint8_t apiflags);
err_t tcp_output(struct tcp_pcb *pcb);
err_t tcp_close(struct tcp_pcb *pcb);
err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
void tcp_abort(struct tcp_pcb *pcb);
void tcp_recved(struct tcp_pcb *pcb, uint16_t len);

83
src/proxy/tcp_proxy_client.c

@ -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);

84
src/proxy/tcp_proxy_server.c

@ -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);
}
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);
}
DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "TCP proxy server: CLOSE sid=%08x — no conn, dropping", stream_id);
}
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);
}
// ====================================================================

3
src/proxy/tcp_proxy_server.h

@ -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

Loading…
Cancel
Save