@ -24,13 +24,13 @@
static void md_etcp_recv ( struct ETCP_CONN * conn , struct ll_entry * entry ) ;
static void md_on_conn_status ( struct ETCP_CONN * conn , int status , void * arg ) ;
static void md_on_bgp_node ( struct TOPO_GROUP * group , uint64_t node_id , int event , void * arg ) ;
static void md_on_props_changed ( uint64_t node_id , const char * adm_tags , void * arg ) ;
static void md_on_props_changed ( uint64_t node_id , const char * adm_tags , const char * channel_id , void * arg ) ;
static int md_super_start ( struct media_delivery_ctx * md ) ;
static void md_super_stop ( struct media_delivery_ctx * md ) ;
static void md_super_repl_send ( struct media_delivery_ctx * md , struct media_super_peer * peer ) ;
static void md_super_connect ( struct media_delivery_ctx * md , uint64_t peer_node_id ) ;
static void md_super_connect ( struct media_delivery_ctx * md , uint64_t peer_node_id , uint64_t group_id ) ;
static int md_send ( struct UTUN_INSTANCE * inst , uint64_t group_id , uint64_t dst_node_id , const uint8_t * data , size_t len ) ;
static struct media_super_peer * md_super_peer_add ( struct media_delivery_ctx * md , uint64_t node_id ) ;
static struct media_super_peer * md_super_peer_add ( struct media_delivery_ctx * md , uint64_t node_id , uint64_t group_id ) ;
/* ── helpers ── */
@ -198,7 +198,7 @@ static struct media_super_peer* md_super_peer_find(struct media_delivery_ctx* md
return e ? ( struct media_super_peer * ) e - > data : NULL ;
}
static struct media_super_peer * md_super_peer_add ( struct media_delivery_ctx * md , uint64_t node_id ) {
static struct media_super_peer * md_super_peer_add ( struct media_delivery_ctx * md , uint64_t node_id , uint64_t group_id ) {
struct media_super_peer * sp = md_super_peer_find ( md , node_id ) ;
if ( sp ) return sp ;
if ( ! md - > super_peers ) {
@ -210,6 +210,7 @@ static struct media_super_peer* md_super_peer_add(struct media_delivery_ctx* md,
sp = ( struct media_super_peer * ) qe - > data ;
memset ( sp , 0 , sizeof ( * sp ) ) ;
sp - > peer_node_id = node_id ;
sp - > group_id = group_id ;
sp - > timeout_tb = MEDIA_REPL_TIMEOUT_TB ;
sp - > md = md ;
memcpy ( qe - > data , & node_id , 8 ) ;
@ -346,7 +347,7 @@ static void md_reconnect_cb(void* arg) {
while ( peer ) {
if ( ! peer - > connected & & peer - > connect_timer ) {
peer - > connect_timer = NULL ;
md_super_connect ( md , peer - > peer_node_id ) ;
md_super_connect ( md , peer - > peer_node_id , peer - > group_id ) ;
}
peer = peer - > connected ? NULL : peer ;
}
@ -384,7 +385,7 @@ static void md_super_repl_send(struct media_delivery_ctx* md, struct media_super
uint16_t num = ( uint16_t ) num_entries ; memcpy ( pkt + off , & num , 2 ) ; off + = 2 ;
memcpy ( pkt + off , buf , ( size_t ) nb ) ; off + = nb ;
if ( md_send ( md - > inst , TOPO_GROUP_UTUN , peer - > peer_node_id , pkt , ( size_t ) off ) = = 0 ) {
if ( md_send ( md - > inst , peer - > group_id , peer - > peer_node_id , pkt , ( size_t ) off ) = = 0 ) {
peer - > inflight_count + + ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEDIA , " %s: SUPER_REPL sent to 0x%016llx seq=%u entries=%d " ,
MD_ID , ( unsigned long long ) peer - > peer_node_id , seq , num_entries ) ;
@ -413,9 +414,8 @@ static int md_send(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t dst_n
memcpy ( e - > dgram + 1 , data , len ) ; e - > len = ( uint16_t ) ( len + 1 ) ;
int rc = etcp_route_send ( inst , group_id , dst_node_id , e , 1 ) ;
if ( rc ! = 0 ) {
struct ETCP_CONN * c = topo_group_find_conn_for_node ( topo_groups_find ( inst - > topo_groups , group_id ) , dst_node_id ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEDIA , " %s: md_send FAIL rc=%d dst=0x%016llx group=0x%016llx route_conn=%p " ,
MD_ID , rc , ( unsigned long long ) dst_node_id , ( unsigned long long ) group_id , ( void * ) c ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_MEDIA , " %s: md_send FAIL rc=%d dst=0x%016llx group=0x%016llx " ,
MD_ID , rc , ( unsigned long long ) dst_node_id , ( unsigned long long ) group_id ) ;
u_free ( e - > dgram ) ; queue_entry_free ( e ) ;
}
return rc ;
@ -497,10 +497,10 @@ static void md_handle_query(struct media_delivery_ctx* md, uint64_t from_node,
uint16_t nc = ( uint16_t ) count ;
memcpy ( resp + num_pos , & nc , 2 ) ;
struct ETCP_CONN * qconn = topo_group_find_conn_for_node ( topo_groups_find ( md - > inst - > topo_groups , TOPO_GROUP_UTUN ) , from_node ) ;
int snd_rc = md_send ( md - > inst , TOPO_GROUP_UTUN , from_node , resp , ( size_t ) off ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEDIA , " %s: QUERY from 0x%016llx → %d entries (super=%d) resp_len=%zu send_rc=%d route_conn=%p " ,
MD_ID , ( unsigned long long ) from_node , count , md - > is_supernode , ( size_t ) off , snd_rc , ( void * ) qconn ) ;
uint64_t resp_group = q - > group_id ? q - > group_id : TOPO_GROUP_UTUN ;
md_send ( md - > inst , resp_group , from_node , resp , ( size_t ) off ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEDIA , " %s: QUERY from 0x%016llx → %d entries (super=%d) " ,
MD_ID , ( unsigned long long ) from_node , count , md - > is_supernode ) ;
}
static void md_handle_have_block ( struct media_delivery_ctx * md , uint64_t from_node ,
@ -519,7 +519,7 @@ static void md_handle_have_block(struct media_delivery_ctx* md, uint64_t from_no
memcpy ( ha - > block_id , hb - > block_id , 16 ) ;
ha - > status = ( rc = = 0 ) ? 0 : 1 ;
md_send ( md - > inst , TOPO_GROUP_UTUN , from_node , ack , sizeof ( ack ) ) ;
md_send ( md - > inst , hb - > group_id , from_node , ack , sizeof ( ack ) ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEDIA , " %s: HAVE_BLOCK from 0x%016llx rc=%d " ,
MD_ID , ( unsigned long long ) from_node , rc ) ;
@ -606,7 +606,8 @@ static void md_handle_super_repl(struct media_delivery_ctx* md, uint64_t from_no
struct media_pkt_super_ack * sa = ( struct media_pkt_super_ack * ) ack ;
sa - > subcmd = MEDIA_SUBCMD_SUPER_ACK ;
sa - > ack_seq = ( uint32_t ) max_id ;
md_send ( md - > inst , TOPO_GROUP_UTUN , from_node , ack , sizeof ( ack ) ) ;
struct media_super_peer * peer = md_super_peer_find ( md , from_node ) ;
md_send ( md - > inst , peer ? peer - > group_id : TOPO_GROUP_UTUN , from_node , ack , sizeof ( ack ) ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_MEDIA , " %s: SUPER_REPL from 0x%016llx entries=%d max_id=%lld " ,
MD_ID , ( unsigned long long ) from_node , num , ( long long ) max_id ) ;
@ -636,7 +637,7 @@ static void md_handle_super_hello(struct media_delivery_ctx* md, uint64_t from_n
if ( ! md - > db ) { DEBUG_ERROR ( DEBUG_CATEGORY_GENERAL , " %s: SUPER_HELLO but no DB " , MD_ID ) ; return ; }
struct media_pkt_super_hello * sh = ( struct media_pkt_super_hello * ) data ;
struct media_super_peer * peer = md_super_peer_add ( md , from_node ) ;
struct media_super_peer * peer = md_super_peer_add ( md , from_node , sh - > group_id ) ;
if ( ! peer ) { DEBUG_ERROR ( DEBUG_CATEGORY_GENERAL , " %s: super_peer_add failed for 0x%016llx " , MD_ID , ( unsigned long long ) from_node ) ; return ; }
peer - > peer_last_recv_id = sh - > last_recv_id ;
@ -648,7 +649,8 @@ static void md_handle_super_hello(struct media_delivery_ctx* md, uint64_t from_n
struct media_pkt_super_hello resp ;
resp . subcmd = MEDIA_SUBCMD_SUPER_HELLO ;
resp . last_recv_id = my_last_recv ;
md_send ( md - > inst , TOPO_GROUP_UTUN , from_node , ( const uint8_t * ) & resp , sizeof ( resp ) ) ;
resp . group_id = peer - > group_id ;
md_send ( md - > inst , peer - > group_id , from_node , ( const uint8_t * ) & resp , sizeof ( resp ) ) ;
DEBUG_INFO ( DEBUG_CATEGORY_MEDIA , " %s: SUPER_HELLO from 0x%016llx (peer_last_recv=%lld, my_last_recv=%lld) " ,
MD_ID , ( unsigned long long ) from_node , ( long long ) sh - > last_recv_id , ( long long ) my_last_recv ) ;
@ -681,8 +683,9 @@ static void md_super_conn_cb(struct CONN_MGR_HANDLE* h, uint64_t node_id, uint64
struct media_pkt_super_hello hello ;
hello . subcmd = MEDIA_SUBCMD_SUPER_HELLO ;
hello . last_recv_id = my_last ;
hello . group_id = peer - > group_id ;
if ( md_send ( md - > inst , TOPO_GROUP_UTUN , node_id , ( const uint8_t * ) & hello , sizeof ( hello ) ) = = 0 ) {
if ( md_send ( md - > inst , peer - > group_id , node_id , ( const uint8_t * ) & hello , sizeof ( hello ) ) = = 0 ) {
DEBUG_INFO ( DEBUG_CATEGORY_MEDIA , " %s: SUPER_HELLO sent to 0x%016llx last_recv=%lld " ,
MD_ID , ( unsigned long long ) node_id , ( long long ) my_last ) ;
} else {
@ -1036,18 +1039,11 @@ void media_delivery_stream_done(struct UTUN_INSTANCE* inst) {
if ( inst ) { struct media_delivery_ctx * md = & inst - > md ; if ( md - > active_streams > 0 ) md - > active_streams - - ; md - > stream_completed = 1 ; }
}
static void md_super_connect ( struct media_delivery_ctx * md , uint64_t peer_node_id ) {
struct media_super_peer * peer = md_super_peer_add ( md , peer_node_id ) ;
static void md_super_connect ( struct media_delivery_ctx * md , uint64_t peer_node_id , uint64_t group_id ) {
struct media_super_peer * peer = md_super_peer_add ( md , peer_node_id , group_id ) ;
if ( ! peer ) { DEBUG_ERROR ( DEBUG_CATEGORY_GENERAL , " %s: super_peer_add failed for 0x%016llx " , MD_ID , ( unsigned long long ) peer_node_id ) ; return ; }
struct TOPO_GROUP * grp = NULL ;
/* find group containing this peer */
struct ll_entry * gle = md - > inst - > topo_groups - > group_list - > head ;
while ( gle ) {
struct TOPO_GROUP * g = ( struct TOPO_GROUP * ) gle ;
if ( g - > conn_mgr ) { grp = g ; break ; }
gle = gle - > next ;
}
struct TOPO_GROUP * grp = topo_groups_find ( md - > inst - > topo_groups , group_id ) ;
if ( ! grp | | ! grp - > conn_mgr ) {
DEBUG_WARN ( DEBUG_CATEGORY_GENERAL , " %s: no group/conn_mgr for supernode connect " , MD_ID ) ;
return ;
@ -1083,7 +1079,7 @@ static int md_super_start(struct media_delivery_ctx* md) {
if ( sqlite3_prepare_v2 ( md - > db , sql , - 1 , & st , NULL ) = = SQLITE_OK ) {
while ( sqlite3_step ( st ) = = SQLITE_ROW ) {
uint64_t pid = ( uint64_t ) sqlite3_column_int64 ( st , 0 ) ;
md_super_connect ( md , pid ) ;
md_super_connect ( md , pid , g - > group_id ) ;
}
sqlite3_finalize ( st ) ;
}
@ -1150,19 +1146,19 @@ static void md_on_bgp_node(struct TOPO_GROUP* group, uint64_t node_id, int event
int nt = 0 ;
if ( sqlite3_step ( st ) = = SQLITE_ROW ) nt = sqlite3_column_int ( st , 0 ) ;
sqlite3_finalize ( st ) ;
if ( nt = = 4 ) md_super_connect ( md , node_id ) ;
if ( nt = = 4 ) md_super_connect ( md , node_id , group - > group_id ) ;
}
}
}
static void md_on_props_changed ( uint64_t node_id , const char * adm_tags , void * arg ) {
static void md_on_props_changed ( uint64_t node_id , const char * adm_tags , const char * channel_id , void * arg ) {
struct media_delivery_ctx * md = ( struct media_delivery_ctx * ) arg ;
int is_super = adm_tags & & strstr ( adm_tags , " supernode=yes " ) ;
if ( node_id = = md - > self_node_id ) {
media_delivery_set_supernode ( md - > inst , is_super ) ;
} else {
if ( is_super ) md_super_connect ( md , node_id ) ;
if ( is_super ) md_super_connect ( md , node_id , strtoull ( channel_id , NULL , 10 ) ) ;
else md_super_peer_remove ( md , node_id ) ;
}
}