|
|
|
@ -25,7 +25,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
// Forward declarations
|
|
|
|
// Forward declarations
|
|
|
|
static uint32_t get_dest_ip(const uint8_t *packet, size_t len); |
|
|
|
static uint32_t get_dest_ip(const uint8_t *packet, size_t len); |
|
|
|
static int local_sockaddr_equal(const struct sockaddr_storage *a, const struct sockaddr_storage *b); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Global instance for signal handlers
|
|
|
|
// Global instance for signal handlers
|
|
|
|
static struct UTUN_INSTANCE *g_instance = NULL; |
|
|
|
static struct UTUN_INSTANCE *g_instance = NULL; |
|
|
|
@ -459,16 +458,6 @@ void utun_instance_diagnose_leaks(struct UTUN_INSTANCE *instance, const char *ph |
|
|
|
report.etcp_connections_count); |
|
|
|
report.etcp_connections_count); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int local_local_sockaddr_equal(const struct sockaddr_storage *a, const struct sockaddr_storage *b) { |
|
|
|
|
|
|
|
if (!a || !b || a->ss_family != b->ss_family) return 0; |
|
|
|
|
|
|
|
if (a->ss_family == AF_INET) { |
|
|
|
|
|
|
|
const struct sockaddr_in *ia = (const struct sockaddr_in *)a; |
|
|
|
|
|
|
|
const struct sockaddr_in *ib = (const struct sockaddr_in *)b; |
|
|
|
|
|
|
|
return ia->sin_addr.s_addr == ib->sin_addr.s_addr && ia->sin_port == ib->sin_port; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0; // IPv6 stub
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Variant B: selective reload. Compares settings for [server:], [client:], link=. Unchanged untouched (no close, no timers, no queues). Changed/deleted: target only that object. New: add. Routing/fw always. BGP self-restarts. */ |
|
|
|
/* Variant B: selective reload. Compares settings for [server:], [client:], link=. Unchanged untouched (no close, no timers, no queues). Changed/deleted: target only that object. New: add. Routing/fw always. BGP self-restarts. */ |
|
|
|
struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struct UASYNC *ua, const char *config_file) { |
|
|
|
struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struct UASYNC *ua, const char *config_file) { |
|
|
|
if (!instance || !ua || !config_file) { |
|
|
|
if (!instance || !ua || !config_file) { |
|
|
|
@ -482,6 +471,23 @@ struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struc |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to parse new config"); |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to parse new config"); |
|
|
|
return instance; |
|
|
|
return instance; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reset + apply debug categories from [debug] section (always, for partial and full paths).
|
|
|
|
|
|
|
|
// Mirrors utun_instance_create exactly. Reset ensures removed categories fall back to global.
|
|
|
|
|
|
|
|
for (int i = 0; i < DEBUG_CATEGORY_COUNT; i++) { |
|
|
|
|
|
|
|
g_debug_config.category_levels[i] = DEBUG_LEVEL_NONE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (new_config->global.debug_level[0]) { |
|
|
|
|
|
|
|
debug_apply_global_level(new_config->global.debug_level); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < new_config->global.debug_levels.count; i++) { |
|
|
|
|
|
|
|
debug_apply_category_config( |
|
|
|
|
|
|
|
new_config->global.debug_levels.category[i], |
|
|
|
|
|
|
|
new_config->global.debug_levels.level[i] |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Applied [debug] section (%d categories)", new_config->global.debug_levels.count); |
|
|
|
|
|
|
|
|
|
|
|
int needs_full = 0; |
|
|
|
int needs_full = 0; |
|
|
|
if (strcmp(instance->config->global.my_public_key_hex, new_config->global.my_public_key_hex) != 0 || |
|
|
|
if (strcmp(instance->config->global.my_public_key_hex, new_config->global.my_public_key_hex) != 0 || |
|
|
|
strcmp(instance->config->global.my_private_key_hex, new_config->global.my_private_key_hex) != 0 || |
|
|
|
strcmp(instance->config->global.my_private_key_hex, new_config->global.my_private_key_hex) != 0 || |
|
|
|
@ -596,10 +602,10 @@ struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struc |
|
|
|
fw_free(&instance->fw); |
|
|
|
fw_free(&instance->fw); |
|
|
|
fw_init(&instance->fw); |
|
|
|
fw_init(&instance->fw); |
|
|
|
fw_load_rules(&instance->fw, &new_config->global); |
|
|
|
fw_load_rules(&instance->fw, &new_config->global); |
|
|
|
routing_destroy(instance); |
|
|
|
// routing_destroy(instance); // commented per request - BGP self-restarts on conn events
|
|
|
|
routing_create(instance); |
|
|
|
// routing_create(instance); // commented per request
|
|
|
|
if (instance->config) free_config(instance->config); |
|
|
|
if (instance->config) free_config(instance->config); |
|
|
|
instance->config = new_config; |
|
|
|
instance->config = new_config; |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Selective partial reload completed (only changed updated, unchanged untouched)"); |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Selective partial reload completed (only changed updated, unchanged untouched, [debug] applied)"); |
|
|
|
return instance; |
|
|
|
return instance; |
|
|
|
} |
|
|
|
} |
|
|
|
|