@ -34,67 +34,40 @@ void utun_instance_set_tun_init_enabled(int enabled) {
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN initialization %s " , enabled ? " enabled " : " disabled " ) ;
}
// Create and initialize root instance
struct UTUN_INSTANCE * utun_instance_create ( struct UASYNC * ua , const char * config_file ) {
struct UTUN_INSTANCE * instance = calloc ( 1 , sizeof ( struct UTUN_INSTANCE ) ) ;
if ( ! instance ) return NULL ;
// Common initialization function (called by both create functions)
// Returns 0 on success, -1 on error (instance is NOT freed on error - caller must handle)
static int instance_init_common ( struct UTUN_INSTANCE * instance , struct UASYNC * ua , struct utun_config * config ) {
// Initialize basic fields
instance - > running = 0 ;
instance - > ua = ua ;
instance - > config = config ;
// Note: Global debug system is initialized from command line arguments if provided
// If not initialized via command line, instance-specific logging can be set up here
// The first initialization wins - either global (from main) or instance-specific
// Ensure keys and node_id exist in config
if ( config_ensure_keys_and_node_id ( config_file ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to ensure keys and node_id in config: %s " , config_file ) ;
free ( instance ) ;
return NULL ;
}
// Load configuration
instance - > config = parse_config ( config_file ) ;
if ( ! instance - > config ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to load config from %s " , config_file ) ;
free ( instance ) ;
return NULL ;
}
// Open log file only if not using global debug system output
if ( instance - > config - > global . log_file ) {
debug_set_output_file ( instance - > config - > global . log_file ) ;
}
// Set node_id from config
instance - > node_id = instance - > config - > global . my_node_id ;
instance - > node_id = config - > global . my_node_id ;
// Set my keys
if ( sc_init_local_keys ( & instance - > my_keys , instance - > config - > global . my_public_key_hex , instance - > config - > global . my_private_key_hex ) ) {
if ( sc_init_local_keys ( & instance - > my_keys , config - > global . my_public_key_hex , config - > global . my_private_key_hex ) ! = SC_OK ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to initialize local keys " ) ;
return - 1 ;
}
instance - > ack_pool = memory_pool_init ( sizeof ( struct ACK_PACKET ) ) ;
instance - > data_pool = memory_pool_init ( PACKET_DATA_SIZE ) ;
instance - > pkt_pool = memory_pool_init ( sizeof ( struct ETCP_DGRAM ) + PACKET_DATA_SIZE ) ;
// Create memory pools
instance - > ack_pool = memory_pool_init ( sizeof ( struct ACK_PACKET ) ) ;
instance - > data_pool = memory_pool_init ( PACKET_DATA_SIZE ) ;
instance - > pkt_pool = memory_pool_init ( sizeof ( struct ETCP_DGRAM ) + PACKET_DATA_SIZE ) ;
// Create routing module
if ( routing_create ( instance ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to create routing module " ) ;
free_config ( instance - > config ) ;
free ( instance ) ;
return NULL ;
return - 1 ;
}
DEBUG_INFO ( DEBUG_CATEGORY_ROUTING , " Routing module created " ) ;
// Add local subnets from config as static routes
struct CFG_ROUTE_ENTRY * subnet = instance - > config - > my_subnets ;
struct CFG_ROUTE_ENTRY * subnet = config - > my_subnets ;
while ( subnet ) {
struct ROUTE_ENTRY entry = { 0 } ;
entry . network = subnet - > ip . addr . v4 . s_addr ; // Network byte order
entry . network = subnet - > ip . addr . v4 . s_addr ;
entry . prefix_length = subnet - > netmask ;
entry . next_hop = NULL ; // Local route
entry . type = ROUTE_TYPE_LOCAL ;
@ -119,17 +92,15 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
subnet = subnet - > next ;
}
// Initialize TUN device only if enabled
// Initialize TUN device if enabled
if ( g_tun_init_enabled ) {
instance - > tun = tun_init ( ua , instance - > config ) ;
instance - > tun = tun_init ( ua , config ) ;
if ( ! instance - > tun ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to initialize TUN device " ) ;
free ( instance ) ;
return NULL ;
return - 1 ;
}
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN interface initialized: %s " , instance - > tun - > ifname ) ;
} else {
// TUN initialization disabled - skip TUN setup
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN initialization disabled - skipping TUN device setup " ) ;
instance - > tun = NULL ;
}
@ -143,93 +114,66 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " BGP module initialized " ) ;
}
return instance ;
return 0 ;
}
// Create instance from existing config structure (config ownership transfers to instance)
struct UTUN_INSTANCE * utun_instance_create_from_config ( struct UASYNC * ua , struct utun_config * config ) {
if ( ! config ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " utun_instance_create_from_config: NULL config " ) ;
// Create and initialize root instance from config file
struct UTUN_INSTANCE * utun_instance_create ( struct UASYNC * ua , const char * config_file ) {
// Ensure keys and node_id exist in config (generates them if missing)
if ( config_ensure_keys_and_node_id ( config_file ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to ensure keys and node_id in config: %s " , config_file ) ;
return NULL ;
}
struct UTUN_INSTANCE * instance = calloc ( 1 , sizeof ( struct UTUN_INSTANCE ) ) ;
if ( ! instance ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to allocate UTUN_INSTANCE " ) ;
// Load configuration
struct utun_config * config = parse_config ( config_file ) ;
if ( ! config ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to load config from %s " , config_file ) ;
return NULL ;
}
// Initialize basic fields
instance - > running = 0 ;
instance - > ua = ua ;
instance - > config = config ; // Transfer ownership
// Set node_id from config
instance - > node_id = config - > global . my_node_id ;
// Open log file only if not using global debug system output
if ( config - > global . log_file ) {
debug_set_output_file ( config - > global . log_file ) ;
}
// Set my keys
if ( sc_init_local_keys ( & instance - > my_keys , config - > global . my_public_key_hex , config - > global . my_private_key_hex ) ! = SC_OK ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to initialize local keys " ) ;
free ( instance ) ;
// Allocate instance
struct UTUN_INSTANCE * instance = calloc ( 1 , sizeof ( struct UTUN_INSTANCE ) ) ;
if ( ! instance ) {
free_config ( config ) ;
return NULL ;
}
instance - > ack_pool = memory_pool_init ( sizeof ( struct ACK_PACKET ) ) ;
instance - > data_pool = memory_pool_init ( PACKET_DATA_SIZE ) ;
instance - > pkt_pool = memory_pool_init ( sizeof ( struct ETCP_DGRAM ) + PACKET_DATA_SIZE ) ;
// Create routing module
if ( routing_create ( instance ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to create routing module " ) ;
// Initialize using common function
if ( instance_init_common ( instance , ua , config ) ! = 0 ) {
// Cleanup on error
if ( instance - > config ) free_config ( instance - > config ) ;
free ( instance ) ;
return NULL ;
}
DEBUG_INFO ( DEBUG_CATEGORY_ROUTING , " Routing module created " ) ;
// Add local subnets from config as static routes
struct CFG_ROUTE_ENTRY * subnet = config - > my_subnets ;
while ( subnet ) {
struct ROUTE_ENTRY entry = { 0 } ;
entry . network = subnet - > ip . addr . v4 . s_addr ;
entry . prefix_length = subnet - > netmask ;
entry . next_hop = NULL ;
entry . type = ROUTE_TYPE_LOCAL ;
entry . flags = ROUTE_FLAG_ACTIVE | ROUTE_FLAG_VALIDATED ;
entry . metrics . bandwidth_kbps = UINT32_MAX ;
entry . metrics . latency_ms = 0 ;
entry . metrics . packet_loss_rate = 0 ;
entry . metrics . hop_count = 0 ;
if ( route_table_insert ( instance - > rt , & entry ) ) {
char ip_str [ INET_ADDRSTRLEN ] ;
inet_ntop ( AF_INET , & entry . network , ip_str , sizeof ( ip_str ) ) ;
DEBUG_INFO ( DEBUG_CATEGORY_ROUTING , " Added local route: %s/%d " ,
ip_str , entry . prefix_length ) ;
}
return instance ;
}
subnet = subnet - > next ;
// Create instance from existing config structure (config ownership transfers to instance)
struct UTUN_INSTANCE * utun_instance_create_from_config ( struct UASYNC * ua , struct utun_config * config ) {
if ( ! config ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " utun_instance_create_from_config: NULL config " ) ;
return NULL ;
}
// Initialize TUN device if enabled
if ( g_tun_init_enabled ) {
instance - > tun = tun_init ( ua , config ) ;
if ( ! instance - > tun ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to initialize TUN device " ) ;
free ( instance ) ;
return NULL ;
}
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN interface initialized: %s " , instance - > tun - > ifname ) ;
} else {
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN initialization disabled - skipping TUN device setup " ) ;
instance - > tun = NULL ;
// Allocate instance
struct UTUN_INSTANCE * instance = calloc ( 1 , sizeof ( struct UTUN_INSTANCE ) ) ;
if ( ! instance ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to allocate UTUN_INSTANCE " ) ;
return NULL ;
}
// Initialize BGP module
instance - > bgp = route_bgp_init ( instance ) ;
if ( ! instance - > bgp ) {
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " Failed to initialize BGP module " ) ;
} else {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " BGP module initialized " ) ;
// Initialize using common function (config ownership transferred to instance)
if ( instance_init_common ( instance , ua , config ) ! = 0 ) {
// Cleanup on error - caller still owns config since we failed
free ( instance ) ;
return NULL ;
}
return instance ;