]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
refactor dns_xfrin to use dns_dispatch
authorEvan Hunt <each@isc.org>
Wed, 22 Feb 2023 04:14:30 +0000 (20:14 -0800)
committerEvan Hunt <each@isc.org>
Fri, 24 Feb 2023 08:30:33 +0000 (08:30 +0000)
the dns_xfrin module was still using the network manager directly to
manage TCP connections and send and receive messages.  this commit
changes it to use the dispatch manager instead.

bin/tests/system/xfer/tests.sh
lib/dns/dispatch.c
lib/dns/include/dns/dispatch.h
lib/dns/include/dns/xfrin.h
lib/dns/xfrin.c
lib/dns/zone.c

index 7ff58c7bd04b46caeca93d0a47e88122cbea41c3..fd0e5ff4957a9028e96decefe7141fa6c909457e 100755 (executable)
@@ -431,7 +431,7 @@ $RNDCCMD 10.53.0.4 retransfer nil | sed 's/^/ns4 /' | cat_i
 
 sleep 2
 
-nextpart ns4/named.run | grep "unexpected message id" > /dev/null || {
+nextpart ns4/named.run | grep "Transfer status: unexpected error" > /dev/null || {
     echo_i "failed: expected status was not logged"
     status=$((status+1))
 }
index f97655f3b251d49079eb510636718ba19d0ca137..9e16b5682b9767961c71d563b23b422278d995ef 100644 (file)
@@ -2328,3 +2328,14 @@ dns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
        isc_mutex_destroy(&dset->lock);
        isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
 }
+
+isc_result_t
+dns_dispatch_checkperm(dns_dispatch_t *disp) {
+       REQUIRE(VALID_DISPATCH(disp));
+
+       if (disp->handle == NULL || disp->socktype == isc_socktype_udp) {
+               return (ISC_R_NOPERM);
+       }
+
+       return (isc_nm_xfr_checkperm(disp->handle));
+}
index 265918bda480d131cab824de7d04c91db009b721..254fda8e32a88eca3b94fbd5f0eb513b9118c7d3 100644 (file)
@@ -387,4 +387,15 @@ dns_dispatch_getnext(dns_dispentry_t *resp);
  * Requires:
  *\li  resp is valid
  */
+
+isc_result_t
+dns_dispatch_checkperm(dns_dispatch_t *disp);
+/*%<
+ * Check whether it is permitted to do a zone transfer over a dispatch.
+ * See isc_nm_xfr_checkperm().
+ *
+ * Requires:
+ *\li  disp is valid
+ */
+
 ISC_LANG_ENDDECLS
index 7e269c48eba3f9cb1892917590b20cf7abf14550..24ed327de760160aa4b26a6c25f5907d333a6551 100644 (file)
@@ -55,8 +55,7 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
                 const isc_sockaddr_t *primaryaddr,
                 const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
                 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
-                isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
-                dns_xfrin_t **xfrp);
+                isc_mem_t *mctx, dns_xfrindone_t done, dns_xfrin_t **xfrp);
 /*%<
  * Attempt to start an incoming zone transfer of 'zone'
  * from 'primaryaddr', creating a dns_xfrin_t object to
index c74cce66f917e14a2ef934f1af0d12e36197c4e0..290754f699333fb58045f4a2e1e5848cadc2b391 100644 (file)
@@ -17,7 +17,6 @@
 #include <stdbool.h>
 
 #include <isc/mem.h>
-#include <isc/netmgr.h>
 #include <isc/random.h>
 #include <isc/result.h>
 #include <isc/string.h>
@@ -27,6 +26,7 @@
 #include <dns/catz.h>
 #include <dns/db.h>
 #include <dns/diff.h>
+#include <dns/dispatch.h>
 #include <dns/journal.h>
 #include <dns/log.h>
 #include <dns/message.h>
@@ -94,15 +94,10 @@ struct dns_xfrin {
        unsigned int magic;
        isc_mem_t *mctx;
        dns_zone_t *zone;
+       dns_view_t *view;
 
        isc_refcount_t references;
 
-       isc_nm_t *netmgr;
-
-       isc_refcount_t connects; /*%< Connect in progress */
-       isc_refcount_t sends;    /*%< Send in progress */
-       isc_refcount_t recvs;    /*%< Receive in progress */
-
        atomic_bool shuttingdown;
 
        isc_result_t shutdown_result;
