Browse Source

TOPO_GROUP: embed struct ll_entry as first member (direct queue embedding, hash index)

chatgui
Evgeny 3 months ago
parent
commit
3f874a80ab
  1. 26
      src/topo_group.c
  2. 1
      src/topo_group.h
  3. 21
      tests/test_etcp_router_unit.c

26
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; } 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); 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)); struct ll_entry* qe = queue_entry_new(sizeof(struct TOPO_GROUP));
if (!group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed"); return NULL; } 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->group_id = group_id;
group->instance = instance; group->instance = instance;
group->ping_pending = NULL; group->next_ping_req_id = 1; group->next_ping_req_id = 1;
group->nodeinfo_env = NULL; group->nodeinfo_dbi = 0;
sc_derive_ed25519_pubkey(instance->my_keys.private_key, group->ed25519_public_key); 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"); 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); 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"); 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"); 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; group->local_node = NULL;
topo_group_update_my_nodeinfo(instance, group); 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); topo_node_lmdb_destroy(group);
if (group->nodes) queue_free(group->nodes); if (group->nodes) queue_free(group->nodes);
u_free(group);
} }
struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { 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; } if (!g) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed"); return NULL; }
g->instance = instance; 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; } 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"); 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"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "failed to create default group");
return NULL; 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_bind(instance, ETCP_ID_TOPO_ENTRY, topo_group_receive_cbk);
etcp_add_new_conn_cbk(instance, topo_group_etcp_conn_cbk, NULL); 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 TOPO_GROUPS* g = instance->topo_groups;
struct ll_entry* ge; 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); queue_free(g->group_list);
memory_pool_destroy(g->v4_sock_meta_pool); 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) { struct TOPO_GROUP* topo_groups_find(struct TOPO_GROUPS* g, uint64_t group_id) {
if (!g || !g->group_list) return NULL; if (!g || !g->group_list) return NULL;
struct ll_entry* e = g->group_list->head; struct ll_entry* e = queue_find_data_by_index(g->group_list, &group_id);
while (e) { struct TOPO_GROUP* grp = *(struct TOPO_GROUP**)e->data; if (grp && grp->group_id == group_id) return grp; e = e->next; } return e ? (struct TOPO_GROUP*)e : NULL;
return 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; } void topo_group_set_nat_check_local(struct TOPO_GROUP* group, int allow) { if (!group) return; group->allow_nat_check_local = allow ? 1 : 0; }

1
src/topo_group.h

@ -92,6 +92,7 @@ struct ETCP_LINK;
* @brief Группа топологии (одна на каждый group_id: utun, чат-группа, …) * @brief Группа топологии (одна на каждый group_id: utun, чат-группа, …)
*/ */
struct TOPO_GROUP { struct TOPO_GROUP {
struct ll_entry ll;
uint64_t group_id; // уникальный идентификатор группы uint64_t group_id; // уникальный идентификатор группы
struct UTUN_INSTANCE* instance; struct UTUN_INSTANCE* instance;
struct ll_queue* senders_list; struct ll_queue* senders_list;

21
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) { 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)); inst->topo_groups = u_calloc(1, sizeof(struct TOPO_GROUPS));
if (!inst->topo_groups) { printf(" setup_bgp: topo_groups alloc failed\n"); return; } 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"); inst->topo_groups->group_list = queue_new(inst->ua, 16, 0, 8, "group_list_test");
struct TOPO_GROUP* group = u_calloc(1, sizeof(struct TOPO_GROUP));
if (!group) { printf(" setup_bgp: u_calloc failed\n"); return; } 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->instance = inst;
group->group_id = TOPO_GROUP_UTUN; group->group_id = TOPO_GROUP_UTUN;
group->nodes = queue_new(inst->ua, BGP_NODES_HASH_SIZE, 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"); 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; } if (!group->nodes) { printf(" setup_bgp: queue_new failed\n"); queue_entry_free(qe); return; }
{ struct ll_entry* e = queue_entry_new(sizeof(struct TOPO_GROUP)); queue_data_put_with_index(inst->topo_groups->group_list, &group->ll);
if (e) { *(struct TOPO_GROUP**)e->data = group; queue_data_put(inst->topo_groups->group_list, e); } }
struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ)); struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ));
if (!nq) { printf(" setup_bgp: nq alloc failed\n"); return; } 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) { static void teardown_bgp_for_sign_test(struct UTUN_INSTANCE* inst) {
if (!inst || !inst->topo_groups) return; if (!inst || !inst->topo_groups) return;
struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups); struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups);
if (!group) return; if (group && group->nodes) {
if (group->nodes) {
struct ll_entry* e; struct ll_entry* e;
while ((e = queue_data_get(group->nodes)) != NULL) queue_entry_free(e); while ((e = queue_data_get(group->nodes)) != NULL) queue_entry_free(e);
queue_free(group->nodes); 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); queue_free(inst->topo_groups->group_list);
u_free(inst->topo_groups); u_free(inst->topo_groups);
inst->topo_groups = NULL; inst->topo_groups = NULL;

Loading…
Cancel
Save