2 * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and 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.124.2.4.2.16 2006/07/19 01:04:24 marka Exp $ */
23 #include <isc/print.h>
24 #include <isc/random.h>
25 #include <isc/string.h> /* Required for HP/UX (and others?) */
27 #include <isc/timer.h>
32 #include <dns/events.h>
33 #include <dns/journal.h>
35 #include <dns/message.h>
36 #include <dns/rdataclass.h>
37 #include <dns/rdatalist.h>
38 #include <dns/rdataset.h>
39 #include <dns/result.h>
41 #include <dns/tcpmsg.h>
42 #include <dns/timer.h>
45 #include <dns/xfrin.h>
51 * Incoming AXFR and IXFR.
55 * It would be non-sensical (or at least obtuse) to use FAIL() with an
56 * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
57 * from complaining about "end-of-loop code not reached".
60 do { result = (code); \
61 if (result != ISC_R_SUCCESS) goto failure; \
66 if (result != ISC_R_SUCCESS) goto failure; \
70 * The states of the *XFR state machine. We handle both IXFR and AXFR
71 * with a single integrated state machine because they cannot be distinguished
72 * immediately - an AXFR response to an IXFR request can only be detected
73 * when the first two (2) response RRs have already been received.
89 * Incoming zone transfer context.
92 struct dns_xfrin_ctx
{
101 isc_socketmgr_t
*socketmgr
;
103 int connects
; /* Connect in progress */
104 int sends
; /* Send in progress */
105 int recvs
; /* Receive in progress */
106 isc_boolean_t shuttingdown
;
108 dns_name_t name
; /* Name of zone to transfer */
109 dns_rdataclass_t rdclass
;
111 isc_boolean_t checkid
;
115 * Requested transfer type (dns_rdatatype_axfr or
116 * dns_rdatatype_ixfr). The actual transfer type
117 * may differ due to IXFR->AXFR fallback.
119 dns_rdatatype_t reqtype
;
121 isc_sockaddr_t masteraddr
;
122 isc_sockaddr_t sourceaddr
;
123 isc_socket_t
*socket
;
125 /* Buffer for IXFR/AXFR request message */
126 isc_buffer_t qbuffer
;
127 unsigned char qbuffer_data
[512];
129 /* Incoming reply TCP message */
131 isc_boolean_t tcpmsg_valid
;
134 dns_dbversion_t
*ver
;
135 dns_diff_t diff
; /* Pending database changes */
136 int difflen
; /* Number of pending tuples */
139 isc_uint32_t end_serial
;
140 isc_boolean_t is_ixfr
;
142 unsigned int nmsg
; /* Number of messages recvd */
144 dns_tsigkey_t
*tsigkey
; /* Key used to create TSIG */
145 isc_buffer_t
*lasttsig
; /* The last TSIG */
146 dst_context_t
*tsigctx
; /* TSIG verification context */
147 unsigned int sincetsig
; /* recvd since the last TSIG */
148 dns_xfrindone_t done
;
151 * AXFR- and IXFR-specific data. Only one is used at a time
152 * according to the is_ixfr flag, so this could be a union,
153 * but keeping them separate makes it a bit simpler to clean
154 * things up when destroying the context.
157 dns_addrdatasetfunc_t add_func
;
158 dns_dbload_t
*add_private
;
162 isc_uint32_t request_serial
;
163 isc_uint32_t current_serial
;
164 dns_journal_t
*journal
;
169 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
170 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
172 /**************************************************************************/
174 * Forward declarations.
178 xfrin_create(isc_mem_t
*mctx
,
182 isc_timermgr_t
*timermgr
,
183 isc_socketmgr_t
*socketmgr
,
184 dns_name_t
*zonename
,
185 dns_rdataclass_t rdclass
,
186 dns_rdatatype_t reqtype
,
187 isc_sockaddr_t
*masteraddr
,
188 isc_sockaddr_t
*sourceaddr
,
189 dns_tsigkey_t
*tsigkey
,
190 dns_xfrin_ctx_t
**xfrp
);
192 static isc_result_t
axfr_init(dns_xfrin_ctx_t
*xfr
);
193 static isc_result_t
axfr_makedb(dns_xfrin_ctx_t
*xfr
, dns_db_t
**dbp
);
194 static isc_result_t
axfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
195 dns_name_t
*name
, dns_ttl_t ttl
,
197 static isc_result_t
axfr_apply(dns_xfrin_ctx_t
*xfr
);
198 static isc_result_t
axfr_commit(dns_xfrin_ctx_t
*xfr
);
200 static isc_result_t
ixfr_init(dns_xfrin_ctx_t
*xfr
);
201 static isc_result_t
ixfr_apply(dns_xfrin_ctx_t
*xfr
);
202 static isc_result_t
ixfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
203 dns_name_t
*name
, dns_ttl_t ttl
,
205 static isc_result_t
ixfr_commit(dns_xfrin_ctx_t
*xfr
);
207 static isc_result_t
xfr_rr(dns_xfrin_ctx_t
*xfr
, dns_name_t
*name
,
208 isc_uint32_t ttl
, dns_rdata_t
*rdata
);
210 static isc_result_t
xfrin_start(dns_xfrin_ctx_t
*xfr
);
212 static void xfrin_connect_done(isc_task_t
*task
, isc_event_t
*event
);
213 static isc_result_t
xfrin_send_request(dns_xfrin_ctx_t
*xfr
);
214 static void xfrin_send_done(isc_task_t
*task
, isc_event_t
*event
);
215 static void xfrin_sendlen_done(isc_task_t
*task
, isc_event_t
*event
);
216 static void xfrin_recv_done(isc_task_t
*task
, isc_event_t
*event
);
217 static void xfrin_timeout(isc_task_t
*task
, isc_event_t
*event
);
219 static void maybe_free(dns_xfrin_ctx_t
*xfr
);
222 xfrin_fail(dns_xfrin_ctx_t
*xfr
, isc_result_t result
, const char *msg
);
224 render(dns_message_t
*msg
, isc_mem_t
*mctx
, isc_buffer_t
*buf
);
227 xfrin_logv(int level
, dns_name_t
*zonename
, dns_rdataclass_t rdclass
,
228 isc_sockaddr_t
*masteraddr
, const char *fmt
, va_list ap
)
229 ISC_FORMAT_PRINTF(5, 0);
232 xfrin_log1(int level
, dns_name_t
*zonename
, dns_rdataclass_t rdclass
,
233 isc_sockaddr_t
*masteraddr
, const char *fmt
, ...)
234 ISC_FORMAT_PRINTF(5, 6);
237 xfrin_log(dns_xfrin_ctx_t
*xfr
, int level
, const char *fmt
, ...)
238 ISC_FORMAT_PRINTF(3, 4);
240 /**************************************************************************/
246 axfr_init(dns_xfrin_ctx_t
*xfr
) {
249 xfr
->is_ixfr
= ISC_FALSE
;
252 dns_db_detach(&xfr
->db
);
254 CHECK(axfr_makedb(xfr
, &xfr
->db
));
255 CHECK(dns_db_beginload(xfr
->db
, &xfr
->axfr
.add_func
,
256 &xfr
->axfr
.add_private
));
257 result
= ISC_R_SUCCESS
;
263 axfr_makedb(dns_xfrin_ctx_t
*xfr
, dns_db_t
**dbp
) {
264 return (dns_db_create(xfr
->mctx
, /* XXX */
265 "rbt", /* XXX guess */
269 0, NULL
, /* XXX guess */
274 axfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
275 dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
279 dns_difftuple_t
*tuple
= NULL
;
281 CHECK(dns_zone_checknames(xfr
->zone
, name
, rdata
));
282 CHECK(dns_difftuple_create(xfr
->diff
.mctx
, op
,
283 name
, ttl
, rdata
, &tuple
));
284 dns_diff_append(&xfr
->diff
, &tuple
);
285 if (++xfr
->difflen
> 100)
286 CHECK(axfr_apply(xfr
));
287 result
= ISC_R_SUCCESS
;
293 * Store a set of AXFR RRs in the database.
296 axfr_apply(dns_xfrin_ctx_t
*xfr
) {
299 CHECK(dns_diff_load(&xfr
->diff
,
300 xfr
->axfr
.add_func
, xfr
->axfr
.add_private
));
302 dns_diff_clear(&xfr
->diff
);
303 result
= ISC_R_SUCCESS
;
309 axfr_commit(dns_xfrin_ctx_t
*xfr
) {
312 CHECK(axfr_apply(xfr
));
313 CHECK(dns_db_endload(xfr
->db
, &xfr
->axfr
.add_private
));
314 CHECK(dns_zone_replacedb(xfr
->zone
, xfr
->db
, ISC_TRUE
));
316 result
= ISC_R_SUCCESS
;
321 /**************************************************************************/
327 ixfr_init(dns_xfrin_ctx_t
*xfr
) {
331 if (xfr
->reqtype
!= dns_rdatatype_ixfr
) {
332 xfrin_log(xfr
, ISC_LOG_ERROR
,
333 "got incremental response to AXFR request");
334 return (DNS_R_FORMERR
);
337 xfr
->is_ixfr
= ISC_TRUE
;
338 INSIST(xfr
->db
!= NULL
);
341 journalfile
= dns_zone_getjournal(xfr
->zone
);
342 if (journalfile
!= NULL
)
343 CHECK(dns_journal_open(xfr
->mctx
, journalfile
,
344 ISC_TRUE
, &xfr
->ixfr
.journal
));
346 result
= ISC_R_SUCCESS
;
352 ixfr_putdata(dns_xfrin_ctx_t
*xfr
, dns_diffop_t op
,
353 dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
357 dns_difftuple_t
*tuple
= NULL
;
358 if (op
== DNS_DIFFOP_ADD
)
359 CHECK(dns_zone_checknames(xfr
->zone
, name
, rdata
));
360 CHECK(dns_difftuple_create(xfr
->diff
.mctx
, op
,
361 name
, ttl
, rdata
, &tuple
));
362 dns_diff_append(&xfr
->diff
, &tuple
);
363 if (++xfr
->difflen
> 100)
364 CHECK(ixfr_apply(xfr
));
365 result
= ISC_R_SUCCESS
;
371 * Apply a set of IXFR changes to the database.
374 ixfr_apply(dns_xfrin_ctx_t
*xfr
) {
377 if (xfr
->ver
== NULL
) {
378 CHECK(dns_db_newversion(xfr
->db
, &xfr
->ver
));
379 if (xfr
->ixfr
.journal
!= NULL
)
380 CHECK(dns_journal_begin_transaction(xfr
->ixfr
.journal
));
382 CHECK(dns_diff_apply(&xfr
->diff
, xfr
->db
, xfr
->ver
));
383 if (xfr
->ixfr
.journal
!= NULL
) {
384 result
= dns_journal_writediff(xfr
->ixfr
.journal
, &xfr
->diff
);
385 if (result
!= ISC_R_SUCCESS
)
388 dns_diff_clear(&xfr
->diff
);
390 result
= ISC_R_SUCCESS
;
396 ixfr_commit(dns_xfrin_ctx_t
*xfr
) {
399 CHECK(ixfr_apply(xfr
));
400 if (xfr
->ver
!= NULL
) {
401 /* XXX enter ready-to-commit state here */
402 if (xfr
->ixfr
.journal
!= NULL
)
403 CHECK(dns_journal_commit(xfr
->ixfr
.journal
));
404 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_TRUE
);
405 dns_zone_markdirty(xfr
->zone
);
407 result
= ISC_R_SUCCESS
;
412 /**************************************************************************/
414 * Common AXFR/IXFR protocol code
418 * Handle a single incoming resource record according to the current
422 xfr_rr(dns_xfrin_ctx_t
*xfr
, dns_name_t
*name
, isc_uint32_t ttl
,
428 switch (xfr
->state
) {
430 if (rdata
->type
!= dns_rdatatype_soa
) {
431 xfrin_log(xfr
, ISC_LOG_ERROR
,
432 "non-SOA response to SOA query");
435 xfr
->end_serial
= dns_soa_getserial(rdata
);
436 if (!DNS_SERIAL_GT(xfr
->end_serial
, xfr
->ixfr
.request_serial
) &&
437 !dns_zone_isforced(xfr
->zone
)) {
438 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
439 "requested serial %u, "
440 "master has %u, not updating",
441 xfr
->ixfr
.request_serial
, xfr
->end_serial
);
442 FAIL(DNS_R_UPTODATE
);
444 xfr
->state
= XFRST_GOTSOA
;
449 * Skip other records in the answer section.
453 case XFRST_INITIALSOA
:
454 if (rdata
->type
!= dns_rdatatype_soa
) {
455 xfrin_log(xfr
, ISC_LOG_ERROR
,
456 "first RR in zone transfer must be SOA");
460 * Remember the serial number in the intial SOA.
461 * We need it to recognize the end of an IXFR.
463 xfr
->end_serial
= dns_soa_getserial(rdata
);
464 if (xfr
->reqtype
== dns_rdatatype_ixfr
&&
465 ! DNS_SERIAL_GT(xfr
->end_serial
, xfr
->ixfr
.request_serial
)
466 && !dns_zone_isforced(xfr
->zone
))
469 * This must be the single SOA record that is
470 * sent when the current version on the master
471 * is not newer than the version in the request.
473 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
474 "requested serial %u, "
475 "master has %u, not updating",
476 xfr
->ixfr
.request_serial
, xfr
->end_serial
);
477 FAIL(DNS_R_UPTODATE
);
479 if (xfr
->reqtype
== dns_rdatatype_axfr
)
480 xfr
->checkid
= ISC_FALSE
;
481 xfr
->state
= XFRST_FIRSTDATA
;
484 case XFRST_FIRSTDATA
:
486 * If the transfer begins with one SOA record, it is an AXFR,
487 * if it begins with two SOAs, it is an IXFR.
489 if (xfr
->reqtype
== dns_rdatatype_ixfr
&&
490 rdata
->type
== dns_rdatatype_soa
&&
491 xfr
->ixfr
.request_serial
== dns_soa_getserial(rdata
)) {
492 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
493 "got incremental response");
494 CHECK(ixfr_init(xfr
));
495 xfr
->state
= XFRST_IXFR_DELSOA
;
497 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
498 "got nonincremental response");
499 CHECK(axfr_init(xfr
));
500 xfr
->state
= XFRST_AXFR
;
504 case XFRST_IXFR_DELSOA
:
505 INSIST(rdata
->type
== dns_rdatatype_soa
);
506 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_DEL
, name
, ttl
, rdata
));
507 xfr
->state
= XFRST_IXFR_DEL
;
511 if (rdata
->type
== dns_rdatatype_soa
) {
512 isc_uint32_t soa_serial
= dns_soa_getserial(rdata
);
513 xfr
->state
= XFRST_IXFR_ADDSOA
;
514 xfr
->ixfr
.current_serial
= soa_serial
;
517 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_DEL
, name
, ttl
, rdata
));
520 case XFRST_IXFR_ADDSOA
:
521 INSIST(rdata
->type
== dns_rdatatype_soa
);
522 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_ADD
, name
, ttl
, rdata
));
523 xfr
->state
= XFRST_IXFR_ADD
;
527 if (rdata
->type
== dns_rdatatype_soa
) {
528 isc_uint32_t soa_serial
= dns_soa_getserial(rdata
);
529 if (soa_serial
== xfr
->end_serial
) {
530 CHECK(ixfr_commit(xfr
));
531 xfr
->state
= XFRST_END
;
533 } else if (soa_serial
!= xfr
->ixfr
.current_serial
) {
534 xfrin_log(xfr
, ISC_LOG_ERROR
,
536 "expected serial %u, got %u",
537 xfr
->ixfr
.current_serial
, soa_serial
);
540 CHECK(ixfr_commit(xfr
));
541 xfr
->state
= XFRST_IXFR_DELSOA
;
545 if (rdata
->type
== dns_rdatatype_ns
&&
546 dns_name_iswildcard(name
))
547 FAIL(DNS_R_INVALIDNS
);
548 CHECK(ixfr_putdata(xfr
, DNS_DIFFOP_ADD
, name
, ttl
, rdata
));
553 * Old BINDs sent cross class A records for non IN classes.
555 if (rdata
->type
== dns_rdatatype_a
&&
556 rdata
->rdclass
!= xfr
->rdclass
&&
557 xfr
->rdclass
!= dns_rdataclass_in
)
559 CHECK(axfr_putdata(xfr
, DNS_DIFFOP_ADD
, name
, ttl
, rdata
));
560 if (rdata
->type
== dns_rdatatype_soa
) {
561 CHECK(axfr_commit(xfr
));
562 xfr
->state
= XFRST_END
;
567 FAIL(DNS_R_EXTRADATA
);
572 result
= ISC_R_SUCCESS
;
578 dns_xfrin_create(dns_zone_t
*zone
, dns_rdatatype_t xfrtype
,
579 isc_sockaddr_t
*masteraddr
, dns_tsigkey_t
*tsigkey
,
580 isc_mem_t
*mctx
, isc_timermgr_t
*timermgr
,
581 isc_socketmgr_t
*socketmgr
, isc_task_t
*task
,
582 dns_xfrindone_t done
, dns_xfrin_ctx_t
**xfrp
)
584 isc_sockaddr_t sourceaddr
;
586 switch (isc_sockaddr_pf(masteraddr
)) {
588 sourceaddr
= *dns_zone_getxfrsource4(zone
);
591 sourceaddr
= *dns_zone_getxfrsource6(zone
);
597 return(dns_xfrin_create2(zone
, xfrtype
, masteraddr
, &sourceaddr
,
598 tsigkey
, mctx
, timermgr
, socketmgr
,
603 dns_xfrin_create2(dns_zone_t
*zone
, dns_rdatatype_t xfrtype
,
604 isc_sockaddr_t
*masteraddr
, isc_sockaddr_t
*sourceaddr
,
605 dns_tsigkey_t
*tsigkey
, isc_mem_t
*mctx
,
606 isc_timermgr_t
*timermgr
, isc_socketmgr_t
*socketmgr
,
607 isc_task_t
*task
, dns_xfrindone_t done
, dns_xfrin_ctx_t
**xfrp
)
609 dns_name_t
*zonename
= dns_zone_getorigin(zone
);
610 dns_xfrin_ctx_t
*xfr
= NULL
;
614 REQUIRE(xfrp
!= NULL
&& *xfrp
== NULL
);
616 (void)dns_zone_getdb(zone
, &db
);
618 if (xfrtype
== dns_rdatatype_soa
|| xfrtype
== dns_rdatatype_ixfr
)
621 CHECK(xfrin_create(mctx
, zone
, db
, task
, timermgr
, socketmgr
, zonename
,
622 dns_zone_getclass(zone
), xfrtype
, masteraddr
,
623 sourceaddr
, tsigkey
, &xfr
));
625 CHECK(xfrin_start(xfr
));
634 if (result
!= ISC_R_SUCCESS
)
635 xfrin_log1(ISC_LOG_ERROR
, zonename
, dns_zone_getclass(zone
),
636 masteraddr
, "zone transfer setup failed");
641 dns_xfrin_shutdown(dns_xfrin_ctx_t
*xfr
) {
642 if (! xfr
->shuttingdown
)
643 xfrin_fail(xfr
, ISC_R_CANCELED
, "shut down");
647 dns_xfrin_attach(dns_xfrin_ctx_t
*source
, dns_xfrin_ctx_t
**target
) {
648 REQUIRE(target
!= NULL
&& *target
== NULL
);
654 dns_xfrin_detach(dns_xfrin_ctx_t
**xfrp
) {
655 dns_xfrin_ctx_t
*xfr
= *xfrp
;
656 INSIST(xfr
->refcount
> 0);
663 xfrin_cancelio(dns_xfrin_ctx_t
*xfr
) {
664 if (xfr
->connects
> 0) {
665 isc_socket_cancel(xfr
->socket
, xfr
->task
,
666 ISC_SOCKCANCEL_CONNECT
);
667 } else if (xfr
->recvs
> 0) {
668 dns_tcpmsg_cancelread(&xfr
->tcpmsg
);
669 } else if (xfr
->sends
> 0) {
670 isc_socket_cancel(xfr
->socket
, xfr
->task
,
671 ISC_SOCKCANCEL_SEND
);
676 xfrin_reset(dns_xfrin_ctx_t
*xfr
) {
677 REQUIRE(VALID_XFRIN(xfr
));
679 xfrin_log(xfr
, ISC_LOG_INFO
, "resetting");
683 if (xfr
->socket
!= NULL
)
684 isc_socket_detach(&xfr
->socket
);
686 if (xfr
->lasttsig
!= NULL
)
687 isc_buffer_free(&xfr
->lasttsig
);
689 dns_diff_clear(&xfr
->diff
);
692 if (xfr
->ixfr
.journal
!= NULL
)
693 dns_journal_destroy(&xfr
->ixfr
.journal
);
695 if (xfr
->axfr
.add_private
!= NULL
) {
696 (void)dns_db_endload(xfr
->db
, &xfr
->axfr
.add_private
);
697 xfr
->axfr
.add_func
= NULL
;
700 if (xfr
->tcpmsg_valid
) {
701 dns_tcpmsg_invalidate(&xfr
->tcpmsg
);
702 xfr
->tcpmsg_valid
= ISC_FALSE
;
705 if (xfr
->ver
!= NULL
)
706 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_FALSE
);
711 xfrin_fail(dns_xfrin_ctx_t
*xfr
, isc_result_t result
, const char *msg
) {
712 if (result
!= DNS_R_UPTODATE
) {
713 xfrin_log(xfr
, ISC_LOG_ERROR
, "%s: %s",
714 msg
, isc_result_totext(result
));
716 /* Pass special result code to force AXFR retry */
717 result
= DNS_R_BADIXFR
;
720 if (xfr
->done
!= NULL
) {
721 (xfr
->done
)(xfr
->zone
, result
);
724 xfr
->shuttingdown
= ISC_TRUE
;
729 xfrin_create(isc_mem_t
*mctx
,
733 isc_timermgr_t
*timermgr
,
734 isc_socketmgr_t
*socketmgr
,
735 dns_name_t
*zonename
,
736 dns_rdataclass_t rdclass
,
737 dns_rdatatype_t reqtype
,
738 isc_sockaddr_t
*masteraddr
,
739 isc_sockaddr_t
*sourceaddr
,
740 dns_tsigkey_t
*tsigkey
,
741 dns_xfrin_ctx_t
**xfrp
)
743 dns_xfrin_ctx_t
*xfr
= NULL
;
747 xfr
= isc_mem_get(mctx
, sizeof(*xfr
));
749 return (ISC_R_NOMEMORY
);
753 dns_zone_iattach(zone
, &xfr
->zone
);
755 isc_task_attach(task
, &xfr
->task
);
757 xfr
->socketmgr
= socketmgr
;
763 xfr
->shuttingdown
= ISC_FALSE
;
765 dns_name_init(&xfr
->name
, NULL
);
766 xfr
->rdclass
= rdclass
;
767 isc_random_get(&tmp
);
768 xfr
->checkid
= ISC_TRUE
;
769 xfr
->id
= (isc_uint16_t
)(tmp
& 0xffff);
770 xfr
->reqtype
= reqtype
;
777 xfr
->tcpmsg_valid
= ISC_FALSE
;
781 dns_db_attach(db
, &xfr
->db
);
783 dns_diff_init(xfr
->mctx
, &xfr
->diff
);
786 if (reqtype
== dns_rdatatype_soa
)
787 xfr
->state
= XFRST_SOAQUERY
;
789 xfr
->state
= XFRST_INITIALSOA
;
796 dns_tsigkey_attach(tsigkey
, &xfr
->tsigkey
);
797 xfr
->lasttsig
= NULL
;
800 xfr
->is_ixfr
= ISC_FALSE
;
802 /* ixfr.request_serial */
803 /* ixfr.current_serial */
804 xfr
->ixfr
.journal
= NULL
;
806 xfr
->axfr
.add_func
= NULL
;
807 xfr
->axfr
.add_private
= NULL
;
809 CHECK(dns_name_dup(zonename
, mctx
, &xfr
->name
));
811 CHECK(isc_timer_create(timermgr
, isc_timertype_inactive
, NULL
, NULL
,
812 task
, xfrin_timeout
, xfr
, &xfr
->timer
));
813 CHECK(dns_timer_setidle(xfr
->timer
,
814 dns_zone_getmaxxfrin(xfr
->zone
),
815 dns_zone_getidlein(xfr
->zone
),
818 xfr
->masteraddr
= *masteraddr
;
820 INSIST(isc_sockaddr_pf(masteraddr
) == isc_sockaddr_pf(sourceaddr
));
821 xfr
->sourceaddr
= *sourceaddr
;
822 isc_sockaddr_setport(&xfr
->sourceaddr
, 0);
824 isc_buffer_init(&xfr
->qbuffer
, xfr
->qbuffer_data
,
825 sizeof(xfr
->qbuffer_data
));
827 xfr
->magic
= XFRIN_MAGIC
;
829 return (ISC_R_SUCCESS
);
832 if (xfr
->timer
!= NULL
)
833 isc_timer_detach(&xfr
->timer
);
834 if (dns_name_dynamic(&xfr
->name
))
835 dns_name_free(&xfr
->name
, xfr
->mctx
);
836 if (xfr
->tsigkey
!= NULL
)
837 dns_tsigkey_detach(&xfr
->tsigkey
);
839 dns_db_detach(&xfr
->db
);
840 isc_task_detach(&xfr
->task
);
841 dns_zone_idetach(&xfr
->zone
);
842 isc_mem_put(mctx
, xfr
, sizeof(*xfr
));
848 xfrin_start(dns_xfrin_ctx_t
*xfr
) {
850 CHECK(isc_socket_create(xfr
->socketmgr
,
851 isc_sockaddr_pf(&xfr
->sourceaddr
),
854 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
855 CHECK(isc_socket_bind(xfr
->socket
, &xfr
->sourceaddr
));
857 CHECK(isc_socket_connect(xfr
->socket
, &xfr
->masteraddr
, xfr
->task
,
858 xfrin_connect_done
, xfr
));
860 return (ISC_R_SUCCESS
);
862 xfrin_fail(xfr
, result
, "failed setting up socket");
866 /* XXX the resolver could use this, too */
869 render(dns_message_t
*msg
, isc_mem_t
*mctx
, isc_buffer_t
*buf
) {
871 isc_boolean_t cleanup_cctx
= ISC_FALSE
;
874 CHECK(dns_compress_init(&cctx
, -1, mctx
));
875 cleanup_cctx
= ISC_TRUE
;
876 CHECK(dns_message_renderbegin(msg
, &cctx
, buf
));
877 CHECK(dns_message_rendersection(msg
, DNS_SECTION_QUESTION
, 0));
878 CHECK(dns_message_rendersection(msg
, DNS_SECTION_ANSWER
, 0));
879 CHECK(dns_message_rendersection(msg
, DNS_SECTION_AUTHORITY
, 0));
880 CHECK(dns_message_rendersection(msg
, DNS_SECTION_ADDITIONAL
, 0));
881 CHECK(dns_message_renderend(msg
));
882 result
= ISC_R_SUCCESS
;
885 dns_compress_invalidate(&cctx
);
890 * A connection has been established.
893 xfrin_connect_done(isc_task_t
*task
, isc_event_t
*event
) {
894 isc_socket_connev_t
*cev
= (isc_socket_connev_t
*) event
;
895 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
896 isc_result_t evresult
= cev
->result
;
898 char sourcetext
[ISC_SOCKADDR_FORMATSIZE
];
899 isc_sockaddr_t sockaddr
;
901 REQUIRE(VALID_XFRIN(xfr
));
905 INSIST(event
->ev_type
== ISC_SOCKEVENT_CONNECT
);
906 isc_event_free(&event
);
909 if (xfr
->shuttingdown
) {
915 result
= isc_socket_getsockname(xfr
->socket
, &sockaddr
);
916 if (result
== ISC_R_SUCCESS
) {
917 isc_sockaddr_format(&sockaddr
, sourcetext
, sizeof(sourcetext
));
919 strcpy(sourcetext
, "<UNKNOWN>");
920 xfrin_log(xfr
, ISC_LOG_INFO
, "connected using %s", sourcetext
);
922 dns_tcpmsg_init(xfr
->mctx
, xfr
->socket
, &xfr
->tcpmsg
);
923 xfr
->tcpmsg_valid
= ISC_TRUE
;
925 CHECK(xfrin_send_request(xfr
));
927 if (result
!= ISC_R_SUCCESS
)
928 xfrin_fail(xfr
, result
, "failed to connect");
932 * Convert a tuple into a dns_name_t suitable for inserting
933 * into the given dns_message_t.
936 tuple2msgname(dns_difftuple_t
*tuple
, dns_message_t
*msg
, dns_name_t
**target
)
939 dns_rdata_t
*rdata
= NULL
;
940 dns_rdatalist_t
*rdl
= NULL
;
941 dns_rdataset_t
*rds
= NULL
;
942 dns_name_t
*name
= NULL
;
944 REQUIRE(target
!= NULL
&& *target
== NULL
);
946 CHECK(dns_message_gettemprdata(msg
, &rdata
));
947 dns_rdata_init(rdata
);
948 dns_rdata_clone(&tuple
->rdata
, rdata
);
950 CHECK(dns_message_gettemprdatalist(msg
, &rdl
));
951 dns_rdatalist_init(rdl
);
952 rdl
->type
= tuple
->rdata
.type
;
953 rdl
->rdclass
= tuple
->rdata
.rdclass
;
954 rdl
->ttl
= tuple
->ttl
;
955 ISC_LIST_APPEND(rdl
->rdata
, rdata
, link
);
957 CHECK(dns_message_gettemprdataset(msg
, &rds
));
958 dns_rdataset_init(rds
);
959 CHECK(dns_rdatalist_tordataset(rdl
, rds
));
961 CHECK(dns_message_gettempname(msg
, &name
));
962 dns_name_init(name
, NULL
);
963 dns_name_clone(&tuple
->name
, name
);
964 ISC_LIST_APPEND(name
->list
, rds
, link
);
967 return (ISC_R_SUCCESS
);
972 dns_rdataset_disassociate(rds
);
973 dns_message_puttemprdataset(msg
, &rds
);
976 ISC_LIST_UNLINK(rdl
->rdata
, rdata
, link
);
977 dns_message_puttemprdatalist(msg
, &rdl
);
980 dns_message_puttemprdata(msg
, &rdata
);
987 * Build an *XFR request and send its length prefix.
990 xfrin_send_request(dns_xfrin_ctx_t
*xfr
) {
993 isc_region_t lregion
;
994 dns_rdataset_t
*qrdataset
= NULL
;
995 dns_message_t
*msg
= NULL
;
996 unsigned char length
[2];
997 dns_difftuple_t
*soatuple
= NULL
;
998 dns_name_t
*qname
= NULL
;
999 dns_dbversion_t
*ver
= NULL
;
1000 dns_name_t
*msgsoaname
= NULL
;
1002 /* Create the request message */
1003 CHECK(dns_message_create(xfr
->mctx
, DNS_MESSAGE_INTENTRENDER
, &msg
));
1004 CHECK(dns_message_settsigkey(msg
, xfr
->tsigkey
));
1006 /* Create a name for the question section. */
1007 CHECK(dns_message_gettempname(msg
, &qname
));
1008 dns_name_init(qname
, NULL
);
1009 dns_name_clone(&xfr
->name
, qname
);
1011 /* Formulate the question and attach it to the question name. */
1012 CHECK(dns_message_gettemprdataset(msg
, &qrdataset
));
1013 dns_rdataset_init(qrdataset
);
1014 dns_rdataset_makequestion(qrdataset
, xfr
->rdclass
, xfr
->reqtype
);
1015 ISC_LIST_APPEND(qname
->list
, qrdataset
, link
);
1018 dns_message_addname(msg
, qname
, DNS_SECTION_QUESTION
);
1021 if (xfr
->reqtype
== dns_rdatatype_ixfr
) {
1022 /* Get the SOA and add it to the authority section. */
1023 /* XXX is using the current version the right thing? */
1024 dns_db_currentversion(xfr
->db
, &ver
);
1025 CHECK(dns_db_createsoatuple(xfr
->db
, ver
, xfr
->mctx
,
1026 DNS_DIFFOP_EXISTS
, &soatuple
));
1027 xfr
->ixfr
.request_serial
= dns_soa_getserial(&soatuple
->rdata
);
1028 xfr
->ixfr
.current_serial
= xfr
->ixfr
.request_serial
;
1029 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
1030 "requesting IXFR for serial %u",
1031 xfr
->ixfr
.request_serial
);
1033 CHECK(tuple2msgname(soatuple
, msg
, &msgsoaname
));
1034 dns_message_addname(msg
, msgsoaname
, DNS_SECTION_AUTHORITY
);
1035 } else if (xfr
->reqtype
== dns_rdatatype_soa
)
1036 CHECK(dns_db_getsoaserial(xfr
->db
, NULL
,
1037 &xfr
->ixfr
.request_serial
));
1039 xfr
->checkid
= ISC_TRUE
;
1043 CHECK(render(msg
, xfr
->mctx
, &xfr
->qbuffer
));
1046 * Free the last tsig, if there is one.
1048 if (xfr
->lasttsig
!= NULL
)
1049 isc_buffer_free(&xfr
->lasttsig
);
1052 * Save the query TSIG and don't let message_destroy free it.
1054 CHECK(dns_message_getquerytsig(msg
, xfr
->mctx
, &xfr
->lasttsig
));
1056 isc_buffer_usedregion(&xfr
->qbuffer
, ®ion
);
1057 INSIST(region
.length
<= 65535);
1059 length
[0] = region
.length
>> 8;
1060 length
[1] = region
.length
& 0xFF;
1061 lregion
.base
= length
;
1063 CHECK(isc_socket_send(xfr
->socket
, &lregion
, xfr
->task
,
1064 xfrin_sendlen_done
, xfr
));
1069 dns_message_puttempname(msg
, &qname
);
1070 if (qrdataset
!= NULL
)
1071 dns_message_puttemprdataset(msg
, &qrdataset
);
1073 dns_message_destroy(&msg
);
1074 if (soatuple
!= NULL
)
1075 dns_difftuple_free(&soatuple
);
1077 dns_db_closeversion(xfr
->db
, &ver
, ISC_FALSE
);
1081 /* XXX there should be library support for sending DNS TCP messages */
1084 xfrin_sendlen_done(isc_task_t
*task
, isc_event_t
*event
) {
1085 isc_socketevent_t
*sev
= (isc_socketevent_t
*) event
;
1086 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
1087 isc_result_t evresult
= sev
->result
;
1088 isc_result_t result
;
1089 isc_region_t region
;
1091 REQUIRE(VALID_XFRIN(xfr
));
1095 INSIST(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1096 isc_event_free(&event
);
1099 if (xfr
->shuttingdown
) {
1104 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "sent request length prefix");
1107 isc_buffer_usedregion(&xfr
->qbuffer
, ®ion
);
1108 CHECK(isc_socket_send(xfr
->socket
, ®ion
, xfr
->task
,
1109 xfrin_send_done
, xfr
));
1112 if (result
!= ISC_R_SUCCESS
)
1113 xfrin_fail(xfr
, result
, "failed sending request length prefix");
1118 xfrin_send_done(isc_task_t
*task
, isc_event_t
*event
) {
1119 isc_socketevent_t
*sev
= (isc_socketevent_t
*) event
;
1120 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
1121 isc_result_t result
;
1123 REQUIRE(VALID_XFRIN(xfr
));
1127 INSIST(event
->ev_type
== ISC_SOCKEVENT_SENDDONE
);
1130 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "sent request data");
1133 CHECK(dns_tcpmsg_readmessage(&xfr
->tcpmsg
, xfr
->task
,
1134 xfrin_recv_done
, xfr
));
1137 isc_event_free(&event
);
1138 if (result
!= ISC_R_SUCCESS
)
1139 xfrin_fail(xfr
, result
, "failed sending request data");
1144 xfrin_recv_done(isc_task_t
*task
, isc_event_t
*ev
) {
1145 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) ev
->ev_arg
;
1146 isc_result_t result
;
1147 dns_message_t
*msg
= NULL
;
1149 dns_tcpmsg_t
*tcpmsg
;
1150 dns_name_t
*tsigowner
= NULL
;
1152 REQUIRE(VALID_XFRIN(xfr
));
1156 INSIST(ev
->ev_type
== DNS_EVENT_TCPMSG
);
1157 tcpmsg
= ev
->ev_sender
;
1158 isc_event_free(&ev
);
1161 if (xfr
->shuttingdown
) {
1166 CHECK(tcpmsg
->result
);
1168 xfrin_log(xfr
, ISC_LOG_DEBUG(7), "received %u bytes",
1169 tcpmsg
->buffer
.used
);
1171 CHECK(isc_timer_touch(xfr
->timer
));
1173 CHECK(dns_message_create(xfr
->mctx
, DNS_MESSAGE_INTENTPARSE
, &msg
));
1175 CHECK(dns_message_settsigkey(msg
, xfr
->tsigkey
));
1176 CHECK(dns_message_setquerytsig(msg
, xfr
->lasttsig
));
1177 msg
->tsigctx
= xfr
->tsigctx
;
1179 msg
->tcp_continuation
= 1;
1181 result
= dns_message_parse(msg
, &tcpmsg
->buffer
,
1182 DNS_MESSAGEPARSE_PRESERVEORDER
);
1184 if (result
!= ISC_R_SUCCESS
|| msg
->rcode
!= dns_rcode_noerror
||
1185 (xfr
->checkid
&& msg
->id
!= xfr
->id
)) {
1186 if (result
== ISC_R_SUCCESS
)
1187 result
= ISC_RESULTCLASS_DNSRCODE
+ msg
->rcode
; /*XXX*/
1188 if (result
== ISC_R_SUCCESS
|| result
== DNS_R_NOERROR
)
1189 result
= DNS_R_UNEXPECTEDID
;
1190 if (xfr
->reqtype
== dns_rdatatype_axfr
||
1191 xfr
->reqtype
== dns_rdatatype_soa
)
1193 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1194 isc_result_totext(result
));
1196 dns_message_destroy(&msg
);
1198 xfr
->reqtype
= dns_rdatatype_soa
;
1199 xfr
->state
= XFRST_SOAQUERY
;
1200 (void)xfrin_start(xfr
);
1205 * Does the server know about IXFR? If it doesn't we will get
1206 * a message with a empty answer section or a potentially a CNAME /
1207 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1208 * if the first RR in the answer section is not a SOA record.
1210 if (xfr
->reqtype
== dns_rdatatype_ixfr
&&
1211 xfr
->state
== XFRST_INITIALSOA
&&
1212 msg
->counts
[DNS_SECTION_ANSWER
] == 0) {
1213 xfrin_log(xfr
, ISC_LOG_DEBUG(3),
1214 "empty answer section, retrying with AXFR");
1218 if (xfr
->reqtype
== dns_rdatatype_soa
&&
1219 (msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) {
1220 FAIL(DNS_R_NOTAUTHORITATIVE
);
1224 result
= dns_message_checksig(msg
, dns_zone_getview(xfr
->zone
));
1225 if (result
!= ISC_R_SUCCESS
) {
1226 xfrin_log(xfr
, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1227 isc_result_totext(result
));
1231 for (result
= dns_message_firstname(msg
, DNS_SECTION_ANSWER
);
1232 result
== ISC_R_SUCCESS
;
1233 result
= dns_message_nextname(msg
, DNS_SECTION_ANSWER
))
1235 dns_rdataset_t
*rds
;
1238 dns_message_currentname(msg
, DNS_SECTION_ANSWER
, &name
);
1239 for (rds
= ISC_LIST_HEAD(name
->list
);
1241 rds
= ISC_LIST_NEXT(rds
, link
))
1243 for (result
= dns_rdataset_first(rds
);
1244 result
== ISC_R_SUCCESS
;
1245 result
= dns_rdataset_next(rds
))
1247 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1248 dns_rdataset_current(rds
, &rdata
);
1249 CHECK(xfr_rr(xfr
, name
, rds
->ttl
, &rdata
));
1253 if (result
!= ISC_R_NOMORE
)
1256 if (dns_message_gettsig(msg
, &tsigowner
) != NULL
) {
1258 * Reset the counter.
1263 * Free the last tsig, if there is one.
1265 if (xfr
->lasttsig
!= NULL
)
1266 isc_buffer_free(&xfr
->lasttsig
);
1269 * Update the last tsig pointer.
1271 CHECK(dns_message_getquerytsig(msg
, xfr
->mctx
,
1274 } else if (dns_message_gettsigkey(msg
) != NULL
) {
1276 if (xfr
->sincetsig
> 100 ||
1277 xfr
->nmsg
== 0 || xfr
->state
== XFRST_END
)
1279 result
= DNS_R_EXPECTEDTSIG
;
1285 * Update the number of messages received.
1290 * Copy the context back.
1292 xfr
->tsigctx
= msg
->tsigctx
;
1294 dns_message_destroy(&msg
);
1296 if (xfr
->state
== XFRST_GOTSOA
) {
1297 xfr
->reqtype
= dns_rdatatype_axfr
;
1298 xfr
->state
= XFRST_INITIALSOA
;
1299 CHECK(xfrin_send_request(xfr
));
1300 } else if (xfr
->state
== XFRST_END
) {
1302 * Inform the caller we succeeded.
1304 if (xfr
->done
!= NULL
) {
1305 (xfr
->done
)(xfr
->zone
, ISC_R_SUCCESS
);
1309 * We should have no outstanding events at this
1310 * point, thus maybe_free() should succeed.
1312 xfr
->shuttingdown
= ISC_TRUE
;
1316 * Read the next message.
1318 CHECK(dns_tcpmsg_readmessage(&xfr
->tcpmsg
, xfr
->task
,
1319 xfrin_recv_done
, xfr
));
1326 dns_message_destroy(&msg
);
1327 if (result
!= ISC_R_SUCCESS
)
1328 xfrin_fail(xfr
, result
, "failed while receiving responses");
1332 xfrin_timeout(isc_task_t
*task
, isc_event_t
*event
) {
1333 dns_xfrin_ctx_t
*xfr
= (dns_xfrin_ctx_t
*) event
->ev_arg
;
1335 REQUIRE(VALID_XFRIN(xfr
));
1339 isc_event_free(&event
);
1341 * This will log "giving up: timeout".
1343 xfrin_fail(xfr
, ISC_R_TIMEDOUT
, "giving up");
1347 maybe_free(dns_xfrin_ctx_t
*xfr
) {
1348 REQUIRE(VALID_XFRIN(xfr
));
1350 if (! xfr
->shuttingdown
|| xfr
->refcount
!= 0 ||
1351 xfr
->connects
!= 0 || xfr
->sends
!= 0 ||
1355 xfrin_log(xfr
, ISC_LOG_INFO
, "end of transfer");
1357 if (xfr
->socket
!= NULL
)
1358 isc_socket_detach(&xfr
->socket
);
1360 if (xfr
->timer
!= NULL
)
1361 isc_timer_detach(&xfr
->timer
);
1363 if (xfr
->task
!= NULL
)
1364 isc_task_detach(&xfr
->task
);
1366 if (xfr
->tsigkey
!= NULL
)
1367 dns_tsigkey_detach(&xfr
->tsigkey
);
1369 if (xfr
->lasttsig
!= NULL
)
1370 isc_buffer_free(&xfr
->lasttsig
);
1372 dns_diff_clear(&xfr
->diff
);
1374 if (xfr
->ixfr
.journal
!= NULL
)
1375 dns_journal_destroy(&xfr
->ixfr
.journal
);
1377 if (xfr
->axfr
.add_private
!= NULL
)
1378 (void)dns_db_endload(xfr
->db
, &xfr
->axfr
.add_private
);
1380 if (xfr
->tcpmsg_valid
)
1381 dns_tcpmsg_invalidate(&xfr
->tcpmsg
);
1383 if ((xfr
->name
.attributes
& DNS_NAMEATTR_DYNAMIC
) != 0)
1384 dns_name_free(&xfr
->name
, xfr
->mctx
);
1386 if (xfr
->ver
!= NULL
)
1387 dns_db_closeversion(xfr
->db
, &xfr
->ver
, ISC_FALSE
);
1389 if (xfr
->db
!= NULL
)
1390 dns_db_detach(&xfr
->db
);
1392 if (xfr
->zone
!= NULL
)
1393 dns_zone_idetach(&xfr
->zone
);
1395 isc_mem_put(xfr
->mctx
, xfr
, sizeof(*xfr
));
1399 * Log incoming zone transfer messages in a format like
1400 * transfer of <zone> from <address>: <message>
1403 xfrin_logv(int level
, dns_name_t
*zonename
, dns_rdataclass_t rdclass
,
1404 isc_sockaddr_t
*masteraddr
, const char *fmt
, va_list ap
)
1406 char zntext
[DNS_NAME_FORMATSIZE
];
1407 char mastertext
[ISC_SOCKADDR_FORMATSIZE
];
1408 char classtext
[DNS_RDATACLASS_FORMATSIZE
];
1411 dns_name_format(zonename
, zntext
, sizeof(zntext
));
1412 dns_rdataclass_format(rdclass
, classtext
, sizeof(classtext
));
1413 isc_sockaddr_format(masteraddr
, mastertext
, sizeof(mastertext
));
1414 vsnprintf(msgtext
, sizeof(msgtext
), fmt
, ap
);
1416 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_XFER_IN
,
1417 DNS_LOGMODULE_XFER_IN
, level
,
1418 "transfer of '%s/%s' from %s: %s",
1419 zntext
, classtext
, mastertext
, msgtext
);
1423 * Logging function for use when a xfrin_ctx_t has not yet been created.
1427 xfrin_log1(int level
, dns_name_t
*zonename
, dns_rdataclass_t rdclass
,
1428 isc_sockaddr_t
*masteraddr
, const char *fmt
, ...)
1432 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
1436 xfrin_logv(level
, zonename
, rdclass
, masteraddr
, fmt
, ap
);
1441 * Logging function for use when there is a xfrin_ctx_t.
1445 xfrin_log(dns_xfrin_ctx_t
*xfr
, int level
, const char *fmt
, ...)
1449 if (isc_log_wouldlog(dns_lctx
, level
) == ISC_FALSE
)
1453 xfrin_logv(level
, &xfr
->name
, xfr
->rdclass
, &xfr
->masteraddr
, fmt
, ap
);