@@ -122,9 +117,8 @@ struct dns_xfrin {
        isc_sockaddr_t primaryaddr;
        isc_sockaddr_t sourceaddr;
 
-       isc_nmhandle_t *handle;
-       isc_nmhandle_t *readhandle;
-       isc_nmhandle_t *sendhandle;
+       dns_dispatch_t *disp;
+       dns_dispentry_t *dispentry;
 
        /*% Buffer for IXFR/AXFR request message */
        isc_buffer_t qbuffer;
@@ -194,7 +188,7 @@ struct dns_xfrin {
  */
 
 static void
-xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
+xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db,
             dns_name_t *zonename, dns_rdataclass_t rdclass,
             dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
             const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
@@ -232,14 +226,13 @@ static isc_result_t
 xfrin_start(dns_xfrin_t *xfr);
 
 static void
-xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
+xfrin_connect_done(isc_result_t result, isc_region_t *region, void *arg);
 static isc_result_t
 xfrin_send_request(dns_xfrin_t *xfr);
 static void
-xfrin_send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
+xfrin_send_done(isc_result_t eresult, isc_region_t *region, void *arg);
 static void
-xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
-               isc_region_t *region, void *cbarg);
+xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg);
 
 static void
 xfrin_destroy(dns_xfrin_t *xfr);
@@ -689,8 +682,7 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
                 const isc_sockaddr_t *primaryaddr,
                 const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
                 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
-                isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
-                dns_xfrin_t **xfrp) {
+                isc_mem_t *mctx, dns_xfrindone_t done, dns_xfrin_t **xfrp) {
        dns_name_t *zonename = dns_zone_getorigin(zone);
        dns_xfrin_t *xfr = NULL;
        isc_result_t result;
@@ -708,9 +700,9 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
                REQUIRE(db != NULL);
        }
 
-       xfrin_create(mctx, zone, db, netmgr, zonename, dns_zone_getclass(zone),
-                    xfrtype, primaryaddr, sourceaddr, tsigkey, transport,
-                    tlsctx_cache, &xfr);
+       xfrin_create(mctx, zone, db, zonename, dns_zone_getclass(zone), xfrtype,
+                    primaryaddr, sourceaddr, tsigkey, transport, tlsctx_cache,
+                    &xfr);
 
        if (db != NULL) {
                xfr->zone_had_db = true;
@@ -721,11 +713,9 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
        isc_refcount_init(&xfr->references, 1);
 
        /*
-        * Set *xfrp now, before calling xfrin_start(). Asynchronous
-        * netmgr processing could cause the 'done' callback to run in
-        * another thread before we reached the end of the present
-        * function. In that case, if *xfrp hadn't already been
-        * attached, the 'done' function would be unable to detach it.
+        * Set *xfrp now, before calling xfrin_start(), otherwise it's
+        * possible the 'done' callback could be run before *xfrp
+        * was attached.
         */
        *xfrp = xfr;
 
@@ -752,6 +742,9 @@ dns_xfrin_shutdown(dns_xfrin_t *xfr) {
        REQUIRE(VALID_XFRIN(xfr));
 
        xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
+
+       /* we won't reach xfrin_recv_done(), so dereference xfr here */
+       dns_xfrin_unref(xfr);
 }
 
 #if DNS_XFRIN_TRACE
@@ -762,12 +755,8 @@ ISC_REFCOUNT_IMPL(dns_xfrin, xfrin_destroy);
 
 static void
 xfrin_cancelio(dns_xfrin_t *xfr) {
-       if (xfr->readhandle == NULL) {
-               return;
-       }
-
-       isc_nm_cancelread(xfr->readhandle);
-       /* The xfr->readhandle detach will happen in xfrin_recv_done callback */
+       dns_dispatch_done(&xfr->dispentry);
+       dns_dispatch_detach(&xfr->disp);
 }
 
 static void
@@ -776,9 +765,6 @@ xfrin_reset(dns_xfrin_t *xfr) {
 
        xfrin_log(xfr, ISC_LOG_INFO, "resetting");
 
-       REQUIRE(xfr->readhandle == NULL);
-       REQUIRE(xfr->sendhandle == NULL);
-
        if (xfr->lasttsig != NULL) {
                isc_buffer_free(&xfr->lasttsig);
        }
@@ -801,6 +787,8 @@ xfrin_reset(dns_xfrin_t *xfr) {
 
 static void
 xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) {
+       dns_xfrin_ref(xfr);
+
        /* Make sure only the first xfrin_fail() trumps */
        if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false },
                                           true))
