4 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: xfrout.c,v 1.136 2009/06/30 02:52:32 each Exp */
24 #include <isc/formatcheck.h>
26 #include <isc/timer.h>
27 #include <isc/print.h>
28 #include <isc/stats.h>
32 #include <dns/dbiterator.h>
36 #include <dns/fixedname.h>
37 #include <dns/journal.h>
38 #include <dns/message.h>
40 #include <dns/rdataclass.h>
41 #include <dns/rdatalist.h>
42 #include <dns/rdataset.h>
43 #include <dns/rdatasetiter.h>
44 #include <dns/result.h>
45 #include <dns/rriterator.h>
47 #include <dns/stats.h>
48 #include <dns/timer.h>
54 #include <named/client.h>
55 #include <named/log.h>
56 #include <named/server.h>
57 #include <named/xfrout.h>
61 * Outgoing AXFR and IXFR.
69 #define XFROUT_COMMON_LOGARGS \
70 ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT
72 #define XFROUT_PROTOCOL_LOGARGS \
73 XFROUT_COMMON_LOGARGS, ISC_LOG_INFO
75 #define XFROUT_DEBUG_LOGARGS(n) \
76 XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n)
78 #define XFROUT_RR_LOGARGS \
79 XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL
81 #define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8)
84 * Fail unconditionally and log as a client error.
85 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
86 * from complaining about "end-of-loop code not reached".
88 #define FAILC(code, msg) \
91 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
92 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
93 "bad zone transfer request: %s (%s)", \
94 msg, isc_result_totext(code)); \
95 if (result != ISC_R_SUCCESS) goto failure; \
98 #define FAILQ(code, msg, question, rdclass) \
100 char _buf1[DNS_NAME_FORMATSIZE]; \
101 char _buf2[DNS_RDATACLASS_FORMATSIZE]; \
103 dns_name_format(question, _buf1, sizeof(_buf1)); \
104 dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \
105 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
106 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
107 "bad zone transfer request: '%s/%s': %s (%s)", \
108 _buf1, _buf2, msg, isc_result_totext(code)); \
109 if (result != ISC_R_SUCCESS) goto failure; \
113 do { result = (op); \
114 if (result != ISC_R_SUCCESS) goto failure; \
117 /**************************************************************************/
120 inc_stats(dns_zone_t
*zone
, isc_statscounter_t counter
) {
121 isc_stats_increment(ns_g_server
->nsstats
, counter
);
123 isc_stats_t
*zonestats
= dns_zone_getrequeststats(zone
);
124 if (zonestats
!= NULL
)
125 isc_stats_increment(zonestats
, counter
);
129 /**************************************************************************/
131 /*% Log an RR (for debugging) */
134 log_rr(dns_name_t
*name
, dns_rdata_t
*rdata
, isc_uint32_t ttl
) {
140 dns_rdata_t rd
= DNS_RDATA_INIT
;
142 rdl
.type
= rdata
->type
;
143 rdl
.rdclass
= rdata
->rdclass
;
145 if (rdata
->type
== dns_rdatatype_sig
||
146 rdata
->type
== dns_rdatatype_rrsig
)
147 rdl
.covers
= dns_rdata_covers(rdata
);
149 rdl
.covers
= dns_rdatatype_none
;
150 ISC_LIST_INIT(rdl
.rdata
);
151 ISC_LINK_INIT(&rdl
, link
);
152 dns_rdataset_init(&rds
);
154 dns_rdata_clone(rdata
, &rd
);
155 ISC_LIST_APPEND(rdl
.rdata
, &rd
, link
);
156 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl
, &rds
) == ISC_R_SUCCESS
);
158 isc_buffer_init(&buf
, mem
, sizeof(mem
));
159 result
= dns_rdataset_totext(&rds
, name
,
160 ISC_FALSE
, ISC_FALSE
, &buf
);
163 * We could use xfrout_log(), but that would produce
164 * very long lines with a repetitive prefix.
166 if (result
== ISC_R_SUCCESS
) {
168 * Get rid of final newline.
170 INSIST(buf
.used
>= 1 &&
171 ((char *) buf
.base
)[buf
.used
- 1] == '\n');
174 isc_log_write(XFROUT_RR_LOGARGS
, "%.*s",
175 (int)isc_buffer_usedlength(&buf
),
176 (char *)isc_buffer_base(&buf
));
178 isc_log_write(XFROUT_RR_LOGARGS
, "<RR too large to print>");
182 /**************************************************************************/
184 * An 'rrstream_t' is a polymorphic iterator that returns
185 * a stream of resource records. There are multiple implementations,
186 * e.g. for generating AXFR and IXFR records streams.
189 typedef struct rrstream_methods rrstream_methods_t
;
191 typedef struct rrstream
{
193 rrstream_methods_t
*methods
;
196 struct rrstream_methods
{
197 isc_result_t (*first
)(rrstream_t
*);
198 isc_result_t (*next
)(rrstream_t
*);
199 void (*current
)(rrstream_t
*,
203 void (*pause
)(rrstream_t
*);
204 void (*destroy
)(rrstream_t
**);
208 rrstream_noop_pause(rrstream_t
*rs
) {
212 /**************************************************************************/
214 * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
215 * an IXFR-like RR stream from a journal file.
217 * The SOA at the beginning of each sequence of additions
218 * or deletions are included in the stream, but the extra
219 * SOAs at the beginning and end of the entire transfer are
223 typedef struct ixfr_rrstream
{
225 dns_journal_t
*journal
;
228 /* Forward declarations. */
230 ixfr_rrstream_destroy(rrstream_t
**sp
);
232 static rrstream_methods_t ixfr_rrstream_methods
;
235 * Returns: anything dns_journal_open() or dns_journal_iter_init()
240 ixfr_rrstream_create(isc_mem_t
*mctx
,
241 const char *journal_filename
,
242 isc_uint32_t begin_serial
,
243 isc_uint32_t end_serial
,
249 INSIST(sp
!= NULL
&& *sp
== NULL
);
251 s
= isc_mem_get(mctx
, sizeof(*s
));
253 return (ISC_R_NOMEMORY
);
254 s
->common
.mctx
= mctx
;
255 s
->common
.methods
= &ixfr_rrstream_methods
;
258 CHECK(dns_journal_open(mctx
, journal_filename
,
259 ISC_FALSE
, &s
->journal
));
260 CHECK(dns_journal_iter_init(s
->journal
, begin_serial
, end_serial
));
262 *sp
= (rrstream_t
*) s
;
263 return (ISC_R_SUCCESS
);
266 ixfr_rrstream_destroy((rrstream_t
**) (void *)&s
);
271 ixfr_rrstream_first(rrstream_t
*rs
) {
272 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) rs
;
273 return (dns_journal_first_rr(s
->journal
));
277 ixfr_rrstream_next(rrstream_t
*rs
) {
278 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) rs
;
279 return (dns_journal_next_rr(s
->journal
));
283 ixfr_rrstream_current(rrstream_t
*rs
,
284 dns_name_t
**name
, isc_uint32_t
*ttl
,
287 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) rs
;
288 dns_journal_current_rr(s
->journal
, name
, ttl
, rdata
);
292 ixfr_rrstream_destroy(rrstream_t
**rsp
) {
293 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) *rsp
;
295 dns_journal_destroy(&s
->journal
);
296 isc_mem_put(s
->common
.mctx
, s
, sizeof(*s
));
299 static rrstream_methods_t ixfr_rrstream_methods
= {
302 ixfr_rrstream_current
,
304 ixfr_rrstream_destroy
307 /**************************************************************************/
309 * An 'axfr_rrstream_t' is an 'rrstream_t' that returns
310 * an AXFR-like RR stream from a database.
312 * The SOAs at the beginning and end of the transfer are
313 * not included in the stream.
316 typedef struct axfr_rrstream
{
319 isc_boolean_t it_valid
;
323 * Forward declarations.
326 axfr_rrstream_destroy(rrstream_t
**rsp
);
328 static rrstream_methods_t axfr_rrstream_methods
;
331 axfr_rrstream_create(isc_mem_t
*mctx
, dns_db_t
*db
, dns_dbversion_t
*ver
,
337 INSIST(sp
!= NULL
&& *sp
== NULL
);
339 s
= isc_mem_get(mctx
, sizeof(*s
));
341 return (ISC_R_NOMEMORY
);
342 s
->common
.mctx
= mctx
;
343 s
->common
.methods
= &axfr_rrstream_methods
;
344 s
->it_valid
= ISC_FALSE
;
346 CHECK(dns_rriterator_init(&s
->it
, db
, ver
, 0));
347 s
->it_valid
= ISC_TRUE
;
349 *sp
= (rrstream_t
*) s
;
350 return (ISC_R_SUCCESS
);
353 axfr_rrstream_destroy((rrstream_t
**) (void *)&s
);
358 axfr_rrstream_first(rrstream_t
*rs
) {
359 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
361 result
= dns_rriterator_first(&s
->it
);
362 if (result
!= ISC_R_SUCCESS
)
364 /* Skip SOA records. */
366 dns_name_t
*name_dummy
= NULL
;
367 isc_uint32_t ttl_dummy
;
368 dns_rdata_t
*rdata
= NULL
;
369 dns_rriterator_current(&s
->it
, &name_dummy
,
370 &ttl_dummy
, NULL
, &rdata
);
371 if (rdata
->type
!= dns_rdatatype_soa
)
373 result
= dns_rriterator_next(&s
->it
);
374 if (result
!= ISC_R_SUCCESS
)
381 axfr_rrstream_next(rrstream_t
*rs
) {
382 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
385 /* Skip SOA records. */
387 dns_name_t
*name_dummy
= NULL
;
388 isc_uint32_t ttl_dummy
;
389 dns_rdata_t
*rdata
= NULL
;
390 result
= dns_rriterator_next(&s
->it
);
391 if (result
!= ISC_R_SUCCESS
)
393 dns_rriterator_current(&s
->it
, &name_dummy
,
394 &ttl_dummy
, NULL
, &rdata
);
395 if (rdata
->type
!= dns_rdatatype_soa
)
402 axfr_rrstream_current(rrstream_t
*rs
, dns_name_t
**name
, isc_uint32_t
*ttl
,
405 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
406 dns_rriterator_current(&s
->it
, name
, ttl
, NULL
, rdata
);
410 axfr_rrstream_pause(rrstream_t
*rs
) {
411 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
412 dns_rriterator_pause(&s
->it
);
416 axfr_rrstream_destroy(rrstream_t
**rsp
) {
417 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) *rsp
;
419 dns_rriterator_destroy(&s
->it
);
420 isc_mem_put(s
->common
.mctx
, s
, sizeof(*s
));
423 static rrstream_methods_t axfr_rrstream_methods
= {
426 axfr_rrstream_current
,
428 axfr_rrstream_destroy
431 /**************************************************************************/
433 * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns
434 * a single SOA record.
437 typedef struct soa_rrstream
{
439 dns_difftuple_t
*soa_tuple
;
443 * Forward declarations.
446 soa_rrstream_destroy(rrstream_t
**rsp
);
448 static rrstream_methods_t soa_rrstream_methods
;
451 soa_rrstream_create(isc_mem_t
*mctx
, dns_db_t
*db
, dns_dbversion_t
*ver
,
457 INSIST(sp
!= NULL
&& *sp
== NULL
);
459 s
= isc_mem_get(mctx
, sizeof(*s
));
461 return (ISC_R_NOMEMORY
);
462 s
->common
.mctx
= mctx
;
463 s
->common
.methods
= &soa_rrstream_methods
;
466 CHECK(dns_db_createsoatuple(db
, ver
, mctx
, DNS_DIFFOP_EXISTS
,
469 *sp
= (rrstream_t
*) s
;
470 return (ISC_R_SUCCESS
);
473 soa_rrstream_destroy((rrstream_t
**) (void *)&s
);
478 soa_rrstream_first(rrstream_t
*rs
) {
480 return (ISC_R_SUCCESS
);
484 soa_rrstream_next(rrstream_t
*rs
) {
486 return (ISC_R_NOMORE
);
490 soa_rrstream_current(rrstream_t
*rs
, dns_name_t
**name
, isc_uint32_t
*ttl
,
493 soa_rrstream_t
*s
= (soa_rrstream_t
*) rs
;
494 *name
= &s
->soa_tuple
->name
;
495 *ttl
= s
->soa_tuple
->ttl
;
496 *rdata
= &s
->soa_tuple
->rdata
;
500 soa_rrstream_destroy(rrstream_t
**rsp
) {
501 soa_rrstream_t
*s
= (soa_rrstream_t
*) *rsp
;
502 if (s
->soa_tuple
!= NULL
)
503 dns_difftuple_free(&s
->soa_tuple
);
504 isc_mem_put(s
->common
.mctx
, s
, sizeof(*s
));
507 static rrstream_methods_t soa_rrstream_methods
= {
510 soa_rrstream_current
,
515 /**************************************************************************/
517 * A 'compound_rrstream_t' objects owns a soa_rrstream
518 * and another rrstream, the "data stream". It returns
519 * a concatenated stream consisting of the soa_rrstream, then
520 * the data stream, then the soa_rrstream again.
522 * The component streams are owned by the compound_rrstream_t
523 * and are destroyed with it.
526 typedef struct compound_rrstream
{
528 rrstream_t
*components
[3];
531 } compound_rrstream_t
;
534 * Forward declarations.
537 compound_rrstream_destroy(rrstream_t
**rsp
);
540 compound_rrstream_next(rrstream_t
*rs
);
542 static rrstream_methods_t compound_rrstream_methods
;
546 * soa_stream != NULL && *soa_stream != NULL
547 * data_stream != NULL && *data_stream != NULL
548 * sp != NULL && *sp == NULL
551 * *soa_stream == NULL
552 * *data_stream == NULL
553 * *sp points to a valid compound_rrstream_t
554 * The soa and data streams will be destroyed
555 * when the compound_rrstream_t is destroyed.
558 compound_rrstream_create(isc_mem_t
*mctx
, rrstream_t
**soa_stream
,
559 rrstream_t
**data_stream
, rrstream_t
**sp
)
561 compound_rrstream_t
*s
;
563 INSIST(sp
!= NULL
&& *sp
== NULL
);
565 s
= isc_mem_get(mctx
, sizeof(*s
));
567 return (ISC_R_NOMEMORY
);
568 s
->common
.mctx
= mctx
;
569 s
->common
.methods
= &compound_rrstream_methods
;
570 s
->components
[0] = *soa_stream
;
571 s
->components
[1] = *data_stream
;
572 s
->components
[2] = *soa_stream
;
574 s
->result
= ISC_R_FAILURE
;
578 *sp
= (rrstream_t
*) s
;
579 return (ISC_R_SUCCESS
);
583 compound_rrstream_first(rrstream_t
*rs
) {
584 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
587 rrstream_t
*curstream
= s
->components
[s
->state
];
588 s
->result
= curstream
->methods
->first(curstream
);
589 } while (s
->result
== ISC_R_NOMORE
&& s
->state
< 2);
594 compound_rrstream_next(rrstream_t
*rs
) {
595 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
596 rrstream_t
*curstream
= s
->components
[s
->state
];
597 s
->result
= curstream
->methods
->next(curstream
);
598 while (s
->result
== ISC_R_NOMORE
) {
600 * Make sure locks held by the current stream
601 * are released before we switch streams.
603 curstream
->methods
->pause(curstream
);
605 return (ISC_R_NOMORE
);
607 curstream
= s
->components
[s
->state
];
608 s
->result
= curstream
->methods
->first(curstream
);
614 compound_rrstream_current(rrstream_t
*rs
, dns_name_t
**name
, isc_uint32_t
*ttl
,
617 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
618 rrstream_t
*curstream
;
619 INSIST(0 <= s
->state
&& s
->state
< 3);
620 INSIST(s
->result
== ISC_R_SUCCESS
);
621 curstream
= s
->components
[s
->state
];
622 curstream
->methods
->current(curstream
, name
, ttl
, rdata
);
626 compound_rrstream_pause(rrstream_t
*rs
)
628 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
629 rrstream_t
*curstream
;
630 INSIST(0 <= s
->state
&& s
->state
< 3);
631 curstream
= s
->components
[s
->state
];
632 curstream
->methods
->pause(curstream
);
636 compound_rrstream_destroy(rrstream_t
**rsp
) {
637 compound_rrstream_t
*s
= (compound_rrstream_t
*) *rsp
;
638 s
->components
[0]->methods
->destroy(&s
->components
[0]);
639 s
->components
[1]->methods
->destroy(&s
->components
[1]);
640 s
->components
[2] = NULL
; /* Copy of components[0]. */
641 isc_mem_put(s
->common
.mctx
, s
, sizeof(*s
));
644 static rrstream_methods_t compound_rrstream_methods
= {
645 compound_rrstream_first
,
646 compound_rrstream_next
,
647 compound_rrstream_current
,
648 compound_rrstream_pause
,
649 compound_rrstream_destroy
652 /**************************************************************************/
654 * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR
661 unsigned int id
; /* ID of request */
662 dns_name_t
*qname
; /* Question name of request */
663 dns_rdatatype_t qtype
; /* dns_rdatatype_{a,i}xfr */
664 dns_rdataclass_t qclass
;
665 dns_zone_t
*zone
; /* (necessary for stats) */
667 dns_dbversion_t
*ver
;
669 rrstream_t
*stream
; /* The XFR RR stream */
670 isc_boolean_t end_of_stream
; /* EOS has been reached */
671 isc_buffer_t buf
; /* Buffer for message owner
673 isc_buffer_t txlenbuf
; /* Transmit length buffer */
674 isc_buffer_t txbuf
; /* Transmit message buffer */
676 unsigned int txmemlen
;
677 unsigned int nmsg
; /* Number of messages sent */
678 dns_tsigkey_t
*tsigkey
; /* Key used to create TSIG */
679 isc_buffer_t
*lasttsig
; /* the last TSIG */
680 isc_boolean_t many_answers
;
681 int sends
; /* Send in progress */
682 isc_boolean_t shuttingdown
;
683 const char *mnemonic
; /* Style of transfer */
687 xfrout_ctx_create(isc_mem_t
*mctx
, ns_client_t
*client
,
688 unsigned int id
, dns_name_t
*qname
, dns_rdatatype_t qtype
,
689 dns_rdataclass_t qclass
, dns_zone_t
*zone
,
690 dns_db_t
*db
, dns_dbversion_t
*ver
, isc_quota_t
*quota
,
691 rrstream_t
*stream
, dns_tsigkey_t
*tsigkey
,
692 isc_buffer_t
*lasttsig
,
693 unsigned int maxtime
,
694 unsigned int idletime
,
695 isc_boolean_t many_answers
,
696 xfrout_ctx_t
**xfrp
);
699 sendstream(xfrout_ctx_t
*xfr
);
702 xfrout_senddone(isc_task_t
*task
, isc_event_t
*event
);
705 xfrout_fail(xfrout_ctx_t
*xfr
, isc_result_t result
, const char *msg
);
708 xfrout_maybe_destroy(xfrout_ctx_t
*xfr
);
711 xfrout_ctx_destroy(xfrout_ctx_t
**xfrp
);
714 xfrout_client_shutdown(void *arg
, isc_result_t result
);
717 xfrout_log1(ns_client_t
*client
, dns_name_t
*zonename
,
718 dns_rdataclass_t rdclass
, int level
,
719 const char *fmt
, ...) ISC_FORMAT_PRINTF(5, 6);
722 xfrout_log(xfrout_ctx_t
*xfr
, int level
, const char *fmt
, ...)
723 ISC_FORMAT_PRINTF(3, 4);
725 /**************************************************************************/
728 ns_xfr_start(ns_client_t
*client
, dns_rdatatype_t reqtype
) {
730 dns_name_t
*question_name
;
731 dns_rdataset_t
*question_rdataset
;
732 dns_zone_t
*zone
= NULL
;
734 dns_dbversion_t
*ver
= NULL
;
735 dns_rdataclass_t question_class
;
736 rrstream_t
*soa_stream
= NULL
;
737 rrstream_t
*data_stream
= NULL
;
738 rrstream_t
*stream
= NULL
;
739 dns_difftuple_t
*current_soa_tuple
= NULL
;
740 dns_name_t
*soa_name
;
741 dns_rdataset_t
*soa_rdataset
;
742 dns_rdata_t soa_rdata
= DNS_RDATA_INIT
;
743 isc_boolean_t have_soa
= ISC_FALSE
;
744 const char *mnemonic
= NULL
;
745 isc_mem_t
*mctx
= client
->mctx
;
746 dns_message_t
*request
= client
->message
;
747 xfrout_ctx_t
*xfr
= NULL
;
748 isc_quota_t
*quota
= NULL
;
749 dns_transfer_format_t format
= client
->view
->transfer_format
;
751 dns_peer_t
*peer
= NULL
;
752 isc_buffer_t
*tsigbuf
= NULL
;
754 char msg
[NS_CLIENT_ACLMSGSIZE("zone transfer")];
755 char keyname
[DNS_NAME_FORMATSIZE
];
756 isc_boolean_t is_poll
= ISC_FALSE
;
758 isc_boolean_t is_dlz
= ISC_FALSE
;
762 case dns_rdatatype_axfr
:
765 case dns_rdatatype_ixfr
:
773 ns_client_log(client
,
774 DNS_LOGCATEGORY_XFER_OUT
, NS_LOGMODULE_XFER_OUT
,
775 ISC_LOG_DEBUG(6), "%s request", mnemonic
);
779 result
= isc_quota_attach(&ns_g_server
->xfroutquota
, "a
);
780 if (result
!= ISC_R_SUCCESS
) {
781 isc_log_write(XFROUT_COMMON_LOGARGS
, ISC_LOG_WARNING
,
782 "%s request denied: %s", mnemonic
,
783 isc_result_totext(result
));
788 * Interpret the question section.
790 result
= dns_message_firstname(request
, DNS_SECTION_QUESTION
);
791 INSIST(result
== ISC_R_SUCCESS
);
794 * The question section must contain exactly one question, and
795 * it must be for AXFR/IXFR as appropriate.
797 question_name
= NULL
;
798 dns_message_currentname(request
, DNS_SECTION_QUESTION
, &question_name
);
799 question_rdataset
= ISC_LIST_HEAD(question_name
->list
);
800 question_class
= question_rdataset
->rdclass
;
801 INSIST(question_rdataset
->type
== reqtype
);
802 if (ISC_LIST_NEXT(question_rdataset
, link
) != NULL
)
803 FAILC(DNS_R_FORMERR
, "multiple questions");
804 result
= dns_message_nextname(request
, DNS_SECTION_QUESTION
);
805 if (result
!= ISC_R_NOMORE
)
806 FAILC(DNS_R_FORMERR
, "multiple questions");
808 result
= dns_zt_find(client
->view
->zonetable
, question_name
, 0, NULL
,
811 if (result
!= ISC_R_SUCCESS
)
815 * Normal zone table does not have a match. Try the DLZ database
817 if (client
->view
->dlzdatabase
!= NULL
) {
818 result
= dns_dlzallowzonexfr(client
->view
,
819 question_name
, &client
->peeraddr
,
822 if (result
== ISC_R_NOPERM
) {
823 char _buf1
[DNS_NAME_FORMATSIZE
];
824 char _buf2
[DNS_RDATACLASS_FORMATSIZE
];
826 result
= DNS_R_REFUSED
;
827 dns_name_format(question_name
, _buf1
,
829 dns_rdataclass_format(question_class
,
830 _buf2
, sizeof(_buf2
));
831 ns_client_log(client
, DNS_LOGCATEGORY_SECURITY
,
832 NS_LOGMODULE_XFER_OUT
,
834 "zone transfer '%s/%s' denied",
838 if (result
!= ISC_R_SUCCESS
)
840 FAILQ(DNS_R_NOTAUTH
, "non-authoritative zone",
841 question_name
, question_class
);
845 * DLZ only support full zone transfer, not incremental
847 if (reqtype
!= dns_rdatatype_axfr
) {
848 mnemonic
= "AXFR-style IXFR";
849 reqtype
= dns_rdatatype_axfr
;
854 * not DLZ and not in normal zone table, we are
857 FAILQ(DNS_R_NOTAUTH
, "non-authoritative zone",
858 question_name
, question_class
);
861 /* zone table has a match */
863 switch(dns_zone_gettype(zone
)) {
864 case dns_zone_master
:
866 break; /* Master and slave zones are OK for transfer. */
868 FAILQ(DNS_R_NOTAUTH
, "non-authoritative zone", question_name
, question_class
);
870 CHECK(dns_zone_getdb(zone
, &db
));
871 dns_db_currentversion(db
, &ver
);
876 xfrout_log1(client
, question_name
, question_class
, ISC_LOG_DEBUG(6),
877 "%s question section OK", mnemonic
);
880 * Check the authority section. Look for a SOA record with
881 * the same name and class as the question.
883 for (result
= dns_message_firstname(request
, DNS_SECTION_AUTHORITY
);
884 result
== ISC_R_SUCCESS
;
885 result
= dns_message_nextname(request
, DNS_SECTION_AUTHORITY
))
888 dns_message_currentname(request
, DNS_SECTION_AUTHORITY
,
892 * Ignore data whose owner name is not the zone apex.
894 if (! dns_name_equal(soa_name
, question_name
))
897 for (soa_rdataset
= ISC_LIST_HEAD(soa_name
->list
);
898 soa_rdataset
!= NULL
;
899 soa_rdataset
= ISC_LIST_NEXT(soa_rdataset
, link
))
902 * Ignore non-SOA data.
904 if (soa_rdataset
->type
!= dns_rdatatype_soa
)
906 if (soa_rdataset
->rdclass
!= question_class
)
909 CHECK(dns_rdataset_first(soa_rdataset
));
910 dns_rdataset_current(soa_rdataset
, &soa_rdata
);
911 result
= dns_rdataset_next(soa_rdataset
);
912 if (result
== ISC_R_SUCCESS
)
914 "IXFR authority section "
915 "has multiple SOAs");
921 if (result
!= ISC_R_NOMORE
)
924 xfrout_log1(client
, question_name
, question_class
, ISC_LOG_DEBUG(6),
925 "%s authority section OK", mnemonic
);
928 * Decide whether to allow this transfer.
932 * if not a DLZ zone decide whether to allow this transfer.
936 ns_client_aclmsg("zone transfer", question_name
, reqtype
,
937 client
->view
->rdclass
, msg
, sizeof(msg
));
938 CHECK(ns_client_checkacl(client
, NULL
, msg
,
939 dns_zone_getxfracl(zone
),
940 ISC_TRUE
, ISC_LOG_ERROR
));
946 * AXFR over UDP is not possible.
948 if (reqtype
== dns_rdatatype_axfr
&&
949 (client
->attributes
& NS_CLIENTATTR_TCP
) == 0)
950 FAILC(DNS_R_FORMERR
, "attempted AXFR over UDP");
953 * Look up the requesting server in the peer table.
955 isc_netaddr_fromsockaddr(&na
, &client
->peeraddr
);
956 (void)dns_peerlist_peerbyaddr(client
->view
->peers
, &na
, &peer
);
959 * Decide on the transfer format (one-answer or many-answers).
962 (void)dns_peer_gettransferformat(peer
, &format
);
965 * Get a dynamically allocated copy of the current SOA.
969 dns_db_currentversion(db
, &ver
);
971 CHECK(dns_db_createsoatuple(db
, ver
, mctx
, DNS_DIFFOP_EXISTS
,
972 ¤t_soa_tuple
));
974 if (reqtype
== dns_rdatatype_ixfr
) {
975 isc_uint32_t begin_serial
, current_serial
;
976 isc_boolean_t provide_ixfr
;
979 * Outgoing IXFR may have been disabled for this peer
982 provide_ixfr
= client
->view
->provideixfr
;
984 (void) dns_peer_getprovideixfr(peer
, &provide_ixfr
);
985 if (provide_ixfr
== ISC_FALSE
)
990 "IXFR request missing SOA");
992 begin_serial
= dns_soa_getserial(&soa_rdata
);
993 current_serial
= dns_soa_getserial(¤t_soa_tuple
->rdata
);
996 * RFC1995 says "If an IXFR query with the same or
997 * newer version number than that of the server
998 * is received, it is replied to with a single SOA
999 * record of the server's current version, just as
1000 * in AXFR". The claim about AXFR is incorrect,
1001 * but other than that, we do as the RFC says.
1003 * Sending a single SOA record is also how we refuse
1004 * IXFR over UDP (currently, we always do).
1006 if (DNS_SERIAL_GE(begin_serial
, current_serial
) ||
1007 (client
->attributes
& NS_CLIENTATTR_TCP
) == 0)
1009 CHECK(soa_rrstream_create(mctx
, db
, ver
, &stream
));
1013 journalfile
= dns_zone_getjournal(zone
);
1014 if (journalfile
!= NULL
)
1015 result
= ixfr_rrstream_create(mctx
,
1021 result
= ISC_R_NOTFOUND
;
1022 if (result
== ISC_R_NOTFOUND
||
1023 result
== ISC_R_RANGE
) {
1024 xfrout_log1(client
, question_name
, question_class
,
1026 "IXFR version not in journal, "
1027 "falling back to AXFR");
1028 mnemonic
= "AXFR-style IXFR";
1034 CHECK(axfr_rrstream_create(mctx
, db
, ver
,
1039 * Bracket the data stream with SOAs.
1041 CHECK(soa_rrstream_create(mctx
, db
, ver
, &soa_stream
));
1042 CHECK(compound_rrstream_create(mctx
, &soa_stream
, &data_stream
,
1048 CHECK(dns_message_getquerytsig(request
, mctx
, &tsigbuf
));
1050 * Create the xfrout context object. This transfers the ownership
1051 * of "stream", "db", "ver", and "quota" to the xfrout context object.
1058 CHECK(xfrout_ctx_create(mctx
, client
, request
->id
, question_name
,
1059 reqtype
, question_class
, zone
, db
, ver
,
1061 dns_message_gettsigkey(request
),
1065 (format
== dns_many_answers
) ?
1066 ISC_TRUE
: ISC_FALSE
,
1070 CHECK(xfrout_ctx_create(mctx
, client
, request
->id
, question_name
,
1071 reqtype
, question_class
, zone
, db
, ver
,
1073 dns_message_gettsigkey(request
),
1075 dns_zone_getmaxxfrout(zone
),
1076 dns_zone_getidleout(zone
),
1077 (format
== dns_many_answers
) ?
1078 ISC_TRUE
: ISC_FALSE
,
1081 xfr
->mnemonic
= mnemonic
;
1085 CHECK(xfr
->stream
->methods
->first(xfr
->stream
));
1087 if (xfr
->tsigkey
!= NULL
) {
1088 dns_name_format(&xfr
->tsigkey
->name
, keyname
, sizeof(keyname
));
1092 xfrout_log1(client
, question_name
, question_class
,
1093 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s",
1094 (xfr
->tsigkey
!= NULL
) ? ": TSIG " : "", keyname
);
1096 xfrout_log1(client
, question_name
, question_class
,
1097 ISC_LOG_INFO
, "%s started%s%s", mnemonic
,
1098 (xfr
->tsigkey
!= NULL
) ? ": TSIG " : "", keyname
);
1101 * Hand the context over to sendstream(). Set xfr to NULL;
1102 * sendstream() is responsible for either passing the
1103 * context on to a later event handler or destroying it.
1108 result
= ISC_R_SUCCESS
;
1111 if (result
== DNS_R_REFUSED
)
1112 inc_stats(zone
, dns_nsstatscounter_xfrrej
);
1114 isc_quota_detach("a
);
1115 if (current_soa_tuple
!= NULL
)
1116 dns_difftuple_free(¤t_soa_tuple
);
1118 stream
->methods
->destroy(&stream
);
1119 if (soa_stream
!= NULL
)
1120 soa_stream
->methods
->destroy(&soa_stream
);
1121 if (data_stream
!= NULL
)
1122 data_stream
->methods
->destroy(&data_stream
);
1124 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
1128 dns_zone_detach(&zone
);
1131 xfrout_fail(xfr
, result
, "setting up zone transfer");
1132 } else if (result
!= ISC_R_SUCCESS
) {
1133 ns_client_log(client
, DNS_LOGCATEGORY_XFER_OUT
,
1134 NS_LOGMODULE_XFER_OUT
,
1135 ISC_LOG_DEBUG(3), "zone transfer setup failed");
1136 ns_client_error(client
, result
);
1141 xfrout_ctx_create(isc_mem_t
*mctx
, ns_client_t
*client
, unsigned int id
,
1142 dns_name_t
*qname
, dns_rdatatype_t qtype
,
1143 dns_rdataclass_t qclass
, dns_zone_t
*zone
,
1144 dns_db_t
*db
, dns_dbversion_t
*ver
, isc_quota_t
*quota
,
1145 rrstream_t
*stream
, dns_tsigkey_t
*tsigkey
,
1146 isc_buffer_t
*lasttsig
, unsigned int maxtime
,
1147 unsigned int idletime
, isc_boolean_t many_answers
,
1148 xfrout_ctx_t
**xfrp
)
1151 isc_result_t result
;
1155 INSIST(xfrp
!= NULL
&& *xfrp
== NULL
);
1156 xfr
= isc_mem_get(mctx
, sizeof(*xfr
));
1158 return (ISC_R_NOMEMORY
);
1161 ns_client_attach(client
, &xfr
->client
);
1165 xfr
->qclass
= qclass
;
1169 if (zone
!= NULL
) /* zone will be NULL if it's DLZ */
1170 dns_zone_attach(zone
, &xfr
->zone
);
1171 dns_db_attach(db
, &xfr
->db
);
1172 dns_db_attachversion(db
, ver
, &xfr
->ver
);
1173 xfr
->end_of_stream
= ISC_FALSE
;
1174 xfr
->tsigkey
= tsigkey
;
1175 xfr
->lasttsig
= lasttsig
;
1179 xfr
->many_answers
= many_answers
,
1181 xfr
->shuttingdown
= ISC_FALSE
;
1182 xfr
->mnemonic
= NULL
;
1183 xfr
->buf
.base
= NULL
;
1184 xfr
->buf
.length
= 0;
1191 * Allocate a temporary buffer for the uncompressed response
1192 * message data. The size should be no more than 65535 bytes
1193 * so that the compressed data will fit in a TCP message,
1194 * and no less than 65535 bytes so that an almost maximum-sized
1195 * RR will fit. Note that although 65535-byte RRs are allowed
1196 * in principle, they cannot be zone-transferred (at least not
1197 * if uncompressible), because the message and RR headers would
1198 * push the size of the TCP message over the 65536 byte limit.
1201 mem
= isc_mem_get(mctx
, len
);
1203 result
= ISC_R_NOMEMORY
;
1206 isc_buffer_init(&xfr
->buf
, mem
, len
);
1209 * Allocate another temporary buffer for the compressed
1210 * response message and its TCP length prefix.
1213 mem
= isc_mem_get(mctx
, len
);
1215 result
= ISC_R_NOMEMORY
;
1218 isc_buffer_init(&xfr
->txlenbuf
, mem
, 2);
1219 isc_buffer_init(&xfr
->txbuf
, (char *) mem
+ 2, len
- 2);
1221 xfr
->txmemlen
= len
;
1223 CHECK(dns_timer_setidle(xfr
->client
->timer
,
1224 maxtime
, idletime
, ISC_FALSE
));
1227 * Register a shutdown callback with the client, so that we
1228 * can stop the transfer immediately when the client task
1229 * gets a shutdown event.
1231 xfr
->client
->shutdown
= xfrout_client_shutdown
;
1232 xfr
->client
->shutdown_arg
= xfr
;
1234 * These MUST be after the last "goto failure;" / CHECK to
1235 * prevent a double free by the caller.
1238 xfr
->stream
= stream
;
1241 return (ISC_R_SUCCESS
);
1244 xfrout_ctx_destroy(&xfr
);
1250 * Arrange to send as much as we can of "stream" without blocking.
1253 * The stream iterator is initialized and points at an RR,
1254 * or possibly at the end of the stream (that is, the
1255 * _first method of the iterator has been called).
1258 sendstream(xfrout_ctx_t
*xfr
) {
1259 dns_message_t
*tcpmsg
= NULL
;
1260 dns_message_t
*msg
= NULL
; /* Client message if UDP, tcpmsg if TCP */
1261 isc_result_t result
;
1263 isc_region_t region
;
1264 dns_rdataset_t
*qrdataset
;
1265 dns_name_t
*msgname
= NULL
;
1266 dns_rdata_t
*msgrdata
= NULL
;
1267 dns_rdatalist_t
*msgrdl
= NULL
;
1268 dns_rdataset_t
*msgrds
= NULL
;
1269 dns_compress_t cctx
;
1270 isc_boolean_t cleanup_cctx
= ISC_FALSE
;
1274 isc_buffer_clear(&xfr
->buf
);
1275 isc_buffer_clear(&xfr
->txlenbuf
);
1276 isc_buffer_clear(&xfr
->txbuf
);
1278 if ((xfr
->client
->attributes
& NS_CLIENTATTR_TCP
) == 0) {
1280 * In the UDP case, we put the response data directly into
1281 * the client message.
1283 msg
= xfr
->client
->message
;
1284 CHECK(dns_message_reply(msg
, ISC_TRUE
));
1287 * TCP. Build a response dns_message_t, temporarily storing
1288 * the raw, uncompressed owner names and RR data contiguously
1289 * in xfr->buf. We know that if the uncompressed data fits
1290 * in xfr->buf, the compressed data will surely fit in a TCP
1294 CHECK(dns_message_create(xfr
->mctx
,
1295 DNS_MESSAGE_INTENTRENDER
, &tcpmsg
));
1299 msg
->rcode
= dns_rcode_noerror
;
1300 msg
->flags
= DNS_MESSAGEFLAG_QR
| DNS_MESSAGEFLAG_AA
;
1301 if ((xfr
->client
->attributes
& NS_CLIENTATTR_RA
) != 0)
1302 msg
->flags
|= DNS_MESSAGEFLAG_RA
;
1303 CHECK(dns_message_settsigkey(msg
, xfr
->tsigkey
));
1304 CHECK(dns_message_setquerytsig(msg
, xfr
->lasttsig
));
1305 if (xfr
->lasttsig
!= NULL
)
1306 isc_buffer_free(&xfr
->lasttsig
);
1309 * Include a question section in the first message only.
1310 * BIND 8.2.1 will not recognize an IXFR if it does not
1311 * have a question section.
1313 if (xfr
->nmsg
== 0) {
1314 dns_name_t
*qname
= NULL
;
1318 * Reserve space for the 12-byte message header
1319 * and 4 bytes of question.
1321 isc_buffer_add(&xfr
->buf
, 12 + 4);
1324 result
= dns_message_gettemprdataset(msg
, &qrdataset
);
1325 if (result
!= ISC_R_SUCCESS
)
1327 dns_rdataset_init(qrdataset
);
1328 dns_rdataset_makequestion(qrdataset
,
1329 xfr
->client
->message
->rdclass
,
1332 result
= dns_message_gettempname(msg
, &qname
);
1333 if (result
!= ISC_R_SUCCESS
)
1335 dns_name_init(qname
, NULL
);
1336 isc_buffer_availableregion(&xfr
->buf
, &r
);
1337 INSIST(r
.length
>= xfr
->qname
->length
);
1338 r
.length
= xfr
->qname
->length
;
1339 isc_buffer_putmem(&xfr
->buf
, xfr
->qname
->ndata
,
1340 xfr
->qname
->length
);
1341 dns_name_fromregion(qname
, &r
);
1342 ISC_LIST_INIT(qname
->list
);
1343 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
1345 dns_message_addname(msg
, qname
, DNS_SECTION_QUESTION
);
1348 msg
->tcp_continuation
= 1;
1352 * Try to fit in as many RRs as possible, unless "one-answer"
1353 * format has been requested.
1355 for (n_rrs
= 0; ; n_rrs
++) {
1356 dns_name_t
*name
= NULL
;
1358 dns_rdata_t
*rdata
= NULL
;
1368 xfr
->stream
->methods
->current(xfr
->stream
,
1369 &name
, &ttl
, &rdata
);
1370 size
= name
->length
+ 10 + rdata
->length
;
1371 isc_buffer_availableregion(&xfr
->buf
, &r
);
1372 if (size
>= r
.length
) {
1374 * RR would not fit. If there are other RRs in the
1375 * buffer, send them now and leave this RR to the
1376 * next message. If this RR overflows the buffer
1377 * all by itself, fail.
1379 * In theory some RRs might fit in a TCP message
1380 * when compressed even if they do not fit when
1381 * uncompressed, but surely we don't want
1382 * to send such monstrosities to an unsuspecting
1386 xfrout_log(xfr
, ISC_LOG_WARNING
,
1387 "RR too large for zone transfer "
1388 "(%d bytes)", size
);
1389 /* XXX DNS_R_RRTOOLARGE? */
1390 result
= ISC_R_NOSPACE
;
1396 if (isc_log_wouldlog(ns_g_lctx
, XFROUT_RR_LOGLEVEL
))
1397 log_rr(name
, rdata
, ttl
); /* XXX */
1399 result
= dns_message_gettempname(msg
, &msgname
);
1400 if (result
!= ISC_R_SUCCESS
)
1402 dns_name_init(msgname
, NULL
);
1403 isc_buffer_availableregion(&xfr
->buf
, &r
);
1404 INSIST(r
.length
>= name
->length
);
1405 r
.length
= name
->length
;
1406 isc_buffer_putmem(&xfr
->buf
, name
->ndata
, name
->length
);
1407 dns_name_fromregion(msgname
, &r
);
1409 /* Reserve space for RR header. */
1410 isc_buffer_add(&xfr
->buf
, 10);
1412 result
= dns_message_gettemprdata(msg
, &msgrdata
);
1413 if (result
!= ISC_R_SUCCESS
)
1415 isc_buffer_availableregion(&xfr
->buf
, &r
);
1416 r
.length
= rdata
->length
;
1417 isc_buffer_putmem(&xfr
->buf
, rdata
->data
, rdata
->length
);
1418 dns_rdata_init(msgrdata
);
1419 dns_rdata_fromregion(msgrdata
,
1420 rdata
->rdclass
, rdata
->type
, &r
);
1422 result
= dns_message_gettemprdatalist(msg
, &msgrdl
);
1423 if (result
!= ISC_R_SUCCESS
)
1425 msgrdl
->type
= rdata
->type
;
1426 msgrdl
->rdclass
= rdata
->rdclass
;
1428 if (rdata
->type
== dns_rdatatype_sig
||
1429 rdata
->type
== dns_rdatatype_rrsig
)
1430 msgrdl
->covers
= dns_rdata_covers(rdata
);
1432 msgrdl
->covers
= dns_rdatatype_none
;
1433 ISC_LINK_INIT(msgrdl
, link
);
1434 ISC_LIST_INIT(msgrdl
->rdata
);
1435 ISC_LIST_APPEND(msgrdl
->rdata
, msgrdata
, link
);
1437 result
= dns_message_gettemprdataset(msg
, &msgrds
);
1438 if (result
!= ISC_R_SUCCESS
)
1440 dns_rdataset_init(msgrds
);
1441 result
= dns_rdatalist_tordataset(msgrdl
, msgrds
);
1442 INSIST(result
== ISC_R_SUCCESS
);
1444 ISC_LIST_APPEND(msgname
->list
, msgrds
, link
);
1446 dns_message_addname(msg
, msgname
, DNS_SECTION_ANSWER
);
1449 result
= xfr
->stream
->methods
->next(xfr
->stream
);
1450 if (result
== ISC_R_NOMORE
) {
1451 xfr
->end_of_stream
= ISC_TRUE
;
1456 if (! xfr
->many_answers
)
1460 if ((xfr
->client
->attributes
& NS_CLIENTATTR_TCP
) != 0) {
1461 CHECK(dns_compress_init(&cctx
, -1, xfr
->mctx
));
1462 dns_compress_setsensitive(&cctx
, ISC_TRUE
);
1463 cleanup_cctx
= ISC_TRUE
;
1464 CHECK(dns_message_renderbegin(msg
, &cctx
, &xfr
->txbuf
));
1465 CHECK(dns_message_rendersection(msg
, DNS_SECTION_QUESTION
, 0));
1466 CHECK(dns_message_rendersection(msg
, DNS_SECTION_ANSWER
, 0));
1467 CHECK(dns_message_renderend(msg
));
1468 dns_compress_invalidate(&cctx
);
1469 cleanup_cctx
= ISC_FALSE
;
1471 isc_buffer_usedregion(&xfr
->txbuf
, &used
);
1472 isc_buffer_putuint16(&xfr
->txlenbuf
,
1473 (isc_uint16_t
)used
.length
);
1474 region
.base
= xfr
->txlenbuf
.base
;
1475 region
.length
= 2 + used
.length
;
1476 xfrout_log(xfr
, ISC_LOG_DEBUG(8),
1477 "sending TCP message of %d bytes",
1479 CHECK(isc_socket_send(xfr
->client
->tcpsocket
, /* XXX */
1480 ®ion
, xfr
->client
->task
,
1485 xfrout_log(xfr
, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
1486 ns_client_send(xfr
->client
);
1487 xfr
->stream
->methods
->pause(xfr
->stream
);
1488 xfrout_ctx_destroy(&xfr
);
1492 /* Advance lasttsig to be the last TSIG generated */
1493 CHECK(dns_message_getquerytsig(msg
, xfr
->mctx
, &xfr
->lasttsig
));
1498 if (msgname
!= NULL
) {
1499 if (msgrds
!= NULL
) {
1500 if (dns_rdataset_isassociated(msgrds
))
1501 dns_rdataset_disassociate(msgrds
);
1502 dns_message_puttemprdataset(msg
, &msgrds
);
1504 if (msgrdl
!= NULL
) {
1505 ISC_LIST_UNLINK(msgrdl
->rdata
, msgrdata
, link
);
1506 dns_message_puttemprdatalist(msg
, &msgrdl
);
1508 if (msgrdata
!= NULL
)
1509 dns_message_puttemprdata(msg
, &msgrdata
);
1510 dns_message_puttempname(msg
, &msgname
);
1514 dns_message_destroy(&tcpmsg
);
1517 dns_compress_invalidate(&cctx
);
1519 * Make sure to release any locks held by database
1520 * iterators before returning from the event handler.
1522 xfr
->stream
->methods
->pause(xfr
->stream
);
1524 if (result
== ISC_R_SUCCESS
)
1527 xfrout_fail(xfr
, result
, "sending zone data");
1531 xfrout_ctx_destroy(xfrout_ctx_t
**xfrp
) {
1532 xfrout_ctx_t
*xfr
= *xfrp
;
1534 INSIST(xfr
->sends
== 0);
1536 xfr
->client
->shutdown
= NULL
;
1537 xfr
->client
->shutdown_arg
= NULL
;
1539 if (xfr
->stream
!= NULL
)
1540 xfr
->stream
->methods
->destroy(&xfr
->stream
);
1541 if (xfr
->buf
.base
!= NULL
)
1542 isc_mem_put(xfr
->mctx
, xfr
->buf
.base
, xfr
->buf
.length
);
1543 if (xfr
->txmem
!= NULL
)
1544 isc_mem_put(xfr
->mctx
, xfr
->txmem
, xfr
->txmemlen
);
1545 if (xfr
->lasttsig
!= NULL
)
1546 isc_buffer_free(&xfr
->lasttsig
);
1547 if (xfr
->quota
!= NULL
)
1548 isc_quota_detach(&xfr
->quota
);
1549 if (xfr
->ver
!= NULL
)
1550 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_FALSE
);
1551 if (xfr
->zone
!= NULL
)
1552 dns_zone_detach(&xfr
->zone
);
1553 if (xfr
->db
!= NULL
)
1554 dns_db_detach(&xfr
->db
);
1556 ns_client_detach(&xfr
->client
);
1558 isc_mem_put(xfr
->mctx
, xfr
, sizeof(*xfr
));
1564 xfrout_senddone(isc_task_t
*task
, isc_event_t
*event
) {
1565 isc_socketevent_t
*sev
= (isc_socketevent_t
*)event
;
1566 xfrout_ctx_t
*xfr
= (xfrout_ctx_t
*)event
->ev_arg
;
1567 isc_result_t evresult
= sev
->result
;
1571 INSIST(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1573 isc_event_free(&event
);
1575 INSIST(xfr
->sends
== 0);
1577 (void)isc_timer_touch(xfr
->client
->timer
);
1578 if (xfr
->shuttingdown
== ISC_TRUE
) {
1579 xfrout_maybe_destroy(xfr
);
1580 } else if (evresult
!= ISC_R_SUCCESS
) {
1581 xfrout_fail(xfr
, evresult
, "send");
1582 } else if (xfr
->end_of_stream
== ISC_FALSE
) {
1585 /* End of zone transfer stream. */
1586 inc_stats(xfr
->zone
, dns_nsstatscounter_xfrdone
);
1587 xfrout_log(xfr
, ISC_LOG_INFO
, "%s ended", xfr
->mnemonic
);
1588 ns_client_next(xfr
->client
, ISC_R_SUCCESS
);
1589 xfrout_ctx_destroy(&xfr
);
1594 xfrout_fail(xfrout_ctx_t
*xfr
, isc_result_t result
, const char *msg
) {
1595 xfr
->shuttingdown
= ISC_TRUE
;
1596 xfrout_log(xfr
, ISC_LOG_ERROR
, "%s: %s",
1597 msg
, isc_result_totext(result
));
1598 xfrout_maybe_destroy(xfr
);
1602 xfrout_maybe_destroy(xfrout_ctx_t
*xfr
) {
1603 INSIST(xfr
->shuttingdown
== ISC_TRUE
);
1604 if (xfr
->sends
> 0) {
1606 * If we are currently sending, cancel it and wait for
1607 * cancel event before destroying the context.
1609 isc_socket_cancel(xfr
->client
->tcpsocket
, xfr
->client
->task
,
1610 ISC_SOCKCANCEL_SEND
);
1612 ns_client_next(xfr
->client
, ISC_R_CANCELED
);
1613 xfrout_ctx_destroy(&xfr
);
1618 xfrout_client_shutdown(void *arg
, isc_result_t result
) {
1619 xfrout_ctx_t
*xfr
= (xfrout_ctx_t
*) arg
;
1620 xfrout_fail(xfr
, result
, "aborted");
1624 * Log outgoing zone transfer messages in a format like
1625 * <client>: transfer of <zone>: <message>
1629 xfrout_logv(ns_client_t
*client
, dns_name_t
*zonename
,
1630 dns_rdataclass_t rdclass
, int level
, const char *fmt
, va_list ap
)
1631 ISC_FORMAT_PRINTF(5, 0);
1634 xfrout_logv(ns_client_t
*client
, dns_name_t
*zonename
,
1635 dns_rdataclass_t rdclass
, int level
, const char *fmt
, va_list ap
)
1638 char namebuf
[DNS_NAME_FORMATSIZE
];
1639 char classbuf
[DNS_RDATACLASS_FORMATSIZE
];
1641 dns_name_format(zonename
, namebuf
, sizeof(namebuf
));
1642 dns_rdataclass_format(rdclass
, classbuf
, sizeof(classbuf
));
1643 vsnprintf(msgbuf
, sizeof(msgbuf
), fmt
, ap
);
1644 ns_client_log(client
, DNS_LOGCATEGORY_XFER_OUT
,
1645 NS_LOGMODULE_XFER_OUT
, level
,
1646 "transfer of '%s/%s': %s", namebuf
, classbuf
, msgbuf
);
1650 * Logging function for use when a xfrout_ctx_t has not yet been created.
1653 xfrout_log1(ns_client_t
*client
, dns_name_t
*zonename
,
1654 dns_rdataclass_t rdclass
, int level
, const char *fmt
, ...) {
1657 xfrout_logv(client
, zonename
, rdclass
, level
, fmt
, ap
);
1662 * Logging function for use when there is a xfrout_ctx_t.
1665 xfrout_log(xfrout_ctx_t
*xfr
, int level
, const char *fmt
, ...) {
1668 xfrout_logv(xfr
->client
, xfr
->qname
, xfr
->qclass
, level
, fmt
, ap
);