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 ISC_TRUE, &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, dns_xfrin_ctx_t **xfrp)
640 dns_name_t *zonename = dns_zone_getorigin(zone);
641 dns_xfrin_ctx_t *xfr = NULL;
645 REQUIRE(xfrp != NULL && *xfrp == NULL);
647 (void)dns_zone_getdb(zone, &db);
649 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
652 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
653 dns_zone_getclass(zone), xfrtype, masteraddr,
654 sourceaddr, tsigkey, &xfr));
656 CHECK(xfrin_start(xfr));
665 if (result != ISC_R_SUCCESS) {
666 char zonetext[DNS_NAME_MAXTEXT+32];
667 dns_zone_name(zone, zonetext, sizeof(zonetext));
668 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
669 "zone transfer setup failed");
675 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
676 if (! xfr->shuttingdown)
677 xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
681 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
682 REQUIRE(target != NULL && *target == NULL);
688 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
689 dns_xfrin_ctx_t *xfr = *xfrp;
690 INSIST(xfr->refcount > 0);
697 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
698 if (xfr->connects > 0) {
699 isc_socket_cancel(xfr->socket, xfr->task,
700 ISC_SOCKCANCEL_CONNECT);
701 } else if (xfr->recvs > 0) {
702 dns_tcpmsg_cancelread(&xfr->tcpmsg);
703 } else if (xfr->sends > 0) {
704 isc_socket_cancel(xfr->socket, xfr->task,
705 ISC_SOCKCANCEL_SEND);
710 xfrin_reset(dns_xfrin_ctx_t *xfr) {
711 REQUIRE(VALID_XFRIN(xfr));
713 xfrin_log(xfr, ISC_LOG_INFO, "resetting");
717 if (xfr->socket != NULL)
718 isc_socket_detach(&xfr->socket);
720 if (xfr->lasttsig != NULL)
721 isc_buffer_free(&xfr->lasttsig);
723 dns_diff_clear(&xfr->diff);
726 if (xfr->ixfr.journal != NULL)
727 dns_journal_destroy(&xfr->ixfr.journal);
729 if (xfr->axfr.add_private != NULL) {
730 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
731 xfr->axfr.add_func = NULL;
734 if (xfr->tcpmsg_valid) {
735 dns_tcpmsg_invalidate(&xfr->tcpmsg);
736 xfr->tcpmsg_valid = ISC_FALSE;
739 if (xfr->ver != NULL)
740 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
745 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
746 if (result != DNS_R_UPTODATE) {
747 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
748 msg, isc_result_totext(result));
750 /* Pass special result code to force AXFR retry */
751 result = DNS_R_BADIXFR;
757 if (xfr->ixfr.journal != NULL)
758 dns_journal_destroy(&xfr->ixfr.journal);
759 if (xfr->done != NULL) {
760 (xfr->done)(xfr->zone, result);
763 xfr->shuttingdown = ISC_TRUE;
768 xfrin_create(isc_mem_t *mctx,
772 isc_timermgr_t *timermgr,
773 isc_socketmgr_t *socketmgr,
774 dns_name_t *zonename,
775 dns_rdataclass_t rdclass,
776 dns_rdatatype_t reqtype,
777 isc_sockaddr_t *masteraddr,
778 isc_sockaddr_t *sourceaddr,
779 dns_tsigkey_t *tsigkey,
780 dns_xfrin_ctx_t **xfrp)
782 dns_xfrin_ctx_t *xfr = NULL;
786 xfr = isc_mem_get(mctx, sizeof(*xfr));
788 return (ISC_R_NOMEMORY);
790 isc_mem_attach(mctx, &xfr->mctx);
793 dns_zone_iattach(zone, &xfr->zone);
795 isc_task_attach(task, &xfr->task);
797 xfr->socketmgr = socketmgr;
803 xfr->shuttingdown = ISC_FALSE;
805 dns_name_init(&xfr->name, NULL);
806 xfr->rdclass = rdclass;
807 isc_random_get(&tmp);
808 xfr->checkid = ISC_TRUE;
809 xfr->id = (isc_uint16_t)(tmp & 0xffff);
810 xfr->reqtype = reqtype;
817 xfr->tcpmsg_valid = ISC_FALSE;
821 dns_db_attach(db, &xfr->db);
823 dns_diff_init(xfr->mctx, &xfr->diff);
826 if (reqtype == dns_rdatatype_soa)
827 xfr->state = XFRST_SOAQUERY;
829 xfr->state = XFRST_INITIALSOA;
835 isc_time_now(&xfr->start);
839 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
840 xfr->lasttsig = NULL;
843 xfr->is_ixfr = ISC_FALSE;
845 /* ixfr.request_serial */
846 /* ixfr.current_serial */
847 xfr->ixfr.journal = NULL;
849 xfr->axfr.add_func = NULL;
850 xfr->axfr.add_private = NULL;
852 CHECK(dns_name_dup(zonename, mctx, &xfr->name));
854 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
855 task, xfrin_timeout, xfr, &xfr->timer));
856 CHECK(dns_timer_setidle(xfr->timer,
857 dns_zone_getmaxxfrin(xfr->zone),
858 dns_zone_getidlein(xfr->zone),
861 xfr->masteraddr = *masteraddr;
863 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
864 xfr->sourceaddr = *sourceaddr;
865 isc_sockaddr_setport(&xfr->sourceaddr, 0);
868 * Reserve 2 bytes for TCP length at the begining of the buffer.
870 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
871 sizeof(xfr->qbuffer_data) - 2);
873 xfr->magic = XFRIN_MAGIC;
875 return (ISC_R_SUCCESS);
878 if (xfr->timer != NULL)
879 isc_timer_detach(&xfr->timer);
880 if (dns_name_dynamic(&xfr->name))
881 dns_name_free(&xfr->name, xfr->mctx);
882 if (xfr->tsigkey != NULL)
883 dns_tsigkey_detach(&xfr->tsigkey);
885 dns_db_detach(&xfr->db);
886 isc_task_detach(&xfr->task);
887 dns_zone_idetach(&xfr->zone);
888 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
894 xfrin_start(dns_xfrin_ctx_t *xfr) {
896 CHECK(isc_socket_create(xfr->socketmgr,
897 isc_sockaddr_pf(&xfr->sourceaddr),
900 isc_socket_setname(xfr->socket, "xfrin", NULL);
901 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
902 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
903 ISC_SOCKET_REUSEADDRESS));
905 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
906 xfrin_connect_done, xfr));
908 return (ISC_R_SUCCESS);
910 xfrin_fail(xfr, result, "failed setting up socket");
914 /* XXX the resolver could use this, too */
917 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
919 isc_boolean_t cleanup_cctx = ISC_FALSE;
922 CHECK(dns_compress_init(&cctx, -1, mctx));
923 cleanup_cctx = ISC_TRUE;
924 CHECK(dns_message_renderbegin(msg, &cctx, buf));
925 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
926 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
927 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
928 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
929 CHECK(dns_message_renderend(msg));
930 result = ISC_R_SUCCESS;
933 dns_compress_invalidate(&cctx);
938 * A connection has been established.
941 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
942 isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
943 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
944 isc_result_t result = cev->result;
945 char sourcetext[ISC_SOCKADDR_FORMATSIZE];
946 isc_sockaddr_t sockaddr;
947 dns_zonemgr_t * zmgr;
950 REQUIRE(VALID_XFRIN(xfr));
954 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
955 isc_event_free(&event);
958 if (xfr->shuttingdown) {
963 zmgr = dns_zone_getmgr(xfr->zone);
965 if (result != ISC_R_SUCCESS) {
967 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
968 &xfr->sourceaddr, &now);
971 dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
975 result = isc_socket_getsockname(xfr->socket, &sockaddr);
976 if (result == ISC_R_SUCCESS) {
977 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
979 strcpy(sourcetext, "<UNKNOWN>");
980 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext);
982 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
983 xfr->tcpmsg_valid = ISC_TRUE;
985 CHECK(xfrin_send_request(xfr));
987 if (result != ISC_R_SUCCESS)
988 xfrin_fail(xfr, result, "failed to connect");
992 * Convert a tuple into a dns_name_t suitable for inserting
993 * into the given dns_message_t.
996 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
999 dns_rdata_t *rdata = NULL;
1000 dns_rdatalist_t *rdl = NULL;
1001 dns_rdataset_t *rds = NULL;
1002 dns_name_t *name = NULL;
1004 REQUIRE(target != NULL && *target == NULL);
1006 CHECK(dns_message_gettemprdata(msg, &rdata));
1007 dns_rdata_init(rdata);
1008 dns_rdata_clone(&tuple->rdata, rdata);
1010 CHECK(dns_message_gettemprdatalist(msg, &rdl));
1011 dns_rdatalist_init(rdl);
1012 rdl->type = tuple->rdata.type;
1013 rdl->rdclass = tuple->rdata.rdclass;
1014 rdl->ttl = tuple->ttl;
1015 ISC_LIST_APPEND(rdl->rdata, rdata, link);
1017 CHECK(dns_message_gettemprdataset(msg, &rds));
1018 dns_rdataset_init(rds);
1019 CHECK(dns_rdatalist_tordataset(rdl, rds));
1021 CHECK(dns_message_gettempname(msg, &name));
1022 dns_name_init(name, NULL);
1023 dns_name_clone(&tuple->name, name);
1024 ISC_LIST_APPEND(name->list, rds, link);
1027 return (ISC_R_SUCCESS);
1032 dns_rdataset_disassociate(rds);
1033 dns_message_puttemprdataset(msg, &rds);
1036 ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1037 dns_message_puttemprdatalist(msg, &rdl);
1040 dns_message_puttemprdata(msg, &rdata);
1047 * Build an *XFR request and send its length prefix.
1050 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1051 isc_result_t result;
1052 isc_region_t region;
1053 dns_rdataset_t *qrdataset = NULL;
1054 dns_message_t *msg = NULL;
1055 dns_difftuple_t *soatuple = NULL;
1056 dns_name_t *qname = NULL;
1057 dns_dbversion_t *ver = NULL;
1058 dns_name_t *msgsoaname = NULL;
1060 /* Create the request message */
1061 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
1062 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1064 /* Create a name for the question section. */
1065 CHECK(dns_message_gettempname(msg, &qname));
1066 dns_name_init(qname, NULL);
1067 dns_name_clone(&xfr->name, qname);
1069 /* Formulate the question and attach it to the question name. */
1070 CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1071 dns_rdataset_init(qrdataset);
1072 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1073 ISC_LIST_APPEND(qname->list, qrdataset, link);
1076 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1079 if (xfr->reqtype == dns_rdatatype_ixfr) {
1080 /* Get the SOA and add it to the authority section. */
1081 /* XXX is using the current version the right thing? */
1082 dns_db_currentversion(xfr->db, &ver);
1083 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1084 DNS_DIFFOP_EXISTS, &soatuple));
1085 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1086 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1087 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1088 "requesting IXFR for serial %u",
1089 xfr->ixfr.request_serial);
1091 CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1092 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1093 } else if (xfr->reqtype == dns_rdatatype_soa)
1094 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1095 &xfr->ixfr.request_serial));
1097 xfr->checkid = ISC_TRUE;
1102 isc_time_now(&xfr->start);
1104 if (xfr->tsigctx != NULL)
1105 dst_context_destroy(&xfr->tsigctx);
1107 CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1110 * Free the last tsig, if there is one.
1112 if (xfr->lasttsig != NULL)
1113 isc_buffer_free(&xfr->lasttsig);
1116 * Save the query TSIG and don't let message_destroy free it.
1118 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1120 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1121 INSIST(region.length <= 65535);
1124 * Record message length and adjust region to include TCP
1127 xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
1128 xfr->qbuffer_data[1] = region.length & 0xff;
1131 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task,
1132 xfrin_send_done, xfr));
1137 dns_message_puttempname(msg, &qname);
1138 if (qrdataset != NULL)
1139 dns_message_puttemprdataset(msg, &qrdataset);
1141 dns_message_destroy(&msg);
1142 if (soatuple != NULL)
1143 dns_difftuple_free(&soatuple);
1145 dns_db_closeversion(xfr->db, &ver, ISC_FALSE);
1150 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
1151 isc_socketevent_t *sev = (isc_socketevent_t *) event;
1152 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1153 isc_result_t result;
1155 REQUIRE(VALID_XFRIN(xfr));
1159 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1162 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1165 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1166 xfrin_recv_done, xfr));
1169 isc_event_free(&event);
1170 if (result != ISC_R_SUCCESS)
1171 xfrin_fail(xfr, result, "failed sending request data");
1176 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
1177 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
1178 isc_result_t result;
1179 dns_message_t *msg = NULL;
1181 dns_tcpmsg_t *tcpmsg;
1182 dns_name_t *tsigowner = NULL;
1184 REQUIRE(VALID_XFRIN(xfr));
1188 INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
1189 tcpmsg = ev->ev_sender;
1190 isc_event_free(&ev);
1193 if (xfr->shuttingdown) {
1198 CHECK(tcpmsg->result);
1200 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
1201 tcpmsg->buffer.used);
1203 CHECK(isc_timer_touch(xfr->timer));
1205 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
1207 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1208 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1210 msg->tsigctx = xfr->tsigctx;
1211 xfr->tsigctx = NULL;
1214 msg->tcp_continuation = 1;
1216 result = dns_message_parse(msg, &tcpmsg->buffer,
1217 DNS_MESSAGEPARSE_PRESERVEORDER);
1219 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1220 (xfr->checkid && msg->id != xfr->id)) {
1221 if (result == ISC_R_SUCCESS)
1222 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
1223 if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
1224 result = DNS_R_UNEXPECTEDID;
1225 if (xfr->reqtype == dns_rdatatype_axfr ||
1226 xfr->reqtype == dns_rdatatype_soa)
1228 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1229 isc_result_totext(result));
1231 dns_message_destroy(&msg);
1233 xfr->reqtype = dns_rdatatype_soa;
1234 xfr->state = XFRST_SOAQUERY;
1235 (void)xfrin_start(xfr);
1240 * Does the server know about IXFR? If it doesn't we will get
1241 * a message with a empty answer section or a potentially a CNAME /
1242 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1243 * if the first RR in the answer section is not a SOA record.
1245 if (xfr->reqtype == dns_rdatatype_ixfr &&
1246 xfr->state == XFRST_INITIALSOA &&
1247 msg->counts[DNS_SECTION_ANSWER] == 0) {
1248 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1249 "empty answer section, retrying with AXFR");
1253 if (xfr->reqtype == dns_rdatatype_soa &&
1254 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
1255 FAIL(DNS_R_NOTAUTHORITATIVE);
1259 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1260 if (result != ISC_R_SUCCESS) {
1261 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1262 isc_result_totext(result));
1266 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1267 result == ISC_R_SUCCESS;
1268 result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1270 dns_rdataset_t *rds;
1273 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1274 for (rds = ISC_LIST_HEAD(name->list);
1276 rds = ISC_LIST_NEXT(rds, link))
1278 for (result = dns_rdataset_first(rds);
1279 result == ISC_R_SUCCESS;
1280 result = dns_rdataset_next(rds))
1282 dns_rdata_t rdata = DNS_RDATA_INIT;
1283 dns_rdataset_current(rds, &rdata);
1284 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1288 if (result != ISC_R_NOMORE)
1291 if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1293 * Reset the counter.
1298 * Free the last tsig, if there is one.
1300 if (xfr->lasttsig != NULL)
1301 isc_buffer_free(&xfr->lasttsig);
1304 * Update the last tsig pointer.
1306 CHECK(dns_message_getquerytsig(msg, xfr->mctx,
1309 } else if (dns_message_gettsigkey(msg) != NULL) {
1311 if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1312 xfr->state == XFRST_AXFR_END ||
1313 xfr->state == XFRST_IXFR_END)
1315 result = DNS_R_EXPECTEDTSIG;
1321 * Update the number of messages received.
1326 * Update the number of bytes received.
1328 xfr->nbytes += tcpmsg->buffer.used;
1331 * Take the context back.
1333 INSIST(xfr->tsigctx == NULL);
1334 xfr->tsigctx = msg->tsigctx;
1335 msg->tsigctx = NULL;
1337 dns_message_destroy(&msg);
1339 switch (xfr->state) {
1341 xfr->reqtype = dns_rdatatype_axfr;
1342 xfr->state = XFRST_INITIALSOA;
1343 CHECK(xfrin_send_request(xfr));
1345 case XFRST_AXFR_END:
1346 CHECK(axfr_finalize(xfr));
1348 case XFRST_IXFR_END:
1350 * Close the journal.
1352 if (xfr->ixfr.journal != NULL)
1353 dns_journal_destroy(&xfr->ixfr.journal);
1356 * Inform the caller we succeeded.
1358 if (xfr->done != NULL) {
1359 (xfr->done)(xfr->zone, ISC_R_SUCCESS);
1363 * We should have no outstanding events at this
1364 * point, thus maybe_free() should succeed.
1366 xfr->shuttingdown = ISC_TRUE;
1371 * Read the next message.
1373 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1374 xfrin_recv_done, xfr));
1381 dns_message_destroy(&msg);
1382 if (result != ISC_R_SUCCESS)
1383 xfrin_fail(xfr, result, "failed while receiving responses");
1387 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
1388 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1390 REQUIRE(VALID_XFRIN(xfr));
1394 isc_event_free(&event);
1396 * This will log "giving up: timeout".
1398 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
1402 maybe_free(dns_xfrin_ctx_t *xfr) {
1404 isc_uint64_t persec;
1406 REQUIRE(VALID_XFRIN(xfr));
1408 if (! xfr->shuttingdown || xfr->refcount != 0 ||
1409 xfr->connects != 0 || xfr->sends != 0 ||
1414 * Calculate the length of time the transfer took,
1415 * and print a log message with the bytes and rate.
1417 isc_time_now(&xfr->end);
1418 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1421 persec = (xfr->nbytes * 1000) / msecs;
1422 xfrin_log(xfr, ISC_LOG_INFO,
1423 "Transfer completed: %d messages, %d records, "
1424 "%" ISC_PRINT_QUADFORMAT "u bytes, "
1425 "%u.%03u secs (%u bytes/sec)",
1426 xfr->nmsg, xfr->nrecs, xfr->nbytes,
1427 (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000),
1428 (unsigned int) persec);
1430 if (xfr->socket != NULL)
1431 isc_socket_detach(&xfr->socket);
1433 if (xfr->timer != NULL)
1434 isc_timer_detach(&xfr->timer);
1436 if (xfr->task != NULL)
1437 isc_task_detach(&xfr->task);
1439 if (xfr->tsigkey != NULL)
1440 dns_tsigkey_detach(&xfr->tsigkey);
1442 if (xfr->lasttsig != NULL)
1443 isc_buffer_free(&xfr->lasttsig);
1445 dns_diff_clear(&xfr->diff);
1447 if (xfr->ixfr.journal != NULL)
1448 dns_journal_destroy(&xfr->ixfr.journal);
1450 if (xfr->axfr.add_private != NULL)
1451 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
1453 if (xfr->tcpmsg_valid)
1454 dns_tcpmsg_invalidate(&xfr->tcpmsg);
1456 if (xfr->tsigctx != NULL)
1457 dst_context_destroy(&xfr->tsigctx);
1459 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
1460 dns_name_free(&xfr->name, xfr->mctx);
1462 if (xfr->ver != NULL)
1463 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
1465 if (xfr->db != NULL)
1466 dns_db_detach(&xfr->db);
1468 if (xfr->zone != NULL)
1469 dns_zone_idetach(&xfr->zone);
1471 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1475 * Log incoming zone transfer messages in a format like
1476 * transfer of <zone> from <address>: <message>
1479 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1480 const char *fmt, va_list ap)
1482 char mastertext[ISC_SOCKADDR_FORMATSIZE];
1485 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
1486 vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
1488 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
1489 DNS_LOGMODULE_XFER_IN, level,
1490 "transfer of '%s' from %s: %s",
1491 zonetext, mastertext, msgtext);
1495 * Logging function for use when a xfrin_ctx_t has not yet been created.
1499 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1500 const char *fmt, ...)
1504 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1508 xfrin_logv(level, zonetext, masteraddr, fmt, ap);
1513 * Logging function for use when there is a xfrin_ctx_t.
1517 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
1520 char zonetext[DNS_NAME_MAXTEXT+32];
1522 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1525 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
1528 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);