@@ -810,12 +798,14 @@ xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) {
                        xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
                                  isc_result_totext(result));
                        if (xfr->is_ixfr) {
-                               /* Pass special result code to force AXFR retry
+                               /*
+                                * Pass special result code to force AXFR retry
                                 */
                                result = DNS_R_BADIXFR;
                        }
                }
                xfrin_cancelio(xfr);
+
                /*
                 * Close the journal.
                 */
@@ -828,10 +818,12 @@ xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) {
                }
                xfr->shutdown_result = result;
        }
+
+       dns_xfrin_detach(&xfr);
 }
 
 static void
-xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
+xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db,
             dns_name_t *zonename, dns_rdataclass_t rdclass,
             dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
             const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
@@ -840,11 +832,9 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
        dns_xfrin_t *xfr = NULL;
 
        xfr = isc_mem_get(mctx, sizeof(*xfr));
-       *xfr = (dns_xfrin_t){ .netmgr = netmgr,
-                             .shutdown_result = ISC_R_UNSET,
+       *xfr = (dns_xfrin_t){ .shutdown_result = ISC_R_UNSET,
                              .rdclass = rdclass,
                              .reqtype = reqtype,
-                             .id = (dns_messageid_t)isc_random16(),
                              .maxrecords = dns_zone_getmaxrecords(zone),
                              .primaryaddr = *primaryaddr,
                              .sourceaddr = *sourceaddr,
@@ -852,12 +842,9 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
 
        isc_mem_attach(mctx, &xfr->mctx);
        dns_zone_iattach(zone, &xfr->zone);
+       dns_view_weakattach(dns_zone_getview(zone), &xfr->view);
        dns_name_init(&xfr->name, NULL);
 
-       isc_refcount_init(&xfr->connects, 0);
-       isc_refcount_init(&xfr->sends, 0);
-       isc_refcount_init(&xfr->recvs, 0);
-
        atomic_init(&xfr->shuttingdown, false);
 
        if (db != NULL) {
@@ -902,50 +889,53 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
 
 static isc_result_t
 xfrin_start(dns_xfrin_t *xfr) {
-       isc_result_t result;
-       dns_xfrin_t *connect_xfr = NULL;
-       dns_transport_type_t transport_type = DNS_TRANSPORT_TCP;
-       isc_tlsctx_t *tlsctx = NULL;
-       isc_tlsctx_client_session_cache_t *sess_cache = NULL;
+       isc_result_t result = ISC_R_FAILURE;
 
-       (void)isc_refcount_increment0(&xfr->connects);
-       dns_xfrin_attach(xfr, &connect_xfr);
+       dns_xfrin_ref(xfr);
 
-       if (xfr->transport != NULL) {
-               transport_type = dns_transport_get_type(xfr->transport);
+       /*
+        * Reuse an existing TCP connection if possible.  For XoT, we can't
+        * do this because other connections could be using a different
+        * certificate, so we just create a new dispatch every time.
+        */
+       if (xfr->transport == NULL ||
+           dns_transport_get_type(xfr->transport) == DNS_TRANSPORT_TCP)
+       {
+               result = dns_dispatch_gettcp(dns_view_getdispatchmgr(xfr->view),
+                                            &xfr->primaryaddr,
+                                            &xfr->sourceaddr, &xfr->disp);
+       }
+       if (result == ISC_R_SUCCESS) {
+               char peer[ISC_SOCKADDR_FORMATSIZE];
+               isc_sockaddr_format(&xfr->primaryaddr, peer, sizeof(peer));
+               xfrin_log(xfr, ISC_LOG_DEBUG(1),
+                         "attached to TCP connection to %s", peer);
+       } else {
+               CHECK(dns_dispatch_createtcp(dns_view_getdispatchmgr(xfr->view),
+                                            &xfr->sourceaddr,
+                                            &xfr->primaryaddr, &xfr->disp));
        }
 
        /*
         * XXX: timeouts are hard-coded to 30 seconds; this needs to be
         * configurable.
         */
-       switch (transport_type) {
-       case DNS_TRANSPORT_TCP:
-               isc_nm_streamdnsconnect(xfr->netmgr, &xfr->sourceaddr,
-                                       &xfr->primaryaddr, xfrin_connect_done,
-                                       connect_xfr, 30000, NULL, NULL);
-               break;
-       case DNS_TRANSPORT_TLS: {
-               result = dns_transport_get_tlsctx(
-                       xfr->transport, &xfr->primaryaddr, xfr->tlsctx_cache,
-                       xfr->mctx, &tlsctx, &sess_cache);
-               if (result != ISC_R_SUCCESS) {
-                       goto failure;
-               }
-               INSIST(tlsctx != NULL);
-               isc_nm_streamdnsconnect(xfr->netmgr, &xfr->sourceaddr,
-                                       &xfr->primaryaddr, xfrin_connect_done,
-                                       connect_xfr, 30000, tlsctx, sess_cache);
-       } break;
-       default:
-               UNREACHABLE();
-       }
-
+       CHECK(dns_dispatch_add(
+               xfr->disp, 0, 30000, &xfr->primaryaddr, xfr->transport,
+               xfr->tlsctx_cache, xfrin_connect_done, xfrin_send_done,
+               xfrin_recv_done, xfr, &xfr->id, &xfr->dispentry));
+       CHECK(dns_dispatch_connect(xfr->dispentry));
        return (ISC_R_SUCCESS);
 
 failure:
-       isc_refcount_decrement0(&xfr->connects);
-       dns_xfrin_detach(&connect_xfr);
+       if (xfr->dispentry != NULL) {
+               dns_dispatch_done(&xfr->dispentry);
+       }
+       if (xfr->disp != NULL) {
+               dns_dispatch_detach(&xfr->disp);
+       }
+       dns_xfrin_detach(&xfr);
+
        return (result);
 }
 
@@ -973,26 +963,29 @@ failure:
  * A connection has been established.
  */
 static void
-xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
-       dns_xfrin_t *xfr = (dns_xfrin_t *)cbarg;
-       char sourcetext[ISC_SOCKADDR_FORMATSIZE];
+xfrin_connect_done(isc_result_t result, isc_region_t *region, void *arg) {
+       dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
+       char addrtext[ISC_SOCKADDR_FORMATSIZE];
        char signerbuf[DNS_NAME_FORMATSIZE];
        const char *signer = "", *sep = "";
-       isc_sockaddr_t sockaddr;
        dns_zonemgr_t *zmgr = NULL;
        isc_time_t now;
 
-       REQUIRE(VALID_XFRIN(xfr));
+       UNUSED(region);
 
-       isc_refcount_decrement0(&xfr->connects);
+       REQUIRE(VALID_XFRIN(xfr));
 
        if (atomic_load(&xfr->shuttingdown)) {
                result = ISC_R_SHUTTINGDOWN;
        }
 
-       CHECK(result);
+       if (result != ISC_R_SUCCESS) {
+               xfrin_fail(xfr, result, "failed to connect");
+               dns_xfrin_unref(xfr);
+               return;
+       }
 
-       CHECK(isc_nm_xfr_checkperm(handle));
+       CHECK(dns_dispatch_checkperm(xfr->disp));
 
        zmgr = dns_zone_getmgr(xfr->zone);
        if (zmgr != NULL) {
@@ -1007,10 +1000,6 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
                }
        }
 
-       xfr->handle = handle;
-       sockaddr = isc_nmhandle_peeraddr(handle);
-       isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
-
        if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
                dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
                                sizeof(signerbuf));
@@ -1018,17 +1007,16 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
                signer = signerbuf;
        }
 
-       xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", sourcetext, sep,
+       isc_sockaddr_format(&xfr->primaryaddr, addrtext, sizeof(addrtext));
+       xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", addrtext, sep,
                  signer);
 
        CHECK(xfrin_send_request(xfr));
 
 failure:
        if (result != ISC_R_SUCCESS) {
-               xfrin_fail(xfr, result, "failed to connect");
+               xfrin_fail(xfr, result, "connected but unable to transfer");
        }
-
-       dns_xfrin_detach(&xfr); /* connect_xfr */
 }
 
 /*
@@ -1065,6 +1053,20 @@ tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
        *target = name;
 }
 
+static const char *
+request_type(dns_xfrin_t *xfr) {
+       switch (xfr->reqtype) {
+       case dns_rdatatype_soa:
+               return "SOA";
+       case dns_rdatatype_axfr:
+               return "AXFR";
+       case dns_rdatatype_ixfr:
+               return "IXFR";
+       default:
+               ISC_UNREACHABLE();
+       }
+}
+
 /*
  * Build an *XFR request and send its length prefix.
  */
