"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/dns/xfrin.c" (7 Sep 2020, 41670 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xfrin.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 /*! \file */
   14 
   15 #include <config.h>
   16 
   17 #include <inttypes.h>
   18 #include <stdbool.h>
   19 
   20 #include <isc/mem.h>
   21 #include <isc/print.h>
   22 #include <isc/random.h>
   23 #include <isc/string.h>     /* Required for HP/UX (and others?) */
   24 #include <isc/task.h>
   25 #include <isc/timer.h>
   26 #include <isc/util.h>
   27 
   28 #include <dns/callbacks.h>
   29 #include <dns/catz.h>
   30 #include <dns/db.h>
   31 #include <dns/diff.h>
   32 #include <dns/events.h>
   33 #include <dns/journal.h>
   34 #include <dns/log.h>
   35 #include <dns/message.h>
   36 #include <dns/rdataclass.h>
   37 #include <dns/rdatalist.h>
   38 #include <dns/rdataset.h>
   39 #include <dns/result.h>
   40 #include <dns/soa.h>
   41 #include <dns/tcpmsg.h>
   42 #include <dns/timer.h>
   43 #include <dns/tsig.h>
   44 #include <dns/view.h>
   45 #include <dns/xfrin.h>
   46 #include <dns/zone.h>
   47 
   48 #include <dst/dst.h>
   49 
   50 /*
   51  * Incoming AXFR and IXFR.
   52  */
   53 
   54 /*%
   55  * It would be non-sensical (or at least obtuse) to use FAIL() with an
   56  * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
   57  * from complaining about "end-of-loop code not reached".
   58  */
   59 #define FAIL(code) \
   60     do { result = (code);                   \
   61         if (result != ISC_R_SUCCESS) goto failure;  \
   62     } while (0)
   63 
   64 #define CHECK(op) \
   65     do { result = (op);                 \
   66         if (result != ISC_R_SUCCESS) goto failure;  \
   67     } while (0)
   68 
   69 /*%
   70  * The states of the *XFR state machine.  We handle both IXFR and AXFR
   71  * with a single integrated state machine because they cannot be distinguished
   72  * immediately - an AXFR response to an IXFR request can only be detected
   73  * when the first two (2) response RRs have already been received.
   74  */
   75 typedef enum {
   76     XFRST_SOAQUERY,
   77     XFRST_GOTSOA,
   78     XFRST_INITIALSOA,
   79     XFRST_FIRSTDATA,
   80     XFRST_IXFR_DELSOA,
   81     XFRST_IXFR_DEL,
   82     XFRST_IXFR_ADDSOA,
   83     XFRST_IXFR_ADD,
   84     XFRST_IXFR_END,
   85     XFRST_AXFR,
   86     XFRST_AXFR_END
   87 } xfrin_state_t;
   88 
   89 /*%
   90  * Incoming zone transfer context.
   91  */
   92 
   93 struct dns_xfrin_ctx {
   94     unsigned int        magic;
   95     isc_mem_t       *mctx;
   96     dns_zone_t      *zone;
   97 
   98     int         refcount;
   99 
  100     isc_task_t      *task;
  101     isc_timer_t     *timer;
  102     isc_socketmgr_t     *socketmgr;
  103 
  104     int         connects;   /*%< Connect in progress */
  105     int         sends;      /*%< Send in progress */
  106     int         recvs;      /*%< Receive in progress */
  107     bool        shuttingdown;
  108     isc_result_t        shutdown_result;
  109 
  110     dns_name_t      name;       /*%< Name of zone to transfer */
  111     dns_rdataclass_t    rdclass;
  112 
  113     bool            checkid, logit;
  114     dns_messageid_t     id;
  115 
  116     /*%
  117      * Requested transfer type (dns_rdatatype_axfr or
  118      * dns_rdatatype_ixfr).  The actual transfer type
  119      * may differ due to IXFR->AXFR fallback.
  120      */
  121     dns_rdatatype_t     reqtype;
  122     isc_dscp_t      dscp;
  123 
  124     isc_sockaddr_t      masteraddr;
  125     isc_sockaddr_t      sourceaddr;
  126     isc_socket_t        *socket;
  127 
  128     /*% Buffer for IXFR/AXFR request message */
  129     isc_buffer_t        qbuffer;
  130     unsigned char       qbuffer_data[512];
  131 
  132     /*% Incoming reply TCP message */
  133     dns_tcpmsg_t        tcpmsg;
  134     bool        tcpmsg_valid;
  135 
  136     dns_db_t        *db;
  137     dns_dbversion_t     *ver;
  138     dns_diff_t      diff;       /*%< Pending database changes */
  139     int             difflen;    /*%< Number of pending tuples */
  140 
  141     xfrin_state_t       state;
  142     uint32_t        end_serial;
  143     bool        is_ixfr;
  144 
  145     unsigned int        nmsg;       /*%< Number of messages recvd */
  146     unsigned int        nrecs;      /*%< Number of records recvd */
  147     uint64_t        nbytes;     /*%< Number of bytes received */
  148 
  149     unsigned int        maxrecords; /*%< The maximum number of
  150                              records set for the zone */
  151 
  152     isc_time_t      start;      /*%< Start time of the transfer */
  153     isc_time_t      end;        /*%< End time of the transfer */
  154 
  155     dns_tsigkey_t       *tsigkey;   /*%< Key used to create TSIG */
  156     isc_buffer_t        *lasttsig;  /*%< The last TSIG */
  157     dst_context_t       *tsigctx;   /*%< TSIG verification context */
  158     unsigned int        sincetsig;  /*%< recvd since the last TSIG */
  159     dns_xfrindone_t     done;
  160 
  161     /*%
  162      * AXFR- and IXFR-specific data.  Only one is used at a time
  163      * according to the is_ixfr flag, so this could be a union,
  164      * but keeping them separate makes it a bit simpler to clean
  165      * things up when destroying the context.
  166      */
  167     dns_rdatacallbacks_t    axfr;
  168 
  169     struct {
  170         uint32_t    request_serial;
  171         uint32_t    current_serial;
  172         dns_journal_t   *journal;
  173 
  174     } ixfr;
  175 };
  176 
  177 #define XFRIN_MAGIC       ISC_MAGIC('X', 'f', 'r', 'I')
  178 #define VALID_XFRIN(x)        ISC_MAGIC_VALID(x, XFRIN_MAGIC)
  179 
  180 /**************************************************************************/
  181 /*
  182  * Forward declarations.
  183  */
  184 
  185 static isc_result_t
  186 xfrin_create(isc_mem_t *mctx,
  187          dns_zone_t *zone,
  188          dns_db_t *db,
  189          isc_task_t *task,
  190          isc_timermgr_t *timermgr,
  191          isc_socketmgr_t *socketmgr,
  192          dns_name_t *zonename,
  193          dns_rdataclass_t rdclass,
  194          dns_rdatatype_t reqtype,
  195          isc_sockaddr_t *masteraddr,
  196          isc_sockaddr_t *sourceaddr,
  197          isc_dscp_t dscp,
  198          dns_tsigkey_t *tsigkey,
  199          dns_xfrin_ctx_t **xfrp);
  200 
  201 static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
  202 static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
  203 static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
  204                    dns_name_t *name, dns_ttl_t ttl,
  205                    dns_rdata_t *rdata);
  206 static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
  207 static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
  208 static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr);
  209 
  210 static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
  211 static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
  212 static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
  213                  dns_name_t *name, dns_ttl_t ttl,
  214                  dns_rdata_t *rdata);
  215 static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
  216 
  217 static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
  218                uint32_t ttl, dns_rdata_t *rdata);
  219 
  220 static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
  221 
  222 static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
  223 static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
  224 static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
  225 static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
  226 static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
  227 
  228 static void maybe_free(dns_xfrin_ctx_t *xfr);
  229 
  230 static void
  231 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
  232 static isc_result_t
  233 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
  234 
  235 static void
  236 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
  237        const char *fmt, va_list ap)
  238      ISC_FORMAT_PRINTF(4, 0);
  239 
  240 static void
  241 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
  242        const char *fmt, ...)
  243      ISC_FORMAT_PRINTF(4, 5);
  244 
  245 static void
  246 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
  247      ISC_FORMAT_PRINTF(3, 4);
  248 
  249 /**************************************************************************/
  250 /*
  251  * AXFR handling
  252  */
  253 
  254 static isc_result_t
  255 axfr_init(dns_xfrin_ctx_t *xfr) {
  256     isc_result_t result;
  257 
  258     xfr->is_ixfr = false;
  259 
  260     if (xfr->db != NULL)
  261         dns_db_detach(&xfr->db);
  262 
  263     CHECK(axfr_makedb(xfr, &xfr->db));
  264     dns_rdatacallbacks_init(&xfr->axfr);
  265     CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
  266     result = ISC_R_SUCCESS;
  267  failure:
  268     return (result);
  269 }
  270 
  271 static isc_result_t
  272 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
  273     isc_result_t result;
  274 
  275     result = dns_db_create(xfr->mctx, /* XXX */
  276                    "rbt",   /* XXX guess */
  277                    &xfr->name,
  278                    dns_dbtype_zone,
  279                    xfr->rdclass,
  280                    0, NULL, /* XXX guess */
  281                    dbp);
  282     if (result == ISC_R_SUCCESS) {
  283         dns_zone_rpz_enable_db(xfr->zone, *dbp);
  284         dns_zone_catz_enable_db(xfr->zone, *dbp);
  285     }
  286     return (result);
  287 }
  288 
  289 static isc_result_t
  290 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
  291          dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
  292 {
  293     isc_result_t result;
  294 
  295     dns_difftuple_t *tuple = NULL;
  296 
  297     if (rdata->rdclass != xfr->rdclass)
  298         return(DNS_R_BADCLASS);
  299 
  300     CHECK(dns_zone_checknames(xfr->zone, name, rdata));
  301     CHECK(dns_difftuple_create(xfr->diff.mctx, op,
  302                    name, ttl, rdata, &tuple));
  303     dns_diff_append(&xfr->diff, &tuple);
  304     if (++xfr->difflen > 100)
  305         CHECK(axfr_apply(xfr));
  306     result = ISC_R_SUCCESS;
  307  failure:
  308     return (result);
  309 }
  310 
  311 /*
  312  * Store a set of AXFR RRs in the database.
  313  */
  314 static isc_result_t
  315 axfr_apply(dns_xfrin_ctx_t *xfr) {
  316     isc_result_t result;
  317     uint64_t records;
  318 
  319     CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private));
  320     xfr->difflen = 0;
  321     dns_diff_clear(&xfr->diff);
  322     if (xfr->maxrecords != 0U) {
  323         result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
  324         if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
  325             result = DNS_R_TOOMANYRECORDS;
  326             goto failure;
  327         }
  328     }
  329     result = ISC_R_SUCCESS;
  330  failure:
  331     return (result);
  332 }
  333 
  334 static isc_result_t
  335 axfr_commit(dns_xfrin_ctx_t *xfr) {
  336     isc_result_t result;
  337 
  338     CHECK(axfr_apply(xfr));
  339     CHECK(dns_db_endload(xfr->db, &xfr->axfr));
  340 
  341     result = ISC_R_SUCCESS;
  342  failure:
  343     return (result);
  344 }
  345 
  346 static isc_result_t
  347 axfr_finalize(dns_xfrin_ctx_t *xfr) {
  348     isc_result_t result;
  349 
  350     CHECK(dns_zone_replacedb(xfr->zone, xfr->db, true));
  351 
  352     result = ISC_R_SUCCESS;
  353  failure:
  354     return (result);
  355 }
  356 
  357 /**************************************************************************/
  358 /*
  359  * IXFR handling
  360  */
  361 
  362 static isc_result_t
  363 ixfr_init(dns_xfrin_ctx_t *xfr) {
  364     isc_result_t result;
  365     char *journalfile;
  366 
  367     if (xfr->reqtype != dns_rdatatype_ixfr) {
  368         xfrin_log(xfr, ISC_LOG_ERROR,
  369               "got incremental response to AXFR request");
  370         return (DNS_R_FORMERR);
  371     }
  372 
  373     xfr->is_ixfr = true;
  374     INSIST(xfr->db != NULL);
  375     xfr->difflen = 0;
  376 
  377     journalfile = dns_zone_getjournal(xfr->zone);
  378     if (journalfile != NULL)
  379         CHECK(dns_journal_open(xfr->mctx, journalfile,
  380                        DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
  381 
  382     result = ISC_R_SUCCESS;
  383  failure:
  384     return (result);
  385 }
  386 
  387 static isc_result_t
  388 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
  389          dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
  390 {
  391     isc_result_t result;
  392     dns_difftuple_t *tuple = NULL;
  393 
  394     if (rdata->rdclass != xfr->rdclass)
  395         return(DNS_R_BADCLASS);
  396 
  397     if (op == DNS_DIFFOP_ADD)
  398         CHECK(dns_zone_checknames(xfr->zone, name, rdata));
  399     CHECK(dns_difftuple_create(xfr->diff.mctx, op,
  400                    name, ttl, rdata, &tuple));
  401     dns_diff_append(&xfr->diff, &tuple);
  402     if (++xfr->difflen > 100)
  403         CHECK(ixfr_apply(xfr));
  404     result = ISC_R_SUCCESS;
  405  failure:
  406     return (result);
  407 }
  408 
  409 /*
  410  * Apply a set of IXFR changes to the database.
  411  */
  412 static isc_result_t
  413 ixfr_apply(dns_xfrin_ctx_t *xfr) {
  414     isc_result_t result;
  415     uint64_t records;
  416 
  417     if (xfr->ver == NULL) {
  418         CHECK(dns_db_newversion(xfr->db, &xfr->ver));
  419         if (xfr->ixfr.journal != NULL)
  420             CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
  421     }
  422     CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
  423     if (xfr->maxrecords != 0U) {
  424         result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
  425         if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
  426             result = DNS_R_TOOMANYRECORDS;
  427             goto failure;
  428         }
  429     }
  430     if (xfr->ixfr.journal != NULL) {
  431         result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
  432         if (result != ISC_R_SUCCESS)
  433             goto failure;
  434     }
  435     dns_diff_clear(&xfr->diff);
  436     xfr->difflen = 0;
  437     result = ISC_R_SUCCESS;
  438  failure:
  439     return (result);
  440 }
  441 
  442 static isc_result_t
  443 ixfr_commit(dns_xfrin_ctx_t *xfr) {
  444     isc_result_t result;
  445 
  446     CHECK(ixfr_apply(xfr));
  447     if (xfr->ver != NULL) {
  448         /* XXX enter ready-to-commit state here */
  449         if (xfr->ixfr.journal != NULL)
  450             CHECK(dns_journal_commit(xfr->ixfr.journal));
  451         dns_db_closeversion(xfr->db, &xfr->ver, true);
  452         dns_zone_markdirty(xfr->zone);
  453     }
  454     result = ISC_R_SUCCESS;
  455  failure:
  456     return (result);
  457 }
  458 
  459 /**************************************************************************/
  460 /*
  461  * Common AXFR/IXFR protocol code
  462  */
  463 
  464 /*
  465  * Handle a single incoming resource record according to the current
  466  * state.
  467  */
  468 static isc_result_t
  469 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
  470        dns_rdata_t *rdata)
  471 {
  472     isc_result_t result;
  473 
  474     xfr->nrecs++;
  475 
  476     if (rdata->type == dns_rdatatype_none ||
  477         dns_rdatatype_ismeta(rdata->type))
  478         FAIL(DNS_R_FORMERR);
  479 
  480  redo:
  481     switch (xfr->state) {
  482     case XFRST_SOAQUERY:
  483         if (rdata->type != dns_rdatatype_soa) {
  484             xfrin_log(xfr, ISC_LOG_ERROR,
  485                   "non-SOA response to SOA query");
  486             FAIL(DNS_R_FORMERR);
  487         }
  488         xfr->end_serial = dns_soa_getserial(rdata);
  489         if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
  490             !dns_zone_isforced(xfr->zone)) {
  491             xfrin_log(xfr, ISC_LOG_DEBUG(3),
  492                   "requested serial %u, "
  493                   "master has %u, not updating",
  494                   xfr->ixfr.request_serial, xfr->end_serial);
  495             FAIL(DNS_R_UPTODATE);
  496         }
  497         xfr->state = XFRST_GOTSOA;
  498         break;
  499 
  500     case XFRST_GOTSOA:
  501         /*
  502          * Skip other records in the answer section.
  503          */
  504         break;
  505 
  506     case XFRST_INITIALSOA:
  507         if (rdata->type != dns_rdatatype_soa) {
  508             xfrin_log(xfr, ISC_LOG_ERROR,
  509                   "first RR in zone transfer must be SOA");
  510             FAIL(DNS_R_FORMERR);
  511         }
  512         /*
  513          * Remember the serial number in the initial SOA.
  514          * We need it to recognize the end of an IXFR.
  515          */
  516         xfr->end_serial = dns_soa_getserial(rdata);
  517         if (xfr->reqtype == dns_rdatatype_ixfr &&
  518             ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial)
  519             && !dns_zone_isforced(xfr->zone))
  520         {
  521             /*
  522              * This must be the single SOA record that is
  523              * sent when the current version on the master
  524              * is not newer than the version in the request.
  525              */
  526             xfrin_log(xfr, ISC_LOG_DEBUG(3),
  527                   "requested serial %u, "
  528                   "master has %u, not updating",
  529                   xfr->ixfr.request_serial, xfr->end_serial);
  530             FAIL(DNS_R_UPTODATE);
  531         }
  532         if (xfr->reqtype == dns_rdatatype_axfr)
  533             xfr->checkid = false;
  534         xfr->state = XFRST_FIRSTDATA;
  535         break;
  536 
  537     case XFRST_FIRSTDATA:
  538         /*
  539          * If the transfer begins with one SOA record, it is an AXFR,
  540          * if it begins with two SOAs, it is an IXFR.
  541          */
  542         if (xfr->reqtype == dns_rdatatype_ixfr &&
  543             rdata->type == dns_rdatatype_soa &&
  544             xfr->ixfr.request_serial == dns_soa_getserial(rdata)) {
  545             xfrin_log(xfr, ISC_LOG_DEBUG(3),
  546                   "got incremental response");
  547             CHECK(ixfr_init(xfr));
  548             xfr->state = XFRST_IXFR_DELSOA;
  549         } else {
  550             xfrin_log(xfr, ISC_LOG_DEBUG(3),
  551                   "got nonincremental response");
  552             CHECK(axfr_init(xfr));
  553             xfr->state = XFRST_AXFR;
  554         }
  555         goto redo;
  556 
  557     case XFRST_IXFR_DELSOA:
  558         INSIST(rdata->type == dns_rdatatype_soa);
  559         CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
  560         xfr->state = XFRST_IXFR_DEL;
  561         break;
  562 
  563     case XFRST_IXFR_DEL:
  564         if (rdata->type == dns_rdatatype_soa) {
  565             uint32_t soa_serial = dns_soa_getserial(rdata);
  566             xfr->state = XFRST_IXFR_ADDSOA;
  567             xfr->ixfr.current_serial = soa_serial;
  568             goto redo;
  569         }
  570         CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
  571         break;
  572 
  573     case XFRST_IXFR_ADDSOA:
  574         INSIST(rdata->type == dns_rdatatype_soa);
  575         CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
  576         xfr->state = XFRST_IXFR_ADD;
  577         break;
  578 
  579     case XFRST_IXFR_ADD:
  580         if (rdata->type == dns_rdatatype_soa) {
  581             uint32_t soa_serial = dns_soa_getserial(rdata);
  582             if (soa_serial == xfr->end_serial) {
  583                 CHECK(ixfr_commit(xfr));
  584                 xfr->state = XFRST_IXFR_END;
  585                 break;
  586             } else if (soa_serial != xfr->ixfr.current_serial) {
  587                 xfrin_log(xfr, ISC_LOG_ERROR,
  588                       "IXFR out of sync: "
  589                       "expected serial %u, got %u",
  590                       xfr->ixfr.current_serial, soa_serial);
  591                 FAIL(DNS_R_FORMERR);
  592             } else {
  593                 CHECK(ixfr_commit(xfr));
  594                 xfr->state = XFRST_IXFR_DELSOA;
  595                 goto redo;
  596             }
  597         }
  598         if (rdata->type == dns_rdatatype_ns &&
  599             dns_name_iswildcard(name))
  600             FAIL(DNS_R_INVALIDNS);
  601         CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
  602         break;
  603 
  604     case XFRST_AXFR:
  605         /*
  606          * Old BINDs sent cross class A records for non IN classes.
  607          */
  608         if (rdata->type == dns_rdatatype_a &&
  609             rdata->rdclass != xfr->rdclass &&
  610             xfr->rdclass != dns_rdataclass_in)
  611             break;
  612         CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
  613         if (rdata->type == dns_rdatatype_soa) {
  614             CHECK(axfr_commit(xfr));
  615             xfr->state = XFRST_AXFR_END;
  616             break;
  617         }
  618         break;
  619     case XFRST_AXFR_END:
  620     case XFRST_IXFR_END:
  621         FAIL(DNS_R_EXTRADATA);
  622         /* NOTREACHED */
  623         /* FALLTHROUGH */
  624     default:
  625         INSIST(0);
  626         ISC_UNREACHABLE();
  627     }
  628     result = ISC_R_SUCCESS;
  629  failure:
  630     return (result);
  631 }
  632 
  633 isc_result_t
  634 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
  635          isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
  636          isc_mem_t *mctx, isc_timermgr_t *timermgr,
  637          isc_socketmgr_t *socketmgr, isc_task_t *task,
  638          dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
  639 {
  640     isc_sockaddr_t sourceaddr;
  641     isc_dscp_t dscp;
  642 
  643     switch (isc_sockaddr_pf(masteraddr)) {
  644     case PF_INET:
  645         sourceaddr = *dns_zone_getxfrsource4(zone);
  646         dscp = dns_zone_getxfrsource4dscp(zone);
  647         break;
  648     case PF_INET6:
  649         sourceaddr = *dns_zone_getxfrsource6(zone);
  650         dscp = dns_zone_getxfrsource6dscp(zone);
  651         break;
  652     default:
  653         INSIST(0);
  654         ISC_UNREACHABLE();
  655     }
  656 
  657     return(dns_xfrin_create3(zone, xfrtype, masteraddr, &sourceaddr,
  658                  dscp, tsigkey, mctx, timermgr, socketmgr,
  659                  task, done, xfrp));
  660 }
  661 
  662 isc_result_t
  663 dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
  664           isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
  665           dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
  666           isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
  667           isc_task_t *task, dns_xfrindone_t done,
  668           dns_xfrin_ctx_t **xfrp)
  669 {
  670     return (dns_xfrin_create3(zone, xfrtype, masteraddr, sourceaddr, -1,
  671                   tsigkey, mctx, timermgr, socketmgr, task,
  672                   done, xfrp));
  673 }
  674 
  675 isc_result_t
  676 dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype,
  677           isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
  678           isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
  679           isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
  680           isc_task_t *task, dns_xfrindone_t done,
  681           dns_xfrin_ctx_t **xfrp)
  682 {
  683     dns_name_t *zonename = dns_zone_getorigin(zone);
  684     dns_xfrin_ctx_t *xfr = NULL;
  685     isc_result_t result;
  686     dns_db_t *db = NULL;
  687 
  688     REQUIRE(xfrp != NULL && *xfrp == NULL);
  689 
  690     (void)dns_zone_getdb(zone, &db);
  691 
  692     if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
  693         REQUIRE(db != NULL);
  694 
  695     CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
  696                dns_zone_getclass(zone), xfrtype, masteraddr,
  697                sourceaddr, dscp, tsigkey, &xfr));
  698 
  699     CHECK(xfrin_start(xfr));
  700 
  701     xfr->done = done;
  702     if (xfr->done != NULL)
  703         xfr->refcount++;
  704     *xfrp = xfr;
  705 
  706  failure:
  707     if (db != NULL)
  708         dns_db_detach(&db);
  709     if (result != ISC_R_SUCCESS) {
  710         char zonetext[DNS_NAME_MAXTEXT+32];
  711         dns_zone_name(zone, zonetext, sizeof(zonetext));
  712         xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
  713                "zone transfer setup failed");
  714     }
  715     return (result);
  716 }
  717 
  718 void
  719 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
  720     if (! xfr->shuttingdown)
  721         xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
  722 }
  723 
  724 void
  725 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
  726     REQUIRE(target != NULL && *target == NULL);
  727     source->refcount++;
  728     *target = source;
  729 }
  730 
  731 void
  732 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
  733     dns_xfrin_ctx_t *xfr = *xfrp;
  734     INSIST(xfr->refcount > 0);
  735     xfr->refcount--;
  736     maybe_free(xfr);
  737     *xfrp = NULL;
  738 }
  739 
  740 static void
  741 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
  742     if (xfr->connects > 0) {
  743         isc_socket_cancel(xfr->socket, xfr->task,
  744                   ISC_SOCKCANCEL_CONNECT);
  745     } else if (xfr->recvs > 0) {
  746         dns_tcpmsg_cancelread(&xfr->tcpmsg);
  747     } else if (xfr->sends > 0) {
  748         isc_socket_cancel(xfr->socket, xfr->task,
  749                   ISC_SOCKCANCEL_SEND);
  750     }
  751 }
  752 
  753 static void
  754 xfrin_reset(dns_xfrin_ctx_t *xfr) {
  755     REQUIRE(VALID_XFRIN(xfr));
  756 
  757     xfrin_log(xfr, ISC_LOG_INFO, "resetting");
  758 
  759     xfrin_cancelio(xfr);
  760 
  761     if (xfr->socket != NULL)
  762         isc_socket_detach(&xfr->socket);
  763 
  764     if (xfr->lasttsig != NULL)
  765         isc_buffer_free(&xfr->lasttsig);
  766 
  767     dns_diff_clear(&xfr->diff);
  768     xfr->difflen = 0;
  769 
  770     if (xfr->ixfr.journal != NULL)
  771         dns_journal_destroy(&xfr->ixfr.journal);
  772 
  773     if (xfr->axfr.add_private != NULL)
  774         (void)dns_db_endload(xfr->db, &xfr->axfr);
  775 
  776     if (xfr->tcpmsg_valid) {
  777         dns_tcpmsg_invalidate(&xfr->tcpmsg);
  778         xfr->tcpmsg_valid = false;
  779     }
  780 
  781     if (xfr->ver != NULL)
  782         dns_db_closeversion(xfr->db, &xfr->ver, false);
  783 }
  784 
  785 
  786 static void
  787 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
  788     if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) {
  789         xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
  790               msg, isc_result_totext(result));
  791         if (xfr->is_ixfr)
  792             /* Pass special result code to force AXFR retry */
  793             result = DNS_R_BADIXFR;
  794     }
  795     xfrin_cancelio(xfr);
  796     /*
  797      * Close the journal.
  798      */
  799     if (xfr->ixfr.journal != NULL)
  800         dns_journal_destroy(&xfr->ixfr.journal);
  801     if (xfr->done != NULL) {
  802         (xfr->done)(xfr->zone, result);
  803         xfr->done = NULL;
  804     }
  805     xfr->shuttingdown = true;
  806     xfr->shutdown_result = result;
  807     maybe_free(xfr);
  808 }
  809 
  810 static isc_result_t
  811 xfrin_create(isc_mem_t *mctx,
  812          dns_zone_t *zone,
  813          dns_db_t *db,
  814          isc_task_t *task,
  815          isc_timermgr_t *timermgr,
  816          isc_socketmgr_t *socketmgr,
  817          dns_name_t *zonename,
  818          dns_rdataclass_t rdclass,
  819          dns_rdatatype_t reqtype,
  820          isc_sockaddr_t *masteraddr,
  821          isc_sockaddr_t *sourceaddr,
  822          isc_dscp_t dscp,
  823          dns_tsigkey_t *tsigkey,
  824          dns_xfrin_ctx_t **xfrp)
  825 {
  826     dns_xfrin_ctx_t *xfr = NULL;
  827     isc_result_t result;
  828     uint32_t tmp;
  829 
  830     xfr = isc_mem_get(mctx, sizeof(*xfr));
  831     if (xfr == NULL)
  832         return (ISC_R_NOMEMORY);
  833     xfr->mctx = NULL;
  834     isc_mem_attach(mctx, &xfr->mctx);
  835     xfr->refcount = 0;
  836     xfr->zone = NULL;
  837     dns_zone_iattach(zone, &xfr->zone);
  838     xfr->task = NULL;
  839     isc_task_attach(task, &xfr->task);
  840     xfr->timer = NULL;
  841     xfr->socketmgr = socketmgr;
  842     xfr->done = NULL;
  843 
  844     xfr->connects = 0;
  845     xfr->sends = 0;
  846     xfr->recvs = 0;
  847     xfr->shuttingdown = false;
  848     xfr->shutdown_result = ISC_R_UNSET;
  849 
  850     dns_name_init(&xfr->name, NULL);
  851     xfr->rdclass = rdclass;
  852     isc_random_get(&tmp);
  853     xfr->checkid = true;
  854     xfr->id = (uint16_t)(tmp & 0xffff);
  855     xfr->logit = true;
  856     xfr->reqtype = reqtype;
  857     xfr->dscp = dscp;
  858 
  859     /* sockaddr */
  860     xfr->socket = NULL;
  861     /* qbuffer */
  862     /* qbuffer_data */
  863     /* tcpmsg */
  864     xfr->tcpmsg_valid = false;
  865 
  866     xfr->db = NULL;
  867     if (db != NULL)
  868         dns_db_attach(db, &xfr->db);
  869     xfr->ver = NULL;
  870     dns_diff_init(xfr->mctx, &xfr->diff);
  871     xfr->difflen = 0;
  872 
  873     if (reqtype == dns_rdatatype_soa)
  874         xfr->state = XFRST_SOAQUERY;
  875     else
  876         xfr->state = XFRST_INITIALSOA;
  877     /* end_serial */
  878 
  879     xfr->nmsg = 0;
  880     xfr->nrecs = 0;
  881     xfr->nbytes = 0;
  882     xfr->maxrecords = dns_zone_getmaxrecords(zone);
  883     isc_time_now(&xfr->start);
  884 
  885     xfr->tsigkey = NULL;
  886     if (tsigkey != NULL)
  887         dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
  888     xfr->lasttsig = NULL;
  889     xfr->tsigctx = NULL;
  890     xfr->sincetsig = 0;
  891     xfr->is_ixfr = false;
  892 
  893     /* ixfr.request_serial */
  894     /* ixfr.current_serial */
  895     xfr->ixfr.journal = NULL;
  896 
  897     xfr->axfr.add = NULL;
  898     xfr->axfr.add_private = NULL;
  899 
  900     CHECK(dns_name_dup(zonename, mctx, &xfr->name));
  901 
  902     CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
  903                    task, xfrin_timeout, xfr, &xfr->timer));
  904     CHECK(dns_timer_setidle(xfr->timer,
  905                 dns_zone_getmaxxfrin(xfr->zone),
  906                 dns_zone_getidlein(xfr->zone),
  907                 false));
  908 
  909     xfr->masteraddr = *masteraddr;
  910 
  911     INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
  912     xfr->sourceaddr = *sourceaddr;
  913     isc_sockaddr_setport(&xfr->sourceaddr, 0);
  914 
  915     /*
  916      * Reserve 2 bytes for TCP length at the beginning of the buffer.
  917      */
  918     isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
  919             sizeof(xfr->qbuffer_data) - 2);
  920 
  921     xfr->magic = XFRIN_MAGIC;
  922     *xfrp = xfr;
  923     return (ISC_R_SUCCESS);
  924 
  925  failure:
  926     if (xfr->timer != NULL)
  927         isc_timer_detach(&xfr->timer);
  928     if (dns_name_dynamic(&xfr->name))
  929         dns_name_free(&xfr->name, xfr->mctx);
  930     if (xfr->tsigkey != NULL)
  931         dns_tsigkey_detach(&xfr->tsigkey);
  932     if (xfr->db != NULL)
  933         dns_db_detach(&xfr->db);
  934     isc_task_detach(&xfr->task);
  935     dns_zone_idetach(&xfr->zone);
  936     isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
  937 
  938     return (result);
  939 }
  940 
  941 static isc_result_t
  942 xfrin_start(dns_xfrin_ctx_t *xfr) {
  943     isc_result_t result;
  944     CHECK(isc_socket_create(xfr->socketmgr,
  945                 isc_sockaddr_pf(&xfr->sourceaddr),
  946                 isc_sockettype_tcp,
  947                 &xfr->socket));
  948     isc_socket_setname(xfr->socket, "xfrin", NULL);
  949 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
  950     CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
  951                   ISC_SOCKET_REUSEADDRESS));
  952 #endif
  953     isc_socket_dscp(xfr->socket, xfr->dscp);
  954     CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
  955                  xfrin_connect_done, xfr));
  956     xfr->connects++;
  957     return (ISC_R_SUCCESS);
  958  failure:
  959     xfrin_fail(xfr, result, "failed setting up socket");
  960     return (result);
  961 }
  962 
  963 /* XXX the resolver could use this, too */
  964 
  965 static isc_result_t
  966 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
  967     dns_compress_t cctx;
  968     bool cleanup_cctx = false;
  969     isc_result_t result;
  970 
  971     CHECK(dns_compress_init(&cctx, -1, mctx));
  972     cleanup_cctx = true;
  973     CHECK(dns_message_renderbegin(msg, &cctx, buf));
  974     CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
  975     CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
  976     CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
  977     CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
  978     CHECK(dns_message_renderend(msg));
  979     result = ISC_R_SUCCESS;
  980  failure:
  981     if (cleanup_cctx)
  982         dns_compress_invalidate(&cctx);
  983     return (result);
  984 }
  985 
  986 /*
  987  * A connection has been established.
  988  */
  989 static void
  990 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
  991     isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
  992     dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
  993     isc_result_t result = cev->result;
  994     char sourcetext[ISC_SOCKADDR_FORMATSIZE];
  995     char signerbuf[DNS_NAME_FORMATSIZE];
  996     const char *signer = "", *sep = "";
  997     isc_sockaddr_t sockaddr;
  998     dns_zonemgr_t * zmgr;
  999     isc_time_t now;
 1000 
 1001     REQUIRE(VALID_XFRIN(xfr));
 1002 
 1003     UNUSED(task);
 1004 
 1005     INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
 1006     isc_event_free(&event);
 1007 
 1008     xfr->connects--;
 1009     if (xfr->shuttingdown) {
 1010         maybe_free(xfr);
 1011         return;
 1012     }
 1013 
 1014     zmgr = dns_zone_getmgr(xfr->zone);
 1015     if (zmgr != NULL) {
 1016         if (result != ISC_R_SUCCESS) {
 1017             TIME_NOW(&now);
 1018             dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
 1019                            &xfr->sourceaddr, &now);
 1020             goto failure;
 1021         } else
 1022             dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
 1023                            &xfr->sourceaddr);
 1024     }
 1025 
 1026     result = isc_socket_getsockname(xfr->socket, &sockaddr);
 1027     if (result == ISC_R_SUCCESS) {
 1028         isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
 1029     } else {
 1030         strlcpy(sourcetext, "<UNKNOWN>", sizeof(sourcetext));
 1031     }
 1032 
 1033     if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
 1034         dns_name_format(dst_key_name(xfr->tsigkey->key),
 1035                 signerbuf, sizeof(signerbuf));
 1036         sep = " TSIG ";
 1037         signer = signerbuf;
 1038     }
 1039 
 1040     xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s",
 1041           sourcetext, sep, signer);
 1042 
 1043     dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
 1044     xfr->tcpmsg_valid = true;
 1045 
 1046     CHECK(xfrin_send_request(xfr));
 1047  failure:
 1048     if (result != ISC_R_SUCCESS)
 1049         xfrin_fail(xfr, result, "failed to connect");
 1050 }
 1051 
 1052 /*
 1053  * Convert a tuple into a dns_name_t suitable for inserting
 1054  * into the given dns_message_t.
 1055  */
 1056 static isc_result_t
 1057 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
 1058 {
 1059     isc_result_t result;
 1060     dns_rdata_t *rdata = NULL;
 1061     dns_rdatalist_t *rdl = NULL;
 1062     dns_rdataset_t *rds = NULL;
 1063     dns_name_t *name = NULL;
 1064 
 1065     REQUIRE(target != NULL && *target == NULL);
 1066 
 1067     CHECK(dns_message_gettemprdata(msg, &rdata));
 1068     dns_rdata_init(rdata);
 1069     dns_rdata_clone(&tuple->rdata, rdata);
 1070 
 1071     CHECK(dns_message_gettemprdatalist(msg, &rdl));
 1072     dns_rdatalist_init(rdl);
 1073     rdl->type = tuple->rdata.type;
 1074     rdl->rdclass = tuple->rdata.rdclass;
 1075     rdl->ttl = tuple->ttl;
 1076     ISC_LIST_APPEND(rdl->rdata, rdata, link);
 1077 
 1078     CHECK(dns_message_gettemprdataset(msg, &rds));
 1079     CHECK(dns_rdatalist_tordataset(rdl, rds));
 1080 
 1081     CHECK(dns_message_gettempname(msg, &name));
 1082     dns_name_init(name, NULL);
 1083     dns_name_clone(&tuple->name, name);
 1084     ISC_LIST_APPEND(name->list, rds, link);
 1085 
 1086     *target = name;
 1087     return (ISC_R_SUCCESS);
 1088 
 1089  failure:
 1090 
 1091     if (rds != NULL) {
 1092         dns_rdataset_disassociate(rds);
 1093         dns_message_puttemprdataset(msg, &rds);
 1094     }
 1095     if (rdl != NULL) {
 1096         ISC_LIST_UNLINK(rdl->rdata, rdata, link);
 1097         dns_message_puttemprdatalist(msg, &rdl);
 1098     }
 1099     if (rdata != NULL)
 1100         dns_message_puttemprdata(msg, &rdata);
 1101 
 1102     return (result);
 1103 }
 1104 
 1105 
 1106 /*
 1107  * Build an *XFR request and send its length prefix.
 1108  */
 1109 static isc_result_t
 1110 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
 1111     isc_result_t result;
 1112     isc_region_t region;
 1113     dns_rdataset_t *qrdataset = NULL;
 1114     dns_message_t *msg = NULL;
 1115     dns_difftuple_t *soatuple = NULL;
 1116     dns_name_t *qname = NULL;
 1117     dns_dbversion_t *ver = NULL;
 1118     dns_name_t *msgsoaname = NULL;
 1119 
 1120     /* Create the request message */
 1121     CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
 1122     CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
 1123 
 1124     /* Create a name for the question section. */
 1125     CHECK(dns_message_gettempname(msg, &qname));
 1126     dns_name_init(qname, NULL);
 1127     dns_name_clone(&xfr->name, qname);
 1128 
 1129     /* Formulate the question and attach it to the question name. */
 1130     CHECK(dns_message_gettemprdataset(msg, &qrdataset));
 1131     dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
 1132     ISC_LIST_APPEND(qname->list, qrdataset, link);
 1133     qrdataset = NULL;
 1134 
 1135     dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
 1136     qname = NULL;
 1137 
 1138     if (xfr->reqtype == dns_rdatatype_ixfr) {
 1139         /* Get the SOA and add it to the authority section. */
 1140         /* XXX is using the current version the right thing? */
 1141         dns_db_currentversion(xfr->db, &ver);
 1142         CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
 1143                         DNS_DIFFOP_EXISTS, &soatuple));
 1144         xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
 1145         xfr->ixfr.current_serial = xfr->ixfr.request_serial;
 1146         xfrin_log(xfr, ISC_LOG_DEBUG(3),
 1147               "requesting IXFR for serial %u",
 1148               xfr->ixfr.request_serial);
 1149 
 1150         CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
 1151         dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
 1152     } else if (xfr->reqtype == dns_rdatatype_soa)
 1153         CHECK(dns_db_getsoaserial(xfr->db, NULL,
 1154                       &xfr->ixfr.request_serial));
 1155 
 1156     xfr->checkid = true;
 1157     xfr->logit = true;
 1158     xfr->id++;
 1159     xfr->nmsg = 0;
 1160     xfr->nrecs = 0;
 1161     xfr->nbytes = 0;
 1162     isc_time_now(&xfr->start);
 1163     msg->id = xfr->id;
 1164     if (xfr->tsigctx != NULL)
 1165         dst_context_destroy(&xfr->tsigctx);
 1166 
 1167     CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
 1168 
 1169     /*
 1170      * Free the last tsig, if there is one.
 1171      */
 1172     if (xfr->lasttsig != NULL)
 1173         isc_buffer_free(&xfr->lasttsig);
 1174 
 1175     /*
 1176      * Save the query TSIG and don't let message_destroy free it.
 1177      */
 1178     CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
 1179 
 1180     isc_buffer_usedregion(&xfr->qbuffer, &region);
 1181     INSIST(region.length <= 65535);
 1182 
 1183     /*
 1184      * Record message length and adjust region to include TCP
 1185      * length field.
 1186      */
 1187     xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
 1188     xfr->qbuffer_data[1] = region.length & 0xff;
 1189     region.base -= 2;
 1190     region.length += 2;
 1191     CHECK(isc_socket_send(xfr->socket, &region, xfr->task,
 1192                   xfrin_send_done, xfr));
 1193     xfr->sends++;
 1194 
 1195  failure:
 1196     if (qname != NULL)
 1197         dns_message_puttempname(msg, &qname);
 1198     if (qrdataset != NULL)
 1199         dns_message_puttemprdataset(msg, &qrdataset);
 1200     if (msg != NULL)
 1201         dns_message_destroy(&msg);
 1202     if (soatuple != NULL)
 1203         dns_difftuple_free(&soatuple);
 1204     if (ver != NULL)
 1205         dns_db_closeversion(xfr->db, &ver, false);
 1206     return (result);
 1207 }
 1208 
 1209 static void
 1210 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
 1211     isc_socketevent_t *sev = (isc_socketevent_t *) event;
 1212     dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
 1213     isc_result_t result;
 1214 
 1215     REQUIRE(VALID_XFRIN(xfr));
 1216 
 1217     UNUSED(task);
 1218 
 1219     INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
 1220 
 1221     xfr->sends--;
 1222     xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
 1223     CHECK(sev->result);
 1224 
 1225     CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
 1226                      xfrin_recv_done, xfr));
 1227     xfr->recvs++;
 1228  failure:
 1229     isc_event_free(&event);
 1230     if (result != ISC_R_SUCCESS)
 1231         xfrin_fail(xfr, result, "failed sending request data");
 1232 }
 1233 
 1234 
 1235 static void
 1236 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
 1237     dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
 1238     isc_result_t result;
 1239     dns_message_t *msg = NULL;
 1240     dns_name_t *name;
 1241     dns_tcpmsg_t *tcpmsg;
 1242     dns_name_t *tsigowner = NULL;
 1243 
 1244     REQUIRE(VALID_XFRIN(xfr));
 1245 
 1246     UNUSED(task);
 1247 
 1248     INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
 1249     tcpmsg = ev->ev_sender;
 1250     isc_event_free(&ev);
 1251 
 1252     xfr->recvs--;
 1253     if (xfr->shuttingdown) {
 1254         maybe_free(xfr);
 1255         return;
 1256     }
 1257 
 1258     CHECK(tcpmsg->result);
 1259 
 1260     xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
 1261           tcpmsg->buffer.used);
 1262 
 1263     CHECK(isc_timer_touch(xfr->timer));
 1264 
 1265     CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
 1266 
 1267     CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
 1268     CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
 1269 
 1270     msg->tsigctx = xfr->tsigctx;
 1271     xfr->tsigctx = NULL;
 1272 
 1273     dns_message_setclass(msg, xfr->rdclass);
 1274 
 1275     if (xfr->nmsg > 0)
 1276         msg->tcp_continuation = 1;
 1277 
 1278     result = dns_message_parse(msg, &tcpmsg->buffer,
 1279                    DNS_MESSAGEPARSE_PRESERVEORDER);
 1280 
 1281     if (result == ISC_R_SUCCESS)
 1282         dns_message_logpacket2(msg, "received message from",
 1283                        &tcpmsg->address,
 1284                        DNS_LOGCATEGORY_XFER_IN,
 1285                        DNS_LOGMODULE_XFER_IN,
 1286                        ISC_LOG_DEBUG(10), xfr->mctx);
 1287     else
 1288         xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
 1289               dns_result_totext(result));
 1290 
 1291     if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
 1292         msg->opcode != dns_opcode_query ||msg->rdclass != xfr->rdclass ||
 1293         (xfr->checkid && msg->id != xfr->id)) {
 1294         if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
 1295             result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
 1296         else if (result == ISC_R_SUCCESS &&
 1297              msg->opcode != dns_opcode_query)
 1298             result = DNS_R_UNEXPECTEDOPCODE;
 1299         else if (result == ISC_R_SUCCESS &&
 1300              msg->rdclass != xfr->rdclass)
 1301             result = DNS_R_BADCLASS;
 1302         else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
 1303             result = DNS_R_UNEXPECTEDID;
 1304         if (xfr->reqtype == dns_rdatatype_axfr ||
 1305             xfr->reqtype == dns_rdatatype_soa)
 1306             goto failure;
 1307         xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
 1308                isc_result_totext(result));
 1309  try_axfr:
 1310         dns_message_destroy(&msg);
 1311         xfrin_reset(xfr);
 1312         xfr->reqtype = dns_rdatatype_soa;
 1313         xfr->state = XFRST_SOAQUERY;
 1314         (void)xfrin_start(xfr);
 1315         return;
 1316     } else if (!xfr->checkid && msg->id != xfr->id && xfr->logit) {
 1317         xfrin_log(xfr, ISC_LOG_WARNING,
 1318               "detected message ID mismatch on incoming AXFR "
 1319               "stream, transfer will fail in BIND 9.17.2 and "
 1320               "later if AXFR source is not fixed");
 1321         xfr->logit = false;
 1322     }
 1323 
 1324     /*
 1325      * Does the server know about IXFR?  If it doesn't we will get
 1326      * a message with a empty answer section or a potentially a CNAME /
 1327      * DNAME, the later is handled by xfr_rr() which will return FORMERR
 1328      * if the first RR in the answer section is not a SOA record.
 1329      */
 1330     if (xfr->reqtype == dns_rdatatype_ixfr &&
 1331         xfr->state == XFRST_INITIALSOA &&
 1332         msg->counts[DNS_SECTION_ANSWER] == 0) {
 1333         xfrin_log(xfr, ISC_LOG_DEBUG(3),
 1334               "empty answer section, retrying with AXFR");
 1335         goto try_axfr;
 1336     }
 1337 
 1338     if (xfr->reqtype == dns_rdatatype_soa &&
 1339         (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
 1340         FAIL(DNS_R_NOTAUTHORITATIVE);
 1341     }
 1342 
 1343 
 1344     result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
 1345     if (result != ISC_R_SUCCESS) {
 1346         xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
 1347                isc_result_totext(result));
 1348         goto failure;
 1349     }
 1350 
 1351     for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
 1352          result == ISC_R_SUCCESS;
 1353          result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
 1354     {
 1355         dns_rdataset_t *rds;
 1356 
 1357         name = NULL;
 1358         dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
 1359         for (rds = ISC_LIST_HEAD(name->list);
 1360              rds != NULL;
 1361              rds = ISC_LIST_NEXT(rds, link))
 1362         {
 1363             for (result = dns_rdataset_first(rds);
 1364                  result == ISC_R_SUCCESS;
 1365                  result = dns_rdataset_next(rds))
 1366             {
 1367                 dns_rdata_t rdata = DNS_RDATA_INIT;
 1368                 dns_rdataset_current(rds, &rdata);
 1369                 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
 1370             }
 1371         }
 1372     }
 1373     if (result != ISC_R_NOMORE)
 1374         goto failure;
 1375 
 1376     if (dns_message_gettsig(msg, &tsigowner) != NULL) {
 1377         /*
 1378          * Reset the counter.
 1379          */
 1380         xfr->sincetsig = 0;
 1381 
 1382         /*
 1383          * Free the last tsig, if there is one.
 1384          */
 1385         if (xfr->lasttsig != NULL)
 1386             isc_buffer_free(&xfr->lasttsig);
 1387 
 1388         /*
 1389          * Update the last tsig pointer.
 1390          */
 1391         CHECK(dns_message_getquerytsig(msg, xfr->mctx,
 1392                            &xfr->lasttsig));
 1393 
 1394     } else if (dns_message_gettsigkey(msg) != NULL) {
 1395         xfr->sincetsig++;
 1396         if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
 1397             xfr->state == XFRST_AXFR_END ||
 1398             xfr->state == XFRST_IXFR_END)
 1399         {
 1400             result = DNS_R_EXPECTEDTSIG;
 1401             goto failure;
 1402         }
 1403     }
 1404 
 1405     /*
 1406      * Update the number of messages received.
 1407      */
 1408     xfr->nmsg++;
 1409 
 1410     /*
 1411      * Update the number of bytes received.
 1412      */
 1413     xfr->nbytes += tcpmsg->buffer.used;
 1414 
 1415     /*
 1416      * Take the context back.
 1417      */
 1418     INSIST(xfr->tsigctx == NULL);
 1419     xfr->tsigctx = msg->tsigctx;
 1420     msg->tsigctx = NULL;
 1421 
 1422     dns_message_destroy(&msg);
 1423 
 1424     switch (xfr->state) {
 1425     case XFRST_GOTSOA:
 1426         xfr->reqtype = dns_rdatatype_axfr;
 1427         xfr->state = XFRST_INITIALSOA;
 1428         CHECK(xfrin_send_request(xfr));
 1429         break;
 1430     case XFRST_AXFR_END:
 1431         CHECK(axfr_finalize(xfr));
 1432         /* FALLTHROUGH */
 1433     case XFRST_IXFR_END:
 1434         /*
 1435          * Close the journal.
 1436          */
 1437         if (xfr->ixfr.journal != NULL)
 1438             dns_journal_destroy(&xfr->ixfr.journal);
 1439 
 1440         /*
 1441          * Inform the caller we succeeded.
 1442          */
 1443         if (xfr->done != NULL) {
 1444             (xfr->done)(xfr->zone, ISC_R_SUCCESS);
 1445             xfr->done = NULL;
 1446         }
 1447         /*
 1448          * We should have no outstanding events at this
 1449          * point, thus maybe_free() should succeed.
 1450          */
 1451         xfr->shuttingdown = true;
 1452         xfr->shutdown_result = ISC_R_SUCCESS;
 1453         maybe_free(xfr);
 1454         break;
 1455     default:
 1456         /*
 1457          * Read the next message.
 1458          */
 1459         CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
 1460                          xfrin_recv_done, xfr));
 1461         xfr->recvs++;
 1462     }
 1463     return;
 1464 
 1465  failure:
 1466     if (msg != NULL)
 1467         dns_message_destroy(&msg);
 1468     if (result != ISC_R_SUCCESS)
 1469         xfrin_fail(xfr, result, "failed while receiving responses");
 1470 }
 1471 
 1472 static void
 1473 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
 1474     dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
 1475 
 1476     REQUIRE(VALID_XFRIN(xfr));
 1477 
 1478     UNUSED(task);
 1479 
 1480     isc_event_free(&event);
 1481     /*
 1482      * This will log "giving up: timeout".
 1483      */
 1484     xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
 1485 }
 1486 
 1487 static void
 1488 maybe_free(dns_xfrin_ctx_t *xfr) {
 1489     uint64_t msecs;
 1490     uint64_t persec;
 1491     const char *result_str;
 1492 
 1493     REQUIRE(VALID_XFRIN(xfr));
 1494 
 1495     if (! xfr->shuttingdown || xfr->refcount != 0 ||
 1496         xfr->connects != 0 || xfr->sends != 0 ||
 1497         xfr->recvs != 0)
 1498         return;
 1499 
 1500     INSIST(! xfr->shuttingdown || xfr->shutdown_result != ISC_R_UNSET);
 1501 
 1502     /* If we're called through dns_xfrin_detach() and are not
 1503      * shutting down, we can't know what the transfer status is as
 1504      * we are only called when the last reference is lost.
 1505      */
 1506     result_str = (xfr->shuttingdown ?
 1507               isc_result_totext(xfr->shutdown_result) : "unknown");
 1508     xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str);
 1509 
 1510     /*
 1511      * Calculate the length of time the transfer took,
 1512      * and print a log message with the bytes and rate.
 1513      */
 1514     isc_time_now(&xfr->end);
 1515     msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
 1516     if (msecs == 0)
 1517         msecs = 1;
 1518     persec = (xfr->nbytes * 1000) / msecs;
 1519     xfrin_log(xfr, ISC_LOG_INFO,
 1520           "Transfer completed: %d messages, %d records, "
 1521           "%" PRIu64 " bytes, "
 1522           "%u.%03u secs (%u bytes/sec)",
 1523           xfr->nmsg, xfr->nrecs, xfr->nbytes,
 1524           (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000),
 1525           (unsigned int) persec);
 1526 
 1527     if (xfr->socket != NULL)
 1528         isc_socket_detach(&xfr->socket);
 1529 
 1530     if (xfr->timer != NULL)
 1531         isc_timer_detach(&xfr->timer);
 1532 
 1533     if (xfr->task != NULL)
 1534         isc_task_detach(&xfr->task);
 1535 
 1536     if (xfr->tsigkey != NULL)
 1537         dns_tsigkey_detach(&xfr->tsigkey);
 1538 
 1539     if (xfr->lasttsig != NULL)
 1540         isc_buffer_free(&xfr->lasttsig);
 1541 
 1542     dns_diff_clear(&xfr->diff);
 1543 
 1544     if (xfr->ixfr.journal != NULL)
 1545         dns_journal_destroy(&xfr->ixfr.journal);
 1546 
 1547     if (xfr->axfr.add_private != NULL)
 1548         (void)dns_db_endload(xfr->db, &xfr->axfr);
 1549 
 1550     if (xfr->tcpmsg_valid)
 1551         dns_tcpmsg_invalidate(&xfr->tcpmsg);
 1552 
 1553     if (xfr->tsigctx != NULL)
 1554         dst_context_destroy(&xfr->tsigctx);
 1555 
 1556     if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
 1557         dns_name_free(&xfr->name, xfr->mctx);
 1558 
 1559     if (xfr->ver != NULL)
 1560         dns_db_closeversion(xfr->db, &xfr->ver, false);
 1561 
 1562     if (xfr->db != NULL)
 1563         dns_db_detach(&xfr->db);
 1564 
 1565     if (xfr->zone != NULL)
 1566         dns_zone_idetach(&xfr->zone);
 1567 
 1568     isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
 1569 }
 1570 
 1571 /*
 1572  * Log incoming zone transfer messages in a format like
 1573  * transfer of <zone> from <address>: <message>
 1574  */
 1575 static void
 1576 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
 1577        const char *fmt, va_list ap)
 1578 {
 1579     char mastertext[ISC_SOCKADDR_FORMATSIZE];
 1580     char msgtext[2048];
 1581 
 1582     isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
 1583     vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
 1584 
 1585     isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
 1586               DNS_LOGMODULE_XFER_IN, level,
 1587               "transfer of '%s' from %s: %s",
 1588               zonetext, mastertext, msgtext);
 1589 }
 1590 
 1591 /*
 1592  * Logging function for use when a xfrin_ctx_t has not yet been created.
 1593  */
 1594 
 1595 static void
 1596 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
 1597        const char *fmt, ...)
 1598 {
 1599     va_list ap;
 1600 
 1601     if (isc_log_wouldlog(dns_lctx, level) == false)
 1602         return;
 1603 
 1604     va_start(ap, fmt);
 1605     xfrin_logv(level, zonetext, masteraddr, fmt, ap);
 1606     va_end(ap);
 1607 }
 1608 
 1609 /*
 1610  * Logging function for use when there is a xfrin_ctx_t.
 1611  */
 1612 
 1613 static void
 1614 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
 1615 {
 1616     va_list ap;
 1617     char zonetext[DNS_NAME_MAXTEXT+32];
 1618 
 1619     if (isc_log_wouldlog(dns_lctx, level) == false)
 1620         return;
 1621 
 1622     dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
 1623 
 1624     va_start(ap, fmt);
 1625     xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);
 1626     va_end(ap);
 1627 }