"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/lib/dns/xfrin.c" (4 Sep 2020, 41450 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.tar.xz:


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