2 * Copyright (C) 2004-2008 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.
18 /* $Id: xfrin.c,v 1.157.12.7 2008/09/25 04:15:41 marka Exp $ */
25 #include <isc/print.h>
26 #include <isc/random.h>
27 #include <isc/string.h> /* Required for HP/UX (and others?) */
29 #include <isc/timer.h>
34 #include <dns/events.h>
35 #include <dns/journal.h>
37 #include <dns/message.h>
38 #include <dns/rdataclass.h>
39 #include <dns/rdatalist.h>
40 #include <dns/rdataset.h>
41 #include <dns/result.h>
43 #include <dns/tcpmsg.h>
44 #include <dns/timer.h>
47 #include <dns/xfrin.h>
53 * Incoming AXFR and IXFR.
57 * It would be non-sensical (or at least obtuse) to use FAIL() with an
58 * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
59 * from complaining about "end-of-loop code not reached".
62 do { result = (code); \
63 if (result != ISC_R_SUCCESS) goto failure; \
68 if (result != ISC_R_SUCCESS) goto failure; \
72 * The states of the *XFR state machine. We handle both IXFR and AXFR
73 * with a single integrated state machine because they cannot be distinguished
74 * immediately - an AXFR response to an IXFR request can only be detected
75 * when the first two (2) response RRs have already been received.
91 * Incoming zone transfer context.
94 struct dns_xfrin_ctx
{
103 isc_socketmgr_t
*socketmgr
;
105 int connects
; /*%< Connect in progress */
106 int sends
; /*%< Send in progress */
107 int recvs
; /*%< Receive in progress */
108 isc_boolean_t shuttingdown
;
110 dns_name_t name
; /*%< Name of zone to transfer */
111 dns_rdataclass_t rdclass
;
113 isc_boolean_t checkid
;
117 * Requested transfer type (dns_rdatatype_axfr or
118 * dns_rdatatype_ixfr). The actual transfer type
119 * may differ due to IXFR->AXFR fallback.
121 dns_rdatatype_t reqtype
;
123 isc_sockaddr_t masteraddr
;
124 isc_sockaddr_t sourceaddr
;
125 isc_socket_t
*socket
;
127 /*% Buffer for IXFR/AXFR request message */
128 isc_buffer_t qbuffer
;
129 unsigned char qbuffer_data
[512];
131 /*% Incoming reply TCP message */
133 isc_boolean_t tcpmsg_valid
;
136 dns_dbversion_t
*ver
;
137 dns_diff_t diff
; /*%< Pending database changes */
138 int difflen
; /*%< Number of pending tuples */
141 isc_uint32_t end_serial
;
142 isc_boolean_t is_ixfr
;
144 unsigned int nmsg
; /*%< Number of messages recvd */
145 unsigned int nrecs
; /*%< Number of records recvd */
146 isc_uint64_t nbytes
; /*%< Number of bytes received */
148 isc_time_t start
; /*%< Start time of the transfer */
149 isc_time_t end
; /*%< End time of the transfer */
151 dns_tsigkey_t
*tsigkey
; /*%< Key used to create TSIG */
152 isc_buffer_t
*lasttsig
; /*%< The last TSIG */
153 dst_context_t
*tsigctx
; /*%< TSIG verification context */
154 unsigned int sincetsig
; /*%< recvd since the last TSIG */
155 dns_xfrindone_t done
;
158 * AXFR- and IXFR-specific data. Only one is used at a time
159 * according to the is_ixfr flag, so this could be a union,
160 * but keeping them separate makes it a bit simpler to clean
161 * things up when destroying the context.
164 dns_addrdatasetfunc_t add_func
;
165 dns_dbload_t
*add_private
;
169 isc_uint32_t request_serial
;
170 isc_uint32_t current_serial
;
171 dns_journal_t
*journal
;
176 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
177 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
179 /**************************************************************************/
181 * Forward declarations.
185 xfrin_create(isc_mem_t
*mctx
,
189 isc_timermgr_t
*timermgr
,
190 isc_socketmgr_t
*socketmgr
,
191 dns_name_t
*zonename
,
192 dns_rdataclass_t rdclass
,
193 dns_rdatatype_t reqtype
,
194 isc_sockaddr_t
*masteraddr
,
195 isc_sockaddr_t
*sourceaddr
,
196 dns_tsigkey_t
*tsigkey
,
197 dns_xfrin_ctx_t
**xfrp
);
199 static isc_result_t
axfr_init(dns_xfrin_ctx_t
*xfr
);
200 static isc_result_t
axfr_makedb(dns_xfrin_ctx_t
*xfr
, dns_db_t
**dbp
);
201 static isc_result_t
axfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
202 dns_name_t
*name
, dns_ttl_t ttl
,
204 static isc_result_t
axfr_apply(dns_xfrin_ctx_t
*xfr
);
205 static isc_result_t
axfr_commit(dns_xfrin_ctx_t
*xfr
);
207 static isc_result_t
ixfr_init(dns_xfrin_ctx_t
*xfr
);
208 static isc_result_t
ixfr_apply(dns_xfrin_ctx_t
*xfr
);
209 static isc_result_t
ixfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
210 dns_name_t
*name
, dns_ttl_t ttl
,
212 static isc_result_t
ixfr_commit(dns_xfrin_ctx_t
*xfr
);
214 static isc_result_t
xfr_rr(dns_xfrin_ctx_t
*xfr
, dns_name_t
*name
,
215 isc_uint32_t ttl
, dns_rdata_t
*rdata
);
217 static isc_result_t
xfrin_start(dns_xfrin_ctx_t
*xfr
);
219 static void xfrin_connect_done(isc_task_t
*task
, isc_event_t
*event
);
220 static isc_result_t
xfrin_send_request(dns_xfrin_ctx_t
*xfr
);
221 static void xfrin_send_done(isc_task_t
*task
, isc_event_t
*event
);
222 static void xfrin_sendlen_done(isc_task_t
*task
, isc_event_t
*event
);
223 static void xfrin_recv_done(isc_task_t
*task
, isc_event_t
*event
);
224 static void xfrin_timeout(isc_task_t
*task
, isc_event_t
*event
);
226 static void maybe_free(dns_xfrin_ctx_t
*xfr
);
229 xfrin_fail(dns_xfrin_ctx_t
*xfr
, isc_result_t result
, const char *msg
);
231 render(dns_message_t
*msg
, isc_mem_t
*mctx
, isc_buffer_t
*buf
);
234 xfrin_logv(int level
, const char *zonetext
, isc_sockaddr_t
*masteraddr
,
235 const char *fmt
, va_list ap
)
236 ISC_FORMAT_PRINTF(4, 0);
239 xfrin_log1(int level
, const char *zonetext
, isc_sockaddr_t
*masteraddr
,
240 const char *fmt
, ...)
241 ISC_FORMAT_PRINTF(4, 5);
244 xfrin_log(dns_xfrin_ctx_t
*xfr
, int level
, const char *fmt
, ...)
245 ISC_FORMAT_PRINTF(3, 4);
247 /**************************************************************************/
253 axfr_init(dns_xfrin_ctx_t
*xfr
) {
256 xfr
->is_ixfr
= ISC_FALSE
;
259 dns_db_detach(&xfr
->db
);
261 CHECK(axfr_makedb(xfr
, &xfr
->db
));
262 CHECK(dns_db_beginload(xfr
->db
, &xfr
->axfr
.add_func
,
263 &xfr
->axfr
.add_private
));
264 result
= ISC_R_SUCCESS
;
270 axfr_makedb(dns_xfrin_ctx_t
*xfr
, dns_db_t
**dbp
) {
271 return (dns_db_create(xfr
->mctx
, /* XXX */
272 "rbt", /* XXX guess */
276 0, NULL
, /* XXX guess */
281 axfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
282 dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
286 dns_difftuple_t
*tuple
= NULL
;
288 CHECK(dns_zone_checknames(xfr
->zone
, name
, rdata
));
289 CHECK(dns_difftuple_create(xfr
->diff
.mctx
, op
,
290 name
, ttl
, rdata
, &tuple
));
291 dns_diff_append(&xfr
->diff
, &tuple
);
292 if (++xfr
->difflen
> 100)
293 CHECK(axfr_apply(xfr
));
294 result
= ISC_R_SUCCESS
;
300 * Store a set of AXFR RRs in the database.
303 axfr_apply(dns_xfrin_ctx_t
*xfr
) {
306 CHECK(dns_diff_load(&xfr
->diff
,
307 xfr
->axfr
.add_func
, xfr
->axfr
.add_private
));
309 dns_diff_clear(&xfr
->diff
);
310 result
= ISC_R_SUCCESS
;
316 axfr_commit(dns_xfrin_ctx_t
*xfr
) {
319 CHECK(axfr_apply(xfr
));
320 CHECK(dns_db_endload(xfr
->db
, &xfr
->axfr
.add_private
));
321 CHECK(dns_zone_replacedb(xfr
->zone
, xfr
->db
, ISC_TRUE
));
323 result
= ISC_R_SUCCESS
;
328 /**************************************************************************/
334 ixfr_init(dns_xfrin_ctx_t
*xfr
) {
338 if (xfr
->reqtype
!= dns_rdatatype_ixfr
) {
339 xfrin_log(xfr
, ISC_LOG_ERROR
,
340 "got incremental response to AXFR request");
341 return (DNS_R_FORMERR
);
344 xfr
->is_ixfr
= ISC_TRUE
;
345 INSIST(xfr
->db
!= NULL
);
348 journalfile
= dns_zone_getjournal(xfr
->zone
);
349 if (journalfile
!= NULL
)
350 CHECK(dns_journal_open(xfr
->mctx
, journalfile
,
351 ISC_TRUE
, &xfr
->ixfr
.journal
));
353 result
= ISC_R_SUCCESS
;
359 ixfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
360 dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
364 dns_difftuple_t
*tuple
= NULL
;
365 if (op
== DNS_DIFFOP_ADD
)
366 CHECK(dns_zone_checknames(xfr
->zone
, name
, rdata
));
367 CHECK(dns_difftuple_create(xfr
->diff
.mctx
, op
,
368 name
, ttl
, rdata
, &tuple
));
369 dns_diff_append(&xfr
->diff
, &tuple
);
370 if (++xfr
->difflen
> 100)
371 CHECK(ixfr_apply(xfr
));
372 result
= ISC_R_SUCCESS
;
378 * Apply a set of IXFR changes to the database.
381 ixfr_apply(dns_xfrin_ctx_t
*xfr
) {
384 if (xfr
->ver
== NULL
) {
385 CHECK(dns_db_newversion(xfr
->db
, &xfr
->ver
));
386 if (xfr
->ixfr
.journal
!= NULL
)
387 CHECK(dns_journal_begin_transaction(xfr
->ixfr
.journal
));
389 CHECK(dns_diff_apply(&xfr
->diff
, xfr
->db
, xfr
->ver
));
390 if (xfr
->ixfr
.journal
!= NULL
) {
391 result
= dns_journal_writediff(xfr
->ixfr
.journal
, &xfr
->diff
);
392 if (result
!= ISC_R_SUCCESS
)
395 dns_diff_clear(&xfr
->diff
);
397 result
= ISC_R_SUCCESS
;
403 ixfr_commit(dns_xfrin_ctx_t
*xfr
) {
406 CHECK(ixfr_apply(xfr
));
407 if (xfr
->ver
!= NULL
) {
408 /* XXX enter ready-to-commit state here */
409 if (xfr
->ixfr
.journal
!= NULL
)
410 CHECK(dns_journal_commit(xfr
->ixfr
.journal
));
411 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_TRUE
);
412 dns_zone_markdirty(xfr
->zone
);
414 result
= ISC_R_SUCCESS
;
419 /**************************************************************************/
421 * Common AXFR/IXFR protocol code
425 * Handle a single incoming resource record according to the current
429 xfr_rr(dns_xfrin_ctx_t
*xfr
, dns_name_t
*name
, isc_uint32_t ttl
,
436 if (rdata
->type
== dns_rdatatype_none
||
437 dns_rdatatype_ismeta(rdata
->type
))
441 switch (xfr
->state
) {
443 if (rdata
->type
!= dns_rdatatype_soa
) {
444 xfrin_log(xfr
, ISC_LOG_ERROR
,
445 "non-SOA response to SOA query");
448 xfr
->end_serial
= dns_soa_getserial(rdata
);
449 if (!DNS_SERIAL_GT(xfr
->end_serial
, xfr
->ixfr
.request_serial
) &&
450 !dns_zone_isforced(xfr
->zone
)) {
451 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
452 "requested serial %u, "
453 "master has %u, not updating",
454 xfr
->ixfr
.request_serial
, xfr
->end_serial
);
455 FAIL(DNS_R_UPTODATE
);
457 xfr
->state
= XFRST_GOTSOA
;
462 * Skip other records in the answer section.
466 case XFRST_INITIALSOA
:
467 if (rdata
->type
!= dns_rdatatype_soa
) {
468 xfrin_log(xfr
, ISC_LOG_ERROR
,
469 "first RR in zone transfer must be SOA");
473 * Remember the serial number in the initial SOA.
474 * We need it to recognize the end of an IXFR.
476 xfr
->end_serial
= dns_soa_getserial(rdata
);
477 if (xfr
->reqtype
== dns_rdatatype_ixfr
&&
478 ! DNS_SERIAL_GT(xfr
->end_serial
, xfr
->ixfr
.request_serial
)
479 && !dns_zone_isforced(xfr
->zone
))
482 * This must be the single SOA record that is
483 * sent when the current version on the master
484 * is not newer than the version in the request.
486 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
487 "requested serial %u, "
488 "master has %u, not updating",
489 xfr
->ixfr
.request_serial
, xfr
->end_serial
);
490 FAIL(DNS_R_UPTODATE
);
492 if (xfr
->reqtype
== dns_rdatatype_axfr
)
493 xfr
->checkid
= ISC_FALSE
;
494 xfr
->state
= XFRST_FIRSTDATA
;
497 case XFRST_FIRSTDATA
:
499 * If the transfer begins with one SOA record, it is an AXFR,
500 * if it begins with two SOAs, it is an IXFR.
502 if (xfr
->reqtype
== dns_rdatatype_ixfr
&&
503 rdata
->type
== dns_rdatatype_soa
&&
504 xfr
->ixfr
.request_serial
== dns_soa_getserial(rdata
)) {
505 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
506 "got incremental response");
507 CHECK(ixfr_init(xfr
));
508 xfr
->state
= XFRST_IXFR_DELSOA
;
510 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
511 "got nonincremental response");
512 CHECK(axfr_init(xfr
));
513 xfr
->state
= XFRST_AXFR
;
517 case XFRST_IXFR_DELSOA
:
518 INSIST(rdata
->type
== dns_rdatatype_soa
);
519 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_DEL
, name
, ttl
, rdata
));
520 xfr
->state
= XFRST_IXFR_DEL
;
524 if (rdata
->type
== dns_rdatatype_soa
) {
525 isc_uint32_t soa_serial
= dns_soa_getserial(rdata
);
526 xfr
->state
= XFRST_IXFR_ADDSOA
;
527 xfr
->ixfr
.current_serial
= soa_serial
;
530 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_DEL
, name
, ttl
, rdata
));
533 case XFRST_IXFR_ADDSOA
:
534 INSIST(rdata
->type
== dns_rdatatype_soa
);
535 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_ADD
, name
, ttl
, rdata
));
536 xfr
->state
= XFRST_IXFR_ADD
;
540 if (rdata
->type
== dns_rdatatype_soa
) {
541 isc_uint32_t soa_serial
= dns_soa_getserial(rdata
);
542 if (soa_serial
== xfr
->end_serial
) {
543 CHECK(ixfr_commit(xfr
));
544 xfr
->state
= XFRST_END
;
546 } else if (soa_serial
!= xfr
->ixfr
.current_serial
) {
547 xfrin_log(xfr
, ISC_LOG_ERROR
,
549 "expected serial %u, got %u",
550 xfr
->ixfr
.current_serial
, soa_serial
);
553 CHECK(ixfr_commit(xfr
));
554 xfr
->state
= XFRST_IXFR_DELSOA
;
558 if (rdata
->type
== dns_rdatatype_ns
&&
559 dns_name_iswildcard(name
))
560 FAIL(DNS_R_INVALIDNS
);
561 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_ADD
, name
, ttl
, rdata
));
566 * Old BINDs sent cross class A records for non IN classes.
568 if (rdata
->type
== dns_rdatatype_a
&&
569 rdata
->rdclass
!= xfr
->rdclass
&&
570 xfr
->rdclass
!= dns_rdataclass_in
)
572 CHECK(axfr_putdata(xfr
, DNS_DIFFOP_ADD
, name
, ttl
, rdata
));
573 if (rdata
->type
== dns_rdatatype_soa
) {
574 CHECK(axfr_commit(xfr
));
575 xfr
->state
= XFRST_END
;
580 FAIL(DNS_R_EXTRADATA
);
585 result
= ISC_R_SUCCESS
;
591 dns_xfrin_create(dns_zone_t
*zone
, dns_rdatatype_t xfrtype
,
592 isc_sockaddr_t
*masteraddr
, dns_tsigkey_t
*tsigkey
,
593 isc_mem_t
*mctx
, isc_timermgr_t
*timermgr
,
594 isc_socketmgr_t
*socketmgr
, isc_task_t
*task
,
595 dns_xfrindone_t done
, dns_xfrin_ctx_t
**xfrp
)
597 isc_sockaddr_t sourceaddr
;
599 switch (isc_sockaddr_pf(masteraddr
)) {
601 sourceaddr
= *dns_zone_getxfrsource4(zone
);
604 sourceaddr
= *dns_zone_getxfrsource6(zone
);
610 return(dns_xfrin_create2(zone
, xfrtype
, masteraddr
, &sourceaddr
,
611 tsigkey
, mctx
, timermgr
, socketmgr
,
616 dns_xfrin_create2(dns_zone_t
*zone
, dns_rdatatype_t xfrtype
,
617 isc_sockaddr_t
*masteraddr
, isc_sockaddr_t
*sourceaddr
,
618 dns_tsigkey_t
*tsigkey
, isc_mem_t
*mctx
,
619 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
620 isc_task_t
*task
, dns_xfrindone_t done
, dns_xfrin_ctx_t
**xfrp
)
622 dns_name_t
*zonename
= dns_zone_getorigin(zone
);
623 dns_xfrin_ctx_t
*xfr
= NULL
;
627 REQUIRE(xfrp
!= NULL
&& *xfrp
== NULL
);
629 (void)dns_zone_getdb(zone
, &db
);
631 if (xfrtype
== dns_rdatatype_soa
|| xfrtype
== dns_rdatatype_ixfr
)
634 CHECK(xfrin_create(mctx
, zone
, db
, task
, timermgr
, socketmgr
, zonename
,
635 dns_zone_getclass(zone
), xfrtype
, masteraddr
,
636 sourceaddr
, tsigkey
, &xfr
));
638 CHECK(xfrin_start(xfr
));
647 if (result
!= ISC_R_SUCCESS
) {
648 char zonetext
[DNS_NAME_MAXTEXT
+32];
649 dns_zone_name(zone
, zonetext
, sizeof(zonetext
));
650 xfrin_log1(ISC_LOG_ERROR
, zonetext
, masteraddr
,
651 "zone transfer setup failed");
657 dns_xfrin_shutdown(dns_xfrin_ctx_t
*xfr
) {
658 if (! xfr
->shuttingdown
)
659 xfrin_fail(xfr
, ISC_R_CANCELED
, "shut down");
663 dns_xfrin_attach(dns_xfrin_ctx_t
*source
, dns_xfrin_ctx_t
**target
) {
664 REQUIRE(target
!= NULL
&& *target
== NULL
);
670 dns_xfrin_detach(dns_xfrin_ctx_t
**xfrp
) {
671 dns_xfrin_ctx_t
*xfr
= *xfrp
;
672 INSIST(xfr
->refcount
> 0);
679 xfrin_cancelio(dns_xfrin_ctx_t
*xfr
) {
680 if (xfr
->connects
> 0) {
681 isc_socket_cancel(xfr
->socket
, xfr
->task
,
682 ISC_SOCKCANCEL_CONNECT
);
683 } else if (xfr
->recvs
> 0) {
684 dns_tcpmsg_cancelread(&xfr
->tcpmsg
);
685 } else if (xfr
->sends
> 0) {
686 isc_socket_cancel(xfr
->socket
, xfr
->task
,
687 ISC_SOCKCANCEL_SEND
);
692 xfrin_reset(dns_xfrin_ctx_t
*xfr
) {
693 REQUIRE(VALID_XFRIN(xfr
));
695 xfrin_log(xfr
, ISC_LOG_INFO
, "resetting");
699 if (xfr
->socket
!= NULL
)
700 isc_socket_detach(&xfr
->socket
);
702 if (xfr
->lasttsig
!= NULL
)
703 isc_buffer_free(&xfr
->lasttsig
);
705 dns_diff_clear(&xfr
->diff
);
708 if (xfr
->ixfr
.journal
!= NULL
)
709 dns_journal_destroy(&xfr
->ixfr
.journal
);
711 if (xfr
->axfr
.add_private
!= NULL
) {
712 (void)dns_db_endload(xfr
->db
, &xfr
->axfr
.add_private
);
713 xfr
->axfr
.add_func
= NULL
;
716 if (xfr
->tcpmsg_valid
) {
717 dns_tcpmsg_invalidate(&xfr
->tcpmsg
);
718 xfr
->tcpmsg_valid
= ISC_FALSE
;
721 if (xfr
->ver
!= NULL
)
722 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_FALSE
);
727 xfrin_fail(dns_xfrin_ctx_t
*xfr
, isc_result_t result
, const char *msg
) {
728 if (result
!= DNS_R_UPTODATE
) {
729 xfrin_log(xfr
, ISC_LOG_ERROR
, "%s: %s",
730 msg
, isc_result_totext(result
));
732 /* Pass special result code to force AXFR retry */
733 result
= DNS_R_BADIXFR
;
739 if (xfr
->ixfr
.journal
!= NULL
)
740 dns_journal_destroy(&xfr
->ixfr
.journal
);
741 if (xfr
->done
!= NULL
) {
742 (xfr
->done
)(xfr
->zone
, result
);
745 xfr
->shuttingdown
= ISC_TRUE
;
750 xfrin_create(isc_mem_t
*mctx
,
754 isc_timermgr_t
*timermgr
,
755 isc_socketmgr_t
*socketmgr
,
756 dns_name_t
*zonename
,
757 dns_rdataclass_t rdclass
,
758 dns_rdatatype_t reqtype
,
759 isc_sockaddr_t
*masteraddr
,
760 isc_sockaddr_t
*sourceaddr
,
761 dns_tsigkey_t
*tsigkey
,
762 dns_xfrin_ctx_t
**xfrp
)
764 dns_xfrin_ctx_t
*xfr
= NULL
;
768 xfr
= isc_mem_get(mctx
, sizeof(*xfr
));
770 return (ISC_R_NOMEMORY
);
774 dns_zone_iattach(zone
, &xfr
->zone
);
776 isc_task_attach(task
, &xfr
->task
);
778 xfr
->socketmgr
= socketmgr
;
784 xfr
->shuttingdown
= ISC_FALSE
;
786 dns_name_init(&xfr
->name
, NULL
);
787 xfr
->rdclass
= rdclass
;
788 isc_random_get(&tmp
);
789 xfr
->checkid
= ISC_TRUE
;
790 xfr
->id
= (isc_uint16_t
)(tmp
& 0xffff);
791 xfr
->reqtype
= reqtype
;
798 xfr
->tcpmsg_valid
= ISC_FALSE
;
802 dns_db_attach(db
, &xfr
->db
);
804 dns_diff_init(xfr
->mctx
, &xfr
->diff
);
807 if (reqtype
== dns_rdatatype_soa
)
808 xfr
->state
= XFRST_SOAQUERY
;
810 xfr
->state
= XFRST_INITIALSOA
;
816 isc_time_now(&xfr
->start
);
820 dns_tsigkey_attach(tsigkey
, &xfr
->tsigkey
);
821 xfr
->lasttsig
= NULL
;
824 xfr
->is_ixfr
= ISC_FALSE
;
826 /* ixfr.request_serial */
827 /* ixfr.current_serial */
828 xfr
->ixfr
.journal
= NULL
;
830 xfr
->axfr
.add_func
= NULL
;
831 xfr
->axfr
.add_private
= NULL
;
833 CHECK(dns_name_dup(zonename
, mctx
, &xfr
->name
));
835 CHECK(isc_timer_create(timermgr
, isc_timertype_inactive
, NULL
, NULL
,
836 task
, xfrin_timeout
, xfr
, &xfr
->timer
));
837 CHECK(dns_timer_setidle(xfr
->timer
,
838 dns_zone_getmaxxfrin(xfr
->zone
),
839 dns_zone_getidlein(xfr
->zone
),
842 xfr
->masteraddr
= *masteraddr
;
844 INSIST(isc_sockaddr_pf(masteraddr
) == isc_sockaddr_pf(sourceaddr
));
845 xfr
->sourceaddr
= *sourceaddr
;
846 isc_sockaddr_setport(&xfr
->sourceaddr
, 0);
848 isc_buffer_init(&xfr
->qbuffer
, xfr
->qbuffer_data
,
849 sizeof(xfr
->qbuffer_data
));
851 xfr
->magic
= XFRIN_MAGIC
;
853 return (ISC_R_SUCCESS
);
856 if (xfr
->timer
!= NULL
)
857 isc_timer_detach(&xfr
->timer
);
858 if (dns_name_dynamic(&xfr
->name
))
859 dns_name_free(&xfr
->name
, xfr
->mctx
);
860 if (xfr
->tsigkey
!= NULL
)
861 dns_tsigkey_detach(&xfr
->tsigkey
);
863 dns_db_detach(&xfr
->db
);
864 isc_task_detach(&xfr
->task
);
865 dns_zone_idetach(&xfr
->zone
);
866 isc_mem_put(mctx
, xfr
, sizeof(*xfr
));
872 xfrin_start(dns_xfrin_ctx_t
*xfr
) {
874 CHECK(isc_socket_create(xfr
->socketmgr
,
875 isc_sockaddr_pf(&xfr
->sourceaddr
),
878 isc_socket_setname(xfr
->socket
, "xfrin", NULL
);
879 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
880 CHECK(isc_socket_bind(xfr
->socket
, &xfr
->sourceaddr
,
881 ISC_SOCKET_REUSEADDRESS
));
883 CHECK(isc_socket_connect(xfr
->socket
, &xfr
->masteraddr
, xfr
->task
,
884 xfrin_connect_done
, xfr
));
886 return (ISC_R_SUCCESS
);
888 xfrin_fail(xfr
, result
, "failed setting up socket");
892 /* XXX the resolver could use this, too */
895 render(dns_message_t
*msg
, isc_mem_t
*mctx
, isc_buffer_t
*buf
) {
897 isc_boolean_t cleanup_cctx
= ISC_FALSE
;
900 CHECK(dns_compress_init(&cctx
, -1, mctx
));
901 cleanup_cctx
= ISC_TRUE
;
902 CHECK(dns_message_renderbegin(msg
, &cctx
, buf
));
903 CHECK(dns_message_rendersection(msg
, DNS_SECTION_QUESTION
, 0));
904 CHECK(dns_message_rendersection(msg
, DNS_SECTION_ANSWER
, 0));
905 CHECK(dns_message_rendersection(msg
, DNS_SECTION_AUTHORITY
, 0));
906 CHECK(dns_message_rendersection(msg
, DNS_SECTION_ADDITIONAL
, 0));
907 CHECK(dns_message_renderend(msg
));
908 result
= ISC_R_SUCCESS
;
911 dns_compress_invalidate(&cctx
);
916 * A connection has been established.
919 xfrin_connect_done(isc_task_t
*task
, isc_event_t
*event
) {
920 isc_socket_connev_t
*cev
= (isc_socket_connev_t
*) event
;
921 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
922 isc_result_t result
= cev
->result
;
923 char sourcetext
[ISC_SOCKADDR_FORMATSIZE
];
924 isc_sockaddr_t sockaddr
;
926 REQUIRE(VALID_XFRIN(xfr
));
930 INSIST(event
->ev_type
== ISC_SOCKEVENT_CONNECT
);
931 isc_event_free(&event
);
934 if (xfr
->shuttingdown
) {
939 if (result
!= ISC_R_SUCCESS
) {
940 dns_zonemgr_t
* zmgr
= dns_zone_getmgr(xfr
->zone
);
945 dns_zonemgr_unreachableadd(zmgr
, &xfr
->masteraddr
,
946 &xfr
->sourceaddr
, &now
);
951 result
= isc_socket_getsockname(xfr
->socket
, &sockaddr
);
952 if (result
== ISC_R_SUCCESS
) {
953 isc_sockaddr_format(&sockaddr
, sourcetext
, sizeof(sourcetext
));
955 strcpy(sourcetext
, "<UNKNOWN>");
956 xfrin_log(xfr
, ISC_LOG_INFO
, "connected using %s", sourcetext
);
958 dns_tcpmsg_init(xfr
->mctx
, xfr
->socket
, &xfr
->tcpmsg
);
959 xfr
->tcpmsg_valid
= ISC_TRUE
;
961 CHECK(xfrin_send_request(xfr
));
963 if (result
!= ISC_R_SUCCESS
)
964 xfrin_fail(xfr
, result
, "failed to connect");
968 * Convert a tuple into a dns_name_t suitable for inserting
969 * into the given dns_message_t.
972 tuple2msgname(dns_difftuple_t
*tuple
, dns_message_t
*msg
, dns_name_t
**target
)
975 dns_rdata_t
*rdata
= NULL
;
976 dns_rdatalist_t
*rdl
= NULL
;
977 dns_rdataset_t
*rds
= NULL
;
978 dns_name_t
*name
= NULL
;
980 REQUIRE(target
!= NULL
&& *target
== NULL
);
982 CHECK(dns_message_gettemprdata(msg
, &rdata
));
983 dns_rdata_init(rdata
);
984 dns_rdata_clone(&tuple
->rdata
, rdata
);
986 CHECK(dns_message_gettemprdatalist(msg
, &rdl
));
987 dns_rdatalist_init(rdl
);
988 rdl
->type
= tuple
->rdata
.type
;
989 rdl
->rdclass
= tuple
->rdata
.rdclass
;
990 rdl
->ttl
= tuple
->ttl
;
991 ISC_LIST_APPEND(rdl
->rdata
, rdata
, link
);
993 CHECK(dns_message_gettemprdataset(msg
, &rds
));
994 dns_rdataset_init(rds
);
995 CHECK(dns_rdatalist_tordataset(rdl
, rds
));
997 CHECK(dns_message_gettempname(msg
, &name
));
998 dns_name_init(name
, NULL
);
999 dns_name_clone(&tuple
->name
, name
);
1000 ISC_LIST_APPEND(name
->list
, rds
, link
);
1003 return (ISC_R_SUCCESS
);
1008 dns_rdataset_disassociate(rds
);
1009 dns_message_puttemprdataset(msg
, &rds
);
1012 ISC_LIST_UNLINK(rdl
->rdata
, rdata
, link
);
1013 dns_message_puttemprdatalist(msg
, &rdl
);
1016 dns_message_puttemprdata(msg
, &rdata
);
1023 * Build an *XFR request and send its length prefix.
1026 xfrin_send_request(dns_xfrin_ctx_t
*xfr
) {
1027 isc_result_t result
;
1028 isc_region_t region
;
1029 isc_region_t lregion
;
1030 dns_rdataset_t
*qrdataset
= NULL
;
1031 dns_message_t
*msg
= NULL
;
1032 unsigned char length
[2];
1033 dns_difftuple_t
*soatuple
= NULL
;
1034 dns_name_t
*qname
= NULL
;
1035 dns_dbversion_t
*ver
= NULL
;
1036 dns_name_t
*msgsoaname
= NULL
;
1038 /* Create the request message */
1039 CHECK(dns_message_create(xfr
->mctx
, DNS_MESSAGE_INTENTRENDER
, &msg
));
1040 CHECK(dns_message_settsigkey(msg
, xfr
->tsigkey
));
1042 /* Create a name for the question section. */
1043 CHECK(dns_message_gettempname(msg
, &qname
));
1044 dns_name_init(qname
, NULL
);
1045 dns_name_clone(&xfr
->name
, qname
);
1047 /* Formulate the question and attach it to the question name. */
1048 CHECK(dns_message_gettemprdataset(msg
, &qrdataset
));
1049 dns_rdataset_init(qrdataset
);
1050 dns_rdataset_makequestion(qrdataset
, xfr
->rdclass
, xfr
->reqtype
);
1051 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
1054 dns_message_addname(msg
, qname
, DNS_SECTION_QUESTION
);
1057 if (xfr
->reqtype
== dns_rdatatype_ixfr
) {
1058 /* Get the SOA and add it to the authority section. */
1059 /* XXX is using the current version the right thing? */
1060 dns_db_currentversion(xfr
->db
, &ver
);
1061 CHECK(dns_db_createsoatuple(xfr
->db
, ver
, xfr
->mctx
,
1062 DNS_DIFFOP_EXISTS
, &soatuple
));
1063 xfr
->ixfr
.request_serial
= dns_soa_getserial(&soatuple
->rdata
);
1064 xfr
->ixfr
.current_serial
= xfr
->ixfr
.request_serial
;
1065 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
1066 "requesting IXFR for serial %u",
1067 xfr
->ixfr
.request_serial
);
1069 CHECK(tuple2msgname(soatuple
, msg
, &msgsoaname
));
1070 dns_message_addname(msg
, msgsoaname
, DNS_SECTION_AUTHORITY
);
1071 } else if (xfr
->reqtype
== dns_rdatatype_soa
)
1072 CHECK(dns_db_getsoaserial(xfr
->db
, NULL
,
1073 &xfr
->ixfr
.request_serial
));
1075 xfr
->checkid
= ISC_TRUE
;
1080 isc_time_now(&xfr
->start
);
1082 if (xfr
->tsigctx
!= NULL
)
1083 dst_context_destroy(&xfr
->tsigctx
);
1085 CHECK(render(msg
, xfr
->mctx
, &xfr
->qbuffer
));
1088 * Free the last tsig, if there is one.
1090 if (xfr
->lasttsig
!= NULL
)
1091 isc_buffer_free(&xfr
->lasttsig
);
1094 * Save the query TSIG and don't let message_destroy free it.
1096 CHECK(dns_message_getquerytsig(msg
, xfr
->mctx
, &xfr
->lasttsig
));
1098 isc_buffer_usedregion(&xfr
->qbuffer
, ®ion
);
1099 INSIST(region
.length
<= 65535);
1101 length
[0] = region
.length
>> 8;
1102 length
[1] = region
.length
& 0xFF;
1103 lregion
.base
= length
;
1105 CHECK(isc_socket_send(xfr
->socket
, &lregion
, xfr
->task
,
1106 xfrin_sendlen_done
, xfr
));
1111 dns_message_puttempname(msg
, &qname
);
1112 if (qrdataset
!= NULL
)
1113 dns_message_puttemprdataset(msg
, &qrdataset
);
1115 dns_message_destroy(&msg
);
1116 if (soatuple
!= NULL
)
1117 dns_difftuple_free(&soatuple
);
1119 dns_db_closeversion(xfr
->db
, &ver
, ISC_FALSE
);
1123 /* XXX there should be library support for sending DNS TCP messages */
1126 xfrin_sendlen_done(isc_task_t
*task
, isc_event_t
*event
) {
1127 isc_socketevent_t
*sev
= (isc_socketevent_t
*) event
;
1128 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
1129 isc_result_t evresult
= sev
->result
;
1130 isc_result_t result
;
1131 isc_region_t region
;
1133 REQUIRE(VALID_XFRIN(xfr
));
1137 INSIST(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1138 isc_event_free(&event
);
1141 if (xfr
->shuttingdown
) {
1146 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "sent request length prefix");
1149 isc_buffer_usedregion(&xfr
->qbuffer
, ®ion
);
1150 CHECK(isc_socket_send(xfr
->socket
, ®ion
, xfr
->task
,
1151 xfrin_send_done
, xfr
));
1154 if (result
!= ISC_R_SUCCESS
)
1155 xfrin_fail(xfr
, result
, "failed sending request length prefix");
1160 xfrin_send_done(isc_task_t
*task
, isc_event_t
*event
) {
1161 isc_socketevent_t
*sev
= (isc_socketevent_t
*) event
;
1162 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
1163 isc_result_t result
;
1165 REQUIRE(VALID_XFRIN(xfr
));
1169 INSIST(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1172 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "sent request data");
1175 CHECK(dns_tcpmsg_readmessage(&xfr
->tcpmsg
, xfr
->task
,
1176 xfrin_recv_done
, xfr
));
1179 isc_event_free(&event
);
1180 if (result
!= ISC_R_SUCCESS
)
1181 xfrin_fail(xfr
, result
, "failed sending request data");
1186 xfrin_recv_done(isc_task_t
*task
, isc_event_t
*ev
) {
1187 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) ev
->ev_arg
;
1188 isc_result_t result
;
1189 dns_message_t
*msg
= NULL
;
1191 dns_tcpmsg_t
*tcpmsg
;
1192 dns_name_t
*tsigowner
= NULL
;
1194 REQUIRE(VALID_XFRIN(xfr
));
1198 INSIST(ev
->ev_type
== DNS_EVENT_TCPMSG
);
1199 tcpmsg
= ev
->ev_sender
;
1200 isc_event_free(&ev
);
1203 if (xfr
->shuttingdown
) {
1208 CHECK(tcpmsg
->result
);
1210 xfrin_log(xfr
, ISC_LOG_DEBUG(7), "received %u bytes",
1211 tcpmsg
->buffer
.used
);
1213 CHECK(isc_timer_touch(xfr
->timer
));
1215 CHECK(dns_message_create(xfr
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
));
1217 CHECK(dns_message_settsigkey(msg
, xfr
->tsigkey
));
1218 CHECK(dns_message_setquerytsig(msg
, xfr
->lasttsig
));
1220 msg
->tsigctx
= xfr
->tsigctx
;
1221 xfr
->tsigctx
= NULL
;
1224 msg
->tcp_continuation
= 1;
1226 result
= dns_message_parse(msg
, &tcpmsg
->buffer
,
1227 DNS_MESSAGEPARSE_PRESERVEORDER
);
1229 if (result
!= ISC_R_SUCCESS
|| msg
->rcode
!= dns_rcode_noerror
||
1230 (xfr
->checkid
&& msg
->id
!= xfr
->id
)) {
1231 if (result
== ISC_R_SUCCESS
)
1232 result
= ISC_RESULTCLASS_DNSRCODE
+ msg
->rcode
; /*XXX*/
1233 if (result
== ISC_R_SUCCESS
|| result
== DNS_R_NOERROR
)
1234 result
= DNS_R_UNEXPECTEDID
;
1235 if (xfr
->reqtype
== dns_rdatatype_axfr
||
1236 xfr
->reqtype
== dns_rdatatype_soa
)
1238 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1239 isc_result_totext(result
));
1241 dns_message_destroy(&msg
);
1243 xfr
->reqtype
= dns_rdatatype_soa
;
1244 xfr
->state
= XFRST_SOAQUERY
;
1245 (void)xfrin_start(xfr
);
1250 * Does the server know about IXFR? If it doesn't we will get
1251 * a message with a empty answer section or a potentially a CNAME /
1252 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1253 * if the first RR in the answer section is not a SOA record.
1255 if (xfr
->reqtype
== dns_rdatatype_ixfr
&&
1256 xfr
->state
== XFRST_INITIALSOA
&&
1257 msg
->counts
[DNS_SECTION_ANSWER
] == 0) {
1258 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
1259 "empty answer section, retrying with AXFR");
1263 if (xfr
->reqtype
== dns_rdatatype_soa
&&
1264 (msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
1265 FAIL(DNS_R_NOTAUTHORITATIVE
);
1269 result
= dns_message_checksig(msg
, dns_zone_getview(xfr
->zone
));
1270 if (result
!= ISC_R_SUCCESS
) {
1271 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1272 isc_result_totext(result
));
1276 for (result
= dns_message_firstname(msg
, DNS_SECTION_ANSWER
);
1277 result
== ISC_R_SUCCESS
;
1278 result
= dns_message_nextname(msg
, DNS_SECTION_ANSWER
))
1280 dns_rdataset_t
*rds
;
1283 dns_message_currentname(msg
, DNS_SECTION_ANSWER
, &name
);
1284 for (rds
= ISC_LIST_HEAD(name
->list
);
1286 rds
= ISC_LIST_NEXT(rds
, link
))
1288 for (result
= dns_rdataset_first(rds
);
1289 result
== ISC_R_SUCCESS
;
1290 result
= dns_rdataset_next(rds
))
1292 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1293 dns_rdataset_current(rds
, &rdata
);
1294 CHECK(xfr_rr(xfr
, name
, rds
->ttl
, &rdata
));
1298 if (result
!= ISC_R_NOMORE
)
1301 if (dns_message_gettsig(msg
, &tsigowner
) != NULL
) {
1303 * Reset the counter.
1308 * Free the last tsig, if there is one.
1310 if (xfr
->lasttsig
!= NULL
)
1311 isc_buffer_free(&xfr
->lasttsig
);
1314 * Update the last tsig pointer.
1316 CHECK(dns_message_getquerytsig(msg
, xfr
->mctx
,
1319 } else if (dns_message_gettsigkey(msg
) != NULL
) {
1321 if (xfr
->sincetsig
> 100 ||
1322 xfr
->nmsg
== 0 || xfr
->state
== XFRST_END
)
1324 result
= DNS_R_EXPECTEDTSIG
;
1330 * Update the number of messages received.
1335 * Update the number of bytes received.
1337 xfr
->nbytes
+= tcpmsg
->buffer
.used
;
1340 * Take the context back.
1342 INSIST(xfr
->tsigctx
== NULL
);
1343 xfr
->tsigctx
= msg
->tsigctx
;
1344 msg
->tsigctx
= NULL
;
1346 dns_message_destroy(&msg
);
1348 if (xfr
->state
== XFRST_GOTSOA
) {
1349 xfr
->reqtype
= dns_rdatatype_axfr
;
1350 xfr
->state
= XFRST_INITIALSOA
;
1351 CHECK(xfrin_send_request(xfr
));
1352 } else if (xfr
->state
== XFRST_END
) {
1354 * Close the journal.
1356 if (xfr
->ixfr
.journal
!= NULL
)
1357 dns_journal_destroy(&xfr
->ixfr
.journal
);
1359 * Inform the caller we succeeded.
1361 if (xfr
->done
!= NULL
) {
1362 (xfr
->done
)(xfr
->zone
, ISC_R_SUCCESS
);
1366 * We should have no outstanding events at this
1367 * point, thus maybe_free() should succeed.
1369 xfr
->shuttingdown
= ISC_TRUE
;
1373 * Read the next message.
1375 CHECK(dns_tcpmsg_readmessage(&xfr
->tcpmsg
, xfr
->task
,
1376 xfrin_recv_done
, xfr
));
1383 dns_message_destroy(&msg
);
1384 if (result
!= ISC_R_SUCCESS
)
1385 xfrin_fail(xfr
, result
, "failed while receiving responses");
1389 xfrin_timeout(isc_task_t
*task
, isc_event_t
*event
) {
1390 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
1392 REQUIRE(VALID_XFRIN(xfr
));
1396 isc_event_free(&event
);
1398 * This will log "giving up: timeout".
1400 xfrin_fail(xfr
, ISC_R_TIMEDOUT
, "giving up");
1404 maybe_free(dns_xfrin_ctx_t
*xfr
) {
1406 isc_uint64_t persec
;
1408 REQUIRE(VALID_XFRIN(xfr
));
1410 if (! xfr
->shuttingdown
|| xfr
->refcount
!= 0 ||
1411 xfr
->connects
!= 0 || xfr
->sends
!= 0 ||
1416 * Calculate the length of time the transfer took,
1417 * and print a log message with the bytes and rate.
1419 isc_time_now(&xfr
->end
);
1420 msecs
= isc_time_microdiff(&xfr
->end
, &xfr
->start
) / 1000;
1423 persec
= (xfr
->nbytes
* 1000) / msecs
;
1424 xfrin_log(xfr
, ISC_LOG_INFO
,
1425 "Transfer completed: %d messages, %d records, "
1426 "%" ISC_PRINT_QUADFORMAT
"u bytes, "
1427 "%u.%03u secs (%u bytes/sec)",
1428 xfr
->nmsg
, xfr
->nrecs
, xfr
->nbytes
,
1429 (unsigned int) (msecs
/ 1000), (unsigned int) (msecs
% 1000),
1430 (unsigned int) persec
);
1432 if (xfr
->socket
!= NULL
)
1433 isc_socket_detach(&xfr
->socket
);
1435 if (xfr
->timer
!= NULL
)
1436 isc_timer_detach(&xfr
->timer
);
1438 if (xfr
->task
!= NULL
)
1439 isc_task_detach(&xfr
->task
);
1441 if (xfr
->tsigkey
!= NULL
)
1442 dns_tsigkey_detach(&xfr
->tsigkey
);
1444 if (xfr
->lasttsig
!= NULL
)
1445 isc_buffer_free(&xfr
->lasttsig
);
1447 dns_diff_clear(&xfr
->diff
);
1449 if (xfr
->ixfr
.journal
!= NULL
)
1450 dns_journal_destroy(&xfr
->ixfr
.journal
);
1452 if (xfr
->axfr
.add_private
!= NULL
)
1453 (void)dns_db_endload(xfr
->db
, &xfr
->axfr
.add_private
);
1455 if (xfr
->tcpmsg_valid
)
1456 dns_tcpmsg_invalidate(&xfr
->tcpmsg
);
1458 if (xfr
->tsigctx
!= NULL
)
1459 dst_context_destroy(&xfr
->tsigctx
);
1461 if ((xfr
->name
.attributes
& DNS_NAMEATTR_DYNAMIC
) != 0)
1462 dns_name_free(&xfr
->name
, xfr
->mctx
);
1464 if (xfr
->ver
!= NULL
)
1465 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_FALSE
);
1467 if (xfr
->db
!= NULL
)
1468 dns_db_detach(&xfr
->db
);
1470 if (xfr
->zone
!= NULL
)
1471 dns_zone_idetach(&xfr
->zone
);
1473 isc_mem_put(xfr
->mctx
, xfr
, sizeof(*xfr
));
1477 * Log incoming zone transfer messages in a format like
1478 * transfer of <zone> from <address>: <message>
1481 xfrin_logv(int level
, const char *zonetext
, isc_sockaddr_t
*masteraddr
,
1482 const char *fmt
, va_list ap
)
1484 char mastertext
[ISC_SOCKADDR_FORMATSIZE
];
1487 isc_sockaddr_format(masteraddr
, mastertext
, sizeof(mastertext
));
1488 vsnprintf(msgtext
, sizeof(msgtext
), fmt
, ap
);
1490 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_XFER_IN
,
1491 DNS_LOGMODULE_XFER_IN
, level
,
1492 "transfer of '%s' from %s: %s",
1493 zonetext
, mastertext
, msgtext
);
1497 * Logging function for use when a xfrin_ctx_t has not yet been created.
1501 xfrin_log1(int level
, const char *zonetext
, isc_sockaddr_t
*masteraddr
,
1502 const char *fmt
, ...)
1506 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
1510 xfrin_logv(level
, zonetext
, masteraddr
, fmt
, ap
);
1515 * Logging function for use when there is a xfrin_ctx_t.
1519 xfrin_log(dns_xfrin_ctx_t
*xfr
, int level
, const char *fmt
, ...)
1522 char zonetext
[DNS_NAME_MAXTEXT
+32];
1524 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
1527 dns_zone_name(xfr
->zone
, zonetext
, sizeof(zonetext
));
1530 xfrin_logv(level
, zonetext
, &xfr
->masteraddr
, fmt
, ap
);