@ -99,8 +99,14 @@ static void route_ping_cb(int success, uint16_t rtt, void* arg, uint64_t nonce,
series - > rtt_sum + = rtt ;
}
if ( series - > count_sent < series - > count_total & & series - > req - > reply_conn ) {
struct UTUN_INSTANCE * inst = series - > req - > reply_conn - > instance ;
series - > next_timer = uasync_set_timeout ( inst - > ua , series - > interval_ms * 10 , series , route_ping_next ) ;
if ( success ) {
// Ответ получен — следующий пинг сразу (burst mode)
route_ping_next ( series ) ;
} else {
// Таймаут — ждем interval_ms перед retry
struct UTUN_INSTANCE * inst = series - > req - > reply_conn - > instance ;
series - > next_timer = uasync_set_timeout ( inst - > ua , series - > interval_ms * 10 , series , route_ping_next ) ;
}
return ;
}
// серия завершена
@ -236,7 +242,7 @@ int route_ping_send_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, uint64
return - 3 ;
}
e - > dgram = ( uint8_t * ) req_pkt ;
e - > len = size of( struct BGP_PING_REQUEST ) ;
e - > len = offset of( struct BGP_PING_REQUEST , target_ipv4 ) ;
int ret = etcp_send ( to_conn , e ) ;
if ( ret ! = 0 ) {
@ -275,8 +281,7 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, u
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " route_ping_send_req_addr: invalid args " ) ;
return - 1 ;
}
size_t extra = 6 + ( pubkey ? SC_PUBKEY_SIZE : 0 ) ;
size_t pkt_size = sizeof ( struct BGP_PING_REQUEST ) + extra ;
size_t pkt_size = pubkey ? sizeof ( struct BGP_PING_REQUEST ) : offsetof ( struct BGP_PING_REQUEST , pubkey ) ;
struct BGP_PING_REQUEST * req_pkt = u_calloc ( 1 , pkt_size ) ;
if ( ! req_pkt ) {
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " route_ping_send_req_addr: alloc failed " ) ;
@ -289,16 +294,13 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, u
req_pkt - > count = count ;
req_pkt - > interval_ms = interval_ms ;
req_pkt - > timeout_ms = timeout_ms ;
uint8_t * tail = ( uint8_t * ) req_pkt + sizeof ( struct BGP_PING_REQUEST ) ;
tail [ 0 ] = ( target_ip > > 24 ) & 0xFF ;
tail [ 1 ] = ( target_ip > > 16 ) & 0xFF ;
tail [ 2 ] = ( target_ip > > 8 ) & 0xFF ;
tail [ 3 ] = target_ip & 0xFF ;
tail [ 4 ] = ( target_port > > 8 ) & 0xFF ;
tail [ 5 ] = target_port & 0xFF ;
req_pkt - > target_ipv4 [ 0 ] = ( target_ip > > 24 ) & 0xFF ;
req_pkt - > target_ipv4 [ 1 ] = ( target_ip > > 16 ) & 0xFF ;
req_pkt - > target_ipv4 [ 2 ] = ( target_ip > > 8 ) & 0xFF ;
req_pkt - > target_ipv4 [ 3 ] = target_ip & 0xFF ;
req_pkt - > target_port = target_port ;
if ( pubkey ) {
memcpy ( tail + 6 , pubkey , SC_PUBKEY_SIZE ) ;
memcpy ( req_pkt - > pubkey , pubkey , SC_PUBKEY_SIZE ) ;
}
struct ll_entry * e = queue_entry_new ( 0 ) ;
@ -352,8 +354,10 @@ void route_ping_destroy_pending(struct ROUTE_BGP* bgp) {
}
void route_ping_handle_req ( struct ROUTE_BGP * bgp , struct ETCP_CONN * from_conn , const uint8_t * data , size_t len ) {
if ( ! bgp | | ! from_conn | | ! data | | len < sizeof ( struct BGP_PING_REQUEST ) ) {
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: invalid args " ) ;
const size_t base_len = offsetof ( struct BGP_PING_REQUEST , target_ipv4 ) ;
const size_t addr_len = offsetof ( struct BGP_PING_REQUEST , pubkey ) ;
if ( ! bgp | | ! from_conn | | ! data | | ( len ! = base_len & & len ! = addr_len & & len ! = sizeof ( struct BGP_PING_REQUEST ) ) ) {
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: invalid args len=%zu " , len ) ;
return ;
}
const struct BGP_PING_REQUEST * req_pkt = ( const struct BGP_PING_REQUEST * ) data ;
@ -367,29 +371,34 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, c
struct NODEINFO_Q * target = NULL ;
const uint8_t * embedded_pubkey = NULL ;
if ( len > = sizeof ( struct BGP_PING_REQUEST ) + 6 ) {
// Custom target address provided (for NAT ping)
const uint8_t * tail = data + sizeof ( struct BGP_PING_REQUEST ) ;
custom_socket . addr [ 0 ] = tail [ 0 ] ;
custom_socket . addr [ 1 ] = tail [ 1 ] ;
custom_socket . addr [ 2 ] = tail [ 2 ] ;
custom_socket . addr [ 3 ] = tail [ 3 ] ;
custom_socket . port = ( tail [ 4 ] < < 8 ) | tail [ 5 ] ;
if ( len = = sizeof ( struct BGP_PING_REQUEST ) | | len = = addr_len ) {
// Extended packet with custom target (with or without pubkey)
custom_socket . addr [ 0 ] = req_pkt - > target_ipv4 [ 0 ] ;
custom_socket . addr [ 1 ] = req_pkt - > target_ipv4 [ 1 ] ;
custom_socket . addr [ 2 ] = req_pkt - > target_ipv4 [ 2 ] ;
custom_socket . addr [ 3 ] = req_pkt - > target_ipv4 [ 3 ] ;
custom_socket . port = req_pkt - > target_port ;
custom_socket . type = 0 ;
custom_socket . id = 0 ;
sockets_v4 = & custom_socket ;
sock_count_v4 = 1 ;
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: using custom target %d.%d.%d.%d:%u for node %016llx " ,
tail [ 0 ] , tail [ 1 ] , tail [ 2 ] , tail [ 3 ] , custom_socket . port ,
( unsigned long long ) req_pkt - > node_id ) ;
// Check for embedded pubkey
if ( len > = sizeof ( struct BGP_PING_REQUEST ) + 6 + SC_PUBKEY_SIZE ) {
embedded_pubkey = tail + 6 ;
req_pkt - > target_ipv4 [ 0 ] , req_pkt - > target_ipv4 [ 1 ] , req_pkt - > target_ipv4 [ 2 ] , req_pkt - > target_ipv4 [ 3 ] ,
req_pkt - > target_port , ( unsigned long long ) req_pkt - > node_id ) ;
// Check if embedded pubkey is non-zero (only when full packet length)
if ( len = = sizeof ( struct BGP_PING_REQUEST ) ) {
int pubkey_zero = 1 ;
for ( int i = 0 ; i < SC_PUBKEY_SIZE ; i + + ) {
if ( req_pkt - > pubkey [ i ] ! = 0 ) { pubkey_zero = 0 ; break ; }
}
if ( ! pubkey_zero ) {
embedded_pubkey = req_pkt - > pubkey ;
}
}
// For custom target, we still need target node for pubkey lookup if not embedded
target = route_bgp_get_node ( bgp , req_pkt - > node_id ) ;
} else {
// No custom target - look up nodeinfo for advertised sockets
} else if ( len = = base_len ) {
// Base packet without custom target - use nodeinfo sockets
target = route_bgp_get_node ( bgp , req_pkt - > node_id ) ;
if ( ! target ) {
DEBUG_WARN ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: node %016llx not found " ,
@ -407,6 +416,9 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, c
}
sock_count_v4 = get_node_v4_sockets ( target , & sockets_v4 ) ;
sock_count_v6 = get_node_v6_sockets ( target , & sockets_v6 ) ;
} else {
DEBUG_WARN ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: unexpected packet size %zu " , len ) ;
return ;
}
if ( ( sock_count_v4 < = 0 | | ! sockets_v4 ) & & ( sock_count_v6 < = 0 | | ! sockets_v6 ) ) {