@ -20,11 +20,20 @@
// Forward declarations
static uint32_t get_dest_ip ( const uint8_t * packet , size_t len ) ;
// Global instance for signal handlers
static struct UTUN_INSTANCE * g_instance = NULL ;
// Global flag to control TUN initialization (disabled by default)
static int g_tun_init_enabled = 0 ;
// Function to control TUN initialization
void utun_instance_set_tun_init_enabled ( int enabled ) {
g_tun_init_enabled = enabled ? 1 : 0 ;
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 , const char * log_file ) {
struct UTUN_INSTANCE * instance = calloc ( 1 , sizeof ( struct UTUN_INSTANCE ) ) ;
@ -71,58 +80,68 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
instance - > pkt_pool = memory_pool_init ( PACKET_DATA_SIZE + 100 ) ;
// Initialize TUN device
if ( tun_create ( & instance - > tun ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to create TUN device " ) ;
free ( instance ) ;
return NULL ;
}
// Configure TUN device IP (BSD: use config IP as-is, Linux/Win: IP/32)
char tun_ip_str [ 64 ] ;
char ip_buffer [ 64 ] ;
// Initialize TUN device only if enabled
if ( g_tun_init_enabled ) {
// Initialize TUN device
if ( tun_create ( & instance - > tun ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to create TUN device " ) ;
free ( instance ) ;
return NULL ;
}
// Convert struct IP to string using inet_ntop
if ( instance - > config - > global . tun_ip . family = = AF_INET ) {
inet_ntop ( AF_INET , & instance - > config - > global . tun_ip . addr . v4 , ip_buffer , sizeof ( ip_buffer ) ) ;
} else {
inet_ntop ( AF_INET6 , & instance - > config - > global . tun_ip . addr . v6 , ip_buffer , sizeof ( ip_buffer ) ) ;
}
// Configure TUN device IP (BSD: use config IP as-is, Linux/Win: IP/32)
char tun_ip_str [ 64 ] ;
char ip_buffer [ 64 ] ;
# ifdef __linux__
snprintf ( tun_ip_str , sizeof ( tun_ip_str ) , " %s/32 " , ip_buffer ) ;
# elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
// BSD systems: use config IP as-is, peer IP will be 192.0.2.1
snprintf ( tun_ip_str , sizeof ( tun_ip_str ) , " %s " , ip_buffer ) ;
# else
snprintf ( tun_ip_str , sizeof ( tun_ip_str ) , " %s/32 " , ip_buffer ) ; // Default to /32
# endif
if ( tun_set_ip ( instance - > tun . ifname , tun_ip_str ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to set TUN IP: %s " , tun_ip_str ) ;
tun_close ( & instance - > tun ) ;
free ( instance ) ;
return NULL ;
}
// Convert struct IP to string using inet_ntop
if ( instance - > config - > global . tun_ip . family = = AF_INET ) {
inet_ntop ( AF_INET , & instance - > config - > global . tun_ip . addr . v4 , ip_buffer , sizeof ( ip_buffer ) ) ;
} else {
inet_ntop ( AF_INET6 , & instance - > config - > global . tun_ip . addr . v6 , ip_buffer , sizeof ( ip_buffer ) ) ;
}
// Set MTU (default 1500)
int mtu = instance - > config - > global . mtu > 0 ? instance - > config - > global . mtu : 1500 ;
if ( tun_set_mtu ( instance - > tun . ifname , mtu ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to set TUN MTU: %d " , mtu ) ;
tun_close ( & instance - > tun ) ;
free ( instance ) ;
return NULL ;
}
# ifdef __linux__
snprintf ( tun_ip_str , sizeof ( tun_ip_str ) , " %s/32 " , ip_buffer ) ;
# elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
// BSD systems: use config IP as-is, peer IP will be 192.0.2.1
snprintf ( tun_ip_str , sizeof ( tun_ip_str ) , " %s " , ip_buffer ) ;
# else
snprintf ( tun_ip_str , sizeof ( tun_ip_str ) , " %s/32 " , ip_buffer ) ; // Default to /32
# endif
if ( tun_set_ip ( instance - > tun . ifname , tun_ip_str ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to set TUN IP: %s " , tun_ip_str ) ;
tun_close ( & instance - > tun ) ;
free ( instance ) ;
return NULL ;
}
if ( tun_set_up ( instance - > tun . ifname ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to bring up TUN interface " ) ;
tun_close ( & instance - > tun ) ;
free ( instance ) ;
return NULL ;
}
// Set MTU (default 1500)
int mtu = instance - > config - > global . mtu > 0 ? instance - > config - > global . mtu : 1500 ;
if ( tun_set_mtu ( instance - > tun . ifname , mtu ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to set TUN MTU: %d " , mtu ) ;
tun_close ( & instance - > tun ) ;
free ( instance ) ;
return NULL ;
}
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN interface initialized: %s with IP %s " ,
instance - > tun . ifname , tun_ip_str ) ;
if ( tun_set_up ( instance - > tun . ifname ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to bring up TUN interface " ) ;
tun_close ( & instance - > tun ) ;
free ( instance ) ;
return NULL ;
}
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN interface initialized: %s with IP %s " ,
instance - > tun . ifname , tun_ip_str ) ;
} else {
// TUN initialization disabled - skip TUN setup
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " TUN initialization disabled - skipping TUN device setup " ) ;
// Initialize TUN structure with safe defaults
memset ( & instance - > tun , 0 , sizeof ( instance - > tun ) ) ;
instance - > tun . fd = - 1 ; // Invalid file descriptor to indicate no TUN device
}
// Create routing table
instance - > routing_table = routing_table_create ( ) ;