Retain NCD entry and transport through synchronous CLOSE callbacks
This commit is contained in:
1 parent
88004f11ca
commit
702389d8d9
1 file changed
+11
-6
@@ -907,22 +907,24 @@ int node_conn_direct_open_node(struct UTUN_INSTANCE* inst, uint64_t node_id,
|
||||
static void ncd_handle_close(struct NODE_CONN_DIRECT* h, int force) {
|
||||
if (!h || h->closed) return;
|
||||
struct ncd_entry* entry = h->entry;
|
||||
entry->active_calls++;
|
||||
struct ETCP_CONN* conn = entry->conn;
|
||||
int held = conn && etcp_conn_ref_take(conn) == 0;
|
||||
ncd_cancel_deliver_up(h, entry->ua);
|
||||
h->closed = 1; h->cb = NULL; h->cb_arg = NULL;
|
||||
entry->handle_count--;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_NCD, "[ncd] handle close node=%016llx remaining=%d force=%d",
|
||||
(unsigned long long)entry->node_id, entry->handle_count, force);
|
||||
if (entry->handle_count || entry->closed) { ncd_collect(entry); return; }
|
||||
struct ETCP_CONN* conn = entry->conn;
|
||||
if (entry->handle_count || entry->closed) goto done;
|
||||
if (force || !conn || conn->close_requested || conn->state == 2 || entry->timed_out || (!conn->state && !conn->links_up)) {
|
||||
ncd_finish(entry, 1); return;
|
||||
ncd_finish(entry, 1); goto done;
|
||||
}
|
||||
if (!conn->links_up) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_NCD, "[ncd] last handle released while DOWN, retaining until ETCP timeout node=%016llx",
|
||||
(unsigned long long)entry->node_id);
|
||||
ncd_finish(entry, 0);
|
||||
if (etcp_conn_schedule_down_close(conn) < 0) etcp_connection_close(conn);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
if (entry->connect_timer) { uasync_cancel_timeout(entry->ua, entry->connect_timer); entry->connect_timer = NULL; }
|
||||
conn->fin_wait = 1; conn->fin_wait_clear_cb = ncd_fin_wait_cancelled; conn->fin_wait_clear_arg = entry;
|
||||
@@ -935,6 +937,7 @@ static void ncd_handle_close(struct NODE_CONN_DIRECT* h, int force) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_NCD, "[ncd] CLOSE send failed"); queue_dgram_free(e); queue_entry_free(e);
|
||||
}
|
||||
}
|
||||
if (entry->closed || conn->close_requested || !conn->fin_wait || entry->handle_count) goto done;
|
||||
uint64_t now = get_time_tb(), wait_tb = NCD_FIN_WAIT_TIMEOUT_TB;
|
||||
for (struct ETCP_LINK* link = conn->links; link; link = link->next) {
|
||||
if (!link->link_status || (!link->ka_my_sleeping && !link->ka_peer_sleeping)) continue;
|
||||
@@ -944,10 +947,12 @@ static void ncd_handle_close(struct NODE_CONN_DIRECT* h, int force) {
|
||||
entry->fin_wait_timer = uasync_set_timeout(entry->ua, delay, entry, ncd_fin_wait_timeout_cb, "ncd_fin_wait");
|
||||
if (!entry->fin_wait_timer) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_NCD, "[ncd] cannot schedule FIN_WAIT node=%016llx", (unsigned long long)entry->node_id);
|
||||
ncd_finish(entry, 1); return;
|
||||
ncd_finish(entry, 1); goto done;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_NCD, "[ncd] fin_wait node=%016llx timeout_ms=%d", (unsigned long long)entry->node_id, delay / 10);
|
||||
ncd_collect(entry);
|
||||
done:
|
||||
entry->active_calls--; ncd_collect(entry);
|
||||
if (held) etcp_conn_ref_free(conn);
|
||||
}
|
||||
void node_conn_direct_close(struct NODE_CONN_DIRECT* h) { ncd_handle_close(h, 0); }
|
||||
void node_conn_direct_force_close(struct NODE_CONN_DIRECT* h) { ncd_handle_close(h, 1); }
|
||||
|
||||
Reference in new issue
Block a user