mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
netmgr fixes needed for dispatch
- The read timer must always be stopped when reading stops. - Read callbacks can now call isc_nm_read() again in TCP, TCPDNS and TLSDNS; previously this caused an assertion. - The wrong failure code could be sent after a UDP recv failure because the if statements were in the wrong order. the check for a NULL address needs to be after the check for an error code, otherwise the result will always be set to ISC_R_EOF. - When aborting a read or connect because the netmgr is shutting down, use ISC_R_SHUTTINGDOWN. (ISC_R_CANCELED is now reserved for when the read has been canceled by the caller.) - A new function isc_nmhandle_timer_running() has been added enabling a callback to check whether the timer has been reset after processing a timeout. - Incidental netmgr fix: always use isc__nm_closing() instead of referencing sock->mgr->closing directly - Corrected a few comments that used outdated function names.
This commit is contained in:
parent
d9e1ad9e37
commit
9ee60e7a17
@ -222,13 +222,6 @@ http_session_active(isc_nm_http_session_t *session) {
|
||||
return (!session->closed && !session->closing);
|
||||
}
|
||||
|
||||
static bool
|
||||
inactive(isc_nmsocket_t *sock) {
|
||||
return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
|
||||
atomic_load(&sock->mgr->closing) ||
|
||||
(sock->server != NULL && !isc__nmsocket_active(sock->server)));
|
||||
}
|
||||
|
||||
static void *
|
||||
http_malloc(size_t sz, isc_mem_t *mctx) {
|
||||
return (isc_mem_allocate(mctx, sz));
|
||||
@ -1461,7 +1454,7 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
}
|
||||
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, ISC_R_CANCELED, true);
|
||||
isc__nm_connectcb(sock, req, ISC_R_SHUTTINGDOWN, true);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
isc__nmsocket_detach(&sock);
|
||||
return;
|
||||
@ -2154,7 +2147,8 @@ server_httpsend(isc_nmhandle_t *handle, isc_nmsocket_t *sock,
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nm_cb_t cb = req->cb.send;
|
||||
void *cbarg = req->cbarg;
|
||||
if (inactive(sock) || !http_session_active(handle->httpsession)) {
|
||||
if (isc__nmsocket_closing(sock) ||
|
||||
!http_session_active(handle->httpsession)) {
|
||||
failed_send_cb(sock, req, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
@ -2381,7 +2375,7 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
* function gets invoked, so we need to do extra sanity checks to
|
||||
* detect this case.
|
||||
*/
|
||||
if (inactive(handle->sock) || httpserver == NULL) {
|
||||
if (isc__nmsocket_closing(handle->sock) || httpserver == NULL) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
@ -2393,8 +2387,9 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
REQUIRE(VALID_NMSOCK(httplistensock));
|
||||
INSIST(httplistensock == httpserver);
|
||||
|
||||
if (inactive(httplistensock) ||
|
||||
!atomic_load(&httplistensock->listening)) {
|
||||
if (isc__nmsocket_closing(httplistensock) ||
|
||||
!atomic_load(&httplistensock->listening))
|
||||
{
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
@ -3041,7 +3036,7 @@ isc__nm_http_cleartimeout(isc_nmhandle_t *handle) {
|
||||
REQUIRE(handle->sock->type == isc_nm_httpsocket);
|
||||
|
||||
sock = handle->sock;
|
||||
if (sock->h2.session != NULL && sock->h2.session->handle) {
|
||||
if (sock->h2.session != NULL && sock->h2.session->handle != NULL) {
|
||||
INSIST(VALID_HTTP2_SESSION(sock->h2.session));
|
||||
INSIST(VALID_NMHANDLE(sock->h2.session->handle));
|
||||
isc_nmhandle_cleartimeout(sock->h2.session->handle);
|
||||
@ -3057,7 +3052,7 @@ isc__nm_http_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
|
||||
REQUIRE(handle->sock->type == isc_nm_httpsocket);
|
||||
|
||||
sock = handle->sock;
|
||||
if (sock->h2.session != NULL && sock->h2.session->handle) {
|
||||
if (sock->h2.session != NULL && sock->h2.session->handle != NULL) {
|
||||
INSIST(VALID_HTTP2_SESSION(sock->h2.session));
|
||||
INSIST(VALID_NMHANDLE(sock->h2.session->handle));
|
||||
isc_nmhandle_settimeout(sock->h2.session->handle, timeout);
|
||||
|
@ -976,8 +976,8 @@ struct isc_nmsocket {
|
||||
atomic_bool listening;
|
||||
atomic_bool connecting;
|
||||
atomic_bool connected;
|
||||
bool accepting;
|
||||
bool reading;
|
||||
atomic_bool accepting;
|
||||
atomic_bool reading;
|
||||
isc_refcount_t references;
|
||||
|
||||
/*%
|
||||
|
@ -1915,7 +1915,7 @@ isc__nm_failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
|
||||
void
|
||||
isc__nm_failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
||||
REQUIRE(sock->accepting);
|
||||
REQUIRE(atomic_load(&sock->accepting));
|
||||
REQUIRE(sock->server);
|
||||
|
||||
/*
|
||||
@ -1929,7 +1929,7 @@ isc__nm_failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
||||
|
||||
isc__nmsocket_detach(&sock->server);
|
||||
|
||||
sock->accepting = false;
|
||||
atomic_store(&sock->accepting, false);
|
||||
|
||||
switch (eresult) {
|
||||
case ISC_R_NOTCONNECTED:
|
||||
@ -2024,11 +2024,13 @@ isc__nmsocket_readtimeout_cb(uv_timer_t *timer) {
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->reading);
|
||||
REQUIRE(atomic_load(&sock->reading));
|
||||
|
||||
if (atomic_load(&sock->client)) {
|
||||
uv_timer_stop(timer);
|
||||
|
||||
sock->recv_read = false;
|
||||
|
||||
if (sock->recv_cb != NULL) {
|
||||
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
||||
isc__nm_readcb(sock, req, ISC_R_TIMEDOUT);
|
||||
@ -2172,7 +2174,7 @@ void
|
||||
isc__nm_start_reading(isc_nmsocket_t *sock) {
|
||||
int r;
|
||||
|
||||
if (sock->reading) {
|
||||
if (atomic_load(&sock->reading)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2198,14 +2200,14 @@ isc__nm_start_reading(isc_nmsocket_t *sock) {
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
RUNTIME_CHECK(r == 0);
|
||||
sock->reading = true;
|
||||
atomic_store(&sock->reading, true);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_stop_reading(isc_nmsocket_t *sock) {
|
||||
int r;
|
||||
|
||||
if (!sock->reading) {
|
||||
if (!atomic_load(&sock->reading)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2223,7 +2225,7 @@ isc__nm_stop_reading(isc_nmsocket_t *sock) {
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
RUNTIME_CHECK(r == 0);
|
||||
sock->reading = false;
|
||||
atomic_store(&sock->reading, false);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2234,7 +2236,7 @@ isc__nm_closing(isc_nmsocket_t *sock) {
|
||||
bool
|
||||
isc__nmsocket_closing(isc_nmsocket_t *sock) {
|
||||
return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
|
||||
atomic_load(&sock->mgr->closing) ||
|
||||
isc__nm_closing(sock) ||
|
||||
(sock->server != NULL && !isc__nmsocket_active(sock->server)));
|
||||
}
|
||||
|
||||
@ -2260,8 +2262,8 @@ processbuffer(isc_nmsocket_t *sock) {
|
||||
* Stop reading if this is a client socket, or if the server socket
|
||||
* has been set to sequential mode, or the number of queries we are
|
||||
* processing simultaneously has reached the clients-per-connection
|
||||
* limit. In this case we'll be called again by resume_processing()
|
||||
* later.
|
||||
* limit. In this case we'll be called again later by
|
||||
* isc__nm_resume_processing().
|
||||
*/
|
||||
void
|
||||
isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
||||
@ -3123,6 +3125,45 @@ isc__nm_socket_disable_pmtud(uv_os_sock_t fd, sa_family_t sa_family) {
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_checkaddr(const isc_sockaddr_t *addr, isc_socktype_t type) {
|
||||
int proto, pf, addrlen, fd, r;
|
||||
|
||||
REQUIRE(addr != NULL);
|
||||
|
||||
switch (type) {
|
||||
case isc_socktype_tcp:
|
||||
proto = SOCK_STREAM;
|
||||
break;
|
||||
case isc_socktype_udp:
|
||||
proto = SOCK_DGRAM;
|
||||
break;
|
||||
default:
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
pf = isc_sockaddr_pf(addr);
|
||||
if (pf == AF_INET) {
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
|
||||
fd = socket(pf, proto, 0);
|
||||
if (fd < 0) {
|
||||
return (isc_errno_toresult(errno));
|
||||
}
|
||||
|
||||
r = bind(fd, (const struct sockaddr *)&addr->type.sa, addrlen);
|
||||
if (r < 0) {
|
||||
close(fd);
|
||||
return (isc_errno_toresult(errno));
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
#if defined(TCP_CONNECTIONTIMEOUT)
|
||||
#define TIMEOUT_TYPE int
|
||||
#define TIMEOUT_DIV 1000
|
||||
@ -3304,11 +3345,10 @@ isc_nm_sequential(isc_nmhandle_t *handle) {
|
||||
* We don't want pipelining on this connection. That means
|
||||
* that we need to pause after reading each request, and
|
||||
* resume only after the request has been processed. This
|
||||
* is done in resume_processing(), which is the socket's
|
||||
* closehandle_cb callback, called whenever a handle
|
||||
* is done in isc__nm_resume_processing(), which is the
|
||||
* socket's closehandle_cb callback, called whenever a handle
|
||||
* is released.
|
||||
*/
|
||||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
atomic_store(&sock->sequential, true);
|
||||
@ -3414,7 +3454,7 @@ nmsocket_dump(isc_nmsocket_t *sock) {
|
||||
atomic_load(&sock->closing) ? " closing" : "",
|
||||
atomic_load(&sock->destroying) ? " destroying" : "",
|
||||
atomic_load(&sock->connecting) ? " connecting" : "",
|
||||
sock->accepting ? " accepting" : "");
|
||||
atomic_load(&sock->accepting) ? " accepting" : "");
|
||||
fprintf(stderr, "Created by:\n");
|
||||
isc_backtrace_symbols_fd(sock->backtrace, sock->backtrace_size,
|
||||
STDERR_FILENO);
|
||||
|
@ -86,7 +86,7 @@ stop_tcp_child(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
||||
REQUIRE(sock->accepting);
|
||||
REQUIRE(atomic_load(&sock->accepting));
|
||||
REQUIRE(sock->server);
|
||||
|
||||
/*
|
||||
@ -100,7 +100,7 @@ failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
||||
|
||||
isc__nmsocket_detach(&sock->server);
|
||||
|
||||
sock->accepting = false;
|
||||
atomic_store(&sock->accepting, false);
|
||||
|
||||
switch (eresult) {
|
||||
case ISC_R_NOTCONNECTED:
|
||||
@ -250,7 +250,11 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
return;
|
||||
} else if (isc__nmsocket_closing(sock)) {
|
||||
/* Socket was closed midflight by isc__nm_tcp_shutdown() */
|
||||
/* Network manager shutting down */
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
} else if (isc__nmsocket_closing(sock)) {
|
||||
/* Connection canceled */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
} else if (status == UV_ETIMEDOUT) {
|
||||
@ -732,8 +736,6 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
|
||||
REQUIRE(sock->type == isc_nm_tcpsocket);
|
||||
REQUIRE(sock->statichandle == handle);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(!sock->recv_read);
|
||||
|
||||
sock->recv_cb = cb;
|
||||
sock->recv_cbarg = cbarg;
|
||||
@ -770,7 +772,7 @@ isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
UNUSED(worker);
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_tcp_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
@ -833,7 +835,7 @@ isc__nm_tcp_resumeread(isc_nmhandle_t *handle) {
|
||||
}
|
||||
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
sock->reading = true;
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_tcp_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
@ -856,7 +858,7 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->reading);
|
||||
REQUIRE(atomic_load(&sock->reading));
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
@ -895,7 +897,7 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
||||
isc__nm_readcb(sock, req, ISC_R_SUCCESS);
|
||||
|
||||
/* The readcb could have paused the reading */
|
||||
if (sock->reading) {
|
||||
if (atomic_load(&sock->reading)) {
|
||||
/* The timer will be updated */
|
||||
isc__nmsocket_timer_restart(sock);
|
||||
}
|
||||
@ -973,7 +975,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
||||
csock->recv_cb = ssock->recv_cb;
|
||||
csock->recv_cbarg = ssock->recv_cbarg;
|
||||
csock->quota = quota;
|
||||
csock->accepting = true;
|
||||
atomic_init(&csock->accepting, true);
|
||||
|
||||
worker = &csock->mgr->workers[isc_nm_tid()];
|
||||
|
||||
@ -1024,7 +1026,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
csock->accepting = false;
|
||||
atomic_store(&csock->accepting, false);
|
||||
|
||||
isc__nm_incstats(csock->mgr, csock->statsindex[STATID_ACCEPT]);
|
||||
|
||||
@ -1354,7 +1356,7 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->accepting) {
|
||||
if (atomic_load(&sock->accepting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1366,7 +1368,11 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
|
||||
}
|
||||
|
||||
if (sock->statichandle != NULL) {
|
||||
isc__nm_tcp_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
if (isc__nm_closing(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_SHUTTINGDOWN, false);
|
||||
} else {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
RUNTIME_CHECK(r == 0);
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -217,7 +217,11 @@ tcpdns_connect_cb(uv_connect_t *uvreq, int status) {
|
||||
REQUIRE(VALID_NMHANDLE(req->handle));
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
/* Socket was closed midflight by isc__nm_tcpdns_shutdown() */
|
||||
/* Network manager shutting down */
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
} else if (isc__nmsocket_closing(sock)) {
|
||||
/* Connection canceled */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
} else if (status == UV_ETIMEDOUT) {
|
||||
@ -690,8 +694,6 @@ isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
|
||||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
REQUIRE(sock->statichandle == handle);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(!sock->recv_read);
|
||||
|
||||
sock->recv_cb = cb;
|
||||
sock->recv_cbarg = cbarg;
|
||||
@ -729,7 +731,7 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
@ -780,8 +782,8 @@ isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
|
||||
/*
|
||||
* We need to launch the resume_processing after the buffer has
|
||||
* been consumed, thus we need to delay the detaching the handle.
|
||||
* We need to launch isc__nm_resume_processing() after the buffer
|
||||
* has been consumed, thus we must delay detaching the handle.
|
||||
*/
|
||||
isc_nmhandle_attach(req->handle, &handle);
|
||||
|
||||
@ -800,9 +802,10 @@ isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock) {
|
||||
sock->recv_read = false;
|
||||
|
||||
/*
|
||||
* The assertion failure here means that there's a errnoneous extra
|
||||
* nmhandle detach happening in the callback and resume_processing gets
|
||||
* called while we are still processing the buffer.
|
||||
* An assertion failure here means that there's an erroneous
|
||||
* extra nmhandle detach happening in the callback and
|
||||
* isc__nm_resume_processing() is called while we're
|
||||
* processing the buffer.
|
||||
*/
|
||||
REQUIRE(sock->processing == false);
|
||||
sock->processing = true;
|
||||
@ -829,7 +832,7 @@ isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->reading);
|
||||
REQUIRE(atomic_load(&sock->reading));
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
@ -949,7 +952,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
||||
csock->recv_cb = ssock->recv_cb;
|
||||
csock->recv_cbarg = ssock->recv_cbarg;
|
||||
csock->quota = quota;
|
||||
csock->accepting = true;
|
||||
atomic_init(&csock->accepting, true);
|
||||
|
||||
worker = &csock->mgr->workers[csock->tid];
|
||||
|
||||
@ -1007,7 +1010,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
csock->accepting = false;
|
||||
atomic_store(&csock->accepting, false);
|
||||
|
||||
isc__nm_incstats(csock->mgr, csock->statsindex[STATID_ACCEPT]);
|
||||
|
||||
@ -1056,13 +1059,15 @@ failure:
|
||||
void
|
||||
isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
isc_nm_cb_t cb, void *cbarg) {
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||
|
||||
isc_nmsocket_t *sock = handle->sock;
|
||||
isc__netievent_tcpdnssend_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *uvreq = NULL;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
||||
sock = handle->sock;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
|
||||
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
@ -1107,24 +1112,26 @@ tcpdns_send_cb(uv_write_t *req, int status) {
|
||||
*/
|
||||
void
|
||||
isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc_result_t result;
|
||||
isc__netievent_tcpdnssend_t *ievent =
|
||||
(isc__netievent_tcpdnssend_t *)ev0;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc__nm_uvreq_t *uvreq = NULL;
|
||||
int r, nbufs = 2;
|
||||
|
||||
UNUSED(worker);
|
||||
|
||||
REQUIRE(VALID_UVREQ(ievent->req));
|
||||
REQUIRE(VALID_NMSOCK(ievent->sock));
|
||||
REQUIRE(ievent->sock->type == isc_nm_tcpdnssocket);
|
||||
REQUIRE(ievent->sock->tid == isc_nm_tid());
|
||||
|
||||
isc_result_t result;
|
||||
isc_nmsocket_t *sock = ievent->sock;
|
||||
isc__nm_uvreq_t *uvreq = ievent->req;
|
||||
sock = ievent->sock;
|
||||
uvreq = ievent->req;
|
||||
|
||||
uv_buf_t bufs[2] = { { .base = uvreq->tcplen, .len = 2 },
|
||||
{ .base = uvreq->uvbuf.base,
|
||||
.len = uvreq->uvbuf.len } };
|
||||
int nbufs = 2;
|
||||
int r;
|
||||
|
||||
UNUSED(worker);
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
@ -1380,7 +1387,7 @@ isc__nm_tcpdns_shutdown(isc_nmsocket_t *sock) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->accepting) {
|
||||
if (atomic_load(&sock->accepting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1392,7 +1399,11 @@ isc__nm_tcpdns_shutdown(isc_nmsocket_t *sock) {
|
||||
}
|
||||
|
||||
if (sock->statichandle != NULL) {
|
||||
if (isc__nm_closing(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_SHUTTINGDOWN, false);
|
||||
} else {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -233,7 +233,11 @@ tlsdns_connect_cb(uv_connect_t *uvreq, int status) {
|
||||
REQUIRE(VALID_NMHANDLE(req->handle));
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
/* Socket was closed midflight by isc__nm_tlsdns_shutdown() */
|
||||
/* Network manager shutting down */
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
} else if (isc__nmsocket_closing(sock)) {
|
||||
/* Connection canceled */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
} else if (status == UV_ETIMEDOUT) {
|
||||
@ -344,6 +348,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
}
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@ -373,6 +378,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
return;
|
||||
|
||||
failure:
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
@ -843,8 +849,6 @@ isc__nm_tlsdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
|
||||
REQUIRE(sock->type == isc_nm_tlsdnssocket);
|
||||
REQUIRE(sock->statichandle == handle);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(!sock->recv_read);
|
||||
|
||||
sock->recv_cb = cb;
|
||||
sock->recv_cbarg = cbarg;
|
||||
@ -884,7 +888,7 @@ isc__nm_async_tlsdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
@ -938,9 +942,8 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
|
||||
/*
|
||||
* We need to launch the resume_processing after the buffer has
|
||||
* been consumed, thus we need to delay the detaching the
|
||||
* handle.
|
||||
* We need to launch isc__nm_resume_processing() after the buffer
|
||||
* has been consumed, thus we must delay detaching the handle.
|
||||
*/
|
||||
isc_nmhandle_attach(req->handle, &handle);
|
||||
|
||||
@ -959,10 +962,10 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
|
||||
sock->recv_read = false;
|
||||
|
||||
/*
|
||||
* The assertion failure here means that there's a errnoneous
|
||||
* An assertion failure here means that there's an erroneous
|
||||
* extra nmhandle detach happening in the callback and
|
||||
* resume_processing gets called while we are still processing
|
||||
* the buffer.
|
||||
* isc__nm_resume_processing() is called while we're
|
||||
* processing the buffer.
|
||||
*/
|
||||
REQUIRE(sock->processing == false);
|
||||
sock->processing = true;
|
||||
@ -1278,6 +1281,8 @@ done:
|
||||
|
||||
static void
|
||||
async_tlsdns_cycle(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tlsdnscycle_t *ievent = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
/* Socket was closed midflight by isc__nm_tlsdns_shutdown() */
|
||||
@ -1285,8 +1290,7 @@ async_tlsdns_cycle(isc_nmsocket_t *sock) {
|
||||
return;
|
||||
}
|
||||
|
||||
isc__netievent_tlsdnscycle_t *ievent =
|
||||
isc__nm_get_netievent_tlsdnscycle(sock->mgr, sock);
|
||||
ievent = isc__nm_get_netievent_tlsdnscycle(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
@ -1321,7 +1325,7 @@ isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->reading);
|
||||
REQUIRE(atomic_load(&sock->reading));
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
@ -1441,7 +1445,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
||||
csock->recv_cb = ssock->recv_cb;
|
||||
csock->recv_cbarg = ssock->recv_cbarg;
|
||||
csock->quota = quota;
|
||||
csock->accepting = true;
|
||||
atomic_init(&csock->accepting, true);
|
||||
|
||||
worker = &csock->mgr->workers[csock->tid];
|
||||
|
||||
@ -1530,7 +1534,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
||||
|
||||
/* FIXME: Set SSL_MODE_RELEASE_BUFFERS */
|
||||
|
||||
csock->accepting = false;
|
||||
atomic_store(&csock->accepting, false);
|
||||
|
||||
isc__nm_incstats(csock->mgr, csock->statsindex[STATID_ACCEPT]);
|
||||
|
||||
@ -1579,13 +1583,15 @@ failure:
|
||||
void
|
||||
isc__nm_tlsdns_send(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
isc_nm_cb_t cb, void *cbarg) {
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||
|
||||
isc_nmsocket_t *sock = handle->sock;
|
||||
isc__netievent_tlsdnssend_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *uvreq = NULL;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
||||
sock = handle->sock;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tlsdnssocket);
|
||||
|
||||
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
@ -1936,12 +1942,14 @@ isc__nm_tlsdns_shutdown(isc_nmsocket_t *sock) {
|
||||
(void)SSL_shutdown(sock->tls.tls);
|
||||
}
|
||||
|
||||
if (sock->accepting) {
|
||||
if (atomic_load(&sock->accepting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TLS handshake hasn't been completed yet */
|
||||
if (atomic_load(&sock->connecting)) {
|
||||
isc_nmsocket_t *tsock = NULL;
|
||||
|
||||
/*
|
||||
* TCP connection has been established, now waiting on
|
||||
* TLS handshake to complete
|
||||
@ -1956,14 +1964,17 @@ isc__nm_tlsdns_shutdown(isc_nmsocket_t *sock) {
|
||||
}
|
||||
|
||||
/* The TCP connection hasn't been established yet */
|
||||
isc_nmsocket_t *tsock = NULL;
|
||||
isc__nmsocket_attach(sock, &tsock);
|
||||
uv_close(&sock->uv_handle.handle, tlsdns_close_connect_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle != NULL) {
|
||||
if (isc__nm_closing(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_SHUTTINGDOWN, false);
|
||||
} else {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ inactive(isc_nmsocket_t *sock) {
|
||||
atomic_load(&sock->outerhandle->sock->closing) ||
|
||||
(sock->listener != NULL &&
|
||||
!isc__nmsocket_active(sock->listener)) ||
|
||||
atomic_load(&sock->mgr->closing));
|
||||
isc__nm_closing(sock));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -913,7 +913,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
tlssock->iface = handle->sock->iface;
|
||||
tlssock->peer = handle->sock->peer;
|
||||
if (isc__nm_closing(tlssock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ start_udp_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock,
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_udpsocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->iface = sock->iface;
|
||||
csock->reading = true;
|
||||
atomic_init(&csock->reading, true);
|
||||
csock->recv_cb = sock->recv_cb;
|
||||
csock->recv_cbarg = sock->recv_cbarg;
|
||||
csock->extrahandlesize = sock->extrahandlesize;
|
||||
@ -344,7 +344,7 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->reading);
|
||||
REQUIRE(atomic_load(&sock->reading));
|
||||
|
||||
#ifdef UV_UDP_MMSG_FREE
|
||||
free_buf = ((flags & UV_UDP_MMSG_FREE) == UV_UDP_MMSG_FREE);
|
||||
@ -356,7 +356,7 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Three possible reasons to return now without processing:
|
||||
* Four possible reasons to return now without processing:
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -373,6 +373,15 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
goto free;
|
||||
}
|
||||
|
||||
/*
|
||||
* - If there was a networking error.
|
||||
*/
|
||||
if (nrecv < 0) {
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nrecv),
|
||||
false);
|
||||
goto free;
|
||||
}
|
||||
|
||||
/*
|
||||
* - If addr == NULL, in which case it's the end of stream;
|
||||
* we can free the buffer and bail.
|
||||
@ -390,12 +399,6 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
goto free;
|
||||
}
|
||||
|
||||
if (nrecv < 0) {
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nrecv),
|
||||
false);
|
||||
goto free;
|
||||
}
|
||||
|
||||
result = isc_sockaddr_fromsockaddr(&sockaddr, addr);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
@ -612,6 +615,11 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
RUNTIME_CHECK(r == 0);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
|
||||
if (r != 0) {
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]);
|
||||
@ -653,6 +661,7 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
|
||||
done:
|
||||
result = isc__nm_uverr2result(r);
|
||||
error:
|
||||
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
@ -800,6 +809,7 @@ isc__nm_udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
* does not.
|
||||
*/
|
||||
if (!sock->parent) {
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
}
|
||||
}
|
||||
@ -856,15 +866,22 @@ void
|
||||
isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_udpread_t *ievent = (isc__netievent_udpread_t *)ev0;
|
||||
isc_nmsocket_t *sock = ievent->sock;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
UNUSED(worker);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
} else if (isc__nmsocket_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_failed_read_cb(sock, result, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -881,14 +898,13 @@ isc__nm_udp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->statichandle == handle);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(!sock->recv_read);
|
||||
|
||||
sock->recv_cb = cb;
|
||||
sock->recv_cbarg = cbarg;
|
||||
sock->recv_read = true;
|
||||
|
||||
if (!sock->reading && sock->tid == isc_nm_tid()) {
|
||||
if (!atomic_load(&sock->reading) && sock->tid == isc_nm_tid()) {
|
||||
isc__netievent_udpread_t ievent = { .sock = sock };
|
||||
isc__nm_async_udpread(NULL, (isc__netievent_t *)&ievent);
|
||||
} else {
|
||||
@ -1079,7 +1095,11 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock) {
|
||||
* interested in the callback.
|
||||
*/
|
||||
if (sock->statichandle != NULL) {
|
||||
if (isc__nm_closing(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_SHUTTINGDOWN, false);
|
||||
} else {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user