diff --git a/src/utun_instance.c b/src/utun_instance.c index 6f2f9b22..c0c6b910 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -409,6 +409,8 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) { instance->running = 0; stun_nat_destroy(instance); stun_nat_forget_ports(instance); + /* Оба детектора остановить до callbacks закрываемых сервисов и транспорта. */ + if (instance->nat_det) { nat_detection_destroy(instance->nat_det); instance->nat_det = NULL; } etcp_padding_stop(&instance->padding); DEBUG_INFO(DEBUG_CATEGORY_SYS, "[DESTROY] A done — diagnose complete"); @@ -433,9 +435,6 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) { auto_socket_destroy(instance); DEBUG_INFO(DEBUG_CATEGORY_SYS, "[DESTROY] E done — socket_monitor+auto_socket"); - /* Детектор владеет таймерами и вспомогательными сокетами: остановить до групп/транспорта. */ - if (instance->nat_det) { nat_detection_destroy(instance->nat_det); instance->nat_det = NULL; } - /* Phase F: BGP */ if (instance->topo_groups) { etcp_router_unbind(instance, ETCP_RT_ID_CONN_MGR); diff --git a/tests/test_stun_nat.c b/tests/test_stun_nat.c index cbd301c0..186d4709 100644 --- a/tests/test_stun_nat.c +++ b/tests/test_stun_nat.c @@ -334,6 +334,11 @@ static void test_groups(void) { assert(!stun_nat_get_socket_result(&f.inst, &f.source, &first)); assert(second.key.address[3] == 5 && first.key.address[3] == 1 && second.evidence_id != first.evidence_id); socket_close_wrapper(duplicate.fd); f.source.next = NULL; f.original = f.source; + first = wait_result(&f); stun_nat_destroy(&f.inst); + assert(f.inst.stun_port_history && !stun_nat_init(&f.inst)); + second = wait_result(&f); + assert(second.generation != first.generation); + assert(((const struct sockaddr_in*)&second.local)->sin_port != ((const struct sockaddr_in*)&first.local)->sin_port); fixture_destroy(&f); DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS STUN groups: duplicate ports, representative removal, separate netif, policy conflict"); }