]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Don't free udp recv buffer if UV_UDP_MMSG_CHUNK is set
authorWitold Kręcicki <wpk@isc.org>
Wed, 29 Apr 2020 13:19:32 +0000 (15:19 +0200)
committerWitold Kręcicki <wpk@isc.org>
Thu, 30 Apr 2020 15:30:37 +0000 (17:30 +0200)
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/udp.c

index 180d3336f9d527c4b6908cf23880b140df00c70c..66ddeb8e9cda645d43b592cf01c9d2dd97fbc361 100644 (file)
@@ -996,7 +996,7 @@ isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf) {
        if (buf->base > worker->recvbuf &&
            buf->base <= worker->recvbuf + ISC_NETMGR_RECVBUF_SIZE)
        {
-               /* Can happen in case of recvmmsg */
+               /* Can happen in case of out-of-order recvmmsg in libuv1.36 */
                return;
        }
        REQUIRE(buf->base == worker->recvbuf);
index 48e7328648a1864d1f7070da692796f0f6f5147a..6f8c83a75f4fcf7b3be445faf72e00f58d593f08 100644 (file)
@@ -295,22 +295,24 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
        isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle);
        isc_region_t region;
        uint32_t maxudp;
+       bool free_buf = true;
 
        REQUIRE(VALID_NMSOCK(sock));
 
-       /*
-        * We can ignore the flags; currently the only one in use by libuv
-        * is UV_UDP_PARTIAL, which only occurs if the receive buffer is
-        * too small, which can't happen here.
-        */
+#ifdef UV_UDP_MMSG_CHUNK
+       free_buf = ((flags & UV_UDP_MMSG_CHUNK) == 0);
+#else
        UNUSED(flags);
+#endif
 
        /*
         * If addr == NULL that's the end of stream - we can
         * free the buffer and bail.
         */
        if (addr == NULL) {
-               isc__nm_free_uvbuf(sock, buf);
+               if (free_buf) {
+                       isc__nm_free_uvbuf(sock, buf);
+               }
                return;
        }
 
@@ -331,7 +333,9 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
 
        INSIST(sock->rcb.recv != NULL);
        sock->rcb.recv(nmhandle, &region, sock->rcbarg);
-       isc__nm_free_uvbuf(sock, buf);
+       if (free_buf) {
+               isc__nm_free_uvbuf(sock, buf);
+       }
 
        /*
         * If the recv callback wants to hold on to the handle,