diff --git a/src/remote_proxy.c b/src/remote_proxy.c index a6ac4d84..6e3cc26a 100644 --- a/src/remote_proxy.c +++ b/src/remote_proxy.c @@ -70,6 +70,7 @@ static void rp_sock_read_cb(socket_t sock, void* arg) { if (!rc || rc->sock == SOCKET_INVALID) return; uint8_t buf[8192]; ssize_t n = recv(rc->sock, buf, sizeof(buf), 0); if (n > 0) { + if (rc->cli_closed || rc->error) return; struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "SOCK:RECV fd=%d sid=%08x — inst is NULL, drop", (int)rc->sock, rc->stream_id); return; } DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:RECV fd=%d sid=%08x len=%zd total=%d", (int)rc->sock, rc->stream_id, n, rp_conn_total(rc)); @@ -196,11 +197,15 @@ int remote_proxy_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry* ent return 0; } -int remote_proxy_handle_data(struct UTUN_INSTANCE* inst, struct ll_entry* entry, uint32_t stream_id) { +int remote_proxy_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn, struct ll_entry* entry, uint32_t stream_id) { if (!inst) { queue_dgram_free(entry); queue_entry_free(entry); return -1; } struct remote_proxy_ctx* ctx = &inst->remote_proxy; struct remote_proxy_conn* rc = remote_proxy_find_conn(ctx, stream_id); - if (!rc || rc->sock == SOCKET_INVALID || rc->connected != 1) { DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "RP handle_data drop: no active conn for sid=%08x", stream_id); queue_dgram_free(entry); queue_entry_free(entry); return -1; } + if (!rc || rc->sock == SOCKET_INVALID || rc->connected != 1) { + DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "RP handle_data drop: нет активного соединения для sid=%08x, шлём CLOSE", stream_id); + if (conn) rp_send_msg(inst, conn->peer_node_id, TCP_PROXY_SUBCMD_CLOSE, stream_id, 0, NULL, 0); + queue_dgram_free(entry); queue_entry_free(entry); return -1; + } if (rc->error) { queue_dgram_free(entry); queue_entry_free(entry); return -1; } uint16_t seq; memcpy(&seq, entry->dgram + 6, 2); diff --git a/src/remote_proxy.h b/src/remote_proxy.h index a7ef4b49..0fc6eb88 100644 --- a/src/remote_proxy.h +++ b/src/remote_proxy.h @@ -60,7 +60,7 @@ void rp_conn_free(struct remote_proxy_conn* rc); int remote_proxy_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry* entry, uint32_t stream_id, uint64_t src_node_id); -int remote_proxy_handle_data(struct UTUN_INSTANCE* inst, struct ll_entry* entry, uint32_t stream_id); +int remote_proxy_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn, struct ll_entry* entry, uint32_t stream_id); void remote_proxy_handle_close(struct UTUN_INSTANCE* inst, uint32_t stream_id); #endif diff --git a/src/tcp_proxy.c b/src/tcp_proxy.c index 782899cb..1a5054fe 100644 --- a/src/tcp_proxy.c +++ b/src/tcp_proxy.c @@ -416,9 +416,14 @@ static void handle_connected(struct tcp_proxy* p, uint32_t stream_id, struct ll_ queue_dgram_free(entry); queue_entry_free(entry); } -static void handle_data(struct tcp_proxy* p, uint32_t stream_id, struct ll_entry* entry) { +static void handle_data(struct tcp_proxy* p, struct ETCP_CONN* conn, uint32_t stream_id, struct ll_entry* entry) { struct proxy_conn* pc = find_pc_by_stream(p, stream_id); - if (!pc) { DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "PROXY DATA sid=%08x — no conn, drop", stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; } + if (!pc) { + DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "PROXY DATA sid=%08x — нет соединения, шлём CLOSE", stream_id); + if (conn) proxy_send_msg(p->inst, conn->peer_node_id, TCP_PROXY_SUBCMD_CLOSE, stream_id, 0, NULL, 0); + queue_dgram_free(entry); queue_entry_free(entry); return; + } + if (pc->rem_closed || pc->error) { queue_dgram_free(entry); queue_entry_free(entry); return; } uint16_t seq; memcpy(&seq, entry->dgram + 6, 2); if (!pc->recv_init) { @@ -487,14 +492,14 @@ void tcp_proxy_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { if (inst && inst->remote_proxy.enabled) { struct remote_proxy_conn* rc = remote_proxy_find_conn(&inst->remote_proxy, stream_id); if (rc) { - if (subcmd == TCP_PROXY_SUBCMD_DATA) { remote_proxy_handle_data(inst, entry, stream_id); return; } + if (subcmd == TCP_PROXY_SUBCMD_DATA) { remote_proxy_handle_data(inst, conn, entry, stream_id); return; } if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { remote_proxy_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); rc->error = 1; rp_conn_free(rc); queue_dgram_free(entry); queue_entry_free(entry); return; } } } if (proxy) { if (subcmd == TCP_PROXY_SUBCMD_CONNECTED) { handle_connected(proxy, stream_id, entry); return; } - if (subcmd == TCP_PROXY_SUBCMD_DATA) { handle_data(proxy, stream_id, entry); return; } + if (subcmd == TCP_PROXY_SUBCMD_DATA) { handle_data(proxy, conn, stream_id, entry); return; } if (subcmd == TCP_PROXY_SUBCMD_CLOSE) { handle_close(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; } if (subcmd == TCP_PROXY_SUBCMD_ERROR) { handle_error(proxy, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; } }