mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-23 18:49:54 +00:00
Merge branch '3400-gracefully-handle-the-errors-from-uv_start_read' into 'main'
Gracefully handle uv_read_start() failures Closes #3400 See merge request isc-projects/bind9!6424
This commit is contained in:
commit
e8cc03f1df
5
CHANGES
5
CHANGES
@ -1,3 +1,8 @@
|
|||||||
|
5905. [bug] When the TCP connection would be closed/reset between
|
||||||
|
the connect/accept and the read, the uv_read_start()
|
||||||
|
return value would be unexpected and cause an assertion
|
||||||
|
failure. [GL #3400]
|
||||||
|
|
||||||
5904. [func] Changed dnssec-signzone -H default to 0 additional
|
5904. [func] Changed dnssec-signzone -H default to 0 additional
|
||||||
NSEC3 iterations. [GL #3395]
|
NSEC3 iterations. [GL #3395]
|
||||||
|
|
||||||
|
@ -46,3 +46,6 @@ Bug Fixes
|
|||||||
- It was possible for a catalog zone consumer to process a catalog zone member
|
- It was possible for a catalog zone consumer to process a catalog zone member
|
||||||
zone when there was a configured pre-existing forward-only forward zone with
|
zone when there was a configured pre-existing forward-only forward zone with
|
||||||
the same name. This has been fixed. :gl:`#2506`.
|
the same name. This has been fixed. :gl:`#2506`.
|
||||||
|
|
||||||
|
- Fix the assertion failure caused by TCP connection closing between the
|
||||||
|
connect (or accept) and the read from the socket. :gl:`#3400`
|
||||||
|
@ -2098,11 +2098,11 @@ isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
|||||||
void
|
void
|
||||||
isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||||
|
|
||||||
void
|
isc_result_t
|
||||||
isc__nm_start_reading(isc_nmsocket_t *sock);
|
isc__nm_start_reading(isc_nmsocket_t *sock);
|
||||||
void
|
void
|
||||||
isc__nm_stop_reading(isc_nmsocket_t *sock);
|
isc__nm_stop_reading(isc_nmsocket_t *sock);
|
||||||
void
|
isc_result_t
|
||||||
isc__nm_process_sock_buffer(isc_nmsocket_t *sock);
|
isc__nm_process_sock_buffer(isc_nmsocket_t *sock);
|
||||||
void
|
void
|
||||||
isc__nm_resume_processing(void *arg);
|
isc__nm_resume_processing(void *arg);
|
||||||
|
@ -2161,39 +2161,42 @@ isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
|
|||||||
worker->recvbuf_inuse = true;
|
worker->recvbuf_inuse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
isc_result_t
|
||||||
isc__nm_start_reading(isc_nmsocket_t *sock) {
|
isc__nm_start_reading(isc_nmsocket_t *sock) {
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (atomic_load(&sock->reading)) {
|
if (atomic_load(&sock->reading)) {
|
||||||
return;
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sock->type) {
|
switch (sock->type) {
|
||||||
case isc_nm_udpsocket:
|
case isc_nm_udpsocket:
|
||||||
r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
|
r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
|
||||||
isc__nm_udp_read_cb);
|
isc__nm_udp_read_cb);
|
||||||
UV_RUNTIME_CHECK(uv_udp_recv_start, r);
|
|
||||||
break;
|
break;
|
||||||
case isc_nm_tcpsocket:
|
case isc_nm_tcpsocket:
|
||||||
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
||||||
isc__nm_tcp_read_cb);
|
isc__nm_tcp_read_cb);
|
||||||
UV_RUNTIME_CHECK(uv_read_start, r);
|
|
||||||
break;
|
break;
|
||||||
case isc_nm_tcpdnssocket:
|
case isc_nm_tcpdnssocket:
|
||||||
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
||||||
isc__nm_tcpdns_read_cb);
|
isc__nm_tcpdns_read_cb);
|
||||||
UV_RUNTIME_CHECK(uv_read_start, r);
|
|
||||||
break;
|
break;
|
||||||
case isc_nm_tlsdnssocket:
|
case isc_nm_tlsdnssocket:
|
||||||
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
||||||
isc__nm_tlsdns_read_cb);
|
isc__nm_tlsdns_read_cb);
|
||||||
UV_RUNTIME_CHECK(uv_read_start, r);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
atomic_store(&sock->reading, true);
|
if (r != 0) {
|
||||||
|
result = isc_uverr2result(r);
|
||||||
|
} else {
|
||||||
|
atomic_store(&sock->reading, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2254,7 +2257,7 @@ processbuffer(isc_nmsocket_t *sock) {
|
|||||||
* Stop reading if this is a client socket. In this case we'll be
|
* Stop reading if this is a client socket. In this case we'll be
|
||||||
* called again later by isc__nm_resume_processing().
|
* called again later by isc__nm_resume_processing().
|
||||||
*/
|
*/
|
||||||
void
|
isc_result_t
|
||||||
isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int_fast32_t ah = atomic_load(&sock->ah);
|
int_fast32_t ah = atomic_load(&sock->ah);
|
||||||
@ -2265,7 +2268,10 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
|||||||
* Don't reset the timer until we have a
|
* Don't reset the timer until we have a
|
||||||
* full DNS message.
|
* full DNS message.
|
||||||
*/
|
*/
|
||||||
isc__nm_start_reading(sock);
|
result = isc__nm_start_reading(sock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Start the timer only if there are no externally used
|
* Start the timer only if there are no externally used
|
||||||
* active handles, there's always one active handle
|
* active handles, there's always one active handle
|
||||||
@ -2275,11 +2281,11 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
|||||||
if (ah == 1) {
|
if (ah == 1) {
|
||||||
isc__nmsocket_timer_start(sock);
|
isc__nmsocket_timer_start(sock);
|
||||||
}
|
}
|
||||||
return;
|
goto done;
|
||||||
case ISC_R_CANCELED:
|
case ISC_R_CANCELED:
|
||||||
isc__nmsocket_timer_stop(sock);
|
isc__nmsocket_timer_stop(sock);
|
||||||
isc__nm_stop_reading(sock);
|
isc__nm_stop_reading(sock);
|
||||||
return;
|
goto done;
|
||||||
case ISC_R_SUCCESS:
|
case ISC_R_SUCCESS:
|
||||||
/*
|
/*
|
||||||
* Stop the timer on the successful message read, this
|
* Stop the timer on the successful message read, this
|
||||||
@ -2290,13 +2296,15 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
|||||||
|
|
||||||
if (atomic_load(&sock->client)) {
|
if (atomic_load(&sock->client)) {
|
||||||
isc__nm_stop_reading(sock);
|
isc__nm_stop_reading(sock);
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -747,18 +747,24 @@ isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
isc__netievent_tcpstartread_t *ievent =
|
isc__netievent_tcpstartread_t *ievent =
|
||||||
(isc__netievent_tcpstartread_t *)ev0;
|
(isc__netievent_tcpstartread_t *)ev0;
|
||||||
isc_nmsocket_t *sock = ievent->sock;
|
isc_nmsocket_t *sock = ievent->sock;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
REQUIRE(sock->tid == isc_nm_tid());
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
|
|
||||||
if (isc__nmsocket_closing(sock)) {
|
if (isc__nmsocket_closing(sock)) {
|
||||||
|
result = ISC_R_CANCELED;
|
||||||
|
} else {
|
||||||
|
result = isc__nm_start_reading(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
atomic_store(&sock->reading, true);
|
atomic_store(&sock->reading, true);
|
||||||
isc__nm_tcp_failed_read_cb(sock, ISC_R_CANCELED);
|
isc__nm_tcp_failed_read_cb(sock, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isc__nm_start_reading(sock);
|
|
||||||
isc__nmsocket_timer_start(sock);
|
isc__nmsocket_timer_start(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,6 +714,7 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
isc__netievent_tcpdnsread_t *ievent =
|
isc__netievent_tcpdnsread_t *ievent =
|
||||||
(isc__netievent_tcpdnsread_t *)ev0;
|
(isc__netievent_tcpdnsread_t *)ev0;
|
||||||
isc_nmsocket_t *sock = ievent->sock;
|
isc_nmsocket_t *sock = ievent->sock;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
|
|
||||||
@ -721,12 +722,15 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
REQUIRE(sock->tid == isc_nm_tid());
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
|
|
||||||
if (isc__nmsocket_closing(sock)) {
|
if (isc__nmsocket_closing(sock)) {
|
||||||
atomic_store(&sock->reading, true);
|
result = ISC_R_CANCELED;
|
||||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
} else {
|
||||||
return;
|
result = isc__nm_process_sock_buffer(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc__nm_process_sock_buffer(sock);
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
atomic_store(&sock->reading, true);
|
||||||
|
isc__nm_failed_read_cb(sock, result, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -836,6 +840,7 @@ isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream);
|
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream);
|
||||||
uint8_t *base = NULL;
|
uint8_t *base = NULL;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
REQUIRE(sock->tid == isc_nm_tid());
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
@ -878,7 +883,10 @@ isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||||||
sock->read_timeout = atomic_load(&sock->mgr->idle);
|
sock->read_timeout = atomic_load(&sock->mgr->idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc__nm_process_sock_buffer(sock);
|
result = isc__nm_process_sock_buffer(sock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc__nm_failed_read_cb(sock, result, true);
|
||||||
|
}
|
||||||
free:
|
free:
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
/*
|
/*
|
||||||
@ -1029,7 +1037,12 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||||||
* prep_destroy()->tcpdns_close_direct().
|
* prep_destroy()->tcpdns_close_direct().
|
||||||
*/
|
*/
|
||||||
isc_nmhandle_attach(handle, &csock->recv_handle);
|
isc_nmhandle_attach(handle, &csock->recv_handle);
|
||||||
isc__nm_process_sock_buffer(csock);
|
result = isc__nm_process_sock_buffer(csock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_nmhandle_detach(&csock->recv_handle);
|
||||||
|
isc_nmhandle_detach(&handle);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The initial timer has been set, update the read timeout for the next
|
* The initial timer has been set, update the read timeout for the next
|
||||||
|
@ -316,7 +316,11 @@ tlsdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||||||
/* Setting pending req */
|
/* Setting pending req */
|
||||||
sock->tls.pending_req = req;
|
sock->tls.pending_req = req;
|
||||||
|
|
||||||
isc__nm_process_sock_buffer(sock);
|
result = isc__nm_process_sock_buffer(sock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
sock->tls.pending_req = NULL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
result = tls_cycle(sock);
|
result = tls_cycle(sock);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@ -1068,8 +1072,10 @@ tls_cycle_input(isc_nmsocket_t *sock) {
|
|||||||
/*
|
/*
|
||||||
* Process what's in the buffer so far
|
* Process what's in the buffer so far
|
||||||
*/
|
*/
|
||||||
isc__nm_process_sock_buffer(sock);
|
result = isc__nm_process_sock_buffer(sock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* FIXME: Should we call
|
* FIXME: Should we call
|
||||||
* isc__nm_failed_read_cb()?
|
* isc__nm_failed_read_cb()?
|
||||||
@ -1081,7 +1087,10 @@ tls_cycle_input(isc_nmsocket_t *sock) {
|
|||||||
|
|
||||||
sock->buf_len += len;
|
sock->buf_len += len;
|
||||||
|
|
||||||
isc__nm_process_sock_buffer(sock);
|
result = isc__nm_process_sock_buffer(sock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (!SSL_is_init_finished(sock->tls.tls)) {
|
} else if (!SSL_is_init_finished(sock->tls.tls)) {
|
||||||
if (SSL_is_server(sock->tls.tls)) {
|
if (SSL_is_server(sock->tls.tls)) {
|
||||||
@ -1103,7 +1112,10 @@ tls_cycle_input(isc_nmsocket_t *sock) {
|
|||||||
if (sock->tls.state == TLS_STATE_NONE &&
|
if (sock->tls.state == TLS_STATE_NONE &&
|
||||||
!SSL_is_init_finished(sock->tls.tls)) {
|
!SSL_is_init_finished(sock->tls.tls)) {
|
||||||
sock->tls.state = TLS_STATE_HANDSHAKE;
|
sock->tls.state = TLS_STATE_HANDSHAKE;
|
||||||
isc__nm_process_sock_buffer(sock);
|
result = isc__nm_process_sock_buffer(sock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* else continue reading */
|
/* else continue reading */
|
||||||
break;
|
break;
|
||||||
@ -1656,7 +1668,10 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||||||
|
|
||||||
isc_nmhandle_detach(&handle);
|
isc_nmhandle_detach(&handle);
|
||||||
|
|
||||||
isc__nm_process_sock_buffer(csock);
|
result = isc__nm_process_sock_buffer(csock);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sock is now attached to the handle.
|
* sock is now attached to the handle.
|
||||||
|
@ -1118,7 +1118,7 @@ void
|
|||||||
isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||||
isc__netievent_udpread_t *ievent = (isc__netievent_udpread_t *)ev0;
|
isc__netievent_udpread_t *ievent = (isc__netievent_udpread_t *)ev0;
|
||||||
isc_nmsocket_t *sock = ievent->sock;
|
isc_nmsocket_t *sock = ievent->sock;
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result;
|
||||||
|
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
|
|
||||||
@ -1129,6 +1129,8 @@ isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
result = ISC_R_SHUTTINGDOWN;
|
result = ISC_R_SHUTTINGDOWN;
|
||||||
} else if (isc__nmsocket_closing(sock)) {
|
} else if (isc__nmsocket_closing(sock)) {
|
||||||
result = ISC_R_CANCELED;
|
result = ISC_R_CANCELED;
|
||||||
|
} else {
|
||||||
|
result = isc__nm_start_reading(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@ -1137,7 +1139,6 @@ isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isc__nm_start_reading(sock);
|
|
||||||
isc__nmsocket_timer_start(sock);
|
isc__nmsocket_timer_start(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user