mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +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:
@@ -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);
|
||||
|
Reference in New Issue
Block a user