@@ -1078,7 +1080,6 @@ xfrin_send_request(dns_xfrin_t *xfr) {
        dns_name_t *qname = NULL;
        dns_dbversion_t *ver = NULL;
        dns_name_t *msgsoaname = NULL;
-       dns_xfrin_t *send_xfr = NULL;
 
        /* Create the request message */
        dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg);
@@ -1099,7 +1100,6 @@ xfrin_send_request(dns_xfrin_t *xfr) {
 
        if (xfr->reqtype == dns_rdatatype_ixfr) {
                /* Get the SOA and add it to the authority section. */
-               /* XXX is using the current version the right thing? */
                dns_db_currentversion(xfr->db, &ver);
                CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
                                            DNS_DIFFOP_EXISTS, &soatuple));
@@ -1116,7 +1116,6 @@ xfrin_send_request(dns_xfrin_t *xfr) {
                                          &xfr->ixfr.request_serial));
        }
 
-       xfr->id++;
        xfr->nmsg = 0;
        xfr->nrecs = 0;
        xfr->nbytes = 0;
@@ -1143,10 +1142,10 @@ xfrin_send_request(dns_xfrin_t *xfr) {
        isc_buffer_usedregion(&xfr->qbuffer, &region);
        INSIST(region.length <= 65535);
 
-       dns_xfrin_attach(xfr, &send_xfr);
-       isc_nmhandle_attach(send_xfr->handle, &xfr->sendhandle);
-       isc_refcount_increment0(&send_xfr->sends);
-       isc_nm_send(xfr->handle, &region, xfrin_send_done, send_xfr);
+       dns_xfrin_ref(xfr);
+       dns_dispatch_send(xfr->dispentry, &region);
+       xfrin_log(xfr, ISC_LOG_DEBUG(3), "sending %s request, QID %d",
+                 request_type(xfr), xfr->id);
 
 failure:
        dns_message_detach(&msg);
@@ -1161,13 +1160,13 @@ failure:
 }
 
 static void
