From 11c869a3d53eafa4083b404e6b6686a120919c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 6 Jan 2022 13:03:39 +0100 Subject: [PATCH] Always enqueue isc__nm_tcp_resumeread() The isc__nm_tcp_resumeread() was using maybe_enqueue function to enqueue netmgr event which could case the read callback to be executed immediately if there was enough data waiting in the TCP queue. If such thing would happen, the read callback would be called before the previous read callback was finished and the worker receive buffer would be still marked "in use" causing a assertion failure. This would affect only raw TCP channels, e.g. rndc and http statistics. --- lib/isc/netmgr/tcp.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index b818f41a20..872d96fe6a 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -814,6 +814,7 @@ isc__nm_tcp_resumeread(isc_nmhandle_t *handle) { isc__netievent_tcpstartread_t *ievent = NULL; isc_nmsocket_t *sock = handle->sock; + isc__networker_t *worker = &sock->mgr->workers[sock->tid]; REQUIRE(sock->tid == isc_nm_tid()); @@ -835,8 +836,18 @@ isc__nm_tcp_resumeread(isc_nmhandle_t *handle) { ievent = isc__nm_get_netievent_tcpstartread(sock->mgr, sock); - isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid], - (isc__netievent_t *)ievent); + if (worker->recvbuf_inuse) { + /* + * If we happen to call the resumeread from inside the receive + * callback, the worker->recvbuf might still be in use, so we + * need to force enqueue the next read event. + */ + isc__nm_enqueue_ievent(worker, (isc__netievent_t *)ievent); + + } else { + isc__nm_maybe_enqueue_ievent(worker, + (isc__netievent_t *)ievent); + } } void