diff --git a/src/proxy/tcp_proxy_client.c b/src/proxy/tcp_proxy_client.c index ed733b82..5b295635 100644 --- a/src/proxy/tcp_proxy_client.c +++ b/src/proxy/tcp_proxy_client.c @@ -682,6 +682,15 @@ void tcp_proxy_client_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* en if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return; } + if (entry->len < ROUTER_SVC_HDR_SIZE) { queue_dgram_free(entry); queue_entry_free(entry); return; } + uint64_t peer, group; + memcpy(&peer, entry->dgram + ROUTER_SVC_SRC_OFF, 8); + memcpy(&group, entry->dgram + ROUTER_SVC_GROUP_OFF, 8); + if (!proxy || peer != proxy->via_node_id || group != TOPO_GROUP_UTUN) { + DEBUG_WARN(DEBUG_CATEGORY_PROXY, "proxy client: unexpected peer=%016llx group=%016llx", + (unsigned long long)peer, (unsigned long long)group); + queue_dgram_free(entry); queue_entry_free(entry); return; + } // CLOSE_ALL / restart-уведомление: [svc_id][src][dst] без payload if (entry->len == ROUTER_SVC_HDR_SIZE && entry->dgram[0] == ETCP_RT_ID_TCP_PROXY_CLIENT) { uint64_t peer_id; diff --git a/src/proxy/tcp_proxy_server.c b/src/proxy/tcp_proxy_server.c index d0e83ab3..ad77b5c2 100644 --- a/src/proxy/tcp_proxy_server.c +++ b/src/proxy/tcp_proxy_server.c @@ -338,9 +338,9 @@ void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) { u_free(rc); } -struct tcp_proxy_server_conn* tcp_proxy_server_find_conn(struct tcp_proxy_server* ctx, uint32_t stream_id) { +struct tcp_proxy_server_conn* tcp_proxy_server_find_conn(struct tcp_proxy_server* ctx, uint64_t peer, uint32_t stream_id) { struct tcp_proxy_server_conn* c; - for (c = ctx->conns; c; c = c->next) if (c->stream_id == stream_id) return c; + for (c = ctx->conns; c; c = c->next) if (c->peer_node_id == peer && c->stream_id == stream_id) return c; return NULL; } @@ -351,6 +351,11 @@ struct tcp_proxy_server_conn* tcp_proxy_server_find_conn(struct tcp_proxy_server int tcp_proxy_server_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry* entry, uint32_t stream_id, uint64_t src_node_id) { if (!inst || !inst->tcp_proxy_server.enabled) { if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return -1; } struct tcp_proxy_server* ctx = &inst->tcp_proxy_server; + if (tcp_proxy_server_find_conn(ctx, src_node_id, stream_id)) { + DEBUG_WARN(DEBUG_CATEGORY_PROXY, "proxy exit: duplicate CONNECT peer=%016llx sid=%08x", (unsigned long long)src_node_id, stream_id); + send_msg(inst, TOPO_GROUP_UTUN, src_node_id, TCP_PROXY_SUBCMD_ERROR, stream_id, NULL, 0, 1); + queue_dgram_free(entry); queue_entry_free(entry); return -1; + } if (entry->len < TCP_PROXY_RECV_HDR_SIZE + 6) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy server: CONNECT too short len=%u", entry->len); queue_dgram_free(entry); queue_entry_free(entry); return -1; } uint8_t* dest_ip = entry->dgram + TCP_PROXY_RECV_HDR_SIZE; uint16_t dest_port = 0; memcpy(&dest_port, dest_ip + 4, 2); @@ -422,9 +427,10 @@ int tcp_proxy_server_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry* int tcp_proxy_server_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn, struct ll_entry* entry, uint32_t stream_id) { (void)conn; + uint64_t peer; memcpy(&peer, entry->dgram + ROUTER_SVC_SRC_OFF, 8); 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); + struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, peer, stream_id); if (!rc || !rc->tc || rc->tc->sock == SOCKET_INVALID || rc->tc->error || rc->cli_closed) { DEBUG_INFO(DEBUG_CATEGORY_PROXY, "TPS handle_data: no/closed conn sid=%08x, dropping", stream_id); queue_dgram_free(entry); queue_entry_free(entry); return -1; @@ -455,10 +461,10 @@ int tcp_proxy_server_handle_data(struct UTUN_INSTANCE* inst, struct ETCP_CONN* c return 0; } -void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint32_t stream_id) { +void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint64_t peer, 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); + struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, peer, stream_id); if (!rc) { DEBUG_WARN(DEBUG_CATEGORY_PROXY, "TCP proxy server: CLOSE sid=%08x — no conn", stream_id); return; } DEBUG_DEBUG(DEBUG_CATEGORY_PROXY, "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), @@ -477,21 +483,21 @@ void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint32_t stream_i if (rc->tc->connected) tcp_conn_push_close(rc->tc); else tcp_proxy_server_conn_free(rc); } -void tcp_proxy_server_handle_error(struct UTUN_INSTANCE* inst, uint32_t stream_id) { +void tcp_proxy_server_handle_error(struct UTUN_INSTANCE* inst, uint64_t peer, 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); + struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, peer, stream_id); if (!rc) { DEBUG_INFO(DEBUG_CATEGORY_PROXY, "TCP proxy server: ERROR sid=%08x — no conn", stream_id); return; } DEBUG_DEBUG(DEBUG_CATEGORY_PROXY, "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_remote : 0, rc->tc ? write_pending(rc->tc) : 0); - tcp_proxy_server_handle_close(inst, stream_id); + tcp_proxy_server_handle_close(inst, peer, stream_id); } -void tcp_proxy_server_handle_fin(struct UTUN_INSTANCE* inst, uint32_t stream_id) { +void tcp_proxy_server_handle_fin(struct UTUN_INSTANCE* inst, uint64_t peer, 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); + struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(ctx, peer, stream_id); if (!rc || !rc->tc || !rc->tc->connected) return; DEBUG_DEBUG(DEBUG_CATEGORY_PROXY, "SOCK:FIN_RECV fd=%d sid=%08x — pushing FIN to wq", (int)rc->tc->sock, stream_id); @@ -529,6 +535,7 @@ void tcp_proxy_server_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { queue_dgram_free(entry); queue_entry_free(entry); return; } + uint64_t peer; memcpy(&peer, entry->dgram + ROUTER_SVC_SRC_OFF, 8); uint8_t subcmd = entry->dgram[ROUTER_SVC_PAYLOAD_OFF]; uint32_t stream_id; memcpy(&stream_id, entry->dgram + ROUTER_SVC_PAYLOAD_OFF + 1, 4); @@ -541,12 +548,12 @@ void tcp_proxy_server_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { return; } if (inst && inst->tcp_proxy_server.enabled) { - struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(&inst->tcp_proxy_server, stream_id); + struct tcp_proxy_server_conn* rc = tcp_proxy_server_find_conn(&inst->tcp_proxy_server, peer, stream_id); 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) { 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 (subcmd == TCP_PROXY_SUBCMD_CLOSE) { tcp_proxy_server_handle_close(inst, peer, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; } + if (subcmd == TCP_PROXY_SUBCMD_ERROR) { tcp_proxy_server_handle_error(inst, peer, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; } + if (subcmd == TCP_PROXY_SUBCMD_FIN) { tcp_proxy_server_handle_fin(inst, peer, stream_id); queue_dgram_free(entry); queue_entry_free(entry); return; } } } if (subcmd == TCP_PROXY_SUBCMD_DATA || subcmd == TCP_PROXY_SUBCMD_CLOSE || subcmd == TCP_PROXY_SUBCMD_FIN || subcmd == TCP_PROXY_SUBCMD_ERROR) { diff --git a/src/proxy/tcp_proxy_server.h b/src/proxy/tcp_proxy_server.h index 3c3291a1..3d9ec657 100644 --- a/src/proxy/tcp_proxy_server.h +++ b/src/proxy/tcp_proxy_server.h @@ -70,7 +70,7 @@ struct tcp_proxy_server { int tcp_proxy_server_init(struct UTUN_INSTANCE* inst); void tcp_proxy_server_destroy(struct UTUN_INSTANCE* inst); -struct tcp_proxy_server_conn* tcp_proxy_server_find_conn(struct tcp_proxy_server* ctx, uint32_t stream_id); +struct tcp_proxy_server_conn* tcp_proxy_server_find_conn(struct tcp_proxy_server* ctx, uint64_t peer, uint32_t stream_id); void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc); void tcp_proxy_server_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry); @@ -78,9 +78,9 @@ void tcp_proxy_server_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry); int tcp_proxy_server_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry* 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); +void tcp_proxy_server_handle_close(struct UTUN_INSTANCE* inst, uint64_t peer, uint32_t stream_id); +void tcp_proxy_server_handle_error(struct UTUN_INSTANCE* inst, uint64_t peer, uint32_t stream_id); +void tcp_proxy_server_handle_fin(struct UTUN_INSTANCE* inst, uint64_t peer, uint32_t stream_id); #ifdef __cplusplus