-xfrin_send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
-       dns_xfrin_t *xfr = (dns_xfrin_t *)cbarg;
-       dns_xfrin_t *recv_xfr = NULL;
+xfrin_send_done(isc_result_t result, isc_region_t *region, void *arg) {
+       dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
+
+       UNUSED(region);
 
        REQUIRE(VALID_XFRIN(xfr));
 
-       isc_refcount_decrement0(&xfr->sends);
        if (atomic_load(&xfr->shuttingdown)) {
                result = ISC_R_SHUTTINGDOWN;
        }
@@ -1176,34 +1175,24 @@ xfrin_send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
 
        xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
 
-       dns_xfrin_attach(xfr, &recv_xfr);
-       isc_nmhandle_attach(handle, &recv_xfr->readhandle);
-       isc_refcount_increment0(&recv_xfr->recvs);
-       isc_nm_read(recv_xfr->handle, xfrin_recv_done, recv_xfr);
-
 failure:
        if (result != ISC_R_SUCCESS) {
                xfrin_fail(xfr, result, "failed sending request data");
        }
 
-       isc_nmhandle_detach(&xfr->sendhandle);
-       dns_xfrin_detach(&xfr); /* send_xfr */
+       dns_xfrin_detach(&xfr);
 }
 
 static void
-xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
-               isc_region_t *region, void *cbarg) {
-       dns_xfrin_t *xfr = (dns_xfrin_t *)cbarg;
+xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) {
+       dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
        dns_message_t *msg = NULL;
        dns_name_t *name = NULL;
        const dns_name_t *tsigowner = NULL;
        isc_buffer_t buffer;
-       isc_sockaddr_t peer;
 
        REQUIRE(VALID_XFRIN(xfr));
 
-       isc_refcount_decrement0(&xfr->recvs);
-
        if (atomic_load(&xfr->shuttingdown)) {
                result = ISC_R_SHUTTINGDOWN;
        }
@@ -1228,23 +1217,21 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
 
        isc_buffer_init(&buffer, region->base, region->length);
        isc_buffer_add(&buffer, region->length);
-       peer = isc_nmhandle_peeraddr(handle);
 
        result = dns_message_parse(msg, &buffer,
                                   DNS_MESSAGEPARSE_PRESERVEORDER);
        if (result == ISC_R_SUCCESS) {
-               dns_message_logpacket(msg, "received message from", &peer,
-                                     DNS_LOGCATEGORY_XFER_IN,
-                                     DNS_LOGMODULE_XFER_IN, ISC_LOG_DEBUG(10),
-                                     xfr->mctx);
+               dns_message_logpacket(
+                       msg, "received message from", &xfr->primaryaddr,
+                       DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
+                       ISC_LOG_DEBUG(10), xfr->mctx);
        } else {
                xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
                          isc_result_totext(result));
        }
 
        if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
