Reject incomplete groups and refresh BGP subnet ownership
This commit is contained in:
1 parent
086eefed55
commit
4363a424d0
2 files changed
+26
-11
No files matched your search
+5
-3
@@ -90,10 +90,12 @@ int radio_init(struct TOPO_GROUP* group) {
|
||||
if (!ctx) { DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "%s: alloc failed", RADIO_ID); return -1; }
|
||||
ctx->group = group;
|
||||
ctx->stream_id = (uint16_t)(get_time_tb() & 0xFFFF);
|
||||
group->radio = ctx;
|
||||
|
||||
ctx->talker_timer = uasync_set_timeout(group->instance->ua, RADIO_TALKER_TIMEOUT_TB, ctx, radio_talker_timer_cb, "radio_talker");
|
||||
if (!ctx->talker_timer) DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "%s: init talker_timer failed grp=%016llx", RADIO_ID, (unsigned long long)group->group_id);
|
||||
if (!ctx->talker_timer) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "%s: init talker_timer failed grp=%016llx", RADIO_ID, (unsigned long long)group->group_id);
|
||||
u_free(ctx); return -1;
|
||||
}
|
||||
group->radio = ctx;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "%s: init ok grp=%016llx", RADIO_ID, (unsigned long long)group->group_id);
|
||||
return 0;
|
||||
|
||||
@@ -56,6 +56,7 @@ static void topo_group_routes_changed(struct TOPO_GROUP* group, struct TOPO_GROU
|
||||
static void topo_group_prune_paths(struct TOPO_GROUP_CONN_ITEM* peer, int all);
|
||||
static void topo_exchange_watch(void* arg);
|
||||
static void topo_tx_fail(struct TOPO_GROUP_CONN_ITEM* peer);
|
||||
static void topo_group_destroy(struct TOPO_GROUP* group);
|
||||
|
||||
static void topo_exchange_cancel(struct TOPO_GROUP_CONN_ITEM* peer) {
|
||||
if (peer->exchange_timer) uasync_cancel_timeout(peer->group->instance->ua, peer->exchange_timer);
|
||||
@@ -602,7 +603,10 @@ static struct TOPO_GROUP* topo_group_create(struct UTUN_INSTANCE* instance, uint
|
||||
group->group_type = group_type;
|
||||
group->instance = instance;
|
||||
|
||||
sc_derive_ed25519_pubkey(instance->my_keys.private_key, group->ed25519_public_key);
|
||||
if (sc_derive_ed25519_pubkey(instance->my_keys.private_key, group->ed25519_public_key) != SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "cannot derive group identity group=%016llx", (unsigned long long)group_id);
|
||||
queue_entry_free(qe); return NULL;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Ed25519 pubkey derived from X25519 private key");
|
||||
|
||||
group->nodes = queue_new(instance->ua, BGP_NODES_HASH_SIZE, offsetof(struct TOPO_GROUP_NODE, node_id) - sizeof(struct ll_entry), 8, "group_nodes");
|
||||
@@ -612,15 +616,20 @@ static struct TOPO_GROUP* topo_group_create(struct UTUN_INSTANCE* instance, uint
|
||||
if (!group->senders_list) { queue_free(group->nodes); queue_entry_free(qe); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "senders_list queue creation failed"); return NULL; }
|
||||
|
||||
group->local_node = NULL;
|
||||
topo_group_update_my_nodeinfo(instance, group);
|
||||
if (topo_group_update_my_nodeinfo(instance, group) < 0) goto fail;
|
||||
|
||||
group->conn_mgr = conn_mgr_init(group);
|
||||
if (!group->conn_mgr) goto fail;
|
||||
|
||||
broadcast_init(group);
|
||||
radio_init(group);
|
||||
if (broadcast_init(group) < 0 || radio_init(group) < 0) goto fail;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "TOPO group created: group_id=%016llx", (unsigned long long)group_id);
|
||||
return group;
|
||||
fail:
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "group creation rolled back group=%016llx local_node=%p conn_mgr=%p broadcast=%p radio=%p",
|
||||
(unsigned long long)group_id, (void*)group->local_node, (void*)group->conn_mgr,
|
||||
(void*)group->broadcast, (void*)group->radio);
|
||||
topo_group_destroy(group); queue_entry_free(qe); return NULL;
|
||||
}
|
||||
|
||||
/* Полностью разрушает группу: recovery, connect, broadcast, conn_mgr, узлы. */
|
||||
@@ -920,14 +929,16 @@ void topo_group_set_radio(struct TOPO_GROUP* group, int on) {
|
||||
(unsigned long long)group->group_id, group->channel_id);
|
||||
return;
|
||||
}
|
||||
uint8_t previous = group->radio_active;
|
||||
group->radio_active = v;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "set_radio: %s grp=%016llx ch=%s",
|
||||
v ? "ON" : "OFF", (unsigned long long)group->group_id, group->channel_id);
|
||||
if (topo_group_update_my_nodeinfo(group->instance, group) < 0) {
|
||||
group->radio_active = previous;
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "set_radio: cannot update local NODEINFO grp=%016llx ch=%s radio=%u",
|
||||
(unsigned long long)group->group_id, group->channel_id, v);
|
||||
return;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "set_radio: %s grp=%016llx ch=%s",
|
||||
v ? "ON" : "OFF", (unsigned long long)group->group_id, group->channel_id);
|
||||
/* Свой мембер обновляется через те же подписки, что и удалённые BGP-узлы. */
|
||||
for (struct topo_node_cbk_entry* cb = group->node_cbks; cb; cb = cb->next)
|
||||
cb->fn(group, group->instance->node_id, TOPO_NODE_EVENT_UPDATE, cb->arg);
|
||||
@@ -1191,8 +1202,10 @@ static void topo_group_routes_changed(struct TOPO_GROUP* group, struct TOPO_GROU
|
||||
node->paths ? queue_entry_count(node->paths) : 0,
|
||||
(unsigned long long)(best ? best->conn->peer_node_id : 0), best ? best->hop_count : 0);
|
||||
if (group->group_type != TOPO_GROUP_TYPE_CHAT && group->instance->rt) {
|
||||
if (best && node->subnets) route_insert(group->instance->rt, node);
|
||||
else route_delete(group->instance->rt, node);
|
||||
route_delete(group->instance->rt, node);
|
||||
if (best && node->subnets && node->subnets->v4_subnets && !route_insert(group->instance->rt, node))
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "BGP IPv4 routes rejected: group=%016llx node=%016llx; previous routes removed",
|
||||
(unsigned long long)group->group_id, (unsigned long long)id);
|
||||
}
|
||||
topo_fire_nodeinfo_cbk(group->instance, group, node);
|
||||
if (!node->paths) {
|
||||
|
||||
Reference in new issue
Block a user