2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
22 #include <isc/formatcheck.h>
24 #include <isc/timer.h>
25 #include <isc/print.h>
26 #include <isc/stats.h>
30 #include <dns/dbiterator.h>
34 #include <dns/fixedname.h>
35 #include <dns/journal.h>
36 #include <dns/message.h>
38 #include <dns/rdataclass.h>
39 #include <dns/rdatalist.h>
40 #include <dns/rdataset.h>
41 #include <dns/rdatasetiter.h>
42 #include <dns/result.h>
44 #include <dns/stats.h>
45 #include <dns/timer.h>
51 #include <named/client.h>
52 #include <named/log.h>
53 #include <named/server.h>
54 #include <named/xfrout.h>
58 * Outgoing AXFR and IXFR.
66 #define XFROUT_COMMON_LOGARGS \
67 ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT
69 #define XFROUT_PROTOCOL_LOGARGS \
70 XFROUT_COMMON_LOGARGS, ISC_LOG_INFO
72 #define XFROUT_DEBUG_LOGARGS(n) \
73 XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n)
75 #define XFROUT_RR_LOGARGS \
76 XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL
78 #define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8)
81 * Fail unconditionally and log as a client error.
82 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
83 * from complaining about "end-of-loop code not reached".
85 #define FAILC(code, msg) \
88 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
89 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
90 "bad zone transfer request: %s (%s)", \
91 msg, isc_result_totext(code)); \
92 if (result != ISC_R_SUCCESS) goto failure; \
95 #define FAILQ(code, msg, question, rdclass) \
97 char _buf1[DNS_NAME_FORMATSIZE]; \
98 char _buf2[DNS_RDATACLASS_FORMATSIZE]; \
100 dns_name_format(question, _buf1, sizeof(_buf1)); \
101 dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \
102 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
103 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
104 "bad zone transfer request: '%s/%s': %s (%s)", \
105 _buf1, _buf2, msg, isc_result_totext(code)); \
106 if (result != ISC_R_SUCCESS) goto failure; \
110 do { result = (op); \
111 if (result != ISC_R_SUCCESS) goto failure; \
114 /**************************************************************************/
116 * A db_rr_iterator_t is an iterator that iterates over an entire database,
117 * returning one RR at a time, in some arbitrary order.
120 typedef struct db_rr_iterator db_rr_iterator_t;
122 /*% db_rr_iterator structure */
123 struct db_rr_iterator {
126 dns_dbiterator_t *dbit;
127 dns_dbversion_t *ver;
130 dns_fixedname_t fixedname;
131 dns_rdatasetiter_t *rdatasetit;
132 dns_rdataset_t rdataset;
137 db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
141 db_rr_iterator_first(db_rr_iterator_t *it);
144 db_rr_iterator_next(db_rr_iterator_t *it);
147 db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
148 isc_uint32_t *ttl, dns_rdata_t **rdata);
151 db_rr_iterator_destroy(db_rr_iterator_t *it);
154 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
155 isc_stats_increment(ns_g_server->nsstats, counter);
157 isc_stats_t *zonestats = dns_zone_getrequeststats(zone);
158 if (zonestats != NULL)
159 isc_stats_increment(zonestats, counter);
164 db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
173 result = dns_db_createiterator(it->db, 0, &it->dbit);
174 if (result != ISC_R_SUCCESS)
176 it->rdatasetit = NULL;
177 dns_rdata_init(&it->rdata);
178 dns_rdataset_init(&it->rdataset);
179 dns_fixedname_init(&it->fixedname);
180 INSIST(! dns_rdataset_isassociated(&it->rdataset));
181 it->result = ISC_R_SUCCESS;
186 db_rr_iterator_first(db_rr_iterator_t *it) {
187 it->result = dns_dbiterator_first(it->dbit);
189 * The top node may be empty when out of zone glue exists.
190 * Walk the tree to find the first node with data.
192 while (it->result == ISC_R_SUCCESS) {
193 it->result = dns_dbiterator_current(it->dbit, &it->node,
194 dns_fixedname_name(&it->fixedname));
195 if (it->result != ISC_R_SUCCESS)
198 it->result = dns_db_allrdatasets(it->db, it->node,
201 if (it->result != ISC_R_SUCCESS)
204 it->result = dns_rdatasetiter_first(it->rdatasetit);
205 if (it->result != ISC_R_SUCCESS) {
207 * This node is empty. Try next node.
209 dns_rdatasetiter_destroy(&it->rdatasetit);
210 dns_db_detachnode(it->db, &it->node);
211 it->result = dns_dbiterator_next(it->dbit);
214 dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
215 it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
216 it->result = dns_rdataset_first(&it->rdataset);
224 db_rr_iterator_next(db_rr_iterator_t *it) {
225 if (it->result != ISC_R_SUCCESS)
228 INSIST(it->dbit != NULL);
229 INSIST(it->node != NULL);
230 INSIST(it->rdatasetit != NULL);
232 it->result = dns_rdataset_next(&it->rdataset);
233 if (it->result == ISC_R_NOMORE) {
234 dns_rdataset_disassociate(&it->rdataset);
235 it->result = dns_rdatasetiter_next(it->rdatasetit);
237 * The while loop body is executed more than once
238 * only when an empty dbnode needs to be skipped.
240 while (it->result == ISC_R_NOMORE) {
241 dns_rdatasetiter_destroy(&it->rdatasetit);
242 dns_db_detachnode(it->db, &it->node);
243 it->result = dns_dbiterator_next(it->dbit);
244 if (it->result == ISC_R_NOMORE) {
245 /* We are at the end of the entire database. */
248 if (it->result != ISC_R_SUCCESS)
250 it->result = dns_dbiterator_current(it->dbit,
252 dns_fixedname_name(&it->fixedname));
253 if (it->result != ISC_R_SUCCESS)
255 it->result = dns_db_allrdatasets(it->db, it->node,
258 if (it->result != ISC_R_SUCCESS)
260 it->result = dns_rdatasetiter_first(it->rdatasetit);
262 if (it->result != ISC_R_SUCCESS)
264 dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
265 it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
266 it->result = dns_rdataset_first(&it->rdataset);
267 if (it->result != ISC_R_SUCCESS)
274 db_rr_iterator_pause(db_rr_iterator_t *it) {
275 RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
279 db_rr_iterator_destroy(db_rr_iterator_t *it) {
280 if (dns_rdataset_isassociated(&it->rdataset))
281 dns_rdataset_disassociate(&it->rdataset);
282 if (it->rdatasetit != NULL)
283 dns_rdatasetiter_destroy(&it->rdatasetit);
284 if (it->node != NULL)
285 dns_db_detachnode(it->db, &it->node);
286 dns_dbiterator_destroy(&it->dbit);
290 db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
291 isc_uint32_t *ttl, dns_rdata_t **rdata)
293 REQUIRE(name != NULL && *name == NULL);
294 REQUIRE(it->result == ISC_R_SUCCESS);
295 *name = dns_fixedname_name(&it->fixedname);
296 *ttl = it->rdataset.ttl;
297 dns_rdata_reset(&it->rdata);
298 dns_rdataset_current(&it->rdataset, &it->rdata);
302 /**************************************************************************/
304 /*% Log an RR (for debugging) */
307 log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) {
313 dns_rdata_t rd = DNS_RDATA_INIT;
315 rdl.type = rdata->type;
316 rdl.rdclass = rdata->rdclass;
318 if (rdata->type == dns_rdatatype_sig ||
319 rdata->type == dns_rdatatype_rrsig)
320 rdl.covers = dns_rdata_covers(rdata);
322 rdl.covers = dns_rdatatype_none;
323 ISC_LIST_INIT(rdl.rdata);
324 ISC_LINK_INIT(&rdl, link);
325 dns_rdataset_init(&rds);
327 dns_rdata_clone(rdata, &rd);
328 ISC_LIST_APPEND(rdl.rdata, &rd, link);
329 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS);
331 isc_buffer_init(&buf, mem, sizeof(mem));
332 result = dns_rdataset_totext(&rds, name,
333 ISC_FALSE, ISC_FALSE, &buf);
336 * We could use xfrout_log(), but that would produce
337 * very long lines with a repetitive prefix.
339 if (result == ISC_R_SUCCESS) {
341 * Get rid of final newline.
343 INSIST(buf.used >= 1 &&
344 ((char *) buf.base)[buf.used - 1] == '\n');
347 isc_log_write(XFROUT_RR_LOGARGS, "%.*s",
348 (int)isc_buffer_usedlength(&buf),
349 (char *)isc_buffer_base(&buf));
351 isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>");
355 /**************************************************************************/
357 * An 'rrstream_t' is a polymorphic iterator that returns
358 * a stream of resource records. There are multiple implementations,
359 * e.g. for generating AXFR and IXFR records streams.
362 typedef struct rrstream_methods rrstream_methods_t;
364 typedef struct rrstream {
366 rrstream_methods_t *methods;
369 struct rrstream_methods {
370 isc_result_t (*first)(rrstream_t *);
371 isc_result_t (*next)(rrstream_t *);
372 void (*current)(rrstream_t *,
376 void (*pause)(rrstream_t *);
377 void (*destroy)(rrstream_t **);
381 rrstream_noop_pause(rrstream_t *rs) {
385 /**************************************************************************/
387 * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
388 * an IXFR-like RR stream from a journal file.
390 * The SOA at the beginning of each sequence of additions
391 * or deletions are included in the stream, but the extra
392 * SOAs at the beginning and end of the entire transfer are
396 typedef struct ixfr_rrstream {
398 dns_journal_t *journal;
401 /* Forward declarations. */
403 ixfr_rrstream_destroy(rrstream_t **sp);
405 static rrstream_methods_t ixfr_rrstream_methods;
408 * Returns: anything dns_journal_open() or dns_journal_iter_init()
413 ixfr_rrstream_create(isc_mem_t *mctx,
414 const char *journal_filename,
415 isc_uint32_t begin_serial,
416 isc_uint32_t end_serial,
422 INSIST(sp != NULL && *sp == NULL);
424 s = isc_mem_get(mctx, sizeof(*s));
426 return (ISC_R_NOMEMORY);
427 s->common.mctx = mctx;
428 s->common.methods = &ixfr_rrstream_methods;
431 CHECK(dns_journal_open(mctx, journal_filename,
432 ISC_FALSE, &s->journal));
433 CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial));
435 *sp = (rrstream_t *) s;
436 return (ISC_R_SUCCESS);
439 ixfr_rrstream_destroy((rrstream_t **) (void *)&s);
444 ixfr_rrstream_first(rrstream_t *rs) {
445 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs;
446 return (dns_journal_first_rr(s->journal));
450 ixfr_rrstream_next(rrstream_t *rs) {
451 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs;
452 return (dns_journal_next_rr(s->journal));
456 ixfr_rrstream_current(rrstream_t *rs,
457 dns_name_t **name, isc_uint32_t *ttl,
460 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs;
461 dns_journal_current_rr(s->journal, name, ttl, rdata);
465 ixfr_rrstream_destroy(rrstream_t **rsp) {
466 ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp;
468 dns_journal_destroy(&s->journal);
469 isc_mem_put(s->common.mctx, s, sizeof(*s));
472 static rrstream_methods_t ixfr_rrstream_methods = {
475 ixfr_rrstream_current,
477 ixfr_rrstream_destroy
480 /**************************************************************************/
482 * An 'axfr_rrstream_t' is an 'rrstream_t' that returns
483 * an AXFR-like RR stream from a database.
485 * The SOAs at the beginning and end of the transfer are
486 * not included in the stream.
489 typedef struct axfr_rrstream {
492 isc_boolean_t it_valid;
496 * Forward declarations.
499 axfr_rrstream_destroy(rrstream_t **rsp);
501 static rrstream_methods_t axfr_rrstream_methods;
504 axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
510 INSIST(sp != NULL && *sp == NULL);
512 s = isc_mem_get(mctx, sizeof(*s));
514 return (ISC_R_NOMEMORY);
515 s->common.mctx = mctx;
516 s->common.methods = &axfr_rrstream_methods;
517 s->it_valid = ISC_FALSE;
519 CHECK(db_rr_iterator_init(&s->it, db, ver, 0));
520 s->it_valid = ISC_TRUE;
522 *sp = (rrstream_t *) s;
523 return (ISC_R_SUCCESS);
526 axfr_rrstream_destroy((rrstream_t **) (void *)&s);
531 axfr_rrstream_first(rrstream_t *rs) {
532 axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
534 result = db_rr_iterator_first(&s->it);
535 if (result != ISC_R_SUCCESS)
537 /* Skip SOA records. */
539 dns_name_t *name_dummy = NULL;
540 isc_uint32_t ttl_dummy;
541 dns_rdata_t *rdata = NULL;
542 db_rr_iterator_current(&s->it, &name_dummy,
544 if (rdata->type != dns_rdatatype_soa)
546 result = db_rr_iterator_next(&s->it);
547 if (result != ISC_R_SUCCESS)
554 axfr_rrstream_next(rrstream_t *rs) {
555 axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
558 /* Skip SOA records. */
560 dns_name_t *name_dummy = NULL;
561 isc_uint32_t ttl_dummy;
562 dns_rdata_t *rdata = NULL;
563 result = db_rr_iterator_next(&s->it);
564 if (result != ISC_R_SUCCESS)
566 db_rr_iterator_current(&s->it, &name_dummy,
568 if (rdata->type != dns_rdatatype_soa)
575 axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
578 axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
579 db_rr_iterator_current(&s->it, name, ttl, rdata);
583 axfr_rrstream_pause(rrstream_t *rs) {
584 axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
585 db_rr_iterator_pause(&s->it);
589 axfr_rrstream_destroy(rrstream_t **rsp) {
590 axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp;
592 db_rr_iterator_destroy(&s->it);
593 isc_mem_put(s->common.mctx, s, sizeof(*s));
596 static rrstream_methods_t axfr_rrstream_methods = {
599 axfr_rrstream_current,
601 axfr_rrstream_destroy
604 /**************************************************************************/
606 * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns
607 * a single SOA record.
610 typedef struct soa_rrstream {
612 dns_difftuple_t *soa_tuple;
616 * Forward declarations.
619 soa_rrstream_destroy(rrstream_t **rsp);
621 static rrstream_methods_t soa_rrstream_methods;
624 soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
630 INSIST(sp != NULL && *sp == NULL);
632 s = isc_mem_get(mctx, sizeof(*s));
634 return (ISC_R_NOMEMORY);
635 s->common.mctx = mctx;
636 s->common.methods = &soa_rrstream_methods;
639 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
642 *sp = (rrstream_t *) s;
643 return (ISC_R_SUCCESS);
646 soa_rrstream_destroy((rrstream_t **) (void *)&s);
651 soa_rrstream_first(rrstream_t *rs) {
653 return (ISC_R_SUCCESS);
657 soa_rrstream_next(rrstream_t *rs) {
659 return (ISC_R_NOMORE);
663 soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
666 soa_rrstream_t *s = (soa_rrstream_t *) rs;
667 *name = &s->soa_tuple->name;
668 *ttl = s->soa_tuple->ttl;
669 *rdata = &s->soa_tuple->rdata;
673 soa_rrstream_destroy(rrstream_t **rsp) {
674 soa_rrstream_t *s = (soa_rrstream_t *) *rsp;
675 if (s->soa_tuple != NULL)
676 dns_difftuple_free(&s->soa_tuple);
677 isc_mem_put(s->common.mctx, s, sizeof(*s));
680 static rrstream_methods_t soa_rrstream_methods = {
683 soa_rrstream_current,
688 /**************************************************************************/
690 * A 'compound_rrstream_t' objects owns a soa_rrstream
691 * and another rrstream, the "data stream". It returns
692 * a concatenated stream consisting of the soa_rrstream, then
693 * the data stream, then the soa_rrstream again.
695 * The component streams are owned by the compound_rrstream_t
696 * and are destroyed with it.
699 typedef struct compound_rrstream {
701 rrstream_t *components[3];
704 } compound_rrstream_t;
707 * Forward declarations.
710 compound_rrstream_destroy(rrstream_t **rsp);
713 compound_rrstream_next(rrstream_t *rs);
715 static rrstream_methods_t compound_rrstream_methods;
719 * soa_stream != NULL && *soa_stream != NULL
720 * data_stream != NULL && *data_stream != NULL
721 * sp != NULL && *sp == NULL
724 * *soa_stream == NULL
725 * *data_stream == NULL
726 * *sp points to a valid compound_rrstream_t
727 * The soa and data streams will be destroyed
728 * when the compound_rrstream_t is destroyed.
731 compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream,
732 rrstream_t **data_stream, rrstream_t **sp)
734 compound_rrstream_t *s;
736 INSIST(sp != NULL && *sp == NULL);
738 s = isc_mem_get(mctx, sizeof(*s));
740 return (ISC_R_NOMEMORY);
741 s->common.mctx = mctx;
742 s->common.methods = &compound_rrstream_methods;
743 s->components[0] = *soa_stream;
744 s->components[1] = *data_stream;
745 s->components[2] = *soa_stream;
747 s->result = ISC_R_FAILURE;
751 *sp = (rrstream_t *) s;
752 return (ISC_R_SUCCESS);
756 compound_rrstream_first(rrstream_t *rs) {
757 compound_rrstream_t *s = (compound_rrstream_t *) rs;
760 rrstream_t *curstream = s->components[s->state];
761 s->result = curstream->methods->first(curstream);
762 } while (s->result == ISC_R_NOMORE && s->state < 2);
767 compound_rrstream_next(rrstream_t *rs) {
768 compound_rrstream_t *s = (compound_rrstream_t *) rs;
769 rrstream_t *curstream = s->components[s->state];
770 s->result = curstream->methods->next(curstream);
771 while (s->result == ISC_R_NOMORE) {
773 * Make sure locks held by the current stream
774 * are released before we switch streams.
776 curstream->methods->pause(curstream);
778 return (ISC_R_NOMORE);
780 curstream = s->components[s->state];
781 s->result = curstream->methods->first(curstream);
787 compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
790 compound_rrstream_t *s = (compound_rrstream_t *) rs;
791 rrstream_t *curstream;
792 INSIST(0 <= s->state && s->state < 3);
793 INSIST(s->result == ISC_R_SUCCESS);
794 curstream = s->components[s->state];
795 curstream->methods->current(curstream, name, ttl, rdata);
799 compound_rrstream_pause(rrstream_t *rs)
801 compound_rrstream_t *s = (compound_rrstream_t *) rs;
802 rrstream_t *curstream;
803 INSIST(0 <= s->state && s->state < 3);
804 curstream = s->components[s->state];
805 curstream->methods->pause(curstream);
809 compound_rrstream_destroy(rrstream_t **rsp) {
810 compound_rrstream_t *s = (compound_rrstream_t *) *rsp;
811 s->components[0]->methods->destroy(&s->components[0]);
812 s->components[1]->methods->destroy(&s->components[1]);
813 s->components[2] = NULL; /* Copy of components[0]. */
814 isc_mem_put(s->common.mctx, s, sizeof(*s));
817 static rrstream_methods_t compound_rrstream_methods = {
818 compound_rrstream_first,
819 compound_rrstream_next,
820 compound_rrstream_current,
821 compound_rrstream_pause,
822 compound_rrstream_destroy
825 /**************************************************************************/
827 * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR
834 unsigned int id; /* ID of request */
835 dns_name_t *qname; /* Question name of request */
836 dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */
837 dns_rdataclass_t qclass;
838 dns_zone_t *zone; /* (necessary for stats) */
840 dns_dbversion_t *ver;
842 rrstream_t *stream; /* The XFR RR stream */
843 isc_boolean_t end_of_stream; /* EOS has been reached */
844 isc_buffer_t buf; /* Buffer for message owner
846 isc_buffer_t txlenbuf; /* Transmit length buffer */
847 isc_buffer_t txbuf; /* Transmit message buffer */
849 unsigned int txmemlen;
850 unsigned int nmsg; /* Number of messages sent */
851 dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
852 isc_buffer_t *lasttsig; /* the last TSIG */
853 isc_boolean_t many_answers;
854 int sends; /* Send in progress */
855 isc_boolean_t shuttingdown;
856 const char *mnemonic; /* Style of transfer */
860 xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client,
861 unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype,
862 dns_rdataclass_t qclass, dns_zone_t *zone,
863 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota,
864 rrstream_t *stream, dns_tsigkey_t *tsigkey,
865 isc_buffer_t *lasttsig,
866 unsigned int maxtime,
867 unsigned int idletime,
868 isc_boolean_t many_answers,
869 xfrout_ctx_t **xfrp);
872 sendstream(xfrout_ctx_t *xfr);
875 xfrout_senddone(isc_task_t *task, isc_event_t *event);
878 xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg);
881 xfrout_maybe_destroy(xfrout_ctx_t *xfr);
884 xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
887 xfrout_client_shutdown(void *arg, isc_result_t result);
890 xfrout_log1(ns_client_t *client, dns_name_t *zonename,
891 dns_rdataclass_t rdclass, int level,
892 const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
895 xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...)
896 ISC_FORMAT_PRINTF(3, 4);
898 /**************************************************************************/
901 ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
903 dns_name_t *question_name;
904 dns_rdataset_t *question_rdataset;
905 dns_zone_t *zone = NULL;
907 dns_dbversion_t *ver = NULL;
908 dns_rdataclass_t question_class;
909 rrstream_t *soa_stream = NULL;
910 rrstream_t *data_stream = NULL;
911 rrstream_t *stream = NULL;
912 dns_difftuple_t *current_soa_tuple = NULL;
913 dns_name_t *soa_name;
914 dns_rdataset_t *soa_rdataset;
915 dns_rdata_t soa_rdata = DNS_RDATA_INIT;
916 isc_boolean_t have_soa = ISC_FALSE;
917 const char *mnemonic = NULL;
918 isc_mem_t *mctx = client->mctx;
919 dns_message_t *request = client->message;
920 xfrout_ctx_t *xfr = NULL;
921 isc_quota_t *quota = NULL;
922 dns_transfer_format_t format = client->view->transfer_format;
924 dns_peer_t *peer = NULL;
925 isc_buffer_t *tsigbuf = NULL;
927 char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")];
928 char keyname[DNS_NAME_FORMATSIZE];
929 isc_boolean_t is_poll = ISC_FALSE;
931 isc_boolean_t is_dlz = ISC_FALSE;
935 case dns_rdatatype_axfr:
938 case dns_rdatatype_ixfr:
946 ns_client_log(client,
947 DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT,
948 ISC_LOG_DEBUG(6), "%s request", mnemonic);
952 result = isc_quota_attach(&ns_g_server->xfroutquota, "a);
953 if (result != ISC_R_SUCCESS) {
954 isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING,
955 "%s request denied: %s", mnemonic,
956 isc_result_totext(result));
961 * Interpret the question section.
963 result = dns_message_firstname(request, DNS_SECTION_QUESTION);
964 INSIST(result == ISC_R_SUCCESS);
967 * The question section must contain exactly one question, and
968 * it must be for AXFR/IXFR as appropriate.
970 question_name = NULL;
971 dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name);
972 question_rdataset = ISC_LIST_HEAD(question_name->list);
973 question_class = question_rdataset->rdclass;
974 INSIST(question_rdataset->type == reqtype);
975 if (ISC_LIST_NEXT(question_rdataset, link) != NULL)
976 FAILC(DNS_R_FORMERR, "multiple questions");
977 result = dns_message_nextname(request, DNS_SECTION_QUESTION);
978 if (result != ISC_R_NOMORE)
979 FAILC(DNS_R_FORMERR, "multiple questions");
981 result = dns_zt_find(client->view->zonetable, question_name, 0, NULL,
984 if (result != ISC_R_SUCCESS)
988 * Normal zone table does not have a match.
989 * Try the DLZ database
991 if (client->view->dlzdatabase != NULL) {
992 result = dns_dlzallowzonexfr(client->view,
997 if (result == ISC_R_NOPERM) {
998 char _buf1[DNS_NAME_FORMATSIZE];
999 char _buf2[DNS_RDATACLASS_FORMATSIZE];
1001 result = DNS_R_REFUSED;
1002 dns_name_format(question_name, _buf1,
1004 dns_rdataclass_format(question_class,
1005 _buf2, sizeof(_buf2));
1006 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1007 NS_LOGMODULE_XFER_OUT,
1009 "zone transfer '%s/%s' denied",
1013 if (result != ISC_R_SUCCESS)
1015 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
1016 question_name, question_class);
1020 * DLZ only support full zone transfer, not incremental
1022 if (reqtype != dns_rdatatype_axfr) {
1023 mnemonic = "AXFR-style IXFR";
1024 reqtype = dns_rdatatype_axfr;
1029 * not DLZ and not in normal zone table, we are
1032 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
1033 question_name, question_class);
1036 /* zone table has a match */
1038 switch(dns_zone_gettype(zone)) {
1039 case dns_zone_master:
1040 case dns_zone_slave:
1041 break; /* Master and slave zones are OK for transfer. */
1043 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class);
1045 CHECK(dns_zone_getdb(zone, &db));
1046 dns_db_currentversion(db, &ver);
1051 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6),
1052 "%s question section OK", mnemonic);
1055 * Check the authority section. Look for a SOA record with
1056 * the same name and class as the question.
1058 for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY);
1059 result == ISC_R_SUCCESS;
1060 result = dns_message_nextname(request, DNS_SECTION_AUTHORITY))
1063 dns_message_currentname(request, DNS_SECTION_AUTHORITY,
1067 * Ignore data whose owner name is not the zone apex.
1069 if (! dns_name_equal(soa_name, question_name))
1072 for (soa_rdataset = ISC_LIST_HEAD(soa_name->list);
1073 soa_rdataset != NULL;
1074 soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link))
1077 * Ignore non-SOA data.
1079 if (soa_rdataset->type != dns_rdatatype_soa)
1081 if (soa_rdataset->rdclass != question_class)
1084 CHECK(dns_rdataset_first(soa_rdataset));
1085 dns_rdataset_current(soa_rdataset, &soa_rdata);
1086 result = dns_rdataset_next(soa_rdataset);
1087 if (result == ISC_R_SUCCESS)
1088 FAILC(DNS_R_FORMERR,
1089 "IXFR authority section "
1090 "has multiple SOAs");
1091 have_soa = ISC_TRUE;
1096 if (result != ISC_R_NOMORE)
1099 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6),
1100 "%s authority section OK", mnemonic);
1103 * Decide whether to allow this transfer.
1107 * if not a DLZ zone decide whether to allow this transfer.
1111 ns_client_aclmsg("zone transfer", question_name, reqtype,
1112 client->view->rdclass, msg, sizeof(msg));
1113 CHECK(ns_client_checkacl(client, NULL, msg,
1114 dns_zone_getxfracl(zone),
1115 ISC_TRUE, ISC_LOG_ERROR));
1121 * AXFR over UDP is not possible.
1123 if (reqtype == dns_rdatatype_axfr &&
1124 (client->attributes & NS_CLIENTATTR_TCP) == 0)
1125 FAILC(DNS_R_FORMERR, "attempted AXFR over UDP");
1128 * Look up the requesting server in the peer table.
1130 isc_netaddr_fromsockaddr(&na, &client->peeraddr);
1131 (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer);
1134 * Decide on the transfer format (one-answer or many-answers).
1137 (void)dns_peer_gettransferformat(peer, &format);
1140 * Get a dynamically allocated copy of the current SOA.
1144 dns_db_currentversion(db, &ver);
1146 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
1147 ¤t_soa_tuple));
1149 if (reqtype == dns_rdatatype_ixfr) {
1150 isc_uint32_t begin_serial, current_serial;
1151 isc_boolean_t provide_ixfr;
1154 * Outgoing IXFR may have been disabled for this peer
1157 provide_ixfr = client->view->provideixfr;
1159 (void) dns_peer_getprovideixfr(peer, &provide_ixfr);
1160 if (provide_ixfr == ISC_FALSE)
1164 FAILC(DNS_R_FORMERR,
1165 "IXFR request missing SOA");
1167 begin_serial = dns_soa_getserial(&soa_rdata);
1168 current_serial = dns_soa_getserial(¤t_soa_tuple->rdata);
1171 * RFC1995 says "If an IXFR query with the same or
1172 * newer version number than that of the server
1173 * is received, it is replied to with a single SOA
1174 * record of the server's current version, just as
1175 * in AXFR". The claim about AXFR is incorrect,
1176 * but other than that, we do as the RFC says.
1178 * Sending a single SOA record is also how we refuse
1179 * IXFR over UDP (currently, we always do).
1181 if (DNS_SERIAL_GE(begin_serial, current_serial) ||
1182 (client->attributes & NS_CLIENTATTR_TCP) == 0)
1184 CHECK(soa_rrstream_create(mctx, db, ver, &stream));
1188 journalfile = dns_zone_getjournal(zone);
1189 if (journalfile != NULL)
1190 result = ixfr_rrstream_create(mctx,
1196 result = ISC_R_NOTFOUND;
1197 if (result == ISC_R_NOTFOUND ||
1198 result == ISC_R_RANGE) {
1199 xfrout_log1(client, question_name, question_class,
1201 "IXFR version not in journal, "
1202 "falling back to AXFR");
1203 mnemonic = "AXFR-style IXFR";
1209 CHECK(axfr_rrstream_create(mctx, db, ver,
1214 * Bracket the data stream with SOAs.
1216 CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream));
1217 CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream,
1223 CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf));
1225 * Create the xfrout context object. This transfers the ownership
1226 * of "stream", "db", "ver", and "quota" to the xfrout context object.
1233 CHECK(xfrout_ctx_create(mctx, client, request->id,
1234 question_name, reqtype, question_class,
1235 zone, db, ver, quota, stream,
1236 dns_message_gettsigkey(request),
1240 (format == dns_many_answers) ?
1241 ISC_TRUE : ISC_FALSE,
1245 CHECK(xfrout_ctx_create(mctx, client, request->id,
1246 question_name, reqtype, question_class,
1247 zone, db, ver, quota, stream,
1248 dns_message_gettsigkey(request),
1250 dns_zone_getmaxxfrout(zone),
1251 dns_zone_getidleout(zone),
1252 (format == dns_many_answers) ?
1253 ISC_TRUE : ISC_FALSE,
1256 xfr->mnemonic = mnemonic;
1260 CHECK(xfr->stream->methods->first(xfr->stream));
1262 if (xfr->tsigkey != NULL)
1263 dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname));
1267 xfrout_log1(client, question_name, question_class,
1268 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s",
1269 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname);
1271 xfrout_log1(client, question_name, question_class,
1272 ISC_LOG_INFO, "%s started%s%s", mnemonic,
1273 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname);
1276 * Hand the context over to sendstream(). Set xfr to NULL;
1277 * sendstream() is responsible for either passing the
1278 * context on to a later event handler or destroying it.
1283 result = ISC_R_SUCCESS;
1286 if (result == DNS_R_REFUSED)
1287 inc_stats(zone, dns_nsstatscounter_xfrrej);
1289 isc_quota_detach("a);
1290 if (current_soa_tuple != NULL)
1291 dns_difftuple_free(¤t_soa_tuple);
1293 stream->methods->destroy(&stream);
1294 if (soa_stream != NULL)
1295 soa_stream->methods->destroy(&soa_stream);
1296 if (data_stream != NULL)
1297 data_stream->methods->destroy(&data_stream);
1299 dns_db_closeversion(db, &ver, ISC_FALSE);
1303 dns_zone_detach(&zone);
1306 xfrout_fail(xfr, result, "setting up zone transfer");
1307 } else if (result != ISC_R_SUCCESS) {
1308 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,
1309 NS_LOGMODULE_XFER_OUT,
1310 ISC_LOG_DEBUG(3), "zone transfer setup failed");
1311 ns_client_error(client, result);
1316 xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
1317 dns_name_t *qname, dns_rdatatype_t qtype,
1318 dns_rdataclass_t qclass, dns_zone_t *zone,
1319 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota,
1320 rrstream_t *stream, dns_tsigkey_t *tsigkey,
1321 isc_buffer_t *lasttsig, unsigned int maxtime,
1322 unsigned int idletime, isc_boolean_t many_answers,
1323 xfrout_ctx_t **xfrp)
1326 isc_result_t result;
1330 INSIST(xfrp != NULL && *xfrp == NULL);
1331 xfr = isc_mem_get(mctx, sizeof(*xfr));
1333 return (ISC_R_NOMEMORY);
1335 isc_mem_attach(mctx, &xfr->mctx);
1337 ns_client_attach(client, &xfr->client);
1341 xfr->qclass = qclass;
1345 if (zone != NULL) /* zone will be NULL if it's DLZ */
1346 dns_zone_attach(zone, &xfr->zone);
1347 dns_db_attach(db, &xfr->db);
1348 dns_db_attachversion(db, ver, &xfr->ver);
1349 xfr->end_of_stream = ISC_FALSE;
1350 xfr->tsigkey = tsigkey;
1351 xfr->lasttsig = lasttsig;
1355 xfr->many_answers = many_answers,
1357 xfr->shuttingdown = ISC_FALSE;
1358 xfr->mnemonic = NULL;
1359 xfr->buf.base = NULL;
1360 xfr->buf.length = 0;
1367 * Allocate a temporary buffer for the uncompressed response
1368 * message data. The size should be no more than 65535 bytes
1369 * so that the compressed data will fit in a TCP message,
1370 * and no less than 65535 bytes so that an almost maximum-sized
1371 * RR will fit. Note that although 65535-byte RRs are allowed
1372 * in principle, they cannot be zone-transferred (at least not
1373 * if uncompressible), because the message and RR headers would
1374 * push the size of the TCP message over the 65536 byte limit.
1377 mem = isc_mem_get(mctx, len);
1379 result = ISC_R_NOMEMORY;
1382 isc_buffer_init(&xfr->buf, mem, len);
1385 * Allocate another temporary buffer for the compressed
1386 * response message and its TCP length prefix.
1389 mem = isc_mem_get(mctx, len);
1391 result = ISC_R_NOMEMORY;
1394 isc_buffer_init(&xfr->txlenbuf, mem, 2);
1395 isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2);
1397 xfr->txmemlen = len;
1399 CHECK(dns_timer_setidle(xfr->client->timer,
1400 maxtime, idletime, ISC_FALSE));
1403 * Register a shutdown callback with the client, so that we
1404 * can stop the transfer immediately when the client task
1405 * gets a shutdown event.
1407 xfr->client->shutdown = xfrout_client_shutdown;
1408 xfr->client->shutdown_arg = xfr;
1410 * These MUST be after the last "goto failure;" / CHECK to
1411 * prevent a double free by the caller.
1414 xfr->stream = stream;
1417 return (ISC_R_SUCCESS);
1420 xfrout_ctx_destroy(&xfr);
1426 * Arrange to send as much as we can of "stream" without blocking.
1429 * The stream iterator is initialized and points at an RR,
1430 * or possibly at the end of the stream (that is, the
1431 * _first method of the iterator has been called).
1434 sendstream(xfrout_ctx_t *xfr) {
1435 dns_message_t *tcpmsg = NULL;
1436 dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */
1437 isc_result_t result;
1439 isc_region_t region;
1440 dns_rdataset_t *qrdataset;
1441 dns_name_t *msgname = NULL;
1442 dns_rdata_t *msgrdata = NULL;
1443 dns_rdatalist_t *msgrdl = NULL;
1444 dns_rdataset_t *msgrds = NULL;
1445 dns_compress_t cctx;
1446 isc_boolean_t cleanup_cctx = ISC_FALSE;
1450 isc_buffer_clear(&xfr->buf);
1451 isc_buffer_clear(&xfr->txlenbuf);
1452 isc_buffer_clear(&xfr->txbuf);
1454 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) {
1456 * In the UDP case, we put the response data directly into
1457 * the client message.
1459 msg = xfr->client->message;
1460 CHECK(dns_message_reply(msg, ISC_TRUE));
1463 * TCP. Build a response dns_message_t, temporarily storing
1464 * the raw, uncompressed owner names and RR data contiguously
1465 * in xfr->buf. We know that if the uncompressed data fits
1466 * in xfr->buf, the compressed data will surely fit in a TCP
1470 CHECK(dns_message_create(xfr->mctx,
1471 DNS_MESSAGE_INTENTRENDER, &tcpmsg));
1475 msg->rcode = dns_rcode_noerror;
1476 msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
1477 if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0)
1478 msg->flags |= DNS_MESSAGEFLAG_RA;
1479 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1480 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1481 if (xfr->lasttsig != NULL)
1482 isc_buffer_free(&xfr->lasttsig);
1485 * Account for reserved space.
1487 if (xfr->tsigkey != NULL)
1488 INSIST(msg->reserved != 0U);
1489 isc_buffer_add(&xfr->buf, msg->reserved);
1492 * Include a question section in the first message only.
1493 * BIND 8.2.1 will not recognize an IXFR if it does not
1494 * have a question section.
1496 if (xfr->nmsg == 0) {
1497 dns_name_t *qname = NULL;
1501 * Reserve space for the 12-byte message header
1502 * and 4 bytes of question.
1504 isc_buffer_add(&xfr->buf, 12 + 4);
1507 result = dns_message_gettemprdataset(msg, &qrdataset);
1508 if (result != ISC_R_SUCCESS)
1510 dns_rdataset_init(qrdataset);
1511 dns_rdataset_makequestion(qrdataset,
1512 xfr->client->message->rdclass,
1515 result = dns_message_gettempname(msg, &qname);
1516 if (result != ISC_R_SUCCESS)
1518 dns_name_init(qname, NULL);
1519 isc_buffer_availableregion(&xfr->buf, &r);
1520 INSIST(r.length >= xfr->qname->length);
1521 r.length = xfr->qname->length;
1522 isc_buffer_putmem(&xfr->buf, xfr->qname->ndata,
1523 xfr->qname->length);
1524 dns_name_fromregion(qname, &r);
1525 ISC_LIST_INIT(qname->list);
1526 ISC_LIST_APPEND(qname->list, qrdataset, link);
1528 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1531 * Reserve space for the 12-byte message header
1533 isc_buffer_add(&xfr->buf, 12);
1534 msg->tcp_continuation = 1;
1539 * Try to fit in as many RRs as possible, unless "one-answer"
1540 * format has been requested.
1542 for (n_rrs = 0; ; n_rrs++) {
1543 dns_name_t *name = NULL;
1545 dns_rdata_t *rdata = NULL;
1555 xfr->stream->methods->current(xfr->stream,
1556 &name, &ttl, &rdata);
1557 size = name->length + 10 + rdata->length;
1558 isc_buffer_availableregion(&xfr->buf, &r);
1559 if (size >= r.length) {
1561 * RR would not fit. If there are other RRs in the
1562 * buffer, send them now and leave this RR to the
1563 * next message. If this RR overflows the buffer
1564 * all by itself, fail.
1566 * In theory some RRs might fit in a TCP message
1567 * when compressed even if they do not fit when
1568 * uncompressed, but surely we don't want
1569 * to send such monstrosities to an unsuspecting
1573 xfrout_log(xfr, ISC_LOG_WARNING,
1574 "RR too large for zone transfer "
1575 "(%d bytes)", size);
1576 /* XXX DNS_R_RRTOOLARGE? */
1577 result = ISC_R_NOSPACE;
1583 if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL))
1584 log_rr(name, rdata, ttl); /* XXX */
1586 result = dns_message_gettempname(msg, &msgname);
1587 if (result != ISC_R_SUCCESS)
1589 dns_name_init(msgname, NULL);
1590 isc_buffer_availableregion(&xfr->buf, &r);
1591 INSIST(r.length >= name->length);
1592 r.length = name->length;
1593 isc_buffer_putmem(&xfr->buf, name->ndata, name->length);
1594 dns_name_fromregion(msgname, &r);
1596 /* Reserve space for RR header. */
1597 isc_buffer_add(&xfr->buf, 10);
1599 result = dns_message_gettemprdata(msg, &msgrdata);
1600 if (result != ISC_R_SUCCESS)
1602 isc_buffer_availableregion(&xfr->buf, &r);
1603 r.length = rdata->length;
1604 isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length);
1605 dns_rdata_init(msgrdata);
1606 dns_rdata_fromregion(msgrdata,
1607 rdata->rdclass, rdata->type, &r);
1609 result = dns_message_gettemprdatalist(msg, &msgrdl);
1610 if (result != ISC_R_SUCCESS)
1612 msgrdl->type = rdata->type;
1613 msgrdl->rdclass = rdata->rdclass;
1615 if (rdata->type == dns_rdatatype_sig ||
1616 rdata->type == dns_rdatatype_rrsig)
1617 msgrdl->covers = dns_rdata_covers(rdata);
1619 msgrdl->covers = dns_rdatatype_none;
1620 ISC_LINK_INIT(msgrdl, link);
1621 ISC_LIST_INIT(msgrdl->rdata);
1622 ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link);
1624 result = dns_message_gettemprdataset(msg, &msgrds);
1625 if (result != ISC_R_SUCCESS)
1627 dns_rdataset_init(msgrds);
1628 result = dns_rdatalist_tordataset(msgrdl, msgrds);
1629 INSIST(result == ISC_R_SUCCESS);
1631 ISC_LIST_APPEND(msgname->list, msgrds, link);
1633 dns_message_addname(msg, msgname, DNS_SECTION_ANSWER);
1636 result = xfr->stream->methods->next(xfr->stream);
1637 if (result == ISC_R_NOMORE) {
1638 xfr->end_of_stream = ISC_TRUE;
1643 if (! xfr->many_answers)
1647 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) {
1648 CHECK(dns_compress_init(&cctx, -1, xfr->mctx));
1649 dns_compress_setsensitive(&cctx, ISC_TRUE);
1650 cleanup_cctx = ISC_TRUE;
1651 CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf));
1652 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
1653 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
1654 CHECK(dns_message_renderend(msg));
1655 dns_compress_invalidate(&cctx);
1656 cleanup_cctx = ISC_FALSE;
1658 isc_buffer_usedregion(&xfr->txbuf, &used);
1659 isc_buffer_putuint16(&xfr->txlenbuf,
1660 (isc_uint16_t)used.length);
1661 region.base = xfr->txlenbuf.base;
1662 region.length = 2 + used.length;
1663 xfrout_log(xfr, ISC_LOG_DEBUG(8),
1664 "sending TCP message of %d bytes",
1666 CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */
1667 ®ion, xfr->client->task,
1672 xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
1673 ns_client_send(xfr->client);
1674 xfr->stream->methods->pause(xfr->stream);
1675 xfrout_ctx_destroy(&xfr);
1679 /* Advance lasttsig to be the last TSIG generated */
1680 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1685 if (msgname != NULL) {
1686 if (msgrds != NULL) {
1687 if (dns_rdataset_isassociated(msgrds))
1688 dns_rdataset_disassociate(msgrds);
1689 dns_message_puttemprdataset(msg, &msgrds);
1691 if (msgrdl != NULL) {
1692 ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link);
1693 dns_message_puttemprdatalist(msg, &msgrdl);
1695 if (msgrdata != NULL)
1696 dns_message_puttemprdata(msg, &msgrdata);
1697 dns_message_puttempname(msg, &msgname);
1701 dns_message_destroy(&tcpmsg);
1704 dns_compress_invalidate(&cctx);
1706 * Make sure to release any locks held by database
1707 * iterators before returning from the event handler.
1709 xfr->stream->methods->pause(xfr->stream);
1711 if (result == ISC_R_SUCCESS)
1714 xfrout_fail(xfr, result, "sending zone data");
1718 xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
1719 xfrout_ctx_t *xfr = *xfrp;
1720 ns_client_t *client = NULL;
1722 INSIST(xfr->sends == 0);
1724 xfr->client->shutdown = NULL;
1725 xfr->client->shutdown_arg = NULL;
1727 if (xfr->stream != NULL)
1728 xfr->stream->methods->destroy(&xfr->stream);
1729 if (xfr->buf.base != NULL)
1730 isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length);
1731 if (xfr->txmem != NULL)
1732 isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen);
1733 if (xfr->lasttsig != NULL)
1734 isc_buffer_free(&xfr->lasttsig);
1735 if (xfr->quota != NULL)
1736 isc_quota_detach(&xfr->quota);
1737 if (xfr->ver != NULL)
1738 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
1739 if (xfr->zone != NULL)
1740 dns_zone_detach(&xfr->zone);
1741 if (xfr->db != NULL)
1742 dns_db_detach(&xfr->db);
1745 * We want to detch the client after we have released the memory
1746 * context as ns_client_detach checks the memory reference count.
1748 ns_client_attach(xfr->client, &client);
1749 ns_client_detach(&xfr->client);
1750 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1751 ns_client_detach(&client);
1757 xfrout_senddone(isc_task_t *task, isc_event_t *event) {
1758 isc_socketevent_t *sev = (isc_socketevent_t *)event;
1759 xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg;
1760 isc_result_t evresult = sev->result;
1764 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1766 isc_event_free(&event);
1768 INSIST(xfr->sends == 0);
1770 (void)isc_timer_touch(xfr->client->timer);
1771 if (xfr->shuttingdown == ISC_TRUE) {
1772 xfrout_maybe_destroy(xfr);
1773 } else if (evresult != ISC_R_SUCCESS) {
1774 xfrout_fail(xfr, evresult, "send");
1775 } else if (xfr->end_of_stream == ISC_FALSE) {
1778 /* End of zone transfer stream. */
1779 inc_stats(xfr->zone, dns_nsstatscounter_xfrdone);
1780 xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic);
1781 ns_client_next(xfr->client, ISC_R_SUCCESS);
1782 xfrout_ctx_destroy(&xfr);
1787 xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) {
1788 xfr->shuttingdown = ISC_TRUE;
1789 xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s",
1790 msg, isc_result_totext(result));
1791 xfrout_maybe_destroy(xfr);
1795 xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
1796 INSIST(xfr->shuttingdown == ISC_TRUE);
1797 if (xfr->sends > 0) {
1799 * If we are currently sending, cancel it and wait for
1800 * cancel event before destroying the context.
1802 isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task,
1803 ISC_SOCKCANCEL_SEND);
1805 ns_client_next(xfr->client, ISC_R_CANCELED);
1806 xfrout_ctx_destroy(&xfr);
1811 xfrout_client_shutdown(void *arg, isc_result_t result) {
1812 xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg;
1813 xfrout_fail(xfr, result, "aborted");
1817 * Log outgoing zone transfer messages in a format like
1818 * <client>: transfer of <zone>: <message>
1822 xfrout_logv(ns_client_t *client, dns_name_t *zonename,
1823 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap)
1824 ISC_FORMAT_PRINTF(5, 0);
1827 xfrout_logv(ns_client_t *client, dns_name_t *zonename,
1828 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap)
1831 char namebuf[DNS_NAME_FORMATSIZE];
1832 char classbuf[DNS_RDATACLASS_FORMATSIZE];
1834 dns_name_format(zonename, namebuf, sizeof(namebuf));
1835 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
1836 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
1837 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,
1838 NS_LOGMODULE_XFER_OUT, level,
1839 "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf);
1843 * Logging function for use when a xfrout_ctx_t has not yet been created.
1846 xfrout_log1(ns_client_t *client, dns_name_t *zonename,
1847 dns_rdataclass_t rdclass, int level, const char *fmt, ...) {
1850 xfrout_logv(client, zonename, rdclass, level, fmt, ap);
1855 * Logging function for use when there is a xfrout_ctx_t.
1858 xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) {
1861 xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap);