@ -27,6 +27,9 @@ static int hex_to_binary(const char *hex_str, uint8_t *binary, size_t binary_len
return 0 ;
}
// Callback для приема пакетов через uasync
static void etcp_socket_read_callback ( int fd , void * user_arg ) ;
// Forward declaration
int etcp_socket_send ( struct ETCP_SOCKET * sock , const uint8_t * data , size_t len , const struct sockaddr * to_addr ) ;
@ -540,6 +543,45 @@ int etcp_socket_set_option(struct ETCP_SOCKET* sock, int level, int optname, con
return setsockopt ( sock - > fd , level , optname , optval , optlen ) ;
}
// Callback для приема пакетов через uasync
static void etcp_socket_read_callback ( int fd , void * user_arg ) {
struct ETCP_CONNECTIONS * conns = ( struct ETCP_CONNECTIONS * ) user_arg ;
if ( ! conns | | fd < 0 ) return ;
struct packet_buffer * pkt = packet_pool_get ( & conns - > etcp - > packet_pool ) ;
if ( ! pkt ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to get packet from pool " ) ;
return ;
}
struct sockaddr_storage remote_addr ;
socklen_t addr_len = sizeof ( remote_addr ) ;
ssize_t nread = recvfrom ( fd , pkt - > data , sizeof ( pkt - > data ) , 0 ,
( struct sockaddr * ) & remote_addr , & addr_len ) ;
if ( nread < 0 ) {
if ( errno ! = EAGAIN & & errno ! = EWOULDBLOCK ) {
conns - > recv_errors + + ;
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " recvfrom failed: %s " , strerror ( errno ) ) ;
}
packet_pool_put ( & conns - > etcp - > packet_pool , pkt ) ;
return ;
}
if ( nread = = 0 ) {
packet_pool_put ( & conns - > etcp - > packet_pool , pkt ) ;
return ;
}
pkt - > metadata . data_len = nread ;
pkt - > metadata . remote_addr = remote_addr ;
pkt - > metadata . s = & conns - > socket ;
etcp_input ( pkt , & conns - > socket , conns ) ;
packet_pool_put ( & conns - > etcp - > packet_pool , pkt ) ;
}
// Helper function to parse IP:port address
static int parse_ip_port ( const char * addr_str , struct sockaddr_storage * addr , socklen_t * addr_len ) {
if ( ! addr_str | | ! addr | | ! addr_len ) return - 1 ;
@ -629,21 +671,28 @@ int init_connections(struct UTUN_INSTANCE* instance) {
continue ;
}
// Create connections manager
// Create connections manager (includes socket creation)
struct ETCP_CONNECTIONS * conns = etcp_connections_init ( etcp , bind_ip_str , bind_port ) ;
if ( ! conns ) {
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " Failed to create connections for %s " , server - > name ) ;
etcp_socket_destroy ( sock ) ;
etcp_destroy ( etcp ) ;
continue ;
}
// Register socket with uasync
if ( uasync_add_socket ( instance - > ua , conns - > socket . fd ,
etcp_socket_read_callback , NULL , NULL , conns ) = = NULL ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTION , " Failed to register socket with uasync for %s " , server - > name ) ;
etcp_connections_destroy ( conns ) ;
etcp_destroy ( etcp ) ;
return - 1 ;
}
// Create connection handle
conn_handle_t * handle = calloc ( 1 , sizeof ( conn_handle_t ) ) ;
if ( ! handle ) {
DEBUG_ERROR ( DEBUG_CATEGORY_MEMORY , " Failed to allocate connection handle " ) ;
etcp_connections_destroy ( conns ) ;
etcp_socket_destroy ( sock ) ;
etcp_destroy ( etcp ) ;
continue ;
}
@ -653,7 +702,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
// Set first listen socket
if ( i = = 0 ) {
instance - > first_listen_socket = ( struct ETCP_SOCKET * ) sock ;
instance - > first_listen_socket = & conns - > socket ;
}
// Process clients that connect to this server
@ -674,7 +723,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
}
// Create link for this client
struct ETCP_LINK * link = etcp_link_new ( etcp , sock ,
struct ETCP_LINK * link = etcp_link_new ( etcp , & conns - > socket , conns ,
( struct sockaddr * ) & client_addr ,
client_addr_len ) ;
if ( ! link ) {