2 * Copyright (C) 2004-2008, 2011-2013 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_recv_done(isc_task_t *task, isc_event_t *event);
225 static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
227 static void maybe_free(dns_xfrin_ctx_t *xfr);
230 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
232 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
235 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
236 const char *fmt, va_list ap)
237 ISC_FORMAT_PRINTF(4, 0);
240 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
241 const char *fmt, ...)
242 ISC_FORMAT_PRINTF(4, 5);
245 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
246 ISC_FORMAT_PRINTF(3, 4);
248 /**************************************************************************/
254 axfr_init(dns_xfrin_ctx_t *xfr) {
257 xfr->is_ixfr = ISC_FALSE;
260 dns_db_detach(&xfr->db);
262 CHECK(axfr_makedb(xfr, &xfr->db));
263 CHECK(dns_db_beginload(xfr->db, &xfr->axfr.add_func,
264 &xfr->axfr.add_private));
265 result = ISC_R_SUCCESS;
271 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
274 result = dns_db_create(xfr->mctx, /* XXX */
275 "rbt", /* XXX guess */
279 0, NULL, /* XXX guess */
281 if (result == ISC_R_SUCCESS)
282 result = dns_zone_rpz_enable_db(xfr->zone, *dbp);
287 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
288 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
292 dns_difftuple_t *tuple = NULL;
294 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
295 CHECK(dns_difftuple_create(xfr->diff.mctx, op,
296 name, ttl, rdata, &tuple));
297 dns_diff_append(&xfr->diff, &tuple);
298 if (++xfr->difflen > 100)
299 CHECK(axfr_apply(xfr));
300 result = ISC_R_SUCCESS;
306 * Store a set of AXFR RRs in the database.
309 axfr_apply(dns_xfrin_ctx_t *xfr) {
312 CHECK(dns_diff_load(&xfr->diff,
313 xfr->axfr.add_func, xfr->axfr.add_private));
315 dns_diff_clear(&xfr->diff);
316 result = ISC_R_SUCCESS;
322 axfr_commit(dns_xfrin_ctx_t *xfr) {
325 CHECK(axfr_apply(xfr));
326 CHECK(dns_db_endload(xfr->db, &xfr->axfr.add_private));
328 result = ISC_R_SUCCESS;
334 axfr_finalize(dns_xfrin_ctx_t *xfr) {
337 CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE));
339 result = ISC_R_SUCCESS;
344 /**************************************************************************/
350 ixfr_init(dns_xfrin_ctx_t *xfr) {
354 if (xfr->reqtype != dns_rdatatype_ixfr) {
355 xfrin_log(xfr, ISC_LOG_ERROR,
356 "got incremental response to AXFR request");
357 return (DNS_R_FORMERR);
360 xfr->is_ixfr = ISC_TRUE;
361 INSIST(xfr->db != NULL);
364 journalfile = dns_zone_getjournal(xfr->zone);
365 if (journalfile != NULL)
366 CHECK(dns_journal_open(xfr->mctx, journalfile,
367 DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
369 result = ISC_R_SUCCESS;
375 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
376 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
380 dns_difftuple_t *tuple = NULL;
381 if (op == DNS_DIFFOP_ADD)
382 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
383 CHECK(dns_difftuple_create(xfr->diff.mctx, op,
384 name, ttl, rdata, &tuple));
385 dns_diff_append(&xfr->diff, &tuple);
386 if (++xfr->difflen > 100)
387 CHECK(ixfr_apply(xfr));
388 result = ISC_R_SUCCESS;
394 * Apply a set of IXFR changes to the database.
397 ixfr_apply(dns_xfrin_ctx_t *xfr) {
400 if (xfr->ver == NULL) {
401 CHECK(dns_db_newversion(xfr->db, &xfr->ver));
402 if (xfr->ixfr.journal != NULL)
403 CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
405 CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
406 if (xfr->ixfr.journal != NULL) {
407 result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
408 if (result != ISC_R_SUCCESS)
411 dns_diff_clear(&xfr->diff);
413 result = ISC_R_SUCCESS;
419 ixfr_commit(dns_xfrin_ctx_t *xfr) {
422 CHECK(ixfr_apply(xfr));
423 if (xfr->ver != NULL) {
424 /* XXX enter ready-to-commit state here */
425 if (xfr->ixfr.journal != NULL)
426 CHECK(dns_journal_commit(xfr->ixfr.journal));
427 dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE);
428 dns_zone_markdirty(xfr->zone);
430 result = ISC_R_SUCCESS;
435 /**************************************************************************/
437 * Common AXFR/IXFR protocol code
441 * Handle a single incoming resource record according to the current
445 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
452 if (rdata->type == dns_rdatatype_none ||
453 dns_rdatatype_ismeta(rdata->type))
457 switch (xfr->state) {
459 if (rdata->type != dns_rdatatype_soa) {
460 xfrin_log(xfr, ISC_LOG_ERROR,
461 "non-SOA response to SOA query");
464 xfr->end_serial = dns_soa_getserial(rdata);
465 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
466 !dns_zone_isforced(xfr->zone)) {
467 xfrin_log(xfr, ISC_LOG_DEBUG(3),
468 "requested serial %u, "
469 "master has %u, not updating",
470 xfr->ixfr.request_serial, xfr->end_serial);
471 FAIL(DNS_R_UPTODATE);
473 xfr->state = XFRST_GOTSOA;
478 * Skip other records in the answer section.
482 case XFRST_INITIALSOA:
483 if (rdata->type != dns_rdatatype_soa) {
484 xfrin_log(xfr, ISC_LOG_ERROR,
485 "first RR in zone transfer must be SOA");
489 * Remember the serial number in the initial SOA.
490 * We need it to recognize the end of an IXFR.
492 xfr->end_serial = dns_soa_getserial(rdata);
493 if (xfr->reqtype == dns_rdatatype_ixfr &&
494 ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial)
495 && !dns_zone_isforced(xfr->zone))
498 * This must be the single SOA record that is
499 * sent when the current version on the master
500 * is not newer than the version in the request.
502 xfrin_log(xfr, ISC_LOG_DEBUG(3),
503 "requested serial %u, "
504 "master has %u, not updating",
505 xfr->ixfr.request_serial, xfr->end_serial);
506 FAIL(DNS_R_UPTODATE);
508 if (xfr->reqtype == dns_rdatatype_axfr)
509 xfr->checkid = ISC_FALSE;
510 xfr->state = XFRST_FIRSTDATA;
513 case XFRST_FIRSTDATA:
515 * If the transfer begins with one SOA record, it is an AXFR,
516 * if it begins with two SOAs, it is an IXFR.
518 if (xfr->reqtype == dns_rdatatype_ixfr &&
519 rdata->type == dns_rdatatype_soa &&
520 xfr->ixfr.request_serial == dns_soa_getserial(rdata)) {
521 xfrin_log(xfr, ISC_LOG_DEBUG(3),
522 "got incremental response");
523 CHECK(ixfr_init(xfr));
524 xfr->state = XFRST_IXFR_DELSOA;
526 xfrin_log(xfr, ISC_LOG_DEBUG(3),
527 "got nonincremental response");
528 CHECK(axfr_init(xfr));
529 xfr->state = XFRST_AXFR;
533 case XFRST_IXFR_DELSOA:
534 INSIST(rdata->type == dns_rdatatype_soa);
535 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
536 xfr->state = XFRST_IXFR_DEL;
540 if (rdata->type == dns_rdatatype_soa) {
541 isc_uint32_t soa_serial = dns_soa_getserial(rdata);
542 xfr->state = XFRST_IXFR_ADDSOA;
543 xfr->ixfr.current_serial = soa_serial;
546 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
549 case XFRST_IXFR_ADDSOA:
550 INSIST(rdata->type == dns_rdatatype_soa);
551 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
552 xfr->state = XFRST_IXFR_ADD;
556 if (rdata->type == dns_rdatatype_soa) {
557 isc_uint32_t soa_serial = dns_soa_getserial(rdata);
558 if (soa_serial == xfr->end_serial) {
559 CHECK(ixfr_commit(xfr));
560 xfr->state = XFRST_IXFR_END;
562 } else if (soa_serial != xfr->ixfr.current_serial) {
563 xfrin_log(xfr, ISC_LOG_ERROR,
565 "expected serial %u, got %u",
566 xfr->ixfr.current_serial, soa_serial);
569 CHECK(ixfr_commit(xfr));
570 xfr->state = XFRST_IXFR_DELSOA;
574 if (rdata->type == dns_rdatatype_ns &&
575 dns_name_iswildcard(name))
576 FAIL(DNS_R_INVALIDNS);
577 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
582 * Old BINDs sent cross class A records for non IN classes.
584 if (rdata->type == dns_rdatatype_a &&
585 rdata->rdclass != xfr->rdclass &&
586 xfr->rdclass != dns_rdataclass_in)
588 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
589 if (rdata->type == dns_rdatatype_soa) {
590 CHECK(axfr_commit(xfr));
591 xfr->state = XFRST_AXFR_END;
597 FAIL(DNS_R_EXTRADATA);
603 result = ISC_R_SUCCESS;
609 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
610 isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
611 isc_mem_t *mctx, isc_timermgr_t *timermgr,
612 isc_socketmgr_t *socketmgr, isc_task_t *task,
613 dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
615 isc_sockaddr_t sourceaddr;
617 switch (isc_sockaddr_pf(masteraddr)) {
619 sourceaddr = *dns_zone_getxfrsource4(zone);
622 sourceaddr = *dns_zone_getxfrsource6(zone);
628 return(dns_xfrin_create2(zone, xfrtype, masteraddr, &sourceaddr,
629 tsigkey, mctx, timermgr, socketmgr,
634 dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
635 isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
636 dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
637 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
638 isc_task_t *task, dns_xfrindone_t done,
639 dns_xfrin_ctx_t **xfrp)
641 dns_name_t *zonename = dns_zone_getorigin(zone);
642 dns_xfrin_ctx_t *xfr = NULL;
646 REQUIRE(xfrp != NULL && *xfrp == NULL);
648 (void)dns_zone_getdb(zone, &db);
650 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
653 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
654 dns_zone_getclass(zone), xfrtype, masteraddr,
655 sourceaddr, tsigkey, &xfr));
657 CHECK(xfrin_start(xfr));
666 if (result != ISC_R_SUCCESS) {
667 char zonetext[DNS_NAME_MAXTEXT+32];
668 dns_zone_name(zone, zonetext, sizeof(zonetext));
669 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
670 "zone transfer setup failed");
676 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
677 if (! xfr->shuttingdown)
678 xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
682 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
683 REQUIRE(target != NULL && *target == NULL);
689 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
690 dns_xfrin_ctx_t *xfr = *xfrp;
691 INSIST(xfr->refcount > 0);
698 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
699 if (xfr->connects > 0) {
700 isc_socket_cancel(xfr->socket, xfr->task,
701 ISC_SOCKCANCEL_CONNECT);
702 } else if (xfr->recvs > 0) {
703 dns_tcpmsg_cancelread(&xfr->tcpmsg);
704 } else if (xfr->sends > 0) {
705 isc_socket_cancel(xfr->socket, xfr->task,
706 ISC_SOCKCANCEL_SEND);
711 xfrin_reset(dns_xfrin_ctx_t *xfr) {
712 REQUIRE(VALID_XFRIN(xfr));
714 xfrin_log(xfr, ISC_LOG_INFO, "resetting");
718 if (xfr->socket != NULL)
719 isc_socket_detach(&xfr->socket);
721 if (xfr->lasttsig != NULL)
722 isc_buffer_free(&xfr->lasttsig);
724 dns_diff_clear(&xfr->diff);
727 if (xfr->ixfr.journal != NULL)
728 dns_journal_destroy(&xfr->ixfr.journal);
730 if (xfr->axfr.add_private != NULL) {
731 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
732 xfr->axfr.add_func = NULL;
735 if (xfr->tcpmsg_valid) {
736 dns_tcpmsg_invalidate(&xfr->tcpmsg);
737 xfr->tcpmsg_valid = ISC_FALSE;
740 if (xfr->ver != NULL)
741 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
746 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
747 if (result != DNS_R_UPTODATE) {
748 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
749 msg, isc_result_totext(result));
751 /* Pass special result code to force AXFR retry */
752 result = DNS_R_BADIXFR;
758 if (xfr->ixfr.journal != NULL)
759 dns_journal_destroy(&xfr->ixfr.journal);
760 if (xfr->done != NULL) {
761 (xfr->done)(xfr->zone, result);
764 xfr->shuttingdown = ISC_TRUE;
769 xfrin_create(isc_mem_t *mctx,
773 isc_timermgr_t *timermgr,
774 isc_socketmgr_t *socketmgr,
775 dns_name_t *zonename,
776 dns_rdataclass_t rdclass,
777 dns_rdatatype_t reqtype,
778 isc_sockaddr_t *masteraddr,
779 isc_sockaddr_t *sourceaddr,
780 dns_tsigkey_t *tsigkey,
781 dns_xfrin_ctx_t **xfrp)
783 dns_xfrin_ctx_t *xfr = NULL;
787 xfr = isc_mem_get(mctx, sizeof(*xfr));
789 return (ISC_R_NOMEMORY);
791 isc_mem_attach(mctx, &xfr->mctx);
794 dns_zone_iattach(zone, &xfr->zone);
796 isc_task_attach(task, &xfr->task);
798 xfr->socketmgr = socketmgr;
804 xfr->shuttingdown = ISC_FALSE;
806 dns_name_init(&xfr->name, NULL);
807 xfr->rdclass = rdclass;
808 isc_random_get(&tmp);
809 xfr->checkid = ISC_TRUE;
810 xfr->id = (isc_uint16_t)(tmp & 0xffff);
811 xfr->reqtype = reqtype;
818 xfr->tcpmsg_valid = ISC_FALSE;
822 dns_db_attach(db, &xfr->db);
824 dns_diff_init(xfr->mctx, &xfr->diff);
827 if (reqtype == dns_rdatatype_soa)
828 xfr->state = XFRST_SOAQUERY;
830 xfr->state = XFRST_INITIALSOA;
836 isc_time_now(&xfr->start);
840 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
841 xfr->lasttsig = NULL;
844 xfr->is_ixfr = ISC_FALSE;
846 /* ixfr.request_serial */
847 /* ixfr.current_serial */
848 xfr->ixfr.journal = NULL;
850 xfr->axfr.add_func = NULL;
851 xfr->axfr.add_private = NULL;
853 CHECK(dns_name_dup(zonename, mctx, &xfr->name));
855 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
856 task, xfrin_timeout, xfr, &xfr->timer));
857 CHECK(dns_timer_setidle(xfr->timer,
858 dns_zone_getmaxxfrin(xfr->zone),
859 dns_zone_getidlein(xfr->zone),
862 xfr->masteraddr = *masteraddr;
864 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
865 xfr->sourceaddr = *sourceaddr;
866 isc_sockaddr_setport(&xfr->sourceaddr, 0);
869 * Reserve 2 bytes for TCP length at the begining of the buffer.
871 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
872 sizeof(xfr->qbuffer_data) - 2);
874 xfr->magic = XFRIN_MAGIC;
876 return (ISC_R_SUCCESS);
879 if (xfr->timer != NULL)
880 isc_timer_detach(&xfr->timer);
881 if (dns_name_dynamic(&xfr->name))
882 dns_name_free(&xfr->name, xfr->mctx);
883 if (xfr->tsigkey != NULL)
884 dns_tsigkey_detach(&xfr->tsigkey);
886 dns_db_detach(&xfr->db);
887 isc_task_detach(&xfr->task);
888 dns_zone_idetach(&xfr->zone);
889 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
895 xfrin_start(dns_xfrin_ctx_t *xfr) {
897 CHECK(isc_socket_create(xfr->socketmgr,
898 isc_sockaddr_pf(&xfr->sourceaddr),
901 isc_socket_setname(xfr->socket, "xfrin", NULL);
902 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
903 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
904 ISC_SOCKET_REUSEADDRESS));
906 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
907 xfrin_connect_done, xfr));
909 return (ISC_R_SUCCESS);
911 xfrin_fail(xfr, result, "failed setting up socket");
915 /* XXX the resolver could use this, too */
918 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
920 isc_boolean_t cleanup_cctx = ISC_FALSE;
923 CHECK(dns_compress_init(&cctx, -1, mctx));
924 cleanup_cctx = ISC_TRUE;
925 CHECK(dns_message_renderbegin(msg, &cctx, buf));
926 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
927 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
928 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
929 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
930 CHECK(dns_message_renderend(msg));
931 result = ISC_R_SUCCESS;
934 dns_compress_invalidate(&cctx);
939 * A connection has been established.
942 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
943 isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
944 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
945 isc_result_t result = cev->result;
946 char sourcetext[ISC_SOCKADDR_FORMATSIZE];
947 isc_sockaddr_t sockaddr;
948 dns_zonemgr_t * zmgr;
951 REQUIRE(VALID_XFRIN(xfr));
955 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
956 isc_event_free(&event);
959 if (xfr->shuttingdown) {
964 zmgr = dns_zone_getmgr(xfr->zone);
966 if (result != ISC_R_SUCCESS) {
968 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
969 &xfr->sourceaddr, &now);
972 dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
976 result = isc_socket_getsockname(xfr->socket, &sockaddr);
977 if (result == ISC_R_SUCCESS) {
978 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
980 strcpy(sourcetext, "<UNKNOWN>");
981 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext);
983 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
984 xfr->tcpmsg_valid = ISC_TRUE;
986 CHECK(xfrin_send_request(xfr));
988 if (result != ISC_R_SUCCESS)
989 xfrin_fail(xfr, result, "failed to connect");
993 * Convert a tuple into a dns_name_t suitable for inserting
994 * into the given dns_message_t.
997 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
1000 dns_rdata_t *rdata = NULL;
1001 dns_rdatalist_t *rdl = NULL;
1002 dns_rdataset_t *rds = NULL;
1003 dns_name_t *name = NULL;
1005 REQUIRE(target != NULL && *target == NULL);
1007 CHECK(dns_message_gettemprdata(msg, &rdata));
1008 dns_rdata_init(rdata);
1009 dns_rdata_clone(&tuple->rdata, rdata);
1011 CHECK(dns_message_gettemprdatalist(msg, &rdl));
1012 dns_rdatalist_init(rdl);
1013 rdl->type = tuple->rdata.type;
1014 rdl->rdclass = tuple->rdata.rdclass;
1015 rdl->ttl = tuple->ttl;
1016 ISC_LIST_APPEND(rdl->rdata, rdata, link);
1018 CHECK(dns_message_gettemprdataset(msg, &rds));
1019 dns_rdataset_init(rds);
1020 CHECK(dns_rdatalist_tordataset(rdl, rds));
1022 CHECK(dns_message_gettempname(msg, &name));
1023 dns_name_init(name, NULL);
1024 dns_name_clone(&tuple->name, name);
1025 ISC_LIST_APPEND(name->list, rds, link);
1028 return (ISC_R_SUCCESS);
1033 dns_rdataset_disassociate(rds);
1034 dns_message_puttemprdataset(msg, &rds);
1037 ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1038 dns_message_puttemprdatalist(msg, &rdl);
1041 dns_message_puttemprdata(msg, &rdata);
1048 * Build an *XFR request and send its length prefix.
1051 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1052 isc_result_t result;
1053 isc_region_t region;
1054 dns_rdataset_t *qrdataset = NULL;
1055 dns_message_t *msg = NULL;
1056 dns_difftuple_t *soatuple = NULL;
1057 dns_name_t *qname = NULL;
1058 dns_dbversion_t *ver = NULL;
1059 dns_name_t *msgsoaname = NULL;
1061 /* Create the request message */
1062 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
1063 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1065 /* Create a name for the question section. */
1066 CHECK(dns_message_gettempname(msg, &qname));
1067 dns_name_init(qname, NULL);
1068 dns_name_clone(&xfr->name, qname);
1070 /* Formulate the question and attach it to the question name. */
1071 CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1072 dns_rdataset_init(qrdataset);
1073 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1074 ISC_LIST_APPEND(qname->list, qrdataset, link);
1077 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1080 if (xfr->reqtype == dns_rdatatype_ixfr) {
1081 /* Get the SOA and add it to the authority section. */
1082 /* XXX is using the current version the right thing? */
1083 dns_db_currentversion(xfr->db, &ver);
1084 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1085 DNS_DIFFOP_EXISTS, &soatuple));
1086 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1087 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1088 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1089 "requesting IXFR for serial %u",
1090 xfr->ixfr.request_serial);
1092 CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1093 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1094 } else if (xfr->reqtype == dns_rdatatype_soa)
1095 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1096 &xfr->ixfr.request_serial));
1098 xfr->checkid = ISC_TRUE;
1103 isc_time_now(&xfr->start);
1105 if (xfr->tsigctx != NULL)
1106 dst_context_destroy(&xfr->tsigctx);
1108 CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1111 * Free the last tsig, if there is one.
1113 if (xfr->lasttsig != NULL)
1114 isc_buffer_free(&xfr->lasttsig);
1117 * Save the query TSIG and don't let message_destroy free it.
1119 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1121 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1122 INSIST(region.length <= 65535);
1125 * Record message length and adjust region to include TCP
1128 xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
1129 xfr->qbuffer_data[1] = region.length & 0xff;
1132 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task,
1133 xfrin_send_done, xfr));
1138 dns_message_puttempname(msg, &qname);
1139 if (qrdataset != NULL)
1140 dns_message_puttemprdataset(msg, &qrdataset);
1142 dns_message_destroy(&msg);
1143 if (soatuple != NULL)
1144 dns_difftuple_free(&soatuple);
1146 dns_db_closeversion(xfr->db, &ver, ISC_FALSE);
1151 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
1152 isc_socketevent_t *sev = (isc_socketevent_t *) event;
1153 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1154 isc_result_t result;
1156 REQUIRE(VALID_XFRIN(xfr));
1160 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1163 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1166 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1167 xfrin_recv_done, xfr));
1170 isc_event_free(&event);
1171 if (result != ISC_R_SUCCESS)
1172 xfrin_fail(xfr, result, "failed sending request data");
1177 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
1178 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
1179 isc_result_t result;
1180 dns_message_t *msg = NULL;
1182 dns_tcpmsg_t *tcpmsg;
1183 dns_name_t *tsigowner = NULL;
1185 REQUIRE(VALID_XFRIN(xfr));
1189 INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
1190 tcpmsg = ev->ev_sender;
1191 isc_event_free(&ev);
1194 if (xfr->shuttingdown) {
1199 CHECK(tcpmsg->result);
1201 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
1202 tcpmsg->buffer.used);
1204 CHECK(isc_timer_touch(xfr->timer));
1206 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
1208 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1209 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1211 msg->tsigctx = xfr->tsigctx;
1212 xfr->tsigctx = NULL;
1214 dns_message_setclass(msg, xfr->rdclass);
1217 msg->tcp_continuation = 1;
1219 result = dns_message_parse(msg, &tcpmsg->buffer,
1220 DNS_MESSAGEPARSE_PRESERVEORDER);
1222 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1223 (xfr->checkid && msg->id != xfr->id)) {
1224 if (result == ISC_R_SUCCESS)
1225 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
1226 if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
1227 result = DNS_R_UNEXPECTEDID;
1228 if (xfr->reqtype == dns_rdatatype_axfr ||
1229 xfr->reqtype == dns_rdatatype_soa)
1231 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1232 isc_result_totext(result));
1234 dns_message_destroy(&msg);
1236 xfr->reqtype = dns_rdatatype_soa;
1237 xfr->state = XFRST_SOAQUERY;
1238 (void)xfrin_start(xfr);
1243 * Does the server know about IXFR? If it doesn't we will get
1244 * a message with a empty answer section or a potentially a CNAME /
1245 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1246 * if the first RR in the answer section is not a SOA record.
1248 if (xfr->reqtype == dns_rdatatype_ixfr &&
1249 xfr->state == XFRST_INITIALSOA &&
1250 msg->counts[DNS_SECTION_ANSWER] == 0) {
1251 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1252 "empty answer section, retrying with AXFR");
1256 if (xfr->reqtype == dns_rdatatype_soa &&
1257 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
1258 FAIL(DNS_R_NOTAUTHORITATIVE);
1262 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1263 if (result != ISC_R_SUCCESS) {
1264 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1265 isc_result_totext(result));
1269 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1270 result == ISC_R_SUCCESS;
1271 result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1273 dns_rdataset_t *rds;
1276 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1277 for (rds = ISC_LIST_HEAD(name->list);
1279 rds = ISC_LIST_NEXT(rds, link))
1281 for (result = dns_rdataset_first(rds);
1282 result == ISC_R_SUCCESS;
1283 result = dns_rdataset_next(rds))
1285 dns_rdata_t rdata = DNS_RDATA_INIT;
1286 dns_rdataset_current(rds, &rdata);
1287 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1291 if (result != ISC_R_NOMORE)
1294 if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1296 * Reset the counter.
1301 * Free the last tsig, if there is one.
1303 if (xfr->lasttsig != NULL)
1304 isc_buffer_free(&xfr->lasttsig);
1307 * Update the last tsig pointer.
1309 CHECK(dns_message_getquerytsig(msg, xfr->mctx,
1312 } else if (dns_message_gettsigkey(msg) != NULL) {
1314 if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1315 xfr->state == XFRST_AXFR_END ||
1316 xfr->state == XFRST_IXFR_END)
1318 result = DNS_R_EXPECTEDTSIG;
1324 * Update the number of messages received.
1329 * Update the number of bytes received.
1331 xfr->nbytes += tcpmsg->buffer.used;
1334 * Take the context back.
1336 INSIST(xfr->tsigctx == NULL);
1337 xfr->tsigctx = msg->tsigctx;
1338 msg->tsigctx = NULL;
1340 dns_message_destroy(&msg);
1342 switch (xfr->state) {
1344 xfr->reqtype = dns_rdatatype_axfr;
1345 xfr->state = XFRST_INITIALSOA;
1346 CHECK(xfrin_send_request(xfr));
1348 case XFRST_AXFR_END:
1349 CHECK(axfr_finalize(xfr));
1351 case XFRST_IXFR_END:
1353 * Close the journal.
1355 if (xfr->ixfr.journal != NULL)
1356 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;
1374 * Read the next message.
1376 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1377 xfrin_recv_done, xfr));
1384 dns_message_destroy(&msg);
1385 if (result != ISC_R_SUCCESS)
1386 xfrin_fail(xfr, result, "failed while receiving responses");
1390 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
1391 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1393 REQUIRE(VALID_XFRIN(xfr));
1397 isc_event_free(&event);
1399 * This will log "giving up: timeout".
1401 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
1405 maybe_free(dns_xfrin_ctx_t *xfr) {
1407 isc_uint64_t persec;
1409 REQUIRE(VALID_XFRIN(xfr));
1411 if (! xfr->shuttingdown || xfr->refcount != 0 ||
1412 xfr->connects != 0 || xfr->sends != 0 ||
1417 * Calculate the length of time the transfer took,
1418 * and print a log message with the bytes and rate.
1420 isc_time_now(&xfr->end);
1421 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1424 persec = (xfr->nbytes * 1000) / msecs;
1425 xfrin_log(xfr, ISC_LOG_INFO,
1426 "Transfer completed: %d messages, %d records, "
1427 "%" ISC_PRINT_QUADFORMAT "u bytes, "
1428 "%u.%03u secs (%u bytes/sec)",
1429 xfr->nmsg, xfr->nrecs, xfr->nbytes,
1430 (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000),
1431 (unsigned int) persec);
1433 if (xfr->socket != NULL)
1434 isc_socket_detach(&xfr->socket);
1436 if (xfr->timer != NULL)
1437 isc_timer_detach(&xfr->timer);
1439 if (xfr->task != NULL)
1440 isc_task_detach(&xfr->task);
1442 if (xfr->tsigkey != NULL)
1443 dns_tsigkey_detach(&xfr->tsigkey);
1445 if (xfr->lasttsig != NULL)
1446 isc_buffer_free(&xfr->lasttsig);
1448 dns_diff_clear(&xfr->diff);
1450 if (xfr->ixfr.journal != NULL)
1451 dns_journal_destroy(&xfr->ixfr.journal);
1453 if (xfr->axfr.add_private != NULL)
1454 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
1456 if (xfr->tcpmsg_valid)
1457 dns_tcpmsg_invalidate(&xfr->tcpmsg);
1459 if (xfr->tsigctx != NULL)
1460 dst_context_destroy(&xfr->tsigctx);
1462 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
1463 dns_name_free(&xfr->name, xfr->mctx);
1465 if (xfr->ver != NULL)
1466 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
1468 if (xfr->db != NULL)
1469 dns_db_detach(&xfr->db);
1471 if (xfr->zone != NULL)
1472 dns_zone_idetach(&xfr->zone);
1474 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1478 * Log incoming zone transfer messages in a format like
1479 * transfer of <zone> from <address>: <message>
1482 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1483 const char *fmt, va_list ap)
1485 char mastertext[ISC_SOCKADDR_FORMATSIZE];
1488 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
1489 vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
1491 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
1492 DNS_LOGMODULE_XFER_IN, level,
1493 "transfer of '%s' from %s: %s",
1494 zonetext, mastertext, msgtext);
1498 * Logging function for use when a xfrin_ctx_t has not yet been created.
1502 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1503 const char *fmt, ...)
1507 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1511 xfrin_logv(level, zonetext, masteraddr, fmt, ap);
1516 * Logging function for use when there is a xfrin_ctx_t.
1520 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
1523 char zonetext[DNS_NAME_MAXTEXT+32];
1525 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1528 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
1531 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);