chatgui-android: auto_sockets=android — сокеты из конфига, лёгкое обновление без полного рестарта
- auto_sockets три-режимный: off/system/android; android берёт сокеты из [server] конфига - auto_socket_reload_config: reconcile сокетов (remove→create) по имени+addr:port, сохранение портов - etcp_create_server_socket вынесен из init_sockets; stcp_server_list_find_by_sock - instance_lite_update_sockets + JNI nativeUpdateSockets + NativeLib.updateSockets - NetworkChangeMonitor: updateSockets вместо restart; порты сохраняются при смене сети
This commit is contained in:
1 parent
c474c37284
commit
5b31a765c2
15 files changed
+266
-46
No files matched your search
@@ -333,6 +333,7 @@ class ConfigProvider(private val context: Context) {
|
||||
appendLine("db_path=$dbDir")
|
||||
appendLine("db_sync_enabled=1")
|
||||
appendLine("chatserver_enabled=1")
|
||||
appendLine("auto_sockets=android")
|
||||
appendLine()
|
||||
for (srv in servers) appendServerSection(this, srv, false)
|
||||
for (srv in commented) appendServerSection(this, srv, true)
|
||||
|
||||
@@ -44,6 +44,11 @@ object NativeLib {
|
||||
return nativeRestart(configText)
|
||||
}
|
||||
|
||||
/** Лёгкое обновление сокетов (auto_sockets=android) без полного рестарта ядра */
|
||||
fun updateSockets(configText: String): Boolean {
|
||||
return nativeUpdateSockets(configText)
|
||||
}
|
||||
|
||||
fun isReady(): Boolean = nativeIsRunning()
|
||||
|
||||
fun getMyNodeId(): Long = nativeGetMyNodeId()
|
||||
@@ -156,6 +161,7 @@ object NativeLib {
|
||||
private external fun nativeRequestInviteCandidates(channelId: String)
|
||||
private external fun nativeRequestInviteLink(channelId: String, targetNodeId: Long)
|
||||
private external fun nativeRestart(configText: String): Boolean
|
||||
private external fun nativeUpdateSockets(configText: String): Boolean
|
||||
private external fun nativePing()
|
||||
private external fun nativeIsResponsive(): Boolean
|
||||
private external fun nativeIsRunning(): Boolean
|
||||
|
||||
@@ -69,9 +69,7 @@ object NetworkChangeMonitor {
|
||||
val nowStr = now.joinToString(", ") { (n, ip) -> "$n=$ip" }
|
||||
LogManager.addLog("INFO", "NET", "network change: [$prevStr] -> [$nowStr]")
|
||||
NativeLib.notifyNetworkActive()
|
||||
val path = provider.getString("db.path") ?: ""
|
||||
val port = provider.getInt("control.port")
|
||||
NativeLib.restart(path, port, provider.buildConfigText())
|
||||
NativeLib.updateSockets(provider.buildConfigText())
|
||||
} finally {
|
||||
restarting = false
|
||||
}
|
||||
|
||||
@@ -1014,6 +1014,11 @@ void utun_bridge_restart(const char* config_text) {
|
||||
bridge_log(BLEV_ERROR, "bridge restart: instance not ready after 5s");
|
||||
}
|
||||
|
||||
void utun_bridge_update_sockets(const char* config_text) {
|
||||
bridge_log(BLEV_INFO, "bridge update_sockets: posting to instance");
|
||||
instance_lite_update_sockets(config_text);
|
||||
}
|
||||
|
||||
void utun_bridge_ping(void) {
|
||||
instance_lite_ping();
|
||||
}
|
||||
@@ -1519,6 +1524,17 @@ JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeRestart(
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeUpdateSockets(
|
||||
JNIEnv* env, jobject thiz, jstring configText) {
|
||||
(void)thiz;
|
||||
if (!configText) return JNI_FALSE;
|
||||
const char* cfg = (*env)->GetStringUTFChars(env, configText, NULL);
|
||||
if (!cfg) return JNI_FALSE;
|
||||
utun_bridge_update_sockets(cfg);
|
||||
(*env)->ReleaseStringUTFChars(env, configText, cfg);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeIsResponsive(
|
||||
JNIEnv* env, jobject thiz) {
|
||||
(void)env; (void)thiz;
|
||||
|
||||
@@ -70,6 +70,10 @@ uint64_t utun_bridge_get_my_node_id(void);
|
||||
|
||||
void utun_bridge_restart(const char* config_text);
|
||||
|
||||
/* ── Лёгкое обновление сокетов (auto_sockets=android) ── */
|
||||
|
||||
void utun_bridge_update_sockets(const char* config_text);
|
||||
|
||||
/* ── Health check ── */
|
||||
|
||||
void utun_bridge_ping(void);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "debug_config.h"
|
||||
#include "transport_layer/etcp_connections.h"
|
||||
#include "transport_layer/etcp.h"
|
||||
#include "transport_layer/auto_socket.h"
|
||||
#include "../jni_bridge/android_udp_log.h"
|
||||
#include "../jni_bridge/android_jni_bridge.h"
|
||||
#include "standby.h"
|
||||
@@ -499,9 +500,9 @@ void instance_lite_stop(void) {
|
||||
g_thread_exited = 0;
|
||||
}
|
||||
|
||||
/* Логирует текущие активные сокеты (имя=ip:port(протокол)) — состояние ДО рестарта. */
|
||||
/* Логирует текущие активные сокеты (имя=ip:port(протокол)) — состояние ДО изменения. */
|
||||
static void log_active_sockets(struct UTUN_INSTANCE* inst, const char* label) {
|
||||
if (!inst) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "restart: %s: (no instance)", label); return; }
|
||||
if (!inst) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "%s: (no instance)", label); return; }
|
||||
char buf[768] = "";
|
||||
int off = 0;
|
||||
for (struct ETCP_SOCKET* s = inst->etcp_sockets; s; s = s->next) {
|
||||
@@ -511,10 +512,10 @@ static void log_active_sockets(struct UTUN_INSTANCE* inst, const char* label) {
|
||||
off += snprintf(buf + off, sizeof(buf) - (size_t)off, " %s=%s(%s)",
|
||||
s->name, addr, s->is_tcp ? "TCP" : "UDP");
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "restart: %s:%s", label, buf[0] ? buf : " (none)");
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "%s:%s", label, buf[0] ? buf : " (none)");
|
||||
}
|
||||
|
||||
/* Логирует [server:...]/addr= секции нового конфига — состояние ПОСЛЕ рестарта. */
|
||||
/* Логирует [server:...]/addr= секции нового конфига — состояние ПОСЛЕ изменения. */
|
||||
static void log_config_servers(const char* cfg, const char* label) {
|
||||
char buf[768] = "";
|
||||
int off = 0;
|
||||
@@ -539,7 +540,7 @@ static void log_config_servers(const char* cfg, const char* label) {
|
||||
while (*p && *p != '\n') p++;
|
||||
if (*p == '\n') p++;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "restart: %s:%s", label, buf[0] ? buf : " (none)");
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "%s:%s", label, buf[0] ? buf : " (none)");
|
||||
}
|
||||
|
||||
void instance_lite_restart(const char* new_config_text) {
|
||||
@@ -549,8 +550,8 @@ void instance_lite_restart(const char* new_config_text) {
|
||||
int running = __atomic_load_n(&g_running, __ATOMIC_ACQUIRE);
|
||||
|
||||
/* Диагностика смены сети: какие сокеты/адреса были → какие будут */
|
||||
log_active_sockets(inst, "OLD sockets");
|
||||
log_config_servers(new_config_text, "NEW config");
|
||||
log_active_sockets(inst, "restart OLD sockets");
|
||||
log_config_servers(new_config_text, "restart NEW config");
|
||||
|
||||
if (!ua || !inst || !running) {
|
||||
IL_LOGI("restart: instance dead, doing hard restart via stop+start");
|
||||
@@ -568,6 +569,42 @@ void instance_lite_restart(const char* new_config_text) {
|
||||
uasync_wakeup(ua);
|
||||
}
|
||||
|
||||
/* ── Лёгкое обновление сокетов (auto_sockets=android) ── */
|
||||
|
||||
static void update_sockets_trampoline(void* arg) {
|
||||
char* cfg_text = (char*)arg;
|
||||
struct UTUN_INSTANCE* inst = (struct UTUN_INSTANCE*)__atomic_load_n(&g_inst, __ATOMIC_ACQUIRE);
|
||||
if (!inst) {
|
||||
IL_LOGE("update_sockets: instance gone in trampoline — dropping update");
|
||||
u_free(cfg_text);
|
||||
return;
|
||||
}
|
||||
struct utun_config* cfg = parse_config_from_buf(cfg_text, strlen(cfg_text), "android-update");
|
||||
u_free(cfg_text);
|
||||
if (!cfg) { IL_LOGE("update_sockets: parse_config_from_buf failed"); return; }
|
||||
auto_socket_reload_config(inst, cfg); /* cfg владеет auto_socket: servers переносятся, остальное освобождается */
|
||||
}
|
||||
|
||||
void instance_lite_update_sockets(const char* config_text) {
|
||||
if (!config_text) return;
|
||||
struct UASYNC* ua = (struct UASYNC*)__atomic_load_n(&g_ua, __ATOMIC_ACQUIRE);
|
||||
struct UTUN_INSTANCE* inst = (struct UTUN_INSTANCE*)__atomic_load_n(&g_inst, __ATOMIC_ACQUIRE);
|
||||
int running = __atomic_load_n(&g_running, __ATOMIC_ACQUIRE);
|
||||
|
||||
/* Диагностика смены сети: какие сокеты/адреса были → какие будут (без полного рестарта). */
|
||||
log_active_sockets(inst, "update OLD sockets");
|
||||
log_config_servers(config_text, "update NEW config");
|
||||
|
||||
if (!ua || !inst || !running) {
|
||||
IL_LOGE("update_sockets: instance not running (ua=%p inst=%p running=%d) — update dropped (no fallback restart)",
|
||||
(void*)ua, (void*)inst, running);
|
||||
return;
|
||||
}
|
||||
char* copy = u_strdup(config_text);
|
||||
if (!copy) { IL_LOGE("update_sockets: u_strdup failed"); return; }
|
||||
uasync_post(ua, update_sockets_trampoline, copy);
|
||||
}
|
||||
|
||||
/* ── Health check ping ── */
|
||||
|
||||
static volatile int g_ping_id = 0;
|
||||
|
||||
@@ -45,6 +45,11 @@ void instance_lite_regenerate_keys(void);
|
||||
* Posts to uasync thread — restart happens asynchronously. */
|
||||
void instance_lite_restart(const char* new_config_text);
|
||||
|
||||
/* Лёгкое обновление сокетов (auto_sockets=android): перечитывает [server] секции
|
||||
* из нового конфига и сверяет сокеты без полного рестарта. Posts to uasync thread.
|
||||
* Если ядро не запущено — только логирует ошибку и дропает вызов. */
|
||||
void instance_lite_update_sockets(const char* config_text);
|
||||
|
||||
/* Health check: posts a ping to uasync, returns responsiveness after delay */
|
||||
void instance_lite_ping(void);
|
||||
int instance_lite_is_responsive(void);
|
||||
|
||||
Reference in new issue
Block a user