1 /* $NetBSD: xfrout.c,v 1.9 2015/07/08 17:28:55 christos Exp $ */
4 * Copyright (C) 2004-2015 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.
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>
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>
43 #include <dns/rriterator.h>
45 #include <dns/stats.h>
46 #include <dns/timer.h>
52 #include <named/client.h>
53 #include <named/log.h>
54 #include <named/server.h>
55 #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; \
96 } while (/*CONSTCOND*/0)
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; \
110 } while (/*CONSTCOND*/0)
113 do { result = (op); \
114 if (result != ISC_R_SUCCESS) goto failure; \
115 } while (/*CONSTCOND*/0)
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
= NULL
;
255 isc_mem_attach(mctx
, &s
->common
.mctx
);
256 s
->common
.methods
= &ixfr_rrstream_methods
;
259 CHECK(dns_journal_open(mctx
, journal_filename
,
260 DNS_JOURNAL_READ
, &s
->journal
));
261 CHECK(dns_journal_iter_init(s
->journal
, begin_serial
, end_serial
));
263 *sp
= (rrstream_t
*) s
;
264 return (ISC_R_SUCCESS
);
267 ixfr_rrstream_destroy((rrstream_t
**) (void *)&s
);
272 ixfr_rrstream_first(rrstream_t
*rs
) {
273 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) rs
;
274 return (dns_journal_first_rr(s
->journal
));
278 ixfr_rrstream_next(rrstream_t
*rs
) {
279 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) rs
;
280 return (dns_journal_next_rr(s
->journal
));
284 ixfr_rrstream_current(rrstream_t
*rs
,
285 dns_name_t
**name
, isc_uint32_t
*ttl
,
288 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) rs
;
289 dns_journal_current_rr(s
->journal
, name
, ttl
, rdata
);
293 ixfr_rrstream_destroy(rrstream_t
**rsp
) {
294 ixfr_rrstream_t
*s
= (ixfr_rrstream_t
*) *rsp
;
296 dns_journal_destroy(&s
->journal
);
297 isc_mem_putanddetach(&s
->common
.mctx
, s
, sizeof(*s
));
300 static rrstream_methods_t ixfr_rrstream_methods
= {
303 ixfr_rrstream_current
,
305 ixfr_rrstream_destroy
308 /**************************************************************************/
310 * An 'axfr_rrstream_t' is an 'rrstream_t' that returns
311 * an AXFR-like RR stream from a database.
313 * The SOAs at the beginning and end of the transfer are
314 * not included in the stream.
317 typedef struct axfr_rrstream
{
320 isc_boolean_t it_valid
;
324 * Forward declarations.
327 axfr_rrstream_destroy(rrstream_t
**rsp
);
329 static rrstream_methods_t axfr_rrstream_methods
;
332 axfr_rrstream_create(isc_mem_t
*mctx
, dns_db_t
*db
, dns_dbversion_t
*ver
,
338 INSIST(sp
!= NULL
&& *sp
== NULL
);
340 s
= isc_mem_get(mctx
, sizeof(*s
));
342 return (ISC_R_NOMEMORY
);
343 s
->common
.mctx
= NULL
;
344 isc_mem_attach(mctx
, &s
->common
.mctx
);
345 s
->common
.methods
= &axfr_rrstream_methods
;
346 s
->it_valid
= ISC_FALSE
;
348 CHECK(dns_rriterator_init(&s
->it
, db
, ver
, 0));
349 s
->it_valid
= ISC_TRUE
;
351 *sp
= (rrstream_t
*) s
;
352 return (ISC_R_SUCCESS
);
355 axfr_rrstream_destroy((rrstream_t
**) (void *)&s
);
360 axfr_rrstream_first(rrstream_t
*rs
) {
361 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
363 result
= dns_rriterator_first(&s
->it
);
364 if (result
!= ISC_R_SUCCESS
)
366 /* Skip SOA records. */
368 dns_name_t
*name_dummy
= NULL
;
369 isc_uint32_t ttl_dummy
;
370 dns_rdata_t
*rdata
= NULL
;
371 dns_rriterator_current(&s
->it
, &name_dummy
,
372 &ttl_dummy
, NULL
, &rdata
);
373 if (rdata
->type
!= dns_rdatatype_soa
)
375 result
= dns_rriterator_next(&s
->it
);
376 if (result
!= ISC_R_SUCCESS
)
383 axfr_rrstream_next(rrstream_t
*rs
) {
384 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
387 /* Skip SOA records. */
389 dns_name_t
*name_dummy
= NULL
;
390 isc_uint32_t ttl_dummy
;
391 dns_rdata_t
*rdata
= NULL
;
392 result
= dns_rriterator_next(&s
->it
);
393 if (result
!= ISC_R_SUCCESS
)
395 dns_rriterator_current(&s
->it
, &name_dummy
,
396 &ttl_dummy
, NULL
, &rdata
);
397 if (rdata
->type
!= dns_rdatatype_soa
)
404 axfr_rrstream_current(rrstream_t
*rs
, dns_name_t
**name
, isc_uint32_t
*ttl
,
407 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
408 dns_rriterator_current(&s
->it
, name
, ttl
, NULL
, rdata
);
412 axfr_rrstream_pause(rrstream_t
*rs
) {
413 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) rs
;
414 dns_rriterator_pause(&s
->it
);
418 axfr_rrstream_destroy(rrstream_t
**rsp
) {
419 axfr_rrstream_t
*s
= (axfr_rrstream_t
*) *rsp
;
421 dns_rriterator_destroy(&s
->it
);
422 isc_mem_putanddetach(&s
->common
.mctx
, s
, sizeof(*s
));
425 static rrstream_methods_t axfr_rrstream_methods
= {
428 axfr_rrstream_current
,
430 axfr_rrstream_destroy
433 /**************************************************************************/
435 * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns
436 * a single SOA record.
439 typedef struct soa_rrstream
{
441 dns_difftuple_t
*soa_tuple
;
445 * Forward declarations.
448 soa_rrstream_destroy(rrstream_t
**rsp
);
450 static rrstream_methods_t soa_rrstream_methods
;
453 soa_rrstream_create(isc_mem_t
*mctx
, dns_db_t
*db
, dns_dbversion_t
*ver
,
459 INSIST(sp
!= NULL
&& *sp
== NULL
);
461 s
= isc_mem_get(mctx
, sizeof(*s
));
463 return (ISC_R_NOMEMORY
);
464 s
->common
.mctx
= NULL
;
465 isc_mem_attach(mctx
, &s
->common
.mctx
);
466 s
->common
.methods
= &soa_rrstream_methods
;
469 CHECK(dns_db_createsoatuple(db
, ver
, mctx
, DNS_DIFFOP_EXISTS
,
472 *sp
= (rrstream_t
*) s
;
473 return (ISC_R_SUCCESS
);
476 soa_rrstream_destroy((rrstream_t
**) (void *)&s
);
481 soa_rrstream_first(rrstream_t
*rs
) {
483 return (ISC_R_SUCCESS
);
487 soa_rrstream_next(rrstream_t
*rs
) {
489 return (ISC_R_NOMORE
);
493 soa_rrstream_current(rrstream_t
*rs
, dns_name_t
**name
, isc_uint32_t
*ttl
,
496 soa_rrstream_t
*s
= (soa_rrstream_t
*) rs
;
497 *name
= &s
->soa_tuple
->name
;
498 *ttl
= s
->soa_tuple
->ttl
;
499 *rdata
= &s
->soa_tuple
->rdata
;
503 soa_rrstream_destroy(rrstream_t
**rsp
) {
504 soa_rrstream_t
*s
= (soa_rrstream_t
*) *rsp
;
505 if (s
->soa_tuple
!= NULL
)
506 dns_difftuple_free(&s
->soa_tuple
);
507 isc_mem_putanddetach(&s
->common
.mctx
, s
, sizeof(*s
));
510 static rrstream_methods_t soa_rrstream_methods
= {
513 soa_rrstream_current
,
518 /**************************************************************************/
520 * A 'compound_rrstream_t' objects owns a soa_rrstream
521 * and another rrstream, the "data stream". It returns
522 * a concatenated stream consisting of the soa_rrstream, then
523 * the data stream, then the soa_rrstream again.
525 * The component streams are owned by the compound_rrstream_t
526 * and are destroyed with it.
529 typedef struct compound_rrstream
{
531 rrstream_t
*components
[3];
534 } compound_rrstream_t
;
537 * Forward declarations.
540 compound_rrstream_destroy(rrstream_t
**rsp
);
543 compound_rrstream_next(rrstream_t
*rs
);
545 static rrstream_methods_t compound_rrstream_methods
;
549 * soa_stream != NULL && *soa_stream != NULL
550 * data_stream != NULL && *data_stream != NULL
551 * sp != NULL && *sp == NULL
554 * *soa_stream == NULL
555 * *data_stream == NULL
556 * *sp points to a valid compound_rrstream_t
557 * The soa and data streams will be destroyed
558 * when the compound_rrstream_t is destroyed.
561 compound_rrstream_create(isc_mem_t
*mctx
, rrstream_t
**soa_stream
,
562 rrstream_t
**data_stream
, rrstream_t
**sp
)
564 compound_rrstream_t
*s
;
566 INSIST(sp
!= NULL
&& *sp
== NULL
);
568 s
= isc_mem_get(mctx
, sizeof(*s
));
570 return (ISC_R_NOMEMORY
);
571 s
->common
.mctx
= NULL
;
572 isc_mem_attach(mctx
, &s
->common
.mctx
);
573 s
->common
.methods
= &compound_rrstream_methods
;
574 s
->components
[0] = *soa_stream
;
575 s
->components
[1] = *data_stream
;
576 s
->components
[2] = *soa_stream
;
578 s
->result
= ISC_R_FAILURE
;
582 *sp
= (rrstream_t
*) s
;
583 return (ISC_R_SUCCESS
);
587 compound_rrstream_first(rrstream_t
*rs
) {
588 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
591 rrstream_t
*curstream
= s
->components
[s
->state
];
592 s
->result
= curstream
->methods
->first(curstream
);
593 } while (s
->result
== ISC_R_NOMORE
&& s
->state
< 2);
598 compound_rrstream_next(rrstream_t
*rs
) {
599 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
600 rrstream_t
*curstream
= s
->components
[s
->state
];
601 s
->result
= curstream
->methods
->next(curstream
);
602 while (s
->result
== ISC_R_NOMORE
) {
604 * Make sure locks held by the current stream
605 * are released before we switch streams.
607 curstream
->methods
->pause(curstream
);
609 return (ISC_R_NOMORE
);
611 curstream
= s
->components
[s
->state
];
612 s
->result
= curstream
->methods
->first(curstream
);
618 compound_rrstream_current(rrstream_t
*rs
, dns_name_t
**name
, isc_uint32_t
*ttl
,
621 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
622 rrstream_t
*curstream
;
623 INSIST(0 <= s
->state
&& s
->state
< 3);
624 INSIST(s
->result
== ISC_R_SUCCESS
);
625 curstream
= s
->components
[s
->state
];
626 curstream
->methods
->current(curstream
, name
, ttl
, rdata
);
630 compound_rrstream_pause(rrstream_t
*rs
)
632 compound_rrstream_t
*s
= (compound_rrstream_t
*) rs
;
633 rrstream_t
*curstream
;
634 INSIST(0 <= s
->state
&& s
->state
< 3);
635 curstream
= s
->components
[s
->state
];
636 curstream
->methods
->pause(curstream
);
640 compound_rrstream_destroy(rrstream_t
**rsp
) {
641 compound_rrstream_t
*s
= (compound_rrstream_t
*) *rsp
;
642 s
->components
[0]->methods
->destroy(&s
->components
[0]);
643 s
->components
[1]->methods
->destroy(&s
->components
[1]);
644 s
->components
[2] = NULL
; /* Copy of components[0]. */
645 isc_mem_putanddetach(&s
->common
.mctx
, s
, sizeof(*s
));
648 static rrstream_methods_t compound_rrstream_methods
= {
649 compound_rrstream_first
,
650 compound_rrstream_next
,
651 compound_rrstream_current
,
652 compound_rrstream_pause
,
653 compound_rrstream_destroy
656 /**************************************************************************/
658 * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR
665 unsigned int id
; /* ID of request */
666 dns_name_t
*qname
; /* Question name of request */
667 dns_rdatatype_t qtype
; /* dns_rdatatype_{a,i}xfr */
668 dns_rdataclass_t qclass
;
669 dns_zone_t
*zone
; /* (necessary for stats) */
671 dns_dbversion_t
*ver
;
673 rrstream_t
*stream
; /* The XFR RR stream */
674 isc_boolean_t end_of_stream
; /* EOS has been reached */
675 isc_buffer_t buf
; /* Buffer for message owner
677 isc_buffer_t txlenbuf
; /* Transmit length buffer */
678 isc_buffer_t txbuf
; /* Transmit message buffer */
680 unsigned int txmemlen
;
681 unsigned int nmsg
; /* Number of messages sent */
682 dns_tsigkey_t
*tsigkey
; /* Key used to create TSIG */
683 isc_buffer_t
*lasttsig
; /* the last TSIG */
684 isc_boolean_t many_answers
;
685 int sends
; /* Send in progress */
686 isc_boolean_t shuttingdown
;
687 const char *mnemonic
; /* Style of transfer */
691 xfrout_ctx_create(isc_mem_t
*mctx
, ns_client_t
*client
,
692 unsigned int id
, dns_name_t
*qname
, dns_rdatatype_t qtype
,
693 dns_rdataclass_t qclass
, dns_zone_t
*zone
,
694 dns_db_t
*db
, dns_dbversion_t
*ver
, isc_quota_t
*quota
,
695 rrstream_t
*stream
, dns_tsigkey_t
*tsigkey
,
696 isc_buffer_t
*lasttsig
,
697 unsigned int maxtime
,
698 unsigned int idletime
,
699 isc_boolean_t many_answers
,
700 xfrout_ctx_t
**xfrp
);
703 sendstream(xfrout_ctx_t
*xfr
);
706 xfrout_senddone(isc_task_t
*task
, isc_event_t
*event
);
709 xfrout_fail(xfrout_ctx_t
*xfr
, isc_result_t result
, const char *msg
);
712 xfrout_maybe_destroy(xfrout_ctx_t
*xfr
);
715 xfrout_ctx_destroy(xfrout_ctx_t
**xfrp
);
718 xfrout_client_shutdown(void *arg
, isc_result_t result
);
721 xfrout_log1(ns_client_t
*client
, dns_name_t
*zonename
,
722 dns_rdataclass_t rdclass
, int level
,
723 const char *fmt
, ...) ISC_FORMAT_PRINTF(5, 6);
726 xfrout_log(xfrout_ctx_t
*xfr
, int level
, const char *fmt
, ...)
727 ISC_FORMAT_PRINTF(3, 4);
729 /**************************************************************************/
732 ns_xfr_start(ns_client_t
*client
, dns_rdatatype_t reqtype
) {
734 dns_name_t
*question_name
;
735 dns_rdataset_t
*question_rdataset
;
736 dns_zone_t
*zone
= NULL
, *raw
= NULL
, *mayberaw
;
738 dns_dbversion_t
*ver
= NULL
;
739 dns_rdataclass_t question_class
;
740 rrstream_t
*soa_stream
= NULL
;
741 rrstream_t
*data_stream
= NULL
;
742 rrstream_t
*stream
= NULL
;
743 dns_difftuple_t
*current_soa_tuple
= NULL
;
744 dns_name_t
*soa_name
;
745 dns_rdataset_t
*soa_rdataset
;
746 dns_rdata_t soa_rdata
= DNS_RDATA_INIT
;
747 isc_boolean_t have_soa
= ISC_FALSE
;
748 const char *mnemonic
= NULL
;
749 isc_mem_t
*mctx
= client
->mctx
;
750 dns_message_t
*request
= client
->message
;
751 xfrout_ctx_t
*xfr
= NULL
;
752 isc_quota_t
*quota
= NULL
;
753 dns_transfer_format_t format
= client
->view
->transfer_format
;
755 dns_peer_t
*peer
= NULL
;
756 isc_buffer_t
*tsigbuf
= NULL
;
758 char msg
[NS_CLIENT_ACLMSGSIZE("zone transfer")];
759 char keyname
[DNS_NAME_FORMATSIZE
];
760 isc_boolean_t is_poll
= ISC_FALSE
;
761 isc_boolean_t is_dlz
= ISC_FALSE
;
762 isc_boolean_t is_ixfr
= ISC_FALSE
;
763 isc_uint32_t begin_serial
= 0, current_serial
;
766 case dns_rdatatype_axfr
:
769 case dns_rdatatype_ixfr
:
777 ns_client_log(client
,
778 DNS_LOGCATEGORY_XFER_OUT
, NS_LOGMODULE_XFER_OUT
,
779 ISC_LOG_DEBUG(6), "%s request", mnemonic
);
783 result
= isc_quota_attach(&ns_g_server
->xfroutquota
, "a
);
784 if (result
!= ISC_R_SUCCESS
) {
785 isc_log_write(XFROUT_COMMON_LOGARGS
, ISC_LOG_WARNING
,
786 "%s request denied: %s", mnemonic
,
787 isc_result_totext(result
));
792 * Interpret the question section.
794 result
= dns_message_firstname(request
, DNS_SECTION_QUESTION
);
795 INSIST(result
== ISC_R_SUCCESS
);
798 * The question section must contain exactly one question, and
799 * it must be for AXFR/IXFR as appropriate.
801 question_name
= NULL
;
802 dns_message_currentname(request
, DNS_SECTION_QUESTION
, &question_name
);
803 question_rdataset
= ISC_LIST_HEAD(question_name
->list
);
804 question_class
= question_rdataset
->rdclass
;
805 INSIST(question_rdataset
->type
== reqtype
);
806 if (ISC_LIST_NEXT(question_rdataset
, link
) != NULL
)
807 FAILC(DNS_R_FORMERR
, "multiple questions");
808 result
= dns_message_nextname(request
, DNS_SECTION_QUESTION
);
809 if (result
!= ISC_R_NOMORE
)
810 FAILC(DNS_R_FORMERR
, "multiple questions");
812 result
= dns_zt_find(client
->view
->zonetable
, question_name
, 0, NULL
,
815 if (result
!= ISC_R_SUCCESS
) {
817 * Normal zone table does not have a match.
818 * Try the DLZ database
820 // Temporary: only searching the first DLZ database
821 if (! ISC_LIST_EMPTY(client
->view
->dlz_searched
)) {
822 result
= dns_dlzallowzonexfr(client
->view
,
827 pfilter_notify(result
, client
, "zonexfr");
828 if (result
== ISC_R_NOPERM
) {
829 char _buf1
[DNS_NAME_FORMATSIZE
];
830 char _buf2
[DNS_RDATACLASS_FORMATSIZE
];
832 result
= DNS_R_REFUSED
;
833 dns_name_format(question_name
, _buf1
,
835 dns_rdataclass_format(question_class
,
836 _buf2
, sizeof(_buf2
));
837 ns_client_log(client
, DNS_LOGCATEGORY_SECURITY
,
838 NS_LOGMODULE_XFER_OUT
,
840 "zone transfer '%s/%s' denied",
844 if (result
!= ISC_R_SUCCESS
)
845 FAILQ(DNS_R_NOTAUTH
, "non-authoritative zone",
846 question_name
, question_class
);
850 * not DLZ and not in normal zone table, we are
853 FAILQ(DNS_R_NOTAUTH
, "non-authoritative zone",
854 question_name
, question_class
);
857 /* zone table has a match */
858 switch(dns_zone_gettype(zone
)) {
859 /* Master and slave zones are OK for transfer. */
860 case dns_zone_master
:
865 FAILQ(DNS_R_NOTAUTH
, "non-authoritative zone",
866 question_name
, question_class
);
868 CHECK(dns_zone_getdb(zone
, &db
));
869 dns_db_currentversion(db
, &ver
);
872 xfrout_log1(client
, question_name
, question_class
, ISC_LOG_DEBUG(6),
873 "%s question section OK", mnemonic
);
876 * Check the authority section. Look for a SOA record with
877 * the same name and class as the question.
879 for (result
= dns_message_firstname(request
, DNS_SECTION_AUTHORITY
);
880 result
== ISC_R_SUCCESS
;
881 result
= dns_message_nextname(request
, DNS_SECTION_AUTHORITY
))
884 dns_message_currentname(request
, DNS_SECTION_AUTHORITY
,
888 * Ignore data whose owner name is not the zone apex.
890 if (! dns_name_equal(soa_name
, question_name
))
893 for (soa_rdataset
= ISC_LIST_HEAD(soa_name
->list
);
894 soa_rdataset
!= NULL
;
895 soa_rdataset
= ISC_LIST_NEXT(soa_rdataset
, link
))
898 * Ignore non-SOA data.
900 if (soa_rdataset
->type
!= dns_rdatatype_soa
)
902 if (soa_rdataset
->rdclass
!= question_class
)
905 CHECK(dns_rdataset_first(soa_rdataset
));
906 dns_rdataset_current(soa_rdataset
, &soa_rdata
);
907 result
= dns_rdataset_next(soa_rdataset
);
908 if (result
== ISC_R_SUCCESS
)
910 "IXFR authority section "
911 "has multiple SOAs");
917 if (result
!= ISC_R_NOMORE
)
920 xfrout_log1(client
, question_name
, question_class
, ISC_LOG_DEBUG(6),
921 "%s authority section OK", mnemonic
);
924 * If not a DLZ zone, decide whether to allow this transfer.
927 ns_client_aclmsg("zone transfer", question_name
, reqtype
,
928 client
->view
->rdclass
, msg
, sizeof(msg
));
929 CHECK(ns_client_checkacl(client
, NULL
, msg
,
930 dns_zone_getxfracl(zone
),
931 ISC_TRUE
, ISC_LOG_ERROR
));
935 * AXFR over UDP is not possible.
937 if (reqtype
== dns_rdatatype_axfr
&&
938 (client
->attributes
& NS_CLIENTATTR_TCP
) == 0)
939 FAILC(DNS_R_FORMERR
, "attempted AXFR over UDP");
942 * Look up the requesting server in the peer table.
944 isc_netaddr_fromsockaddr(&na
, &client
->peeraddr
);
945 (void)dns_peerlist_peerbyaddr(client
->view
->peers
, &na
, &peer
);
948 * Decide on the transfer format (one-answer or many-answers).
951 (void)dns_peer_gettransferformat(peer
, &format
);
954 * Get a dynamically allocated copy of the current SOA.
957 dns_db_currentversion(db
, &ver
);
959 CHECK(dns_db_createsoatuple(db
, ver
, mctx
, DNS_DIFFOP_EXISTS
,
960 ¤t_soa_tuple
));
962 current_serial
= dns_soa_getserial(¤t_soa_tuple
->rdata
);
963 if (reqtype
== dns_rdatatype_ixfr
) {
964 isc_boolean_t provide_ixfr
;
967 * Outgoing IXFR may have been disabled for this peer
970 provide_ixfr
= client
->view
->provideixfr
;
972 (void) dns_peer_getprovideixfr(peer
, &provide_ixfr
);
973 if (provide_ixfr
== ISC_FALSE
)
978 "IXFR request missing SOA");
980 begin_serial
= dns_soa_getserial(&soa_rdata
);
983 * RFC1995 says "If an IXFR query with the same or
984 * newer version number than that of the server
985 * is received, it is replied to with a single SOA
986 * record of the server's current version, just as
987 * in AXFR". The claim about AXFR is incorrect,
988 * but other than that, we do as the RFC says.
990 * Sending a single SOA record is also how we refuse
991 * IXFR over UDP (currently, we always do).
993 if (DNS_SERIAL_GE(begin_serial
, current_serial
) ||
994 (client
->attributes
& NS_CLIENTATTR_TCP
) == 0)
996 CHECK(soa_rrstream_create(mctx
, db
, ver
, &stream
));
1000 journalfile
= is_dlz
? NULL
: dns_zone_getjournal(zone
);
1001 if (journalfile
!= NULL
)
1002 result
= ixfr_rrstream_create(mctx
,
1008 result
= ISC_R_NOTFOUND
;
1009 if (result
== ISC_R_NOTFOUND
||
1010 result
== ISC_R_RANGE
) {
1011 xfrout_log1(client
, question_name
, question_class
,
1013 "IXFR version not in journal, "
1014 "falling back to AXFR");
1015 mnemonic
= "AXFR-style IXFR";
1022 CHECK(axfr_rrstream_create(mctx
, db
, ver
, &data_stream
));
1026 * Bracket the data stream with SOAs.
1028 CHECK(soa_rrstream_create(mctx
, db
, ver
, &soa_stream
));
1029 CHECK(compound_rrstream_create(mctx
, &soa_stream
, &data_stream
,
1035 CHECK(dns_message_getquerytsig(request
, mctx
, &tsigbuf
));
1037 * Create the xfrout context object. This transfers the ownership
1038 * of "stream", "db", "ver", and "quota" to the xfrout context object.
1044 CHECK(xfrout_ctx_create(mctx
, client
, request
->id
,
1045 question_name
, reqtype
, question_class
,
1046 zone
, db
, ver
, quota
, stream
,
1047 dns_message_gettsigkey(request
),
1051 (format
== dns_many_answers
) ?
1052 ISC_TRUE
: ISC_FALSE
,
1055 CHECK(xfrout_ctx_create(mctx
, client
, request
->id
,
1056 question_name
, reqtype
, question_class
,
1057 zone
, db
, ver
, quota
, stream
,
1058 dns_message_gettsigkey(request
),
1060 dns_zone_getmaxxfrout(zone
),
1061 dns_zone_getidleout(zone
),
1062 (format
== dns_many_answers
) ?
1063 ISC_TRUE
: ISC_FALSE
,
1066 xfr
->mnemonic
= mnemonic
;
1070 CHECK(xfr
->stream
->methods
->first(xfr
->stream
));
1072 if (xfr
->tsigkey
!= NULL
)
1073 dns_name_format(&xfr
->tsigkey
->name
, keyname
, sizeof(keyname
));
1077 xfrout_log1(client
, question_name
, question_class
,
1078 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s",
1079 (xfr
->tsigkey
!= NULL
) ? ": TSIG " : "", keyname
);
1081 xfrout_log1(client
, question_name
, question_class
,
1082 ISC_LOG_INFO
, "%s started%s%s (serial %u -> %u)",
1083 mnemonic
, (xfr
->tsigkey
!= NULL
) ? ": TSIG " : "",
1084 keyname
, begin_serial
, current_serial
);
1086 xfrout_log1(client
, question_name
, question_class
,
1087 ISC_LOG_INFO
, "%s started%s%s (serial %u)",
1088 mnemonic
, (xfr
->tsigkey
!= NULL
) ? ": TSIG " : "",
1089 keyname
, current_serial
);
1093 dns_zone_getraw(zone
, &raw
);
1094 mayberaw
= (raw
!= NULL
) ? raw
: zone
;
1095 if ((client
->attributes
& NS_CLIENTATTR_WANTEXPIRE
) != 0 &&
1096 dns_zone_gettype(mayberaw
) == dns_zone_slave
) {
1097 isc_time_t expiretime
;
1099 dns_zone_getexpiretime(zone
, &expiretime
);
1100 secs
= isc_time_seconds(&expiretime
);
1101 if (secs
>= client
->now
&& result
== ISC_R_SUCCESS
) {
1102 client
->attributes
|= NS_CLIENTATTR_HAVEEXPIRE
;
1103 client
->expire
= secs
- client
->now
;
1107 dns_zone_detach(&raw
);
1111 * Hand the context over to sendstream(). Set xfr to NULL;
1112 * sendstream() is responsible for either passing the
1113 * context on to a later event handler or destroying it.
1118 result
= ISC_R_SUCCESS
;
1121 if (result
== DNS_R_REFUSED
)
1122 inc_stats(zone
, dns_nsstatscounter_xfrrej
);
1124 isc_quota_detach("a
);
1125 if (current_soa_tuple
!= NULL
)
1126 dns_difftuple_free(¤t_soa_tuple
);
1128 stream
->methods
->destroy(&stream
);
1129 if (soa_stream
!= NULL
)
1130 soa_stream
->methods
->destroy(&soa_stream
);
1131 if (data_stream
!= NULL
)
1132 data_stream
->methods
->destroy(&data_stream
);
1134 dns_db_closeversion(db
, &ver
, ISC_FALSE
);
1138 dns_zone_detach(&zone
);
1141 xfrout_fail(xfr
, result
, "setting up zone transfer");
1142 } else if (result
!= ISC_R_SUCCESS
) {
1143 ns_client_log(client
, DNS_LOGCATEGORY_XFER_OUT
,
1144 NS_LOGMODULE_XFER_OUT
,
1145 ISC_LOG_DEBUG(3), "zone transfer setup failed");
1146 ns_client_error(client
, result
);
1151 xfrout_ctx_create(isc_mem_t
*mctx
, ns_client_t
*client
, unsigned int id
,
1152 dns_name_t
*qname
, dns_rdatatype_t qtype
,
1153 dns_rdataclass_t qclass
, dns_zone_t
*zone
,
1154 dns_db_t
*db
, dns_dbversion_t
*ver
, isc_quota_t
*quota
,
1155 rrstream_t
*stream
, dns_tsigkey_t
*tsigkey
,
1156 isc_buffer_t
*lasttsig
, unsigned int maxtime
,
1157 unsigned int idletime
, isc_boolean_t many_answers
,
1158 xfrout_ctx_t
**xfrp
)
1161 isc_result_t result
;
1165 INSIST(xfrp
!= NULL
&& *xfrp
== NULL
);
1166 xfr
= isc_mem_get(mctx
, sizeof(*xfr
));
1168 return (ISC_R_NOMEMORY
);
1170 isc_mem_attach(mctx
, &xfr
->mctx
);
1172 ns_client_attach(client
, &xfr
->client
);
1176 xfr
->qclass
= qclass
;
1180 if (zone
!= NULL
) /* zone will be NULL if it's DLZ */
1181 dns_zone_attach(zone
, &xfr
->zone
);
1182 dns_db_attach(db
, &xfr
->db
);
1183 dns_db_attachversion(db
, ver
, &xfr
->ver
);
1184 xfr
->end_of_stream
= ISC_FALSE
;
1185 xfr
->tsigkey
= tsigkey
;
1186 xfr
->lasttsig
= lasttsig
;
1190 xfr
->many_answers
= many_answers
,
1192 xfr
->shuttingdown
= ISC_FALSE
;
1193 xfr
->mnemonic
= NULL
;
1194 xfr
->buf
.base
= NULL
;
1195 xfr
->buf
.length
= 0;
1202 * Allocate a temporary buffer for the uncompressed response
1203 * message data. The size should be no more than 65535 bytes
1204 * so that the compressed data will fit in a TCP message,
1205 * and no less than 65535 bytes so that an almost maximum-sized
1206 * RR will fit. Note that although 65535-byte RRs are allowed
1207 * in principle, they cannot be zone-transferred (at least not
1208 * if uncompressible), because the message and RR headers would
1209 * push the size of the TCP message over the 65536 byte limit.
1212 mem
= isc_mem_get(mctx
, len
);
1214 result
= ISC_R_NOMEMORY
;
1217 isc_buffer_init(&xfr
->buf
, mem
, len
);
1220 * Allocate another temporary buffer for the compressed
1221 * response message and its TCP length prefix.
1224 mem
= isc_mem_get(mctx
, len
);
1226 result
= ISC_R_NOMEMORY
;
1229 isc_buffer_init(&xfr
->txlenbuf
, mem
, 2);
1230 isc_buffer_init(&xfr
->txbuf
, (char *) mem
+ 2, len
- 2);
1232 xfr
->txmemlen
= len
;
1234 CHECK(dns_timer_setidle(xfr
->client
->timer
,
1235 maxtime
, idletime
, ISC_FALSE
));
1238 * Register a shutdown callback with the client, so that we
1239 * can stop the transfer immediately when the client task
1240 * gets a shutdown event.
1242 xfr
->client
->shutdown
= xfrout_client_shutdown
;
1243 xfr
->client
->shutdown_arg
= xfr
;
1245 * These MUST be after the last "goto failure;" / CHECK to
1246 * prevent a double free by the caller.
1249 xfr
->stream
= stream
;
1252 return (ISC_R_SUCCESS
);
1255 xfrout_ctx_destroy(&xfr
);
1261 * Arrange to send as much as we can of "stream" without blocking.
1264 * The stream iterator is initialized and points at an RR,
1265 * or possibly at the end of the stream (that is, the
1266 * _first method of the iterator has been called).
1269 sendstream(xfrout_ctx_t
*xfr
) {
1270 dns_message_t
*tcpmsg
= NULL
;
1271 dns_message_t
*msg
= NULL
; /* Client message if UDP, tcpmsg if TCP */
1272 isc_result_t result
;
1274 isc_region_t region
;
1275 dns_rdataset_t
*qrdataset
;
1276 dns_name_t
*msgname
= NULL
;
1277 dns_rdata_t
*msgrdata
= NULL
;
1278 dns_rdatalist_t
*msgrdl
= NULL
;
1279 dns_rdataset_t
*msgrds
= NULL
;
1280 dns_compress_t cctx
;
1281 isc_boolean_t cleanup_cctx
= ISC_FALSE
;
1285 isc_buffer_clear(&xfr
->buf
);
1286 isc_buffer_clear(&xfr
->txlenbuf
);
1287 isc_buffer_clear(&xfr
->txbuf
);
1289 if ((xfr
->client
->attributes
& NS_CLIENTATTR_TCP
) == 0) {
1291 * In the UDP case, we put the response data directly into
1292 * the client message.
1294 msg
= xfr
->client
->message
;
1295 CHECK(dns_message_reply(msg
, ISC_TRUE
));
1298 * TCP. Build a response dns_message_t, temporarily storing
1299 * the raw, uncompressed owner names and RR data contiguously
1300 * in xfr->buf. We know that if the uncompressed data fits
1301 * in xfr->buf, the compressed data will surely fit in a TCP
1305 CHECK(dns_message_create(xfr
->mctx
,
1306 DNS_MESSAGE_INTENTRENDER
, &tcpmsg
));
1310 msg
->rcode
= dns_rcode_noerror
;
1311 msg
->flags
= DNS_MESSAGEFLAG_QR
| DNS_MESSAGEFLAG_AA
;
1312 if ((xfr
->client
->attributes
& NS_CLIENTATTR_RA
) != 0)
1313 msg
->flags
|= DNS_MESSAGEFLAG_RA
;
1314 CHECK(dns_message_settsigkey(msg
, xfr
->tsigkey
));
1315 CHECK(dns_message_setquerytsig(msg
, xfr
->lasttsig
));
1316 if (xfr
->lasttsig
!= NULL
)
1317 isc_buffer_free(&xfr
->lasttsig
);
1320 * Add a EDNS option to the message?
1322 if ((xfr
->client
->attributes
& NS_CLIENTATTR_WANTOPT
) != 0) {
1323 dns_rdataset_t
*opt
= NULL
;
1325 CHECK(ns_client_addopt(xfr
->client
, msg
, &opt
));
1326 CHECK(dns_message_setopt(msg
, opt
));
1328 * Add to first message only.
1330 xfr
->client
->attributes
&= ~NS_CLIENTATTR_WANTNSID
;
1331 xfr
->client
->attributes
&= ~NS_CLIENTATTR_HAVEEXPIRE
;
1335 * Account for reserved space.
1337 if (xfr
->tsigkey
!= NULL
)
1338 INSIST(msg
->reserved
!= 0U);
1339 isc_buffer_add(&xfr
->buf
, msg
->reserved
);
1342 * Include a question section in the first message only.
1343 * BIND 8.2.1 will not recognize an IXFR if it does not
1344 * have a question section.
1346 if (xfr
->nmsg
== 0) {
1347 dns_name_t
*qname
= NULL
;
1351 * Reserve space for the 12-byte message header
1352 * and 4 bytes of question.
1354 isc_buffer_add(&xfr
->buf
, 12 + 4);
1357 result
= dns_message_gettemprdataset(msg
, &qrdataset
);
1358 if (result
!= ISC_R_SUCCESS
)
1360 dns_rdataset_makequestion(qrdataset
,
1361 xfr
->client
->message
->rdclass
,
1364 result
= dns_message_gettempname(msg
, &qname
);
1365 if (result
!= ISC_R_SUCCESS
)
1367 dns_name_init(qname
, NULL
);
1368 isc_buffer_availableregion(&xfr
->buf
, &r
);
1369 INSIST(r
.length
>= xfr
->qname
->length
);
1370 r
.length
= xfr
->qname
->length
;
1371 isc_buffer_putmem(&xfr
->buf
, xfr
->qname
->ndata
,
1372 xfr
->qname
->length
);
1373 dns_name_fromregion(qname
, &r
);
1374 ISC_LIST_INIT(qname
->list
);
1375 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
1377 dns_message_addname(msg
, qname
, DNS_SECTION_QUESTION
);
1380 * Reserve space for the 12-byte message header
1382 isc_buffer_add(&xfr
->buf
, 12);
1383 msg
->tcp_continuation
= 1;
1388 * Try to fit in as many RRs as possible, unless "one-answer"
1389 * format has been requested.
1391 for (n_rrs
= 0; ; n_rrs
++) {
1392 dns_name_t
*name
= NULL
;
1394 dns_rdata_t
*rdata
= NULL
;
1404 xfr
->stream
->methods
->current(xfr
->stream
,
1405 &name
, &ttl
, &rdata
);
1406 size
= name
->length
+ 10 + rdata
->length
;
1407 isc_buffer_availableregion(&xfr
->buf
, &r
);
1408 if (size
>= r
.length
) {
1410 * RR would not fit. If there are other RRs in the
1411 * buffer, send them now and leave this RR to the
1412 * next message. If this RR overflows the buffer
1413 * all by itself, fail.
1415 * In theory some RRs might fit in a TCP message
1416 * when compressed even if they do not fit when
1417 * uncompressed, but surely we don't want
1418 * to send such monstrosities to an unsuspecting
1422 xfrout_log(xfr
, ISC_LOG_WARNING
,
1423 "RR too large for zone transfer "
1424 "(%d bytes)", size
);
1425 /* XXX DNS_R_RRTOOLARGE? */
1426 result
= ISC_R_NOSPACE
;
1432 if (isc_log_wouldlog(ns_g_lctx
, XFROUT_RR_LOGLEVEL
))
1433 log_rr(name
, rdata
, ttl
); /* XXX */
1435 result
= dns_message_gettempname(msg
, &msgname
);
1436 if (result
!= ISC_R_SUCCESS
)
1438 dns_name_init(msgname
, NULL
);
1439 isc_buffer_availableregion(&xfr
->buf
, &r
);
1440 INSIST(r
.length
>= name
->length
);
1441 r
.length
= name
->length
;
1442 isc_buffer_putmem(&xfr
->buf
, name
->ndata
, name
->length
);
1443 dns_name_fromregion(msgname
, &r
);
1445 /* Reserve space for RR header. */
1446 isc_buffer_add(&xfr
->buf
, 10);
1448 result
= dns_message_gettemprdata(msg
, &msgrdata
);
1449 if (result
!= ISC_R_SUCCESS
)
1451 isc_buffer_availableregion(&xfr
->buf
, &r
);
1452 r
.length
= rdata
->length
;
1453 isc_buffer_putmem(&xfr
->buf
, rdata
->data
, rdata
->length
);
1454 dns_rdata_init(msgrdata
);
1455 dns_rdata_fromregion(msgrdata
,
1456 rdata
->rdclass
, rdata
->type
, &r
);
1458 result
= dns_message_gettemprdatalist(msg
, &msgrdl
);
1459 if (result
!= ISC_R_SUCCESS
)
1461 msgrdl
->type
= rdata
->type
;
1462 msgrdl
->rdclass
= rdata
->rdclass
;
1464 if (rdata
->type
== dns_rdatatype_sig
||
1465 rdata
->type
== dns_rdatatype_rrsig
)
1466 msgrdl
->covers
= dns_rdata_covers(rdata
);
1468 msgrdl
->covers
= dns_rdatatype_none
;
1469 ISC_LINK_INIT(msgrdl
, link
);
1470 ISC_LIST_INIT(msgrdl
->rdata
);
1471 ISC_LIST_APPEND(msgrdl
->rdata
, msgrdata
, link
);
1473 result
= dns_message_gettemprdataset(msg
, &msgrds
);
1474 if (result
!= ISC_R_SUCCESS
)
1476 result
= dns_rdatalist_tordataset(msgrdl
, msgrds
);
1477 INSIST(result
== ISC_R_SUCCESS
);
1479 ISC_LIST_APPEND(msgname
->list
, msgrds
, link
);
1481 dns_message_addname(msg
, msgname
, DNS_SECTION_ANSWER
);
1484 result
= xfr
->stream
->methods
->next(xfr
->stream
);
1485 if (result
== ISC_R_NOMORE
) {
1486 xfr
->end_of_stream
= ISC_TRUE
;
1491 if (! xfr
->many_answers
)
1495 if ((xfr
->client
->attributes
& NS_CLIENTATTR_TCP
) != 0) {
1496 CHECK(dns_compress_init(&cctx
, -1, xfr
->mctx
));
1497 dns_compress_setsensitive(&cctx
, ISC_TRUE
);
1498 cleanup_cctx
= ISC_TRUE
;
1499 CHECK(dns_message_renderbegin(msg
, &cctx
, &xfr
->txbuf
));
1500 CHECK(dns_message_rendersection(msg
, DNS_SECTION_QUESTION
, 0));
1501 CHECK(dns_message_rendersection(msg
, DNS_SECTION_ANSWER
, 0));
1502 CHECK(dns_message_renderend(msg
));
1503 dns_compress_invalidate(&cctx
);
1504 cleanup_cctx
= ISC_FALSE
;
1506 isc_buffer_usedregion(&xfr
->txbuf
, &used
);
1507 isc_buffer_putuint16(&xfr
->txlenbuf
,
1508 (isc_uint16_t
)used
.length
);
1509 region
.base
= xfr
->txlenbuf
.base
;
1510 region
.length
= 2 + used
.length
;
1511 xfrout_log(xfr
, ISC_LOG_DEBUG(8),
1512 "sending TCP message of %d bytes",
1514 CHECK(isc_socket_send(xfr
->client
->tcpsocket
, /* XXX */
1515 ®ion
, xfr
->client
->task
,
1520 xfrout_log(xfr
, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
1521 ns_client_send(xfr
->client
);
1522 xfr
->stream
->methods
->pause(xfr
->stream
);
1523 xfrout_ctx_destroy(&xfr
);
1527 /* Advance lasttsig to be the last TSIG generated */
1528 CHECK(dns_message_getquerytsig(msg
, xfr
->mctx
, &xfr
->lasttsig
));
1533 if (msgname
!= NULL
) {
1534 if (msgrds
!= NULL
) {
1535 if (dns_rdataset_isassociated(msgrds
))
1536 dns_rdataset_disassociate(msgrds
);
1537 dns_message_puttemprdataset(msg
, &msgrds
);
1539 if (msgrdl
!= NULL
) {
1540 ISC_LIST_UNLINK(msgrdl
->rdata
, msgrdata
, link
);
1541 dns_message_puttemprdatalist(msg
, &msgrdl
);
1543 if (msgrdata
!= NULL
)
1544 dns_message_puttemprdata(msg
, &msgrdata
);
1545 dns_message_puttempname(msg
, &msgname
);
1549 dns_message_destroy(&tcpmsg
);
1552 dns_compress_invalidate(&cctx
);
1554 * Make sure to release any locks held by database
1555 * iterators before returning from the event handler.
1557 xfr
->stream
->methods
->pause(xfr
->stream
);
1559 if (result
== ISC_R_SUCCESS
)
1562 xfrout_fail(xfr
, result
, "sending zone data");
1566 xfrout_ctx_destroy(xfrout_ctx_t
**xfrp
) {
1567 xfrout_ctx_t
*xfr
= *xfrp
;
1568 ns_client_t
*client
= NULL
;
1570 INSIST(xfr
->sends
== 0);
1572 xfr
->client
->shutdown
= NULL
;
1573 xfr
->client
->shutdown_arg
= NULL
;
1575 if (xfr
->stream
!= NULL
)
1576 xfr
->stream
->methods
->destroy(&xfr
->stream
);
1577 if (xfr
->buf
.base
!= NULL
)
1578 isc_mem_put(xfr
->mctx
, xfr
->buf
.base
, xfr
->buf
.length
);
1579 if (xfr
->txmem
!= NULL
)
1580 isc_mem_put(xfr
->mctx
, xfr
->txmem
, xfr
->txmemlen
);
1581 if (xfr
->lasttsig
!= NULL
)
1582 isc_buffer_free(&xfr
->lasttsig
);
1583 if (xfr
->quota
!= NULL
)
1584 isc_quota_detach(&xfr
->quota
);
1585 if (xfr
->ver
!= NULL
)
1586 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_FALSE
);
1587 if (xfr
->zone
!= NULL
)
1588 dns_zone_detach(&xfr
->zone
);
1589 if (xfr
->db
!= NULL
)
1590 dns_db_detach(&xfr
->db
);
1593 * We want to detch the client after we have released the memory
1594 * context as ns_client_detach checks the memory reference count.
1596 ns_client_attach(xfr
->client
, &client
);
1597 ns_client_detach(&xfr
->client
);
1598 isc_mem_putanddetach(&xfr
->mctx
, xfr
, sizeof(*xfr
));
1599 ns_client_detach(&client
);
1605 xfrout_senddone(isc_task_t
*task
, isc_event_t
*event
) {
1606 isc_socketevent_t
*sev
= (isc_socketevent_t
*)event
;
1607 xfrout_ctx_t
*xfr
= (xfrout_ctx_t
*)event
->ev_arg
;
1608 isc_result_t evresult
= sev
->result
;
1612 INSIST(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1614 isc_event_free(&event
);
1616 INSIST(xfr
->sends
== 0);
1618 (void)isc_timer_touch(xfr
->client
->timer
);
1619 if (xfr
->shuttingdown
== ISC_TRUE
) {
1620 xfrout_maybe_destroy(xfr
);
1621 } else if (evresult
!= ISC_R_SUCCESS
) {
1622 xfrout_fail(xfr
, evresult
, "send");
1623 } else if (xfr
->end_of_stream
== ISC_FALSE
) {
1626 /* End of zone transfer stream. */
1627 inc_stats(xfr
->zone
, dns_nsstatscounter_xfrdone
);
1628 xfrout_log(xfr
, ISC_LOG_INFO
, "%s ended", xfr
->mnemonic
);
1629 ns_client_next(xfr
->client
, ISC_R_SUCCESS
);
1630 xfrout_ctx_destroy(&xfr
);
1635 xfrout_fail(xfrout_ctx_t
*xfr
, isc_result_t result
, const char *msg
) {
1636 xfr
->shuttingdown
= ISC_TRUE
;
1637 xfrout_log(xfr
, ISC_LOG_ERROR
, "%s: %s",
1638 msg
, isc_result_totext(result
));
1639 xfrout_maybe_destroy(xfr
);
1643 xfrout_maybe_destroy(xfrout_ctx_t
*xfr
) {
1644 INSIST(xfr
->shuttingdown
== ISC_TRUE
);
1645 if (xfr
->sends
> 0) {
1647 * If we are currently sending, cancel it and wait for
1648 * cancel event before destroying the context.
1650 isc_socket_cancel(xfr
->client
->tcpsocket
, xfr
->client
->task
,
1651 ISC_SOCKCANCEL_SEND
);
1653 ns_client_next(xfr
->client
, ISC_R_CANCELED
);
1654 xfrout_ctx_destroy(&xfr
);
1659 xfrout_client_shutdown(void *arg
, isc_result_t result
) {
1660 xfrout_ctx_t
*xfr
= (xfrout_ctx_t
*) arg
;
1661 xfrout_fail(xfr
, result
, "aborted");
1665 * Log outgoing zone transfer messages in a format like
1666 * <client>: transfer of <zone>: <message>
1670 xfrout_logv(ns_client_t
*client
, dns_name_t
*zonename
,
1671 dns_rdataclass_t rdclass
, int level
, const char *fmt
, va_list ap
)
1672 ISC_FORMAT_PRINTF(5, 0);
1675 xfrout_logv(ns_client_t
*client
, dns_name_t
*zonename
,
1676 dns_rdataclass_t rdclass
, int level
, const char *fmt
, va_list ap
)
1679 char namebuf
[DNS_NAME_FORMATSIZE
];
1680 char classbuf
[DNS_RDATACLASS_FORMATSIZE
];
1682 dns_name_format(zonename
, namebuf
, sizeof(namebuf
));
1683 dns_rdataclass_format(rdclass
, classbuf
, sizeof(classbuf
));
1684 vsnprintf(msgbuf
, sizeof(msgbuf
), fmt
, ap
);
1685 ns_client_log(client
, DNS_LOGCATEGORY_XFER_OUT
,
1686 NS_LOGMODULE_XFER_OUT
, level
,
1687 "transfer of '%s/%s': %s", namebuf
, classbuf
, msgbuf
);
1691 * Logging function for use when a xfrout_ctx_t has not yet been created.
1694 xfrout_log1(ns_client_t
*client
, dns_name_t
*zonename
,
1695 dns_rdataclass_t rdclass
, int level
, const char *fmt
, ...) {
1698 xfrout_logv(client
, zonename
, rdclass
, level
, fmt
, ap
);
1703 * Logging function for use when there is a xfrout_ctx_t.
1706 xfrout_log(xfrout_ctx_t
*xfr
, int level
, const char *fmt
, ...) {
1709 xfrout_logv(xfr
->client
, xfr
->qname
, xfr
->qclass
, level
, fmt
, ap
);