2 * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
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.
92 * Incoming zone transfer context.
95 struct dns_xfrin_ctx {
104 isc_socketmgr_t *socketmgr;
106 int connects; /*%< Connect in progress */
107 int sends; /*%< Send in progress */
108 int recvs; /*%< Receive in progress */
109 isc_boolean_t shuttingdown;
111 dns_name_t name; /*%< Name of zone to transfer */
112 dns_rdataclass_t rdclass;
114 isc_boolean_t checkid;
118 * Requested transfer type (dns_rdatatype_axfr or
119 * dns_rdatatype_ixfr). The actual transfer type
120 * may differ due to IXFR->AXFR fallback.
122 dns_rdatatype_t reqtype;
124 isc_sockaddr_t masteraddr;
125 isc_sockaddr_t sourceaddr;
126 isc_socket_t *socket;
128 /*% Buffer for IXFR/AXFR request message */
129 isc_buffer_t qbuffer;
130 unsigned char qbuffer_data[512];
132 /*% Incoming reply TCP message */
134 isc_boolean_t tcpmsg_valid;
137 dns_dbversion_t *ver;
138 dns_diff_t diff; /*%< Pending database changes */
139 int difflen; /*%< Number of pending tuples */
142 isc_uint32_t end_serial;
143 isc_boolean_t is_ixfr;
145 unsigned int nmsg; /*%< Number of messages recvd */
146 unsigned int nrecs; /*%< Number of records recvd */
147 isc_uint64_t nbytes; /*%< Number of bytes received */
149 isc_time_t start; /*%< Start time of the transfer */
150 isc_time_t end; /*%< End time of the transfer */
152 dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
153 isc_buffer_t *lasttsig; /*%< The last TSIG */
154 dst_context_t *tsigctx; /*%< TSIG verification context */
155 unsigned int sincetsig; /*%< recvd since the last TSIG */
156 dns_xfrindone_t done;
159 * AXFR- and IXFR-specific data. Only one is used at a time
160 * according to the is_ixfr flag, so this could be a union,
161 * but keeping them separate makes it a bit simpler to clean
162 * things up when destroying the context.
165 dns_addrdatasetfunc_t add_func;
166 dns_dbload_t *add_private;
170 isc_uint32_t request_serial;
171 isc_uint32_t current_serial;
172 dns_journal_t *journal;
177 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
178 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
180 /**************************************************************************/
182 * Forward declarations.
186 xfrin_create(isc_mem_t *mctx,
190 isc_timermgr_t *timermgr,
191 isc_socketmgr_t *socketmgr,
192 dns_name_t *zonename,
193 dns_rdataclass_t rdclass,
194 dns_rdatatype_t reqtype,
195 isc_sockaddr_t *masteraddr,
196 isc_sockaddr_t *sourceaddr,
197 dns_tsigkey_t *tsigkey,
198 dns_xfrin_ctx_t **xfrp);
200 static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
201 static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
202 static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
203 dns_name_t *name, dns_ttl_t ttl,
205 static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
206 static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
207 static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr);
209 static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
210 static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
211 static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
212 dns_name_t *name, dns_ttl_t ttl,
214 static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
216 static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
217 isc_uint32_t ttl, dns_rdata_t *rdata);
219 static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
221 static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
222 static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
223 static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
224 static void xfrin_sendlen_done(isc_task_t *task, isc_event_t *event);
225 static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
226 static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
228 static void maybe_free(dns_xfrin_ctx_t *xfr);
231 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
233 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
236 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
237 const char *fmt, va_list ap)
238 ISC_FORMAT_PRINTF(4, 0);
241 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
242 const char *fmt, ...)
243 ISC_FORMAT_PRINTF(4, 5);
246 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
247 ISC_FORMAT_PRINTF(3, 4);
249 /**************************************************************************/
255 axfr_init(dns_xfrin_ctx_t *xfr) {
258 xfr->is_ixfr = ISC_FALSE;
261 dns_db_detach(&xfr->db);
263 CHECK(axfr_makedb(xfr, &xfr->db));
264 CHECK(dns_db_beginload(xfr->db, &xfr->axfr.add_func,
265 &xfr->axfr.add_private));
266 result = ISC_R_SUCCESS;
272 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
273 return (dns_db_create(xfr->mctx, /* XXX */
274 "rbt", /* XXX guess */
278 0, NULL, /* XXX guess */
283 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
284 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
288 dns_difftuple_t *tuple = NULL;
290 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
291 CHECK(dns_difftuple_create(xfr->diff.mctx, op,
292 name, ttl, rdata, &tuple));
293 dns_diff_append(&xfr->diff, &tuple);
294 if (++xfr->difflen > 100)
295 CHECK(axfr_apply(xfr));
296 result = ISC_R_SUCCESS;
302 * Store a set of AXFR RRs in the database.
305 axfr_apply(dns_xfrin_ctx_t *xfr) {
308 CHECK(dns_diff_load(&xfr->diff,
309 xfr->axfr.add_func, xfr->axfr.add_private));
311 dns_diff_clear(&xfr->diff);
312 result = ISC_R_SUCCESS;
318 axfr_commit(dns_xfrin_ctx_t *xfr) {
321 CHECK(axfr_apply(xfr));
322 CHECK(dns_db_endload(xfr->db, &xfr->axfr.add_private));
324 result = ISC_R_SUCCESS;
330 axfr_finalize(dns_xfrin_ctx_t *xfr) {
333 CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE));
335 result = ISC_R_SUCCESS;
340 /**************************************************************************/
346 ixfr_init(dns_xfrin_ctx_t *xfr) {
350 if (xfr->reqtype != dns_rdatatype_ixfr) {
351 xfrin_log(xfr, ISC_LOG_ERROR,
352 "got incremental response to AXFR request");
353 return (DNS_R_FORMERR);
356 xfr->is_ixfr = ISC_TRUE;
357 INSIST(xfr->db != NULL);
360 journalfile = dns_zone_getjournal(xfr->zone);
361 if (journalfile != NULL)
362 CHECK(dns_journal_open(xfr->mctx, journalfile,
363 ISC_TRUE, &xfr->ixfr.journal));
365 result = ISC_R_SUCCESS;
371 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
372 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
376 dns_difftuple_t *tuple = NULL;
377 if (op == DNS_DIFFOP_ADD)
378 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
379 CHECK(dns_difftuple_create(xfr->diff.mctx, op,
380 name, ttl, rdata, &tuple));
381 dns_diff_append(&xfr->diff, &tuple);
382 if (++xfr->difflen > 100)
383 CHECK(ixfr_apply(xfr));
384 result = ISC_R_SUCCESS;
390 * Apply a set of IXFR changes to the database.
393 ixfr_apply(dns_xfrin_ctx_t *xfr) {
396 if (xfr->ver == NULL) {
397 CHECK(dns_db_newversion(xfr->db, &xfr->ver));
398 if (xfr->ixfr.journal != NULL)
399 CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
401 CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
402 if (xfr->ixfr.journal != NULL) {
403 result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
404 if (result != ISC_R_SUCCESS)
407 dns_diff_clear(&xfr->diff);
409 result = ISC_R_SUCCESS;
415 ixfr_commit(dns_xfrin_ctx_t *xfr) {
418 CHECK(ixfr_apply(xfr));
419 if (xfr->ver != NULL) {
420 /* XXX enter ready-to-commit state here */
421 if (xfr->ixfr.journal != NULL)
422 CHECK(dns_journal_commit(xfr->ixfr.journal));
423 dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE);
424 dns_zone_markdirty(xfr->zone);
426 result = ISC_R_SUCCESS;
431 /**************************************************************************/
433 * Common AXFR/IXFR protocol code
437 * Handle a single incoming resource record according to the current
441 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
448 if (rdata->type == dns_rdatatype_none ||
449 dns_rdatatype_ismeta(rdata->type))
453 switch (xfr->state) {
455 if (rdata->type != dns_rdatatype_soa) {
456 xfrin_log(xfr, ISC_LOG_ERROR,
457 "non-SOA response to SOA query");
460 xfr->end_serial = dns_soa_getserial(rdata);
461 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
462 !dns_zone_isforced(xfr->zone)) {
463 xfrin_log(xfr, ISC_LOG_DEBUG(3),
464 "requested serial %u, "
465 "master has %u, not updating",
466 xfr->ixfr.request_serial, xfr->end_serial);
467 FAIL(DNS_R_UPTODATE);
469 xfr->state = XFRST_GOTSOA;
474 * Skip other records in the answer section.
478 case XFRST_INITIALSOA:
479 if (rdata->type != dns_rdatatype_soa) {
480 xfrin_log(xfr, ISC_LOG_ERROR,
481 "first RR in zone transfer must be SOA");
485 * Remember the serial number in the initial SOA.
486 * We need it to recognize the end of an IXFR.
488 xfr->end_serial = dns_soa_getserial(rdata);
489 if (xfr->reqtype == dns_rdatatype_ixfr &&
490 ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial)
491 && !dns_zone_isforced(xfr->zone))
494 * This must be the single SOA record that is
495 * sent when the current version on the master
496 * is not newer than the version in the request.
498 xfrin_log(xfr, ISC_LOG_DEBUG(3),
499 "requested serial %u, "
500 "master has %u, not updating",
501 xfr->ixfr.request_serial, xfr->end_serial);
502 FAIL(DNS_R_UPTODATE);
504 if (xfr->reqtype == dns_rdatatype_axfr)
505 xfr->checkid = ISC_FALSE;
506 xfr->state = XFRST_FIRSTDATA;
509 case XFRST_FIRSTDATA:
511 * If the transfer begins with one SOA record, it is an AXFR,
512 * if it begins with two SOAs, it is an IXFR.
514 if (xfr->reqtype == dns_rdatatype_ixfr &&
515 rdata->type == dns_rdatatype_soa &&
516 xfr->ixfr.request_serial == dns_soa_getserial(rdata)) {
517 xfrin_log(xfr, ISC_LOG_DEBUG(3),
518 "got incremental response");
519 CHECK(ixfr_init(xfr));
520 xfr->state = XFRST_IXFR_DELSOA;
522 xfrin_log(xfr, ISC_LOG_DEBUG(3),
523 "got nonincremental response");
524 CHECK(axfr_init(xfr));
525 xfr->state = XFRST_AXFR;
529 case XFRST_IXFR_DELSOA:
530 INSIST(rdata->type == dns_rdatatype_soa);
531 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
532 xfr->state = XFRST_IXFR_DEL;
536 if (rdata->type == dns_rdatatype_soa) {
537 isc_uint32_t soa_serial = dns_soa_getserial(rdata);
538 xfr->state = XFRST_IXFR_ADDSOA;
539 xfr->ixfr.current_serial = soa_serial;
542 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
545 case XFRST_IXFR_ADDSOA:
546 INSIST(rdata->type == dns_rdatatype_soa);
547 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
548 xfr->state = XFRST_IXFR_ADD;
552 if (rdata->type == dns_rdatatype_soa) {
553 isc_uint32_t soa_serial = dns_soa_getserial(rdata);
554 if (soa_serial == xfr->end_serial) {
555 CHECK(ixfr_commit(xfr));
556 xfr->state = XFRST_IXFR_END;
558 } else if (soa_serial != xfr->ixfr.current_serial) {
559 xfrin_log(xfr, ISC_LOG_ERROR,
561 "expected serial %u, got %u",
562 xfr->ixfr.current_serial, soa_serial);
565 CHECK(ixfr_commit(xfr));
566 xfr->state = XFRST_IXFR_DELSOA;
570 if (rdata->type == dns_rdatatype_ns &&
571 dns_name_iswildcard(name))
572 FAIL(DNS_R_INVALIDNS);
573 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
578 * Old BINDs sent cross class A records for non IN classes.
580 if (rdata->type == dns_rdatatype_a &&
581 rdata->rdclass != xfr->rdclass &&
582 xfr->rdclass != dns_rdataclass_in)
584 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
585 if (rdata->type == dns_rdatatype_soa) {
586 CHECK(axfr_commit(xfr));
587 xfr->state = XFRST_AXFR_END;
593 FAIL(DNS_R_EXTRADATA);
598 result = ISC_R_SUCCESS;
604 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
605 isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
606 isc_mem_t *mctx, isc_timermgr_t *timermgr,
607 isc_socketmgr_t *socketmgr, isc_task_t *task,
608 dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
610 isc_sockaddr_t sourceaddr;
612 switch (isc_sockaddr_pf(masteraddr)) {
614 sourceaddr = *dns_zone_getxfrsource4(zone);
617 sourceaddr = *dns_zone_getxfrsource6(zone);
623 return(dns_xfrin_create2(zone, xfrtype, masteraddr, &sourceaddr,
624 tsigkey, mctx, timermgr, socketmgr,
629 dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
630 isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
631 dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
632 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
633 isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
635 dns_name_t *zonename = dns_zone_getorigin(zone);
636 dns_xfrin_ctx_t *xfr = NULL;
640 REQUIRE(xfrp != NULL && *xfrp == NULL);
642 (void)dns_zone_getdb(zone, &db);
644 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
647 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
648 dns_zone_getclass(zone), xfrtype, masteraddr,
649 sourceaddr, tsigkey, &xfr));
651 CHECK(xfrin_start(xfr));
660 if (result != ISC_R_SUCCESS) {
661 char zonetext[DNS_NAME_MAXTEXT+32];
662 dns_zone_name(zone, zonetext, sizeof(zonetext));
663 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
664 "zone transfer setup failed");
670 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
671 if (! xfr->shuttingdown)
672 xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
676 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
677 REQUIRE(target != NULL && *target == NULL);
683 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
684 dns_xfrin_ctx_t *xfr = *xfrp;
685 INSIST(xfr->refcount > 0);
692 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
693 if (xfr->connects > 0) {
694 isc_socket_cancel(xfr->socket, xfr->task,
695 ISC_SOCKCANCEL_CONNECT);
696 } else if (xfr->recvs > 0) {
697 dns_tcpmsg_cancelread(&xfr->tcpmsg);
698 } else if (xfr->sends > 0) {
699 isc_socket_cancel(xfr->socket, xfr->task,
700 ISC_SOCKCANCEL_SEND);
705 xfrin_reset(dns_xfrin_ctx_t *xfr) {
706 REQUIRE(VALID_XFRIN(xfr));
708 xfrin_log(xfr, ISC_LOG_INFO, "resetting");
712 if (xfr->socket != NULL)
713 isc_socket_detach(&xfr->socket);
715 if (xfr->lasttsig != NULL)
716 isc_buffer_free(&xfr->lasttsig);
718 dns_diff_clear(&xfr->diff);
721 if (xfr->ixfr.journal != NULL)
722 dns_journal_destroy(&xfr->ixfr.journal);
724 if (xfr->axfr.add_private != NULL) {
725 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
726 xfr->axfr.add_func = NULL;
729 if (xfr->tcpmsg_valid) {
730 dns_tcpmsg_invalidate(&xfr->tcpmsg);
731 xfr->tcpmsg_valid = ISC_FALSE;
734 if (xfr->ver != NULL)
735 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
740 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
741 if (result != DNS_R_UPTODATE) {
742 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
743 msg, isc_result_totext(result));
745 /* Pass special result code to force AXFR retry */
746 result = DNS_R_BADIXFR;
752 if (xfr->ixfr.journal != NULL)
753 dns_journal_destroy(&xfr->ixfr.journal);
754 if (xfr->done != NULL) {
755 (xfr->done)(xfr->zone, result);
758 xfr->shuttingdown = ISC_TRUE;
763 xfrin_create(isc_mem_t *mctx,
767 isc_timermgr_t *timermgr,
768 isc_socketmgr_t *socketmgr,
769 dns_name_t *zonename,
770 dns_rdataclass_t rdclass,
771 dns_rdatatype_t reqtype,
772 isc_sockaddr_t *masteraddr,
773 isc_sockaddr_t *sourceaddr,
774 dns_tsigkey_t *tsigkey,
775 dns_xfrin_ctx_t **xfrp)
777 dns_xfrin_ctx_t *xfr = NULL;
781 xfr = isc_mem_get(mctx, sizeof(*xfr));
783 return (ISC_R_NOMEMORY);
787 dns_zone_iattach(zone, &xfr->zone);
789 isc_task_attach(task, &xfr->task);
791 xfr->socketmgr = socketmgr;
797 xfr->shuttingdown = ISC_FALSE;
799 dns_name_init(&xfr->name, NULL);
800 xfr->rdclass = rdclass;
801 isc_random_get(&tmp);
802 xfr->checkid = ISC_TRUE;
803 xfr->id = (isc_uint16_t)(tmp & 0xffff);
804 xfr->reqtype = reqtype;
811 xfr->tcpmsg_valid = ISC_FALSE;
815 dns_db_attach(db, &xfr->db);
817 dns_diff_init(xfr->mctx, &xfr->diff);
820 if (reqtype == dns_rdatatype_soa)
821 xfr->state = XFRST_SOAQUERY;
823 xfr->state = XFRST_INITIALSOA;
829 isc_time_now(&xfr->start);
833 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
834 xfr->lasttsig = NULL;
837 xfr->is_ixfr = ISC_FALSE;
839 /* ixfr.request_serial */
840 /* ixfr.current_serial */
841 xfr->ixfr.journal = NULL;
843 xfr->axfr.add_func = NULL;
844 xfr->axfr.add_private = NULL;
846 CHECK(dns_name_dup(zonename, mctx, &xfr->name));
848 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
849 task, xfrin_timeout, xfr, &xfr->timer));
850 CHECK(dns_timer_setidle(xfr->timer,
851 dns_zone_getmaxxfrin(xfr->zone),
852 dns_zone_getidlein(xfr->zone),
855 xfr->masteraddr = *masteraddr;
857 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
858 xfr->sourceaddr = *sourceaddr;
859 isc_sockaddr_setport(&xfr->sourceaddr, 0);
861 isc_buffer_init(&xfr->qbuffer, xfr->qbuffer_data,
862 sizeof(xfr->qbuffer_data));
864 xfr->magic = XFRIN_MAGIC;
866 return (ISC_R_SUCCESS);
869 if (xfr->timer != NULL)
870 isc_timer_detach(&xfr->timer);
871 if (dns_name_dynamic(&xfr->name))
872 dns_name_free(&xfr->name, xfr->mctx);
873 if (xfr->tsigkey != NULL)
874 dns_tsigkey_detach(&xfr->tsigkey);
876 dns_db_detach(&xfr->db);
877 isc_task_detach(&xfr->task);
878 dns_zone_idetach(&xfr->zone);
879 isc_mem_put(mctx, xfr, sizeof(*xfr));
885 xfrin_start(dns_xfrin_ctx_t *xfr) {
887 CHECK(isc_socket_create(xfr->socketmgr,
888 isc_sockaddr_pf(&xfr->sourceaddr),
891 isc_socket_setname(xfr->socket, "xfrin", NULL);
892 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
893 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
894 ISC_SOCKET_REUSEADDRESS));
896 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
897 xfrin_connect_done, xfr));
899 return (ISC_R_SUCCESS);
901 xfrin_fail(xfr, result, "failed setting up socket");
905 /* XXX the resolver could use this, too */
908 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
910 isc_boolean_t cleanup_cctx = ISC_FALSE;
913 CHECK(dns_compress_init(&cctx, -1, mctx));
914 cleanup_cctx = ISC_TRUE;
915 CHECK(dns_message_renderbegin(msg, &cctx, buf));
916 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
917 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
918 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
919 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
920 CHECK(dns_message_renderend(msg));
921 result = ISC_R_SUCCESS;
924 dns_compress_invalidate(&cctx);
929 * A connection has been established.
932 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
933 isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
934 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
935 isc_result_t result = cev->result;
936 char sourcetext[ISC_SOCKADDR_FORMATSIZE];
937 isc_sockaddr_t sockaddr;
939 REQUIRE(VALID_XFRIN(xfr));
943 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
944 isc_event_free(&event);
947 if (xfr->shuttingdown) {
952 if (result != ISC_R_SUCCESS) {
953 dns_zonemgr_t * zmgr = dns_zone_getmgr(xfr->zone);
958 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
959 &xfr->sourceaddr, &now);
964 result = isc_socket_getsockname(xfr->socket, &sockaddr);
965 if (result == ISC_R_SUCCESS) {
966 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
968 strcpy(sourcetext, "<UNKNOWN>");
969 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext);
971 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
972 xfr->tcpmsg_valid = ISC_TRUE;
974 CHECK(xfrin_send_request(xfr));
976 if (result != ISC_R_SUCCESS)
977 xfrin_fail(xfr, result, "failed to connect");
981 * Convert a tuple into a dns_name_t suitable for inserting
982 * into the given dns_message_t.
985 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
988 dns_rdata_t *rdata = NULL;
989 dns_rdatalist_t *rdl = NULL;
990 dns_rdataset_t *rds = NULL;
991 dns_name_t *name = NULL;
993 REQUIRE(target != NULL && *target == NULL);
995 CHECK(dns_message_gettemprdata(msg, &rdata));
996 dns_rdata_init(rdata);
997 dns_rdata_clone(&tuple->rdata, rdata);
999 CHECK(dns_message_gettemprdatalist(msg, &rdl));
1000 dns_rdatalist_init(rdl);
1001 rdl->type = tuple->rdata.type;
1002 rdl->rdclass = tuple->rdata.rdclass;
1003 rdl->ttl = tuple->ttl;
1004 ISC_LIST_APPEND(rdl->rdata, rdata, link);
1006 CHECK(dns_message_gettemprdataset(msg, &rds));
1007 dns_rdataset_init(rds);
1008 CHECK(dns_rdatalist_tordataset(rdl, rds));
1010 CHECK(dns_message_gettempname(msg, &name));
1011 dns_name_init(name, NULL);
1012 dns_name_clone(&tuple->name, name);
1013 ISC_LIST_APPEND(name->list, rds, link);
1016 return (ISC_R_SUCCESS);
1021 dns_rdataset_disassociate(rds);
1022 dns_message_puttemprdataset(msg, &rds);
1025 ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1026 dns_message_puttemprdatalist(msg, &rdl);
1029 dns_message_puttemprdata(msg, &rdata);
1036 * Build an *XFR request and send its length prefix.
1039 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1040 isc_result_t result;
1041 isc_region_t region;
1042 isc_region_t lregion;
1043 dns_rdataset_t *qrdataset = NULL;
1044 dns_message_t *msg = NULL;
1045 unsigned char length[2];
1046 dns_difftuple_t *soatuple = NULL;
1047 dns_name_t *qname = NULL;
1048 dns_dbversion_t *ver = NULL;
1049 dns_name_t *msgsoaname = NULL;
1051 /* Create the request message */
1052 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
1053 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1055 /* Create a name for the question section. */
1056 CHECK(dns_message_gettempname(msg, &qname));
1057 dns_name_init(qname, NULL);
1058 dns_name_clone(&xfr->name, qname);
1060 /* Formulate the question and attach it to the question name. */
1061 CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1062 dns_rdataset_init(qrdataset);
1063 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1064 ISC_LIST_APPEND(qname->list, qrdataset, link);
1067 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1070 if (xfr->reqtype == dns_rdatatype_ixfr) {
1071 /* Get the SOA and add it to the authority section. */
1072 /* XXX is using the current version the right thing? */
1073 dns_db_currentversion(xfr->db, &ver);
1074 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1075 DNS_DIFFOP_EXISTS, &soatuple));
1076 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1077 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1078 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1079 "requesting IXFR for serial %u",
1080 xfr->ixfr.request_serial);
1082 CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1083 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1084 } else if (xfr->reqtype == dns_rdatatype_soa)
1085 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1086 &xfr->ixfr.request_serial));
1088 xfr->checkid = ISC_TRUE;
1093 isc_time_now(&xfr->start);
1095 if (xfr->tsigctx != NULL)
1096 dst_context_destroy(&xfr->tsigctx);
1098 CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1101 * Free the last tsig, if there is one.
1103 if (xfr->lasttsig != NULL)
1104 isc_buffer_free(&xfr->lasttsig);
1107 * Save the query TSIG and don't let message_destroy free it.
1109 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1111 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1112 INSIST(region.length <= 65535);
1114 length[0] = region.length >> 8;
1115 length[1] = region.length & 0xFF;
1116 lregion.base = length;
1118 CHECK(isc_socket_send(xfr->socket, &lregion, xfr->task,
1119 xfrin_sendlen_done, xfr));
1124 dns_message_puttempname(msg, &qname);
1125 if (qrdataset != NULL)
1126 dns_message_puttemprdataset(msg, &qrdataset);
1128 dns_message_destroy(&msg);
1129 if (soatuple != NULL)
1130 dns_difftuple_free(&soatuple);
1132 dns_db_closeversion(xfr->db, &ver, ISC_FALSE);
1136 /* XXX there should be library support for sending DNS TCP messages */
1139 xfrin_sendlen_done(isc_task_t *task, isc_event_t *event) {
1140 isc_socketevent_t *sev = (isc_socketevent_t *) event;
1141 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1142 isc_result_t evresult = sev->result;
1143 isc_result_t result;
1144 isc_region_t region;
1146 REQUIRE(VALID_XFRIN(xfr));
1150 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1151 isc_event_free(&event);
1154 if (xfr->shuttingdown) {
1159 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request length prefix");
1162 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1163 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task,
1164 xfrin_send_done, xfr));
1167 if (result != ISC_R_SUCCESS)
1168 xfrin_fail(xfr, result, "failed sending request length prefix");
1173 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
1174 isc_socketevent_t *sev = (isc_socketevent_t *) event;
1175 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1176 isc_result_t result;
1178 REQUIRE(VALID_XFRIN(xfr));
1182 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1185 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1188 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1189 xfrin_recv_done, xfr));
1192 isc_event_free(&event);
1193 if (result != ISC_R_SUCCESS)
1194 xfrin_fail(xfr, result, "failed sending request data");
1199 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
1200 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
1201 isc_result_t result;
1202 dns_message_t *msg = NULL;
1204 dns_tcpmsg_t *tcpmsg;
1205 dns_name_t *tsigowner = NULL;
1207 REQUIRE(VALID_XFRIN(xfr));
1211 INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
1212 tcpmsg = ev->ev_sender;
1213 isc_event_free(&ev);
1216 if (xfr->shuttingdown) {
1221 CHECK(tcpmsg->result);
1223 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
1224 tcpmsg->buffer.used);
1226 CHECK(isc_timer_touch(xfr->timer));
1228 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
1230 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1231 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1233 msg->tsigctx = xfr->tsigctx;
1234 xfr->tsigctx = NULL;
1237 msg->tcp_continuation = 1;
1239 result = dns_message_parse(msg, &tcpmsg->buffer,
1240 DNS_MESSAGEPARSE_PRESERVEORDER);
1242 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1243 (xfr->checkid && msg->id != xfr->id)) {
1244 if (result == ISC_R_SUCCESS)
1245 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
1246 if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
1247 result = DNS_R_UNEXPECTEDID;
1248 if (xfr->reqtype == dns_rdatatype_axfr ||
1249 xfr->reqtype == dns_rdatatype_soa)
1251 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1252 isc_result_totext(result));
1254 dns_message_destroy(&msg);
1256 xfr->reqtype = dns_rdatatype_soa;
1257 xfr->state = XFRST_SOAQUERY;
1258 (void)xfrin_start(xfr);
1263 * Does the server know about IXFR? If it doesn't we will get
1264 * a message with a empty answer section or a potentially a CNAME /
1265 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1266 * if the first RR in the answer section is not a SOA record.
1268 if (xfr->reqtype == dns_rdatatype_ixfr &&
1269 xfr->state == XFRST_INITIALSOA &&
1270 msg->counts[DNS_SECTION_ANSWER] == 0) {
1271 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1272 "empty answer section, retrying with AXFR");
1276 if (xfr->reqtype == dns_rdatatype_soa &&
1277 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
1278 FAIL(DNS_R_NOTAUTHORITATIVE);
1282 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1283 if (result != ISC_R_SUCCESS) {
1284 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1285 isc_result_totext(result));
1289 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1290 result == ISC_R_SUCCESS;
1291 result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1293 dns_rdataset_t *rds;
1296 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1297 for (rds = ISC_LIST_HEAD(name->list);
1299 rds = ISC_LIST_NEXT(rds, link))
1301 for (result = dns_rdataset_first(rds);
1302 result == ISC_R_SUCCESS;
1303 result = dns_rdataset_next(rds))
1305 dns_rdata_t rdata = DNS_RDATA_INIT;
1306 dns_rdataset_current(rds, &rdata);
1307 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1311 if (result != ISC_R_NOMORE)
1314 if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1316 * Reset the counter.
1321 * Free the last tsig, if there is one.
1323 if (xfr->lasttsig != NULL)
1324 isc_buffer_free(&xfr->lasttsig);
1327 * Update the last tsig pointer.
1329 CHECK(dns_message_getquerytsig(msg, xfr->mctx,
1332 } else if (dns_message_gettsigkey(msg) != NULL) {
1334 if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1335 xfr->state == XFRST_AXFR_END ||
1336 xfr->state == XFRST_IXFR_END)
1338 result = DNS_R_EXPECTEDTSIG;
1344 * Update the number of messages received.
1349 * Update the number of bytes received.
1351 xfr->nbytes += tcpmsg->buffer.used;
1354 * Take the context back.
1356 INSIST(xfr->tsigctx == NULL);
1357 xfr->tsigctx = msg->tsigctx;
1358 msg->tsigctx = NULL;
1360 dns_message_destroy(&msg);
1362 switch (xfr->state) {
1364 xfr->reqtype = dns_rdatatype_axfr;
1365 xfr->state = XFRST_INITIALSOA;
1366 CHECK(xfrin_send_request(xfr));
1368 case XFRST_AXFR_END:
1369 CHECK(axfr_finalize(xfr));
1371 case XFRST_IXFR_END:
1373 * Close the journal.
1375 if (xfr->ixfr.journal != NULL)
1376 dns_journal_destroy(&xfr->ixfr.journal);
1379 * Inform the caller we succeeded.
1381 if (xfr->done != NULL) {
1382 (xfr->done)(xfr->zone, ISC_R_SUCCESS);
1386 * We should have no outstanding events at this
1387 * point, thus maybe_free() should succeed.
1389 xfr->shuttingdown = ISC_TRUE;
1394 * Read the next message.
1396 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1397 xfrin_recv_done, xfr));
1404 dns_message_destroy(&msg);
1405 if (result != ISC_R_SUCCESS)
1406 xfrin_fail(xfr, result, "failed while receiving responses");
1410 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
1411 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1413 REQUIRE(VALID_XFRIN(xfr));
1417 isc_event_free(&event);
1419 * This will log "giving up: timeout".
1421 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
1425 maybe_free(dns_xfrin_ctx_t *xfr) {
1427 isc_uint64_t persec;
1429 REQUIRE(VALID_XFRIN(xfr));
1431 if (! xfr->shuttingdown || xfr->refcount != 0 ||
1432 xfr->connects != 0 || xfr->sends != 0 ||
1437 * Calculate the length of time the transfer took,
1438 * and print a log message with the bytes and rate.
1440 isc_time_now(&xfr->end);
1441 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1444 persec = (xfr->nbytes * 1000) / msecs;
1445 xfrin_log(xfr, ISC_LOG_INFO,
1446 "Transfer completed: %d messages, %d records, "
1447 "%" ISC_PRINT_QUADFORMAT "u bytes, "
1448 "%u.%03u secs (%u bytes/sec)",
1449 xfr->nmsg, xfr->nrecs, xfr->nbytes,
1450 (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000),
1451 (unsigned int) persec);
1453 if (xfr->socket != NULL)
1454 isc_socket_detach(&xfr->socket);
1456 if (xfr->timer != NULL)
1457 isc_timer_detach(&xfr->timer);
1459 if (xfr->task != NULL)
1460 isc_task_detach(&xfr->task);
1462 if (xfr->tsigkey != NULL)
1463 dns_tsigkey_detach(&xfr->tsigkey);
1465 if (xfr->lasttsig != NULL)
1466 isc_buffer_free(&xfr->lasttsig);
1468 dns_diff_clear(&xfr->diff);
1470 if (xfr->ixfr.journal != NULL)
1471 dns_journal_destroy(&xfr->ixfr.journal);
1473 if (xfr->axfr.add_private != NULL)
1474 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
1476 if (xfr->tcpmsg_valid)
1477 dns_tcpmsg_invalidate(&xfr->tcpmsg);
1479 if (xfr->tsigctx != NULL)
1480 dst_context_destroy(&xfr->tsigctx);
1482 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
1483 dns_name_free(&xfr->name, xfr->mctx);
1485 if (xfr->ver != NULL)
1486 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
1488 if (xfr->db != NULL)
1489 dns_db_detach(&xfr->db);
1491 if (xfr->zone != NULL)
1492 dns_zone_idetach(&xfr->zone);
1494 isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));
1498 * Log incoming zone transfer messages in a format like
1499 * transfer of <zone> from <address>: <message>
1502 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1503 const char *fmt, va_list ap)
1505 char mastertext[ISC_SOCKADDR_FORMATSIZE];
1508 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
1509 vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
1511 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
1512 DNS_LOGMODULE_XFER_IN, level,
1513 "transfer of '%s' from %s: %s",
1514 zonetext, mastertext, msgtext);
1518 * Logging function for use when a xfrin_ctx_t has not yet been created.
1522 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1523 const char *fmt, ...)
1527 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1531 xfrin_logv(level, zonetext, masteraddr, fmt, ap);
1536 * Logging function for use when there is a xfrin_ctx_t.
1540 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
1543 char zonetext[DNS_NAME_MAXTEXT+32];
1545 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1548 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
1551 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);