Update join tests and start synchronization only after confirmed ready

This commit is contained in:
evgeny committed 2026-11-03 16:06:36 +01:00
1 parent af9ad53a7d
commit 3ce096d352
3 files changed
+25 -19

No files matched your search

+3 -1
View File
@@ -1600,6 +1600,7 @@ static void cs_send_join_ready(struct chat_sync* cs, const char* ch_id, uint64_t
if (!topo_node_sqlite_member_allowed(cs->inst->topo_sqlite_db, ch_id, node_id)) return;
uint64_t group = strtoull(ch_id, NULL, 10);
uint8_t data[9] = { CS_MSG_JOIN_READY }; memcpy(data + 1, &group, 8);
int sent = 0;
struct join_pending** link = &cs->join_pending;
while (*link) {
struct join_pending* pending = *link;
@@ -1620,8 +1621,9 @@ static void cs_send_join_ready(struct chat_sync* cs, const char* ch_id, uint64_t
DEBUG_DEBUG(DEBUG_CATEGORY_MEMBER_SYNC, "join ready peer=%016llx attempt=%016llx",
(unsigned long long)node_id, (unsigned long long)pending->attempt);
*link = pending->next; u_free(pending);
sent++;
}
cs_schedule_sync(cs, group, node_id, "join_accepted");
if (sent) cs_schedule_sync(cs, group, node_id, "join_accepted");
}
void chat_sync_join_rejected(struct UTUN_INSTANCE* inst, uint64_t channel, uint64_t inviter,
+17 -17
View File
@@ -158,11 +158,11 @@ static int serialize_member(uint64_t node_id, const uint8_t* x25519, const uint8
/* ── 5.1.1 build_sign_msg ── */
static void t_build_sign_msg(void) {
TEST("member_sync_build_sign_msg: 42 bytes"); {
uint8_t x[32], priv[32], out[64]; gen_x25519(x, priv);
TEST("member_sync_build_sign_msg: 74 bytes"); {
uint8_t x[64] = {1}, out[74];
int n = member_sync_build_sign_msg(x, out, (int)sizeof(out));
if (n == MEMBER_SIGN_MSG_SIZE && memcmp(out, x, 32) == 0
&& memcmp(out + 32, MEMBER_SIGN_SUFFIX, MEMBER_SIGN_SUFFIX_LEN) == 0) OK();
if (n == MEMBER_SIGN_MSG_SIZE && memcmp(out, x, 64) == 0
&& memcmp(out + 64, MEMBER_SIGN_SUFFIX, MEMBER_SIGN_SUFFIX_LEN) == 0) OK();
else FAIL("n=%d", n);
}
TEST("member_sync_build_sign_msg: short buffer -> -1"); {
@@ -193,35 +193,35 @@ static void t_sign_verify(void) {
(uint64_t)time(NULL), time(NULL));
struct ms_member_rec rec;
uint8_t sig[64];
uint8_t sig[64], join[64] = {1}, other_join[64] = {2};
TEST("verify_signature: root (signed_by=0, channel ed25519) == 1"); {
member_sync_sign_pubkey(ch_ed_priv, jx, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.signature = sig; rec.signed_by = 0;
member_sync_sign_join(ch_ed_priv, join, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.join_sig = join; rec.signature = sig; rec.signed_by = 0;
if (member_sync_verify_signature(db, CH_COMP, &rec) == 1) OK(); else FAIL();
}
TEST("verify_signature: child (signed_by=parent) == 1"); {
member_sync_sign_pubkey(p_ed_priv, jx, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.signature = sig; rec.signed_by = parent_id;
member_sync_sign_join(p_ed_priv, join, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.join_sig = join; rec.signature = sig; rec.signed_by = parent_id;
if (member_sync_verify_signature(db, CH_COMP, &rec) == 1) OK(); else FAIL();
}
TEST("verify_signature: tampered x25519 == 0"); {
member_sync_sign_pubkey(ch_ed_priv, jx, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = other_x; rec.signature = sig; rec.signed_by = 0;
TEST("verify_signature: tampered join_sig == 0"); {
member_sync_sign_join(ch_ed_priv, join, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = other_x; rec.join_sig = other_join; rec.signature = sig; rec.signed_by = 0;
if (member_sync_verify_signature(db, CH_COMP, &rec) == 0) OK(); else FAIL();
}
TEST("verify_signature: parent not in nodes == -1"); {
member_sync_sign_pubkey(ch_ed_priv, jx, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.signature = sig; rec.signed_by = 0x7777ULL;
member_sync_sign_join(ch_ed_priv, join, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.join_sig = join; rec.signature = sig; rec.signed_by = 0x7777ULL;
if (member_sync_verify_signature(db, CH_COMP, &rec) == -1) OK(); else FAIL();
}
TEST("verify_signature: no channel == -1"); {
member_sync_sign_pubkey(ch_ed_priv, jx, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.signature = sig; rec.signed_by = 0;
member_sync_sign_join(ch_ed_priv, join, sig);
memset(&rec, 0, sizeof(rec)); rec.x25519 = jx; rec.join_sig = join; rec.signature = sig; rec.signed_by = 0;
if (member_sync_verify_signature(db, "99999999999", &rec) == -1) OK(); else FAIL();
}
@@ -657,7 +657,7 @@ static void t_registration_edges(void) {
struct chat_join_registration* req = chat_join_register_key(g_inst[0], g_group_id, g_nid[1], JOIN_KEY + 26, registered, &r);
uint8_t key[32] = {0}; struct join_member_data member = {0};
member.node_id = g_nid[0]; member.x25519 = member.ed25519 = key;
int forwarded = chat_join_forward_request(g_inst[0], g_group_id, g_nid[1], JOIN_KEY, &member);
int forwarded = chat_join_forward_request(g_inst[0], g_group_id, g_nid[1], JOIN_KEY, 1, &member);
g_inst[0]->router_conns = saved;
timeout_heap_peek(g_ua->timeout_heap, &timer); /* освобождает отменённые таймеры без вызова callback */
if (!req && !r.calls && forwarded == -1 && !g_inst[0]->join_registrations
+5 -1
View File
@@ -106,6 +106,8 @@ static void setup(struct fixture* f) {
if ((i == 0 && ch == 1) || (i == 2 && ch == 0)) continue;
assert(topo_node_sqlite_member_block_put(f->inst->topo_sqlite_db, f->channel[ch], conn->peer_node_id,
signature, 1, signature, 1, keys.public_key, keys.public_key, "{}", NULL, 0, signature) == 0);
char sql[128]; snprintf(sql, sizeof(sql), "UPDATE peers_%s SET admitted=1", f->channel[ch]);
assert(sqlite3_exec(f->inst->topo_sqlite_db, sql, NULL, NULL, NULL) == SQLITE_OK);
}
}
/* Кеш намеренно не обновляем: задания должны видеть актуальное членство в БД. */
@@ -177,7 +179,9 @@ static void test_join_existing_transport(void) {
struct fixture f; setup(&f);
struct chat_join_route route = {.peer = f.peers[0]->peer_node_id};
memcpy(route.public_key, f.peers[0]->crypto_ctx.peer_public_key, sizeof(route.public_key));
assert(cs_pending_add(f.inst->chat_sync, f.peers[0]->peer_node_id, f.channel[0], &route, 1) == 0);
uint8_t join[64] = {0}; struct join_member_data member = {.join_ts = 1, .join_sig = join};
assert(cs_pending_add(f.inst->chat_sync, f.peers[0]->peer_node_id, f.channel[0], &route, 1, f.inst->node_id, &member) == 0);
f.inst->chat_sync->join_pending->confirmed = 1;
cs_send_join_ready(f.inst->chat_sync, f.channel[0], f.peers[0]->peer_node_id);
assert(!start_count); run_ms(&f, 1100);
assert(start_count == 1 && starts[0].peer == f.peers[0]->peer_node_id && starts[0].channel == f.gid[0]);