diff --git a/lib/platform_compat.h b/lib/platform_compat.h index de43dc2..b828b25 100644 --- a/lib/platform_compat.h +++ b/lib/platform_compat.h @@ -12,7 +12,16 @@ #include #include #include - #include +#include + +// Byte order conversion functions +#ifdef _WIN32 + #include + #define htobe64(x) _byteswap_uint64(x) + #define be64toh(x) _byteswap_uint64(x) +#elif defined(__linux__) + #include +#endif // POSIX functions missing on Windows #define strcasecmp _stricmp diff --git a/src/route_bgp.c b/src/route_bgp.c index fb450f9..cb94de7 100644 --- a/src/route_bgp.c +++ b/src/route_bgp.c @@ -55,18 +55,18 @@ static void format_ip(uint32_t ip, char* buffer) { snprintf(buffer, 16, "%u.%u.%u.%u", b[3], b[2], b[1], b[0]); } -typedef struct { +struct BGP_WITHDRAW_PACKET { uint8_t cmd; uint8_t subcmd; uint64_t node_id; -} BGP_WITHDRAW_PACKET __attribute__((packed)); +} __attribute__((packed)); -typedef struct { +struct BGP_REROUTE_PACKET { uint8_t cmd; uint8_t subcmd; uint64_t old_node_id; struct ROUTE_PEER_INFO peer_info; -} BGP_REROUTE_PACKET __attribute__((packed)); +} __attribute__((packed)); /** * @brief Рассылает маршрут всем соединениям (кроме exclude) @@ -288,6 +288,8 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* return; } + struct ROUTE_BGP* bgp = instance->bgp; + struct BGP_ENTRY_PACKET* pkt = (struct BGP_ENTRY_PACKET*)entry->dgram; // Проверяем команду @@ -309,17 +311,17 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* uint64_t old_node_id = 0; struct ROUTE_PEER_INFO *peer_info; if (pkt->subcmd == ROUTE_SUBCMD_ENTRY_REROUTE) { - if (entry->len < sizeof(BGP_REROUTE_PACKET)) { + if (entry->len < sizeof(struct BGP_REROUTE_PACKET)) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Invalid REROUTE packet size"); queue_dgram_free(entry); queue_entry_free(entry); return; } - BGP_REROUTE_PACKET *reroute_pkt = (BGP_REROUTE_PACKET*)pkt; + struct BGP_REROUTE_PACKET *reroute_pkt = (struct BGP_REROUTE_PACKET*)pkt; old_node_id = be64toh(reroute_pkt->old_node_id); peer_info = &reroute_pkt->peer_info; } else { - if (entry->len < sizeof(BGP_ENTRY_PACKET)) { + if (entry->len < sizeof(struct BGP_ENTRY_PACKET)) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Invalid ENTRY packet size"); queue_dgram_free(entry); queue_entry_free(entry); @@ -351,7 +353,6 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* new_route.hop_count = hop_count + 1; new_route.latency = latency + (from_conn->rtt_last * 10); new_route.metrics.latency_ms = new_route.latency / 10; - new_route.metrics.hop_count = new_route.hop_count; // Set defaults for other metrics new_route.metrics.bandwidth_kbps = 100000; // example default new_route.metrics.packet_loss_rate = 0; @@ -397,13 +398,13 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* break; } case ROUTE_SUBCMD_WITHDRAW: { - if (entry->len < sizeof(BGP_WITHDRAW_PACKET)) { + if (entry->len < sizeof(struct BGP_WITHDRAW_PACKET)) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Invalid WITHDRAW packet size"); queue_dgram_free(entry); queue_entry_free(entry); return; } - BGP_WITHDRAW_PACKET *withdraw_pkt = (BGP_WITHDRAW_PACKET*)pkt; + struct BGP_WITHDRAW_PACKET *withdraw_pkt = (struct BGP_WITHDRAW_PACKET*)pkt; uint64_t withdrawn_node_id = be64toh(withdraw_pkt->node_id); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received WITHDRAW for node %016llx", @@ -449,24 +450,22 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* return; } struct BGP_NODEINFO_PACKET *info_pkt = (struct BGP_NODEINFO_PACKET*)pkt; - struct NODE_CONNS_INFO *node_info = &info_pkt->node_info; - - if (node_info->connlist_count == 0) break; - uint64_t target_node_id = be64toh(node_info->NODE_CONN_INFO[0].node_id); // assume first + uint64_t target_node_id = be64toh(info_pkt->conn_info.node_id); - DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received NODEINFO for node %016llx, count=%d", - (unsigned long long)target_node_id, node_info->connlist_count); + DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received NODEINFO for node %016llx", + (unsigned long long)target_node_id); struct ROUTE_TABLE* table = instance->rt; for (size_t i = 0; i < table->count; i++) { if (table->entries[i].node_id == target_node_id) { size_t size = sizeof(struct NODE_CONNS_INFO) + - node_info->connlist_count * sizeof(struct NODE_CONN_INFO); + sizeof(struct NODE_CONN_INFO); struct NODE_CONNS_INFO *new_list = u_malloc(size); if (new_list) { - memcpy(new_list, node_info, size); + new_list->connlist_count = 1; new_list->ref_count = 1; + memcpy(&new_list->conn_info[0], &info_pkt->conn_info, sizeof(struct NODE_CONN_INFO)); if (table->entries[i].conn_list) { if (--table->entries[i].conn_list->ref_count == 0) { diff --git a/src/route_lib.c b/src/route_lib.c index ce26e67..edd1e34 100644 --- a/src/route_lib.c +++ b/src/route_lib.c @@ -5,6 +5,7 @@ #include "route_lib.h" #include "etcp_connections.h" +#include "u_async.h" #include "../lib/debug_config.h" #include #include @@ -18,6 +19,9 @@ #define MAX_SUBNET_VALIDATION_RANGES 50 #define ROUTE_CACHE_SIZE 10 +// Forward declarations +static const char* route_type_to_string(route_type_t type); + /** * @brief Структура кеша маршрутов (LRU) */ diff --git a/src/routing.c b/src/routing.c index d6adc46..710dc2d 100644 --- a/src/routing.c +++ b/src/routing.c @@ -34,13 +34,12 @@ static uint32_t extract_dst_ip(uint8_t* data, size_t len) { uint8_t version = (data[IP_HDR_VERSION_OFFSET] >> 4) & 0x0F; if (version == IPv6_VERSION) { - // IPv6 - drop for now - DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "IPv6 packet detected, dropping"); + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "IPv6 packet detected, dropping"); return 0; } if (version != IPv4_VERSION) { - DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "Unknown IP version: %d", version); + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "Unknown IP version: %d", version); return 0; } @@ -108,12 +107,12 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry) { struct in_addr addr; addr.s_addr = htonl(dst_ip); - DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "route_pkt: dst=%s len=%zu", ip_to_str(&addr, AF_INET).str, ip_len); + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: dst=%s len=%zu", ip_to_str(&addr, AF_INET).str, ip_len); // Lookup route struct ROUTE_ARRAY* routes = route_table_lookup(instance->rt, dst_ip); if (!routes || routes->routes == 0) { - DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_pkt: no route to %s, dropping", ip_to_str(&addr, AF_INET).str); + DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "route_pkt: no route to %s, dropping", ip_to_str(&addr, AF_INET).str); instance->dropped_packets++; queue_entry_free(entry); queue_dgram_free(entry); @@ -132,7 +131,7 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry) { } // Entry sent to TUN, don't free here instance->routed_packets++; - DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "route_pkt: sent %zu bytes to TUN", ip_len); + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sent %zu bytes to TUN", ip_len); return; } @@ -155,7 +154,7 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry) { } // Send to ETCP - DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "route_pkt: sending %zu bytes to ETCP %s", ip_len, conn->log_name); + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sending %zu bytes to ETCP %s", ip_len, conn->log_name); if (etcp_send(conn, entry) != 0) { DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: etcp_send failed for %s", ip_to_str(&addr, AF_INET).str); instance->dropped_packets++; diff --git a/src/utun_instance.c b/src/utun_instance.c index f37279f..355481e 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -78,8 +78,8 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u entry.metrics.bandwidth_kbps = UINT32_MAX; // Unlimited entry.metrics.latency_ms = 0; entry.metrics.packet_loss_rate = 0; - entry.metrics.hop_count = 0; - entry.destination_node_id = instance->node_id; + entry.hop_count = 0; + entry.node_id = instance->node_id; if (route_table_insert(instance->rt, &entry)) { struct in_addr addr; diff --git a/tests/test_bgp_route_exchange.c b/tests/test_bgp_route_exchange.c index 1ecb4c4..7de02bb 100644 --- a/tests/test_bgp_route_exchange.c +++ b/tests/test_bgp_route_exchange.c @@ -206,8 +206,8 @@ static void print_routing_table(struct UTUN_INSTANCE* inst, const char* name) { DEBUG_INFO(DEBUG_CATEGORY_ROUTING, " Route %zu: %s/%d [%s] node_id=%016llX hops=%d", i + 1, network_str, entry->prefix_length, type_str, - (unsigned long long)entry->destination_node_id, - entry->metrics.hop_count); + (unsigned long long)entry->node_id, + entry->hop_count); } DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "=====================================\n"); } @@ -225,7 +225,7 @@ static int check_learned_route(struct UTUN_INSTANCE* inst, uint32_t network, if (entry->network == network && entry->prefix_length == prefix_len && entry->type == ROUTE_TYPE_LEARNED && - entry->destination_node_id == expected_node_id) { + entry->node_id == expected_node_id) { return 1; } } diff --git a/tests/test_route_lib.c b/tests/test_route_lib.c index 5687d2b..eb03732 100644 --- a/tests/test_route_lib.c +++ b/tests/test_route_lib.c @@ -53,7 +53,7 @@ static void create_test_route(struct ROUTE_ENTRY *entry, uint32_t network, entry->flags = ROUTE_FLAG_ACTIVE; entry->metrics.latency_ms = 10 + (rand() % 100); entry->metrics.packet_loss_rate = rand() % 50; - entry->metrics.hop_count = 1 + (rand() % 5); + entry->hop_count = 1 + (rand() % 5); entry->metrics.bandwidth_kbps = 1000 + (rand() % 9000); route_update_quality(entry); } @@ -251,9 +251,9 @@ static void test_update_quality(void) { struct ROUTE_ENTRY entry; memset(&entry, 0, sizeof(entry)); - entry.metrics.latency_ms = 10; + entry.latency = 100; // x0.1 ms units (= 10 ms) entry.metrics.packet_loss_rate = 0; - entry.metrics.hop_count = 1; + entry.hop_count = 1; ASSERT(route_update_quality(&entry), "failed to update quality"); @@ -261,9 +261,9 @@ static void test_update_quality(void) { struct ROUTE_ENTRY entry2; memset(&entry2, 0, sizeof(entry2)); - entry2.metrics.latency_ms = 5; + entry2.latency = 50; // x0.1 ms units (= 5 ms) entry2.metrics.packet_loss_rate = 0; - entry2.metrics.hop_count = 1; + entry2.hop_count = 1; route_update_quality(&entry2); ASSERT(entry2.metrics.metric < entry.metrics.metric, @@ -547,7 +547,7 @@ static void test_route_withdraw_scenario(void) { entry.next_hop = peer; entry.type = ROUTE_TYPE_LEARNED; entry.flags = ROUTE_FLAG_ACTIVE | ROUTE_FLAG_LEARNED; - entry.destination_node_id = 0x1234567890ABCDEFULL; + entry.node_id = 0x1234567890ABCDEFULL; ASSERT(route_table_insert(table, &entry), "failed to insert learned route"); ASSERT_EQ(table->stats.learned_routes, 1, "should have 1 learned route");