@ -13,9 +13,6 @@
# include "../../../src/utun_instance.h"
# include "../../../src/utun_instance.h"
# include "../../../src/etcp_api.h"
# include "../../../src/etcp_api.h"
# include "../../../src/topo_group.h"
# include "../../../src/topo_node.h"
# include "../../../src/conn_mgr.h"
# include "../../../src/etcp.h"
# include "../../../src/etcp.h"
# include "../../../src/etcp_connections.h"
# include "../../../src/etcp_connections.h"
# include "../../../src/secure_channel.h"
# include "../../../src/secure_channel.h"
@ -108,7 +105,7 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
g_cc . my_node_id = inst - > node_id ;
g_cc . my_node_id = inst - > node_id ;
topo_node_sqlite_init ( g_cc . db ) ;
topo_node_sqlite_init ( g_cc . db ) ;
topo_groups_set_sqlite_db ( inst - > topo_groups , g_cc . db ) ;
inst - > topo_sqlite_db = g_cc . db ;
/* записать себя в nodes + local_identity с реальным node_id и именем */
/* записать себя в nodes + local_identity с реальным node_id и именем */
{
{
@ -302,9 +299,6 @@ void chat_core_update_my_name(const char* name) {
sqlite3_finalize ( cs ) ;
sqlite3_finalize ( cs ) ;
}
}
/* broadcast updated NODEINFO to connected peers */
struct TOPO_GROUP * grp = topo_groups_get_default ( g_cc . inst - > topo_groups ) ;
if ( grp ) topo_group_update_my_nodeinfo ( g_cc . inst , grp ) ;
}
}
void chat_core_sync_my_addresses ( void ) {
void chat_core_sync_my_addresses ( void ) {
@ -603,237 +597,55 @@ static void connect_result_cb(int result, uint64_t node_id, void* arg) {
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , data , 20 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , data , 20 ) ;
}
}
# define CC_PARALLEL_CONNECT_TIMEOUT_MS 3000
struct cc_parallel_state {
struct UTUN_INSTANCE * inst ;
int addr_count ;
int pending_count ;
int completed ; /* 0=pending, 1=success, -1=fail-delivered */
uint64_t node_id ;
uint64_t channel_id ;
struct ETCP_CONN * * conns ;
void * * timers ;
} ;
struct cc_parallel_ctx {
struct cc_parallel_state * state ;
int addr_index ;
} ;
static void cc_parallel_cleanup ( struct cc_parallel_state * st ) {
if ( ! st ) return ;
u_free ( st - > conns ) ;
u_free ( st - > timers ) ;
u_free ( st ) ;
}
static void cc_parallel_ready_cb ( struct ETCP_CONN * conn , void * arg ) {
struct cc_parallel_ctx * pctx = ( struct cc_parallel_ctx * ) arg ;
struct cc_parallel_state * st = pctx - > state ;
if ( st - > completed ) { u_free ( pctx ) ; return ; }
st - > completed = 1 ;
uint8_t data [ 20 ] ;
memcpy ( data , & st - > node_id , 8 ) ;
int r = CONN_MGR_OK ;
memcpy ( data + 8 , & r , 4 ) ;
memcpy ( data + 12 , & st - > channel_id , 8 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , data , 20 ) ;
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTIVITY , " %s: parallel connect SUCCESS idx=%d peer=0x%016llx " ,
CC_ID , pctx - > addr_index , ( unsigned long long ) st - > node_id ) ;
for ( int i = 0 ; i < st - > addr_count ; i + + ) {
if ( st - > timers [ i ] ) { uasync_cancel_timeout ( st - > inst - > ua , st - > timers [ i ] ) ; st - > timers [ i ] = NULL ; }
if ( st - > conns [ i ] & & i ! = pctx - > addr_index ) { uasync_call_soon ( st - > inst - > ua , st - > conns [ i ] , ( timeout_callback_t ) etcp_connection_close ) ; st - > conns [ i ] = NULL ; }
}
u_free ( pctx ) ;
cc_parallel_cleanup ( st ) ;
}
static void cc_parallel_timeout_cb ( void * arg ) {
struct cc_parallel_ctx * pctx = ( struct cc_parallel_ctx * ) arg ;
struct cc_parallel_state * st = pctx - > state ;
if ( st - > completed ) { u_free ( pctx ) ; return ; }
if ( st - > conns [ pctx - > addr_index ] ) { etcp_connection_close ( st - > conns [ pctx - > addr_index ] ) ; st - > conns [ pctx - > addr_index ] = NULL ; }
st - > timers [ pctx - > addr_index ] = NULL ;
st - > pending_count - - ;
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTIVITY , " %s: parallel connect TIMEOUT idx=%d pending=%d/%d peer=0x%016llx " ,
CC_ID , pctx - > addr_index , st - > pending_count , st - > addr_count , ( unsigned long long ) st - > node_id ) ;
if ( st - > pending_count < = 0 & & ! st - > completed ) {
st - > completed = - 1 ;
uint8_t data [ 20 ] ;
memcpy ( data , & st - > node_id , 8 ) ;
int r = CONN_MGR_ERR_TIMEOUT ;
memcpy ( data + 8 , & r , 4 ) ;
memcpy ( data + 12 , & st - > channel_id , 8 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , data , 20 ) ;
cc_parallel_cleanup ( st ) ;
}
u_free ( pctx ) ;
}
void chat_core_connect_from_invite ( struct chat_invite * inv ) {
void chat_core_connect_from_invite ( struct chat_invite * inv ) {
if ( ! g_cc . initialized | | ! g_cc . inst | | ! inv ) return ;
if ( ! g_cc . initialized | | ! g_cc . inst | | ! inv ) return ;
struct TOPO_GROUP * group = topo_groups_get_default ( g_cc . inst - > topo_groups ) ;
if ( ! group | | ! g_cc . inst - > conn_mgr ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: bgp/conn_mgr not available " , CC_ID ) ;
uint8_t err [ 12 ] ; int r = - 7 ;
memcpy ( err , & inv - > node_id , 8 ) ; memcpy ( err + 8 , & r , 4 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , err , 12 ) ;
return ;
}
uint64_t node_id = inv - > node_id ;
uint64_t node_id = inv - > node_id ;
if ( topo_node_find_by_id ( group , node_id ) ) {
/* save pubkey to nodes table */
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTIVITY , " %s: node 0x%016llx already in BGP, connecting " ,
sqlite3_stmt * st = NULL ;
CC_ID , ( unsigned long long ) node_id ) ;
if ( sqlite3_prepare_v2 ( g_cc . db ,
conn_mgr_connect_node ( g_cc . inst - > conn_mgr , node_id , 30000 ,
" INSERT OR REPLACE INTO nodes(node_id, x25519_pubkey) VALUES(?,?) " ,
connect_result_cb , & inv - > channel_id ) ;
- 1 , & st , NULL ) = = SQLITE_OK ) {
return ;
sqlite3_bind_int64 ( st , 1 , ( sqlite3_int64 ) node_id ) ;
sqlite3_bind_blob ( st , 2 , inv - > pubkey , 32 , SQLITE_STATIC ) ;
sqlite3_step ( st ) ; sqlite3_finalize ( st ) ;
}
}
struct ll_entry * qe = queue_entry_new ( sizeof ( struct TOPO_NODEQ ) ) ;
/* save addresses to node_addresses */
if ( ! qe ) {
{
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: failed to alloc TOPO_NODEQ " , CC_ID ) ;
sqlite3_stmt * ds = NULL ;
uint8_t err [ 12 ] ; int r = - 7 ;
if ( sqlite3_prepare_v2 ( g_cc . db ,
memcpy ( err , & node_id , 8 ) ; memcpy ( err + 8 , & r , 4 ) ;
" DELETE FROM node_addresses WHERE node_id=? " , - 1 , & ds , NULL ) = = SQLITE_OK ) {
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , err , 12 ) ;
sqlite3_bind_int64 ( ds , 1 , ( sqlite3_int64 ) node_id ) ;
return ;
sqlite3_step ( ds ) ; sqlite3_finalize ( ds ) ;
}
}
struct TOPO_NODEQ * nq = ( struct TOPO_NODEQ * ) qe ;
sqlite3_stmt * is = NULL ;
memset ( ( uint8_t * ) nq + sizeof ( struct ll_entry ) , 0 , sizeof ( * nq ) - sizeof ( struct ll_entry ) ) ;
if ( sqlite3_prepare_v2 ( g_cc . db ,
" INSERT INTO node_addresses(node_id,family,protocol,address,port,addr_type) "
struct TOPO_NODE * ni = u_calloc ( 1 , sizeof ( struct TOPO_NODE ) ) ;
" VALUES(?,?,1,?,?,0) " , - 1 , & is , NULL ) = = SQLITE_OK ) {
if ( ! ni ) { queue_entry_free ( qe ) ; return ; }
const uint8_t * src = inv - > addrs_data ;
ni - > node_id = node_id ;
for ( int i = 0 ; i < inv - > addr_count ; i + + ) {
ni - > group_id = group - > group_id ;
uint8_t family = * src + + ;
ni - > ver = 0 ;
if ( family = = 4 ) {
memcpy ( ni - > public_key , inv - > pubkey , SC_PUBKEY_SIZE ) ;
sqlite3_bind_int64 ( is , 1 , ( sqlite3_int64 ) node_id ) ;
memset ( ni - > ed25519_public_key , 0 , SC_PUBKEY_SIZE ) ;
sqlite3_bind_int ( is , 2 , 4 ) ;
ni - > node_name = u_strdup ( " " ) ;
sqlite3_bind_blob ( is , 3 , src , 4 , SQLITE_STATIC ) ; src + = 4 ;
uint16_t port = ( ( uint16_t ) src [ 0 ] < < 8 ) | src [ 1 ] ; src + = 2 ;
struct TOPO_ADDR4 * addrs_head = NULL ;
sqlite3_bind_int ( is , 4 , ( int ) port ) ;
const uint8_t * src = inv - > addrs_data ;
sqlite3_step ( is ) ; sqlite3_reset ( is ) ;
for ( int i = 0 ; i < inv - > addr_count ; i + + ) {
} else {
uint8_t family = * src + + ;
src + = 18 ;
if ( family = = 4 ) {
}
struct TOPO_ADDR4 * a4 = memory_pool_alloc ( group - > instance - > topo_groups - > v4_addr_pool ) ;
}
if ( ! a4 ) continue ;
sqlite3_finalize ( is ) ;
memcpy ( a4 - > addr , src , 4 ) ; src + = 4 ;
a4 - > port = ( ( uint16_t ) src [ 0 ] < < 8 ) | src [ 1 ] ; src + = 2 ;
a4 - > type = TOPO_ADDR_REAL ; a4 - > socket_id = 0 ; a4 - > protocol = TOPO_PROTO_UDP ;
a4 - > next = addrs_head ; addrs_head = a4 ;
} else {
src + = 18 ; /* skip v6 */
}
}
}
}
ni - > v4_addrs = addrs_head ;
/* alien-узел: sock_meta с неизвестной конфигурацией цели */
struct TOPO_SOCKMETA4 * sm = memory_pool_alloc ( group - > instance - > topo_groups - > v4_sock_meta_pool ) ;
if ( sm ) { sm - > id = 0 ; sm - > config_type = CFG_SERVER_TYPE_UNKNOWN ; sm - > nat_type = NAT_TYPE_UNKNOWN ; sm - > next = NULL ; ni - > v4_sock_meta = sm ; }
nq - > node = ni ; topo_node_ref ( ni ) ;
nq - > hash_node_id = node_id ; nq - > alien = 0 ;
nq - > dirty = 0 ; nq - > last_ver = 0 ;
nq - > conn_mgr_type = CONN_TYPE_NONE ; nq - > conn_mgr_intermediariy_count = 0 ;
memset ( & nq - > connectivity , 0 , sizeof ( nq - > connectivity ) ) ;
nq - > best_socket = NULL ;
queue_data_put_with_index ( group - > nodes , & nq - > ll ) ;
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTIVITY , " %s: invite saved node=0x%016llx addrs=%d, starting direct connect " ,
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTIVITY , " %s: created NODEINFO for 0x%016llx, %d addrs, parallel connect " ,
CC_ID , ( unsigned long long ) node_id , inv - > addr_count ) ;
CC_ID , ( unsigned long long ) node_id , inv - > addr_count ) ;
/* count IPv4 addresses and collect them for parallel connect */
chat_core_connect_auto ( node_id , connect_result_cb , & inv - > channel_id , NULL ) ;
int v4_count = 0 ;
for ( struct TOPO_ADDR4 * a = addrs_head ; a ; a = a - > next ) v4_count + + ;
if ( v4_count = = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: no IPv4 addresses in invite " , CC_ID ) ;
uint8_t err [ 20 ] ; memcpy ( err , & node_id , 8 ) ; int r = CONN_MGR_ERR_NO_ADDRESSES ;
memcpy ( err + 8 , & r , 4 ) ; memset ( err + 12 , 0 , 8 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , err , 20 ) ;
return ;
}
struct ETCP_SOCKET * best_socket = g_cc . inst - > etcp_sockets ;
while ( best_socket & & best_socket - > local_addr . ss_family ! = AF_INET ) best_socket = best_socket - > next ;
if ( ! best_socket ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: no AF_INET socket " , CC_ID ) ;
uint8_t err [ 20 ] ; memcpy ( err , & node_id , 8 ) ; int r = CONN_MGR_ERR_INTERNAL ;
memcpy ( err + 8 , & r , 4 ) ; memset ( err + 12 , 0 , 8 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , err , 20 ) ;
return ;
}
struct cc_parallel_state * pst = u_calloc ( 1 , sizeof ( struct cc_parallel_state ) ) ;
if ( ! pst ) {
uint8_t err [ 20 ] ; memcpy ( err , & node_id , 8 ) ; int r = CONN_MGR_ERR_INTERNAL ;
memcpy ( err + 8 , & r , 4 ) ; memset ( err + 12 , 0 , 8 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , err , 20 ) ;
return ;
}
pst - > inst = g_cc . inst ;
pst - > addr_count = v4_count ;
pst - > pending_count = v4_count ;
pst - > completed = 0 ;
pst - > node_id = node_id ;
pst - > channel_id = inv - > channel_id ;
pst - > conns = u_calloc ( v4_count , sizeof ( struct ETCP_CONN * ) ) ;
pst - > timers = u_calloc ( v4_count , sizeof ( void * ) ) ;
if ( ! pst - > conns | | ! pst - > timers ) { cc_parallel_cleanup ( pst ) ; return ; }
int idx = 0 ;
for ( struct TOPO_ADDR4 * a = addrs_head ; a & & idx < v4_count ; a = a - > next , idx + + ) {
struct sockaddr_in sin ;
memset ( & sin , 0 , sizeof ( sin ) ) ; sin . sin_family = AF_INET ;
memcpy ( & sin . sin_addr . s_addr , a - > addr , 4 ) ; sin . sin_port = htons ( a - > port ) ;
struct sockaddr_storage sa ;
memset ( & sa , 0 , sizeof ( sa ) ) ; memcpy ( & sa , & sin , sizeof ( sin ) ) ;
struct ETCP_CONN * conn = etcp_connection_create ( g_cc . inst , NULL ) ;
if ( ! conn ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: etcp_connection_create failed idx=%d " , CC_ID , idx ) ;
pst - > conns [ idx ] = NULL ; pst - > timers [ idx ] = NULL ; pst - > pending_count - - ; continue ;
}
sc_init_ctx ( & conn - > crypto_ctx , & g_cc . inst - > my_keys ) ;
sc_set_peer_public_key ( & conn - > crypto_ctx , inv - > pubkey , 0 ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: invite connect set peer_pubkey=%016llx my_pub=%016llx peer_node=0x%016llx " ,
CC_ID , * ( uint64_t * ) inv - > pubkey , * ( uint64_t * ) conn - > crypto_ctx . pk - > public_key , inv - > node_id ) ;
struct cc_parallel_ctx * pctx = u_calloc ( 1 , sizeof ( struct cc_parallel_ctx ) ) ;
if ( ! pctx ) { etcp_connection_close ( conn ) ; pst - > conns [ idx ] = NULL ; pst - > timers [ idx ] = NULL ; pst - > pending_count - - ; continue ; }
pctx - > state = pst ; pctx - > addr_index = idx ;
etcp_conn_set_ready_cbk ( conn , cc_parallel_ready_cb , pctx ) ;
if ( ! etcp_link_new ( conn , best_socket , & sa , 0 ) ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: etcp_link_new failed idx=%d " , CC_ID , idx ) ;
u_free ( pctx ) ; etcp_connection_close ( conn ) ;
pst - > conns [ idx ] = NULL ; pst - > timers [ idx ] = NULL ; pst - > pending_count - - ; continue ;
}
pst - > conns [ idx ] = conn ;
etcp_conn_set_peer_node_id ( conn , inv - > node_id ) ;
pst - > timers [ idx ] = uasync_set_timeout ( g_cc . inst - > ua , CC_PARALLEL_CONNECT_TIMEOUT_MS * 10 ,
pctx , cc_parallel_timeout_cb , " cc_parallel " ) ;
DEBUG_INFO ( DEBUG_CATEGORY_CONNECTIVITY , " %s: parallel connect attempt %d/%d to %d.%d.%d.%d:%d " ,
CC_ID , idx + 1 , v4_count , sin . sin_addr . s_addr & 0xFF , ( sin . sin_addr . s_addr > > 8 ) & 0xFF ,
( sin . sin_addr . s_addr > > 16 ) & 0xFF , ( sin . sin_addr . s_addr > > 24 ) & 0xFF , a - > port ) ;
}
if ( pst - > pending_count < = 0 & & ! pst - > completed ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: all %d parallel connects failed to start " , CC_ID , v4_count ) ;
uint8_t err [ 20 ] ; memcpy ( err , & node_id , 8 ) ; int r = CONN_MGR_ERR_UNREACHABLE ;
memcpy ( err + 8 , & r , 4 ) ; memcpy ( err + 12 , & inv - > channel_id , 8 ) ;
gui_bridge_post ( GUI_EVT_CONNECT_RESULT , err , 20 ) ;
cc_parallel_cleanup ( pst ) ;
}
}
}
/* ═══ Auto-connect: direct ETCP connection from SQLite (no BGP) ═══ */
/* ═══ Auto-connect: direct ETCP connection from SQLite (no BGP) ═══ */
@ -882,7 +694,7 @@ static void ca_ready_cb(struct ETCP_CONN* conn, void* arg) {
if ( st - > conns [ i ] & & i ! = ctx - > addr_index ) { uasync_call_soon ( st - > inst - > ua , st - > conns [ i ] , ( timeout_callback_t ) etcp_connection_close ) ; st - > conns [ i ] = NULL ; }
if ( st - > conns [ i ] & & i ! = ctx - > addr_index ) { uasync_call_soon ( st - > inst - > ua , st - > conns [ i ] , ( timeout_callback_t ) etcp_connection_close ) ; st - > conns [ i ] = NULL ; }
}
}
etcp_conn_remove_ready_cbk ( conn , ca_ready_cb , ctx ) ;
etcp_conn_remove_ready_cbk ( conn , ca_ready_cb , ctx ) ;
st - > result_cb ( CONN_MGR _OK , st - > node_id , st - > result_arg ) ;
st - > result_cb ( CC _OK , st - > node_id , st - > result_arg ) ;
ca_cleanup ( st ) ;
ca_cleanup ( st ) ;
}
}
@ -896,7 +708,7 @@ static void ca_timeout_cb(void* arg) {
CC_ID , ctx - > addr_index , st - > pending_count , st - > addr_count , ( unsigned long long ) st - > node_id ) ;
CC_ID , ctx - > addr_index , st - > pending_count , st - > addr_count , ( unsigned long long ) st - > node_id ) ;
if ( st - > pending_count < = 0 & & ! st - > delivered ) {
if ( st - > pending_count < = 0 & & ! st - > delivered ) {
st - > delivered = 1 ;
st - > delivered = 1 ;
st - > result_cb ( CONN_MGR _ERR_TIMEOUT , st - > node_id , st - > result_arg ) ;
st - > result_cb ( CC _ERR_TIMEOUT , st - > node_id , st - > result_arg ) ;
}
}
}
}
@ -925,7 +737,7 @@ void chat_core_connect_auto(uint64_t node_id,
if ( ! best_socket ) {
if ( ! best_socket ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: auto_connect no AF_INET socket for node 0x%016llx " ,
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: auto_connect no AF_INET socket for node 0x%016llx " ,
CC_ID , ( unsigned long long ) node_id ) ;
CC_ID , ( unsigned long long ) node_id ) ;
cb ( CONN_MGR _ERR_INTERNAL , node_id , arg ) ;
cb ( CC _ERR_INTERNAL , node_id , arg ) ;
return ;
return ;
}
}
@ -945,7 +757,7 @@ void chat_core_connect_auto(uint64_t node_id,
if ( pubkey [ 0 ] = = 0 & & pubkey [ 1 ] = = 0 ) {
if ( pubkey [ 0 ] = = 0 & & pubkey [ 1 ] = = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: auto_connect no pubkey for node 0x%016llx " ,
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: auto_connect no pubkey for node 0x%016llx " ,
CC_ID , ( unsigned long long ) node_id ) ;
CC_ID , ( unsigned long long ) node_id ) ;
cb ( CONN_MGR _ERR_NOT_FOUND , node_id , arg ) ;
cb ( CC _ERR_NOT_FOUND , node_id , arg ) ;
return ;
return ;
}
}
@ -978,12 +790,12 @@ void chat_core_connect_auto(uint64_t node_id,
addr_count = uniq ; }
addr_count = uniq ; }
if ( addr_count = = 0 ) {
if ( addr_count = = 0 ) {
DEBUG_DEBUG ( DEBUG_CATEGORY_DEBUG , " %s: auto_connect no IPv4 addrs yet for node 0x%016llx (BGP not synced?) " , CC_ID , ( unsigned long long ) node_id ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DEBUG , " %s: auto_connect no IPv4 addrs yet for node 0x%016llx (BGP not synced?) " , CC_ID , ( unsigned long long ) node_id ) ;
cb ( CONN_MGR _ERR_NO_ADDRESSES , node_id , arg ) ;
cb ( CC _ERR_NO_ADDRESSES , node_id , arg ) ;
return ;
return ;
}
}
struct ca_state * pst = u_calloc ( 1 , sizeof ( struct ca_state ) ) ;
struct ca_state * pst = u_calloc ( 1 , sizeof ( struct ca_state ) ) ;
if ( ! pst ) { cb ( CONN_MGR _ERR_INTERNAL , node_id , arg ) ; return ; }
if ( ! pst ) { cb ( CC _ERR_INTERNAL , node_id , arg ) ; return ; }
pst - > inst = g_cc . inst ;
pst - > inst = g_cc . inst ;
pst - > addr_count = addr_count ;
pst - > addr_count = addr_count ;
pst - > pending_count = addr_count ;
pst - > pending_count = addr_count ;
@ -994,7 +806,7 @@ void chat_core_connect_auto(uint64_t node_id,
pst - > conns = u_calloc ( addr_count , sizeof ( struct ETCP_CONN * ) ) ;
pst - > conns = u_calloc ( addr_count , sizeof ( struct ETCP_CONN * ) ) ;
pst - > timers = u_calloc ( addr_count , sizeof ( void * ) ) ;
pst - > timers = u_calloc ( addr_count , sizeof ( void * ) ) ;
pst - > ctxs = u_calloc ( addr_count , sizeof ( struct ca_ctx * ) ) ;
pst - > ctxs = u_calloc ( addr_count , sizeof ( struct ca_ctx * ) ) ;
if ( ! pst - > conns | | ! pst - > timers | | ! pst - > ctxs ) { ca_cleanup ( pst ) ; cb ( CONN_MGR _ERR_INTERNAL , node_id , arg ) ; return ; }
if ( ! pst - > conns | | ! pst - > timers | | ! pst - > ctxs ) { ca_cleanup ( pst ) ; cb ( CC _ERR_INTERNAL , node_id , arg ) ; return ; }
for ( int i = 0 ; i < addr_count ; i + + ) {
for ( int i = 0 ; i < addr_count ; i + + ) {
struct sockaddr_in sin ;
struct sockaddr_in sin ;
@ -1039,7 +851,7 @@ void chat_core_connect_auto(uint64_t node_id,
if ( pst - > pending_count < = 0 & & ! pst - > delivered ) {
if ( pst - > pending_count < = 0 & & ! pst - > delivered ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: auto_connect all %d attempts failed to start " , CC_ID , addr_count ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_CONNECTIVITY , " %s: auto_connect all %d attempts failed to start " , CC_ID , addr_count ) ;
if ( out_state ) * out_state = NULL ;
if ( out_state ) * out_state = NULL ;
cb ( CONN_MGR _ERR_UNREACHABLE , node_id , arg ) ;
cb ( CC _ERR_UNREACHABLE , node_id , arg ) ;
ca_cleanup ( pst ) ;
ca_cleanup ( pst ) ;
}
}
}
}
@ -1265,12 +1077,6 @@ static void on_db_sync_insert(struct DB_SYNC_INSTANCE* si, uint64_t record_ts, c
/* ─── сбор статуса (NTP + connections) и отправка в GUI ─── */
/* ─── сбор статуса (NTP + connections) и отправка в GUI ─── */
static const char * conn_state_str ( uint8_t state ) {
switch ( state ) { case 0 : return " DISCONNECTED " ; case 1 : return " CONNECTING " ; case 2 : return " CONNECTED " ; default : return " ? " ; }
}
static const char * conn_type_str ( uint8_t t ) {
switch ( t ) { case 0 : return " NONE " ; case 1 : return " DIRECT " ; case 2 : return " REVERSE " ; case 3 : return " INDIRECT " ; default : return " ? " ; }
}
static const char * nat_type_str ( uint8_t t ) {
static const char * nat_type_str ( uint8_t t ) {
switch ( t ) { case 0 : return " UNKNOWN " ; case 1 : return " EIM " ; case 2 : return " STRICT " ; case 3 : return " DIRECT " ; default : return " ? " ; }
switch ( t ) { case 0 : return " UNKNOWN " ; case 1 : return " EIM " ; case 2 : return " STRICT " ; case 3 : return " DIRECT " ; default : return " ? " ; }
}
}
@ -1335,13 +1141,6 @@ static void chat_core_collect_status(void) {
struct ETCP_LINK * tl = conn - > links ;
struct ETCP_LINK * tl = conn - > links ;
while ( tl ) { link_count + + ; tl = tl - > next ; }
while ( tl ) { link_count + + ; tl = tl - > next ; }
uint8_t state = 0 , ctype = 0 ;
conn_mgr_get_status ( g_cc . inst - > conn_mgr , pid , & state , & ctype ) ;
char mgr_str [ 64 ] ;
if ( ctype = = 0 ) snprintf ( mgr_str , sizeof ( mgr_str ) , " %s " , conn_state_str ( state ) ) ;
else snprintf ( mgr_str , sizeof ( mgr_str ) , " %s/%s " , conn_state_str ( state ) , conn_type_str ( ctype ) ) ;
const char * init_str = conn - > initialized ? " " : " (!init) " ;
const char * init_str = conn - > initialized ? " " : " (!init) " ;
char myhex [ 5 ] , peerhex [ 5 ] ;
char myhex [ 5 ] , peerhex [ 5 ] ;
@ -1352,13 +1151,13 @@ static void chat_core_collect_status(void) {
get_node_name ( pid , peername , sizeof ( peername ) ) ;
get_node_name ( pid , peername , sizeof ( peername ) ) ;
if ( peername [ 0 ] )
if ( peername [ 0 ] )
off + = snprintf ( buf + off , sizeof ( buf ) - off , " [%s]→[%s] %s ETCP:%s%s(%dL) MGR:%s \n " ,
off + = snprintf ( buf + off , sizeof ( buf ) - off , " [%s]→[%s] %s ETCP:%s%s(%dL) \n " ,
myhex , peerhex , peername ,
myhex , peerhex , peername ,
conn - > links_up ? " UP " : " DOWN " , init_str , link_count , mgr_str ) ;
conn - > links_up ? " UP " : " DOWN " , init_str , link_count ) ;
else
else
off + = snprintf ( buf + off , sizeof ( buf ) - off , " [%s]→[%s] ETCP:%s%s(%dL) MGR:%s \n " ,
off + = snprintf ( buf + off , sizeof ( buf ) - off , " [%s]→[%s] ETCP:%s%s(%dL) \n " ,
myhex , peerhex ,
myhex , peerhex ,
conn - > links_up ? " UP " : " DOWN " , init_str , link_count , mgr_str ) ;
conn - > links_up ? " UP " : " DOWN " , init_str , link_count ) ;
int link_idx = 0 ;
int link_idx = 0 ;
struct ETCP_LINK * link = conn - > links ;
struct ETCP_LINK * link = conn - > links ;