@ -206,6 +206,9 @@ void cm_update_nodeinfo(struct CONN_MGR_ENTRY* entry) {
nq - > conn_mgr_type = entry - > conn_type ;
memcpy ( nq - > conn_mgr_intermediaries , entry - > intermediaries , sizeof ( entry - > intermediaries ) ) ;
nq - > conn_mgr_intermediariy_count = entry - > intermediariy_count ;
if ( entry - > conn_type = = CONN_TYPE_INDIRECT ) { nq - > conn_presence | = NCONN_INDIRECT ; nq - > conn_up | = NCONN_INDIRECT ; }
else { nq - > conn_presence & = ~ NCONN_INDIRECT ; nq - > conn_up & = ~ NCONN_INDIRECT ; }
topo_fire_nodeinfo_cbk ( entry - > mgr - > instance , entry - > mgr - > group , nq ) ;
}
void cm_cleanup_db_node ( struct CONN_MGR_ENTRY * entry ) {
@ -235,14 +238,16 @@ void cm_ncd_callback(struct NODE_CONN_DIRECT* ncd_h, enum ncd_event ncd_ev, void
switch ( ncd_ev ) {
case NCD_EVENT_UP :
if ( entry - > state = = CONN_MGR_STATE_CONNECTED ) return ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: NCD UP for 0x%016llx " , ( unsigned long long ) entry - > node_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " link: ETCP handshake OK with 0x%016llx — connection ESTABLISHED " ,
( unsigned long long ) entry - > node_id ) ;
if ( entry - > main . timer ) { uasync_cancel_timeout ( entry - > mgr - > instance - > ua , entry - > main . timer ) ; entry - > main . timer = NULL ; }
entry - > main_connect_state = CM_TRY_OK ; entry - > conn_type = CONN_TYPE_DIRECT ;
entry - > state = CONN_MGR_STATE_CONNECTED ;
cm_update_nodeinfo ( entry ) ; cm_deliver_event ( entry , CONN_EVENT_UP ) ;
break ;
case NCD_EVENT_TIMEOUT :
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: NCD TIMEOUT for 0x%016llx " , ( unsigned long long ) entry - > node_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " link: ETCP connect TIMEOUT to 0x%016llx — no response, trying fallback " ,
( unsigned long long ) entry - > node_id ) ;
entry - > ncd_handle = NULL ;
if ( entry - > db_loaded ) {
entry - > main_connect_state = CM_TRY_FAILED ;
@ -261,7 +266,8 @@ void cm_ncd_callback(struct NODE_CONN_DIRECT* ncd_h, enum ncd_event ncd_ev, void
if ( entry - > local_scan_state = = CM_TRY_FAILED ) cm_deliver_event ( entry , CONN_EVENT_TIMEOUT ) ;
break ;
case NCD_EVENT_DOWN :
DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " conn_mgr: NCD DOWN for 0x%016llx " , ( unsigned long long ) entry - > node_id ) ;
DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " link: ETCP link DROPPED to 0x%016llx " ,
( unsigned long long ) entry - > node_id ) ;
entry - > ncd_handle = NULL ;
cm_deliver_event ( entry , CONN_EVENT_DOWN ) ;
break ;
@ -275,7 +281,8 @@ void cm_invite_ncd_callback(struct NODE_CONN_DIRECT* ncd_h, enum ncd_event ncd_e
switch ( ncd_ev ) {
case NCD_EVENT_UP :
if ( inv - > state ! = CM_INVITE_CONNECTING ) return ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: invite INIT OK node=0x%016llx group=0x%016llx " , ( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: ETCP handshake OK with 0x%016llx — sending membership check " ,
( unsigned long long ) inv - > node_id ) ;
inv - > state = CM_INVITE_WAIT_INFO ;
{ struct CM_INVITE_REQ req ; memset ( & req , 0 , sizeof ( req ) ) ;
req . cmd = ETCP_RT_ID_CONN_MGR ; req . subcmd = CM_SUBCMD_INVITE_INFO_REQ ; req . group_id = inv - > mgr - > group - > group_id ;
@ -284,15 +291,15 @@ void cm_invite_ncd_callback(struct NODE_CONN_DIRECT* ncd_h, enum ncd_event ncd_e
qe - > dgram = u_malloc ( sizeof ( req ) ) ; if ( ! qe - > dgram ) { queue_entry_free ( qe ) ; cm_invite_fail ( inv ) ; return ; }
memcpy ( qe - > dgram , & req , sizeof ( req ) ) ; qe - > len = sizeof ( req ) ;
etcp_send ( node_conn_direct_get_conn ( ncd_h ) , qe ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: sent INVITE_INFO_REQ to 0x%016llx group=0x%016llx " ,
( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ) ;
}
break ;
case NCD_EVENT_TIMEOUT :
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: invite connect timeout node=0x%016llx " , ( unsigned long long ) inv - > node_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: ETCP connect TIMEOUT to 0x%016llx — no response from peer " ,
( unsigned long long ) inv - > node_id ) ;
cm_invite_fail ( inv ) ; break ;
case NCD_EVENT_DOWN :
DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " conn_mgr: invite conn down node=0x%016llx " , ( unsigned long long ) inv - > node_id ) ;
DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " invite: ETCP link DROPPED to 0x%016llx while connecting " ,
( unsigned long long ) inv - > node_id ) ;
if ( inv - > state = = CM_INVITE_CONNECTING ) cm_invite_fail ( inv ) ;
break ;
}
@ -711,9 +718,8 @@ void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry
/* ═══════ invite обработчики ═══════ */
void cm_handle_invite_info_req ( struct CONN_MGR * mgr , struct ETCP_CONN * conn , const uint8_t * data , size_t len ) {
if ( len < sizeof ( struct CM_INVITE_REQ ) ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " conn_mgr : INVITE_INFO_REQ too short (%zu)" , len ) ; return ; }
if ( len < sizeof ( struct CM_INVITE_REQ ) ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " invite : INVITE_INFO_REQ too short (%zu)" , len ) ; return ; }
struct CM_INVITE_REQ * req = ( struct CM_INVITE_REQ * ) data ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: INVITE_INFO_REQ from 0x%016llx group=0x%016llx " , ( unsigned long long ) conn - > peer_node_id , ( unsigned long long ) req - > group_id ) ;
struct TOPO_GROUP * grp = topo_groups_find ( mgr - > instance - > topo_groups , req - > group_id ) ;
struct TOPO_GROUP * sg = grp ? grp : mgr - > group ;
struct TOPO_NODE * ln = sg - > local_node ? topo_node_registry_find ( sg - > instance - > topo_groups , sg - > local_node - > node_id ) : NULL ;
@ -725,19 +731,21 @@ void cm_handle_invite_info_req(struct CONN_MGR* mgr, struct ETCP_CONN* conn, con
if ( nl ) memcpy ( resp - > node_name , nm , nl ) ;
struct ll_entry * qe = queue_entry_new ( 0 ) ;
if ( qe ) { qe - > dgram = ( uint8_t * ) resp ; qe - > len = ( uint16_t ) rs ; etcp_send ( conn , qe ) ; } else u_free ( resp ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: sent INVITE_INFO_RESP to 0x%016llx name_len=%zu " , ( unsigned long long ) conn - > peer_node_id , nl ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: membership check RECEIVED from 0x%016llx — responding is_member=yes name= \" %.*s \" " ,
( unsigned long long ) conn - > peer_node_id , ( int ) nl , nm ? nm : " " ) ;
}
void cm_handle_invite_info_resp ( struct CONN_MGR * mgr , const uint8_t * data , size_t len ) {
if ( len < sizeof ( struct CM_INVITE_RESP ) ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " conn_mgr : INVITE_INFO_RESP too short (%zu)" , len ) ; return ; }
if ( len < sizeof ( struct CM_INVITE_RESP ) ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " invite : INVITE_INFO_RESP too short (%zu)" , len ) ; return ; }
struct CM_INVITE_RESP * resp = ( struct CM_INVITE_RESP * ) data ;
if ( len < sizeof ( struct CM_INVITE_RESP ) + ( size_t ) resp - > node_name_len ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " conn_mgr : INVITE_INFO_RESP truncated" ) ; return ; }
if ( len < sizeof ( struct CM_INVITE_RESP ) + ( size_t ) resp - > node_name_len ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " invite : INVITE_INFO_RESP truncated" ) ; return ; }
struct cm_invite_pending * inv = NULL ;
for ( struct cm_invite_pending * p = mgr - > invite_list ; p ; p = p - > next ) if ( p - > state = = CM_INVITE_WAIT_INFO ) { inv = p ; break ; }
if ( ! inv ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " conn_mgr: INVITE_INFO_RESP — no pending invite in WAIT_INFO " ) ; return ; }
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: INVITE_INFO_RESP node=0x%016llx group=0x%016llx member=%d name_len=%u " ,
( unsigned long long ) inv - > node_id , ( unsigned long long ) resp - > group_id , resp - > is_member , resp - > node_name_len ) ;
if ( ! resp - > is_member ) { cm_invite_fail ( inv ) ; return ; }
if ( ! inv ) { DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " invite: INVITE_INFO_RESP — no pending invite in WAIT_INFO state " ) ; return ; }
if ( ! resp - > is_member ) {
DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " invite: membership DENIED by 0x%016llx — not in channel " , ( unsigned long long ) inv - > node_id ) ;
cm_invite_fail ( inv ) ; return ;
}
if ( inv - > temp_nq ) {
struct TOPO_NODE * ni2 = topo_node_registry_find ( inv - > mgr - > instance - > topo_groups , inv - > temp_nq - > node_id ) ;
if ( ni2 ) { memcpy ( ni2 - > ed25519_public_key , resp - > ed25519_pubkey , SC_PUBKEY_SIZE ) ;
@ -746,16 +754,16 @@ void cm_handle_invite_info_resp(struct CONN_MGR* mgr, const uint8_t* data, size_
if ( inv - > mgr - > instance - > topo_sqlite_db ) topo_node_sqlite_node_put ( inv - > mgr - > instance - > topo_sqlite_db , inv - > mgr - > instance - > topo_groups , inv - > temp_nq , ( time_t ) ( get_time_tb ( ) / 10000 ) ) ;
}
if ( inv - > overall_timer ) { uasync_cancel_timeout ( inv - > mgr - > instance - > ua , inv - > overall_timer ) ; inv - > overall_timer = NULL ; }
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: invite JOIN OK node=0x%016llx group=0x%016llx name=%.*s " ,
( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ,
resp - > node_name_len , resp - > node_name_len ? ( const char * ) resp - > node_name : " " ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: membership CONFIRMED by 0x%016llx name= \" %.*s \" — joined to channel, handle registered " ,
( unsigned long long ) inv - > node_id , resp - > node_name_len , resp - > node_name_len ? ( const char * ) resp - > node_name : " " ) ;
if ( inv - > cb ) inv - > cb ( inv - > handle , inv - > node_id , inv - > mgr - > group - > group_id , CONN_EVENT_JOIN , inv - > cb_arg ) ;
cm_invite_cleanup ( inv ) ;
}
void cm_invite_overall_timeout ( void * arg ) {
struct cm_invite_pending * inv = ( struct cm_invite_pending * ) arg ; inv - > overall_timer = NULL ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: invite overall timeout node=0x%016llx " , ( unsigned long long ) inv - > node_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: overall TIMEOUT to 0x%016llx — no response within %ds " ,
( unsigned long long ) inv - > node_id , CM_INVITE_DEFAULT_TIMEOUT_MS / 1000 ) ;
cm_invite_fail ( inv ) ;
}
@ -804,22 +812,21 @@ static void cm_tcp_ready_cb(struct stcp_link* link, void* arg) {
if ( ! qe ) { cm_invite_fail ( inv ) ; return ; }
{ struct tcp_conn_entry * te = ( struct tcp_conn_entry * ) qe - > data ; te - > node_id = inv - > node_id ; te - > link = link ; te - > etcp_conn = etcp ; }
queue_data_put_with_index ( inv - > mgr - > instance - > tcp_connections , qe ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: TCP invite ready node=0x%016llx group=0x%016llx " , ( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: TCP handshake OK with 0x%016llx — sending membership check " ,
( unsigned long long ) inv - > node_id ) ;
inv - > state = CM_INVITE_WAIT_INFO ;
{ struct CM_INVITE_REQ req ; memset ( & req , 0 , sizeof ( req ) ) ;
req . cmd = ETCP_RT_ID_CONN_MGR ; req . subcmd = CM_SUBCMD_INVITE_INFO_REQ ; req . group_id = inv - > mgr - > group - > group_id ;
struct ll_entry * qe2 = queue_entry_new ( 0 ) ; if ( ! qe2 ) { cm_invite_fail ( inv ) ; return ; }
qe2 - > dgram = u_malloc ( sizeof ( req ) ) ; if ( ! qe2 - > dgram ) { queue_entry_free ( qe2 ) ; cm_invite_fail ( inv ) ; return ; }
memcpy ( qe2 - > dgram , & req , sizeof ( req ) ) ; qe2 - > len = sizeof ( req ) ; etcp_send ( etcp , qe2 ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: TCP invite sent INVITE_INFO_REQ to 0x%016llx group=0x%016llx " ,
( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ) ;
}
}
static void cm_tcp_close_cb ( struct stcp_link * link , int err , void * arg ) {
struct cm_invite_pending * inv = ( struct cm_invite_pending * ) arg ;
if ( ! inv ) return ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: TCP invite closed node= 0x%016llx err=%d" , ( unsigned long long ) inv - > node_id , err ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: TCP link CLOSED to 0x%016llx err=%d" , ( unsigned long long ) inv - > node_id , err ) ;
inv - > tcp_link = NULL ;
}
@ -833,9 +840,8 @@ static int cm_invite_tcp_connect(struct cm_invite_pending* inv, const struct TOP
. peer_pubkey = ni - > public_key , . peer_pubkey_mode = 0 , . remote_addr = & sa , . remote_port = a - > port } ;
inv - > tcp_link = stcp_link_connect ( & cfg ) ;
if ( inv - > tcp_link ) { stcp_link_set_on_ready ( inv - > tcp_link , cm_tcp_ready_cb , inv ) ; stcp_link_set_on_close ( inv - > tcp_link , cm_tcp_close_cb , inv ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: TCP connect %d.%d.%d.%d:%d node=0x%016llx group=0x%016llx " ,
a - > addr [ 0 ] , a - > addr [ 1 ] , a - > addr [ 2 ] , a - > addr [ 3 ] , ( int ) a - > port ,
( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: TCP connecting to %d.%d.%d.%d:%d " ,
a - > addr [ 0 ] , a - > addr [ 1 ] , a - > addr [ 2 ] , a - > addr [ 3 ] , ( int ) a - > port ) ;
return 1 ; }
return 0 ;
}
@ -852,8 +858,8 @@ static int cm_invite_tcp_connect(struct cm_invite_pending* inv, const struct TOP
. peer_pubkey = ni - > public_key , . peer_pubkey_mode = 0 , . remote_addr = & sa , . remote_port = a6 - > port } ;
inv - > tcp_link = stcp_link_connect ( & cfg ) ;
if ( inv - > tcp_link ) { stcp_link_set_on_ready ( inv - > tcp_link , cm_tcp_ready_cb , inv ) ; stcp_link_set_on_close ( inv - > tcp_link , cm_tcp_close_cb , inv ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: TCP6 connect port=%d node=0x%016llx group=0x%016llx " ,
( int ) a6 - > port , ( unsigned long long ) inv - > node_id , ( unsigned long long ) inv - > mgr - > group - > group_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: TCP6 connecting to port %d " ,
( int ) a6 - > port ) ;
return 1 ; }
return 0 ;
}
@ -929,7 +935,7 @@ int conn_mgr_open_invite(struct UTUN_INSTANCE* inst,
inv - > overall_timer = uasync_set_timeout ( inst - > ua , CM_INVITE_DEFAULT_TIMEOUT_MS * 10 , inv , cm_invite_overall_timeout , " conn_mgr_invite " ) ;
{
char addrs [ 256 ] = " " ; int aoff = 0 ;
char addrs [ 512 ] = " " ; int aoff = 0 ;
for ( const struct TOPO_ADDR4 * a = gni - > v4_addrs ; a ; a = a - > next )
aoff + = snprintf ( addrs + aoff , sizeof ( addrs ) - ( size_t ) aoff , " %d.%d.%d.%d:%d(%s) " ,
a - > addr [ 0 ] , a - > addr [ 1 ] , a - > addr [ 2 ] , a - > addr [ 3 ] , ( int ) a - > port ,
@ -937,8 +943,8 @@ int conn_mgr_open_invite(struct UTUN_INSTANCE* inst,
for ( const struct TOPO_ADDR6 * a6 = gni - > v6_addrs ; a6 ; a6 = a6 - > next )
aoff + = snprintf ( addrs + aoff , sizeof ( addrs ) - ( size_t ) aoff , " [v6]:%d(%s) " , ( int ) a6 - > port ,
a6 - > protocol = = TOPO_PROTO_UDP ? " UDP " : a6 - > protocol = = TOPO_PROTO_TCP ? " TCP " : " ? " ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " conn_mgr: invite started node=0x%016llx group=0x%016llx udp=%d tcp=%d% s" ,
( unsigned long long ) nid , ( unsigned long long ) group_id , udp , tcp , addrs ) ;
DEBUG_INFO ( DEBUG_CATEGORY_GENERAL , " invite: starting to 0x%016llx via%s udp=%d tcp=%d timeout=%d s" ,
( unsigned long long ) nid , addrs , udp , tcp , CM_INVITE_DEFAULT_TIMEOUT_MS / 1000 ) ;
}
return 0 ;
}