2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35: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:
Ondřej Surý
2021-07-26 13:14:41 +02:00
committed by Evan Hunt
parent d9e1ad9e37
commit 9ee60e7a17
8 changed files with 192 additions and 109 deletions

View File

@@ -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) {
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
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;
}