@@ -87,6 +87,7 @@ void sync_check_timer(utime_t ticks, void *param)
8787 lock_start_read (cl_list_lock );
8888
8989 for (cl = * cluster_list ; cl ; cl = cl -> next ) {
90+ if (!cl -> current_node ) continue ;
9091 lock_get (cl -> current_node -> lock );
9192 if (!(cl -> current_node -> flags & NODE_STATE_ENABLED )) {
9293 lock_release (cl -> current_node -> lock );
@@ -109,11 +110,27 @@ void sync_check_timer(utime_t ticks, void *param)
109110 cap -> flags &= ~(CAP_SYNC_PENDING |CAP_SYNC_STARTUP );
110111 sr_set_status (cl_srg , STR2CI (cap -> reg .sr_id ), CAP_SR_SYNCED ,
111112 STR2CI (CAP_SR_STATUS_STR (CAP_SR_SYNCED )), 0 );
112- sr_add_report_fmt (cl_srg , STR2CI (cap -> reg .sr_id ), 0 ,
113- "ERROR: Sync request aborted! (no donor found in due time)"
114- " => fallback to synced state" );
115- LM_ERR ("Sync request aborted! (no donor found in due time)"
116- ", falling back to synced state\n" );
113+ /* Seed-fallback for a still-PENDING sync (the transfer never
114+ * started - no donor responded to our request within
115+ * seed_fb_interval). This is exactly what the seed
116+ * fallback is *for*: on a fresh or simultaneous cold start
117+ * no peer has any data to donate, so the seed proceeds as
118+ * authoritative. It is expected, not an error - the state
119+ * is still recorded in the status report for visibility. A
120+ * genuine partial-sync failure is a *different* branch (the
121+ * SYNC_IN_PROGRESS timeout below) and is logged there. */
122+ if (cl -> node_list == NULL )
123+ sr_add_report_fmt (cl_srg , STR2CI (cap -> reg .sr_id ), 0 ,
124+ "No peers present — self-synced as first node in cluster" );
125+ else
126+ sr_add_report_fmt (cl_srg , STR2CI (cap -> reg .sr_id ), 0 ,
127+ "Seed fallback — no donor sent data in due time, "
128+ "self-synced as seed" );
129+ LM_DBG ("Seed fallback in cluster %d: capability '%.*s' "
130+ "self-marked as synced (%s)\n" , cl -> cluster_id ,
131+ cap -> reg .name .len , cap -> reg .name .s ,
132+ cl -> node_list == NULL ? "first/lone node"
133+ : "no donor sent data in due time" );
117134 /* send update about the state of this capability */
118135 send_single_cap_update (cl , cap , 1 );
119136
@@ -155,7 +172,7 @@ int cl_set_state(int cluster_id, int node_id, enum cl_node_state state)
155172 return -1 ;
156173 }
157174
158- if (node_id != current_id ) {
175+ if (node_id != cluster_self_id ( cluster ) ) {
159176 node = get_node_by_id (cluster , node_id );
160177 if (!node ) {
161178 lock_stop_read (cl_list_lock );
@@ -190,13 +207,16 @@ int cl_set_state(int cluster_id, int node_id, enum cl_node_state state)
190207 LM_INFO ("Set state: %s for node: %d in cluster: %d\n" ,
191208 state ? "enabled" : "disabled" , node_id , cluster_id );
192209
193- if (db_mode && update_db_state (cluster_id , node_id , state ) < 0 )
210+ if (cl_db_mode ( cluster ) && update_db_state (cluster_id , node_id , state ) < 0 )
194211 LM_ERR ("Failed to update state in clusterer DB for node [%d] cluster [%d]\n" ,
195212 node_id , cluster_id );
196213
197214 return 0 ;
198215 }
199216
217+ if (!cluster -> current_node )
218+ return -1 ;
219+
200220 lock_get (cluster -> current_node -> lock );
201221
202222 if (state == STATE_DISABLED && cluster -> current_node -> flags & NODE_STATE_ENABLED )
@@ -226,7 +246,7 @@ int cl_set_state(int cluster_id, int node_id, enum cl_node_state state)
226246 LM_INFO ("Set state: %s for local node in cluster: %d\n" ,
227247 state ? "enabled" : "disabled" , cluster_id );
228248
229- if (db_mode && update_db_state (cluster_id , current_id , state ) < 0 )
249+ if (cl_db_mode ( cluster ) && update_db_state (cluster_id , current_id , state ) < 0 )
230250 LM_ERR ("Failed to update state in clusterer DB for cluster [%d]\n" , cluster -> cluster_id );
231251
232252 return 0 ;
@@ -628,11 +648,27 @@ clusterer_bridges_bcast_msg(bin_packet_t *packet, int src_cid)
628648}
629649
630650
651+ /* This node's id in @cluster_id, resolved without taking cl_list_lock: clusters
652+ * persist for the module's lifetime, and callers may already hold cl_list_lock
653+ * (read) or a different lock (shtags) whose order is cl_list_lock -> shtags_lock,
654+ * so taking cl_list_lock here would risk a reverse-order deadlock. Matches the
655+ * lock-free nature of the GET_CURRENT_ID this replaces. Returns -1 if the
656+ * cluster is unknown or this node's identity in it is not yet established. */
657+ static int trailer_self_id (int cluster_id )
658+ {
659+ cluster_info_t * cl ;
660+
661+ for (cl = * cluster_list ; cl ; cl = cl -> next )
662+ if (cl -> cluster_id == cluster_id )
663+ return cluster_self_id (cl );
664+ return -1 ;
665+ }
666+
631667int msg_add_trailer (bin_packet_t * packet , int cluster_id , int dst_id )
632668{
633669 if (bin_push_int (packet , cluster_id ) < 0 )
634670 return -1 ;
635- if (bin_push_int (packet , current_id ) < 0 )
671+ if (bin_push_int (packet , trailer_self_id ( cluster_id ) ) < 0 )
636672 return -1 ;
637673 if (bin_push_int (packet , dst_id ) < 0 )
638674 return -1 ;
@@ -947,7 +983,7 @@ static void handle_cap_update(bin_packet_t *packet, node_info_t *source)
947983 for (i = 0 ; i < nr_nodes ; i ++ ) {
948984 bin_pop_int (packet , & node_id );
949985
950- if (node_id == current_id ) {
986+ if (node_id == cluster_self_id ( source -> cluster ) ) {
951987 bin_pop_int (packet , & nr_cap );
952988 for (j = 0 ; j < nr_cap ; j ++ ) {
953989 bin_pop_str (packet , & cap );
@@ -1128,12 +1164,15 @@ static void handle_remove_node(bin_packet_t *packet, cluster_info_t *cl)
11281164 bin_pop_int (packet , & target_node );
11291165 LM_DBG ("Received remove node command for node id: [%d]\n" , target_node );
11301166
1131- if (db_mode ) {
1167+ if (cl_db_mode ( cl ) ) {
11321168 LM_DBG ("We are in DB mode, ignoring received remove node command\n" );
11331169 return ;
11341170 }
11351171
1136- if (target_node == current_id ) {
1172+ if (target_node == cluster_self_id (cl )) {
1173+ if (!cl -> current_node )
1174+ return ;
1175+
11371176 lock_get (cl -> current_node -> lock );
11381177
11391178 if (cl -> current_node -> flags & NODE_STATE_ENABLED ) {
@@ -1180,14 +1219,9 @@ void bin_rcv_cl_extra_packets(bin_packet_t *packet, int packet_type,
11801219 LM_DBG ("received clusterer message from: %s:%hu with source id: %d and"
11811220 " cluster id: %d\n" , ip , port , source_id , cluster_id );
11821221
1183- if (source_id == current_id ) {
1184- LM_ERR ("Received message with bad source - same node id as this instance\n" );
1185- return ;
1186- }
1187-
11881222 gettimeofday (& now , NULL );
11891223
1190- if (!db_mode && packet_type == CLUSTERER_REMOVE_NODE )
1224+ if (( !db_mode || use_controller ) && packet_type == CLUSTERER_REMOVE_NODE )
11911225 lock_start_write (cl_list_lock );
11921226 else
11931227 lock_start_read (cl_list_lock );
@@ -1199,6 +1233,11 @@ void bin_rcv_cl_extra_packets(bin_packet_t *packet, int packet_type,
11991233 goto exit ;
12001234 }
12011235
1236+ if (source_id == cluster_self_id (cl )) {
1237+ LM_ERR ("Received message with bad source - same node id as this instance\n" );
1238+ goto exit ;
1239+ }
1240+
12021241 lock_get (cl -> current_node -> lock );
12031242 if (!(cl -> current_node -> flags & NODE_STATE_ENABLED )) {
12041243 lock_release (cl -> current_node -> lock );
@@ -1236,7 +1275,7 @@ void bin_rcv_cl_extra_packets(bin_packet_t *packet, int packet_type,
12361275 } else
12371276 lock_release (node -> lock );
12381277
1239- if (dest_id != current_id ) {
1278+ if (dest_id != cluster_self_id ( cl ) ) {
12401279 if (clusterer_enable_rerouting == 0 ) {
12411280 LM_WARN ("Received message for destination id [%d] but rerouting disabled\n" , dest_id );
12421281 goto exit ;
@@ -1292,7 +1331,7 @@ void bin_rcv_cl_extra_packets(bin_packet_t *packet, int packet_type,
12921331 }
12931332
12941333exit :
1295- if (!db_mode && packet_type == CLUSTERER_REMOVE_NODE )
1334+ if (( !db_mode || use_controller ) && packet_type == CLUSTERER_REMOVE_NODE )
12961335 lock_stop_write (cl_list_lock );
12971336 else
12981337 lock_stop_read (cl_list_lock );
@@ -1318,12 +1357,7 @@ void bin_rcv_cl_packets(bin_packet_t *packet, int packet_type,
13181357 LM_DBG ("received clusterer message from: %s:%hu with source id: %d and "
13191358 "cluster id: %d\n" , ip , port , source_id , cl_id );
13201359
1321- if (source_id == current_id ) {
1322- LM_ERR ("Received message with bad source - same node id as this instance\n" );
1323- return ;
1324- }
1325-
1326- if (!db_mode && (packet_type == CLUSTERER_NODE_DESCRIPTION ||
1360+ if ((!db_mode || use_controller ) && (packet_type == CLUSTERER_NODE_DESCRIPTION ||
13271361 packet_type == CLUSTERER_FULL_TOP_UPDATE ))
13281362 lock_start_write (cl_list_lock );
13291363 else
@@ -1335,6 +1369,22 @@ void bin_rcv_cl_packets(bin_packet_t *packet, int packet_type,
13351369 goto exit ;
13361370 }
13371371
1372+ /* current_node is legitimately NULL while this node's identity is being
1373+ * (re)established for a dynamically constructed cluster (clusterer_ctrl
1374+ * update_identity: the cluster can already exist and receive BIN packets
1375+ * before current_node is assigned). Drop the packet instead of
1376+ * dereferencing NULL. */
1377+ if (!cl -> current_node ) {
1378+ LM_INFO ("Received message for cluster [%d] before local identity is "
1379+ "established, ignoring\n" , cl_id );
1380+ goto exit ;
1381+ }
1382+
1383+ if (source_id == cluster_self_id (cl )) {
1384+ LM_ERR ("Received message with bad source - same node id as this instance\n" );
1385+ goto exit ;
1386+ }
1387+
13381388 lock_get (cl -> current_node -> lock );
13391389 if (!(cl -> current_node -> flags & NODE_STATE_ENABLED )) {
13401390 lock_release (cl -> current_node -> lock );
@@ -1347,7 +1397,7 @@ void bin_rcv_cl_packets(bin_packet_t *packet, int packet_type,
13471397
13481398 if (!node ) {
13491399 LM_INFO ("Received message with unknown source id [%d]\n" , source_id );
1350- if (!db_mode )
1400+ if (!cl_db_mode ( cl ) )
13511401 handle_internal_msg_unknown (packet , cl , packet_type , & ri -> src_su ,
13521402 ri -> proto , source_id );
13531403 } else {
@@ -1374,7 +1424,7 @@ void bin_rcv_cl_packets(bin_packet_t *packet, int packet_type,
13741424 }
13751425
13761426exit :
1377- if (!db_mode && (packet_type == CLUSTERER_NODE_DESCRIPTION ||
1427+ if (( !db_mode || use_controller ) && (packet_type == CLUSTERER_NODE_DESCRIPTION ||
13781428 packet_type == CLUSTERER_FULL_TOP_UPDATE ))
13791429 lock_stop_write (cl_list_lock );
13801430 else
@@ -1472,11 +1522,6 @@ static void bin_rcv_mod_packets(bin_packet_t *packet, int packet_type,
14721522 "cluster ids: %d->%d\n" , ip , port , source_id , src_cluster_id , cluster_id );
14731523 }
14741524
1475- if (source_id == current_id ) {
1476- LM_ERR ("Received message with bad source - same node id as this instance\n" );
1477- return ;
1478- }
1479-
14801525 cap = (struct capability_reg * )ptr ;
14811526 if (!cap ) {
14821527 LM_ERR ("Failed to get bin callback parameter\n" );
@@ -1493,6 +1538,11 @@ static void bin_rcv_mod_packets(bin_packet_t *packet, int packet_type,
14931538 goto exit ;
14941539 }
14951540
1541+ if (source_id == cluster_self_id (cl )) {
1542+ LM_ERR ("Received message with bad source - same node id as this instance\n" );
1543+ goto exit ;
1544+ }
1545+
14961546 lock_get (cl -> current_node -> lock );
14971547 if (!(cl -> current_node -> flags & NODE_STATE_ENABLED )) {
14981548 lock_release (cl -> current_node -> lock );
@@ -1543,7 +1593,7 @@ static void bin_rcv_mod_packets(bin_packet_t *packet, int packet_type,
15431593 } else
15441594 lock_release (node -> lock );
15451595
1546- if (dest_id != current_id ) {
1596+ if (dest_id != cluster_self_id ( cl ) ) {
15471597 /* route the message */
15481598 bin_push_int (packet , cluster_id );
15491599 bin_push_int (packet , source_id );
@@ -1619,6 +1669,7 @@ int send_single_cap_update(cluster_info_t *cluster, struct local_cap *cap,
16191669
16201670 timestamp = (int )(unsigned long )time (NULL );
16211671
1672+ if (!cluster -> current_node ) return -1 ;
16221673 lock_get (cluster -> current_node -> lock );
16231674
16241675 for (neigh = cluster -> current_node -> neighbour_list ; neigh ;
@@ -1637,7 +1688,7 @@ int send_single_cap_update(cluster_info_t *cluster, struct local_cap *cap,
16371688 return -1 ;
16381689 }
16391690 bin_push_int (& packet , cluster -> cluster_id );
1640- bin_push_int (& packet , current_id );
1691+ bin_push_int (& packet , cluster_self_id ( cluster ) );
16411692
16421693 bin_push_int (& packet , ++ cluster -> current_node -> cap_seq_no );
16431694 bin_push_int (& packet , timestamp );
@@ -1646,7 +1697,7 @@ int send_single_cap_update(cluster_info_t *cluster, struct local_cap *cap,
16461697
16471698 /* only the current node */
16481699 bin_push_int (& packet , 1 );
1649- bin_push_int (& packet , current_id );
1700+ bin_push_int (& packet , cluster_self_id ( cluster ) );
16501701
16511702 /* only a single capability */
16521703 bin_push_int (& packet , 1 );
@@ -1656,7 +1707,7 @@ int send_single_cap_update(cluster_info_t *cluster, struct local_cap *cap,
16561707 bin_push_int (& packet , 0 ); /* don't require reply */
16571708
16581709 bin_push_int (& packet , 1 ); /* path length is 1, only current node at this point */
1659- bin_push_int (& packet , current_id );
1710+ bin_push_int (& packet , cluster_self_id ( cluster ) );
16601711 bin_get_buffer (& packet , & bin_buffer );
16611712
16621713 for (i = 0 ; i < no_dests ; i ++ )
@@ -1704,7 +1755,7 @@ int send_cap_update(node_info_t *dest_node, int require_reply)
17041755 return -1 ;
17051756 }
17061757 bin_push_int (& packet , dest_node -> cluster -> cluster_id );
1707- bin_push_int (& packet , current_id );
1758+ bin_push_int (& packet , cluster_self_id ( dest_node -> cluster ) );
17081759
17091760 lock_get (dest_node -> cluster -> current_node -> lock );
17101761
@@ -1719,7 +1770,7 @@ int send_cap_update(node_info_t *dest_node, int require_reply)
17191770 for (cl_cap = dest_node -> cluster -> capabilities , nr_cap = 0 ; cl_cap ;
17201771 cl_cap = cl_cap -> next , nr_cap ++ ) ;
17211772 if (nr_cap ) {
1722- bin_push_int (& packet , current_id );
1773+ bin_push_int (& packet , cluster_self_id ( dest_node -> cluster ) );
17231774 bin_push_int (& packet , nr_cap );
17241775 for (cl_cap = dest_node -> cluster -> capabilities ;cl_cap ;cl_cap = cl_cap -> next ) {
17251776 bin_push_str (& packet , & cl_cap -> reg .name );
@@ -1750,7 +1801,7 @@ int send_cap_update(node_info_t *dest_node, int require_reply)
17501801 bin_push_int (& packet , require_reply );
17511802
17521803 bin_push_int (& packet , 1 ); /* path length is 1, only current node at this point */
1753- bin_push_int (& packet , current_id );
1804+ bin_push_int (& packet , cluster_self_id ( dest_node -> cluster ) );
17541805 bin_get_buffer (& packet , & bin_buffer );
17551806
17561807 if (msg_send (dest_node -> cluster -> send_sock , dest_node -> proto , & dest_node -> addr ,
@@ -1903,9 +1954,25 @@ int cl_register_cap(str *cap, cl_packet_cb_f packet_cb, cl_event_cb_f event_cb,
19031954
19041955 cluster = get_cluster_by_id (cluster_id );
19051956 if (!cluster ) {
1906- LM_ERR ("cluster id %d is not defined in the %s\n" , cluster_id ,
1907- db_mode ? "DB" : "script" );
1908- return -1 ;
1957+ if (use_controller ) {
1958+ cluster = shm_malloc (sizeof * cluster );
1959+ if (!cluster ) { LM_ERR ("no shm\n" ); return -1 ; }
1960+ memset (cluster , 0 , sizeof * cluster );
1961+ cluster -> cluster_id = cluster_id ;
1962+ cluster -> controller_managed = 1 ; /* on-demand controller stub */
1963+ if ((cluster -> lock = lock_alloc ()) == NULL || !lock_init (cluster -> lock )) {
1964+ shm_free (cluster ); return -1 ;
1965+ }
1966+ if (cl_list_lock ) lock_start_write (cl_list_lock );
1967+ cluster -> next = * cluster_list ;
1968+ * cluster_list = cluster ;
1969+ if (cl_list_lock ) lock_stop_write (cl_list_lock );
1970+ LM_INFO ("clusterer: auto-created stub for cluster %d\n" , cluster_id );
1971+ } else {
1972+ LM_ERR ("cluster id %d is not defined in the %s\n" , cluster_id ,
1973+ db_mode ? "DB" : "script" );
1974+ return -1 ;
1975+ }
19091976 }
19101977
19111978 new_cl_cap = shm_malloc (sizeof * new_cl_cap + cap -> len + CAP_SR_ID_PREFIX_LEN );
0 commit comments