@ -296,10 +296,13 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, c
}
return ;
}
const struct NODEINFO_IPV4_SOCKET * sockets ;
int sock_count = get_node_v4_sockets ( target , & sockets ) ;
if ( sock_count < = 0 | | ! sockets ) {
DEBUG_WARN ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: no IPv4 sockets for node %016llx " ,
const struct NODEINFO_IPV4_SOCKET * sockets_v4 = NULL ;
const struct NODEINFO_IPV6_SOCKET * sockets_v6 = NULL ;
int sock_count_v4 = get_node_v4_sockets ( target , & sockets_v4 ) ;
int sock_count_v6 = get_node_v6_sockets ( target , & sockets_v6 ) ;
if ( ( sock_count_v4 < = 0 | | ! sockets_v4 ) & & ( sock_count_v6 < = 0 | | ! sockets_v6 ) ) {
DEBUG_WARN ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: no sockets for node %016llx " ,
( unsigned long long ) req_pkt - > node_id ) ;
struct route_ping_req * req = u_calloc ( 1 , sizeof ( struct route_ping_req ) ) ;
if ( req ) {
@ -311,15 +314,19 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, c
}
return ;
}
// считаем подходящие локальные сокеты AF_INET
uint8_t local_count = 0 ;
// считаем подходящие локальные сокеты (v4 + v6)
uint8_t local_v4_count = 0 ;
uint8_t local_v6_count = 0 ;
struct ETCP_SOCKET * ls = bgp - > instance - > etcp_sockets ;
while ( ls ) {
if ( ls - > local_addr . ss_family = = AF_INET ) local_count + + ;
if ( ls - > local_addr . ss_family = = AF_INET ) local_v4_count + + ;
else if ( ls - > local_addr . ss_family = = AF_INET6 ) local_v6_count + + ;
ls = ls - > next ;
}
uint8_t local_count = local_v4_count + local_v6_count ;
if ( local_count = = 0 ) {
DEBUG_WARN ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: no local IPv4 sockets " ) ;
DEBUG_WARN ( DEBUG_CATEGORY_BGP , " route_ping_handle_req: no local sockets " ) ;
struct route_ping_req * req = u_calloc ( 1 , sizeof ( struct route_ping_req ) ) ;
if ( req ) {
req - > reply_conn = from_conn ;
@ -340,47 +347,66 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, c
req - > target_node = target ;
req - > timeout_ms = req_pkt - > timeout_ms ;
req - > socket_count = local_count ;
// заполняем target_addr из первого сокета узла (можно расширить на все)
struct sockaddr_storage target_addr ;
memset ( & target_addr , 0 , sizeof ( target_addr ) ) ;
struct sockaddr_in * sin = ( struct sockaddr_in * ) & target_addr ;
sin - > sin_family = AF_INET ;
memcpy ( & sin - > sin_addr , sockets [ 0 ] . addr , 4 ) ;
sin - > sin_port = htons ( sockets [ 0 ] . port ) ;
ls = bgp - > instance - > etcp_sockets ;
uint8_t idx = 0 ;
while ( ls ) {
struct sockaddr_storage target_addr ;
memset ( & target_addr , 0 , sizeof ( target_addr ) ) ;
if ( ls - > local_addr . ss_family = = AF_INET ) {
req - > sockets [ idx ] . local_sock = ls ;
struct route_ping_series * series = u_calloc ( 1 , sizeof ( struct route_ping_series ) ) ;
if ( series ) {
series - > req = req ;
series - > sock_ctx = & req - > sockets [ idx ] ;
series - > local_sock = ls ;
series - > target_addr = target_addr ;
memcpy ( series - > pubkey , target - > node . public_key , SC_PUBKEY_SIZE ) ;
series - > count_total = req_pkt - > count ;
series - > count_sent = 0 ;
series - > count_ok = 0 ;
series - > rtt_sum = 0 ;
series - > timeout_ms = req_pkt - > timeout_ms ;
series - > interval_ms = req_pkt - > interval_ms ;
int ret = etcp_send_ping_to_socket ( bgp - > instance , ls , target - > node . public_key ,
& target_addr , req_pkt - > timeout_ms , route_ping_cb , series , NULL , 0 ) ;
if ( ret ! = 0 ) {
// сразу считаем fail
series - > sock_ctx - > avg_rtt = req_pkt - > timeout_ms * 10 ;
series - > sock_ctx - > count_sent = req_pkt - > count ;
req - > completed_count + + ;
u_free ( series ) ;
}
if ( sock_count_v4 > 0 & & sockets_v4 ) {
struct sockaddr_in * sin = ( struct sockaddr_in * ) & target_addr ;
sin - > sin_family = AF_INET ;
memcpy ( & sin - > sin_addr , sockets_v4 [ 0 ] . addr , 4 ) ;
sin - > sin_port = htons ( sockets_v4 [ 0 ] . port ) ;
} else {
ls = ls - > next ;
continue ;
}
} else if ( ls - > local_addr . ss_family = = AF_INET6 ) {
if ( sock_count_v6 > 0 & & sockets_v6 ) {
struct sockaddr_in6 * sin6 = ( struct sockaddr_in6 * ) & target_addr ;
sin6 - > sin6_family = AF_INET6 ;
memcpy ( & sin6 - > sin6_addr , sockets_v6 [ 0 ] . addr , 16 ) ;
sin6 - > sin6_port = htons ( sockets_v6 [ 0 ] . port ) ;
} else {
req - > sockets [ idx ] . avg_rtt = req_pkt - > timeout_ms * 10 ;
req - > sockets [ idx ] . count_sent = req_pkt - > count ;
ls = ls - > next ;
continue ;
}
} else {
ls = ls - > next ;
continue ;
}
req - > sockets [ idx ] . local_sock = ls ;
struct route_ping_series * series = u_calloc ( 1 , sizeof ( struct route_ping_series ) ) ;
if ( series ) {
series - > req = req ;
series - > sock_ctx = & req - > sockets [ idx ] ;
series - > local_sock = ls ;
series - > target_addr = target_addr ;
memcpy ( series - > pubkey , target - > node . public_key , SC_PUBKEY_SIZE ) ;
series - > count_total = req_pkt - > count ;
series - > count_sent = 0 ;
series - > count_ok = 0 ;
series - > rtt_sum = 0 ;
series - > timeout_ms = req_pkt - > timeout_ms ;
series - > interval_ms = req_pkt - > interval_ms ;
int ret = etcp_send_ping_to_socket ( bgp - > instance , ls , target - > node . public_key ,
& target_addr , req_pkt - > timeout_ms , route_ping_cb , series , NULL , 0 ) ;
if ( ret ! = 0 ) {
series - > sock_ctx - > avg_rtt = req_pkt - > timeout_ms * 10 ;
series - > sock_ctx - > count_sent = req_pkt - > count ;
req - > completed_count + + ;
u_free ( series ) ;
}
idx + + ;
} else {
req - > sockets [ idx ] . avg_rtt = req_pkt - > timeout_ms * 10 ;
req - > sockets [ idx ] . count_sent = req_pkt - > count ;
req - > completed_count + + ;
}
idx + + ;
ls = ls - > next ;
}
if ( req - > completed_count > = req - > socket_count ) {