]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Always enqueue isc__nm_tcp_resumeread()
authorOndřej Surý <ondrej@isc.org>
Thu, 6 Jan 2022 12:03:39 +0000 (13:03 +0100)
committerOndřej Surý <ondrej@isc.org>
Thu, 6 Jan 2022 19:00:44 +0000 (20:00 +0100)
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.

(cherry picked from commit 11c869a3d53eafa4083b404e6b6686a120919c26)

lib/isc/netmgr/tcp.c

index 1b5e80d3a73fdbc7ac21b093c4dd149a51cc819d..41c5a51e31c6162fd6a0eef3978d91567c24ec8a 100644 (file)
@@ -816,6 +816,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());
 
@@ -837,8 +838,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