diff --git a/src/routing_layer/devgroup.c b/src/routing_layer/devgroup.c index 71785ae4d..9eb0b9122 100644 --- a/src/routing_layer/devgroup.c +++ b/src/routing_layer/devgroup.c @@ -266,8 +266,9 @@ int devgroup_latest(sqlite3* db, const uint8_t id[32], struct devgroup_record* o *out = best; *profile = bp; return found; } -int devgroup_member(sqlite3* db, uint64_t node, uint8_t id[32], char name[64]) { - sqlite3_stmt* st = NULL; struct devgroup_record r = {0}, best; struct devgroup_profile profile; +int devgroup_read_member(sqlite3* db, uint64_t node, struct devgroup_record* out) { + if (!db || !node || !out) return dg_error("member arguments"); + sqlite3_stmt* st = NULL; struct devgroup_record r = {0}; int rc = sqlite3_prepare_v2(db, "SELECT devgroup_ed,devgroup_x,devgroup_member_sig,devgroup_json,devgroup_profile_sig," "x25519_pubkey,ed25519_pubkey FROM nodes WHERE node_id=? AND devgroup_ed IS NOT NULL", -1, &st, NULL); if (rc == SQLITE_OK) rc = sqlite3_bind_int64(st, 1, (sqlite3_int64)node); @@ -286,6 +287,15 @@ int devgroup_member(sqlite3* db, uint64_t node, uint8_t id[32], char name[64]) { } } if (dg_finish(db, st, rc, SQLITE_DONE)) return -1; + *out = r; + return found; +} + +int devgroup_member(sqlite3* db, uint64_t node, uint8_t id[32], char name[64]) { + if (!id || !name) return dg_error("member output arguments"); + struct devgroup_record r, best; struct devgroup_profile profile; + int found = devgroup_read_member(db, node, &r); + if (found < 0) return -1; memset(id, 0, 32); memset(name, 0, 64); if (!found) return 0; if (devgroup_latest(db, r.ed, &best, &profile) != 1) return dg_error("member profile unavailable"); diff --git a/src/routing_layer/devgroup.h b/src/routing_layer/devgroup.h index 982054528..ab579848b 100644 --- a/src/routing_layer/devgroup.h +++ b/src/routing_layer/devgroup.h @@ -47,6 +47,9 @@ int devgroup_project(struct sqlite3* db, const struct TOPO_NODE* node); int devgroup_load_local(struct UTUN_INSTANCE* inst, struct devgroup_record* out, uint8_t ed_priv[32], uint8_t x_priv[32]); /* Поиск максимального проверенного объявления среди nodes, 0/1/-1. */ int devgroup_latest(struct sqlite3* db, const uint8_t id[32], struct devgroup_record* out, struct devgroup_profile* profile); +/* Проверенная запись одного узла без поиска профилей других устройств; 0=нет,1=найдено,-1=ошибка. + * out обнуляется при отсутствии группы, при ошибке не меняется. Для свежего имени — devgroup_member. */ +int devgroup_read_member(struct sqlite3* db, uint64_t node, struct devgroup_record* out); /* Проверенная принадлежность узла из nodes и самое свежее имя;0=нет,1=найдено,-1=ошибка. Буферы32/64 байта. */ int devgroup_member(struct sqlite3* db, uint64_t node, uint8_t id[32], char name[64]); /* Независимые публичные ключи из seed, 0/-1. */