Keep unresolved invitation chains inactive and test interrupted sync and cycles

This commit is contained in:
evgeny committed 2026-11-03 16:19:12 +01:00
1 parent e7b850f3ea
commit a1653d648b
3 files changed
+18 -8

No files matched your search

+1 -1
View File
@@ -158,7 +158,7 @@ static int gp_load(struct UTUN_INSTANCE* inst, const char* ch, struct gp_member*
int tree = member_sync_verify_signature(db, ch, &m);
if (tree == MS_VERIFY_ERROR) goto done;
p->valid = verified == 1 && tree == 1 && !sqlite3_column_int(st, 12) && memcmp(m.join_sig, (uint8_t[64]){0}, 64);
if (p->valid && m.adm_tags && m.adm_tags_sig) {
if (p->valid && m.adm_tags && m.adm_tags_sig && memcmp(m.adm_tags_sig, (uint8_t[64]){0}, 64)) {
char role[MS_ADM_TAGS_MAX + 1];
if (!json_flat_get(m.adm_tags, "admin", role, sizeof(role))) {
const char* last = role;
+8 -5
View File
@@ -1277,7 +1277,7 @@ static int member_finish(void* ctx, const char* ns) {
if (sqlite3_column_bytes(st, 1) != 32 || sqlite3_column_bytes(st, 3) != 64) { rc = SQLITE_CORRUPT; break; }
if (_sig_is_zero64(m.signature)) continue;
int verified = member_sync_verify_signature(db, ns, &m);
if (verified != 1) {
if (verified != 1 && verified != MS_VERIFY_DEFERRED) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: cannot confirm ns=%s node=%016llx signer=%016llx verification=%d",
MS_ID, ns, (unsigned long long)m.node_id, (unsigned long long)m.signed_by, verified);
rc = SQLITE_CONSTRAINT; break;
@@ -1304,15 +1304,18 @@ static void member_policy_result(void* ctx, const char* ns, uint64_t peer, int r
}
if (group_policy_refresh(inst, ns)) return;
struct ready_member { uint64_t node, signer; uint8_t x[32], signature[64]; };
struct ready_member* rows = NULL; size_t count = 0;
struct ready_member* rows = NULL; size_t count = 0, capacity = 0;
char sql[192]; sqlite3_stmt* st = NULL;
snprintf(sql, sizeof(sql), "SELECT node_id,signed_by,x25519_pubkey,signature FROM peers_%s WHERE admitted=1 AND deleted=0", ns);
int rc = sqlite3_prepare_v2(_db(inst), sql, -1, &st, NULL);
if (rc == SQLITE_OK) while ((rc = sqlite3_step(st)) == SQLITE_ROW) {
if (sqlite3_column_bytes(st, 2) != 32 || sqlite3_column_bytes(st, 3) != 64) { rc = SQLITE_CORRUPT; break; }
if (count >= UINT32_MAX / sizeof(*rows) - 1) { rc = SQLITE_TOOBIG; break; }
struct ready_member* p = u_realloc(rows, (count + 1) * sizeof(*rows));
if (!p) { rc = SQLITE_NOMEM; break; } rows = p;
if (count == capacity) {
size_t next = capacity ? capacity * 2 : 16;
if (next > UINT32_MAX / sizeof(*rows)) { rc = SQLITE_TOOBIG; break; }
struct ready_member* p = u_realloc(rows, next * sizeof(*rows));
if (!p) { rc = SQLITE_NOMEM; break; } rows = p; capacity = next;
}
rows[count].node = (uint64_t)sqlite3_column_int64(st, 0); rows[count].signer = (uint64_t)sqlite3_column_int64(st, 1);
memcpy(rows[count].x, sqlite3_column_blob(st, 2), 32); memcpy(rows[count].signature, sqlite3_column_blob(st, 3), 64); count++;
}
+9 -2
View File
@@ -4,7 +4,7 @@
static uint8_t group_x[32] = {81}, group_private[32] = {82}, group_public[32];
struct person { uint64_t id; uint8_t x[32], ed[32], private[32], join[64], tree[64], role[64]; };
static struct person people[6];
static struct person people[8];
static void public_key(const uint8_t private[32], uint8_t public[32]) {
EVP_PKEY* key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, private, 32); assert(key);
@@ -51,7 +51,7 @@ static void page(struct UTUN_INSTANCE* src, struct UTUN_INSTANCE* dst, uint64_t
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN);
struct UASYNC* ua = uasync_create(); assert(ua); public_key(group_private, group_public);
for (unsigned i = 0; i < 6; i++) {
for (unsigned i = 0; i < 8; i++) {
struct person* p = &people[i]; p->x[0] = i + 1; p->private[0] = i + 11;
public_key(p->private, p->ed); p->id = sc_derive_node_id_from_pubkey(p->x);
uint8_t body[112]; assert(member_sync_build_join_msg(group_x, group_public, p->id, p->x, 1, body, sizeof(body)) == 112);
@@ -90,6 +90,8 @@ int main(void) {
assert(!topo_node_sqlite_member_get_sign(source.topo_sqlite_db, "1001", people[3].id, &signer, signature) && !signer);
/* Политика раньше переподписи: текущий допуск сохраняется до полной контрольной точки. */
page(&source, &target, 0); assert(admitted(&target, 3) && admitted(&target, 4));
member_sync_destroy(&target); assert(!member_sync_init(&target));
assert(admitted(&target, 3) && admitted(&target, 4) && group_policy_pending(target.topo_sqlite_db, "1001") == 1);
const uint64_t mask = ~UINT64_C(0) << (64 - MT_MAX_LEVEL * 5);
for (unsigned i = 0; i < 6; i++) page(&source, &target, people[i].id & mask);
assert(admitted(&target, 3) && admitted(&target, 4));
@@ -104,6 +106,11 @@ int main(void) {
struct ms_member_rec forged = {.node_id = people[3].id, .x25519 = people[3].x, .join_sig = people[4].join,
.signature = signature, .signed_by = 0};
assert(member_sync_verify_signature(source.topo_sqlite_db, "1001", &forged) == 0);
put_person(&source, 6, 7); assert(!admitted(&source, 6) && !member_finish(&source, "1001"));
put_person(&source, 7, 6); assert(!admitted(&source, 6) && !admitted(&source, 7));
token(&source, baseline);
assert(!group_policy_command(&source, "1001", 1, baseline, NULL, &json)); u_free(json);
assert(!admitted(&source, 6) && !admitted(&source, 7));
member_sync_destroy(&source); member_sync_destroy(&target);
assert(sqlite3_close(source.topo_sqlite_db) == SQLITE_OK && sqlite3_close(target.topo_sqlite_db) == SQLITE_OK);
uasync_destroy(ua, 0); puts("PASS: default, roles, cascade, selection, rollback, stale preview, page order, signature precedence, restart");