timer_close_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = (isc_nmsocket_t *)uv_handle_get_data(handle);
INSIST(VALID_NMSOCK(sock));
+ atomic_store(&sock->closed, true);
+ tcpdns_close_direct(sock);
}
static void
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
- tcpdns_close_direct(sock);
+ /* Close the TCP connection, it's closing should fire 'our' closing */
+ isc_nmhandle_unref(sock->outerhandle);
+ sock->outerhandle = NULL;
}
/*
dnssock->extrahandlesize = dnslistensock->extrahandlesize;
isc__nmsocket_attach(dnslistensock, &dnssock->listener);
+ isc__nmsocket_attach(dnssock, &dnssock->self);
+
dnssock->outerhandle = handle;
isc_nmhandle_ref(dnssock->outerhandle);
dnssock->timer_initialized = true;
uv_timer_start(&dnssock->timer, dnstcp_readtimeout,
dnssock->read_timeout, 0);
-
isc_nmhandle_ref(handle);
result = isc_nm_read(handle, dnslisten_readcb, dnssock);
if (result != ISC_R_SUCCESS) {
isc_nmhandle_unref(handle);
}
+ isc__nmsocket_detach(&dnssock);
}
/*
dnssock->buf_len);
}
- /*
- * dnssock is now attached to dnshandle
- */
- isc__nmsocket_detach(&dnssock);
-
*handlep = dnshandle;
return (ISC_R_SUCCESS);
}
if (region == NULL) {
/* Connection closed */
- isc__nm_tcpdns_close(dnssock);
+ isc_nmhandle_unref(handle);
+ if (dnssock->self != NULL) {
+ isc__nmsocket_detach(&dnssock->self);
+ }
return;
}
isc_mem_attach(sock->mgr->mctx, &t->mctx);
t->orighandle = handle;
isc_nmhandle_ref(t->orighandle);
+ isc_nmhandle_ref(t->handle);
t->region = (isc_region_t){ .base = isc_mem_get(t->mctx,
region->length + 2),
static void
tcpdns_close_direct(isc_nmsocket_t *sock) {
REQUIRE(sock->tid == isc_nm_tid());
+
/* We don't need atomics here, it's all in single network thread */
if (sock->timer_initialized) {
/*
sock->timer_initialized = false;
uv_timer_stop(&sock->timer);
uv_close((uv_handle_t *)&sock->timer, timer_close_cb);
+ } else if (sock->self != NULL) {
+ isc__nmsocket_detach(&sock->self);
} else {
/*
* At this point we're certain that there are no external