diff --git a/src/routing_layer/topo_group.c b/src/routing_layer/topo_group.c index fd52e80f..c28e4b9b 100644 --- a/src/routing_layer/topo_group.c +++ b/src/routing_layer/topo_group.c @@ -374,7 +374,8 @@ struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { if (instance->config && instance->config->global.db_path[0]) { char db_file[512]; snprintf(db_file, sizeof(db_file), "%s/chats.db", instance->config->global.db_path); - int rc = sqlite3_open(db_file, &instance->topo_sqlite_db); + int rc = sqlite3_open_v2(db_file, &instance->topo_sqlite_db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL); if (rc == SQLITE_OK && instance->topo_sqlite_db) { sqlite3_exec(instance->topo_sqlite_db, "PRAGMA journal_mode=WAL", NULL, NULL, NULL); sqlite3_exec(instance->topo_sqlite_db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); diff --git a/tools/chatgui/transport/utun_node.cpp b/tools/chatgui/transport/utun_node.cpp index a77594f8..443b8fcd 100644 --- a/tools/chatgui/transport/utun_node.cpp +++ b/tools/chatgui/transport/utun_node.cpp @@ -211,9 +211,25 @@ void UtunNode::runLoop() { } m_ua = ua; - m_instance = utun_instance_create(ua, m_configPath.toUtf8().constData()); + /* Читаем конфиг и выставляем db_path ДО создания инстанса, чтобы topo_groups_init + * (внутри utun_instance_create_from_config) открыл общую SQLite-БД раньше auto_socket_init — + * иначе auto_socket не сможет сохранить/переиспользовать порты (БД ещё не открыта). */ + struct utun_config* cfg = parse_config(m_configPath.toUtf8().constData()); + if (!cfg) { + QMetaObject::invokeMethod(this, [this] { emit error("parse_config failed"); }); + uasync_destroy(ua, 0); + m_ua = nullptr; + g_currentNode = nullptr; + return; + } + cfg->global.db_sync_enabled = 1; + if (!m_dbPath.isEmpty()) + snprintf(cfg->global.db_path, sizeof(cfg->global.db_path), "%s", m_dbPath.toUtf8().constData()); + + m_instance = utun_instance_create_from_config(ua, cfg); if (!m_instance) { - QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_create failed"); }); + free_config(cfg); + QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_create_from_config failed"); }); uasync_destroy(ua, 0); m_ua = nullptr; g_currentNode = nullptr; @@ -222,33 +238,6 @@ void UtunNode::runLoop() { m_instance->test_user_ptr = this; - /* enable db_sync for chat message P2P sync */ - m_instance->config->global.db_sync_enabled = 1; - if (!m_dbPath.isEmpty()) - snprintf(m_instance->config->global.db_path, sizeof(m_instance->config->global.db_path), - "%s", m_dbPath.toUtf8().constData()); - - /* topo_groups_init did not open topo_sqlite_db because db_path was empty at that time. - * Open the single shared SQLite connection here with FULLMUTEX (GUI reads from another thread). - * db_sync_init and chat_core_init will reuse this handle. */ - if (m_instance->config->global.db_path[0] && !m_instance->topo_sqlite_db) { - char db_file[512]; - snprintf(db_file, sizeof(db_file), "%s/chats.db", m_instance->config->global.db_path); - int rc = sqlite3_open_v2(db_file, &m_instance->topo_sqlite_db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL); - if (rc == SQLITE_OK && m_instance->topo_sqlite_db) { - sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA journal_mode=WAL", NULL, NULL, NULL); - sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); - sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA synchronous=NORMAL", NULL, NULL, NULL); - sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA wal_autocheckpoint=10000", NULL, NULL, NULL); - topo_node_sqlite_init(m_instance->topo_sqlite_db); - DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "SQLite (shared): %s db=%p", db_file, (void*)m_instance->topo_sqlite_db); - } else { - DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "SQLite open failed: %s rc=%d", db_file, rc); - if (m_instance->topo_sqlite_db) { sqlite3_close(m_instance->topo_sqlite_db); m_instance->topo_sqlite_db = NULL; } - } - } - /* set ua for gui_bridge before init, so GUI can post */ gui_bridge_set_uasync(ua);