@ -609,36 +609,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
}
# endif
// Store the local address and bind socket if provided
if ( ip ) {
memcpy ( & e_sock - > local_addr , ip , sizeof ( struct sockaddr_storage ) ) ;
// CRITICAL: Actually bind the socket to the address
socklen_t addr_len = ( ip - > ss_family = = AF_INET ) ? sizeof ( struct sockaddr_in ) : sizeof ( struct sockaddr_in6 ) ;
if ( bind ( e_sock - > fd , ( struct sockaddr * ) ip , addr_len ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " [ETCP] Failed to bind socket to address family %d: %s " ,
ip - > ss_family , socket_strerror ( socket_get_error ( ) ) ) ;
if ( ip - > ss_family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) ip ;
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " [ETCP] Failed to bind to %s:%d " , ip_to_str ( & sin - > sin_addr , AF_INET ) . str , ntohs ( sin - > sin_port ) ) ;
} else if ( ip - > ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) ip ;
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " [ETCP] Failed to bind to %s:%d " , ip_to_str ( & sin6 - > sin6_addr , AF_INET6 ) . str , ntohs ( sin6 - > sin6_port ) ) ;
}
socket_close_wrapper ( e_sock - > fd ) ;
u_free ( e_sock ) ;
return NULL ;
}
if ( ip - > ss_family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) ip ;
DEBUG_INFO ( DEBUG_CATEGORY_ETCP , " [ETCP] Successfully bound socket to local address, family=AF_INET %s:%d " , ip_to_str ( & sin - > sin_addr , AF_INET ) . str , ntohs ( sin - > sin_port ) ) ;
} else if ( ip - > ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) ip ;
DEBUG_INFO ( DEBUG_CATEGORY_ETCP , " [ETCP] Successfully bound socket to local address, family=AF_INET6 %s:%d " , ip_to_str ( & sin6 - > sin6_addr , AF_INET6 ) . str , ntohs ( sin6 - > sin6_port ) ) ;
}
}
// Определяем interface_addr: IP интерфейса или из конфига
// Определяем interface_addr до bind, чтобы забиндить на конкретный адрес
memset ( & e_sock - > interface_addr , 0 , sizeof ( e_sock - > interface_addr ) ) ;
if ( netif_index > 0 & & ip & & ip - > ss_family = = AF_INET ) {
uint32_t if_ip = get_interface_ip_by_index ( netif_index ) ;
@ -651,7 +622,6 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
if ( ip - > ss_family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) ip ;
if ( sin - > sin_addr . s_addr = = 0 ) {
// 0.0.0.0 — определяем через default route
struct sockaddr_storage remote ;
memset ( & remote , 0 , sizeof ( remote ) ) ;
struct sockaddr_in * rem_sin = ( struct sockaddr_in * ) & remote ;
@ -665,7 +635,6 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
} else if ( ip - > ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) ip ;
if ( memcmp ( & sin6 - > sin6_addr , & in6addr_any , sizeof ( struct in6_addr ) ) = = 0 ) {
// :: — приоритет: permanent > temporary > get_outgoing_local_ip
uint16_t v6if = ( netif_index > 0 ) ? netif_index : get_default_route_netif_index ( AF_INET6 ) ;
if ( v6if > 0 ) {
uint8_t v6addr [ 16 ] ;
@ -675,6 +644,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
struct sockaddr_in6 * if6 = ( struct sockaddr_in6 * ) & e_sock - > interface_addr ;
if6 - > sin6_family = AF_INET6 ;
memcpy ( & if6 - > sin6_addr , v6addr , 16 ) ;
if6 - > sin6_port = sin6 - > sin6_port ;
}
}
if ( e_sock - > interface_addr . ss_family = = 0 ) {
@ -684,15 +654,15 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
rem_sin6 - > sin6_family = AF_INET6 ;
rem_sin6 - > sin6_port = htons ( 53 ) ;
inet_pton ( AF_INET6 , " 2001:4860:4860::8888 " , & rem_sin6 - > sin6_addr ) ;
if ( get_outgoing_local_ip ( ip , & remote , & e_sock - > interface_addr ) ! = 0 ) {
DEBUG_WARN ( DEBUG_CATEGORY_CONNECTION , " Failed to detect outgoing local IPv6 for socket %s " , e_sock - > name ) ;
if ( get_outgoing_local_ip ( ip , & remote , & e_sock - > interface_addr ) = = 0 ) {
struct sockaddr_in6 * if6 = ( struct sockaddr_in6 * ) & e_sock - > interface_addr ;
if6 - > sin6_port = sin6 - > sin6_port ;
}
}
}
}
}
if ( e_sock - > interface_addr . ss_family = = 0 ) {
// Не удалось определить автоматически — используем адрес из конфига
if ( ip ) memcpy ( & e_sock - > interface_addr , ip , sizeof ( struct sockaddr_storage ) ) ;
}
// Копируем порт из конфига в interface_addr
@ -708,6 +678,36 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
}
}
// Bind — используем interface_addr если определён, иначе ip из конфига
{
struct sockaddr_storage * bind_addr = ( e_sock - > interface_addr . ss_family ! = 0 ) ? & e_sock - > interface_addr : ip ;
if ( bind_addr & & bind_addr - > ss_family ! = 0 ) {
memcpy ( & e_sock - > local_addr , bind_addr , sizeof ( struct sockaddr_storage ) ) ;
socklen_t addr_len = ( bind_addr - > ss_family = = AF_INET ) ? sizeof ( struct sockaddr_in ) : sizeof ( struct sockaddr_in6 ) ;
if ( bind ( e_sock - > fd , ( struct sockaddr * ) bind_addr , addr_len ) < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " [ETCP] Failed to bind socket to address family %d: %s " ,
bind_addr - > ss_family , socket_strerror ( socket_get_error ( ) ) ) ;
if ( bind_addr - > ss_family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) bind_addr ;
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " [ETCP] Failed to bind to %s:%d " , ip_to_str ( & sin - > sin_addr , AF_INET ) . str , ntohs ( sin - > sin_port ) ) ;
} else if ( bind_addr - > ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) bind_addr ;
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " [ETCP] Failed to bind to %s:%d " , ip_to_str ( & sin6 - > sin6_addr , AF_INET6 ) . str , ntohs ( sin6 - > sin6_port ) ) ;
}
socket_close_wrapper ( e_sock - > fd ) ;
u_free ( e_sock ) ;
return NULL ;
}
if ( bind_addr - > ss_family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) bind_addr ;
DEBUG_INFO ( DEBUG_CATEGORY_ETCP , " [ETCP] Successfully bound socket to local address, family=AF_INET %s:%d " , ip_to_str ( & sin - > sin_addr , AF_INET ) . str , ntohs ( sin - > sin_port ) ) ;
} else if ( bind_addr - > ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) bind_addr ;
DEBUG_INFO ( DEBUG_CATEGORY_ETCP , " [ETCP] Successfully bound socket to local address, family=AF_INET6 %s:%d " , ip_to_str ( & sin6 - > sin6_addr , AF_INET6 ) . str , ntohs ( sin6 - > sin6_port ) ) ;
}
}
}
char config_str [ 64 ] = " none " ;
char netif_str [ 64 ] = " none " ;
if ( e_sock - > local_addr . ss_family ! = 0 ) {
@ -1065,11 +1065,10 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
struct sockaddr_storage * addr = & dgram - > link - > remote_addr ;
socklen_t addr_len = ( addr - > ss_family = = AF_INET ) ? sizeof ( struct sockaddr_in ) : sizeof ( struct sockaddr_in6 ) ;
// Debug: print where we're sending the packet
if ( addr - > ss_family = = AF_INET ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) addr ;
// inet_ntop removed - use ip_to_str
if ( addr - > ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) addr ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DEBUG , " [v6_send] fd=%d dst=%-39s scope=%u " , dgram - > link - > conn - > fd ,
sockaddr_storage_to_str ( addr ) . str , sin6 - > sin6_scope_id ) ;
}
ssize_t sent = etcp_udp_send ( dgram - > link , dgram - > link - > conn - > fd , enc_buf , enc_buf_len + dgram - > noencrypt_len ,
@ -1663,7 +1662,17 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
socklen_t addr_len = sizeof ( addr ) ;
memset ( & addr , 0 , sizeof ( addr ) ) ;
ssize_t recv_len = socket_recvfrom ( sock , data , PACKET_DATA_SIZE , ( struct sockaddr * ) & addr , & addr_len ) ;
if ( recv_len > 0 & & addr . ss_family = = AF_INET6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) & addr ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DEBUG , " [v6_recv] sock=%s fd=%d src=[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d len=%zd scope=%u " ,
e_sock - > name , ( int ) sock ,
sin6 - > sin6_addr . s6_addr [ 0 ] , sin6 - > sin6_addr . s6_addr [ 1 ] , sin6 - > sin6_addr . s6_addr [ 2 ] , sin6 - > sin6_addr . s6_addr [ 3 ] ,
sin6 - > sin6_addr . s6_addr [ 4 ] , sin6 - > sin6_addr . s6_addr [ 5 ] , sin6 - > sin6_addr . s6_addr [ 6 ] , sin6 - > sin6_addr . s6_addr [ 7 ] ,
sin6 - > sin6_addr . s6_addr [ 8 ] , sin6 - > sin6_addr . s6_addr [ 9 ] , sin6 - > sin6_addr . s6_addr [ 10 ] , sin6 - > sin6_addr . s6_addr [ 11 ] ,
sin6 - > sin6_addr . s6_addr [ 12 ] , sin6 - > sin6_addr . s6_addr [ 13 ] , sin6 - > sin6_addr . s6_addr [ 14 ] , sin6 - > sin6_addr . s6_addr [ 15 ] ,
( int ) ntohs ( sin6 - > sin6_port ) , recv_len , sin6 - > sin6_scope_id ) ;
}
if ( recv_len < = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " recvfrom failed, error=%zd, sock_err=%d " , recv_len , socket_get_error ( ) ) ;
return ;