Restart instances with duplicate server names to preserve all endpoints

This commit is contained in:
evgeny committed 2026-10-26 09:08:42 +01:00
1 parent a58f3516ab
commit 0d6d1aeb19
2 files changed
+17

No files matched your search

+11
View File
@@ -1031,6 +1031,16 @@ static int instance_servers_equal(const struct CFG_SERVER* a, const struct CFG_S
return !a && !b;
}
/* Parser сохраняет повторные server-секции отдельно; для них поимённый partial reload неоднозначен. */
static int instance_server_names_unique(const struct CFG_SERVER* servers) {
for (const struct CFG_SERVER* a = servers; a; a = a->next)
for (const struct CFG_SERVER* b = a->next; b; b = b->next)
if (!strcmp(a->name, b->name)) {
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "duplicate server name '%s': reload requires full restart", a->name); return 0;
}
return 1;
}
static int instance_routes_equal(const struct CFG_ROUTE_ENTRY* a, const struct CFG_ROUTE_ENTRY* b) {
while (a && b) {
if (a->netmask != b->netmask || a->ip.family != b->ip.family ||
@@ -1098,6 +1108,7 @@ struct UTUN_INSTANCE* utun_instance_reload(struct UTUN_INSTANCE* instance, struc
struct utun_config* previous = instance->config;
int servers_changed = !instance_servers_equal(previous->servers, next->servers);
int full = !instance_globals_equal(&previous->global, &next->global) ||
!instance_server_names_unique(previous->servers) || !instance_server_names_unique(next->servers) ||
!instance_routes_equal(previous->route_subnets, next->route_subnets) ||
!instance_routes_equal(previous->my_subnets, next->my_subnets) ||
(next->global.auto_sockets != CFG_AUTO_SOCKETS_OFF && servers_changed);
+6
View File
@@ -149,6 +149,12 @@ static void test_reload(struct UASYNC* ua) {
write_config(path, "same", one, "");
assert(utun_instance_reload(inst, ua, path) == inst && endpoint_count(inst) == 1);
assert(!endpoint(inst, "tcp")->is_tcp && !stcp_server_list_count(inst));
const char* duplicates = "[server:shared]\naddr=127.0.0.1:0\ntype=private\n"
"[server:shared]\naddr=127.0.0.1:0\ntype=private\n";
write_config(path, "same", duplicates, "");
inst = utun_instance_reload(inst, ua, path); assert(inst && inst->core_started && endpoint_count(inst) == 2);
write_config(path, "same", one, "");
inst = utun_instance_reload(inst, ua, path); assert(inst && inst->core_started && endpoint_count(inst) == 1);
sqlite3_stmt* statement = NULL;
assert(sqlite3_prepare_v2(inst->topo_sqlite_db, "SELECT 1", -1, &statement, NULL) == SQLITE_OK);
utun_instance_stop(inst); assert(!inst->running);