route improvements
This commit is contained in:
1 parent
33629a17c6
commit
aa5171bcd1
20 files changed
+183
-175
No files matched your search
@@ -66,6 +66,8 @@ static uint32_t parse_debug_categories(const char *value) {
|
||||
categories |= DEBUG_CATEGORY_ROUTING;
|
||||
} else if (strstr(token, "timers")) {
|
||||
categories |= DEBUG_CATEGORY_TIMERS;
|
||||
} else if (strstr(token, "traffic")) {
|
||||
categories |= DEBUG_CATEGORY_TRAFFIC;
|
||||
} else if (strstr(token, "all")) {
|
||||
categories |= DEBUG_CATEGORY_ALL;
|
||||
} else if (strstr(token, "none")) {
|
||||
|
||||
@@ -256,7 +256,7 @@ int config_ensure_keys_and_node_id(const char *filename) {
|
||||
struct global_config *global = &config->global;
|
||||
|
||||
// Debug: print what we found
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONFIG, "Checking config - priv_key='%s' (len=%zu), pub_key='%s' (len=%zu), node_id=%llu",
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONFIG, "Checking config - priv_key='%s' (len=%zu), pub_key='%s' (len=%zu), node_id=%016llx",
|
||||
global->my_private_key_hex ? global->my_private_key_hex : "NULL",
|
||||
global->my_private_key_hex ? strlen(global->my_private_key_hex) : 0,
|
||||
global->my_public_key_hex ? global->my_public_key_hex : "NULL",
|
||||
|
||||
+12
-13
@@ -105,8 +105,10 @@ static uint16_t timestamp_diff(uint16_t t1, uint16_t t2) {
|
||||
return (UINT16_MAX - t2) + t1 + 1;
|
||||
}
|
||||
|
||||
static const char EMPTY_NAME[] = "";
|
||||
|
||||
// Create new ETCP connection
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* name) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!instance) return NULL;
|
||||
|
||||
@@ -128,8 +130,9 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
|
||||
etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT));
|
||||
etcp->optimal_inflight=10000;
|
||||
etcp->initialized=0;
|
||||
etcp->name = u_strdup(name);
|
||||
// Initialize log_name with local node_id (peer will be updated later when known)
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04X->????", (uint16_t)instance->node_id);
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04X->???? [%s]", (uint16_t)instance->node_id, etcp->name);
|
||||
|
||||
if (!etcp->input_queue || !etcp->output_queue || !etcp->input_send_q || !etcp->recv_q || !etcp->ack_q ||
|
||||
!etcp->input_wait_ack || !etcp->inflight_pool || !etcp->io_pool) {
|
||||
@@ -241,6 +244,8 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
etcp->links = NULL;
|
||||
}
|
||||
|
||||
u_free(etcp->name);
|
||||
|
||||
// Clear next pointer to prevent dangling references
|
||||
etcp->next = NULL;
|
||||
|
||||
@@ -250,7 +255,6 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
|
||||
// Reset connection
|
||||
void etcp_conn_reset(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
// Reset IDs
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Resetting ETCP instance [%d]", etcp->log_name);
|
||||
etcp->next_tx_id = 1;
|
||||
@@ -303,7 +307,6 @@ void etcp_conn_reset(struct ETCP_CONN* etcp) {
|
||||
}
|
||||
|
||||
void etcp_conn_reinit(struct ETCP_CONN* etcp) {// Если сбой в обмене или ребутнулась одна из сторон -> необходимо заново переинициализировать соединение
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Reinitializing ETCP connection [%s]", etcp->log_name);
|
||||
|
||||
etcp->reinit_count++;
|
||||
@@ -329,13 +332,9 @@ void etcp_conn_ready(struct ETCP_CONN* conn) {
|
||||
|
||||
conn->initialized = 1;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] Connection ready", conn->log_name);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "etcp_conn_ready: conn=%p initialized=%d cbk=%p",
|
||||
(void*)conn, conn->initialized, (void*)conn->ready_cbk);
|
||||
|
||||
// Вызываем callback если установлен
|
||||
if (conn->ready_cbk) {
|
||||
conn->ready_cbk(conn, conn->ready_arg);
|
||||
}
|
||||
if (conn->ready_cbk) conn->ready_cbk(conn, conn->ready_arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -345,7 +344,8 @@ void etcp_update_log_name(struct ETCP_CONN* etcp) {
|
||||
if (!etcp || !etcp->instance) return;
|
||||
uint16_t local_id = etcp->instance->node_id;
|
||||
uint16_t peer_id = etcp->peer_node_id;
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04X->%04X", local_id, peer_id);
|
||||
const char* name = etcp->name ? etcp->name : EMPTY_NAME;
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04X->%04X [%s]", local_id, peer_id, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -441,7 +441,6 @@ static void input_queue_try_resume(struct ETCP_CONN* etcp) {// при ACK
|
||||
}
|
||||
|
||||
void etcp_stats(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp) return;
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] stats for conn=%p:", etcp->log_name, etcp);
|
||||
@@ -982,8 +981,8 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint32_t d=seq - etcp->last_delivered_id;
|
||||
if (d>MAX_INFLIGHT_SIZE) {
|
||||
int32_t d=seq - etcp->last_delivered_id;
|
||||
if (d>MAX_INFLIGHT_SIZE || d<-MAX_INFLIGHT_SIZE) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] Received packet out of inflight bounds: seq=%d last delivered=%d", etcp->log_name, seq, etcp->last_delivered_id);
|
||||
len=0;
|
||||
break;
|
||||
|
||||
+4
-3
@@ -160,12 +160,13 @@ struct ETCP_CONN {
|
||||
uint32_t tx_state; // 1 - wait link ready, 2
|
||||
uint32_t debug[8]; // 8 значений для дебага (live watch)
|
||||
|
||||
// Logging identifier (format: "XXXX→XXXX" - last 4 digits of local and peer node_id)
|
||||
char log_name[16];
|
||||
// Logging identifier (format: "XXXX→XXXX [name]" - last 4 digits of local and peer node_id + optional name)
|
||||
char log_name[256];
|
||||
const char* name; // Connection name from config (e.g., "client_test1"), or NULL/empty
|
||||
};
|
||||
|
||||
// Functions
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance);
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* name);
|
||||
void etcp_connection_close(struct ETCP_CONN* etcp);
|
||||
|
||||
void etcp_conn_reset(struct ETCP_CONN* etcp);
|
||||
|
||||
@@ -29,12 +29,6 @@ void etcp_conn_set_ready_cbk(struct ETCP_CONN* conn, etcp_on_conn_ready callback
|
||||
conn->ready_arg = arg;
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP_API, "etcp_conn_set_ready_cbk: conn=%p cbk=%p arg=%p",
|
||||
(void*)conn, (void*)callback_fn, arg);
|
||||
|
||||
// Если соединение уже готово - сразу вызываем callback
|
||||
if (conn->initialized && callback_fn) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP_API, "etcp_conn_set_ready_cbk: calling callback immediately (already initialized)");
|
||||
callback_fn(conn, arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Установить callback при создании нового ETCP соединения
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "../lib/mem.h"
|
||||
#include "etcp.h"
|
||||
|
||||
// Forward declaration
|
||||
static void etcp_connections_read_callback_socket(socket_t sock, void* arg);
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance);
|
||||
static void etcp_link_remove_from_connections(struct ETCP_SOCKET* conn, struct ETCP_LINK* link);
|
||||
|
||||
static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset);
|
||||
@@ -84,7 +84,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) {
|
||||
|
||||
dgram->data_len = offset;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Sending INIT request to link, node_id=%llu, retry=%d", (unsigned long long)node_id, link->init_retry_count);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Sending INIT request to link, node_id=%016llx, retry=%d", (unsigned long long)node_id, link->init_retry_count);
|
||||
|
||||
// Debug: print remote address before sending
|
||||
if (link->remote_addr.ss_family == AF_INET) {
|
||||
@@ -707,7 +707,7 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
sc_encrypt(sc, (uint8_t*)&dgram->timestamp/*не править это, тут верно!*/, 3 + len, enc_buf, &enc_buf_len);
|
||||
// DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Encrypt end");
|
||||
if (enc_buf_len == 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_encrypt_send: encryption failed for node %llu", (unsigned long long)dgram->link->etcp->instance->node_id);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_encrypt_send: encryption failed for node %016llx", (unsigned long long)dgram->link->etcp->instance->node_id);
|
||||
dgram->link->send_errors++;
|
||||
errcode=2;
|
||||
goto es_err;
|
||||
@@ -865,7 +865,7 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
int new_conn=0;
|
||||
if (!conn || conn->peer_node_id!=peer_id) {// создаём новое подключение [new etcp]
|
||||
new_conn=1;
|
||||
conn=etcp_connection_create(e_sock->instance);
|
||||
conn=etcp_connection_create(e_sock->instance,"");
|
||||
if (!conn) { errorcode=55; DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_connections_read_callback: failed to create connection"); goto ec_fr; }// облом
|
||||
memcpy(&conn->crypto_ctx, &sc, sizeof(sc));// добавляем ключ
|
||||
conn->peer_node_id=peer_id;
|
||||
@@ -879,7 +879,7 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Added incoming connection %p to instance, total count: %d", conn, e_sock->instance->connections_count);
|
||||
}
|
||||
else {// check keys если существующее подключение
|
||||
if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: peer key mismatch for node %llu", (unsigned long long)peer_id); goto ec_fr; }// коллизия - peer id совпал а ключи разные.
|
||||
if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: peer key mismatch for node %016llx", (unsigned long long)peer_id); goto ec_fr; }// коллизия - peer id совпал а ключи разные.
|
||||
}
|
||||
// Check if link already exists (for CHANNEL_INIT recovery)
|
||||
struct ETCP_LINK* existing_link = etcp_link_find_by_addr(e_sock, &addr);
|
||||
@@ -967,7 +967,6 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
link->initialized = 1;// получен init request (server), считаем линк уже готовым к работе
|
||||
if (link->etcp->initialized == 0) {
|
||||
link->etcp->initialized = 1;
|
||||
etcp_conn_ready(link->etcp);
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] Link %p (local_id=%d) initialized and marked as UP (server)",
|
||||
@@ -1085,7 +1084,6 @@ process_decrypted:
|
||||
link->initialized = 1;// получен init response (client)
|
||||
// link->link_status = 1; // Link is up after successful initialization
|
||||
if (link->etcp->initialized == 0) {
|
||||
link->etcp->initialized = 1;
|
||||
etcp_conn_ready(link->etcp);
|
||||
}
|
||||
|
||||
@@ -1105,7 +1103,7 @@ process_decrypted:
|
||||
|
||||
loadbalancer_link_ready(link);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp client: Link initialized successfully! Server node_id=%llu, mtu=%d, local_link_id=%d, remote_link_id=%d", (unsigned long long)server_node_id, link->mtu, link->local_link_id, link->remote_link_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp client: Link initialized successfully! Server node_id=%016llx, mtu=%d, local_link_id=%d, remote_link_id=%d", (unsigned long long)server_node_id, link->mtu, link->local_link_id, link->remote_link_id);
|
||||
|
||||
// Cancel init timer if exists
|
||||
if (link->init_timer) {
|
||||
@@ -1192,7 +1190,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
|
||||
strlen(client->peer_public_key_hex));
|
||||
|
||||
// Create ETCP connection for this client
|
||||
struct ETCP_CONN* etcp_conn = etcp_connection_create(instance);
|
||||
struct ETCP_CONN* etcp_conn = etcp_connection_create(instance, client->name);
|
||||
|
||||
if (!etcp_conn) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to create ETCP connection for client %s", client->name);
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
IP_STR ip_to_string(uint32_t ip) {
|
||||
uint8_t* b = (uint8_t*)&ip;
|
||||
IP_STR ip_str;
|
||||
snprintf(ip_str.a, sizeof(ip_str.a), "%u.%u.%u.%u", b[3], b[2], b[1], b[0]);
|
||||
return ip_str;
|
||||
}
|
||||
|
||||
void etcp_dump_pkt_sections(struct ETCP_DGRAM* pkt, struct ETCP_LINK* link, int is_send) {
|
||||
if (!pkt) return;
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include "etcp_connections.h"
|
||||
|
||||
typedef struct { char a[16]; } IP_STR;
|
||||
|
||||
IP_STR ip_to_string(uint32_t ip);
|
||||
|
||||
void etcp_dump_pkt_sections(struct ETCP_DGRAM* pkt, struct ETCP_LINK* link, int is_send);
|
||||
|
||||
#endif
|
||||
+19
-10
@@ -3,22 +3,25 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void dump_ip_packet(const char* direction, const uint8_t* data, size_t len) {
|
||||
char* dump_ip_packet_to_buffer(const uint8_t* data, size_t len) {
|
||||
static char buffer[512];
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (len < 20) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[%s] Packet too small: %zd bytes", direction, len);
|
||||
return;
|
||||
snprintf(buffer, sizeof(buffer), "Packet too small: %zd bytes", len);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint8_t version = (data[0] >> 4) & 0x0F;
|
||||
if (version != 4) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[%s] Non-IPv4 packet: %zd bytes", direction, len);
|
||||
return;
|
||||
snprintf(buffer, sizeof(buffer), "Non-IPv4 packet: %zd bytes", len);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint8_t ihl = (data[0] & 0x0F) * 4;
|
||||
if (len < ihl) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[%s] Truncated IP header: %zd bytes", direction, len);
|
||||
return;
|
||||
snprintf(buffer, sizeof(buffer), "Truncated IP header: %zd bytes", len);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint8_t protocol = data[9];
|
||||
@@ -48,12 +51,12 @@ void dump_ip_packet(const char* direction, const uint8_t* data, size_t len) {
|
||||
proto_name = "ICMP";
|
||||
}
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[%s] IPv4 %s %s:%d -> %s:%d (%zd bytes) data: "
|
||||
int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s:%d -> %s:%d (%zd bytes) data: "
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x "
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x "
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x "
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
direction, proto_name, src_str, src_port, dst_str, dst_port, len,
|
||||
proto_name, src_str, src_port, dst_str, dst_port, len,
|
||||
data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3],
|
||||
data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7],
|
||||
data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11],
|
||||
@@ -62,4 +65,10 @@ void dump_ip_packet(const char* direction, const uint8_t* data, size_t len) {
|
||||
data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23],
|
||||
data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27],
|
||||
data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]);
|
||||
}
|
||||
|
||||
if (offset > 0 && offset < (int)sizeof(buffer)) {
|
||||
buffer[offset] = '\0';
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
+1
-38
@@ -3,41 +3,4 @@
|
||||
#include <string.h>
|
||||
#include "../lib/platform_compat.h"
|
||||
|
||||
// Packet dump function for debugging
|
||||
static void x_dump_packet(const char* direction, const uint8_t* data, size_t len, struct sockaddr_storage* addr) {
|
||||
printf("[DUMP] %s packet: %zd bytes ", direction, len);
|
||||
|
||||
// Print address if provided
|
||||
if (addr) {
|
||||
if (addr->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
|
||||
printf("to/from %s:%d ",
|
||||
inet_ntoa(sin->sin_addr),
|
||||
ntohs(sin->sin_port));
|
||||
}
|
||||
}
|
||||
|
||||
// Print first 64 bytes
|
||||
printf("data: ");
|
||||
for (size_t i = 0; i < len && i < 64; i++) {
|
||||
printf("%02x", data[i]);
|
||||
if (i % 4 == 3) printf(" ");
|
||||
}
|
||||
if (len > 64) printf("...");
|
||||
|
||||
// If it's INIT packet, parse fields
|
||||
if (len > 0 && data[0] == 0x02) { // ETCP_INIT_REQUEST
|
||||
if (len >= 15) { // Minimum INIT size: code(1) + node_id(8) + mtu(2) + keepalive(2) + pubkey(2 at least)
|
||||
uint64_t node_id = 0;
|
||||
memcpy(&node_id, data + 1, 8);
|
||||
uint16_t mtu = (data[9] << 8) | data[10];
|
||||
uint16_t keepalive = (data[11] << 8) | data[12];
|
||||
printf(" | INIT: node_id=%llu mtu=%d keepalive=%d",
|
||||
(unsigned long long)node_id, mtu, keepalive);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void dump_ip_packet(const char* direction, const uint8_t* data, size_t len);
|
||||
char* dump_ip_packet_to_buffer(const uint8_t* data, size_t len);
|
||||
+16
-21
@@ -12,6 +12,7 @@
|
||||
#include "etcp_api.h"
|
||||
#include "etcp.h"
|
||||
#include "etcp_connections.h"
|
||||
#include "etcp_debug.h"
|
||||
#include "utun_instance.h"
|
||||
#include "config_parser.h"
|
||||
#include "../lib/debug_config.h"
|
||||
@@ -21,11 +22,6 @@
|
||||
// Вспомогательные функции
|
||||
// ============================================================================
|
||||
|
||||
static void format_ip(uint32_t ip, char* buffer) {
|
||||
uint8_t* b = (uint8_t*)&ip;
|
||||
snprintf(buffer, 16, "%u.%u.%u.%u", b[3], b[2], b[1], b[0]);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Отправка (только preferred_conn + hop_list)
|
||||
// ============================================================================
|
||||
@@ -76,6 +72,11 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
||||
if (etcp_send(conn, send_entry) != 0) {
|
||||
queue_entry_free(send_entry);
|
||||
u_free(pkt);
|
||||
} else {
|
||||
const char* subcmd_name = (subcmd == ROUTE_SUBCMD_ENTRY) ? "ENTRY" :
|
||||
(subcmd == ROUTE_SUBCMD_WITHDRAW) ? "WITHDRAW" : "REROUTE";
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending route %s/%d, peer %s (%s)",
|
||||
ip_to_string(route->network).a, route->prefix_length, conn->log_name, subcmd_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,8 +94,8 @@ static void route_bgp_broadcast_route(struct ROUTE_BGP* bgp, const struct ROUTE_
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_broadcast_route: route is NULL");
|
||||
return;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_broadcast_route: network=%08X prefix=%d exclude=%p subcmd=%d",
|
||||
route->network, route->prefix_length, (void*)exclude, subcmd);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_broadcast_route: network=%s/%d exclude=%p subcmd=%d",
|
||||
ip_to_string(route->network).a, route->prefix_length, (void*)exclude, subcmd);
|
||||
|
||||
struct ll_entry* entry = bgp->senders_list->head;
|
||||
int sent_count = 0;
|
||||
@@ -115,7 +116,7 @@ static void route_bgp_broadcast_withdraw(struct ROUTE_BGP* bgp, uint64_t node_id
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_broadcast_withdraw: bgp is NULL");
|
||||
return;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_broadcast_withdraw: node_id=%llu exclude=%p",
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_broadcast_withdraw: node_id=%016llx exclude=%p",
|
||||
(unsigned long long)node_id, (void*)exclude);
|
||||
|
||||
struct BGP_WITHDRAW_PACKET* pkt = u_calloc(1, sizeof(struct BGP_WITHDRAW_PACKET));
|
||||
@@ -186,7 +187,7 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: from=%llu len=%zu",
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: from=%016llx len=%zu",
|
||||
(unsigned long long)from_conn->peer_node_id, entry->len);
|
||||
|
||||
struct UTUN_INSTANCE* instance = from_conn->instance;
|
||||
@@ -232,12 +233,7 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
||||
memcpy(&new_hop_list[1], pkt->hop_list, recv_hop_count * sizeof(uint64_t));
|
||||
}
|
||||
|
||||
char ip_buf[16];
|
||||
format_ip(network, ip_buf);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received route %s/%d from %016llx (hops=%d)",
|
||||
ip_buf, prefix, (unsigned long long)owner_node_id, new_hop_count);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: UPDATE network=%08X prefix=%d owner=%llu",
|
||||
network, prefix, (unsigned long long)owner_node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received route %s/%d from %016llx (hops=%d)", ip_to_string(network).a, prefix, (unsigned long long)owner_node_id, new_hop_count);
|
||||
|
||||
struct ROUTE_ENTRY new_route = {0};
|
||||
new_route.network = network;
|
||||
@@ -252,7 +248,6 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
||||
|
||||
if (!inserted) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "Route insert rejected (loop/overlap/owner conflict)");
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: REJECTED");
|
||||
} else {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: INSERTED");
|
||||
}
|
||||
@@ -266,7 +261,6 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
||||
uint64_t node_id = be64toh(wp->node_id);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received WITHDRAW for node %016llx", (unsigned long long)node_id);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: WITHDRAW node_id=%llu", (unsigned long long)node_id);
|
||||
|
||||
// === ИСПРАВЛЕНИЕ: поддержка резервных путей ===
|
||||
route_remove_path(instance->rt, from_conn, node_id);
|
||||
@@ -285,6 +279,7 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
||||
static void route_bgp_on_conn_ready(struct ETCP_CONN* conn, void* arg) {
|
||||
(void)arg;
|
||||
if (conn && conn->instance && conn->instance->bgp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "Connection %s ready ", conn->log_name);
|
||||
route_bgp_new_conn(conn);
|
||||
}
|
||||
}
|
||||
@@ -293,6 +288,7 @@ static void route_bgp_on_conn_ready(struct ETCP_CONN* conn, void* arg) {
|
||||
static void route_bgp_etcp_conn_cbk(struct ETCP_CONN* conn, void* arg) {
|
||||
(void)arg;
|
||||
if (conn && conn->instance && conn->instance->bgp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "Set ETCP ready callback for connection %s", conn->log_name);
|
||||
etcp_conn_set_ready_cbk(conn, route_bgp_on_conn_ready, conn->instance->bgp);
|
||||
}
|
||||
}
|
||||
@@ -303,7 +299,7 @@ struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_init: node_id=%llu", (unsigned long long)instance->node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_init: node_id=%016llx", (unsigned long long)instance->node_id);
|
||||
|
||||
struct ROUTE_BGP* bgp = u_calloc(1, sizeof(struct ROUTE_BGP));
|
||||
if (!bgp) {
|
||||
@@ -331,7 +327,6 @@ struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance) {
|
||||
etcp_set_new_conn_cbk(instance, route_bgp_etcp_conn_cbk, NULL);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized (with hop_list support)");
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_init: DONE");
|
||||
return bgp;
|
||||
}
|
||||
|
||||
@@ -345,7 +340,7 @@ void route_bgp_destroy(struct UTUN_INSTANCE* instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_destroy: node_id=%llu", (unsigned long long)instance->node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_destroy: node_id=%016llx", (unsigned long long)instance->node_id);
|
||||
|
||||
etcp_unbind(instance, ETCP_ID_ROUTE_ENTRY);
|
||||
|
||||
@@ -428,7 +423,7 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: peer=%llu", (unsigned long long)conn->peer_node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: peer=%016llx", (unsigned long long)conn->peer_node_id);
|
||||
|
||||
struct ROUTE_BGP* bgp = conn->instance->bgp;
|
||||
struct ROUTE_TABLE* rt = conn->instance->rt;
|
||||
|
||||
+22
-39
@@ -1,5 +1,6 @@
|
||||
#include "route_lib.h"
|
||||
#include "etcp.h"
|
||||
#include "etcp_debug.h"
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../lib/mem.h"
|
||||
#include "../lib/platform_compat.h"
|
||||
@@ -15,14 +16,6 @@
|
||||
// Вспомогательные функции (без изменений)
|
||||
// ============================================================================
|
||||
|
||||
static char *ip_to_string(uint32_t ip, char *buffer) {
|
||||
if (!buffer) return NULL;
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(ip);
|
||||
snprintf(buffer, 16, "%s", inet_ntoa(addr));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static uint32_t prefix_to_mask(uint8_t prefix) {
|
||||
if (prefix == 0) return 0;
|
||||
return ~((1U << (32 - prefix)) - 1);
|
||||
@@ -372,16 +365,14 @@ bool route_insert(struct ROUTE_TABLE *table,
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_insert: entry is NULL");
|
||||
return false;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: network=%08X prefix=%d conn=%p node_id=%llu",
|
||||
entry->network, entry->prefix_length, (void*)conn, (unsigned long long)node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_insert: network=%s prefix=%d conn=%p node_id=%016llx",
|
||||
ip_to_string(entry->network).a, entry->prefix_length, (void*)conn, (unsigned long long)node_id);
|
||||
|
||||
// === 0. Loop prevention — ВСЕГДА (исправление проблемы #3) ===
|
||||
if (conn && my_node_id && hop_list && hop_count > 0) {
|
||||
for (uint8_t i = 0; i < hop_count; i++) {
|
||||
if (hop_list[i] == my_node_id) {
|
||||
char ip_str[16];
|
||||
ip_to_string(entry->network, ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Loop detected: %s/%d", ip_str, entry->prefix_length);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Loop detected: %s/%d", ip_to_string(entry->network).a, entry->prefix_length);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: REJECTED (loop detected)");
|
||||
return false;
|
||||
}
|
||||
@@ -397,9 +388,7 @@ bool route_insert(struct ROUTE_TABLE *table,
|
||||
|
||||
if (existing_local != new_local ||
|
||||
(!existing_local && existing->conn_list->node_id != node_id)) {
|
||||
char ip_str[16];
|
||||
ip_to_string(entry->network, ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Route conflict (different owner): %s/%d", ip_str, entry->prefix_length);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Route conflict (different owner): %s/%d", ip_to_string(entry->network).a, entry->prefix_length);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: REJECTED (conflict)");
|
||||
return false;
|
||||
}
|
||||
@@ -409,7 +398,7 @@ bool route_insert(struct ROUTE_TABLE *table,
|
||||
existing->last_update = get_time_tb();
|
||||
if (table->change_callback)
|
||||
table->change_callback(table, existing, 1, table->change_callback_arg);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: UPDATED local route %08X/%d", entry->network, entry->prefix_length);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: UPDATED local route %s/%d", ip_to_string(entry->network).a, entry->prefix_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -428,17 +417,15 @@ bool route_insert(struct ROUTE_TABLE *table,
|
||||
if (table->change_callback)
|
||||
table->change_callback(table, existing, 1, table->change_callback_arg);
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: UPDATED learned route %08X/%d node_id=%llu",
|
||||
entry->network, entry->prefix_length, (unsigned long long)node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_insert: UPDATED learned route %s/%d node_id=%016llx",
|
||||
ip_to_string(entry->network).a, entry->prefix_length, (unsigned long long)node_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
// === 2. Новый префикс ===
|
||||
if (check_route_overlap_in_table(entry->network, entry->prefix_length,
|
||||
table->entries, table->count)) {
|
||||
char ip_str[16];
|
||||
ip_to_string(entry->network, ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Route overlap rejected: %s/%d", ip_str, entry->prefix_length);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Route overlap rejected: %s/%d", ip_to_string(entry->network).a, entry->prefix_length);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: REJECTED (overlap)");
|
||||
return false;
|
||||
}
|
||||
@@ -503,14 +490,12 @@ bool route_insert(struct ROUTE_TABLE *table,
|
||||
}
|
||||
|
||||
// === 8. Отладочное сообщение ===
|
||||
char ip_str[16];
|
||||
ip_to_string(entry->network, ip_str);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Route %s: %s/%d (node %016llx)",
|
||||
conn ? "learned" : "local", ip_str, entry->prefix_length,
|
||||
conn ? "learned" : "local", ip_to_string(entry->network).a, entry->prefix_length,
|
||||
(unsigned long long)node_id);
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: INSERTED %s %08X/%d",
|
||||
conn ? "learned" : "local", entry->network, entry->prefix_length);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_insert: INSERTED %s %s/%d",
|
||||
conn ? "learned" : "local", ip_to_string(entry->network).a, entry->prefix_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -603,7 +588,7 @@ bool route_remove_path(struct ROUTE_TABLE *table,
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_remove_path: conn is NULL");
|
||||
return false;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_remove_path: node_id=%llu conn=%p",
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_remove_path: node_id=%016llx conn=%p",
|
||||
(unsigned long long)node_id, (void*)conn);
|
||||
|
||||
struct NODE_CONNS_INFO* info = find_node_conns(table, node_id);
|
||||
@@ -619,7 +604,7 @@ bool route_remove_path(struct ROUTE_TABLE *table,
|
||||
if (info->conninfo_count == 0) {
|
||||
// Последний путь к узлу — полный withdraw
|
||||
route_delete(table, node_id); // уже вызывает callback(2) и очищает память
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_remove_path: WITHDRAW node_id=%llu", (unsigned long long)node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_remove_path: WITHDRAW node_id=%016llx", (unsigned long long)node_id);
|
||||
return true;
|
||||
} else if (was_preferred) {
|
||||
// Изменился preferred_conn — уведомляем о reroute для всех префиксов этого узла
|
||||
@@ -631,7 +616,7 @@ bool route_remove_path(struct ROUTE_TABLE *table,
|
||||
table->change_callback(table, e, 1, table->change_callback_arg);
|
||||
}
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_remove_path: REROUTE node_id=%llu", (unsigned long long)node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_remove_path: REROUTE node_id=%016llx", (unsigned long long)node_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -641,7 +626,7 @@ void route_delete(struct ROUTE_TABLE *table, uint64_t node_id) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_delete: table is NULL");
|
||||
return;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_delete: node_id=%llu", (unsigned long long)node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_delete: node_id=%016llx", (unsigned long long)node_id);
|
||||
|
||||
size_t i = 0;
|
||||
while (i < table->count) {
|
||||
@@ -679,7 +664,7 @@ void route_delete(struct ROUTE_TABLE *table, uint64_t node_id) {
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routes deleted for node %llu", (unsigned long long)node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routes deleted for node %016llx", (unsigned long long)node_id);
|
||||
}
|
||||
|
||||
struct ROUTE_ENTRY* route_lookup(struct ROUTE_TABLE *table, uint32_t dest_ip) {
|
||||
@@ -687,14 +672,14 @@ struct ROUTE_ENTRY* route_lookup(struct ROUTE_TABLE *table, uint32_t dest_ip) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_lookup: table is NULL");
|
||||
return NULL;
|
||||
}
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_lookup: dest_ip=%08X", dest_ip);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_lookup: dest_ip=%s", ip_to_string(dest_ip).a);
|
||||
|
||||
struct ROUTE_ENTRY *result = binary_search_lpm(table, dest_ip);
|
||||
|
||||
if (result) {
|
||||
table->stats.routes_lookup_hits++;
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_lookup: FOUND %08X/%d node_id=%llu",
|
||||
result->network, result->prefix_length,
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_lookup: FOUND %s/%d node_id=%016llx",
|
||||
ip_to_string(result->network).a, result->prefix_length,
|
||||
result->conn_list ? (unsigned long long)result->conn_list->node_id : 0);
|
||||
} else {
|
||||
table->stats.routes_lookup_misses++;
|
||||
@@ -716,13 +701,11 @@ void route_table_print(const struct ROUTE_TABLE *table) {
|
||||
|
||||
for (size_t i = 0; i < table->count; i++) {
|
||||
const struct ROUTE_ENTRY *entry = &table->entries[i];
|
||||
char network_str[16];
|
||||
ip_to_string(entry->network, network_str);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, " %zu: %s/%d", i + 1, network_str, entry->prefix_length);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, " %zu: %s/%d", i + 1, ip_to_string(entry->network).a, entry->prefix_length);
|
||||
|
||||
if (entry->conn_list) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, " node_id=%llu, conns=%d, ref=%d",
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, " node_id=%016llx, conns=%d, ref=%d",
|
||||
(unsigned long long)entry->conn_list->node_id,
|
||||
entry->conn_list->conninfo_count,
|
||||
entry->conn_list->ref_count);
|
||||
|
||||
+60
-24
@@ -51,7 +51,7 @@ static uint32_t extract_dst_ip(uint8_t* data, size_t len) {
|
||||
}
|
||||
|
||||
// entry format: <id 1 byte> <ip_packet ...>
|
||||
static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry) {
|
||||
static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry, uint64_t src_node_id) {
|
||||
if (!instance || !entry) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_pkt: invalid arguments: instance=%p entry=%p entry->len=%zu",
|
||||
(void*)instance, (void*)entry, entry ? entry->len : 0);
|
||||
@@ -121,7 +121,60 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine destination node ID
|
||||
uint64_t dst_node_id = instance->node_id; // Default to local node
|
||||
struct ETCP_CONN* conn = NULL;
|
||||
|
||||
// Check route type: conn_list == NULL means local route
|
||||
if (route->conn_list == NULL) {
|
||||
// Local route - send to TUN (entry has [cmd=0][IP data], TUN skips cmd byte)
|
||||
// dst_node_id is already instance->node_id
|
||||
} else {
|
||||
// Learned route - use first conn from conn_list
|
||||
if (route->conn_list->conninfo_count > 0) {
|
||||
conn = route->conn_list->conn_info[0].conn_id;
|
||||
}
|
||||
if (!conn) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: route to %s has no next_hop, dropping", ip_to_str(&addr, AF_INET).str);
|
||||
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, dropping", ip_to_str(&addr, AF_INET).str);
|
||||
instance->dropped_packets++;
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TRAFFIC LOGGING
|
||||
// INFO: Show packet path (src node ID -> dst node ID)
|
||||
// DEBUG: Show packet dump
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "##########");
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TRAFFIC)) {
|
||||
// Dump the IP packet (skip cmd byte)
|
||||
char hex_buf[513] = {'\0'};
|
||||
size_t hex_len = 0;
|
||||
size_t show_len = (ip_len > 128) ? 128 : ip_len;
|
||||
for (size_t i = 0; i < show_len && hex_len < 512 - 3; i++) {
|
||||
hex_len += snprintf(hex_buf + hex_len, sizeof(hex_buf) - hex_len, "%02x", ip_data[i]);
|
||||
if (i < show_len - 1 && (i + 1) % 32 == 0) {
|
||||
hex_len += snprintf(hex_buf + hex_len, sizeof(hex_buf) - hex_len, " ");
|
||||
}
|
||||
}
|
||||
if (ip_len > 128) {
|
||||
hex_len += snprintf(hex_buf + hex_len, sizeof(hex_buf) - hex_len, "...");
|
||||
}
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TRAFFIC, "PACKET_DUMP: len=%zu hex=%s", ip_len, hex_buf);
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_TRAFFIC, "NODE %016llx -> NODE %016llx",
|
||||
(unsigned long long)src_node_id, (unsigned long long)dst_node_id);
|
||||
|
||||
if (route->conn_list == NULL) {
|
||||
// Local route - send to TUN (entry has [cmd=0][IP data], TUN skips cmd byte)
|
||||
int put_err = queue_data_put(instance->tun->input_queue, entry, 0);
|
||||
@@ -139,27 +192,6 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Learned route - use first conn from conn_list
|
||||
struct ETCP_CONN* conn = NULL;
|
||||
if (route->conn_list->conninfo_count > 0) {
|
||||
conn = route->conn_list->conn_info[0].conn_id;
|
||||
}
|
||||
if (!conn) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: route to %s has no next_hop, dropping", ip_to_str(&addr, AF_INET).str);
|
||||
instance->dropped_packets++;
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!conn->normalizer) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_pkt: connection for %s has no normalizer, dropping", ip_to_str(&addr, AF_INET).str);
|
||||
instance->dropped_packets++;
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send to ETCP
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_pkt: sending %zu bytes to ETCP %s", ip_len, conn->log_name);
|
||||
int send_err = etcp_send(conn, entry);
|
||||
@@ -197,7 +229,9 @@ static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* pk
|
||||
return;
|
||||
}
|
||||
|
||||
route_pkt(instance, pkt);
|
||||
// Source is the remote node we received the packet from
|
||||
uint64_t src_node_id = conn->peer_node_id;
|
||||
route_pkt(instance, pkt, src_node_id);
|
||||
}
|
||||
|
||||
// Callback for packets from TUN output queue
|
||||
@@ -213,7 +247,9 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
|
||||
if (!pkt) return;
|
||||
|
||||
// Route packet (unified function handles everything)
|
||||
route_pkt(instance, pkt);
|
||||
// Source is the local node (TUN interface)
|
||||
uint64_t src_node_id = instance->node_id;
|
||||
route_pkt(instance, pkt, src_node_id);
|
||||
|
||||
// Resume callback for next packet
|
||||
queue_resume_callback(instance->tun->output_queue);
|
||||
|
||||
+15
-5
@@ -71,7 +71,9 @@ static void tun_read_callback(int fd, void* user_arg)
|
||||
tun->bytes_read += nread + 1;
|
||||
tun->packets_read++;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "Read %zd bytes from TUN %s", nread + 1, tun->ifname);
|
||||
dump_ip_packet("TUN->", packet_data + 1, nread);
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TUN)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[TUN->] %s", dump_ip_packet_to_buffer(packet_data + 1, nread));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -97,7 +99,9 @@ static void tun_input_queue_callback(struct ll_queue* q, void* arg)
|
||||
} else {
|
||||
tun->bytes_written += n;
|
||||
tun->packets_written++;
|
||||
dump_ip_packet("->TUN", pkt->dgram + 1, pkt->len - 1);
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TUN)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[->TUN] %s", dump_ip_packet_to_buffer(pkt->dgram + 1, pkt->len - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
queue_dgram_free(pkt);
|
||||
@@ -253,7 +257,9 @@ ssize_t tun_write(struct tun_if* tun, const uint8_t* buf, size_t len)
|
||||
if (n > 0) {
|
||||
tun->bytes_written += n;
|
||||
tun->packets_written++;
|
||||
dump_ip_packet("->TUN", buf + 1, len - 1);
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TUN)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[->TUN] %s", dump_ip_packet_to_buffer(buf + 1, len - 1));
|
||||
}
|
||||
} else {
|
||||
tun->write_errors++;
|
||||
}
|
||||
@@ -282,7 +288,9 @@ void tun_packet_handler(void* arg) {
|
||||
// Освободить временную структуру
|
||||
u_free(pd);
|
||||
|
||||
dump_ip_packet("TUNh->", entry->dgram, entry->len);
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TUN)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[TUNh->] %s", dump_ip_packet_to_buffer(entry->dgram, entry->len));
|
||||
}
|
||||
|
||||
// Положить в очередь (уже в main thread)
|
||||
int ok = queue_data_put(tun->output_queue, entry, 0);
|
||||
@@ -346,6 +354,8 @@ ssize_t tun_read_packet(struct tun_if* tun, uint8_t* buf, size_t len)
|
||||
|
||||
tun->bytes_written += ret;
|
||||
tun->packets_written++;
|
||||
dump_ip_packet("TUN->", buf + 1, pkt->len);
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TUN)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[TUN->] %s", dump_ip_packet_to_buffer(buf + 1, pkt->len));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
+3
-1
@@ -301,7 +301,9 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
|
||||
tun->bytes_read += size + 1;
|
||||
tun->packets_read ++;
|
||||
|
||||
dump_ip_packet("TUN_THREAD->", data + 1, size); // теперь data вместо buf
|
||||
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_TUN)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "[TUN_THREAD->] %s", dump_ip_packet_to_buffer(data + 1, size));
|
||||
}
|
||||
|
||||
uasync_post(tun->ua, tun_packet_handler, pd);
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "POST done");
|
||||
|
||||
@@ -175,6 +175,7 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
|
||||
else if (strcmp(cat_name, "socket") == 0) cat = DEBUG_CATEGORY_SOCKET;
|
||||
else if (strcmp(cat_name, "control") == 0) cat = DEBUG_CATEGORY_CONTROL;
|
||||
else if (strcmp(cat_name, "dump") == 0) cat = DEBUG_CATEGORY_DUMP;
|
||||
else if (strcmp(cat_name, "traffic") == 0) cat = DEBUG_CATEGORY_TRAFFIC;
|
||||
|
||||
if (cat) {
|
||||
debug_level_t lvl = DEBUG_LEVEL_NONE;
|
||||
|
||||
Reference in new issue
Block a user