-           msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass ||
-           msg->id != xfr->id)
+           msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass)
        {
                if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
                {
@@ -1270,7 +1257,6 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
                xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
                          isc_result_totext(result));
        try_axfr:
-               isc_nmhandle_detach(&xfr->readhandle);
                dns_message_detach(&msg);
                xfrin_reset(xfr);
                xfr->reqtype = dns_rdatatype_soa;
@@ -1279,7 +1265,7 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
                if (result != ISC_R_SUCCESS) {
                        xfrin_fail(xfr, result, "failed setting up socket");
                }
-               dns_xfrin_detach(&xfr); /* recv_xfr */
+               dns_xfrin_detach(&xfr);
                return;
        }
 
@@ -1359,7 +1345,7 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
                FAIL(DNS_R_NOTAUTHORITATIVE);
        }
 
-       result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
+       result = dns_message_checksig(msg, xfr->view);
        if (result != ISC_R_SUCCESS) {
                xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
                          isc_result_totext(result));
@@ -1468,11 +1454,8 @@ xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
                /*
                 * Read the next message.
                 */
-               /* The readhandle is still attached */
-               /* The recv_xfr is still attached */
                dns_message_detach(&msg);
-               isc_refcount_increment0(&xfr->recvs);
-               isc_nm_read(xfr->handle, xfrin_recv_done, xfr);
+               dns_dispatch_getnext(xfr->dispentry);
                return;
        }
 
