diff --git a/src/topo_group.c b/src/topo_group.c index 70b14bc0..8211933b 100644 --- a/src/topo_group.c +++ b/src/topo_group.c @@ -201,12 +201,13 @@ static struct TOPO_GROUP* topo_group_create(struct UTUN_INSTANCE* instance, uint if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "instance is NULL"); return NULL; } DEBUG_INFO(DEBUG_CATEGORY_BGP, "group_id=%016llx node_id=%016llx", (unsigned long long)group_id, (unsigned long long)instance->node_id); - struct TOPO_GROUP* group = u_calloc(1, sizeof(struct TOPO_GROUP)); - if (!group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed"); return NULL; } + struct ll_entry* qe = queue_entry_new(sizeof(struct TOPO_GROUP)); + if (!qe) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed"); return NULL; } + struct TOPO_GROUP* group = (struct TOPO_GROUP*)qe; + memset((uint8_t*)group + sizeof(struct ll_entry), 0, sizeof(*group) - sizeof(struct ll_entry)); group->group_id = group_id; group->instance = instance; - group->ping_pending = NULL; group->next_ping_req_id = 1; - group->nodeinfo_env = NULL; group->nodeinfo_dbi = 0; + group->next_ping_req_id = 1; sc_derive_ed25519_pubkey(instance->my_keys.private_key, group->ed25519_public_key); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Ed25519 pubkey derived from X25519 private key"); @@ -214,10 +215,10 @@ static struct TOPO_GROUP* topo_group_create(struct UTUN_INSTANCE* instance, uint if (instance->config && instance->config->global.db_path[0]) topo_node_lmdb_init(group, instance->config->global.db_path); group->nodes = queue_new(instance->ua, BGP_NODES_HASH_SIZE, offsetof(struct TOPO_NODEQ, hash_node_id) - sizeof(struct ll_entry), 8, "group_nodes"); - if (!group->nodes) { u_free(group); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "nodes queue creation failed"); return NULL; } + if (!group->nodes) { queue_entry_free(qe); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "nodes queue creation failed"); return NULL; } group->senders_list = queue_new(instance->ua, 0, 0, 0, "group_senders"); - if (!group->senders_list) { queue_free(group->nodes); u_free(group); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "senders_list queue creation failed"); return NULL; } + 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); @@ -239,8 +240,6 @@ static void topo_group_destroy(struct TOPO_GROUP* group) { topo_node_lmdb_destroy(group); if (group->nodes) queue_free(group->nodes); - - u_free(group); } struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { @@ -251,7 +250,7 @@ struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { if (!g) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed"); return NULL; } g->instance = instance; - g->group_list = queue_new(instance->ua, 0, 0, 0, "topo_groups"); + g->group_list = queue_new(instance->ua, 16, 0, 8, "topo_groups"); if (!g->group_list) { u_free(g); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "group_list queue creation failed"); return NULL; } g->v4_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA4), "to_v4sock"); @@ -272,7 +271,7 @@ struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "failed to create default group"); return NULL; } - { struct ll_entry* e = queue_entry_new(sizeof(struct TOPO_GROUP)); if (e) { *(struct TOPO_GROUP**)e->data = default_group; queue_data_put(g->group_list, e); } } + queue_data_put_with_index(g->group_list, &default_group->ll); etcp_bind(instance, ETCP_ID_TOPO_ENTRY, topo_group_receive_cbk); etcp_add_new_conn_cbk(instance, topo_group_etcp_conn_cbk, NULL); @@ -291,7 +290,7 @@ void topo_groups_destroy(struct UTUN_INSTANCE* instance) { struct TOPO_GROUPS* g = instance->topo_groups; struct ll_entry* ge; - while ((ge = queue_data_get(g->group_list)) != NULL) { topo_group_destroy(*(struct TOPO_GROUP**)ge->data); queue_entry_free(ge); } + while ((ge = queue_data_get(g->group_list)) != NULL) { struct TOPO_GROUP* grp = (struct TOPO_GROUP*)ge; topo_group_destroy(grp); queue_entry_free(ge); } queue_free(g->group_list); memory_pool_destroy(g->v4_sock_meta_pool); @@ -310,9 +309,8 @@ struct TOPO_GROUP* topo_groups_get_default(struct TOPO_GROUPS* g) { struct TOPO_GROUP* topo_groups_find(struct TOPO_GROUPS* g, uint64_t group_id) { if (!g || !g->group_list) return NULL; - struct ll_entry* e = g->group_list->head; - while (e) { struct TOPO_GROUP* grp = *(struct TOPO_GROUP**)e->data; if (grp && grp->group_id == group_id) return grp; e = e->next; } - return NULL; + struct ll_entry* e = queue_find_data_by_index(g->group_list, &group_id); + return e ? (struct TOPO_GROUP*)e : NULL; } void topo_group_set_nat_check_local(struct TOPO_GROUP* group, int allow) { if (!group) return; group->allow_nat_check_local = allow ? 1 : 0; } diff --git a/src/topo_group.h b/src/topo_group.h index 46aa9a7f..573dce3e 100644 --- a/src/topo_group.h +++ b/src/topo_group.h @@ -92,6 +92,7 @@ struct ETCP_LINK; * @brief Группа топологии (одна на каждый group_id: utun, чат-группа, …) */ struct TOPO_GROUP { + struct ll_entry ll; uint64_t group_id; // уникальный идентификатор группы struct UTUN_INSTANCE* instance; struct ll_queue* senders_list; diff --git a/tests/test_etcp_router_unit.c b/tests/test_etcp_router_unit.c index 6da04c9d..433de172 100644 --- a/tests/test_etcp_router_unit.c +++ b/tests/test_etcp_router_unit.c @@ -142,16 +142,18 @@ static int setup_sign_keys(void) { static void setup_bgp_for_sign_test(struct UTUN_INSTANCE* inst, int with_ed25519_key) { inst->topo_groups = u_calloc(1, sizeof(struct TOPO_GROUPS)); if (!inst->topo_groups) { printf(" setup_bgp: topo_groups alloc failed\n"); return; } - inst->topo_groups->group_list = queue_new(inst->ua, 0, 0, 0, "group_list_test"); - struct TOPO_GROUP* group = u_calloc(1, sizeof(struct TOPO_GROUP)); - if (!group) { printf(" setup_bgp: u_calloc failed\n"); return; } + inst->topo_groups->group_list = queue_new(inst->ua, 16, 0, 8, "group_list_test"); + + struct ll_entry* qe = queue_entry_new(sizeof(struct TOPO_GROUP)); + if (!qe) { printf(" setup_bgp: queue_entry_new failed\n"); return; } + struct TOPO_GROUP* group = (struct TOPO_GROUP*)qe; + memset((uint8_t*)group + sizeof(struct ll_entry), 0, sizeof(*group) - sizeof(struct ll_entry)); group->instance = inst; group->group_id = TOPO_GROUP_UTUN; group->nodes = queue_new(inst->ua, BGP_NODES_HASH_SIZE, offsetof(struct TOPO_NODEQ, hash_node_id) - sizeof(struct ll_entry), 8, "group_nodes_test"); - if (!group->nodes) { printf(" setup_bgp: queue_new failed\n"); u_free(group); return; } - { struct ll_entry* e = queue_entry_new(sizeof(struct TOPO_GROUP)); - if (e) { *(struct TOPO_GROUP**)e->data = group; queue_data_put(inst->topo_groups->group_list, e); } } + if (!group->nodes) { printf(" setup_bgp: queue_new failed\n"); queue_entry_free(qe); return; } + queue_data_put_with_index(inst->topo_groups->group_list, &group->ll); struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ)); if (!nq) { printf(" setup_bgp: nq alloc failed\n"); return; } @@ -167,13 +169,14 @@ static void setup_bgp_for_sign_test(struct UTUN_INSTANCE* inst, int with_ed25519 static void teardown_bgp_for_sign_test(struct UTUN_INSTANCE* inst) { if (!inst || !inst->topo_groups) return; struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups); - if (!group) return; - if (group->nodes) { + if (group && group->nodes) { struct ll_entry* e; while ((e = queue_data_get(group->nodes)) != NULL) queue_entry_free(e); queue_free(group->nodes); + group->nodes = NULL; } - u_free(group); + struct ll_entry* ge; + while ((ge = queue_data_get(inst->topo_groups->group_list)) != NULL) queue_entry_free(ge); queue_free(inst->topo_groups->group_list); u_free(inst->topo_groups); inst->topo_groups = NULL;