@ -128,6 +128,158 @@ struct NODEINFO_Q* nodeinfo_find_by_id(struct ROUTE_BGP* bgp, uint64_t node_id)
return e ? ( struct NODEINFO_Q * ) e : NULL ;
return e ? ( struct NODEINFO_Q * ) e : NULL ;
}
}
static int is_node_connectivity_active ( struct NODE_CONNECTIVITY * c ) {
return c - > probe_status ! = PROBE_STATUS_NONE
| | c - > interface_status ! = PROBE_RESULT_UNKNOWN
| | c - > nat_status ! = PROBE_RESULT_UNKNOWN
| | c - > real_status ! = PROBE_RESULT_UNKNOWN
| | c - > probe_start_time ! = 0
| | c - > ping_req_time ! = 0 ;
}
static const char * probe_status_str ( uint8_t s ) {
switch ( s ) { case 0 : return " NONE " ; case 1 : return " IN_PROGRESS " ; case 2 : return " DONE " ; default : return " ? " ; }
}
static const char * probe_result_str ( uint8_t s ) {
switch ( s ) { case 0 : return " UNKNOWN " ; case 1 : return " REACHABLE " ; case 2 : return " UNREACHABLE " ; default : return " ? " ; }
}
static const char * conn_mgr_type_str ( uint8_t t ) {
switch ( t ) { case 1 : return " DIRECT " ; case 2 : return " REVERSE " ; case 3 : return " INDIRECT " ; default : return " NONE " ; }
}
void route_node_dump_all ( struct ROUTE_BGP * bgp ) {
if ( ! bgp | | ! bgp - > nodes ) return ;
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " === BGP Nodes dump: %d nodes === " , queue_entry_count ( bgp - > nodes ) ) ;
int idx = 0 ;
struct ll_entry * e = bgp - > nodes - > head ;
while ( e ) {
struct NODEINFO_Q * nq = ( struct NODEINFO_Q * ) e ;
struct NODEINFO * ni = & nq - > node ;
int is_local = ( bgp - > local_node = = nq ) ;
const char * name_s = ( ni - > node_name_len > 0 ) ? ( const char * ) ( ( const uint8_t * ) ni + sizeof ( struct NODEINFO ) ) : " " ;
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " --- Node #%d: id=%016llx name= \" %.*s \" ver=%u dirty=%u alien=%u%s --- " ,
idx , ( unsigned long long ) ni - > node_id , ni - > node_name_len , name_s ,
ni - > ver , nq - > dirty , nq - > alien , is_local ? " [LOCAL] " : " " ) ;
if ( nq - > best_socket ) DEBUG_INFO ( DEBUG_CATEGORY_BGP , " best_socket=%p " , ( void * ) nq - > best_socket ) ;
log_dump ( DEBUG_LEVEL_INFO , DEBUG_CATEGORY_BGP , " pubkey " , ni - > public_key , SC_PUBKEY_SIZE ) ;
log_dump ( DEBUG_LEVEL_INFO , DEBUG_CATEGORY_BGP , " ed25519 " , ni - > ed25519_public_key , SC_PUBKEY_SIZE ) ;
const struct NODEINFO_IPV4_SOCKET_META * v4sm ;
int v4sm_cnt = get_node_v4_sockets_meta ( nq , & v4sm ) ;
if ( v4sm_cnt > 0 ) for ( int i = 0 ; i < v4sm_cnt ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " v4sock[%d]: id=%u type=%u " , i , v4sm [ i ] . id , v4sm [ i ] . type ) ;
}
const struct NODEINFO_IPV4_ADDR * v4a ;
int v4a_cnt = get_node_v4_addrs ( nq , & v4a ) ;
if ( v4a_cnt > 0 ) {
const char * atn [ ] = { " INTERFACE " , " NAT " , " REAL " } ;
for ( int i = 0 ; i < v4a_cnt ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " v4addr[%d]: %s:%u %s sock=%u " ,
i , ip_to_str ( v4a [ i ] . addr , AF_INET ) . str , v4a [ i ] . port ,
( v4a [ i ] . type < = 2 ) ? atn [ v4a [ i ] . type ] : " ? " , v4a [ i ] . socket_id ) ;
}
}
const struct NODEINFO_IPV6_SOCKET_META * v6sm ;
int v6sm_cnt = get_node_v6_sockets_meta ( nq , & v6sm ) ;
if ( v6sm_cnt > 0 ) for ( int i = 0 ; i < v6sm_cnt ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " v6sock[%d]: id=%u type=%u " , i , v6sm [ i ] . id , v6sm [ i ] . type ) ;
}
const struct NODEINFO_IPV6_ADDR * v6a ;
int v6a_cnt = get_node_v6_addrs ( nq , & v6a ) ;
if ( v6a_cnt > 0 ) {
for ( int i = 0 ; i < v6a_cnt ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " v6addr[%d]: %s:%u type=%u sock=%u " ,
i , ip_to_str ( v6a [ i ] . addr , AF_INET6 ) . str , v6a [ i ] . port ,
v6a [ i ] . type , v6a [ i ] . socket_id ) ;
}
}
const struct NODEINFO_IPV4_SUBNET * sub4 ;
int sub4_cnt = get_node_routes ( nq , & sub4 ) ;
if ( sub4_cnt > 0 ) for ( int i = 0 ; i < sub4_cnt ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " v4sub[%d]: %s/%d " , i ,
ip_to_str ( sub4 [ i ] . addr , AF_INET ) . str , sub4 [ i ] . prefix_length ) ;
}
const struct NODEINFO_IPV6_SUBNET * sub6 ;
int sub6_cnt = get_node_v6_routes ( nq , & sub6 ) ;
if ( sub6_cnt > 0 ) for ( int i = 0 ; i < sub6_cnt ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " v6sub[%d]: %s/%d " , i ,
ip_to_str ( sub6 [ i ] . addr , AF_INET6 ) . str , sub6 [ i ] . prefix_length ) ;
}
if ( ni - > tranzit_nodes > 0 ) {
const uint8_t * dyn = node_dyn_start ( ni ) ;
dyn = skip_name ( dyn , ni - > node_name_len ) ;
dyn = skip_v4_sockets_meta ( dyn , ni - > local_v4_sockets ) ;
dyn = skip_v4_addrs ( dyn , ni - > local_v4_addrs ) ;
dyn = skip_v6_sockets_meta ( dyn , ni - > local_v6_sockets ) ;
dyn = skip_v6_addrs ( dyn , ni - > local_v6_addrs ) ;
dyn = skip_v4_subnets ( dyn , ni - > local_v4_subnets ) ;
const struct NODEINFO_IPV6_SUBNET * sub6_dyn = ( const struct NODEINFO_IPV6_SUBNET * ) dyn ;
dyn + = ni - > local_v6_subnets * sizeof ( struct NODEINFO_IPV6_SUBNET ) ;
const struct NODEINFO_TRANZIT_NODE * tr = ( const struct NODEINFO_TRANZIT_NODE * ) dyn ;
for ( uint8_t i = 0 ; i < ni - > tranzit_nodes ; i + + ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " tranzit[%d]: node=%016llx rtt=%u linkq=%u " ,
i , ( unsigned long long ) tr [ i ] . node_id , tr [ i ] . rtt , tr [ i ] . link_q ) ;
}
}
int path_idx = 0 ;
if ( nq - > paths ) {
struct ll_entry * pe = nq - > paths - > head ;
while ( pe ) {
struct NODEINFO_PATH * path = ( struct NODEINFO_PATH * ) pe ;
uint64_t * hop = ( uint64_t * ) ( ( uint8_t * ) path + sizeof ( struct NODEINFO_PATH ) ) ;
char hop_buf [ 256 ] = " " ;
int hop_pos = 0 ;
for ( uint8_t hi = 0 ; hi < path - > hop_count & & hop_pos < ( int ) sizeof ( hop_buf ) - 20 ; hi + + ) {
hop_pos + = snprintf ( hop_buf + hop_pos , sizeof ( hop_buf ) - hop_pos ,
" %s%016llx " , hi ? " -> " : " " , ( unsigned long long ) hop [ hi ] ) ;
}
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " path[%d]: conn=%s hop_count=%u hops=[%s] " ,
path_idx , path - > conn ? path - > conn - > log_name : " NULL " ,
path - > hop_count , hop_buf ) ;
path_idx + + ;
pe = pe - > next ;
}
}
struct NODE_CONNECTIVITY * c = & nq - > connectivity ;
if ( is_node_connectivity_active ( c ) ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " connectivity: probe=%s iface=%s(%u) nat=%s(%u) real=%s(%u) pend=%u iface_rtt=%u nat_rtt=%u real_rtt=%u start_tb=%llu ping_req_tb=%llu " ,
probe_status_str ( c - > probe_status ) ,
probe_result_str ( c - > interface_status ) , c - > interface_min_rtt ,
probe_result_str ( c - > nat_status ) , c - > nat_min_rtt ,
probe_result_str ( c - > real_status ) , c - > real_min_rtt ,
c - > pending_count , c - > interface_min_rtt , c - > nat_min_rtt , c - > real_min_rtt ,
( unsigned long long ) c - > probe_start_time , ( unsigned long long ) c - > ping_req_time ) ;
}
if ( nq - > conn_mgr_type ! = CONN_TYPE_NONE ) {
char interm_buf [ 200 ] = " " ;
int ipos = 0 ;
for ( uint8_t i = 0 ; i < nq - > conn_mgr_intermediariy_count & & ipos < ( int ) sizeof ( interm_buf ) - 19 ; i + + ) {
ipos + = snprintf ( interm_buf + ipos , sizeof ( interm_buf ) - ipos ,
" %s%016llx " , i ? " , " : " " , ( unsigned long long ) nq - > conn_mgr_intermediaries [ i ] ) ;
}
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " conn_mgr: type=%s intermediates=[%s] " ,
conn_mgr_type_str ( nq - > conn_mgr_type ) , interm_buf ) ;
}
e = e - > next ;
idx + + ;
}
}
int route_bgp_update_my_nodeinfo ( struct UTUN_INSTANCE * instance , struct ROUTE_BGP * bgp ) {
int route_bgp_update_my_nodeinfo ( struct UTUN_INSTANCE * instance , struct ROUTE_BGP * bgp ) {
if ( ! instance | | ! bgp ) {
if ( ! instance | | ! bgp ) {
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " route_bgp_update_my_nodeinfo: invalid args " ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_BGP , " route_bgp_update_my_nodeinfo: invalid args " ) ;