@ -99,26 +99,26 @@ static struct ETCP_CONN* cs_find_conn_for_node(struct UTUN_INSTANCE* inst, uint6
static int cs_send ( struct chat_sync * cs , const char * ch_id , uint64_t dst ,
const uint8_t * payload , size_t len ) {
if ( len < 1 ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: cs_send len<1 " , CS_ID ) ; return - 1 ; }
if ( len < 1 ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: cs_send len<1 " , CS_ID ) ; return - 1 ; }
uint8_t ch_len = ( uint8_t ) strlen ( ch_id ) ;
if ( ch_len > 63 ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: cs_send ch_len=%u > 63 " , CS_ID , ch_len ) ; return - 1 ; }
if ( ch_len > 63 ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: cs_send ch_len=%u > 63 " , CS_ID , ch_len ) ; return - 1 ; }
size_t total = 1 + 1 + ch_len + len ;
uint8_t * buf = u_malloc ( total ) ;
if ( ! buf ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: cs_send alloc(%zu) failed " , CS_ID , total ) ; return - 1 ; }
if ( ! buf ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: cs_send alloc(%zu) failed " , CS_ID , total ) ; return - 1 ; }
uint8_t * p = buf ;
* p + + = ETCP_RT_ID_CHAT_SYNC ;
* p + + = ch_len ;
memcpy ( p , ch_id , ch_len ) ; p + = ch_len ;
memcpy ( p , payload , len ) ;
struct ll_entry * entry = queue_entry_new ( 0 ) ;
if ( ! entry ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: cs_send queue_entry_new failed " , CS_ID ) ; u_free ( buf ) ; return - 1 ; }
if ( ! entry ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: cs_send queue_entry_new failed " , CS_ID ) ; u_free ( buf ) ; return - 1 ; }
entry - > dgram = buf ; entry - > len = total ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: SEND %s to=%016llx ch=%s len=%zu " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: SEND %s to=%016llx ch=%s len=%zu " ,
CS_ID , cs_msg_name ( payload [ 0 ] ) , ( unsigned long long ) dst , ch_id , len ) ;
struct ETCP_CONN * conn = cs_find_conn_for_node ( cs - > inst , dst ) ;
if ( ! conn ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: no conn for node %016llx " , CS_ID , ( unsigned long long ) dst ) ; u_free ( buf ) ; queue_entry_free ( entry ) ; return - 1 ; }
if ( ! conn ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: no conn for node %016llx " , CS_ID , ( unsigned long long ) dst ) ; u_free ( buf ) ; queue_entry_free ( entry ) ; return - 1 ; }
int rc = etcp_send ( conn , entry ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DEBUG , " %s: etcp_send rc=%d id=0x%02x to=%016llx conn=%s " , CS_ID , rc , payload [ 0 ] , ( unsigned long long ) dst , conn - > log_name ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: etcp_send rc=%d id=0x%02x to=%016llx conn=%s " , CS_ID , rc , payload [ 0 ] , ( unsigned long long ) dst , conn - > log_name ) ;
return rc ;
}
@ -158,7 +158,7 @@ static int cs_send_channel_invite(struct chat_sync* cs, struct UTUN_INSTANCE* in
static void chat_sync_recv_cb ( struct ETCP_CONN * conn , struct ll_entry * entry ) {
if ( ! entry | | entry - > len < 4 ) {
if ( entry ) {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: recv short entry len=%zu conn=%s " , CS_ID , entry - > len , conn ? conn - > log_name : " ? " ) ;
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: recv short entry len=%zu conn=%s " , CS_ID , entry - > len , conn ? conn - > log_name : " ? " ) ;
if ( entry - > dgram ) u_free ( entry - > dgram ) ; queue_entry_free ( entry ) ;
}
return ;
@ -174,22 +174,22 @@ static void chat_sync_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
char ch_id [ 64 ] ; memcpy ( ch_id , d + 2 , ch_len ) ; ch_id [ ch_len ] = ' \0 ' ;
uint8_t type = d [ 2 + ch_len ] ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: recv %s(%02x) from=%016llx ch=%s len=%zu " ,
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: recv %s(%02x) from=%016llx ch=%s len=%zu " ,
CS_ID , cs_msg_name ( type ) , type , ( unsigned long long ) peer , ch_id , dlen ) ;
const uint8_t * pl = d + 3 + ch_len ;
size_t plen = dlen - 3 - ch_len ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: RECV %s from=%016llx ch=%s len=%zu " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: RECV %s from=%016llx ch=%s len=%zu " ,
CS_ID , cs_msg_name ( type ) , ( unsigned long long ) peer , ch_id , plen ) ;
switch ( type ) {
case CS_MSG_CHANNEL_INFO_REQ : DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: → handle INFO_REQ " , CS_ID ) ; cs_handle_channel_info_req ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_CHANNEL_INFO_RESP : DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: → handle INFO_RESP " , CS_ID ) ; cs_handle_channel_info_resp ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_CHANNEL_JOIN : DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: → handle JOIN " , CS_ID ) ; cs_handle_channel_join ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_WELCOME : DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: → handle WELCOME " , CS_ID ) ; cs_handle_welcome ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_PEER_UPSERT : DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: → handle PEER_UPSERT " , CS_ID ) ; cs_handle_peer_upsert ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_CHANNEL_INFO_REQ : DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: → handle INFO_REQ " , CS_ID ) ; cs_handle_channel_info_req ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_CHANNEL_INFO_RESP : DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: → handle INFO_RESP " , CS_ID ) ; cs_handle_channel_info_resp ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_CHANNEL_JOIN : DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: → handle JOIN " , CS_ID ) ; cs_handle_channel_join ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_WELCOME : DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: → handle WELCOME " , CS_ID ) ; cs_handle_welcome ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_PEER_UPSERT : DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: → handle PEER_UPSERT " , CS_ID ) ; cs_handle_peer_upsert ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_ERROR : {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: RECV ERROR from=%016llx ch=%s " , CS_ID , ( unsigned long long ) peer , ch_id ) ;
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: RECV ERROR from=%016llx ch=%s " , CS_ID , ( unsigned long long ) peer , ch_id ) ;
if ( g_cs - > info_req_timer ) { uasync_cancel_timeout ( g_cs - > inst - > ua , g_cs - > info_req_timer ) ; g_cs - > info_req_timer = NULL ; }
uint8_t err [ 20 ] ; memcpy ( err , & peer , 8 ) ; int r = - 1 ; memcpy ( err + 8 , & r , 4 ) ;
memcpy ( err + 12 , & g_cs - > pending_invite_ch_id , 8 ) ; chat_event_post ( CHAT_EVT_CONNECT_RESULT , err , 20 ) ;
@ -198,7 +198,7 @@ static void chat_sync_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
}
case CS_MSG_PEER_REMOVE : cs_handle_peer_remove ( g_cs , peer , ch_id , pl , plen ) ; break ;
case CS_MSG_CHANNEL_INVITE : cs_handle_channel_invite ( g_cs , peer , ch_id , pl , plen ) ; break ;
default : DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: UNKNOWN msg type=%02x from=%016llx " , CS_ID , type , ( unsigned long long ) peer ) ; break ;
default : DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: UNKNOWN msg type=%02x from=%016llx " , CS_ID , type , ( unsigned long long ) peer ) ; break ;
}
u_free ( entry - > dgram ) ; queue_entry_free ( entry ) ;
}
@ -209,7 +209,7 @@ static void cs_info_req_timeout_cb(void* arg) {
struct chat_sync * cs = ( struct chat_sync * ) arg ;
if ( ! cs | | ! cs - > initialized ) return ;
cs - > info_req_timer = NULL ;
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_REQ timeout peer=%016llx ch=%llu " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_REQ timeout peer=%016llx ch=%llu " ,
CS_ID , ( unsigned long long ) cs - > pending_invite_node_id ,
( unsigned long long ) cs - > pending_invite_ch_id ) ;
uint8_t err [ 20 ] ; memcpy ( err , & cs - > pending_invite_node_id , 8 ) ;
@ -225,7 +225,7 @@ static void cs_join_timeout_cb(void* arg) {
if ( ! cs | | ! cs - > initialized ) return ;
cs - > join_timer = NULL ;
uint64_t peer = cs - > pending_invite_node_id ;
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_JOIN timeout peer=%016llx ch=%llu " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_JOIN timeout peer=%016llx ch=%llu " ,
CS_ID , ( unsigned long long ) peer , ( unsigned long long ) cs - > pending_invite_ch_id ) ;
uint8_t err [ 20 ] ; memcpy ( err , & peer , 8 ) ;
int r = CONN_EVENT_TIMEOUT ; memcpy ( err + 8 , & r , 4 ) ;
@ -241,7 +241,7 @@ static void cs_invite_send_timeout_cb(void* arg) {
if ( ! cs | | ! cs - > initialized ) return ;
cs - > invite_send_timer = NULL ;
uint64_t peer = cs - > pending_invite_node_id ;
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE timeout — joiner did not respond peer=%016llx ch=%llu " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE timeout — joiner did not respond peer=%016llx ch=%llu " ,
CS_ID , ( unsigned long long ) peer , ( unsigned long long ) cs - > pending_invite_ch_id ) ;
uint8_t err [ 20 ] ; memcpy ( err , & peer , 8 ) ;
int r = CONN_EVENT_TIMEOUT ; memcpy ( err + 8 , & r , 4 ) ;
@ -257,8 +257,8 @@ static void cs_invite_send_timeout_cb(void* arg) {
static struct ETCP_CONN * cs_find_conn_for_node ( struct UTUN_INSTANCE * inst , uint64_t node_id ) {
struct ETCP_CONN * conn = instance_find_conn ( inst , node_id ) ;
if ( conn & & conn - > initialized & & conn - > links_up ) return conn ;
if ( ! inst - > connections ) { DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: find_conn connections=NULL " , CS_ID ) ; return NULL ; }
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: find_conn node=%016llx NOT FOUND (head=%p count=%d) " ,
if ( ! inst - > connections ) { DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: find_conn connections=NULL " , CS_ID ) ; return NULL ; }
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: find_conn node=%016llx NOT FOUND (head=%p count=%d) " ,
CS_ID , ( unsigned long long ) node_id , ( void * ) inst - > connections - > head , queue_entry_count ( inst - > connections ) ) ;
return NULL ;
}
@ -275,7 +275,7 @@ static struct ETCP_CONN* cs_find_conn_by_pubkey(struct UTUN_INSTANCE* inst,
if ( conn & & conn - > initialized & & conn - > links_up
& & memcmp ( conn - > crypto_ctx . peer_public_key , pubkey_bin , 32 ) = = 0 ) {
* out_node_id = conn - > peer_node_id ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: find_conn_by_pubkey MATCH conn=%s peer=0x%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: find_conn_by_pubkey MATCH conn=%s peer=0x%016llx " ,
CS_ID , conn - > log_name , ( unsigned long long ) conn - > peer_node_id ) ;
return conn ;
}
@ -287,10 +287,10 @@ static struct ETCP_CONN* cs_find_conn_by_pubkey(struct UTUN_INSTANCE* inst,
/* ── helper: check if peer has active ETCP link ── */
static int cs_is_peer_online ( struct UTUN_INSTANCE * inst , uint64_t peer_id ) {
if ( ! inst - > connections ) { DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: is_online peer=0x%016llx CONNS=NULL " , CS_ID , ( unsigned long long ) peer_id ) ; return 0 ; }
if ( ! inst - > connections ) { DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: is_online peer=0x%016llx CONNS=NULL " , CS_ID , ( unsigned long long ) peer_id ) ; return 0 ; }
struct ETCP_CONN * conn = instance_find_conn ( inst , peer_id ) ;
if ( conn ) return conn - > initialized & & conn - > links_up ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: is_online peer=0x%016llx NOT FOUND " , CS_ID , ( unsigned long long ) peer_id ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: is_online peer=0x%016llx NOT FOUND " , CS_ID , ( unsigned long long ) peer_id ) ;
return 0 ;
}
@ -305,7 +305,7 @@ static void cs_post_channel_online(struct chat_sync* cs, const char* ch_id) {
for ( int j = 0 ; j < ch - > peer_count ; j + + ) {
int p_on = cs_is_peer_online ( cs - > inst , ch - > peer_ids [ j ] ) ;
if ( p_on ) online + + ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: PEERS_ONLINE peer[%d]=0x%016llx online=%d " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEERS_ONLINE peer[%d]=0x%016llx online=%d " ,
CS_ID , j , ( unsigned long long ) ch - > peer_ids [ j ] , p_on ) ;
}
}
@ -315,7 +315,7 @@ static void cs_post_channel_online(struct chat_sync* cs, const char* ch_id) {
memcpy ( evt + 1 , ch_id , cl ) ;
uint16_t oc = ( uint16_t ) online ; memcpy ( evt + 1 + cl , & oc , 2 ) ;
chat_event_post ( CHAT_EVT_CHANNEL_PEERS_ONLINE , evt , 1 + ( int ) cl + 2 ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: PEERS_ONLINE ch=%.*s total_online=%d " , CS_ID , ( int ) cl , ch_id , online ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEERS_ONLINE ch=%.*s total_online=%d " , CS_ID , ( int ) cl , ch_id , online ) ;
}
/* ── Throttled sync (не чаще CS_SYNC_INTERVAL_MS) ── */
@ -327,7 +327,7 @@ static void cs_flush_sync(struct chat_sync* cs) {
for ( int j = 0 ; j < ch - > peer_count ; j + + ) {
uint64_t pid = ch - > peer_ids [ j ] ;
if ( pid = = myid | | ! cs_is_peer_online ( cs - > inst , pid ) ) continue ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: flush_sync start for peer=%016llx ch=%s " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: flush_sync start for peer=%016llx ch=%s " ,
CS_ID , ( unsigned long long ) pid , ch - > channel_id ) ;
member_sync_start ( cs - > inst , pid , ch - > channel_id , NULL , NULL ) ;
}
@ -339,7 +339,7 @@ static void cs_sync_timer_cb(void* arg) {
if ( ! cs | | ! cs - > initialized ) return ;
cs - > sync_timer = NULL ;
cs - > sync_scheduled = 0 ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: sync timer fire " , CS_ID ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: sync timer fire " , CS_ID ) ;
cs_flush_sync ( cs ) ;
}
@ -348,14 +348,14 @@ static void cs_schedule_sync(struct chat_sync* cs) {
cs - > sync_scheduled = 1 ;
cs - > sync_timer = uasync_set_timeout ( cs - > inst - > ua ,
CS_SYNC_INTERVAL_MS * 10 , cs , cs_sync_timer_cb , " cs_sync " ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: sync scheduled in %ums " , CS_ID , CS_SYNC_INTERVAL_MS ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: sync scheduled in %ums " , CS_ID , CS_SYNC_INTERVAL_MS ) ;
}
/* ── Unified peer status change (локальная БД + GUI + push_update + schedule_sync) ── */
static void cs_on_remote_status_changed ( uint64_t peer , int online ) {
if ( ! g_cs ) return ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: remote status changed peer=%016llx online=%d " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: remote status changed peer=%016llx online=%d " ,
CS_ID , ( unsigned long long ) peer , online ) ;
for ( int i = 0 ; i < g_cs - > channel_count ; i + + ) {
for ( int j = 0 ; j < g_cs - > channels [ i ] . peer_count ; j + + ) {
@ -397,7 +397,7 @@ static void cs_on_peer_status_changed(uint64_t peer, int online) {
}
}
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: peer_status_changed peer=0x%016llx online=%d channels=%d found=%d " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: peer_status_changed peer=0x%016llx online=%d channels=%d found=%d " ,
CS_ID , ( unsigned long long ) peer , online , g_cs - > channel_count , found_in_channel ) ;
/* 4. Запланировать member_sync_start (throttled) */
@ -407,7 +407,7 @@ static void cs_on_peer_status_changed(uint64_t peer, int online) {
static void _on_member_sync_done ( uint64_t peer , const char * ns , int result , void * arg ) {
struct channel_cache * ch = ( struct channel_cache * ) arg ;
if ( result = = MT_OK & & ch ) ch - > synced = CS_SYNC_DONE ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: member_sync %s ns=%s peer=%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: member_sync %s ns=%s peer=%016llx " ,
CS_ID , result = = MT_OK ? " OK " : " FAIL " , ns , ( unsigned long long ) peer ) ;
}
@ -418,18 +418,18 @@ struct invite_sync_arg {
static void _on_invite_sync_done ( uint64_t peer , const char * ns , int result , void * arg ) {
struct invite_sync_arg * sa = ( struct invite_sync_arg * ) arg ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_sync %s ns=%s peer=%016llx sa=%p node=0x%016llx ch=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_sync %s ns=%s peer=%016llx sa=%p node=0x%016llx ch=%s " ,
CS_ID , result = = MT_OK ? " OK " : " FAIL " , ns ,
( unsigned long long ) peer , ( void * ) sa , sa ? ( unsigned long long ) sa - > node_id : 0 , sa ? sa - > ch_id : " (null) " ) ;
if ( result = = MT_OK & & sa & & g_cs ) {
if ( sa - > node_id = = 0 | | sa - > ch_id [ 0 ] = = ' \0 ' ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_sync CORRUPTED sa=%p node_id=0x%016llx ch_id='%s' — skip, will free " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_sync CORRUPTED sa=%p node_id=0x%016llx ch_id='%s' — skip, will free " ,
CS_ID , ( void * ) sa , ( unsigned long long ) sa - > node_id , sa - > ch_id ) ;
} else {
cs_post_channel_online ( g_cs , sa - > ch_id ) ;
uint8_t one = 1 ;
merkle_sync_push_update ( g_cs - > inst , sa - > ch_id , sa - > node_id , 0x01 , & one , 1 ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_sync push_update node=0x%016llx online=1 ch=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_sync push_update node=0x%016llx online=1 ch=%s " ,
CS_ID , ( unsigned long long ) sa - > node_id , sa - > ch_id ) ;
}
}
@ -450,7 +450,7 @@ static void cs_start_channel_join(struct chat_sync* cs, uint64_t peer) {
cs_send ( cs , ch_id_str , peer , req , 2 + ( plen > 127 ? 127 : ( int ) plen ) ) ;
cs - > info_req_timer = uasync_set_timeout ( cs - > inst - > ua ,
CS_INFO_REQ_TIMEOUT_MS * 10 , cs , cs_info_req_timeout_cb , " cs_info_req " ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: sent CHANNEL_INFO_REQ ch=%llu peer=0x%016llx pass_len=%zu " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: sent CHANNEL_INFO_REQ ch=%llu peer=0x%016llx pass_len=%zu " ,
CS_ID , ( unsigned long long ) cs - > pending_invite_ch_id , ( unsigned long long ) peer , plen ) ;
}
@ -461,14 +461,14 @@ static void cs_on_conn_up(struct ETCP_CONN* conn, int event, void* arg) { (void)
if ( ! conn | | ! g_cs ) return ;
uint64_t peer = conn - > peer_node_id ;
if ( peer = = 0 | | peer = = g_cs - > inst - > node_id ) return ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: conn_up peer=%016llx init=%d links=%d " , CS_ID , ( unsigned long long ) peer , conn - > initialized , conn - > links_up ) ;
if ( ! conn - > initialized ) { DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: conn_up SKIP — not initialized peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ; return ; }
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: conn_up peer=%016llx init=%d links=%d " , CS_ID , ( unsigned long long ) peer , conn - > initialized , conn - > links_up ) ;
if ( ! conn - > initialized ) { DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: conn_up SKIP — not initialized peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ; return ; }
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: conn_up peer=%016llx pending_invite=%llu links_up=%d " , CS_ID , ( unsigned long long ) peer , ( unsigned long long ) g_cs - > pending_invite_ch_id , conn - > links_up ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: conn_up peer=%016llx pending_invite=%llu links_up=%d " , CS_ID , ( unsigned long long ) peer , ( unsigned long long ) g_cs - > pending_invite_ch_id , conn - > links_up ) ;
if ( g_cs - > pending_invite_ch_id ! = 0 ) {
if ( g_cs - > pending_invite_node_id ! = 0 & & g_cs - > pending_invite_node_id ! = peer )
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: invite node_id MISMATCH: invite=0x%016llx ETCP_peer=0x%016llx — invite is STALE! " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite node_id MISMATCH: invite=0x%016llx ETCP_peer=0x%016llx — invite is STALE! " ,
CS_ID , ( unsigned long long ) g_cs - > pending_invite_node_id , ( unsigned long long ) peer ) ;
g_cs - > pending_invite_node_id = peer ;
if ( g_cs - > pending_invite_is_inviter ) {
@ -497,13 +497,13 @@ static void cs_on_conn_down(struct ETCP_CONN* conn, int event, void* arg) { (voi
( void ) arg ;
if ( ! conn | | ! g_cs ) return ;
uint64_t peer = conn - > peer_node_id ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: conn_down peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: conn_down peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
cs_on_peer_status_changed ( peer , 0 ) ;
cs_cancel_proto_timers ( g_cs ) ;
if ( g_cs - > pending_invite_node_id = = peer ) {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: conn down while waiting invite resp peer=%016llx, timers cancelled, state kept for retry on reconnect " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: conn down while waiting invite resp peer=%016llx, timers cancelled, state kept for retry on reconnect " ,
CS_ID , ( unsigned long long ) peer ) ;
/* invite state survives connection flaps: only timeout or explicit protocol end clears it */
}
@ -532,7 +532,7 @@ static void cs_on_conn_status(struct ETCP_CONN* conn, int status, void* arg) {
static void cs_on_new_conn ( struct ETCP_CONN * conn , void * arg ) {
( void ) arg ;
if ( ! conn ) return ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: new_conn conn=%p " , CS_ID , ( void * ) conn ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: new_conn conn=%p " , CS_ID , ( void * ) conn ) ;
etcp_conn_add_cbk ( conn , cs_on_conn_up , NULL , ETCP_CBK_EVENT_UP ) ;
etcp_conn_add_cbk ( conn , cs_on_conn_down , NULL , ETCP_CBK_EVENT_DOWN ) ;
}
@ -599,7 +599,7 @@ static void refresh_timer_cb(void* arg) {
int chat_sync_init ( struct UTUN_INSTANCE * inst ) {
if ( ! inst ) return - 1 ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: init " , CS_ID ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: init " , CS_ID ) ;
struct chat_sync * cs = u_calloc ( 1 , sizeof ( * cs ) ) ;
if ( ! cs ) return - 1 ;
cs - > inst = inst ;
@ -619,14 +619,14 @@ int chat_sync_init(struct UTUN_INSTANCE* inst) {
member_sync_init ( inst ) ;
member_sync_set_node_updated_cb ( cs_on_remote_status_changed ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: initialized " , CS_ID ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: initialized " , CS_ID ) ;
return 0 ;
}
void chat_sync_destroy ( struct UTUN_INSTANCE * inst ) {
struct chat_sync * cs = g_cs ;
if ( ! cs | | ! inst ) return ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: destroy " , CS_ID ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: destroy " , CS_ID ) ;
if ( cs - > sync_timer ) { uasync_cancel_timeout ( inst - > ua , cs - > sync_timer ) ; cs - > sync_timer = NULL ; }
if ( cs - > invite_send_timer ) { uasync_cancel_timeout ( inst - > ua , cs - > invite_send_timer ) ; cs - > invite_send_timer = NULL ; }
if ( cs - > sync_scheduled ) { cs - > sync_scheduled = 0 ; cs_flush_sync ( cs ) ; }
@ -767,7 +767,7 @@ void chat_sync_connect_from_invite(uint64_t channel_id, uint64_t node_id,
}
struct chat_invite * inv = u_calloc ( 1 , sizeof ( struct chat_invite ) ) ;
if ( ! inv ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: connect_from_invite calloc failed " , CS_ID ) ; return ; }
if ( ! inv ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: connect_from_invite calloc failed " , CS_ID ) ; return ; }
inv - > channel_id = channel_id ;
inv - > node_id = node_id ;
@ -775,7 +775,7 @@ void chat_sync_connect_from_invite(uint64_t channel_id, uint64_t node_id,
size_t addrs_sz = addrs_data_len > 0 ? ( size_t ) addrs_data_len : ( size_t ) addr_count * 9 ;
inv - > addrs_data = u_malloc ( addrs_sz ) ;
if ( ! inv - > addrs_data ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: connect_from_invite malloc(%zu) failed " , CS_ID , addrs_sz ) ; u_free ( inv ) ; return ; }
if ( ! inv - > addrs_data ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: connect_from_invite malloc(%zu) failed " , CS_ID , addrs_sz ) ; u_free ( inv ) ; return ; }
memcpy ( inv - > addrs_data , addrs_data , addrs_sz ) ;
inv - > addr_count = addr_count ;
@ -794,7 +794,7 @@ void chat_sync_connect_from_invite(uint64_t channel_id, uint64_t node_id,
( long long ) channel_id , ( long long ) node_id , addr_count , password ? " yes " : " no " ) ;
# endif
# ifndef __ANDROID__
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: invite start ch=%llu node=0x%016llx pubkey=%016llx... addrs=%d pass=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite start ch=%llu node=0x%016llx pubkey=%016llx... addrs=%d pass=%s " ,
CS_ID , channel_id , node_id , * ( const uint64_t * ) pubkey_bin , addr_count , password & & password [ 0 ] ? " yes " : " no " ) ;
# endif
@ -807,20 +807,20 @@ void chat_sync_connect_from_invite(uint64_t channel_id, uint64_t node_id,
/* ─── chat_sync_join_channel: join channel via already-connected peer ─── */
void chat_sync_join_channel ( struct UTUN_INSTANCE * inst , const char * ch_id , uint64_t target_node_id ) {
if ( ! g_cs ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: join_channel: g_cs=NULL, chat_sync not initialized " , CS_ID ) ; return ; }
if ( ! inst ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: join_channel: inst=NULL " , CS_ID ) ; return ; }
if ( ! ch_id | | ! ch_id [ 0 ] ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: join_channel: ch_id NULL/empty " , CS_ID ) ; return ; }
if ( ! g_cs ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: join_channel: g_cs=NULL, chat_sync not initialized " , CS_ID ) ; return ; }
if ( ! inst ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: join_channel: inst=NULL " , CS_ID ) ; return ; }
if ( ! ch_id | | ! ch_id [ 0 ] ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: join_channel: ch_id NULL/empty " , CS_ID ) ; return ; }
uint64_t channel_id = strtoull ( ch_id , NULL , 10 ) ;
if ( channel_id = = 0 ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: join_channel invalid ch_id='%s' " , CS_ID , ch_id ) ; return ; }
if ( channel_id = = 0 ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: join_channel invalid ch_id='%s' " , CS_ID , ch_id ) ; return ; }
struct ETCP_CONN * conn = instance_find_conn ( inst , target_node_id ) ;
if ( ! conn | | ! conn - > links_up | | ! conn - > initialized ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: join_channel no active conn to 0x%016llx for ch=%s " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: join_channel no active conn to 0x%016llx for ch=%s " ,
CS_ID , ( unsigned long long ) target_node_id , ch_id ) ;
return ;
}
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: join_channel ch=%s peer=0x%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: join_channel ch=%s peer=0x%016llx " ,
CS_ID , ch_id , ( unsigned long long ) target_node_id ) ;
g_cs - > pending_invite_ch_id = channel_id ;
@ -834,7 +834,7 @@ void chat_sync_join_channel(struct UTUN_INSTANCE* inst, const char* ch_id, uint6
static int cs_ed25519_sign ( const uint8_t * privkey , const uint8_t * msg , size_t msg_len ,
uint8_t * sig_out ) {
EVP_PKEY * pkey = EVP_PKEY_new_raw_private_key ( EVP_PKEY_ED25519 , NULL , privkey , SC_PRIVKEY_SIZE ) ;
if ( ! pkey ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: EVP_PKEY_new failed " , CS_ID ) ; return - 1 ; }
if ( ! pkey ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: EVP_PKEY_new failed " , CS_ID ) ; return - 1 ; }
EVP_MD_CTX * mdctx = EVP_MD_CTX_new ( ) ;
if ( ! mdctx ) { EVP_PKEY_free ( pkey ) ; return - 1 ; }
int ok = ( EVP_DigestSignInit ( mdctx , NULL , NULL , NULL , pkey ) = = 1 )
@ -847,7 +847,7 @@ static int cs_ed25519_sign(const uint8_t* privkey, const uint8_t* msg, size_t ms
static int cs_ed25519_verify ( const uint8_t * pubkey , const uint8_t * msg , size_t msg_len ,
const uint8_t * sig ) {
EVP_PKEY * pkey = EVP_PKEY_new_raw_public_key ( EVP_PKEY_ED25519 , NULL , pubkey , SC_PUBKEY_SIZE ) ;
if ( ! pkey ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: EVP_PKEY_new pub failed " , CS_ID ) ; return - 1 ; }
if ( ! pkey ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: EVP_PKEY_new pub failed " , CS_ID ) ; return - 1 ; }
EVP_MD_CTX * mdctx = EVP_MD_CTX_new ( ) ;
if ( ! mdctx ) { EVP_PKEY_free ( pkey ) ; return - 1 ; }
int rc = EVP_DigestVerifyInit ( mdctx , NULL , NULL , NULL , pkey )
@ -876,7 +876,7 @@ static int _get_node_name(sqlite3* db, uint64_t node_id, char* out, size_t sz) {
if ( ! db | | ! out | | ! sz ) return - 1 ;
sqlite3_stmt * st = NULL ;
sqlite3_prepare_v2 ( db , " SELECT name FROM nodes WHERE node_id=? " , - 1 , & st , NULL ) ;
if ( ! st ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: _get_node_name prepare failed node=0x%016llx " , CS_ID , ( unsigned long long ) node_id ) ; return - 1 ; }
if ( ! st ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: _get_node_name prepare failed node=0x%016llx " , CS_ID , ( unsigned long long ) node_id ) ; return - 1 ; }
sqlite3_bind_int64 ( st , 1 , ( sqlite3_int64 ) node_id ) ;
int rc = - 1 ;
if ( sqlite3_step ( st ) = = SQLITE_ROW ) {
@ -892,7 +892,7 @@ static int _get_node_name(sqlite3* db, uint64_t node_id, char* out, size_t sz) {
static void cs_handle_channel_info_req ( struct chat_sync * cs , uint64_t peer ,
const char * ch_id , const uint8_t * pl , size_t len ) {
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: INFO_REQ ch=%s from=%016llx len=%zu " , CS_ID , ch_id , ( unsigned long long ) peer , len ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: INFO_REQ ch=%s from=%016llx len=%zu " , CS_ID , ch_id , ( unsigned long long ) peer , len ) ;
/* joiner responded to our CHANNEL_INVITE — cancel invite send timer */
if ( cs - > invite_send_timer ) { uasync_cancel_timeout ( cs - > inst - > ua , cs - > invite_send_timer ) ; cs - > invite_send_timer = NULL ; }
@ -912,7 +912,7 @@ static void cs_handle_channel_info_req(struct chat_sync* cs, uint64_t peer,
struct global_config * gcfg = & cs - > inst - > config - > global ;
if ( gcfg - > chatserver_enabled & & gcfg - > chatserver_join_password [ 0 ] ) {
if ( strcmp ( req_password , gcfg - > chatserver_join_password ) ! = 0 ) {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_REQ wrong password ch=%s from=%016llx (got '%s', expected '%s') " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_REQ wrong password ch=%s from=%016llx (got '%s', expected '%s') " ,
CS_ID , ch_id , ( unsigned long long ) peer , req_password , gcfg - > chatserver_join_password ) ;
uint8_t err [ 2 ] = { CS_MSG_ERROR , 0x01 } ; /* 0x01 = wrong password */
cs_send ( cs , ch_id , peer , err , 2 ) ;
@ -924,13 +924,13 @@ static void cs_handle_channel_info_req(struct chat_sync* cs, uint64_t peer,
char name [ 128 ] ; uint64_t owner ; uint8_t x25519 [ 32 ] , ed_pub [ 32 ] , ch_sig [ 64 ] ;
if ( topo_node_sqlite_channel_get ( cs - > inst - > topo_sqlite_db ,
ch_id , name , ( int ) sizeof ( name ) , & owner , x25519 , ed_pub , ch_sig ) ! = 0 ) {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_REQ unknown ch=%s from=%016llx " , CS_ID , ch_id , ( unsigned long long ) peer ) ;
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_REQ unknown ch=%s from=%016llx " , CS_ID , ch_id , ( unsigned long long ) peer ) ;
uint8_t err [ 1 ] = { CS_MSG_ERROR } ; cs_send ( cs , ch_id , peer , err , 1 ) ;
return ;
}
uint64_t myid = cs - > inst - > node_id ;
if ( memcmp ( cs - > inst - > my_keys . public_key , x25519 , 32 ) ! = 0 )
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP pubkey MISMATCH: my=%016llx ch=%016llx — channel was created with DIFFERENT keys! " ,
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP pubkey MISMATCH: my=%016llx ch=%016llx — channel was created with DIFFERENT keys! " ,
CS_ID , * ( const uint64_t * ) cs - > inst - > my_keys . public_key , * ( const uint64_t * ) x25519 ) ;
/* load or create join_sig */
uint8_t my_join_sig [ 64 ] = { 0 } ; uint64_t my_join_ts = 0 ;
@ -945,7 +945,7 @@ static void cs_handle_channel_info_req(struct chat_sync* cs, uint64_t peer,
my_join_ts = ( uint64_t ) ntp_time_get_seconds ( cs - > inst ) ;
memcpy ( join_msg + mlen , & my_join_ts , 8 ) ; mlen + = 8 ;
cs_ed25519_sign ( cs - > inst - > my_ed25519_privkey , join_msg , mlen , my_join_sig ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP created NEW join_sig: myid=%016llx ts=%llu " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP created NEW join_sig: myid=%016llx ts=%llu " ,
CS_ID , ( unsigned long long ) myid , ( unsigned long long ) my_join_ts ) ;
}
}
@ -989,11 +989,11 @@ static void cs_handle_channel_info_req(struct chat_sync* cs, uint64_t peer,
static void cs_handle_channel_info_resp ( struct chat_sync * cs , uint64_t peer ,
const char * ch_id , const uint8_t * pl , size_t len ) {
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: INFO_RESP ch=%s from=%016llx len=%zu " , CS_ID , ch_id , ( unsigned long long ) peer , len ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: INFO_RESP ch=%s from=%016llx len=%zu " , CS_ID , ch_id , ( unsigned long long ) peer , len ) ;
if ( cs - > info_req_timer ) { uasync_cancel_timeout ( cs - > inst - > ua , cs - > info_req_timer ) ; cs - > info_req_timer = NULL ; }
if ( len < 1 ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ; return ; }
if ( len < 1 ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ; return ; }
uint8_t nl = pl [ 0 ] ;
if ( 1 + nl + 8 + 32 + 32 + 64 + 1 + 64 + 8 + 1 > len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP truncated len=%zu " , CS_ID , len ) ; return ; }
if ( 1 + nl + 8 + 32 + 32 + 64 + 1 + 64 + 8 + 1 > len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP truncated len=%zu " , CS_ID , len ) ; return ; }
const uint8_t * p = pl + 1 ;
char name [ 128 ] ; memcpy ( name , p , nl ) ; name [ nl ] = ' \0 ' ; p + = nl ;
uint64_t owner ; memcpy ( & owner , p , 8 ) ; p + = 8 ;
@ -1003,7 +1003,7 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
uint8_t inv_flags = * p + + ;
const uint8_t * inviter_join_sig = NULL ; uint64_t inviter_join_ts = 0 ;
if ( inv_flags & PEERS_FLAG_HAS_JOIN ) {
if ( p + 72 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP truncated at inviter_join_sig peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ; return ; }
if ( p + 72 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP truncated at inviter_join_sig peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ; return ; }
inviter_join_sig = p ; p + = 64 ; memcpy ( & inviter_join_ts , p , 8 ) ; p + = 8 ;
}
const uint8_t * inviter_update_sig = p ; p + = 64 ; uint64_t inviter_update_ts ;
@ -1012,7 +1012,7 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
char inv_userinfo [ 128 ] = " " ;
if ( p + inv_userinfo_len < = pl + len ) { memcpy ( inv_userinfo , p , inv_userinfo_len ) ; inv_userinfo [ inv_userinfo_len ] = ' \0 ' ; }
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP from peer=%016llx owner=%016llx ch_x25519=%016llx ch_ed=%016llx name=%s " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP from peer=%016llx owner=%016llx ch_x25519=%016llx ch_ed=%016llx name=%s " ,
CS_ID , ( unsigned long long ) peer , ( unsigned long long ) owner ,
* ( const uint64_t * ) x25519 , * ( const uint64_t * ) ed_pub , name ) ;
@ -1024,7 +1024,7 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
memcpy ( vmsg + vlen , x25519 , 32 ) ; vlen + = 32 ;
memcpy ( vmsg + vlen , ed_pub , 32 ) ; vlen + = 32 ;
if ( cs_ed25519_verify ( ed_pub , vmsg , vlen , ch_sig ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP invalid ch_sig ch=%s " , CS_ID , ch_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP invalid ch_sig ch=%s " , CS_ID , ch_id ) ;
return ;
}
@ -1032,13 +1032,13 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
topo_node_sqlite_channel_put ( cs - > inst - > topo_sqlite_db ,
ch_id , name , owner , x25519 , NULL , ed_pub , NULL , ch_sig ) ;
chat_core_ensure_channel_ready ( ch_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: channel ready for sync ch=%s, db_sync will pick up via periodic check or active conn " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: channel ready for sync ch=%s, db_sync will pick up via periodic check or active conn " ,
CS_ID , ch_id ) ;
/* verify inviter's join_sig AND save node info using ETCP-authenticated keys */
{ struct ETCP_CONN * inv_conn = cs_find_conn_for_node ( cs - > inst , peer ) ;
if ( ! inv_conn ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP no ETCP conn for inviter peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP no ETCP conn for inviter peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
return ;
}
const uint8_t * inv_x25519 = inv_conn - > crypto_ctx . peer_public_key ;
@ -1050,12 +1050,12 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
{ const char * nm = inv_userinfo [ 0 ] ? inv_userinfo : " " ;
size_t nl2 = strlen ( nm ) ; memcpy ( ivmsg + ilen , nm , nl2 + 1 ) ; ilen + = nl2 + 1 ; }
if ( cs_ed25519_verify ( inv_ed , ivmsg , ilen , inviter_update_sig ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INFO_RESP invalid inviter_update_sig peer=%016llx ts=%llu " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INFO_RESP invalid inviter_update_sig peer=%016llx ts=%llu " ,
CS_ID , ( unsigned long long ) peer , ( unsigned long long ) inviter_update_ts ) ;
}
sqlite3 * vdb = cs - > inst - > topo_sqlite_db ;
/* save inviter's address from ETCP connection */
{ DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] INFO_RESP save inviter peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
{ DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] INFO_RESP save inviter peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
struct ETCP_LINK * lk = inv_conn - > links ;
int lk_count = 0 , lk_written = 0 ;
while ( lk ) { lk_count + + ;
@ -1072,19 +1072,19 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
sqlite3_bind_int ( as , 4 , ( int ) lk - > conn - > sock_id ) ;
sqlite3_step ( as ) ; sqlite3_finalize ( as ) ;
lk_written + + ;
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] INFO_RESP INSERT peer=%016llx sock=%d %d.%d.%d.%d:%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] INFO_RESP INSERT peer=%016llx sock=%d %d.%d.%d.%d:%d " ,
CS_ID , ( unsigned long long ) peer , ( int ) lk - > conn - > sock_id , ip [ 0 ] , ip [ 1 ] , ip [ 2 ] , ip [ 3 ] , port ) ;
}
} else if ( lk - > initialized ) {
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] INFO_RESP SKIP non-IPv4 link for peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] INFO_RESP SKIP non-IPv4 link for peer=%016llx " , CS_ID , ( unsigned long long ) peer ) ;
}
lk = lk - > next ;
}
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] INFO_RESP DONE peer=%016llx: %d links, %d written " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] INFO_RESP DONE peer=%016llx: %d links, %d written " ,
CS_ID , ( unsigned long long ) peer , lk_count , lk_written ) ;
}
int rc = topo_node_sqlite_member_put ( vdb , ch_id , peer , inviter_join_sig , inviter_join_ts , inviter_update_sig , inviter_update_ts , inv_x25519 , inv_ed , inv_userinfo , inviter_join_sig , NULL , NULL , 0 ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: member_put(inviter) FAILED ch=%s peer=%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) peer , rc ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: member_put(inviter) FAILED ch=%s peer=%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) peer , rc ) ;
char inv_name [ 128 ] ; json_flat_get ( inv_userinfo , " name " , inv_name , sizeof ( inv_name ) ) ;
topo_node_sqlite_node_update_verified ( vdb , peer , inv_name , inv_x25519 , inv_ed , inviter_join_ts , ntp_time_get_seconds ( cs - > inst ) ) ;
}
@ -1159,10 +1159,10 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
static void cs_handle_channel_join ( struct chat_sync * cs , uint64_t peer ,
const char * ch_id , const uint8_t * pl , size_t len ) {
if ( len < 8 + 32 + 32 + 64 + 8 + 1 + 1 ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_JOIN too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ; return ; }
if ( len < 8 + 32 + 32 + 64 + 8 + 1 + 1 ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_JOIN too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ; return ; }
const uint8_t * p = pl ;
uint64_t node_id ; memcpy ( & node_id , p , 8 ) ; p + = 8 ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN ch=%s node=%016llx from=%016llx " , CS_ID , ch_id , ( unsigned long long ) node_id , ( unsigned long long ) peer ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN ch=%s node=%016llx from=%016llx " , CS_ID , ch_id , ( unsigned long long ) node_id , ( unsigned long long ) peer ) ;
const uint8_t * x25519 = p ; p + = 32 ;
const uint8_t * ed_pub = p ; p + = 32 ;
const uint8_t * join_sig = p ; p + = 64 ;
@ -1176,7 +1176,7 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
uint8_t ch_x25519 [ 32 ] , ch_ed25519 [ 32 ] ;
if ( topo_node_sqlite_channel_get ( cs - > inst - > topo_sqlite_db , ch_id ,
NULL , 0 , NULL , ch_x25519 , ch_ed25519 , NULL ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN channel not in DB ch=%s " , CS_ID , ch_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN channel not in DB ch=%s " , CS_ID , ch_id ) ;
return ;
}
uint8_t vmsg [ 256 ] ; size_t vlen = 0 ;
@ -1186,7 +1186,7 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
memcpy ( vmsg + vlen , x25519 , 32 ) ; vlen + = 32 ;
memcpy ( vmsg + vlen , & join_ts , 8 ) ; vlen + = 8 ;
if ( cs_ed25519_verify ( ed_pub , vmsg , vlen , join_sig ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN invalid sig node=0x%016llx ch=%s — signed(node=%016llx x25519=%016llx ed=%016llx ts=%llu) " , CS_ID ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN invalid sig node=0x%016llx ch=%s — signed(node=%016llx x25519=%016llx ed=%016llx ts=%llu) " , CS_ID ,
( unsigned long long ) node_id , ch_id ,
( unsigned long long ) node_id , * ( const uint64_t * ) x25519 , * ( const uint64_t * ) ed_pub , ( unsigned long long ) join_ts ) ;
return ;
@ -1194,19 +1194,19 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
sqlite3 * db = cs - > inst - > topo_sqlite_db ;
int rc = topo_node_sqlite_member_put ( db , ch_id , node_id , join_sig , join_ts , NULL , 0 , x25519 , ed_pub , joiner_userinfo , NULL , NULL , NULL , 0 ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: member_put(joiner) FAILED ch=%s node=0x%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) node_id , rc ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: member_put(joiner) FAILED ch=%s node=0x%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) node_id , rc ) ;
{ char j_name [ 128 ] ; json_flat_get ( joiner_userinfo , " name " , j_name , sizeof ( j_name ) ) ;
topo_node_sqlite_node_update_verified ( db , node_id , j_name , x25519 , ed_pub , join_ts , ntp_time_get_seconds ( cs - > inst ) ) ; }
/* save/update node addresses */
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] JOIN save addrs node=0x%016llx addr_cnt=%d " , CS_ID , ( unsigned long long ) node_id , addr_cnt ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] JOIN save addrs node=0x%016llx addr_cnt=%d " , CS_ID , ( unsigned long long ) node_id , addr_cnt ) ;
for ( uint8_t i = 0 ; i < addr_cnt & & p + 2 < = pl + len ; i + + ) {
uint8_t fm = * p + + ;
uint8_t sid = * p + + ;
uint8_t proto = * p + + ;
int ip_len = ( fm = = 4 ) ? 4 : 16 ;
if ( p + ip_len + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN addr truncated node=0x%016llx fm=%u i=%u " , CS_ID , ( unsigned long long ) node_id , fm , i ) ; break ; }
if ( p + ip_len + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN addr truncated node=0x%016llx fm=%u i=%u " , CS_ID , ( unsigned long long ) node_id , fm , i ) ; break ; }
const uint8_t * ip = p ; p + = ip_len ;
uint16_t port = ( ( uint16_t ) p [ 0 ] < < 8 ) | p [ 1 ] ; p + = 2 ;
@ -1223,10 +1223,10 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
sqlite3_step ( stmt ) ; sqlite3_finalize ( stmt ) ;
}
if ( fm = = 4 )
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] JOIN INSERT node=0x%016llx sock=%d %d.%d.%d.%d:%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] JOIN INSERT node=0x%016llx sock=%d %d.%d.%d.%d:%d " ,
CS_ID , ( unsigned long long ) node_id , sid , ip [ 0 ] , ip [ 1 ] , ip [ 2 ] , ip [ 3 ] , port ) ;
else
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] JOIN INSERT v6 node=0x%016llx sock=%d port=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] JOIN INSERT v6 node=0x%016llx sock=%d port=%d " ,
CS_ID , ( unsigned long long ) node_id , sid , port ) ;
}
@ -1270,17 +1270,17 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
{ uint8_t evt [ 65 ] ; uint8_t cl = ( uint8_t ) strlen ( ch_id ) ; evt [ 0 ] = cl ; memcpy ( evt + 1 , ch_id , cl ) ;
chat_event_post ( CHAT_EVT_MEMBERS_CHANGED , evt , 1 + cl ) ; }
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN calling cs_post_channel_online ch=%s " , CS_ID , ch_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN calling cs_post_channel_online ch=%s " , CS_ID , ch_id ) ;
cs_post_channel_online ( cs , ch_id ) ;
/* initiate member sync with the joiner (server side) */
struct invite_sync_arg * sa = u_malloc ( sizeof ( struct invite_sync_arg ) ) ;
if ( sa ) { sa - > node_id = node_id ;
strncpy ( sa - > ch_id , ch_id , sizeof ( sa - > ch_id ) - 1 ) ; sa - > ch_id [ sizeof ( sa - > ch_id ) - 1 ] = ' \0 ' ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN alloc sa=%p node=0x%016llx ch=%s " , CS_ID , ( void * ) sa , ( unsigned long long ) sa - > node_id , sa - > ch_id ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN alloc sa=%p node=0x%016llx ch=%s " , CS_ID , ( void * ) sa , ( unsigned long long ) sa - > node_id , sa - > ch_id ) ;
member_sync_start ( cs - > inst , node_id , ch_id , _on_invite_sync_done , sa ) ; }
else member_sync_start ( cs - > inst , node_id , ch_id , NULL , NULL ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN starting member_sync with joiner node=0x%016llx ch=%s done_cb=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN starting member_sync with joiner node=0x%016llx ch=%s done_cb=%s " ,
CS_ID , ( unsigned long long ) node_id , ch_id , sa ? " yes " : " no " ) ;
/* if we're the inviter — joiner joined successfully, notify GUI */
@ -1289,14 +1289,14 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
uint8_t evt [ 20 ] ; memcpy ( evt , & node_id , 8 ) ; int r = 0 ; memcpy ( evt + 8 , & r , 4 ) ;
memcpy ( evt + 12 , & ch_id_num , 8 ) ;
chat_event_post ( CHAT_EVT_CONNECT_RESULT , evt , 20 ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN posted CHAT_EVT_CONNECT_RESULT to GUI node=0x%016llx ch=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN posted CHAT_EVT_CONNECT_RESULT to GUI node=0x%016llx ch=%s " ,
CS_ID , ( unsigned long long ) node_id , ch_id ) ;
cs - > pending_invite_node_id = 0 ; cs - > pending_invite_ch_id = 0 ;
cs - > pending_invite_is_inviter = 0 ;
if ( cs - > invite_send_timer ) { uasync_cancel_timeout ( cs - > inst - > ua , cs - > invite_send_timer ) ; cs - > invite_send_timer = NULL ; }
}
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: JOIN accepted node=0x%016llx ch=%s addrs=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: JOIN accepted node=0x%016llx ch=%s addrs=%d " ,
CS_ID , ( unsigned long long ) node_id , ch_id , addr_cnt ) ;
}
@ -1306,21 +1306,21 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
const char * ch_id , const uint8_t * pl , size_t len ) {
if ( cs - > join_timer ) { uasync_cancel_timeout ( cs - > inst - > ua , cs - > join_timer ) ; cs - > join_timer = NULL ; }
( void ) peer ;
if ( len < 2 ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ; return ; }
if ( len < 2 ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ; return ; }
sqlite3 * db = cs - > inst - > topo_sqlite_db ;
const uint8_t * p = pl ;
uint16_t pc ; memcpy ( & pc , p , 2 ) ; p + = 2 ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME ch=%s from=%016llx peers=%u " , CS_ID , ch_id , ( unsigned long long ) peer , pc ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME ch=%s from=%016llx peers=%u " , CS_ID , ch_id , ( unsigned long long ) peer , pc ) ;
for ( uint16_t i = 0 ; i < pc ; i + + ) {
if ( ( size_t ) ( p - pl ) + 8 + 32 + 32 + 1 + 64 + 8 + 1 > len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME peer[%u] truncated at %td len=%zu " , CS_ID , i , p - pl , len ) ; break ; } /* min: id+x25519+ed+flags+update_sig(64+8)+nl+ac */
if ( ( size_t ) ( p - pl ) + 8 + 32 + 32 + 1 + 64 + 8 + 1 > len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME peer[%u] truncated at %td len=%zu " , CS_ID , i , p - pl , len ) ; break ; } /* min: id+x25519+ed+flags+update_sig(64+8)+nl+ac */
uint64_t node_id ; memcpy ( & node_id , p , 8 ) ; p + = 8 ;
const uint8_t * x25519 = p ; p + = 32 ;
const uint8_t * ed_pub = p ; p + = 32 ;
uint8_t flags = * p + + ;
const uint8_t * join_sig = NULL ; uint64_t join_ts = 0 ;
if ( flags & PEERS_FLAG_HAS_JOIN ) {
if ( p + 64 + 8 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME join_sig truncated node=0x%016llx i=%u " , CS_ID , ( unsigned long long ) node_id , i ) ; break ; }
if ( p + 64 + 8 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME join_sig truncated node=0x%016llx i=%u " , CS_ID , ( unsigned long long ) node_id , i ) ; break ; }
join_sig = p ; p + = 64 ;
memcpy ( & join_ts , p , 8 ) ; p + = 8 ;
}
@ -1341,7 +1341,7 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
uint8_t ch_x2 [ 32 ] , ch_ed2 [ 32 ] ;
if ( topo_node_sqlite_channel_get ( db , ch_id ,
NULL , 0 , NULL , ch_x2 , ch_ed2 , NULL ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME channel not in DB ch=%s " , CS_ID , ch_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME channel not in DB ch=%s " , CS_ID , ch_id ) ;
continue ;
}
uint8_t vmsg [ 256 ] ; size_t vlen = 0 ;
@ -1356,7 +1356,7 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
if ( ver ) {
if ( EVP_DigestVerifyInit ( ver , NULL , NULL , NULL , pkey ) ! = 1
| | EVP_DigestVerify ( ver , join_sig , 64 , vmsg , vlen ) ! = 1 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME invalid join_sig node=0x%016llx — skipping " , CS_ID , ( unsigned long long ) node_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME invalid join_sig node=0x%016llx — skipping " , CS_ID , ( unsigned long long ) node_id ) ;
EVP_MD_CTX_free ( ver ) ; EVP_PKEY_free ( pkey ) ;
continue ;
}
@ -1367,20 +1367,20 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
}
int rc = topo_node_sqlite_member_put ( db , ch_id , node_id , join_sig , join_ts , NULL , 0 , x25519 , ed_pub , peer_userinfo , NULL , NULL , NULL , 0 ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: member_put(welcome) FAILED ch=%s node=0x%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) node_id , rc ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: member_put(welcome) FAILED ch=%s node=0x%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) node_id , rc ) ;
{ char pn [ 256 ] ; json_flat_get ( peer_userinfo , " name " , pn , sizeof ( pn ) ) ;
topo_node_sqlite_node_update_verified ( db , node_id , pn , x25519 , ed_pub , join_ts , ntp_time_get_seconds ( cs - > inst ) ) ; }
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] WELCOME save addrs node=0x%016llx ac=%d " , CS_ID , ( unsigned long long ) node_id , ac ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] WELCOME save addrs node=0x%016llx ac=%d " , CS_ID , ( unsigned long long ) node_id , ac ) ;
for ( uint8_t j = 0 ; j < ac ; j + + ) {
if ( p + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME addr[%u] header truncated node=0x%016llx " , CS_ID , j , ( unsigned long long ) node_id ) ; break ; }
if ( p + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME addr[%u] header truncated node=0x%016llx " , CS_ID , j , ( unsigned long long ) node_id ) ; break ; }
uint8_t fm = * p + + ;
uint8_t sid = * p + + ;
uint8_t proto = * p + + ;
int ip_len = ( fm = = 4 ) ? 4 : 16 ;
if ( p + ip_len + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME addr[%u] ip truncated node=0x%016llx fm=%u " , CS_ID , j , ( unsigned long long ) node_id , fm ) ; break ; }
if ( p + ip_len + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME addr[%u] ip truncated node=0x%016llx fm=%u " , CS_ID , j , ( unsigned long long ) node_id , fm ) ; break ; }
const uint8_t * ip = p ; p + = ip_len ;
uint16_t port = ( ( uint16_t ) p [ 0 ] < < 8 ) | p [ 1 ] ; p + = 2 ;
@ -1397,10 +1397,10 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
sqlite3_step ( stmt2 ) ; sqlite3_finalize ( stmt2 ) ;
}
if ( fm = = 4 )
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] WELCOME INSERT node=0x%016llx sock=%d %d.%d.%d.%d:%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] WELCOME INSERT node=0x%016llx sock=%d %d.%d.%d.%d:%d " ,
CS_ID , ( unsigned long long ) node_id , sid , ip [ 0 ] , ip [ 1 ] , ip [ 2 ] , ip [ 3 ] , port ) ;
else
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] WELCOME INSERT v6 node=0x%016llx sock=%d port=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] WELCOME INSERT v6 node=0x%016llx sock=%d port=%d " ,
CS_ID , ( unsigned long long ) node_id , sid , port ) ;
}
member_sync_cancel ( g_cs - > inst , node_id , ch_id ) ;
@ -1416,9 +1416,9 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
const char * my_name = cs - > inst - > name [ 0 ] ? cs - > inst - > name : " " ;
int src = topo_node_sqlite_member_put ( db , ch_id , myid , NULL , 0 , NULL , 0 , my_x25 , my_ed , my_name , NULL , NULL , NULL , 0 ) ;
if ( src ! = 0 )
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: member_put(self) FAILED in WELCOME ch=%s rc=%d " , CS_ID , ch_id , src ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: member_put(self) FAILED in WELCOME ch=%s rc=%d " , CS_ID , ch_id , src ) ;
else
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME added self to peers ch=%s node=0x%016llx " , CS_ID , ch_id , ( unsigned long long ) myid ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME added self to peers ch=%s node=0x%016llx " , CS_ID , ch_id , ( unsigned long long ) myid ) ;
}
uint8_t evt [ 65 ] ; uint8_t ch_id_len = ( uint8_t ) strlen ( ch_id ) ;
@ -1427,17 +1427,17 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
chat_event_post ( CHAT_EVT_MEMBERS_CHANGED , evt , 1 + ch_id_len ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME calling cs_post_channel_online ch=%s " , CS_ID , ch_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME calling cs_post_channel_online ch=%s " , CS_ID , ch_id ) ;
cs_post_channel_online ( cs , ch_id ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME processed ch=%s peers=%d — message sync triggered via db_sync (active conn or peer_check timer every 5s) " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME processed ch=%s peers=%d — message sync triggered via db_sync (active conn or peer_check timer every 5s) " ,
CS_ID , ch_id , pc ) ;
if ( cs - > pending_invite_ch_id ! = 0 ) {
uint64_t ch_id_num = strtoull ( ch_id , NULL , 10 ) ;
uint8_t cevt [ 20 ] ; memcpy ( cevt , & peer , 8 ) ; int r = 0 ; memcpy ( cevt + 8 , & r , 4 ) ; memcpy ( cevt + 12 , & ch_id_num , 8 ) ;
chat_event_post ( CHAT_EVT_CONNECT_RESULT , cevt , 20 ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: WELCOME invite success ch=%s peer=%016llx — posted CHAT_EVT_CONNECT_RESULT " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: WELCOME invite success ch=%s peer=%016llx — posted CHAT_EVT_CONNECT_RESULT " ,
CS_ID , ch_id , ( unsigned long long ) peer ) ;
cs - > pending_invite_node_id = 0 ; cs - > pending_invite_ch_id = 0 ; if ( cs - > join_timer ) { uasync_cancel_timeout ( cs - > inst - > ua , cs - > join_timer ) ; cs - > join_timer = NULL ; }
}
@ -1447,7 +1447,7 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
static void cs_handle_peer_upsert ( struct chat_sync * cs , uint64_t peer ,
const char * ch_id , const uint8_t * pl , size_t len ) {
if ( len < 8 + 32 + 32 + 64 + 8 + 1 + 1 + 1 ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_UPSERT too short len=%zu " , CS_ID , len ) ; return ; }
if ( len < 8 + 32 + 32 + 64 + 8 + 1 + 1 + 1 ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_UPSERT too short len=%zu " , CS_ID , len ) ; return ; }
const uint8_t * p = pl ;
uint64_t node_id ; memcpy ( & node_id , p , 8 ) ; p + = 8 ;
const uint8_t * x25519 = p ; p + = 32 ;
@ -1463,7 +1463,7 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
uint8_t ch_x3 [ 32 ] , ch_ed3 [ 32 ] ;
if ( topo_node_sqlite_channel_get ( cs - > inst - > topo_sqlite_db , ch_id ,
NULL , 0 , NULL , ch_x3 , ch_ed3 , NULL ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_UPSERT channel not in DB ch=%s " , CS_ID , ch_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_UPSERT channel not in DB ch=%s " , CS_ID , ch_id ) ;
return ;
}
uint8_t vmsg [ 256 ] ; size_t vlen = 0 ;
@ -1473,7 +1473,7 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
memcpy ( vmsg + vlen , x25519 , 32 ) ; vlen + = 32 ;
memcpy ( vmsg + vlen , & join_ts , 8 ) ; vlen + = 8 ;
if ( cs_ed25519_verify ( ed_pub , vmsg , vlen , join_sig ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_UPSERT invalid sig node=0x%016llx " , CS_ID ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_UPSERT invalid sig node=0x%016llx " , CS_ID ,
( unsigned long long ) node_id ) ;
return ;
}
@ -1481,19 +1481,19 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
sqlite3 * db = cs - > inst - > topo_sqlite_db ;
int rc = topo_node_sqlite_member_put ( db , ch_id , node_id , join_sig , join_ts , NULL , 0 , x25519 , ed_pub , peer_userinfo , NULL , NULL , NULL , 0 ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: member_put(peer_upsert) FAILED ch=%s node=0x%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) node_id , rc ) ;
if ( rc ! = 0 ) DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: member_put(peer_upsert) FAILED ch=%s node=0x%016llx rc=%d " , CS_ID , ch_id , ( unsigned long long ) node_id , rc ) ;
{ char pn2 [ 128 ] ; json_flat_get ( peer_userinfo , " name " , pn2 , sizeof ( pn2 ) ) ;
topo_node_sqlite_node_update_verified ( db , node_id , pn2 , x25519 , ed_pub , join_ts , ntp_time_get_seconds ( cs - > inst ) ) ; }
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] PEER_UPSERT save addrs node=0x%016llx ac=%d " , CS_ID , ( unsigned long long ) node_id , ac ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] PEER_UPSERT save addrs node=0x%016llx ac=%d " , CS_ID , ( unsigned long long ) node_id , ac ) ;
for ( uint8_t i = 0 ; i < ac ; i + + ) {
if ( p + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_UPSERT addr[%u] header truncated node=0x%016llx " , CS_ID , i , ( unsigned long long ) node_id ) ; break ; }
if ( p + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_UPSERT addr[%u] header truncated node=0x%016llx " , CS_ID , i , ( unsigned long long ) node_id ) ; break ; }
uint8_t fm = * p + + ;
uint8_t sid = * p + + ;
uint8_t proto = * p + + ;
int ip_len = ( fm = = 4 ) ? 4 : 16 ;
if ( p + ip_len + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_UPSERT addr[%u] ip truncated node=0x%016llx fm=%u " , CS_ID , i , ( unsigned long long ) node_id , fm ) ; break ; }
if ( p + ip_len + 2 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_UPSERT addr[%u] ip truncated node=0x%016llx fm=%u " , CS_ID , i , ( unsigned long long ) node_id , fm ) ; break ; }
const uint8_t * ip = p ; p + = ip_len ;
uint16_t port = ( ( uint16_t ) p [ 0 ] < < 8 ) | p [ 1 ] ; p + = 2 ;
@ -1511,10 +1511,10 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
sqlite3_step ( stmt ) ; sqlite3_finalize ( stmt ) ;
}
if ( fm = = 4 )
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] PEER_UPSERT INSERT node=0x%016llx sock=%d %d.%d.%d.%d:%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] PEER_UPSERT INSERT node=0x%016llx sock=%d %d.%d.%d.%d:%d " ,
CS_ID , ( unsigned long long ) node_id , sid , ip [ 0 ] , ip [ 1 ] , ip [ 2 ] , ip [ 3 ] , port ) ;
else
DEBUG_INFO ( DEBUG_CATEGORY_DEBUG , " %s: [ADDR_SYNC] PEER_UPSERT INSERT v6 node=0x%016llx sock=%d port=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER_SYNC , " %s: [ADDR_SYNC] PEER_UPSERT INSERT v6 node=0x%016llx sock=%d port=%d " ,
CS_ID , ( unsigned long long ) node_id , sid , port ) ;
}
@ -1525,7 +1525,7 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
/* propagate to others (except sender and the subject node) */
cs_propagate ( cs , ch_id , peer , pl , len ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_UPSERT node=0x%016llx ch=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_UPSERT node=0x%016llx ch=%s " ,
CS_ID , ( unsigned long long ) node_id , ch_id ) ;
}
@ -1533,7 +1533,7 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
static void cs_handle_peer_remove ( struct chat_sync * cs , uint64_t peer ,
const char * ch_id , const uint8_t * pl , size_t len ) {
if ( len < 8 ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_REMOVE too short len=%zu " , CS_ID , len ) ; return ; }
if ( len < 8 ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_REMOVE too short len=%zu " , CS_ID , len ) ; return ; }
uint64_t node_id ; memcpy ( & node_id , pl , 8 ) ;
sqlite3 * db = cs - > inst - > topo_sqlite_db ;
@ -1544,7 +1544,7 @@ static void cs_handle_peer_remove(struct chat_sync* cs, uint64_t peer,
cs_propagate ( cs , ch_id , peer , pl , len ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: PEER_REMOVE node=0x%016llx ch=%s " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: PEER_REMOVE node=0x%016llx ch=%s " ,
CS_ID , ( unsigned long long ) node_id , ch_id ) ;
}
@ -1552,16 +1552,16 @@ static void cs_handle_peer_remove(struct chat_sync* cs, uint64_t peer,
static void cs_handle_channel_invite ( struct chat_sync * cs , uint64_t peer ,
const char * ch_id , const uint8_t * pl , size_t len ) {
DEBUG_TRACE ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE ch=%s from=%016llx len=%zu " ,
DEBUG_TRACE ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE ch=%s from=%016llx len=%zu " ,
CS_ID , ch_id , ( unsigned long long ) peer , len ) ;
if ( len < 1 + 8 + 32 + 32 + 64 + 1 + 64 + 8 + 1 ) {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ;
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE too short len=%zu peer=%016llx " , CS_ID , len , ( unsigned long long ) peer ) ;
return ;
}
/* Same payload format as CHANNEL_INFO_RESP */
const uint8_t * p = pl ;
uint8_t nl = * p + + ;
if ( 1 + nl + 8 + 32 + 32 + 64 + 1 + 64 + 8 + 1 > ( int ) len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE truncated " , CS_ID ) ; return ; }
if ( 1 + nl + 8 + 32 + 32 + 64 + 1 + 64 + 8 + 1 > ( int ) len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE truncated " , CS_ID ) ; return ; }
char name [ 128 ] ; memcpy ( name , p , nl ) ; name [ nl ] = ' \0 ' ; p + = nl ;
uint64_t owner ; memcpy ( & owner , p , 8 ) ; p + = 8 ;
const uint8_t * x25519 = p ; p + = 32 ;
@ -1570,7 +1570,7 @@ static void cs_handle_channel_invite(struct chat_sync* cs, uint64_t peer,
uint8_t inv_flags = * p + + ;
const uint8_t * inviter_join_sig = NULL ; uint64_t inviter_join_ts = 0 ;
if ( inv_flags & PEERS_FLAG_HAS_JOIN ) {
if ( p + 72 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE truncated at join_sig/ts from=%016llx " , CS_ID , ( unsigned long long ) peer ) ; return ; }
if ( p + 72 > pl + len ) { DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE truncated at join_sig/ts from=%016llx " , CS_ID , ( unsigned long long ) peer ) ; return ; }
inviter_join_sig = p ; p + = 64 ; memcpy ( & inviter_join_ts , p , 8 ) ; p + = 8 ; }
/* skip inviter_update_sig/ts/userinfo for now — verify channel sig only */
p + = 64 ; uint64_t inviter_update_ts ; memcpy ( & inviter_update_ts , p , 8 ) ; p + = 8 ;
@ -1584,7 +1584,7 @@ static void cs_handle_channel_invite(struct chat_sync* cs, uint64_t peer,
memcpy ( vmsg + vlen , x25519 , 32 ) ; vlen + = 32 ;
memcpy ( vmsg + vlen , ed_pub , 32 ) ; vlen + = 32 ;
if ( cs_ed25519_verify ( ed_pub , vmsg , vlen , ch_sig ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE invalid ch_sig ch=%s from=%016llx " , CS_ID , ch_id , ( unsigned long long ) peer ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE invalid ch_sig ch=%s from=%016llx " , CS_ID , ch_id , ( unsigned long long ) peer ) ;
return ;
}
@ -1594,17 +1594,17 @@ static void cs_handle_channel_invite(struct chat_sync* cs, uint64_t peer,
struct global_config * gcfg = & cs - > inst - > config - > global ;
policy = gcfg - > chatserver_enabled ? 0 : chat_setting_get_int ( " join_policy " , 1 ) ;
}
DEBUG_DEBUG ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE policy=%d (chatserver=%d) ch=%s from=%016llx " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE policy=%d (chatserver=%d) ch=%s from=%016llx " ,
CS_ID , policy , cs - > inst - > config - > global . chatserver_enabled , ch_id , ( unsigned long long ) peer ) ;
if ( policy = = 2 ) { /* deny */
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE denied (policy=deny) ch=%s from=%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE denied (policy=deny) ch=%s from=%016llx " ,
CS_ID , ch_id , ( unsigned long long ) peer ) ;
return ;
}
if ( policy = = 0 ) { /* autojoin */
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE autojoin ch=%s from=%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE autojoin ch=%s from=%016llx " ,
CS_ID , ch_id , ( unsigned long long ) peer ) ;
/* Save channel and start join handshake */
topo_node_sqlite_channel_put ( cs - > inst - > topo_sqlite_db ,
@ -1637,7 +1637,7 @@ static void cs_handle_channel_invite(struct chat_sync* cs, uint64_t peer,
evt [ epos + + ] = ( uint8_t ) inv_name_len ;
if ( inv_name_len ) { memcpy ( evt + epos , inv_name , inv_name_len ) ; epos + = inv_name_len ; }
chat_event_post ( CHAT_EVT_INVITE_RECEIVED , evt , epos ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: CHANNEL_INVITE ask posted to GUI ch=%s name=%s from=%016llx (%s) " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: CHANNEL_INVITE ask posted to GUI ch=%s name=%s from=%016llx (%s) " ,
CS_ID , ch_id , name , ( unsigned long long ) peer , inv_name ) ;
}
}
@ -1681,7 +1681,7 @@ static int cs_send_channel_invite(struct chat_sync* cs, struct UTUN_INSTANCE* in
uint8_t il = ( uint8_t ) strlen ( juser ) ;
buf [ boff + + ] = il ; memcpy ( buf + boff , juser , il ) ; boff + = il ;
int rc = cs_send ( cs , ch_id , target_node_id , buf , boff ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: sent CHANNEL_INVITE to 0x%016llx ch=%s rc=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: sent CHANNEL_INVITE to 0x%016llx ch=%s rc=%d " ,
CS_ID , ( unsigned long long ) target_node_id , ch_id , rc ) ;
return rc ;
}
@ -1689,20 +1689,20 @@ static int cs_send_channel_invite(struct chat_sync* cs, struct UTUN_INSTANCE* in
/* ─── chat_sync_invite_to_channel: пригласить узел в наш канал ─── */
void chat_sync_invite_to_channel ( struct UTUN_INSTANCE * inst , const char * ch_id , uint64_t target_node_id ) {
if ( ! g_cs ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel: g_cs=NULL, chat_sync not initialized " , CS_ID ) ; return ; }
if ( ! inst ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel: inst=NULL " , CS_ID ) ; return ; }
if ( ! ch_id | | ! ch_id [ 0 ] ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel: ch_id NULL/empty " , CS_ID ) ; return ; }
if ( target_node_id = = 0 ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel: target_node_id=0 " , CS_ID ) ; return ; }
if ( target_node_id = = inst - > node_id ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel: self-invite rejected self=0x%016llx " , CS_ID , ( unsigned long long ) inst - > node_id ) ; return ; }
if ( ! g_cs ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel: g_cs=NULL, chat_sync not initialized " , CS_ID ) ; return ; }
if ( ! inst ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel: inst=NULL " , CS_ID ) ; return ; }
if ( ! ch_id | | ! ch_id [ 0 ] ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel: ch_id NULL/empty " , CS_ID ) ; return ; }
if ( target_node_id = = 0 ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel: target_node_id=0 " , CS_ID ) ; return ; }
if ( target_node_id = = inst - > node_id ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel: self-invite rejected self=0x%016llx " , CS_ID , ( unsigned long long ) inst - > node_id ) ; return ; }
uint64_t channel_id = strtoull ( ch_id , NULL , 10 ) ;
if ( channel_id = = 0 ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel invalid ch_id='%s' " , CS_ID , ch_id ) ; return ; }
if ( channel_id = = 0 ) { DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel invalid ch_id='%s' " , CS_ID , ch_id ) ; return ; }
/* Get channel data from DB */
char ch_name [ 128 ] ; uint64_t owner ; uint8_t ch_x25519 [ 32 ] , ch_ed [ 32 ] , ch_sig [ 64 ] ;
if ( topo_node_sqlite_channel_get ( inst - > topo_sqlite_db ,
ch_id , ch_name , ( int ) sizeof ( ch_name ) , & owner , ch_x25519 , ch_ed , ch_sig ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel channel not found: %s " , CS_ID , ch_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel channel not found: %s " , CS_ID , ch_id ) ;
return ;
}
@ -1716,7 +1716,7 @@ void chat_sync_invite_to_channel(struct UTUN_INSTANCE* inst, const char* ch_id,
struct TOPO_GROUP_NODE * nq = topo_node_find_by_id ( g , target_node_id ) ;
if ( nq & & nq - > handle ) {
/* Already have a handle — connection in progress or established */
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel — existing handle for node 0x%016llx, waiting for conn_up " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel — existing handle for node 0x%016llx, waiting for conn_up " ,
CS_ID , ( unsigned long long ) target_node_id ) ;
g_cs - > pending_invite_ch_id = channel_id ;
g_cs - > pending_invite_node_id = target_node_id ;
@ -1730,12 +1730,12 @@ void chat_sync_invite_to_channel(struct UTUN_INSTANCE* inst, const char* ch_id,
/* Addresses loaded from node_addresses in DB by conn_mgr */
int r = conn_mgr_open_invite ( inst , channel_id , ni , target_node_id , NULL , NULL , NULL ) ;
if ( r < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel conn_mgr_open_invite failed rc=%d " , CS_ID , r ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel conn_mgr_open_invite failed rc=%d " , CS_ID , r ) ;
}
u_free ( ni ) ;
}
} else {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_to_channel — no topo_groups, cannot connect " , CS_ID ) ;
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_to_channel — no topo_groups, cannot connect " , CS_ID ) ;
return ;
}
/* Mark pending: after conn_up, we send CHANNEL_INVITE.
@ -1776,7 +1776,7 @@ static void cs_invite_trampoline(void* arg) {
uint64_t target_node_id = w - > target_node_id ;
if ( channel_id = = 0 | | target_node_id = = 0 | | target_node_id = = inst - > node_id ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs invalid params ch=%llu target=0x%016llx " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs invalid params ch=%llu target=0x%016llx " ,
CS_ID , ( unsigned long long ) channel_id , ( unsigned long long ) target_node_id ) ;
u_free ( w ) ; return ;
}
@ -1802,7 +1802,7 @@ static void cs_invite_trampoline(void* arg) {
/* Not connected — build TOPO_NODE with addresses and connect */
if ( ! inst - > topo_groups ) {
DEBUG_WARN ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs — no topo_groups, cannot connect " , CS_ID ) ;
DEBUG_WARN ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs — no topo_groups, cannot connect " , CS_ID ) ;
u_free ( w ) ; return ;
}
@ -1832,7 +1832,7 @@ static void cs_invite_trampoline(void* arg) {
}
if ( ! ni - > v4_addrs & & ! ni - > v6_addrs ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs no valid addrs for node=0x%016llx " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs no valid addrs for node=0x%016llx " ,
CS_ID , ( unsigned long long ) target_node_id ) ;
u_free ( ni ) ; u_free ( w ) ; return ;
}
@ -1843,7 +1843,7 @@ static void cs_invite_trampoline(void* arg) {
int r = conn_mgr_open_invite ( inst , channel_id , ni , target_node_id , cs_invite_conn_cb , NULL , NULL ) ;
if ( r < 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs conn_mgr_open_invite failed rc=%d " , CS_ID , r ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs conn_mgr_open_invite failed rc=%d " , CS_ID , r ) ;
g_cs - > pending_invite_node_id = 0 ; g_cs - > pending_invite_ch_id = 0 ;
g_cs - > pending_invite_is_inviter = 0 ;
}
@ -1860,12 +1860,12 @@ void chat_sync_invite_to_channel_with_addrs(
int addrs_data_len )
{
if ( ! g_cs | | ! inst | | ! ch_id | | ! ch_id [ 0 ] | | ! pubkey_bin | | ! addrs_data | | addr_count < = 0 | | addrs_data_len < = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs invalid args " , CS_ID ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs invalid args " , CS_ID ) ;
return ;
}
uint64_t channel_id = strtoull ( ch_id , NULL , 10 ) ;
if ( channel_id = = 0 | | target_node_id = = 0 | | target_node_id = = inst - > node_id ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs invalid params ch=%s target=0x%016llx " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs invalid params ch=%s target=0x%016llx " ,
CS_ID , ch_id , ( unsigned long long ) target_node_id ) ;
return ;
}
@ -1880,7 +1880,7 @@ void chat_sync_invite_to_channel_with_addrs(
memcpy ( w - > addrs_data , addrs_data , ( size_t ) addrs_data_len ) ;
uasync_post ( inst - > ua , cs_invite_trampoline , w ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: invite_with_addrs posted to uasync ch=%s target=0x%016llx addrs=%d " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: invite_with_addrs posted to uasync ch=%s target=0x%016llx addrs=%d " ,
CS_ID , ch_id , ( unsigned long long ) target_node_id , addr_count ) ;
}
@ -1890,11 +1890,11 @@ void chat_sync_accept_invite(struct UTUN_INSTANCE* inst, uint64_t channel_id, ui
if ( ! g_cs | | ! inst ) return ;
char ch_id [ 64 ] ; snprintf ( ch_id , sizeof ( ch_id ) , " %llu " , ( unsigned long long ) channel_id ) ;
if ( channel_id = = 0 | | inviter_node_id = = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_DB _SYNC , " %s: accept_invite invalid params ch=%llu node=%016llx " ,
DEBUG_ERROR ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: accept_invite invalid params ch=%llu node=%016llx " ,
CS_ID , ( unsigned long long ) channel_id , ( unsigned long long ) inviter_node_id ) ;
return ;
}
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: accept_invite ch=%llu inviter=0x%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: accept_invite ch=%llu inviter=0x%016llx " ,
CS_ID , ( unsigned long long ) channel_id , ( unsigned long long ) inviter_node_id ) ;
chat_core_ensure_channel_ready ( ch_id ) ;
chat_sync_join_channel ( inst , ch_id , inviter_node_id ) ;
@ -1903,7 +1903,7 @@ void chat_sync_accept_invite(struct UTUN_INSTANCE* inst, uint64_t channel_id, ui
void chat_sync_deny_invite ( struct UTUN_INSTANCE * inst , uint64_t channel_id , uint64_t inviter_node_id ) {
( void ) inst ;
if ( ! g_cs ) return ;
DEBUG_INFO ( DEBUG_CATEGORY_DB _SYNC , " %s: deny_invite ch=%llu inviter=0x%016llx " ,
DEBUG_INFO ( DEBUG_CATEGORY_MEMBER _SYNC , " %s: deny_invite ch=%llu inviter=0x%016llx " ,
CS_ID , ( unsigned long long ) channel_id , ( unsigned long long ) inviter_node_id ) ;
/* silently ignore — no response needed */
}