diff --git a/lib/socket_compat.c b/lib/socket_compat.c index d99bdde5..a3384dc9 100644 --- a/lib/socket_compat.c +++ b/lib/socket_compat.c @@ -211,7 +211,7 @@ int socket_set_mark(socket_t sock, int mark) { } ssize_t socket_sendto(socket_t sock, const void* buf, size_t len, - struct sockaddr* dest, socklen_t dest_len) { + const struct sockaddr* dest, socklen_t dest_len) { #ifdef _WIN32 return sendto(sock, (const char*)buf, (int)len, 0, dest, dest_len); #else diff --git a/lib/socket_compat.h b/lib/socket_compat.h index 8288aa3d..d2fbe4d9 100644 --- a/lib/socket_compat.h +++ b/lib/socket_compat.h @@ -63,7 +63,7 @@ int socket_set_mark(socket_t sock, int mark); // I/O operations ssize_t socket_sendto(socket_t sock, const void* buf, size_t len, - struct sockaddr* dest, socklen_t dest_len); + const struct sockaddr* dest, socklen_t dest_len); ssize_t socket_recvfrom(socket_t sock, void* buf, size_t len, struct sockaddr* src, socklen_t* src_len); diff --git a/src/nat_transport.c b/src/nat_transport.c index 4217a3bf..80a39020 100644 --- a/src/nat_transport.c +++ b/src/nat_transport.c @@ -5,13 +5,13 @@ #include "config_parser.h" #include "tun_if.h" #include "etcp_api.h" -#include "route_bgp.h" +#include "etcp_router.h" #include "../lib/debug_config.h" #include "../lib/mem.h" #include "../lib/ll_queue.h" #include -#define NAT_HDR_SIZE 17 // cmd(1) + src_node_id(8) + dst_node_id(8) +#define NAT_SVC_HDR_SIZE 9 // svc_id(1) + src_node_id(8) static ip_str_t ip_host_to_str(uint32_t ip_host) { struct in_addr a; a.s_addr = htonl(ip_host); @@ -20,37 +20,24 @@ static ip_str_t ip_host_to_str(uint32_t ip_host) { // ==================== Callbacks ==================== -// CLIENT: NAT TUN output → encapsulate in ETCP_ID_NAT → send to provider +// CLIENT: NAT TUN output → encapsulate in ETCP_ID_NAT → send to provider via etcp_router static void nat_transport_client_tun_out_cb(struct ll_queue* q, void* arg) { struct UTUN_INSTANCE* inst = (struct UTUN_INSTANCE*)arg; if (!inst) { queue_resume_callback(q); return; } struct nat_transport_ctx* tr = &inst->nat_tr; - struct eim_nat_ctx* ctx = &inst->nat; struct ll_entry* pkt = queue_data_get(q); if (!pkt) { queue_resume_callback(q); return; } - if (!pkt->dgram || pkt->len < 2) { queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); return; } - if (!tr->nat_via_conn) { - tr->nat_via_conn = route_bgp_find_conn_for_node(inst->bgp, tr->nat_via_node_id); - if (!tr->nat_via_conn) { - DEBUG_WARN(DEBUG_CATEGORY_NAT, "No connection to NAT provider %016llx, dropping", - (unsigned long long)tr->nat_via_node_id); - queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); - return; - } - } - size_t ip_len = pkt->len - 1; - size_t total_len = NAT_HDR_SIZE + ip_len; + size_t total_len = NAT_SVC_HDR_SIZE + ip_len; uint8_t* new_dgram = u_malloc(total_len); if (!new_dgram) { queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); return; } new_dgram[0] = ETCP_ID_NAT; - memcpy(new_dgram + 1, &tr->self_node_id, 8); - memcpy(new_dgram + 9, &tr->nat_via_node_id, 8); - memcpy(new_dgram + 17, pkt->dgram + 1, ip_len); + memcpy(new_dgram + 1, &tr->self_node_id, 8); + memcpy(new_dgram + 9, pkt->dgram + 1, ip_len); struct ll_entry* new_entry = queue_entry_new(0); if (!new_entry) { u_free(new_dgram); queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); return; } @@ -60,18 +47,18 @@ static void nat_transport_client_tun_out_cb(struct ll_queue* q, void* arg) { queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); - int ret = etcp_send(tr->nat_via_conn, new_entry); + int ret = etcp_route_send(inst, tr->nat_via_node_id, new_entry); if (ret != 0) { - DEBUG_WARN(DEBUG_CATEGORY_NAT, "etcp_send to provider failed"); + DEBUG_WARN(DEBUG_CATEGORY_NAT, "NAT client: etcp_route_send to provider %016llx failed", + (unsigned long long)tr->nat_via_node_id); queue_entry_free(new_entry); queue_dgram_free(new_entry); } } -// PROVIDER: NAT TUN output (internet response) → ingress NAT → encapsulate ETCP_ID_NAT → send back +// PROVIDER: NAT TUN output (internet response) → ingress NAT → send back via etcp_router static void nat_transport_provider_tun_out_cb(struct ll_queue* q, void* arg) { struct UTUN_INSTANCE* inst = (struct UTUN_INSTANCE*)arg; if (!inst) { queue_resume_callback(q); return; } - struct nat_transport_ctx* tr = &inst->nat_tr; struct eim_nat_ctx* ctx = &inst->nat; struct ll_entry* pkt = queue_data_get(q); @@ -80,21 +67,20 @@ static void nat_transport_provider_tun_out_cb(struct ll_queue* q, void* arg) { struct eim_nat_entry* entry = NULL; int ret = eim_nat_ingress(ctx, pkt->dgram + 1, pkt->len - 1, &entry); - if (ret != 0 || !entry || !entry->src_conn) { + if (ret != 0 || !entry || entry->src_node_id == 0) { if (ret == 0) DEBUG_WARN(DEBUG_CATEGORY_NAT, "Ingress NAT: no matching entry, dropping"); queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); return; } size_t ip_len = pkt->len - 1; - size_t total_len = NAT_HDR_SIZE + ip_len; + size_t total_len = NAT_SVC_HDR_SIZE + ip_len; uint8_t* new_dgram = u_malloc(total_len); if (!new_dgram) { queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); return; } new_dgram[0] = ETCP_ID_NAT; - memcpy(new_dgram + 1, &tr->self_node_id, 8); - memcpy(new_dgram + 9, &entry->src_node_id, 8); - memcpy(new_dgram + 17, pkt->dgram + 1, ip_len); + memcpy(new_dgram + 1, &inst->nat_tr.self_node_id, 8); + memcpy(new_dgram + 9, pkt->dgram + 1, ip_len); struct ll_entry* new_entry = queue_entry_new(0); if (!new_entry) { u_free(new_dgram); queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); return; } @@ -104,17 +90,17 @@ static void nat_transport_provider_tun_out_cb(struct ll_queue* q, void* arg) { queue_dgram_free(pkt); queue_entry_free(pkt); queue_resume_callback(q); - int send_ret = etcp_send(entry->src_conn, new_entry); + int send_ret = etcp_route_send(inst, entry->src_node_id, new_entry); if (send_ret != 0) { - DEBUG_WARN(DEBUG_CATEGORY_NAT, "etcp_send back to node %016llx failed", + DEBUG_WARN(DEBUG_CATEGORY_NAT, "NAT provider: etcp_route_send back to node %016llx failed", (unsigned long long)entry->src_node_id); queue_entry_free(new_entry); queue_dgram_free(new_entry); } } -// ETCP_ID_NAT receive: CLIENT gets response, PROVIDER gets request +// ETCP_ID_NAT receive via etcp_router: CLIENT gets response, PROVIDER gets request static void nat_transport_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) { - if (!conn || !entry || !entry->dgram || entry->len < NAT_HDR_SIZE) { + if (!conn || !entry || !entry->dgram || entry->len < NAT_SVC_HDR_SIZE) { if (entry) { queue_entry_free(entry); queue_dgram_free(entry); } return; } @@ -124,25 +110,22 @@ static void nat_transport_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry* struct eim_nat_ctx* ctx = &inst->nat; if (!ctx->initialized) { queue_entry_free(entry); queue_dgram_free(entry); return; } - uint64_t src_node_id, dst_node_id; + uint64_t src_node_id; memcpy(&src_node_id, entry->dgram + 1, 8); - memcpy(&dst_node_id, entry->dgram + 9, 8); - uint8_t* ip_data = entry->dgram + NAT_HDR_SIZE; - size_t ip_len = entry->len - NAT_HDR_SIZE; + uint8_t* ip_data = entry->dgram + NAT_SVC_HDR_SIZE; + size_t ip_len = entry->len - NAT_SVC_HDR_SIZE; if (tr->nat_via_node_id != 0) { - // CLIENT: response from provider → write to NAT TUN if (tr->nat_tun) { - tun_write(tr->nat_tun, entry->dgram + NAT_HDR_SIZE - 1, ip_len + 1); + tun_write(tr->nat_tun, entry->dgram + NAT_SVC_HDR_SIZE - 1, ip_len + 1); DEBUG_DEBUG(DEBUG_CATEGORY_NAT, "NAT client: received %zu bytes from provider", ip_len); } } else { - // PROVIDER: request from client → egress NAT → write to NAT TUN int ret = eim_nat_egress(ctx, ip_data, ip_len, src_node_id, conn); if (ret < 0) { DEBUG_WARN(DEBUG_CATEGORY_NAT, "Egress NAT failed"); } else if (ret == 0 && tr->nat_tun) { - tun_write(tr->nat_tun, entry->dgram + NAT_HDR_SIZE - 1, ip_len + 1); + tun_write(tr->nat_tun, entry->dgram + NAT_SVC_HDR_SIZE - 1, ip_len + 1); DEBUG_DEBUG(DEBUG_CATEGORY_NAT, "NAT provider: sent %zu bytes to internet", ip_len); } } @@ -163,19 +146,15 @@ int nat_transport_init(struct UTUN_INSTANCE* inst) { tr->self_node_id = inst->node_id; tr->nat_via_node_id = g->nat_via_node_id; - // Initialize NAT engine (table, forwards, gateway_ip) — only provider needs full init. - // Client also gets minimal init so ctx->initialized==1 for callback check. if (tr->nat_via_node_id == 0) { if (eim_nat_init_ctx(&inst->nat, g) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "Failed to init NAT engine"); return -1; } } else { - // Client: minimal init — mark as initialized without allocating table inst->nat.initialized = 1; } - // Create NAT TUN const char* tun_name = g->nat_tun_ifname[0] ? g->nat_tun_ifname : "tun_nat"; char ip_str[64] = ""; if (g->nat_tun_ip.family == AF_INET) { @@ -194,15 +173,13 @@ int nat_transport_init(struct UTUN_INSTANCE* inst) { return -1; } - // Bind ETCP_ID_NAT - if (etcp_bind(inst, ETCP_ID_NAT, nat_transport_etcp_recv_cb) != 0) { - DEBUG_ERROR(DEBUG_CATEGORY_NAT, "Failed to bind ETCP_ID_NAT"); + if (etcp_router_bind(inst, ETCP_ID_NAT, nat_transport_etcp_recv_cb) != 0) { + DEBUG_ERROR(DEBUG_CATEGORY_NAT, "Failed to bind ETCP_ID_NAT via etcp_router"); tun_close(tr->nat_tun); tr->nat_tun = NULL; eim_nat_destroy_ctx(&inst->nat); return -1; } - // Role-specific TUN callback struct eim_nat_ctx* ctx = &inst->nat; if (tr->nat_via_node_id != 0) { if (tr->nat_tun->output_queue) queue_set_callback(tr->nat_tun->output_queue, nat_transport_client_tun_out_cb, inst); @@ -223,7 +200,7 @@ void nat_transport_destroy(struct UTUN_INSTANCE* inst) { if (!inst || !inst->nat_tr.initialized) return; struct nat_transport_ctx* tr = &inst->nat_tr; - etcp_unbind(inst, ETCP_ID_NAT); + etcp_router_unbind(inst, ETCP_ID_NAT); if (tr->nat_tun) { tun_close(tr->nat_tun); tr->nat_tun = NULL; } diff --git a/src/nat_transport.h b/src/nat_transport.h index 88ee5d2a..f86afc3e 100644 --- a/src/nat_transport.h +++ b/src/nat_transport.h @@ -11,7 +11,6 @@ struct nat_transport_ctx { uint64_t self_node_id; uint64_t nat_via_node_id; struct tun_if* nat_tun; - struct ETCP_CONN* nat_via_conn; int initialized; }; diff --git a/src/routing.c b/src/routing.c index 51dc640f..23ee548b 100644 --- a/src/routing.c +++ b/src/routing.c @@ -7,6 +7,7 @@ #include "packet_dump.h" #include "etcp.h" #include "etcp_api.h" +#include "etcp_router.h" #include "pkt_normalizer.h" #include "utun_instance.h" #include "../lib/ll_queue.h" @@ -140,75 +141,44 @@ void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry, uint64_t return; } - uint64_t dst_node_id = instance->node_id; - struct ETCP_CONN* conn = NULL; struct NODEINFO_Q* nq = route->v_node_info; if (!nq || nq->node.hop_count == 0) { DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "Local route to %s", ip_to_str(&addr, AF_INET).str); } else { - if (nq->paths && nq->paths->head) { - struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)nq->paths->head; - conn = path->conn; - } - if (!conn) { - DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: no path for node %016llx dst=%s conn=%s", - nq->node.node_id, ip_to_str(&addr, AF_INET).str, conn ? conn->log_name : "null"); + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sending %zu bytes to node %016llx dst=%s", + ip_len, (unsigned long long)nq->node.node_id, ip_to_str(&addr, AF_INET).str); + int send_err = etcp_route_send(instance, nq->node.node_id, entry); + if (send_err != 0) { + DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: etcp_route_send failed: dst=%s err=%d", + ip_to_str(&addr, AF_INET).str, send_err); instance->dropped_packets++; - queue_entry_free(entry); - queue_dgram_free(entry); - return; - } - dst_node_id = conn->peer_node_id; - if (!conn->normalizer) { - DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: connection for %s has no normalizer", ip_to_str(&addr, AF_INET).str); - instance->dropped_packets++; - queue_entry_free(entry); - queue_dgram_free(entry); return; } + instance->routed_packets++; + return; } if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TRAFFIC)) { char* packet_str = dump_ip_packet_to_buffer(ip_data, ip_len); DEBUG_DEBUG(DEBUG_CATEGORY_TRAFFIC, "DUMP: %s", packet_str); } else { - DEBUG_TRACE(DEBUG_CATEGORY_TRAFFIC, "NODE %016llx -> NODE %016llx", (unsigned long long)src_node_id, (unsigned long long)dst_node_id); + DEBUG_TRACE(DEBUG_CATEGORY_TRAFFIC, "NODE %016llx -> NODE %016llx", (unsigned long long)src_node_id, (unsigned long long)src_node_id); } - if (!nq || nq->node.hop_count == 0) { - int put_err = queue_data_put(instance->tun->input_queue, entry); - if (put_err != 0) { - DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: failed to put to TUN: dst=%s err=%d", - ip_to_str(&addr, AF_INET).str, put_err); - instance->dropped_packets++; - queue_entry_free(entry); - queue_dgram_free(entry); - return; - } - instance->routed_packets++; - DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sent %zu bytes to TUN", ip_len); - return; - } - - // Send to ETCP - DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sending %zu bytes to ETCP %s dst=%s", - ip_len, conn->log_name[0] ? conn->log_name : "unknown", ip_to_str(&addr, AF_INET).str); - int send_err = etcp_send(conn, entry); - DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "send retcode=%d", send_err); - if (send_err != 0) { - DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: etcp_send failed: dst=%s err=%d", - ip_to_str(&addr, AF_INET).str, send_err); + int put_err = queue_data_put(instance->tun->input_queue, entry); + if (put_err != 0) { + DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: failed to put to TUN: dst=%s err=%d", + ip_to_str(&addr, AF_INET).str, put_err); instance->dropped_packets++; queue_entry_free(entry); queue_dgram_free(entry); return; } - - // Entry sent successfully, don't free here instance->routed_packets++; + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sent %zu bytes to TUN", ip_len); } -// Callback for packets from ETCP (via etcp_bind id=0) +// Callback for packets from ETCP (via etcp_router_bind id=0) static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* pkt) { DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, ""); if (!conn || !pkt) { @@ -237,10 +207,10 @@ static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* pk // Callback for packets from TUN output queue static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) { - (void)q; struct UTUN_INSTANCE* instance = (struct UTUN_INSTANCE*)arg; if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "routing_pkt_from_tun_cb: invalid instance arg=%p", arg); + queue_resume_callback(q); return; } @@ -256,7 +226,7 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) { queue_resume_callback(instance->tun->output_queue); } -// Initialize routing module for instance +// Initialize routing module for instance (route table only, bind happens via routing_bind) int routing_create(struct UTUN_INSTANCE* instance) { if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "routing_create: instance is NULL"); @@ -271,18 +241,25 @@ int routing_create(struct UTUN_INSTANCE* instance) { return -1; } - // Bind ID=0 for receiving data packets from ETCP - if (etcp_bind(instance, ETCP_ID_DATA, routing_pkt_from_etcp_cb) != 0) { - DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "routing_create: failed to bind ETCP ID=0 for node %016llx", + DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routing table created for instance node_id=%016llx", + (unsigned long long)instance->node_id); + + return 0; +} + +// Bind DATA handler via etcp_router (must be called after etcp_router_init) +int routing_bind(struct UTUN_INSTANCE* instance) { + if (!instance) { + DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "routing_bind: instance is NULL"); + return -1; + } + if (etcp_router_bind(instance, ETCP_ID_DATA, routing_pkt_from_etcp_cb) != 0) { + DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "routing_bind: failed to bind ETCP_ID_DATA via etcp_router for node %016llx", (unsigned long long)instance->node_id); - route_table_destroy(instance->rt); - instance->rt = NULL; return -1; } - - DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routing module initialized for instance node_id=%016llx", + DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routing module bound to etcp_router for node_id=%016llx", (unsigned long long)instance->node_id); - return 0; } @@ -293,8 +270,8 @@ void routing_destroy(struct UTUN_INSTANCE* instance) { DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Destroying routing module for node_id=%016llx", (unsigned long long)instance->node_id); - // Unbind ETCP ID=0 - etcp_unbind(instance, ETCP_ID_DATA); + // Unbind DATA handler from etcp_router + etcp_router_unbind(instance, ETCP_ID_DATA); // Clean up route table if exists if (instance->rt) { diff --git a/src/routing.h b/src/routing.h index b1da002d..c298e104 100644 --- a/src/routing.h +++ b/src/routing.h @@ -11,12 +11,19 @@ struct UTUN_INSTANCE; struct ll_entry; /** - * @brief Initialize routing module for instance + * @brief Initialize routing module for instance (route table only) * @param instance UTUN instance * @return 0 on success, -1 on error */ int routing_create(struct UTUN_INSTANCE* instance); +/** + * @brief Bind DATA handler via etcp_router (must be called after etcp_router_init) + * @param instance UTUN instance + * @return 0 on success, -1 on error + */ +int routing_bind(struct UTUN_INSTANCE* instance); + /** * @brief Destroy routing module for instance * @param instance UTUN instance diff --git a/src/tcp_proxy.c b/src/tcp_proxy.c index cffa7ecc..b93b89bd 100644 --- a/src/tcp_proxy.c +++ b/src/tcp_proxy.c @@ -107,7 +107,7 @@ static struct ll_entry* entry_from_data(struct memory_pool* pool, const uint8_t* static inline void tcp_proxy_write_output(struct tcp_proxy* p) { if(uip_len == 0) return; if(p->tun) tun_platform_write(p->tun, uip_buf, uip_len); - else write(p->ip_fd, uip_buf, uip_len); + else if (write(p->ip_fd, uip_buf, uip_len)) {} } // ==================================================================== diff --git a/src/utun_instance.c b/src/utun_instance.c index eaf9c9cf..6a5b6807 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -130,12 +130,18 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u instance->fw.count, instance->fw.bypass_all); } - // etcp_router — сервисная маршрутизация (после BGP, до TCP proxy/NAT) + // etcp_router — сервисная маршрутизация (после BGP, до TCP proxy/NAT/DATA) if (etcp_router_init(instance) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to initialize etcp_router"); return -1; } + // Bind DATA handler via etcp_router (after etcp_router_init) + if (routing_bind(instance) != 0) { + DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "Failed to bind DATA via etcp_router"); + return -1; + } + // Remote proxy (exit node, optional) — must be before tcp_proxy so // tcp_proxy_create can overwrite the handler if it has remote mappings if (remote_proxy_init(instance) != 0) { @@ -326,11 +332,16 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) { // Cleanup remote proxy remote_proxy_destroy(instance); + // Cleanup routing module (unbinds from etcp_router before etcp_router_destroy) + routing_destroy(instance); + + // Cleanup NAT (unbinds from etcp_router before etcp_router_destroy) + if (instance->nat_tr.initialized) { + nat_transport_destroy(instance); + } + // Cleanup etcp_router etcp_router_destroy(instance); - - // Cleanup routing module - routing_destroy(instance); // Cleanup BGP module if (instance->bgp) { @@ -342,11 +353,6 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) { // Cleanup firewall fw_free(&instance->fw); - // Cleanup NAT - if (instance->nat_tr.initialized) { - nat_transport_destroy(instance); - } - // Cleanup config if (instance->config) { DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] Freeing configuration"); diff --git a/tests/Makefile.am b/tests/Makefile.am index ed49bd46..cfab4da8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -222,7 +222,7 @@ test_pkt_normalizer_etcp_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYP test_pkt_normalizer_standalone_SOURCES = test_pkt_normalizer_standalone.c test_pkt_normalizer_standalone_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source -test_pkt_normalizer_standalone_LDADD = $(top_builddir)/src/utun-pkt_normalizer.o $(top_builddir)/src/utun-route_lib.o $(top_builddir)/src/utun-route_node.o $(top_builddir)/src/utun-routing.o $(top_builddir)/src/utun-packet_dump.o $(top_builddir)/src/utun-etcp_api.o $(top_builddir)/src/utun-etcp_debug.o $(CRYPTO_LIBS) $(COMMON_LIBS) +test_pkt_normalizer_standalone_LDADD = $(ETCP_FULL_OBJS) $(SECURE_CHANNEL_OBJS) $(CRYPTO_LIBS) $(COMMON_LIBS) test_etcp_api_SOURCES = test_etcp_api.c test_etcp_api_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/tinycrypt/lib/include -I$(top_srcdir)/tinycrypt/lib/source diff --git a/tests/test_nat_transport.c b/tests/test_nat_transport.c index 2a9ff9c7..42c3e2aa 100644 --- a/tests/test_nat_transport.c +++ b/tests/test_nat_transport.c @@ -26,6 +26,7 @@ #include "../src/nat_transport.h" #include "../src/eim_nat.h" #include "../src/etcp_api.h" +#include "../src/etcp_router.h" #include "../lib/u_async.h" #include "../lib/debug_config.h" #include "../lib/mem.h" @@ -34,7 +35,7 @@ #define TEST_TIMEOUT_MS 15000 #define NODE_ID_PROVIDER 0xAAAA000000000001ULL #define NODE_ID_CLIENT 0xBBBB000000000001ULL -#define NAT_HDR_SIZE 17 // cmd(1) + src_node_id(8) + dst_node_id(8) +#define NAT_SVC_HDR_SIZE 9 // svc_id(1) + src_node_id(8) static struct UTUN_INSTANCE* inst_provider = NULL; static struct UTUN_INSTANCE* inst_client = NULL; @@ -276,7 +277,7 @@ static int test_provider_egress(void) { /* Inject a raw IP/UDP packet directly into provider via ETCP */ DEBUG_INFO(DEBUG_CATEGORY_NAT, "=== test_provider_egress ==="); - // Get the connection from client to provider + // Get the connection from client to provider (for debug info only) struct ETCP_CONN* client_conn = inst_client->connections; if (!client_conn) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "No client connections"); @@ -284,40 +285,28 @@ static int test_provider_egress(void) { } DEBUG_INFO(DEBUG_CATEGORY_NAT, "Client conn peer_node_id=0x%016llx", (unsigned long long)client_conn->peer_node_id); - // But we need to send FROM client TO provider. The client's nat_via_conn - // should be resolved via route_bgp_find_conn_for_node. - // Since we haven't triggered a TUN out yet, we need to force resolve. - // Simpler: use the already-established connection from client side. - struct ETCP_CONN* via_conn = route_bgp_find_conn_for_node(inst_client->bgp, NODE_ID_PROVIDER); - if (!via_conn) { - DEBUG_ERROR(DEBUG_CATEGORY_NAT, "No route to provider"); - return 0; - } - DEBUG_INFO(DEBUG_CATEGORY_NAT, "via_conn peer=0x%016llx", (unsigned long long)via_conn->peer_node_id); - - // Build ETCP_ID_NAT packet + // Build ETCP_ID_NAT packet via etcp_route_send (new format: svc_id + src_node_id + ip_data) size_t ip_len; uint8_t* raw_ip = build_udp_pkt(0x0A0000FE, 40000, 0x08080808, 53, &ip_len); - size_t total = NAT_HDR_SIZE + ip_len; + size_t total = NAT_SVC_HDR_SIZE + ip_len; uint8_t* dgram = u_malloc(total); dgram[0] = ETCP_ID_NAT; - memcpy(dgram + 1, &inst_client->nat_tr.self_node_id, 8); - memcpy(dgram + 9, &inst_provider->nat_tr.self_node_id, 8); - memcpy(dgram + 17, raw_ip, ip_len); + memcpy(dgram + 1, &inst_client->nat_tr.self_node_id, 8); + memcpy(dgram + 9, raw_ip, ip_len); free(raw_ip); struct ll_entry* entry = queue_entry_new(0); entry->dgram = dgram; entry->len = total; - int ret = etcp_send(via_conn, entry); + int ret = etcp_route_send(inst_client, NODE_ID_PROVIDER, entry); if (ret != 0) { - DEBUG_ERROR(DEBUG_CATEGORY_NAT, "etcp_send failed"); + DEBUG_ERROR(DEBUG_CATEGORY_NAT, "etcp_route_send failed"); queue_entry_free(entry); queue_dgram_free(entry); return 0; } - DEBUG_INFO(DEBUG_CATEGORY_NAT, "ETCP_ID_NAT sent from client to provider"); + DEBUG_INFO(DEBUG_CATEGORY_NAT, "ETCP_ID_NAT sent from client to provider via etcp_router"); // Poll to let provider process int cycles = 0; @@ -466,25 +455,21 @@ static int test_full_roundtrip(void) { memset(&inst_provider->nat.table[p], 0, sizeof(struct eim_nat_entry)); inst_provider->nat.next_port = inst_provider->nat.port_start; - // === Step 1: Send ETCP_ID_NAT from client to provider (egress) === - struct ETCP_CONN* via_conn = route_bgp_find_conn_for_node(inst_client->bgp, NODE_ID_PROVIDER); - if (!via_conn) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "No route to provider"); return 0; } - + // === Step 1: Send ETCP_ID_NAT from client to provider via etcp_router (egress) === size_t ip_len; uint8_t* raw_ip = build_udp_pkt(0x0A0000CD, 44444, 0x08080808, 80, &ip_len); - size_t total = NAT_HDR_SIZE + ip_len; + size_t total = NAT_SVC_HDR_SIZE + ip_len; uint8_t* dgram = u_malloc(total); dgram[0] = ETCP_ID_NAT; - memcpy(dgram + 1, &inst_client->nat_tr.self_node_id, 8); - memcpy(dgram + 9, &inst_provider->nat_tr.self_node_id, 8); - memcpy(dgram + 17, raw_ip, ip_len); + memcpy(dgram + 1, &inst_client->nat_tr.self_node_id, 8); + memcpy(dgram + 9, raw_ip, ip_len); free(raw_ip); struct ll_entry* entry = queue_entry_new(0); entry->dgram = dgram; entry->len = total; - int ret = etcp_send(via_conn, entry); - if (ret != 0) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "etcp_send failed"); queue_entry_free(entry); queue_dgram_free(entry); return 0; } + int ret = etcp_route_send(inst_client, NODE_ID_PROVIDER, entry); + if (ret != 0) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "etcp_route_send failed"); queue_entry_free(entry); queue_dgram_free(entry); return 0; } // Poll for provider to process egress int cycles = 0; diff --git a/tests/test_pkt_normalizer_standalone.c b/tests/test_pkt_normalizer_standalone.c index 3c61b85f..ffdebbd5 100644 --- a/tests/test_pkt_normalizer_standalone.c +++ b/tests/test_pkt_normalizer_standalone.c @@ -12,8 +12,9 @@ #include "../src/pkt_normalizer.h" #include "../src/etcp.h" -// Stub for etcp_conn_reinit - should not be called in standalone test -void etcp_conn_reinit(struct ETCP_CONN* etcp) { +// Weak stub for etcp_conn_reinit — overridden if real ETCP is linked +// Weak stub for etcp_conn_reinit - can be overridden by real ETCP implementation +__attribute__((weak)) void etcp_conn_reinit(struct ETCP_CONN* etcp) { (void)etcp; fprintf(stderr, "FAIL: etcp_conn_reinit called - ETCP not initialized in standalone test!\n"); exit(1);