"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/ns/xfrout.c" (4 Sep 2020, 49450 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.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 "xfrout.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 #include <inttypes.h>
   13 #include <stdbool.h>
   14 
   15 #include <isc/formatcheck.h>
   16 #include <isc/mem.h>
   17 #include <isc/print.h>
   18 #include <isc/stats.h>
   19 #include <isc/timer.h>
   20 #include <isc/util.h>
   21 
   22 #include <dns/db.h>
   23 #include <dns/dbiterator.h>
   24 #include <dns/dlz.h>
   25 #include <dns/fixedname.h>
   26 #include <dns/journal.h>
   27 #include <dns/message.h>
   28 #include <dns/peer.h>
   29 #include <dns/rdataclass.h>
   30 #include <dns/rdatalist.h>
   31 #include <dns/rdataset.h>
   32 #include <dns/rdatasetiter.h>
   33 #include <dns/result.h>
   34 #include <dns/rriterator.h>
   35 #include <dns/soa.h>
   36 #include <dns/stats.h>
   37 #include <dns/timer.h>
   38 #include <dns/tsig.h>
   39 #include <dns/view.h>
   40 #include <dns/zone.h>
   41 #include <dns/zt.h>
   42 
   43 #include <ns/client.h>
   44 #include <ns/log.h>
   45 #include <ns/server.h>
   46 #include <ns/stats.h>
   47 #include <ns/xfrout.h>
   48 
   49 /*! \file
   50  * \brief
   51  * Outgoing AXFR and IXFR.
   52  */
   53 
   54 /*
   55  * TODO:
   56  *  - IXFR over UDP
   57  */
   58 
   59 #define XFROUT_COMMON_LOGARGS \
   60     ns_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT
   61 
   62 #define XFROUT_PROTOCOL_LOGARGS XFROUT_COMMON_LOGARGS, ISC_LOG_INFO
   63 
   64 #define XFROUT_DEBUG_LOGARGS(n) XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n)
   65 
   66 #define XFROUT_RR_LOGARGS XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL
   67 
   68 #define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8)
   69 
   70 /*%
   71  * Fail unconditionally and log as a client error.
   72  * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
   73  * from complaining about "end-of-loop code not reached".
   74  */
   75 #define FAILC(code, msg)                                                 \
   76     do {                                                             \
   77         result = (code);                                         \
   78         ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,          \
   79                   NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO,       \
   80                   "bad zone transfer request: %s (%s)", msg, \
   81                   isc_result_totext(code));                  \
   82         if (result != ISC_R_SUCCESS)                             \
   83             goto failure;                                    \
   84     } while (0)
   85 
   86 #define FAILQ(code, msg, question, rdclass)                                  \
   87     do {                                                                 \
   88         char _buf1[DNS_NAME_FORMATSIZE];                             \
   89         char _buf2[DNS_RDATACLASS_FORMATSIZE];                       \
   90         result = (code);                                             \
   91         dns_name_format(question, _buf1, sizeof(_buf1));             \
   92         dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2));        \
   93         ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,              \
   94                   NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO,           \
   95                   "bad zone transfer request: '%s/%s': %s (%s)", \
   96                   _buf1, _buf2, msg, isc_result_totext(code));   \
   97         if (result != ISC_R_SUCCESS)                                 \
   98             goto failure;                                        \
   99     } while (0)
  100 
  101 #define CHECK(op)                            \
  102     do {                                 \
  103         result = (op);               \
  104         if (result != ISC_R_SUCCESS) \
  105             goto failure;        \
  106     } while (0)
  107 
  108 /**************************************************************************/
  109 
  110 static inline void
  111 inc_stats(ns_client_t *client, dns_zone_t *zone, isc_statscounter_t counter) {
  112     ns_stats_increment(client->sctx->nsstats, counter);
  113     if (zone != NULL) {
  114         isc_stats_t *zonestats = dns_zone_getrequeststats(zone);
  115         if (zonestats != NULL) {
  116             isc_stats_increment(zonestats, counter);
  117         }
  118     }
  119 }
  120 
  121 /**************************************************************************/
  122 
  123 /*% Log an RR (for debugging) */
  124 
  125 static void
  126 log_rr(dns_name_t *name, dns_rdata_t *rdata, uint32_t ttl) {
  127     isc_result_t result;
  128     isc_buffer_t buf;
  129     char mem[2000];
  130     dns_rdatalist_t rdl;
  131     dns_rdataset_t rds;
  132     dns_rdata_t rd = DNS_RDATA_INIT;
  133 
  134     dns_rdatalist_init(&rdl);
  135     rdl.type = rdata->type;
  136     rdl.rdclass = rdata->rdclass;
  137     rdl.ttl = ttl;
  138     if (rdata->type == dns_rdatatype_sig ||
  139         rdata->type == dns_rdatatype_rrsig) {
  140         rdl.covers = dns_rdata_covers(rdata);
  141     } else {
  142         rdl.covers = dns_rdatatype_none;
  143     }
  144     dns_rdataset_init(&rds);
  145     dns_rdata_init(&rd);
  146     dns_rdata_clone(rdata, &rd);
  147     ISC_LIST_APPEND(rdl.rdata, &rd, link);
  148     RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS);
  149 
  150     isc_buffer_init(&buf, mem, sizeof(mem));
  151     result = dns_rdataset_totext(&rds, name, false, false, &buf);
  152 
  153     /*
  154      * We could use xfrout_log(), but that would produce
  155      * very long lines with a repetitive prefix.
  156      */
  157     if (result == ISC_R_SUCCESS) {
  158         /*
  159          * Get rid of final newline.
  160          */
  161         INSIST(buf.used >= 1 &&
  162                ((char *)buf.base)[buf.used - 1] == '\n');
  163         buf.used--;
  164 
  165         isc_log_write(XFROUT_RR_LOGARGS, "%.*s",
  166                   (int)isc_buffer_usedlength(&buf),
  167                   (char *)isc_buffer_base(&buf));
  168     } else {
  169         isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>");
  170     }
  171 }
  172 
  173 /**************************************************************************/
  174 /*
  175  * An 'rrstream_t' is a polymorphic iterator that returns
  176  * a stream of resource records.  There are multiple implementations,
  177  * e.g. for generating AXFR and IXFR records streams.
  178  */
  179 
  180 typedef struct rrstream_methods rrstream_methods_t;
  181 
  182 typedef struct rrstream {
  183     isc_mem_t *mctx;
  184     rrstream_methods_t *methods;
  185 } rrstream_t;
  186 
  187 struct rrstream_methods {
  188     isc_result_t (*first)(rrstream_t *);
  189     isc_result_t (*next)(rrstream_t *);
  190     void (*current)(rrstream_t *, dns_name_t **, uint32_t *,
  191             dns_rdata_t **);
  192     void (*pause)(rrstream_t *);
  193     void (*destroy)(rrstream_t **);
  194 };
  195 
  196 static void
  197 rrstream_noop_pause(rrstream_t *rs) {
  198     UNUSED(rs);
  199 }
  200 
  201 /**************************************************************************/
  202 /*
  203  * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
  204  * an IXFR-like RR stream from a journal file.
  205  *
  206  * The SOA at the beginning of each sequence of additions
  207  * or deletions are included in the stream, but the extra
  208  * SOAs at the beginning and end of the entire transfer are
  209  * not included.
  210  */
  211 
  212 typedef struct ixfr_rrstream {
  213     rrstream_t common;
  214     dns_journal_t *journal;
  215 } ixfr_rrstream_t;
  216 
  217 /* Forward declarations. */
  218 static void
  219 ixfr_rrstream_destroy(rrstream_t **sp);
  220 
  221 static rrstream_methods_t ixfr_rrstream_methods;
  222 
  223 /*
  224  * Returns: anything dns_journal_open() or dns_journal_iter_init()
  225  * may return.
  226  */
  227 
  228 static isc_result_t
  229 ixfr_rrstream_create(isc_mem_t *mctx, const char *journal_filename,
  230              uint32_t begin_serial, uint32_t end_serial, size_t *sizep,
  231              rrstream_t **sp) {
  232     isc_result_t result;
  233     ixfr_rrstream_t *s = NULL;
  234 
  235     INSIST(sp != NULL && *sp == NULL);
  236 
  237     s = isc_mem_get(mctx, sizeof(*s));
  238     s->common.mctx = NULL;
  239     isc_mem_attach(mctx, &s->common.mctx);
  240     s->common.methods = &ixfr_rrstream_methods;
  241     s->journal = NULL;
  242 
  243     CHECK(dns_journal_open(mctx, journal_filename, DNS_JOURNAL_READ,
  244                    &s->journal));
  245     CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial,
  246                     sizep));
  247 
  248     *sp = (rrstream_t *)s;
  249     return (ISC_R_SUCCESS);
  250 
  251 failure:
  252     ixfr_rrstream_destroy((rrstream_t **)(void *)&s);
  253     return (result);
  254 }
  255 
  256 static isc_result_t
  257 ixfr_rrstream_first(rrstream_t *rs) {
  258     ixfr_rrstream_t *s = (ixfr_rrstream_t *)rs;
  259     return (dns_journal_first_rr(s->journal));
  260 }
  261 
  262 static isc_result_t
  263 ixfr_rrstream_next(rrstream_t *rs) {
  264     ixfr_rrstream_t *s = (ixfr_rrstream_t *)rs;
  265     return (dns_journal_next_rr(s->journal));
  266 }
  267 
  268 static void
  269 ixfr_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
  270               dns_rdata_t **rdata) {
  271     ixfr_rrstream_t *s = (ixfr_rrstream_t *)rs;
  272     dns_journal_current_rr(s->journal, name, ttl, rdata);
  273 }
  274 
  275 static void
  276 ixfr_rrstream_destroy(rrstream_t **rsp) {
  277     ixfr_rrstream_t *s = (ixfr_rrstream_t *)*rsp;
  278     if (s->journal != NULL) {
  279         dns_journal_destroy(&s->journal);
  280     }
  281     isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
  282 }
  283 
  284 static rrstream_methods_t ixfr_rrstream_methods = {
  285     ixfr_rrstream_first, ixfr_rrstream_next, ixfr_rrstream_current,
  286     rrstream_noop_pause, ixfr_rrstream_destroy
  287 };
  288 
  289 /**************************************************************************/
  290 /*
  291  * An 'axfr_rrstream_t' is an 'rrstream_t' that returns
  292  * an AXFR-like RR stream from a database.
  293  *
  294  * The SOAs at the beginning and end of the transfer are
  295  * not included in the stream.
  296  */
  297 
  298 typedef struct axfr_rrstream {
  299     rrstream_t common;
  300     dns_rriterator_t it;
  301     bool it_valid;
  302 } axfr_rrstream_t;
  303 
  304 /*
  305  * Forward declarations.
  306  */
  307 static void
  308 axfr_rrstream_destroy(rrstream_t **rsp);
  309 
  310 static rrstream_methods_t axfr_rrstream_methods;
  311 
  312 static isc_result_t
  313 axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
  314              rrstream_t **sp) {
  315     axfr_rrstream_t *s;
  316     isc_result_t result;
  317 
  318     INSIST(sp != NULL && *sp == NULL);
  319 
  320     s = isc_mem_get(mctx, sizeof(*s));
  321     s->common.mctx = NULL;
  322     isc_mem_attach(mctx, &s->common.mctx);
  323     s->common.methods = &axfr_rrstream_methods;
  324     s->it_valid = false;
  325 
  326     CHECK(dns_rriterator_init(&s->it, db, ver, 0));
  327     s->it_valid = true;
  328 
  329     *sp = (rrstream_t *)s;
  330     return (ISC_R_SUCCESS);
  331 
  332 failure:
  333     axfr_rrstream_destroy((rrstream_t **)(void *)&s);
  334     return (result);
  335 }
  336 
  337 static isc_result_t
  338 axfr_rrstream_first(rrstream_t *rs) {
  339     axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
  340     isc_result_t result;
  341     result = dns_rriterator_first(&s->it);
  342     if (result != ISC_R_SUCCESS) {
  343         return (result);
  344     }
  345     /* Skip SOA records. */
  346     for (;;) {
  347         dns_name_t *name_dummy = NULL;
  348         uint32_t ttl_dummy;
  349         dns_rdata_t *rdata = NULL;
  350         dns_rriterator_current(&s->it, &name_dummy, &ttl_dummy, NULL,
  351                        &rdata);
  352         if (rdata->type != dns_rdatatype_soa) {
  353             break;
  354         }
  355         result = dns_rriterator_next(&s->it);
  356         if (result != ISC_R_SUCCESS) {
  357             break;
  358         }
  359     }
  360     return (result);
  361 }
  362 
  363 static isc_result_t
  364 axfr_rrstream_next(rrstream_t *rs) {
  365     axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
  366     isc_result_t result;
  367 
  368     /* Skip SOA records. */
  369     for (;;) {
  370         dns_name_t *name_dummy = NULL;
  371         uint32_t ttl_dummy;
  372         dns_rdata_t *rdata = NULL;
  373         result = dns_rriterator_next(&s->it);
  374         if (result != ISC_R_SUCCESS) {
  375             break;
  376         }
  377         dns_rriterator_current(&s->it, &name_dummy, &ttl_dummy, NULL,
  378                        &rdata);
  379         if (rdata->type != dns_rdatatype_soa) {
  380             break;
  381         }
  382     }
  383     return (result);
  384 }
  385 
  386 static void
  387 axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
  388               dns_rdata_t **rdata) {
  389     axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
  390     dns_rriterator_current(&s->it, name, ttl, NULL, rdata);
  391 }
  392 
  393 static void
  394 axfr_rrstream_pause(rrstream_t *rs) {
  395     axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
  396     dns_rriterator_pause(&s->it);
  397 }
  398 
  399 static void
  400 axfr_rrstream_destroy(rrstream_t **rsp) {
  401     axfr_rrstream_t *s = (axfr_rrstream_t *)*rsp;
  402     if (s->it_valid) {
  403         dns_rriterator_destroy(&s->it);
  404     }
  405     isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
  406 }
  407 
  408 static rrstream_methods_t axfr_rrstream_methods = {
  409     axfr_rrstream_first, axfr_rrstream_next, axfr_rrstream_current,
  410     axfr_rrstream_pause, axfr_rrstream_destroy
  411 };
  412 
  413 /**************************************************************************/
  414 /*
  415  * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns
  416  * a single SOA record.
  417  */
  418 
  419 typedef struct soa_rrstream {
  420     rrstream_t common;
  421     dns_difftuple_t *soa_tuple;
  422 } soa_rrstream_t;
  423 
  424 /*
  425  * Forward declarations.
  426  */
  427 static void
  428 soa_rrstream_destroy(rrstream_t **rsp);
  429 
  430 static rrstream_methods_t soa_rrstream_methods;
  431 
  432 static isc_result_t
  433 soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
  434             rrstream_t **sp) {
  435     soa_rrstream_t *s;
  436     isc_result_t result;
  437 
  438     INSIST(sp != NULL && *sp == NULL);
  439 
  440     s = isc_mem_get(mctx, sizeof(*s));
  441     s->common.mctx = NULL;
  442     isc_mem_attach(mctx, &s->common.mctx);
  443     s->common.methods = &soa_rrstream_methods;
  444     s->soa_tuple = NULL;
  445 
  446     CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
  447                     &s->soa_tuple));
  448 
  449     *sp = (rrstream_t *)s;
  450     return (ISC_R_SUCCESS);
  451 
  452 failure:
  453     soa_rrstream_destroy((rrstream_t **)(void *)&s);
  454     return (result);
  455 }
  456 
  457 static isc_result_t
  458 soa_rrstream_first(rrstream_t *rs) {
  459     UNUSED(rs);
  460     return (ISC_R_SUCCESS);
  461 }
  462 
  463 static isc_result_t
  464 soa_rrstream_next(rrstream_t *rs) {
  465     UNUSED(rs);
  466     return (ISC_R_NOMORE);
  467 }
  468 
  469 static void
  470 soa_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
  471              dns_rdata_t **rdata) {
  472     soa_rrstream_t *s = (soa_rrstream_t *)rs;
  473     *name = &s->soa_tuple->name;
  474     *ttl = s->soa_tuple->ttl;
  475     *rdata = &s->soa_tuple->rdata;
  476 }
  477 
  478 static void
  479 soa_rrstream_destroy(rrstream_t **rsp) {
  480     soa_rrstream_t *s = (soa_rrstream_t *)*rsp;
  481     if (s->soa_tuple != NULL) {
  482         dns_difftuple_free(&s->soa_tuple);
  483     }
  484     isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
  485 }
  486 
  487 static rrstream_methods_t soa_rrstream_methods = {
  488     soa_rrstream_first, soa_rrstream_next, soa_rrstream_current,
  489     rrstream_noop_pause, soa_rrstream_destroy
  490 };
  491 
  492 /**************************************************************************/
  493 /*
  494  * A 'compound_rrstream_t' objects owns a soa_rrstream
  495  * and another rrstream, the "data stream".  It returns
  496  * a concatenated stream consisting of the soa_rrstream, then
  497  * the data stream, then the soa_rrstream again.
  498  *
  499  * The component streams are owned by the compound_rrstream_t
  500  * and are destroyed with it.
  501  */
  502 
  503 typedef struct compound_rrstream {
  504     rrstream_t common;
  505     rrstream_t *components[3];
  506     int state;
  507     isc_result_t result;
  508 } compound_rrstream_t;
  509 
  510 /*
  511  * Forward declarations.
  512  */
  513 static void
  514 compound_rrstream_destroy(rrstream_t **rsp);
  515 
  516 static isc_result_t
  517 compound_rrstream_next(rrstream_t *rs);
  518 
  519 static rrstream_methods_t compound_rrstream_methods;
  520 
  521 /*
  522  * Requires:
  523  *  soa_stream != NULL && *soa_stream != NULL
  524  *  data_stream != NULL && *data_stream != NULL
  525  *  sp != NULL && *sp == NULL
  526  *
  527  * Ensures:
  528  *  *soa_stream == NULL
  529  *  *data_stream == NULL
  530  *  *sp points to a valid compound_rrstream_t
  531  *  The soa and data streams will be destroyed
  532  *  when the compound_rrstream_t is destroyed.
  533  */
  534 static isc_result_t
  535 compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream,
  536              rrstream_t **data_stream, rrstream_t **sp) {
  537     compound_rrstream_t *s;
  538 
  539     INSIST(sp != NULL && *sp == NULL);
  540 
  541     s = isc_mem_get(mctx, sizeof(*s));
  542     s->common.mctx = NULL;
  543     isc_mem_attach(mctx, &s->common.mctx);
  544     s->common.methods = &compound_rrstream_methods;
  545     s->components[0] = *soa_stream;
  546     s->components[1] = *data_stream;
  547     s->components[2] = *soa_stream;
  548     s->state = -1;
  549     s->result = ISC_R_FAILURE;
  550 
  551     *data_stream = NULL;
  552     *soa_stream = NULL;
  553     *sp = (rrstream_t *)s;
  554     return (ISC_R_SUCCESS);
  555 }
  556 
  557 static isc_result_t
  558 compound_rrstream_first(rrstream_t *rs) {
  559     compound_rrstream_t *s = (compound_rrstream_t *)rs;
  560     s->state = 0;
  561     do {
  562         rrstream_t *curstream = s->components[s->state];
  563         s->result = curstream->methods->first(curstream);
  564     } while (s->result == ISC_R_NOMORE && s->state < 2);
  565     return (s->result);
  566 }
  567 
  568 static isc_result_t
  569 compound_rrstream_next(rrstream_t *rs) {
  570     compound_rrstream_t *s = (compound_rrstream_t *)rs;
  571     rrstream_t *curstream = s->components[s->state];
  572     s->result = curstream->methods->next(curstream);
  573     while (s->result == ISC_R_NOMORE) {
  574         /*
  575          * Make sure locks held by the current stream
  576          * are released before we switch streams.
  577          */
  578         curstream->methods->pause(curstream);
  579         if (s->state == 2) {
  580             return (ISC_R_NOMORE);
  581         }
  582         s->state++;
  583         curstream = s->components[s->state];
  584         s->result = curstream->methods->first(curstream);
  585     }
  586     return (s->result);
  587 }
  588 
  589 static void
  590 compound_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
  591               dns_rdata_t **rdata) {
  592     compound_rrstream_t *s = (compound_rrstream_t *)rs;
  593     rrstream_t *curstream;
  594     INSIST(0 <= s->state && s->state < 3);
  595     INSIST(s->result == ISC_R_SUCCESS);
  596     curstream = s->components[s->state];
  597     curstream->methods->current(curstream, name, ttl, rdata);
  598 }
  599 
  600 static void
  601 compound_rrstream_pause(rrstream_t *rs) {
  602     compound_rrstream_t *s = (compound_rrstream_t *)rs;
  603     rrstream_t *curstream;
  604     INSIST(0 <= s->state && s->state < 3);
  605     curstream = s->components[s->state];
  606     curstream->methods->pause(curstream);
  607 }
  608 
  609 static void
  610 compound_rrstream_destroy(rrstream_t **rsp) {
  611     compound_rrstream_t *s = (compound_rrstream_t *)*rsp;
  612     s->components[0]->methods->destroy(&s->components[0]);
  613     s->components[1]->methods->destroy(&s->components[1]);
  614     s->components[2] = NULL; /* Copy of components[0]. */
  615     isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
  616 }
  617 
  618 static rrstream_methods_t compound_rrstream_methods = {
  619     compound_rrstream_first, compound_rrstream_next,
  620     compound_rrstream_current, compound_rrstream_pause,
  621     compound_rrstream_destroy
  622 };
  623 
  624 /**************************************************************************/
  625 
  626 /*%
  627  * Structure holding outgoing transfer statistics
  628  */
  629 struct xfr_stats {
  630     uint64_t nmsg;    /*%< Number of messages sent */
  631     uint64_t nrecs;   /*%< Number of records sent */
  632     uint64_t nbytes;  /*%< Number of bytes sent */
  633     isc_time_t start; /*%< Start time of the transfer */
  634     isc_time_t end;   /*%< End time of the transfer */
  635 };
  636 
  637 /*%
  638  * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR
  639  * in progress.
  640  */
  641 typedef struct {
  642     isc_mem_t *mctx;
  643     ns_client_t *client;
  644     unsigned int id;       /* ID of request */
  645     dns_name_t *qname;     /* Question name of request */
  646     dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */
  647     dns_rdataclass_t qclass;
  648     dns_zone_t *zone; /* (necessary for stats) */
  649     dns_db_t *db;
  650     dns_dbversion_t *ver;
  651     isc_quota_t *quota;
  652     rrstream_t *stream;  /* The XFR RR stream */
  653     bool question_added; /* QUESTION section sent? */
  654     bool end_of_stream;  /* EOS has been reached */
  655     isc_buffer_t buf;    /* Buffer for message owner
  656                   * names and rdatas */
  657     isc_buffer_t txbuf;  /* Transmit message buffer */
  658     size_t cbytes;       /* Length of current message */
  659     void *txmem;
  660     unsigned int txmemlen;
  661     dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
  662     isc_buffer_t *lasttsig; /* the last TSIG */
  663     bool verified_tsig; /* verified request MAC */
  664     bool many_answers;
  665     int sends; /* Send in progress */
  666     bool shuttingdown;
  667     bool poll;
  668     const char *mnemonic;   /* Style of transfer */
  669     uint32_t end_serial;    /* Serial number after XFR is done */
  670     struct xfr_stats stats; /*%< Transfer statistics */
  671 } xfrout_ctx_t;
  672 
  673 static void
  674 xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
  675           dns_name_t *qname, dns_rdatatype_t qtype,
  676           dns_rdataclass_t qclass, dns_zone_t *zone, dns_db_t *db,
  677           dns_dbversion_t *ver, isc_quota_t *quota, rrstream_t *stream,
  678           dns_tsigkey_t *tsigkey, isc_buffer_t *lasttsig,
  679           bool verified_tsig, unsigned int maxtime,
  680           unsigned int idletime, bool many_answers,
  681           xfrout_ctx_t **xfrp);
  682 
  683 static void
  684 sendstream(xfrout_ctx_t *xfr);
  685 
  686 static void
  687 xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg);
  688 
  689 static void
  690 xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg);
  691 
  692 static void
  693 xfrout_maybe_destroy(xfrout_ctx_t *xfr);
  694 
  695 static void
  696 xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
  697 
  698 static void
  699 xfrout_client_shutdown(void *arg, isc_result_t result);
  700 
  701 static void
  702 xfrout_log1(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
  703         int level, const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
  704 
  705 static void
  706 xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...)
  707     ISC_FORMAT_PRINTF(3, 4);
  708 
  709 /**************************************************************************/
  710 
  711 void
  712 ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
  713     isc_result_t result;
  714     dns_name_t *question_name;
  715     dns_rdataset_t *question_rdataset;
  716     dns_zone_t *zone = NULL, *raw = NULL, *mayberaw;
  717     dns_db_t *db = NULL;
  718     dns_dbversion_t *ver = NULL;
  719     dns_rdataclass_t question_class;
  720     rrstream_t *soa_stream = NULL;
  721     rrstream_t *data_stream = NULL;
  722     rrstream_t *stream = NULL;
  723     dns_difftuple_t *current_soa_tuple = NULL;
  724     dns_name_t *soa_name;
  725     dns_rdataset_t *soa_rdataset;
  726     dns_rdata_t soa_rdata = DNS_RDATA_INIT;
  727     bool have_soa = false;
  728     const char *mnemonic = NULL;
  729     isc_mem_t *mctx = client->mctx;
  730     dns_message_t *request = client->message;
  731     xfrout_ctx_t *xfr = NULL;
  732     isc_quota_t *quota = NULL;
  733     dns_transfer_format_t format = client->view->transfer_format;
  734     isc_netaddr_t na;
  735     dns_peer_t *peer = NULL;
  736     isc_buffer_t *tsigbuf = NULL;
  737     char *journalfile;
  738     char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")];
  739     char keyname[DNS_NAME_FORMATSIZE];
  740     bool is_poll = false;
  741     bool is_dlz = false;
  742     bool is_ixfr = false;
  743     bool useviewacl = false;
  744     uint32_t begin_serial = 0, current_serial;
  745 
  746     switch (reqtype) {
  747     case dns_rdatatype_axfr:
  748         mnemonic = "AXFR";
  749         break;
  750     case dns_rdatatype_ixfr:
  751         mnemonic = "IXFR";
  752         break;
  753     default:
  754         INSIST(0);
  755         ISC_UNREACHABLE();
  756     }
  757 
  758     ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT,
  759               ISC_LOG_DEBUG(6), "%s request", mnemonic);
  760     /*
  761      * Apply quota.
  762      */
  763     result = isc_quota_attach(&client->sctx->xfroutquota, &quota);
  764     if (result != ISC_R_SUCCESS) {
  765         isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING,
  766                   "%s request denied: %s", mnemonic,
  767                   isc_result_totext(result));
  768         goto failure;
  769     }
  770 
  771     /*
  772      * Interpret the question section.
  773      */
  774     result = dns_message_firstname(request, DNS_SECTION_QUESTION);
  775     INSIST(result == ISC_R_SUCCESS);
  776 
  777     /*
  778      * The question section must contain exactly one question, and
  779      * it must be for AXFR/IXFR as appropriate.
  780      */
  781     question_name = NULL;
  782     dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name);
  783     question_rdataset = ISC_LIST_HEAD(question_name->list);
  784     question_class = question_rdataset->rdclass;
  785     INSIST(question_rdataset->type == reqtype);
  786     if (ISC_LIST_NEXT(question_rdataset, link) != NULL) {
  787         FAILC(DNS_R_FORMERR, "multiple questions");
  788     }
  789     result = dns_message_nextname(request, DNS_SECTION_QUESTION);
  790     if (result != ISC_R_NOMORE) {
  791         FAILC(DNS_R_FORMERR, "multiple questions");
  792     }
  793 
  794     result = dns_zt_find(client->view->zonetable, question_name, 0, NULL,
  795                  &zone);
  796 
  797     if (result != ISC_R_SUCCESS || dns_zone_gettype(zone) == dns_zone_dlz) {
  798         /*
  799          * The normal zone table does not have a match, or this is
  800          * marked in the zone table as a DLZ zone. Check the DLZ
  801          * databases for a match.
  802          */
  803         if (!ISC_LIST_EMPTY(client->view->dlz_searched)) {
  804             result = dns_dlzallowzonexfr(client->view,
  805                              question_name,
  806                              &client->peeraddr, &db);
  807             if (result == ISC_R_DEFAULT) {
  808                 useviewacl = true;
  809                 result = ISC_R_SUCCESS;
  810             }
  811             if (result == ISC_R_NOPERM) {
  812                 char _buf1[DNS_NAME_FORMATSIZE];
  813                 char _buf2[DNS_RDATACLASS_FORMATSIZE];
  814 
  815                 result = DNS_R_REFUSED;
  816                 dns_name_format(question_name, _buf1,
  817                         sizeof(_buf1));
  818                 dns_rdataclass_format(question_class, _buf2,
  819                               sizeof(_buf2));
  820                 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
  821                           NS_LOGMODULE_XFER_OUT,
  822                           ISC_LOG_ERROR,
  823                           "zone transfer '%s/%s' denied",
  824                           _buf1, _buf2);
  825                 goto failure;
  826             }
  827             if (result != ISC_R_SUCCESS) {
  828                 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
  829                       question_name, question_class);
  830             }
  831             is_dlz = true;
  832         } else {
  833             /*
  834              * not DLZ and not in normal zone table, we are
  835              * not authoritative
  836              */
  837             FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
  838                   question_name, question_class);
  839         }
  840     } else {
  841         /* zone table has a match */
  842         switch (dns_zone_gettype(zone)) {
  843         /*
  844          * Master, slave, and mirror zones are OK for transfer.
  845          */
  846         case dns_zone_master:
  847         case dns_zone_slave:
  848         case dns_zone_mirror:
  849         case dns_zone_dlz:
  850             break;
  851         default:
  852             FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
  853                   question_name, question_class);
  854         }
  855         CHECK(dns_zone_getdb(zone, &db));
  856         dns_db_currentversion(db, &ver);
  857     }
  858 
  859     xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6),
  860             "%s question section OK", mnemonic);
  861 
  862     /*
  863      * Check the authority section.  Look for a SOA record with
  864      * the same name and class as the question.
  865      */
  866     for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY);
  867          result == ISC_R_SUCCESS;
  868          result = dns_message_nextname(request, DNS_SECTION_AUTHORITY))
  869     {
  870         soa_name = NULL;
  871         dns_message_currentname(request, DNS_SECTION_AUTHORITY,
  872                     &soa_name);
  873 
  874         /*
  875          * Ignore data whose owner name is not the zone apex.
  876          */
  877         if (!dns_name_equal(soa_name, question_name)) {
  878             continue;
  879         }
  880 
  881         for (soa_rdataset = ISC_LIST_HEAD(soa_name->list);
  882              soa_rdataset != NULL;
  883              soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link))
  884         {
  885             /*
  886              * Ignore non-SOA data.
  887              */
  888             if (soa_rdataset->type != dns_rdatatype_soa) {
  889                 continue;
  890             }
  891             if (soa_rdataset->rdclass != question_class) {
  892                 continue;
  893             }
  894 
  895             CHECK(dns_rdataset_first(soa_rdataset));
  896             dns_rdataset_current(soa_rdataset, &soa_rdata);
  897             result = dns_rdataset_next(soa_rdataset);
  898             if (result == ISC_R_SUCCESS) {
  899                 FAILC(DNS_R_FORMERR, "IXFR authority section "
  900                              "has multiple SOAs");
  901             }
  902             have_soa = true;
  903             goto got_soa;
  904         }
  905     }
  906 got_soa:
  907     if (result != ISC_R_NOMORE) {
  908         CHECK(result);
  909     }
  910 
  911     xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6),
  912             "%s authority section OK", mnemonic);
  913 
  914     /*
  915      * If not a DLZ zone or we are falling back to the view's transfer
  916      * ACL, decide whether to allow this transfer.
  917      */
  918     if (!is_dlz || useviewacl) {
  919         dns_acl_t *acl;
  920 
  921         ns_client_aclmsg("zone transfer", question_name, reqtype,
  922                  client->view->rdclass, msg, sizeof(msg));
  923         if (useviewacl) {
  924             acl = client->view->transferacl;
  925         } else {
  926             acl = dns_zone_getxfracl(zone);
  927         }
  928         CHECK(ns_client_checkacl(client, NULL, msg, acl, true,
  929                      ISC_LOG_ERROR));
  930     }
  931 
  932     /*
  933      * AXFR over UDP is not possible.
  934      */
  935     if (reqtype == dns_rdatatype_axfr &&
  936         (client->attributes & NS_CLIENTATTR_TCP) == 0)
  937     {
  938         FAILC(DNS_R_FORMERR, "attempted AXFR over UDP");
  939     }
  940 
  941     /*
  942      * Look up the requesting server in the peer table.
  943      */
  944     isc_netaddr_fromsockaddr(&na, &client->peeraddr);
  945     (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer);
  946 
  947     /*
  948      * Decide on the transfer format (one-answer or many-answers).
  949      */
  950     if (peer != NULL) {
  951         (void)dns_peer_gettransferformat(peer, &format);
  952     }
  953 
  954     /*
  955      * Get a dynamically allocated copy of the current SOA.
  956      */
  957     if (is_dlz) {
  958         dns_db_currentversion(db, &ver);
  959     }
  960 
  961     CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
  962                     &current_soa_tuple));
  963 
  964     current_serial = dns_soa_getserial(&current_soa_tuple->rdata);
  965     if (reqtype == dns_rdatatype_ixfr) {
  966         size_t jsize;
  967         uint64_t dbsize;
  968 
  969         if (!have_soa) {
  970             FAILC(DNS_R_FORMERR, "IXFR request missing SOA");
  971         }
  972 
  973         begin_serial = dns_soa_getserial(&soa_rdata);
  974 
  975         /*
  976          * RFC1995 says "If an IXFR query with the same or
  977          * newer version number than that of the server
  978          * is received, it is replied to with a single SOA
  979          * record of the server's current version, just as
  980          * in AXFR".  The claim about AXFR is incorrect,
  981          * but other than that, we do as the RFC says.
  982          *
  983          * Sending a single SOA record is also how we refuse
  984          * IXFR over UDP (currently, we always do).
  985          */
  986         if (DNS_SERIAL_GE(begin_serial, current_serial) ||
  987             (client->attributes & NS_CLIENTATTR_TCP) == 0)
  988         {
  989             CHECK(soa_rrstream_create(mctx, db, ver, &stream));
  990             is_poll = true;
  991             goto have_stream;
  992         }
  993 
  994         /*
  995          * Outgoing IXFR may have been disabled for this peer
  996          * or globally.
  997          */
  998         if ((client->attributes & NS_CLIENTATTR_TCP) != 0) {
  999             bool provide_ixfr;
 1000 
 1001             provide_ixfr = client->view->provideixfr;
 1002             if (peer != NULL) {
 1003                 (void)dns_peer_getprovideixfr(peer,
 1004                                   &provide_ixfr);
 1005             }
 1006             if (!provide_ixfr) {
 1007                 xfrout_log1(client, question_name,
 1008                         question_class, ISC_LOG_DEBUG(4),
 1009                         "IXFR delta response disabled due "
 1010                         "to 'provide-ixfr no;' being set");
 1011                 mnemonic = "AXFR-style IXFR";
 1012                 goto axfr_fallback;
 1013             }
 1014         }
 1015 
 1016         journalfile = is_dlz ? NULL : dns_zone_getjournal(zone);
 1017         if (journalfile != NULL) {
 1018             result = ixfr_rrstream_create(
 1019                 mctx, journalfile, begin_serial, current_serial,
 1020                 &jsize, &data_stream);
 1021         } else {
 1022             result = ISC_R_NOTFOUND;
 1023         }
 1024         if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
 1025             xfrout_log1(client, question_name, question_class,
 1026                     ISC_LOG_DEBUG(4),
 1027                     "IXFR version not in journal, "
 1028                     "falling back to AXFR");
 1029             mnemonic = "AXFR-style IXFR";
 1030             goto axfr_fallback;
 1031         }
 1032         CHECK(result);
 1033 
 1034         result = dns_db_getsize(db, ver, NULL, &dbsize);
 1035         if (result == ISC_R_SUCCESS) {
 1036             uint32_t ratio = dns_zone_getixfrratio(zone);
 1037             if (ratio != 0 && ((100 * jsize) / dbsize) > ratio) {
 1038                 data_stream->methods->destroy(&data_stream);
 1039                 data_stream = NULL;
 1040                 xfrout_log1(client, question_name,
 1041                         question_class, ISC_LOG_DEBUG(4),
 1042                         "IXFR delta size (%zu bytes) "
 1043                         "exceeds the maximum ratio to "
 1044                         "database size "
 1045                         "(%" PRIu64 " bytes), "
 1046                         "falling back to AXFR",
 1047                         jsize, dbsize);
 1048                 mnemonic = "AXFR-style IXFR";
 1049                 goto axfr_fallback;
 1050             } else {
 1051                 xfrout_log1(client, question_name,
 1052                         question_class, ISC_LOG_DEBUG(4),
 1053                         "IXFR delta size (%zu bytes); "
 1054                         "database size "
 1055                         "(%" PRIu64 " bytes)",
 1056                         jsize, dbsize);
 1057             }
 1058         }
 1059         is_ixfr = true;
 1060     } else {
 1061     axfr_fallback:
 1062         CHECK(axfr_rrstream_create(mctx, db, ver, &data_stream));
 1063     }
 1064 
 1065     /*
 1066      * Bracket the data stream with SOAs.
 1067      */
 1068     CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream));
 1069     CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream,
 1070                        &stream));
 1071     soa_stream = NULL;
 1072     data_stream = NULL;
 1073 
 1074 have_stream:
 1075     CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf));
 1076     /*
 1077      * Create the xfrout context object.  This transfers the ownership
 1078      * of "stream", "db", "ver", and "quota" to the xfrout context object.
 1079      */
 1080 
 1081     if (is_dlz) {
 1082         xfrout_ctx_create(mctx, client, request->id, question_name,
 1083                   reqtype, question_class, zone, db, ver, quota,
 1084                   stream, dns_message_gettsigkey(request),
 1085                   tsigbuf, request->verified_sig, 3600, 3600,
 1086                   (format == dns_many_answers) ? true : false,
 1087                   &xfr);
 1088     } else {
 1089         xfrout_ctx_create(
 1090             mctx, client, request->id, question_name, reqtype,
 1091             question_class, zone, db, ver, quota, stream,
 1092             dns_message_gettsigkey(request), tsigbuf,
 1093             request->verified_sig, dns_zone_getmaxxfrout(zone),
 1094             dns_zone_getidleout(zone),
 1095             (format == dns_many_answers) ? true : false, &xfr);
 1096     }
 1097 
 1098     xfr->end_serial = current_serial;
 1099     xfr->mnemonic = mnemonic;
 1100     stream = NULL;
 1101     quota = NULL;
 1102 
 1103     CHECK(xfr->stream->methods->first(xfr->stream));
 1104 
 1105     if (xfr->tsigkey != NULL) {
 1106         dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname));
 1107     } else {
 1108         keyname[0] = '\0';
 1109     }
 1110     xfr->poll = is_poll;
 1111     if (is_poll) {
 1112         xfr->mnemonic = "IXFR poll response";
 1113         xfrout_log1(client, question_name, question_class,
 1114                 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s",
 1115                 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname);
 1116     } else if (is_ixfr) {
 1117         xfrout_log1(client, question_name, question_class, ISC_LOG_INFO,
 1118                 "%s started%s%s (serial %u -> %u)", mnemonic,
 1119                 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname,
 1120                 begin_serial, current_serial);
 1121     } else {
 1122         xfrout_log1(client, question_name, question_class, ISC_LOG_INFO,
 1123                 "%s started%s%s (serial %u)", mnemonic,
 1124                 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname,
 1125                 current_serial);
 1126     }
 1127 
 1128     if (zone != NULL) {
 1129         dns_zone_getraw(zone, &raw);
 1130         mayberaw = (raw != NULL) ? raw : zone;
 1131         if ((client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 &&
 1132             (dns_zone_gettype(mayberaw) == dns_zone_slave ||
 1133              dns_zone_gettype(mayberaw) == dns_zone_mirror))
 1134         {
 1135             isc_time_t expiretime;
 1136             uint32_t secs;
 1137             dns_zone_getexpiretime(zone, &expiretime);
 1138             secs = isc_time_seconds(&expiretime);
 1139             if (secs >= client->now && result == ISC_R_SUCCESS) {
 1140                 client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
 1141                 client->expire = secs - client->now;
 1142             }
 1143         }
 1144         if (raw != NULL) {
 1145             dns_zone_detach(&raw);
 1146         }
 1147     }
 1148 
 1149     /*
 1150      * Hand the context over to sendstream().  Set xfr to NULL;
 1151      * sendstream() is responsible for either passing the
 1152      * context on to a later event handler or destroying it.
 1153      */
 1154     sendstream(xfr);
 1155     xfr = NULL;
 1156 
 1157     result = ISC_R_SUCCESS;
 1158 
 1159 failure:
 1160     if (result == DNS_R_REFUSED) {
 1161         inc_stats(client, zone, ns_statscounter_xfrrej);
 1162     }
 1163     if (quota != NULL) {
 1164         isc_quota_detach(&quota);
 1165     }
 1166     if (current_soa_tuple != NULL) {
 1167         dns_difftuple_free(&current_soa_tuple);
 1168     }
 1169     if (stream != NULL) {
 1170         stream->methods->destroy(&stream);
 1171     }
 1172     if (soa_stream != NULL) {
 1173         soa_stream->methods->destroy(&soa_stream);
 1174     }
 1175     if (data_stream != NULL) {
 1176         data_stream->methods->destroy(&data_stream);
 1177     }
 1178     if (ver != NULL) {
 1179         dns_db_closeversion(db, &ver, false);
 1180     }
 1181     if (db != NULL) {
 1182         dns_db_detach(&db);
 1183     }
 1184     if (zone != NULL) {
 1185         dns_zone_detach(&zone);
 1186     }
 1187     /* XXX kludge */
 1188     if (xfr != NULL) {
 1189         xfrout_fail(xfr, result, "setting up zone transfer");
 1190     } else if (result != ISC_R_SUCCESS) {
 1191         ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,
 1192                   NS_LOGMODULE_XFER_OUT, ISC_LOG_DEBUG(3),
 1193                   "zone transfer setup failed");
 1194         ns_client_error(client, result);
 1195         isc_nmhandle_unref(client->handle);
 1196     }
 1197 }
 1198 
 1199 static void
 1200 xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
 1201           dns_name_t *qname, dns_rdatatype_t qtype,
 1202           dns_rdataclass_t qclass, dns_zone_t *zone, dns_db_t *db,
 1203           dns_dbversion_t *ver, isc_quota_t *quota, rrstream_t *stream,
 1204           dns_tsigkey_t *tsigkey, isc_buffer_t *lasttsig,
 1205           bool verified_tsig, unsigned int maxtime,
 1206           unsigned int idletime, bool many_answers,
 1207           xfrout_ctx_t **xfrp) {
 1208     xfrout_ctx_t *xfr;
 1209     unsigned int len;
 1210     void *mem;
 1211 
 1212     REQUIRE(xfrp != NULL && *xfrp == NULL);
 1213 
 1214     UNUSED(maxtime);
 1215     UNUSED(idletime);
 1216 
 1217     xfr = isc_mem_get(mctx, sizeof(*xfr));
 1218     xfr->mctx = NULL;
 1219     isc_mem_attach(mctx, &xfr->mctx);
 1220     xfr->client = client;
 1221     xfr->id = id;
 1222     xfr->qname = qname;
 1223     xfr->qtype = qtype;
 1224     xfr->qclass = qclass;
 1225     xfr->zone = NULL;
 1226     xfr->db = NULL;
 1227     xfr->ver = NULL;
 1228     if (zone != NULL) { /* zone will be NULL if it's DLZ */
 1229         dns_zone_attach(zone, &xfr->zone);
 1230     }
 1231     dns_db_attach(db, &xfr->db);
 1232     dns_db_attachversion(db, ver, &xfr->ver);
 1233     xfr->question_added = false;
 1234     xfr->end_of_stream = false;
 1235     xfr->tsigkey = tsigkey;
 1236     xfr->lasttsig = lasttsig;
 1237     xfr->verified_tsig = verified_tsig;
 1238     xfr->many_answers = many_answers;
 1239     xfr->sends = 0;
 1240     xfr->shuttingdown = false;
 1241     xfr->poll = false;
 1242     xfr->mnemonic = NULL;
 1243     xfr->buf.base = NULL;
 1244     xfr->buf.length = 0;
 1245     xfr->txmem = NULL;
 1246     xfr->txmemlen = 0;
 1247     xfr->stream = NULL;
 1248     xfr->quota = NULL;
 1249 
 1250     xfr->stats.nmsg = 0;
 1251     xfr->stats.nrecs = 0;
 1252     xfr->stats.nbytes = 0;
 1253     isc_time_now(&xfr->stats.start);
 1254 
 1255     /*
 1256      * Allocate a temporary buffer for the uncompressed response
 1257      * message data.  The size should be no more than 65535 bytes
 1258      * so that the compressed data will fit in a TCP message,
 1259      * and no less than 65535 bytes so that an almost maximum-sized
 1260      * RR will fit.  Note that although 65535-byte RRs are allowed
 1261      * in principle, they cannot be zone-transferred (at least not
 1262      * if uncompressible), because the message and RR headers would
 1263      * push the size of the TCP message over the 65536 byte limit.
 1264      */
 1265     len = 65535;
 1266     mem = isc_mem_get(mctx, len);
 1267     isc_buffer_init(&xfr->buf, mem, len);
 1268 
 1269     /*
 1270      * Allocate another temporary buffer for the compressed
 1271      * response message.
 1272      */
 1273     len = NS_CLIENT_TCP_BUFFER_SIZE;
 1274     mem = isc_mem_get(mctx, len);
 1275     isc_buffer_init(&xfr->txbuf, (char *)mem, len);
 1276     xfr->txmem = mem;
 1277     xfr->txmemlen = len;
 1278 
 1279 #if 0
 1280     CHECK(dns_timer_setidle(xfr->client->timer,
 1281                 maxtime,idletime,false));
 1282 #endif /* if 0 */
 1283 
 1284     /*
 1285      * Register a shutdown callback with the client, so that we
 1286      * can stop the transfer immediately when the client task
 1287      * gets a shutdown event.
 1288      */
 1289     xfr->client->shutdown = xfrout_client_shutdown;
 1290     xfr->client->shutdown_arg = xfr;
 1291     /*
 1292      * These MUST be after the last "goto failure;" / CHECK to
 1293      * prevent a double free by the caller.
 1294      */
 1295     xfr->quota = quota;
 1296     xfr->stream = stream;
 1297 
 1298     *xfrp = xfr;
 1299 }
 1300 
 1301 /*
 1302  * Arrange to send as much as we can of "stream" without blocking.
 1303  *
 1304  * Requires:
 1305  *  The stream iterator is initialized and points at an RR,
 1306  *      or possibly at the end of the stream (that is, the
 1307  *      _first method of the iterator has been called).
 1308  */
 1309 static void
 1310 sendstream(xfrout_ctx_t *xfr) {
 1311     dns_message_t *tcpmsg = NULL;
 1312     dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */
 1313     isc_result_t result;
 1314     dns_rdataset_t *qrdataset;
 1315     dns_name_t *msgname = NULL;
 1316     dns_rdata_t *msgrdata = NULL;
 1317     dns_rdatalist_t *msgrdl = NULL;
 1318     dns_rdataset_t *msgrds = NULL;
 1319     dns_compress_t cctx;
 1320     bool cleanup_cctx = false;
 1321     bool is_tcp;
 1322     int n_rrs;
 1323 
 1324     isc_buffer_clear(&xfr->buf);
 1325     isc_buffer_clear(&xfr->txbuf);
 1326 
 1327     is_tcp = ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0);
 1328     if (!is_tcp) {
 1329         /*
 1330          * In the UDP case, we put the response data directly into
 1331          * the client message.
 1332          */
 1333         msg = xfr->client->message;
 1334         CHECK(dns_message_reply(msg, true));
 1335     } else {
 1336         /*
 1337          * TCP. Build a response dns_message_t, temporarily storing
 1338          * the raw, uncompressed owner names and RR data contiguously
 1339          * in xfr->buf.  We know that if the uncompressed data fits
 1340          * in xfr->buf, the compressed data will surely fit in a TCP
 1341          * message.
 1342          */
 1343 
 1344         CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER,
 1345                      &tcpmsg));
 1346         msg = tcpmsg;
 1347 
 1348         msg->id = xfr->id;
 1349         msg->rcode = dns_rcode_noerror;
 1350         msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
 1351         if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) {
 1352             msg->flags |= DNS_MESSAGEFLAG_RA;
 1353         }
 1354         CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
 1355         CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
 1356         if (xfr->lasttsig != NULL) {
 1357             isc_buffer_free(&xfr->lasttsig);
 1358         }
 1359         msg->verified_sig = xfr->verified_tsig;
 1360 
 1361         /*
 1362          * Add a EDNS option to the message?
 1363          */
 1364         if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
 1365             dns_rdataset_t *opt = NULL;
 1366 
 1367             CHECK(ns_client_addopt(xfr->client, msg, &opt));
 1368             CHECK(dns_message_setopt(msg, opt));
 1369             /*
 1370              * Add to first message only.
 1371              */
 1372             xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID;
 1373             xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE;
 1374         }
 1375 
 1376         /*
 1377          * Account for reserved space.
 1378          */
 1379         if (xfr->tsigkey != NULL) {
 1380             INSIST(msg->reserved != 0U);
 1381         }
 1382         isc_buffer_add(&xfr->buf, msg->reserved);
 1383 
 1384         /*
 1385          * Include a question section in the first message only.
 1386          * BIND 8.2.1 will not recognize an IXFR if it does not
 1387          * have a question section.
 1388          */
 1389         if (!xfr->question_added) {
 1390             dns_name_t *qname = NULL;
 1391             isc_region_t r;
 1392 
 1393             /*
 1394              * Reserve space for the 12-byte message header
 1395              * and 4 bytes of question.
 1396              */
 1397             isc_buffer_add(&xfr->buf, 12 + 4);
 1398 
 1399             qrdataset = NULL;
 1400             result = dns_message_gettemprdataset(msg, &qrdataset);
 1401             if (result != ISC_R_SUCCESS) {
 1402                 goto failure;
 1403             }
 1404             dns_rdataset_makequestion(qrdataset,
 1405                           xfr->client->message->rdclass,
 1406                           xfr->qtype);
 1407 
 1408             result = dns_message_gettempname(msg, &qname);
 1409             if (result != ISC_R_SUCCESS) {
 1410                 goto failure;
 1411             }
 1412             dns_name_init(qname, NULL);
 1413             isc_buffer_availableregion(&xfr->buf, &r);
 1414             INSIST(r.length >= xfr->qname->length);
 1415             r.length = xfr->qname->length;
 1416             isc_buffer_putmem(&xfr->buf, xfr->qname->ndata,
 1417                       xfr->qname->length);
 1418             dns_name_fromregion(qname, &r);
 1419             ISC_LIST_INIT(qname->list);
 1420             ISC_LIST_APPEND(qname->list, qrdataset, link);
 1421 
 1422             dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
 1423             xfr->question_added = true;
 1424         } else {
 1425             /*
 1426              * Reserve space for the 12-byte message header
 1427              */
 1428             isc_buffer_add(&xfr->buf, 12);
 1429             msg->tcp_continuation = 1;
 1430         }
 1431     }
 1432 
 1433     /*
 1434      * Try to fit in as many RRs as possible, unless "one-answer"
 1435      * format has been requested.
 1436      */
 1437     for (n_rrs = 0;; n_rrs++) {
 1438         dns_name_t *name = NULL;
 1439         uint32_t ttl;
 1440         dns_rdata_t *rdata = NULL;
 1441 
 1442         unsigned int size;
 1443         isc_region_t r;
 1444 
 1445         msgname = NULL;
 1446         msgrdata = NULL;
 1447         msgrdl = NULL;
 1448         msgrds = NULL;
 1449 
 1450         xfr->stream->methods->current(xfr->stream, &name, &ttl, &rdata);
 1451         size = name->length + 10 + rdata->length;
 1452         isc_buffer_availableregion(&xfr->buf, &r);
 1453         if (size >= r.length) {
 1454             /*
 1455              * RR would not fit.  If there are other RRs in the
 1456              * buffer, send them now and leave this RR to the
 1457              * next message.  If this RR overflows the buffer
 1458              * all by itself, fail.
 1459              *
 1460              * In theory some RRs might fit in a TCP message
 1461              * when compressed even if they do not fit when
 1462              * uncompressed, but surely we don't want
 1463              * to send such monstrosities to an unsuspecting
 1464              * slave.
 1465              */
 1466             if (n_rrs == 0) {
 1467                 xfrout_log(xfr, ISC_LOG_WARNING,
 1468                        "RR too large for zone transfer "
 1469                        "(%d bytes)",
 1470                        size);
 1471                 /* XXX DNS_R_RRTOOLARGE? */
 1472                 result = ISC_R_NOSPACE;
 1473                 goto failure;
 1474             }
 1475             break;
 1476         }
 1477 
 1478         if (isc_log_wouldlog(ns_lctx, XFROUT_RR_LOGLEVEL)) {
 1479             log_rr(name, rdata, ttl); /* XXX */
 1480         }
 1481 
 1482         result = dns_message_gettempname(msg, &msgname);
 1483         if (result != ISC_R_SUCCESS) {
 1484             goto failure;
 1485         }
 1486         dns_name_init(msgname, NULL);
 1487         isc_buffer_availableregion(&xfr->buf, &r);
 1488         INSIST(r.length >= name->length);
 1489         r.length = name->length;
 1490         isc_buffer_putmem(&xfr->buf, name->ndata, name->length);
 1491         dns_name_fromregion(msgname, &r);
 1492 
 1493         /* Reserve space for RR header. */
 1494         isc_buffer_add(&xfr->buf, 10);
 1495 
 1496         result = dns_message_gettemprdata(msg, &msgrdata);
 1497         if (result != ISC_R_SUCCESS) {
 1498             goto failure;
 1499         }
 1500         isc_buffer_availableregion(&xfr->buf, &r);
 1501         r.length = rdata->length;
 1502         isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length);
 1503         dns_rdata_init(msgrdata);
 1504         dns_rdata_fromregion(msgrdata, rdata->rdclass, rdata->type, &r);
 1505 
 1506         result = dns_message_gettemprdatalist(msg, &msgrdl);
 1507         if (result != ISC_R_SUCCESS) {
 1508             goto failure;
 1509         }
 1510         msgrdl->type = rdata->type;
 1511         msgrdl->rdclass = rdata->rdclass;
 1512         msgrdl->ttl = ttl;
 1513         if (rdata->type == dns_rdatatype_sig ||
 1514             rdata->type == dns_rdatatype_rrsig) {
 1515             msgrdl->covers = dns_rdata_covers(rdata);
 1516         } else {
 1517             msgrdl->covers = dns_rdatatype_none;
 1518         }
 1519         ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link);
 1520 
 1521         result = dns_message_gettemprdataset(msg, &msgrds);
 1522         if (result != ISC_R_SUCCESS) {
 1523             goto failure;
 1524         }
 1525         result = dns_rdatalist_tordataset(msgrdl, msgrds);
 1526         INSIST(result == ISC_R_SUCCESS);
 1527 
 1528         ISC_LIST_APPEND(msgname->list, msgrds, link);
 1529 
 1530         dns_message_addname(msg, msgname, DNS_SECTION_ANSWER);
 1531         msgname = NULL;
 1532 
 1533         xfr->stats.nrecs++;
 1534 
 1535         result = xfr->stream->methods->next(xfr->stream);
 1536         if (result == ISC_R_NOMORE) {
 1537             xfr->end_of_stream = true;
 1538             break;
 1539         }
 1540         CHECK(result);
 1541 
 1542         if (!xfr->many_answers) {
 1543             break;
 1544         }
 1545         /*
 1546          * At this stage, at least 1 RR has been rendered into
 1547          * the message. Check if we want to clamp this message
 1548          * here (TCP only).
 1549          */
 1550         if ((isc_buffer_usedlength(&xfr->buf) >=
 1551              xfr->client->sctx->transfer_tcp_message_size) &&
 1552             is_tcp)
 1553         {
 1554             break;
 1555         }
 1556     }
 1557 
 1558     if (is_tcp) {
 1559         isc_region_t used;
 1560         CHECK(dns_compress_init(&cctx, -1, xfr->mctx));
 1561         dns_compress_setsensitive(&cctx, true);
 1562         cleanup_cctx = true;
 1563         CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf));
 1564         CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
 1565         CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
 1566         CHECK(dns_message_renderend(msg));
 1567         dns_compress_invalidate(&cctx);
 1568         cleanup_cctx = false;
 1569 
 1570         isc_buffer_usedregion(&xfr->txbuf, &used);
 1571 
 1572         xfrout_log(xfr, ISC_LOG_DEBUG(8),
 1573                "sending TCP message of %d bytes", used.length);
 1574 
 1575         CHECK(isc_nm_send(xfr->client->handle, &used, xfrout_senddone,
 1576                   xfr));
 1577         xfr->sends++;
 1578         xfr->cbytes = used.length;
 1579     } else {
 1580         xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
 1581         ns_client_send(xfr->client);
 1582         xfr->stream->methods->pause(xfr->stream);
 1583         isc_nmhandle_unref(xfr->client->handle);
 1584         xfrout_ctx_destroy(&xfr);
 1585         return;
 1586     }
 1587 
 1588     /* Advance lasttsig to be the last TSIG generated */
 1589     CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
 1590 
 1591 failure:
 1592     if (msgname != NULL) {
 1593         if (msgrds != NULL) {
 1594             if (dns_rdataset_isassociated(msgrds)) {
 1595                 dns_rdataset_disassociate(msgrds);
 1596             }
 1597             dns_message_puttemprdataset(msg, &msgrds);
 1598         }
 1599         if (msgrdl != NULL) {
 1600             ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link);
 1601             dns_message_puttemprdatalist(msg, &msgrdl);
 1602         }
 1603         if (msgrdata != NULL) {
 1604             dns_message_puttemprdata(msg, &msgrdata);
 1605         }
 1606         dns_message_puttempname(msg, &msgname);
 1607     }
 1608 
 1609     if (tcpmsg != NULL) {
 1610         dns_message_destroy(&tcpmsg);
 1611     }
 1612 
 1613     if (cleanup_cctx) {
 1614         dns_compress_invalidate(&cctx);
 1615     }
 1616     /*
 1617      * Make sure to release any locks held by database
 1618      * iterators before returning from the event handler.
 1619      */
 1620     xfr->stream->methods->pause(xfr->stream);
 1621 
 1622     if (result == ISC_R_SUCCESS) {
 1623         return;
 1624     }
 1625 
 1626     xfrout_fail(xfr, result, "sending zone data");
 1627 }
 1628 
 1629 static void
 1630 xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
 1631     xfrout_ctx_t *xfr = *xfrp;
 1632     *xfrp = NULL;
 1633 
 1634     INSIST(xfr->sends == 0);
 1635 
 1636     xfr->client->shutdown = NULL;
 1637     xfr->client->shutdown_arg = NULL;
 1638 
 1639     if (xfr->stream != NULL) {
 1640         xfr->stream->methods->destroy(&xfr->stream);
 1641     }
 1642     if (xfr->buf.base != NULL) {
 1643         isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length);
 1644     }
 1645     if (xfr->txmem != NULL) {
 1646         isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen);
 1647     }
 1648     if (xfr->lasttsig != NULL) {
 1649         isc_buffer_free(&xfr->lasttsig);
 1650     }
 1651     if (xfr->quota != NULL) {
 1652         isc_quota_detach(&xfr->quota);
 1653     }
 1654     if (xfr->ver != NULL) {
 1655         dns_db_closeversion(xfr->db, &xfr->ver, false);
 1656     }
 1657     if (xfr->zone != NULL) {
 1658         dns_zone_detach(&xfr->zone);
 1659     }
 1660     if (xfr->db != NULL) {
 1661         dns_db_detach(&xfr->db);
 1662     }
 1663 
 1664     isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
 1665 }
 1666 
 1667 static void
 1668 xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
 1669     xfrout_ctx_t *xfr = (xfrout_ctx_t *)arg;
 1670 
 1671     REQUIRE((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0);
 1672 
 1673     INSIST(handle == xfr->client->handle);
 1674 
 1675     xfr->sends--;
 1676     INSIST(xfr->sends == 0);
 1677 
 1678     /*
 1679      * Update transfer statistics if sending succeeded, accounting for the
 1680      * two-byte TCP length prefix included in the number of bytes sent.
 1681      */
 1682     if (result == ISC_R_SUCCESS) {
 1683         xfr->stats.nmsg++;
 1684         xfr->stats.nbytes += xfr->cbytes;
 1685     }
 1686 
 1687 #if 0
 1688     (void)isc_timer_touch(xfr->client->timer);
 1689 #endif /* if 0 */
 1690 
 1691     if (xfr->shuttingdown) {
 1692         xfrout_maybe_destroy(xfr);
 1693     } else if (result != ISC_R_SUCCESS) {
 1694         xfrout_fail(xfr, result, "send");
 1695     } else if (!xfr->end_of_stream) {
 1696         sendstream(xfr);
 1697     } else {
 1698         /* End of zone transfer stream. */
 1699         uint64_t msecs, persec;
 1700 
 1701         inc_stats(xfr->client, xfr->zone, ns_statscounter_xfrdone);
 1702         isc_time_now(&xfr->stats.end);
 1703         msecs = isc_time_microdiff(&xfr->stats.end, &xfr->stats.start);
 1704         msecs /= 1000;
 1705         if (msecs == 0) {
 1706             msecs = 1;
 1707         }
 1708         persec = (xfr->stats.nbytes * 1000) / msecs;
 1709         xfrout_log(xfr, xfr->poll ? ISC_LOG_DEBUG(1) : ISC_LOG_INFO,
 1710                "%s ended: "
 1711                "%" PRIu64 " messages, %" PRIu64 " records, "
 1712                "%" PRIu64 " bytes, "
 1713                "%u.%03u secs (%u bytes/sec) (serial %u)",
 1714                xfr->mnemonic, xfr->stats.nmsg, xfr->stats.nrecs,
 1715                xfr->stats.nbytes, (unsigned int)(msecs / 1000),
 1716                (unsigned int)(msecs % 1000), (unsigned int)persec,
 1717                xfr->end_serial);
 1718 
 1719         xfrout_ctx_destroy(&xfr);
 1720         /* We're done, unreference the handle */
 1721         isc_nmhandle_unref(handle);
 1722     }
 1723 }
 1724 
 1725 static void
 1726 xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) {
 1727     xfr->shuttingdown = true;
 1728     xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
 1729            isc_result_totext(result));
 1730     xfrout_maybe_destroy(xfr);
 1731 }
 1732 
 1733 static void
 1734 xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
 1735     INSIST(xfr->shuttingdown);
 1736 #if 0
 1737     if (xfr->sends > 0) {
 1738         /*
 1739          * If we are currently sending, cancel it and wait for
 1740          * cancel event before destroying the context.
 1741          */
 1742         isc_socket_cancel(xfr->client->tcpsocket,xfr->client->task,
 1743                   ISC_SOCKCANCEL_SEND);
 1744     } else {
 1745 #endif /* if 0 */
 1746     ns_client_drop(xfr->client, ISC_R_CANCELED);
 1747     isc_nmhandle_unref(xfr->client->handle);
 1748     xfrout_ctx_destroy(&xfr);
 1749 #if 0
 1750 }
 1751 #endif /* if 0 */
 1752 }
 1753 
 1754 static void
 1755 xfrout_client_shutdown(void *arg, isc_result_t result) {
 1756     xfrout_ctx_t *xfr = (xfrout_ctx_t *)arg;
 1757     xfrout_fail(xfr, result, "aborted");
 1758 }
 1759 
 1760 /*
 1761  * Log outgoing zone transfer messages in a format like
 1762  * <client>: transfer of <zone>: <message>
 1763  */
 1764 
 1765 static void
 1766 xfrout_logv(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
 1767         int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0);
 1768 
 1769 static void
 1770 xfrout_logv(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
 1771         int level, const char *fmt, va_list ap) {
 1772     char msgbuf[2048];
 1773     char namebuf[DNS_NAME_FORMATSIZE];
 1774     char classbuf[DNS_RDATACLASS_FORMATSIZE];
 1775 
 1776     dns_name_format(zonename, namebuf, sizeof(namebuf));
 1777     dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
 1778     vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
 1779     ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT,
 1780               level, "transfer of '%s/%s': %s", namebuf, classbuf,
 1781               msgbuf);
 1782 }
 1783 
 1784 /*
 1785  * Logging function for use when a xfrout_ctx_t has not yet been created.
 1786  */
 1787 static void
 1788 xfrout_log1(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
 1789         int level, const char *fmt, ...) {
 1790     va_list ap;
 1791     va_start(ap, fmt);
 1792     xfrout_logv(client, zonename, rdclass, level, fmt, ap);
 1793     va_end(ap);
 1794 }
 1795 
 1796 /*
 1797  * Logging function for use when there is a xfrout_ctx_t.
 1798  */
 1799 static void
 1800 xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) {
 1801     va_list ap;
 1802     va_start(ap, fmt);
 1803     xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap);
 1804     va_end(ap);
 1805 }