@@ -1484,24 +1467,18 @@ failure:
        if (msg != NULL) {
                dns_message_detach(&msg);
        }
-       isc_nmhandle_detach(&xfr->readhandle);
-       dns_xfrin_detach(&xfr); /* recv_xfr */
+       dns_xfrin_detach(&xfr);
 }
 
 static void
 xfrin_destroy(dns_xfrin_t *xfr) {
-       uint64_t msecs;
-       uint64_t persec;
-       const char *result_str;
+       uint64_t msecs, persec;
 
        REQUIRE(VALID_XFRIN(xfr));
 
        /* Safe-guards */
        REQUIRE(atomic_load(&xfr->shuttingdown));
        isc_refcount_destroy(&xfr->references);
-       isc_refcount_destroy(&xfr->connects);
-       isc_refcount_destroy(&xfr->recvs);
-       isc_refcount_destroy(&xfr->sends);
 
        INSIST(xfr->shutdown_result != ISC_R_UNSET);
 
@@ -1510,8 +1487,8 @@ xfrin_destroy(dns_xfrin_t *xfr) {
         * shutting down, we can't know what the transfer status is as
         * we are only called when the last reference is lost.
         */
-       result_str = isc_result_totext(xfr->shutdown_result);
-       xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str);
+       xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s",
+                 isc_result_totext(xfr->shutdown_result));
 
        /*
         * Calculate the length of time the transfer took,
@@ -1531,11 +1508,11 @@ xfrin_destroy(dns_xfrin_t *xfr) {
                  (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
                  (unsigned int)persec, xfr->end_serial);
 
-       if (xfr->readhandle != NULL) {
-               isc_nmhandle_detach(&xfr->readhandle);
+       if (xfr->dispentry != NULL) {
+               dns_dispatch_done(&xfr->dispentry);
        }
-       if (xfr->sendhandle != NULL) {
-               isc_nmhandle_detach(&xfr->sendhandle);
+       if (xfr->disp != NULL) {
+               dns_dispatch_detach(&xfr->disp);
        }
 
        if (xfr->transport != NULL) {
@@ -1591,6 +1568,10 @@ xfrin_destroy(dns_xfrin_t *xfr) {
                dns_zone_idetach(&xfr->zone);
        }
 
+       if (xfr->view != NULL) {
+               dns_view_weakdetach(&xfr->view);
+       }
+
        if (xfr->firstsoa_data != NULL) {
                isc_mem_free(xfr->mctx, xfr->firstsoa_data);
        }
index af3bac270c88a995459bdb3df9ad8ba30547798c..449b8485bcfc1accb172ee62e120e39ddc5ab93a 100644 (file)
@@ -17537,7 +17537,7 @@ got_transfer_quota(void *arg) {
        CHECK(dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr,
                               zone->tsigkey, zone->transport,
                               zone->zmgr->tlsctx_cache, zone->mctx,
-                              zone->zmgr->netmgr, zone_xfrdone, &zone->xfr));
+                              zone_xfrdone, &zone->xfr));
        LOCK_ZONE(zone);
        if (xfrtype == dns_rdatatype_axfr) {
                if (isc_sockaddr_pf(&primaryaddr) == PF_INET) {