|
|
|
|
@ -114,24 +114,13 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
|
|
|
|
|
g_cc.my_node_id = inst->node_id; |
|
|
|
|
sqlite3_int64 now_sec = (sqlite3_int64)ntp_time_get_seconds(inst); |
|
|
|
|
|
|
|
|
|
topo_node_sqlite_init(g_cc.db); |
|
|
|
|
|
|
|
|
|
/* записать себя в nodes + local_identity с реальным node_id и именем */ |
|
|
|
|
/* записать себя в nodes + local_identity */ |
|
|
|
|
{ |
|
|
|
|
const char* my_name = inst->name[0] ? inst->name : "Me"; |
|
|
|
|
topo_node_sqlite_node_update_verified(g_cc.db, g_cc.my_node_id, |
|
|
|
|
my_name, inst->my_keys.public_key, inst->my_ed25519_pubkey, |
|
|
|
|
(uint64_t)now_sec, (time_t)now_sec); |
|
|
|
|
sqlite3_stmt* st = NULL; |
|
|
|
|
sqlite3_prepare_v2(g_cc.db, |
|
|
|
|
"INSERT OR REPLACE INTO nodes(node_id, name, x25519_pubkey, ed25519_pubkey, created_at, online)" |
|
|
|
|
" VALUES(?,?,?,?,?,1)", -1, &st, NULL); |
|
|
|
|
if (st) { |
|
|
|
|
sqlite3_bind_int64(st, 1, (sqlite3_int64)g_cc.my_node_id); |
|
|
|
|
sqlite3_bind_text(st, 2, my_name, -1, SQLITE_STATIC); |
|
|
|
|
sqlite3_bind_blob(st, 3, inst->my_keys.public_key, 32, SQLITE_STATIC); |
|
|
|
|
sqlite3_bind_blob(st, 4, inst->my_ed25519_pubkey, 32, SQLITE_STATIC); |
|
|
|
|
sqlite3_bind_int64(st, 5, now_sec); |
|
|
|
|
sqlite3_step(st); sqlite3_finalize(st); |
|
|
|
|
} |
|
|
|
|
st = NULL; |
|
|
|
|
sqlite3_prepare_v2(g_cc.db, |
|
|
|
|
"INSERT OR REPLACE INTO local_identity(id,node_id,name,x25519_pubkey,ed25519_pubkey,created_at,updated_at)" |
|
|
|
|
" VALUES(1,?,?,?,?,?,?)", -1, &st, NULL); |
|
|
|
|
@ -268,14 +257,9 @@ void chat_core_set_my_node_id(uint64_t node_id) {
|
|
|
|
|
|
|
|
|
|
void chat_core_update_my_name(const char* name) { |
|
|
|
|
if (!g_cc.initialized || !name) return; |
|
|
|
|
sqlite3_stmt* st = NULL; |
|
|
|
|
sqlite3_prepare_v2(g_cc.db, "UPDATE nodes SET name=? WHERE node_id=?", -1, &st, NULL); |
|
|
|
|
if (st) { |
|
|
|
|
sqlite3_bind_text(st, 1, name, -1, SQLITE_STATIC); |
|
|
|
|
sqlite3_bind_int64(st, 2, (sqlite3_int64)g_cc.my_node_id); |
|
|
|
|
sqlite3_step(st); sqlite3_finalize(st); |
|
|
|
|
} |
|
|
|
|
/* update instance name for NODEINFO */ |
|
|
|
|
topo_node_sqlite_node_update_verified(g_cc.db, g_cc.my_node_id, |
|
|
|
|
name, g_cc.inst->my_keys.public_key, g_cc.inst->my_ed25519_pubkey, |
|
|
|
|
(uint64_t)ntp_time_get_seconds(g_cc.inst), 0); |
|
|
|
|
snprintf(g_cc.inst->name, sizeof(g_cc.inst->name), "%s", name); |
|
|
|
|
|
|
|
|
|
/* recompute join_sigs for all channels where I'm a member */ |
|
|
|
|
@ -660,17 +644,21 @@ void chat_core_ensure_channel_ready(const char* ch_id) {
|
|
|
|
|
char sql[512]; |
|
|
|
|
snprintf(sql, sizeof(sql), |
|
|
|
|
"CREATE TABLE IF NOT EXISTS \"%s\" (" |
|
|
|
|
" node_id INTEGER PRIMARY KEY," |
|
|
|
|
" x25519_pubkey BLOB NOT NULL," |
|
|
|
|
" ed25519_pubkey BLOB," |
|
|
|
|
" join_sig BLOB," |
|
|
|
|
" join_ts INTEGER DEFAULT 0," |
|
|
|
|
" update_sig BLOB," |
|
|
|
|
" update_ts INTEGER DEFAULT 0," |
|
|
|
|
" userinfo TEXT NOT NULL DEFAULT ''," |
|
|
|
|
" creator_sig BLOB," |
|
|
|
|
" comment TEXT," |
|
|
|
|
" joined_at INTEGER DEFAULT (unixepoch())" |
|
|
|
|
" node_id INTEGER PRIMARY KEY," /* уникальный ID узла (64-bit) */ |
|
|
|
|
" x25519_pubkey BLOB NOT NULL," /* X25519 публичный ключ (32 байта) */ |
|
|
|
|
" ed25519_pubkey BLOB," /* Ed25519 публичный ключ (32 байта) — верификация join_sig/update_sig */ |
|
|
|
|
" join_sig BLOB," /* Ed25519 подпись присоединения (PEERS_JOIN_SIG_SIZE=64).
|
|
|
|
|
signed: ch_x25519(32)||ch_ed25519(32)||node_id(8 LE)||x25519(32)||join_ts(8 LE) */ |
|
|
|
|
" join_ts INTEGER DEFAULT 0," /* NTP timestamp подписи join_sig — защита от replay */ |
|
|
|
|
" update_sig BLOB," /* Ed25519 подпись обновления userinfo (PEERS_UPDATE_SIG_SIZE=64).
|
|
|
|
|
signed: join_sig(64)||update_ts(8 LE)||userinfo(NUL-terminated) */ |
|
|
|
|
" update_ts INTEGER DEFAULT 0," /* NTP timestamp подписи update_sig */ |
|
|
|
|
" userinfo TEXT NOT NULL DEFAULT ''," /* JSON с информацией о пользователе: {"name":"<display_name>"}.
|
|
|
|
|
извлекается через json_flat_get(userinfo, "name", ...) */ |
|
|
|
|
" creator_sig BLOB," /* Ed25519 подпись создателя (PEERS_JOIN_SIG_SIZE=64).
|
|
|
|
|
в CHANNEL_INFO_RESP ставится join_sig инвайтера, иначе NULL (заглушка) */ |
|
|
|
|
" comment TEXT," /* произвольная заметка (пока не используется в логике) */ |
|
|
|
|
" joined_at INTEGER DEFAULT (unixepoch())" /* NTP timestamp добавления записи в таблицу */ |
|
|
|
|
")", tbl_peers); |
|
|
|
|
db_exec(sql); |
|
|
|
|
|
|
|
|
|
|