#ifndef ETCP_CONNECT_H #define ETCP_CONNECT_H struct UTUN_INSTANCE; struct ETCP_CONN; /* * ============================================================================ * Штатное закрытие исходящих соединений (etcp_connect) * ============================================================================ * * Исходящее соединение создаётся через etcp_connect(): * etcp_connect(inst, node, cb, arg, flags) * ├── etcp_connection_create(inst, NULL) → conn (добавляется в inst->connections) * ├── ctx = u_calloc(...); ctx->conn = conn * ├── для TCP: ctx->tcp_link = stcp_link_connect(...) * │ conn->transport_link = ctx->tcp_link * └── ctx->next = inst->pending_connects; inst->pending_connects = ctx * * Пути завершения: * * 1. Таймаут установки (connect_initial_timeout_cb): * stcp_link_close(tcp_link) → etcp_connection_close(conn) → connect_cancel(ctx) * * 2. Settle таймаут (connect_settle_timeout_cb): * stcp_link_close(tcp_link) (если !tcp_ready) → connect_cancel(ctx) * * 3. Штатное закрытие через utun_instance_destroy(): * utun_instance_destroy(inst) * ├── etcp_connection_close(conn) для всех conn * │ Фаза 1 (detach): закрыть линки, удалить из inst->connections, state=2 * │ Фаза 2 (deferred): uasync_call_soon(ua, conn, etcp_connection_free_deferred) * │ * ├── while (immediate_queue_head) uasync_poll(ua, 0) // ждём завершения * │ └── etcp_connection_free_resources(conn) * │ ├── drain_and_free_queue(*) * │ ├── etcp_connect_cancel_for_conn(inst, conn) ← эта функция * │ └── u_free(etcp) * │ * └── memory_pool_destroy(pkt/ack/data) // теперь безопасно * * Закрытие tcp_link НЕ входит в ответственность cancel-функций. * tcp_link закрывается ДО вызова connect_cancel / cancel_for_conn * (в путях 1 и 2 явно; в пути 3 tcp_link закрыт ранее или утекает — pre-existing). * * ============================================================================ */ /* * ============================================================================ * etcp_connect_cancel_for_conn() * ============================================================================ * * Аналог приватного connect_cancel(), но ищет ETCP_CONNECT ctx по совпадению * ctx->conn == conn (а не по указателю на ctx). * * Делает: * 1. Удаляет ctx из inst->pending_connects * 2. ctx->done = 1; ctx->conn = NULL * 3. uasync_cancel_timeout(initial_timer / settle_timer) * 4. u_free(ctx) * * НЕ закрывает ctx->tcp_link (чужая ответственность). * * Вызывается ТОЛЬКО из etcp_connection_free_resources (фаза 2 deferred cleanup). * НЕ вызывать из mainloop / uasync_poll callbacks — conn уже может быть в state=2. * * ============================================================================ */ void etcp_connect_cancel_for_conn(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn); #endif