Home | History | Annotate | Line # | Download | only in dns
xfrin.c revision 1.9
      1 /*	$NetBSD: xfrin.c,v 1.9 2021/04/29 17:26:11 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * This Source Code Form is subject to the terms of the Mozilla Public
      7  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
      9  *
     10  * See the COPYRIGHT file distributed with this work for additional
     11  * information regarding copyright ownership.
     12  */
     13 
     14 /*! \file */
     15 
     16 #include <inttypes.h>
     17 #include <stdbool.h>
     18 
     19 #include <isc/mem.h>
     20 #include <isc/print.h>
     21 #include <isc/random.h>
     22 #include <isc/string.h> /* Required for HP/UX (and others?) */
     23 #include <isc/task.h>
     24 #include <isc/timer.h>
     25 #include <isc/util.h>
     26 
     27 #include <dns/callbacks.h>
     28 #include <dns/catz.h>
     29 #include <dns/db.h>
     30 #include <dns/diff.h>
     31 #include <dns/events.h>
     32 #include <dns/journal.h>
     33 #include <dns/log.h>
     34 #include <dns/message.h>
     35 #include <dns/rdataclass.h>
     36 #include <dns/rdatalist.h>
     37 #include <dns/rdataset.h>
     38 #include <dns/result.h>
     39 #include <dns/soa.h>
     40 #include <dns/tcpmsg.h>
     41 #include <dns/timer.h>
     42 #include <dns/tsig.h>
     43 #include <dns/view.h>
     44 #include <dns/xfrin.h>
     45 #include <dns/zone.h>
     46 
     47 #include <dst/dst.h>
     48 
     49 /*
     50  * Incoming AXFR and IXFR.
     51  */
     52 
     53 /*%
     54  * It would be non-sensical (or at least obtuse) to use FAIL() with an
     55  * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
     56  * from complaining about "end-of-loop code not reached".
     57  */
     58 #define FAIL(code)                           \
     59 	do {                                 \
     60 		result = (code);             \
     61 		if (result != ISC_R_SUCCESS) \
     62 			goto failure;        \
     63 	} while (0)
     64 
     65 #define CHECK(op)                            \
     66 	do {                                 \
     67 		result = (op);               \
     68 		if (result != ISC_R_SUCCESS) \
     69 			goto failure;        \
     70 	} while (0)
     71 
     72 /*%
     73  * The states of the *XFR state machine.  We handle both IXFR and AXFR
     74  * with a single integrated state machine because they cannot be distinguished
     75  * immediately - an AXFR response to an IXFR request can only be detected
     76  * when the first two (2) response RRs have already been received.
     77  */
     78 typedef enum {
     79 	XFRST_SOAQUERY,
     80 	XFRST_GOTSOA,
     81 	XFRST_INITIALSOA,
     82 	XFRST_FIRSTDATA,
     83 	XFRST_IXFR_DELSOA,
     84 	XFRST_IXFR_DEL,
     85 	XFRST_IXFR_ADDSOA,
     86 	XFRST_IXFR_ADD,
     87 	XFRST_IXFR_END,
     88 	XFRST_AXFR,
     89 	XFRST_AXFR_END
     90 } xfrin_state_t;
     91 
     92 /*%
     93  * Incoming zone transfer context.
     94  */
     95 
     96 struct dns_xfrin_ctx {
     97 	unsigned int magic;
     98 	isc_mem_t *mctx;
     99 	dns_zone_t *zone;
    100 
    101 	int refcount;
    102 
    103 	isc_task_t *task;
    104 	isc_timer_t *timer;
    105 	isc_socketmgr_t *socketmgr;
    106 
    107 	int connects; /*%< Connect in progress */
    108 	int sends;    /*%< Send in progress */
    109 	int recvs;    /*%< Receive in progress */
    110 	bool shuttingdown;
    111 	isc_result_t shutdown_result;
    112 
    113 	dns_name_t name; /*%< Name of zone to transfer */
    114 	dns_rdataclass_t rdclass;
    115 
    116 	bool checkid, logit;
    117 	dns_messageid_t id;
    118 
    119 	/*%
    120 	 * Requested transfer type (dns_rdatatype_axfr or
    121 	 * dns_rdatatype_ixfr).  The actual transfer type
    122 	 * may differ due to IXFR->AXFR fallback.
    123 	 */
    124 	dns_rdatatype_t reqtype;
    125 	isc_dscp_t dscp;
    126 
    127 	isc_sockaddr_t masteraddr;
    128 	isc_sockaddr_t sourceaddr;
    129 	isc_socket_t *socket;
    130 
    131 	/*% Buffer for IXFR/AXFR request message */
    132 	isc_buffer_t qbuffer;
    133 	unsigned char qbuffer_data[512];
    134 
    135 	/*% Incoming reply TCP message */
    136 	dns_tcpmsg_t tcpmsg;
    137 	bool tcpmsg_valid;
    138 
    139 	/*%
    140 	 * Whether the zone originally had a database attached at the time this
    141 	 * transfer context was created.  Used by maybe_free() when making
    142 	 * logging decisions.
    143 	 */
    144 	bool zone_had_db;
    145 
    146 	dns_db_t *db;
    147 	dns_dbversion_t *ver;
    148 	dns_diff_t diff; /*%< Pending database changes */
    149 	int difflen;	 /*%< Number of pending tuples */
    150 
    151 	xfrin_state_t state;
    152 	uint32_t end_serial;
    153 	bool is_ixfr;
    154 
    155 	unsigned int nmsg;  /*%< Number of messages recvd */
    156 	unsigned int nrecs; /*%< Number of records recvd */
    157 	uint64_t nbytes;    /*%< Number of bytes received */
    158 
    159 	unsigned int maxrecords; /*%< The maximum number of
    160 				  *   records set for the zone */
    161 
    162 	isc_time_t start; /*%< Start time of the transfer */
    163 	isc_time_t end;	  /*%< End time of the transfer */
    164 
    165 	dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
    166 	isc_buffer_t *lasttsig; /*%< The last TSIG */
    167 	dst_context_t *tsigctx; /*%< TSIG verification context */
    168 	unsigned int sincetsig; /*%< recvd since the last TSIG */
    169 	dns_xfrindone_t done;
    170 
    171 	/*%
    172 	 * AXFR- and IXFR-specific data.  Only one is used at a time
    173 	 * according to the is_ixfr flag, so this could be a union,
    174 	 * but keeping them separate makes it a bit simpler to clean
    175 	 * things up when destroying the context.
    176 	 */
    177 	dns_rdatacallbacks_t axfr;
    178 
    179 	struct {
    180 		uint32_t request_serial;
    181 		uint32_t current_serial;
    182 		dns_journal_t *journal;
    183 	} ixfr;
    184 };
    185 
    186 #define XFRIN_MAGIC    ISC_MAGIC('X', 'f', 'r', 'I')
    187 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
    188 
    189 /**************************************************************************/
    190 /*
    191  * Forward declarations.
    192  */
    193 
    194 static isc_result_t
    195 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
    196 	     isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
    197 	     dns_name_t *zonename, dns_rdataclass_t rdclass,
    198 	     dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
    199 	     const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
    200 	     dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp);
    201 
    202 static isc_result_t
    203 axfr_init(dns_xfrin_ctx_t *xfr);
    204 static isc_result_t
    205 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
    206 static isc_result_t
    207 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
    208 	     dns_ttl_t ttl, dns_rdata_t *rdata);
    209 static isc_result_t
    210 axfr_apply(dns_xfrin_ctx_t *xfr);
    211 static isc_result_t
    212 axfr_commit(dns_xfrin_ctx_t *xfr);
    213 static isc_result_t
    214 axfr_finalize(dns_xfrin_ctx_t *xfr);
    215 
    216 static isc_result_t
    217 ixfr_init(dns_xfrin_ctx_t *xfr);
    218 static isc_result_t
    219 ixfr_apply(dns_xfrin_ctx_t *xfr);
    220 static isc_result_t
    221 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
    222 	     dns_ttl_t ttl, dns_rdata_t *rdata);
    223 static isc_result_t
    224 ixfr_commit(dns_xfrin_ctx_t *xfr);
    225 
    226 static isc_result_t
    227 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
    228        dns_rdata_t *rdata);
    229 
    230 static isc_result_t
    231 xfrin_start(dns_xfrin_ctx_t *xfr);
    232 
    233 static void
    234 xfrin_connect_done(isc_task_t *task, isc_event_t *event);
    235 static isc_result_t
    236 xfrin_send_request(dns_xfrin_ctx_t *xfr);
    237 static void
    238 xfrin_send_done(isc_task_t *task, isc_event_t *event);
    239 static void
    240 xfrin_recv_done(isc_task_t *task, isc_event_t *event);
    241 static void
    242 xfrin_timeout(isc_task_t *task, isc_event_t *event);
    243 
    244 static void
    245 maybe_free(dns_xfrin_ctx_t *xfr);
    246 
    247 static void
    248 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
    249 static isc_result_t
    250 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
    251 
    252 static void
    253 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
    254 	   const char *fmt, va_list ap) ISC_FORMAT_PRINTF(4, 0);
    255 
    256 static void
    257 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
    258 	   const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
    259 
    260 static void
    261 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
    262 	ISC_FORMAT_PRINTF(3, 4);
    263 
    264 /**************************************************************************/
    265 /*
    266  * AXFR handling
    267  */
    268 
    269 static isc_result_t
    270 axfr_init(dns_xfrin_ctx_t *xfr) {
    271 	isc_result_t result;
    272 
    273 	xfr->is_ixfr = false;
    274 
    275 	if (xfr->db != NULL) {
    276 		dns_db_detach(&xfr->db);
    277 	}
    278 
    279 	CHECK(axfr_makedb(xfr, &xfr->db));
    280 	dns_rdatacallbacks_init(&xfr->axfr);
    281 	CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
    282 	result = ISC_R_SUCCESS;
    283 failure:
    284 	return (result);
    285 }
    286 
    287 static isc_result_t
    288 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
    289 	isc_result_t result;
    290 
    291 	result = dns_db_create(xfr->mctx, /* XXX */
    292 			       "rbt",	  /* XXX guess */
    293 			       &xfr->name, dns_dbtype_zone, xfr->rdclass, 0,
    294 			       NULL, /* XXX guess */
    295 			       dbp);
    296 	if (result == ISC_R_SUCCESS) {
    297 		dns_zone_rpz_enable_db(xfr->zone, *dbp);
    298 		dns_zone_catz_enable_db(xfr->zone, *dbp);
    299 	}
    300 	return (result);
    301 }
    302 
    303 static isc_result_t
    304 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
    305 	     dns_ttl_t ttl, dns_rdata_t *rdata) {
    306 	isc_result_t result;
    307 
    308 	dns_difftuple_t *tuple = NULL;
    309 
    310 	if (rdata->rdclass != xfr->rdclass) {
    311 		return (DNS_R_BADCLASS);
    312 	}
    313 
    314 	CHECK(dns_zone_checknames(xfr->zone, name, rdata));
    315 	CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
    316 				   &tuple));
    317 	dns_diff_append(&xfr->diff, &tuple);
    318 	if (++xfr->difflen > 100) {
    319 		CHECK(axfr_apply(xfr));
    320 	}
    321 	result = ISC_R_SUCCESS;
    322 failure:
    323 	return (result);
    324 }
    325 
    326 /*
    327  * Store a set of AXFR RRs in the database.
    328  */
    329 static isc_result_t
    330 axfr_apply(dns_xfrin_ctx_t *xfr) {
    331 	isc_result_t result;
    332 	uint64_t records;
    333 
    334 	CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private));
    335 	xfr->difflen = 0;
    336 	dns_diff_clear(&xfr->diff);
    337 	if (xfr->maxrecords != 0U) {
    338 		result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
    339 		if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
    340 			result = DNS_R_TOOMANYRECORDS;
    341 			goto failure;
    342 		}
    343 	}
    344 	result = ISC_R_SUCCESS;
    345 failure:
    346 	return (result);
    347 }
    348 
    349 static isc_result_t
    350 axfr_commit(dns_xfrin_ctx_t *xfr) {
    351 	isc_result_t result;
    352 
    353 	CHECK(axfr_apply(xfr));
    354 	CHECK(dns_db_endload(xfr->db, &xfr->axfr));
    355 	CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL));
    356 
    357 	result = ISC_R_SUCCESS;
    358 failure:
    359 	return (result);
    360 }
    361 
    362 static isc_result_t
    363 axfr_finalize(dns_xfrin_ctx_t *xfr) {
    364 	isc_result_t result;
    365 
    366 	CHECK(dns_zone_replacedb(xfr->zone, xfr->db, true));
    367 
    368 	result = ISC_R_SUCCESS;
    369 failure:
    370 	return (result);
    371 }
    372 
    373 /**************************************************************************/
    374 /*
    375  * IXFR handling
    376  */
    377 
    378 static isc_result_t
    379 ixfr_init(dns_xfrin_ctx_t *xfr) {
    380 	isc_result_t result;
    381 	char *journalfile;
    382 
    383 	if (xfr->reqtype != dns_rdatatype_ixfr) {
    384 		xfrin_log(xfr, ISC_LOG_ERROR,
    385 			  "got incremental response to AXFR request");
    386 		return (DNS_R_FORMERR);
    387 	}
    388 
    389 	xfr->is_ixfr = true;
    390 	INSIST(xfr->db != NULL);
    391 	xfr->difflen = 0;
    392 
    393 	journalfile = dns_zone_getjournal(xfr->zone);
    394 	if (journalfile != NULL) {
    395 		CHECK(dns_journal_open(xfr->mctx, journalfile,
    396 				       DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
    397 	}
    398 
    399 	result = ISC_R_SUCCESS;
    400 failure:
    401 	return (result);
    402 }
    403 
    404 static isc_result_t
    405 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
    406 	     dns_ttl_t ttl, dns_rdata_t *rdata) {
    407 	isc_result_t result;
    408 	dns_difftuple_t *tuple = NULL;
    409 
    410 	if (rdata->rdclass != xfr->rdclass) {
    411 		return (DNS_R_BADCLASS);
    412 	}
    413 
    414 	if (op == DNS_DIFFOP_ADD) {
    415 		CHECK(dns_zone_checknames(xfr->zone, name, rdata));
    416 	}
    417 	CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
    418 				   &tuple));
    419 	dns_diff_append(&xfr->diff, &tuple);
    420 	if (++xfr->difflen > 100) {
    421 		CHECK(ixfr_apply(xfr));
    422 	}
    423 	result = ISC_R_SUCCESS;
    424 failure:
    425 	return (result);
    426 }
    427 
    428 /*
    429  * Apply a set of IXFR changes to the database.
    430  */
    431 static isc_result_t
    432 ixfr_apply(dns_xfrin_ctx_t *xfr) {
    433 	isc_result_t result;
    434 	uint64_t records;
    435 
    436 	if (xfr->ver == NULL) {
    437 		CHECK(dns_db_newversion(xfr->db, &xfr->ver));
    438 		if (xfr->ixfr.journal != NULL) {
    439 			CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
    440 		}
    441 	}
    442 	CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
    443 	if (xfr->maxrecords != 0U) {
    444 		result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
    445 		if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
    446 			result = DNS_R_TOOMANYRECORDS;
    447 			goto failure;
    448 		}
    449 	}
    450 	if (xfr->ixfr.journal != NULL) {
    451 		result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
    452 		if (result != ISC_R_SUCCESS) {
    453 			goto failure;
    454 		}
    455 	}
    456 	dns_diff_clear(&xfr->diff);
    457 	xfr->difflen = 0;
    458 	result = ISC_R_SUCCESS;
    459 failure:
    460 	return (result);
    461 }
    462 
    463 static isc_result_t
    464 ixfr_commit(dns_xfrin_ctx_t *xfr) {
    465 	isc_result_t result;
    466 
    467 	CHECK(ixfr_apply(xfr));
    468 	if (xfr->ver != NULL) {
    469 		CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver));
    470 		/* XXX enter ready-to-commit state here */
    471 		if (xfr->ixfr.journal != NULL) {
    472 			CHECK(dns_journal_commit(xfr->ixfr.journal));
    473 		}
    474 		dns_db_closeversion(xfr->db, &xfr->ver, true);
    475 		dns_zone_markdirty(xfr->zone);
    476 	}
    477 	result = ISC_R_SUCCESS;
    478 failure:
    479 	return (result);
    480 }
    481 
    482 /**************************************************************************/
    483 /*
    484  * Common AXFR/IXFR protocol code
    485  */
    486 
    487 /*
    488  * Handle a single incoming resource record according to the current
    489  * state.
    490  */
    491 static isc_result_t
    492 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
    493        dns_rdata_t *rdata) {
    494 	isc_result_t result;
    495 
    496 	xfr->nrecs++;
    497 
    498 	if (rdata->type == dns_rdatatype_none ||
    499 	    dns_rdatatype_ismeta(rdata->type)) {
    500 		FAIL(DNS_R_FORMERR);
    501 	}
    502 
    503 	/*
    504 	 * Immediately reject the entire transfer if the RR that is currently
    505 	 * being processed is an SOA record that is not placed at the zone
    506 	 * apex.
    507 	 */
    508 	if (rdata->type == dns_rdatatype_soa &&
    509 	    !dns_name_equal(&xfr->name, name)) {
    510 		char namebuf[DNS_NAME_FORMATSIZE];
    511 		dns_name_format(name, namebuf, sizeof(namebuf));
    512 		xfrin_log(xfr, ISC_LOG_DEBUG(3), "SOA name mismatch: '%s'",
    513 			  namebuf);
    514 		FAIL(DNS_R_NOTZONETOP);
    515 	}
    516 
    517 redo:
    518 	switch (xfr->state) {
    519 	case XFRST_SOAQUERY:
    520 		if (rdata->type != dns_rdatatype_soa) {
    521 			xfrin_log(xfr, ISC_LOG_ERROR,
    522 				  "non-SOA response to SOA query");
    523 			FAIL(DNS_R_FORMERR);
    524 		}
    525 		xfr->end_serial = dns_soa_getserial(rdata);
    526 		if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
    527 		    !dns_zone_isforced(xfr->zone))
    528 		{
    529 			xfrin_log(xfr, ISC_LOG_DEBUG(3),
    530 				  "requested serial %u, "
    531 				  "master has %u, not updating",
    532 				  xfr->ixfr.request_serial, xfr->end_serial);
    533 			FAIL(DNS_R_UPTODATE);
    534 		}
    535 		xfr->state = XFRST_GOTSOA;
    536 		break;
    537 
    538 	case XFRST_GOTSOA:
    539 		/*
    540 		 * Skip other records in the answer section.
    541 		 */
    542 		break;
    543 
    544 	case XFRST_INITIALSOA:
    545 		if (rdata->type != dns_rdatatype_soa) {
    546 			xfrin_log(xfr, ISC_LOG_ERROR,
    547 				  "first RR in zone transfer must be SOA");
    548 			FAIL(DNS_R_FORMERR);
    549 		}
    550 		/*
    551 		 * Remember the serial number in the initial SOA.
    552 		 * We need it to recognize the end of an IXFR.
    553 		 */
    554 		xfr->end_serial = dns_soa_getserial(rdata);
    555 		if (xfr->reqtype == dns_rdatatype_ixfr &&
    556 		    !DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
    557 		    !dns_zone_isforced(xfr->zone))
    558 		{
    559 			/*
    560 			 * This must be the single SOA record that is
    561 			 * sent when the current version on the master
    562 			 * is not newer than the version in the request.
    563 			 */
    564 			xfrin_log(xfr, ISC_LOG_DEBUG(3),
    565 				  "requested serial %u, "
    566 				  "master has %u, not updating",
    567 				  xfr->ixfr.request_serial, xfr->end_serial);
    568 			FAIL(DNS_R_UPTODATE);
    569 		}
    570 		if (xfr->reqtype == dns_rdatatype_axfr) {
    571 			xfr->checkid = false;
    572 		}
    573 		xfr->state = XFRST_FIRSTDATA;
    574 		break;
    575 
    576 	case XFRST_FIRSTDATA:
    577 		/*
    578 		 * If the transfer begins with one SOA record, it is an AXFR,
    579 		 * if it begins with two SOAs, it is an IXFR.
    580 		 */
    581 		if (xfr->reqtype == dns_rdatatype_ixfr &&
    582 		    rdata->type == dns_rdatatype_soa &&
    583 		    xfr->ixfr.request_serial == dns_soa_getserial(rdata))
    584 		{
    585 			xfrin_log(xfr, ISC_LOG_DEBUG(3),
    586 				  "got incremental response");
    587 			CHECK(ixfr_init(xfr));
    588 			xfr->state = XFRST_IXFR_DELSOA;
    589 		} else {
    590 			xfrin_log(xfr, ISC_LOG_DEBUG(3),
    591 				  "got nonincremental response");
    592 			CHECK(axfr_init(xfr));
    593 			xfr->state = XFRST_AXFR;
    594 		}
    595 		goto redo;
    596 
    597 	case XFRST_IXFR_DELSOA:
    598 		INSIST(rdata->type == dns_rdatatype_soa);
    599 		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
    600 		xfr->state = XFRST_IXFR_DEL;
    601 		break;
    602 
    603 	case XFRST_IXFR_DEL:
    604 		if (rdata->type == dns_rdatatype_soa) {
    605 			uint32_t soa_serial = dns_soa_getserial(rdata);
    606 			xfr->state = XFRST_IXFR_ADDSOA;
    607 			xfr->ixfr.current_serial = soa_serial;
    608 			goto redo;
    609 		}
    610 		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
    611 		break;
    612 
    613 	case XFRST_IXFR_ADDSOA:
    614 		INSIST(rdata->type == dns_rdatatype_soa);
    615 		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
    616 		xfr->state = XFRST_IXFR_ADD;
    617 		break;
    618 
    619 	case XFRST_IXFR_ADD:
    620 		if (rdata->type == dns_rdatatype_soa) {
    621 			uint32_t soa_serial = dns_soa_getserial(rdata);
    622 			if (soa_serial == xfr->end_serial) {
    623 				CHECK(ixfr_commit(xfr));
    624 				xfr->state = XFRST_IXFR_END;
    625 				break;
    626 			} else if (soa_serial != xfr->ixfr.current_serial) {
    627 				xfrin_log(xfr, ISC_LOG_ERROR,
    628 					  "IXFR out of sync: "
    629 					  "expected serial %u, got %u",
    630 					  xfr->ixfr.current_serial, soa_serial);
    631 				FAIL(DNS_R_FORMERR);
    632 			} else {
    633 				CHECK(ixfr_commit(xfr));
    634 				xfr->state = XFRST_IXFR_DELSOA;
    635 				goto redo;
    636 			}
    637 		}
    638 		if (rdata->type == dns_rdatatype_ns &&
    639 		    dns_name_iswildcard(name)) {
    640 			FAIL(DNS_R_INVALIDNS);
    641 		}
    642 		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
    643 		break;
    644 
    645 	case XFRST_AXFR:
    646 		/*
    647 		 * Old BINDs sent cross class A records for non IN classes.
    648 		 */
    649 		if (rdata->type == dns_rdatatype_a &&
    650 		    rdata->rdclass != xfr->rdclass &&
    651 		    xfr->rdclass != dns_rdataclass_in)
    652 		{
    653 			break;
    654 		}
    655 		CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
    656 		if (rdata->type == dns_rdatatype_soa) {
    657 			CHECK(axfr_commit(xfr));
    658 			xfr->state = XFRST_AXFR_END;
    659 			break;
    660 		}
    661 		break;
    662 	case XFRST_AXFR_END:
    663 	case XFRST_IXFR_END:
    664 		FAIL(DNS_R_EXTRADATA);
    665 	/* NOTREACHED */
    666 	/* FALLTHROUGH */
    667 	default:
    668 		INSIST(0);
    669 		ISC_UNREACHABLE();
    670 	}
    671 	result = ISC_R_SUCCESS;
    672 failure:
    673 	return (result);
    674 }
    675 
    676 isc_result_t
    677 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
    678 		 const isc_sockaddr_t *masteraddr,
    679 		 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
    680 		 dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
    681 		 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
    682 		 isc_task_t *task, dns_xfrindone_t done,
    683 		 dns_xfrin_ctx_t **xfrp) {
    684 	dns_name_t *zonename = dns_zone_getorigin(zone);
    685 	dns_xfrin_ctx_t *xfr = NULL;
    686 	isc_result_t result;
    687 	dns_db_t *db = NULL;
    688 
    689 	REQUIRE(xfrp != NULL && *xfrp == NULL);
    690 
    691 	(void)dns_zone_getdb(zone, &db);
    692 
    693 	if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) {
    694 		REQUIRE(db != NULL);
    695 	}
    696 
    697 	CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
    698 			   dns_zone_getclass(zone), xfrtype, masteraddr,
    699 			   sourceaddr, dscp, tsigkey, &xfr));
    700 
    701 	if (db != NULL) {
    702 		xfr->zone_had_db = true;
    703 	}
    704 
    705 	CHECK(xfrin_start(xfr));
    706 
    707 	xfr->done = done;
    708 	if (xfr->done != NULL) {
    709 		xfr->refcount++;
    710 	}
    711 	*xfrp = xfr;
    712 
    713 failure:
    714 	if (db != NULL) {
    715 		dns_db_detach(&db);
    716 	}
    717 	if (result != ISC_R_SUCCESS) {
    718 		char zonetext[DNS_NAME_MAXTEXT + 32];
    719 		dns_zone_name(zone, zonetext, sizeof(zonetext));
    720 		xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
    721 			   "zone transfer setup failed");
    722 	}
    723 	return (result);
    724 }
    725 
    726 void
    727 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
    728 	if (!xfr->shuttingdown) {
    729 		xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
    730 	}
    731 }
    732 
    733 void
    734 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
    735 	REQUIRE(target != NULL && *target == NULL);
    736 	source->refcount++;
    737 	*target = source;
    738 }
    739 
    740 void
    741 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
    742 	dns_xfrin_ctx_t *xfr = *xfrp;
    743 	*xfrp = NULL;
    744 	INSIST(xfr->refcount > 0);
    745 	xfr->refcount--;
    746 	maybe_free(xfr);
    747 }
    748 
    749 static void
    750 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
    751 	if (xfr->connects > 0) {
    752 		isc_socket_cancel(xfr->socket, xfr->task,
    753 				  ISC_SOCKCANCEL_CONNECT);
    754 	} else if (xfr->recvs > 0) {
    755 		dns_tcpmsg_cancelread(&xfr->tcpmsg);
    756 	} else if (xfr->sends > 0) {
    757 		isc_socket_cancel(xfr->socket, xfr->task, ISC_SOCKCANCEL_SEND);
    758 	}
    759 }
    760 
    761 static void
    762 xfrin_reset(dns_xfrin_ctx_t *xfr) {
    763 	REQUIRE(VALID_XFRIN(xfr));
    764 
    765 	xfrin_log(xfr, ISC_LOG_INFO, "resetting");
    766 
    767 	xfrin_cancelio(xfr);
    768 
    769 	if (xfr->socket != NULL) {
    770 		isc_socket_detach(&xfr->socket);
    771 	}
    772 
    773 	if (xfr->lasttsig != NULL) {
    774 		isc_buffer_free(&xfr->lasttsig);
    775 	}
    776 
    777 	dns_diff_clear(&xfr->diff);
    778 	xfr->difflen = 0;
    779 
    780 	if (xfr->ixfr.journal != NULL) {
    781 		dns_journal_destroy(&xfr->ixfr.journal);
    782 	}
    783 
    784 	if (xfr->axfr.add_private != NULL) {
    785 		(void)dns_db_endload(xfr->db, &xfr->axfr);
    786 	}
    787 
    788 	if (xfr->tcpmsg_valid) {
    789 		dns_tcpmsg_invalidate(&xfr->tcpmsg);
    790 		xfr->tcpmsg_valid = false;
    791 	}
    792 
    793 	if (xfr->ver != NULL) {
    794 		dns_db_closeversion(xfr->db, &xfr->ver, false);
    795 	}
    796 }
    797 
    798 static void
    799 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
    800 	if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) {
    801 		xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
    802 			  isc_result_totext(result));
    803 		if (xfr->is_ixfr) {
    804 			/* Pass special result code to force AXFR retry */
    805 			result = DNS_R_BADIXFR;
    806 		}
    807 	}
    808 	xfrin_cancelio(xfr);
    809 	/*
    810 	 * Close the journal.
    811 	 */
    812 	if (xfr->ixfr.journal != NULL) {
    813 		dns_journal_destroy(&xfr->ixfr.journal);
    814 	}
    815 	if (xfr->done != NULL) {
    816 		(xfr->done)(xfr->zone, result);
    817 		xfr->done = NULL;
    818 	}
    819 	xfr->shuttingdown = true;
    820 	xfr->shutdown_result = result;
    821 	maybe_free(xfr);
    822 }
    823 
    824 static isc_result_t
    825 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
    826 	     isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
    827 	     dns_name_t *zonename, dns_rdataclass_t rdclass,
    828 	     dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
    829 	     const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
    830 	     dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp) {
    831 	dns_xfrin_ctx_t *xfr = NULL;
    832 	isc_result_t result;
    833 
    834 	xfr = isc_mem_get(mctx, sizeof(*xfr));
    835 	xfr->mctx = NULL;
    836 	isc_mem_attach(mctx, &xfr->mctx);
    837 	xfr->refcount = 0;
    838 	xfr->zone = NULL;
    839 	dns_zone_iattach(zone, &xfr->zone);
    840 	xfr->task = NULL;
    841 	isc_task_attach(task, &xfr->task);
    842 	xfr->timer = NULL;
    843 	xfr->socketmgr = socketmgr;
    844 	xfr->done = NULL;
    845 
    846 	xfr->connects = 0;
    847 	xfr->sends = 0;
    848 	xfr->recvs = 0;
    849 	xfr->shuttingdown = false;
    850 	xfr->shutdown_result = ISC_R_UNSET;
    851 
    852 	dns_name_init(&xfr->name, NULL);
    853 	xfr->rdclass = rdclass;
    854 	xfr->checkid = true;
    855 	xfr->logit = true;
    856 	xfr->id = (dns_messageid_t)isc_random16();
    857 	xfr->reqtype = reqtype;
    858 	xfr->dscp = dscp;
    859 
    860 	/* sockaddr */
    861 	xfr->socket = NULL;
    862 	/* qbuffer */
    863 	/* qbuffer_data */
    864 	/* tcpmsg */
    865 	xfr->tcpmsg_valid = false;
    866 
    867 	xfr->zone_had_db = false;
    868 	xfr->db = NULL;
    869 	if (db != NULL) {
    870 		dns_db_attach(db, &xfr->db);
    871 	}
    872 	xfr->ver = NULL;
    873 	dns_diff_init(xfr->mctx, &xfr->diff);
    874 	xfr->difflen = 0;
    875 
    876 	if (reqtype == dns_rdatatype_soa) {
    877 		xfr->state = XFRST_SOAQUERY;
    878 	} else {
    879 		xfr->state = XFRST_INITIALSOA;
    880 	}
    881 	/* end_serial */
    882 
    883 	xfr->nmsg = 0;
    884 	xfr->nrecs = 0;
    885 	xfr->nbytes = 0;
    886 	xfr->maxrecords = dns_zone_getmaxrecords(zone);
    887 	isc_time_now(&xfr->start);
    888 
    889 	xfr->tsigkey = NULL;
    890 	if (tsigkey != NULL) {
    891 		dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
    892 	}
    893 	xfr->lasttsig = NULL;
    894 	xfr->tsigctx = NULL;
    895 	xfr->sincetsig = 0;
    896 	xfr->is_ixfr = false;
    897 
    898 	/* ixfr.request_serial */
    899 	/* ixfr.current_serial */
    900 	xfr->ixfr.journal = NULL;
    901 
    902 	xfr->axfr.add = NULL;
    903 	xfr->axfr.add_private = NULL;
    904 
    905 	dns_name_dup(zonename, mctx, &xfr->name);
    906 
    907 	CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
    908 			       task, xfrin_timeout, xfr, &xfr->timer));
    909 	CHECK(dns_timer_setidle(xfr->timer, dns_zone_getmaxxfrin(xfr->zone),
    910 				dns_zone_getidlein(xfr->zone), false));
    911 
    912 	xfr->masteraddr = *masteraddr;
    913 
    914 	INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
    915 	xfr->sourceaddr = *sourceaddr;
    916 	isc_sockaddr_setport(&xfr->sourceaddr, 0);
    917 
    918 	/*
    919 	 * Reserve 2 bytes for TCP length at the beginning of the buffer.
    920 	 */
    921 	isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
    922 			sizeof(xfr->qbuffer_data) - 2);
    923 
    924 	xfr->magic = XFRIN_MAGIC;
    925 	*xfrp = xfr;
    926 	return (ISC_R_SUCCESS);
    927 
    928 failure:
    929 	if (xfr->timer != NULL) {
    930 		isc_timer_detach(&xfr->timer);
    931 	}
    932 	if (dns_name_dynamic(&xfr->name)) {
    933 		dns_name_free(&xfr->name, xfr->mctx);
    934 	}
    935 	if (xfr->tsigkey != NULL) {
    936 		dns_tsigkey_detach(&xfr->tsigkey);
    937 	}
    938 	if (xfr->db != NULL) {
    939 		dns_db_detach(&xfr->db);
    940 	}
    941 	isc_task_detach(&xfr->task);
    942 	dns_zone_idetach(&xfr->zone);
    943 	isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
    944 
    945 	return (result);
    946 }
    947 
    948 static isc_result_t
    949 xfrin_start(dns_xfrin_ctx_t *xfr) {
    950 	isc_result_t result;
    951 	CHECK(isc_socket_create(xfr->socketmgr,
    952 				isc_sockaddr_pf(&xfr->sourceaddr),
    953 				isc_sockettype_tcp, &xfr->socket));
    954 	isc_socket_setname(xfr->socket, "xfrin", NULL);
    955 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
    956 	CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
    957 			      ISC_SOCKET_REUSEADDRESS));
    958 #endif /* ifndef BROKEN_TCP_BIND_BEFORE_CONNECT */
    959 	isc_socket_dscp(xfr->socket, xfr->dscp);
    960 	CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
    961 				 xfrin_connect_done, xfr));
    962 	xfr->connects++;
    963 	return (ISC_R_SUCCESS);
    964 failure:
    965 	xfrin_fail(xfr, result, "failed setting up socket");
    966 	return (result);
    967 }
    968 
    969 /* XXX the resolver could use this, too */
    970 
    971 static isc_result_t
    972 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
    973 	dns_compress_t cctx;
    974 	bool cleanup_cctx = false;
    975 	isc_result_t result;
    976 
    977 	CHECK(dns_compress_init(&cctx, -1, mctx));
    978 	cleanup_cctx = true;
    979 	CHECK(dns_message_renderbegin(msg, &cctx, buf));
    980 	CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
    981 	CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
    982 	CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
    983 	CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
    984 	CHECK(dns_message_renderend(msg));
    985 	result = ISC_R_SUCCESS;
    986 failure:
    987 	if (cleanup_cctx) {
    988 		dns_compress_invalidate(&cctx);
    989 	}
    990 	return (result);
    991 }
    992 
    993 /*
    994  * A connection has been established.
    995  */
    996 static void
    997 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
    998 	isc_socket_connev_t *cev = (isc_socket_connev_t *)event;
    999 	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
   1000 	isc_result_t result = cev->result;
   1001 	char sourcetext[ISC_SOCKADDR_FORMATSIZE];
   1002 	char signerbuf[DNS_NAME_FORMATSIZE];
   1003 	const char *signer = "", *sep = "";
   1004 	isc_sockaddr_t sockaddr;
   1005 	dns_zonemgr_t *zmgr;
   1006 	isc_time_t now;
   1007 
   1008 	REQUIRE(VALID_XFRIN(xfr));
   1009 
   1010 	UNUSED(task);
   1011 
   1012 	INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
   1013 	isc_event_free(&event);
   1014 
   1015 	xfr->connects--;
   1016 	if (xfr->shuttingdown) {
   1017 		maybe_free(xfr);
   1018 		return;
   1019 	}
   1020 
   1021 	zmgr = dns_zone_getmgr(xfr->zone);
   1022 	if (zmgr != NULL) {
   1023 		if (result != ISC_R_SUCCESS) {
   1024 			TIME_NOW(&now);
   1025 			dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
   1026 						   &xfr->sourceaddr, &now);
   1027 			goto failure;
   1028 		} else {
   1029 			dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
   1030 						   &xfr->sourceaddr);
   1031 		}
   1032 	}
   1033 
   1034 	result = isc_socket_getsockname(xfr->socket, &sockaddr);
   1035 	if (result == ISC_R_SUCCESS) {
   1036 		isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
   1037 	} else {
   1038 		strlcpy(sourcetext, "<UNKNOWN>", sizeof(sourcetext));
   1039 	}
   1040 
   1041 	if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
   1042 		dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
   1043 				sizeof(signerbuf));
   1044 		sep = " TSIG ";
   1045 		signer = signerbuf;
   1046 	}
   1047 
   1048 	xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", sourcetext, sep,
   1049 		  signer);
   1050 
   1051 	dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
   1052 	xfr->tcpmsg_valid = true;
   1053 
   1054 	CHECK(xfrin_send_request(xfr));
   1055 failure:
   1056 	if (result != ISC_R_SUCCESS) {
   1057 		xfrin_fail(xfr, result, "failed to connect");
   1058 	}
   1059 }
   1060 
   1061 /*
   1062  * Convert a tuple into a dns_name_t suitable for inserting
   1063  * into the given dns_message_t.
   1064  */
   1065 static isc_result_t
   1066 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
   1067 	isc_result_t result;
   1068 	dns_rdata_t *rdata = NULL;
   1069 	dns_rdatalist_t *rdl = NULL;
   1070 	dns_rdataset_t *rds = NULL;
   1071 	dns_name_t *name = NULL;
   1072 
   1073 	REQUIRE(target != NULL && *target == NULL);
   1074 
   1075 	CHECK(dns_message_gettemprdata(msg, &rdata));
   1076 	dns_rdata_init(rdata);
   1077 	dns_rdata_clone(&tuple->rdata, rdata);
   1078 
   1079 	CHECK(dns_message_gettemprdatalist(msg, &rdl));
   1080 	dns_rdatalist_init(rdl);
   1081 	rdl->type = tuple->rdata.type;
   1082 	rdl->rdclass = tuple->rdata.rdclass;
   1083 	rdl->ttl = tuple->ttl;
   1084 	ISC_LIST_APPEND(rdl->rdata, rdata, link);
   1085 
   1086 	CHECK(dns_message_gettemprdataset(msg, &rds));
   1087 	CHECK(dns_rdatalist_tordataset(rdl, rds));
   1088 
   1089 	CHECK(dns_message_gettempname(msg, &name));
   1090 	dns_name_init(name, NULL);
   1091 	dns_name_clone(&tuple->name, name);
   1092 	ISC_LIST_APPEND(name->list, rds, link);
   1093 
   1094 	*target = name;
   1095 	return (ISC_R_SUCCESS);
   1096 
   1097 failure:
   1098 
   1099 	if (rds != NULL) {
   1100 		dns_rdataset_disassociate(rds);
   1101 		dns_message_puttemprdataset(msg, &rds);
   1102 	}
   1103 	if (rdl != NULL) {
   1104 		ISC_LIST_UNLINK(rdl->rdata, rdata, link);
   1105 		dns_message_puttemprdatalist(msg, &rdl);
   1106 	}
   1107 	if (rdata != NULL) {
   1108 		dns_message_puttemprdata(msg, &rdata);
   1109 	}
   1110 
   1111 	return (result);
   1112 }
   1113 
   1114 /*
   1115  * Build an *XFR request and send its length prefix.
   1116  */
   1117 static isc_result_t
   1118 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
   1119 	isc_result_t result;
   1120 	isc_region_t region;
   1121 	dns_rdataset_t *qrdataset = NULL;
   1122 	dns_message_t *msg = NULL;
   1123 	dns_difftuple_t *soatuple = NULL;
   1124 	dns_name_t *qname = NULL;
   1125 	dns_dbversion_t *ver = NULL;
   1126 	dns_name_t *msgsoaname = NULL;
   1127 
   1128 	/* Create the request message */
   1129 	dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg);
   1130 	CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
   1131 
   1132 	/* Create a name for the question section. */
   1133 	CHECK(dns_message_gettempname(msg, &qname));
   1134 	dns_name_init(qname, NULL);
   1135 	dns_name_clone(&xfr->name, qname);
   1136 
   1137 	/* Formulate the question and attach it to the question name. */
   1138 	CHECK(dns_message_gettemprdataset(msg, &qrdataset));
   1139 	dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
   1140 	ISC_LIST_APPEND(qname->list, qrdataset, link);
   1141 	qrdataset = NULL;
   1142 
   1143 	dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
   1144 	qname = NULL;
   1145 
   1146 	if (xfr->reqtype == dns_rdatatype_ixfr) {
   1147 		/* Get the SOA and add it to the authority section. */
   1148 		/* XXX is using the current version the right thing? */
   1149 		dns_db_currentversion(xfr->db, &ver);
   1150 		CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
   1151 					    DNS_DIFFOP_EXISTS, &soatuple));
   1152 		xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
   1153 		xfr->ixfr.current_serial = xfr->ixfr.request_serial;
   1154 		xfrin_log(xfr, ISC_LOG_DEBUG(3),
   1155 			  "requesting IXFR for serial %u",
   1156 			  xfr->ixfr.request_serial);
   1157 
   1158 		CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
   1159 		dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
   1160 	} else if (xfr->reqtype == dns_rdatatype_soa) {
   1161 		CHECK(dns_db_getsoaserial(xfr->db, NULL,
   1162 					  &xfr->ixfr.request_serial));
   1163 	}
   1164 
   1165 	xfr->checkid = true;
   1166 	xfr->logit = true;
   1167 	xfr->id++;
   1168 	xfr->nmsg = 0;
   1169 	xfr->nrecs = 0;
   1170 	xfr->nbytes = 0;
   1171 	isc_time_now(&xfr->start);
   1172 	msg->id = xfr->id;
   1173 	if (xfr->tsigctx != NULL) {
   1174 		dst_context_destroy(&xfr->tsigctx);
   1175 	}
   1176 
   1177 	CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
   1178 
   1179 	/*
   1180 	 * Free the last tsig, if there is one.
   1181 	 */
   1182 	if (xfr->lasttsig != NULL) {
   1183 		isc_buffer_free(&xfr->lasttsig);
   1184 	}
   1185 
   1186 	/*
   1187 	 * Save the query TSIG and don't let message_destroy free it.
   1188 	 */
   1189 	CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
   1190 
   1191 	isc_buffer_usedregion(&xfr->qbuffer, &region);
   1192 	INSIST(region.length <= 65535);
   1193 
   1194 	/*
   1195 	 * Record message length and adjust region to include TCP
   1196 	 * length field.
   1197 	 */
   1198 	xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
   1199 	xfr->qbuffer_data[1] = region.length & 0xff;
   1200 	region.base -= 2;
   1201 	region.length += 2;
   1202 	CHECK(isc_socket_send(xfr->socket, &region, xfr->task, xfrin_send_done,
   1203 			      xfr));
   1204 	xfr->sends++;
   1205 
   1206 failure:
   1207 	if (qname != NULL) {
   1208 		dns_message_puttempname(msg, &qname);
   1209 	}
   1210 	if (qrdataset != NULL) {
   1211 		dns_message_puttemprdataset(msg, &qrdataset);
   1212 	}
   1213 	if (msg != NULL) {
   1214 		dns_message_detach(&msg);
   1215 	}
   1216 	if (soatuple != NULL) {
   1217 		dns_difftuple_free(&soatuple);
   1218 	}
   1219 	if (ver != NULL) {
   1220 		dns_db_closeversion(xfr->db, &ver, false);
   1221 	}
   1222 	return (result);
   1223 }
   1224 
   1225 static void
   1226 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
   1227 	isc_socketevent_t *sev = (isc_socketevent_t *)event;
   1228 	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
   1229 	isc_result_t result;
   1230 
   1231 	REQUIRE(VALID_XFRIN(xfr));
   1232 
   1233 	UNUSED(task);
   1234 
   1235 	INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
   1236 
   1237 	xfr->sends--;
   1238 	xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
   1239 	CHECK(sev->result);
   1240 
   1241 	CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, xfrin_recv_done,
   1242 				     xfr));
   1243 	xfr->recvs++;
   1244 failure:
   1245 	isc_event_free(&event);
   1246 	if (result != ISC_R_SUCCESS) {
   1247 		xfrin_fail(xfr, result, "failed sending request data");
   1248 	}
   1249 }
   1250 
   1251 static void
   1252 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
   1253 	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)ev->ev_arg;
   1254 	isc_result_t result;
   1255 	dns_message_t *msg = NULL;
   1256 	dns_name_t *name;
   1257 	dns_tcpmsg_t *tcpmsg;
   1258 	const dns_name_t *tsigowner = NULL;
   1259 
   1260 	REQUIRE(VALID_XFRIN(xfr));
   1261 
   1262 	UNUSED(task);
   1263 
   1264 	INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
   1265 	tcpmsg = ev->ev_sender;
   1266 	isc_event_free(&ev);
   1267 
   1268 	xfr->recvs--;
   1269 	if (xfr->shuttingdown) {
   1270 		maybe_free(xfr);
   1271 		return;
   1272 	}
   1273 
   1274 	CHECK(tcpmsg->result);
   1275 
   1276 	xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
   1277 		  tcpmsg->buffer.used);
   1278 
   1279 	CHECK(isc_timer_touch(xfr->timer));
   1280 
   1281 	dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   1282 
   1283 	CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
   1284 	CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
   1285 
   1286 	msg->tsigctx = xfr->tsigctx;
   1287 	xfr->tsigctx = NULL;
   1288 
   1289 	dns_message_setclass(msg, xfr->rdclass);
   1290 
   1291 	if (xfr->nmsg > 0) {
   1292 		msg->tcp_continuation = 1;
   1293 	}
   1294 
   1295 	result = dns_message_parse(msg, &tcpmsg->buffer,
   1296 				   DNS_MESSAGEPARSE_PRESERVEORDER);
   1297 
   1298 	if (result == ISC_R_SUCCESS) {
   1299 		dns_message_logpacket(msg, "received message from",
   1300 				      &tcpmsg->address, DNS_LOGCATEGORY_XFER_IN,
   1301 				      DNS_LOGMODULE_XFER_IN, ISC_LOG_DEBUG(10),
   1302 				      xfr->mctx);
   1303 	} else {
   1304 		xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
   1305 			  dns_result_totext(result));
   1306 	}
   1307 
   1308 	if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
   1309 	    msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass ||
   1310 	    (xfr->checkid && msg->id != xfr->id))
   1311 	{
   1312 		if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
   1313 		{
   1314 			result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
   1315 		} else if (result == ISC_R_SUCCESS &&
   1316 			   msg->opcode != dns_opcode_query) {
   1317 			result = DNS_R_UNEXPECTEDOPCODE;
   1318 		} else if (result == ISC_R_SUCCESS &&
   1319 			   msg->rdclass != xfr->rdclass) {
   1320 			result = DNS_R_BADCLASS;
   1321 		} else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) {
   1322 			result = DNS_R_UNEXPECTEDID;
   1323 		}
   1324 		if (xfr->reqtype == dns_rdatatype_axfr ||
   1325 		    xfr->reqtype == dns_rdatatype_soa) {
   1326 			goto failure;
   1327 		}
   1328 		xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
   1329 			  isc_result_totext(result));
   1330 	try_axfr:
   1331 		dns_message_detach(&msg);
   1332 		xfrin_reset(xfr);
   1333 		xfr->reqtype = dns_rdatatype_soa;
   1334 		xfr->state = XFRST_SOAQUERY;
   1335 		(void)xfrin_start(xfr);
   1336 		return;
   1337 	} else if (!xfr->checkid && msg->id != xfr->id && xfr->logit) {
   1338 		xfrin_log(xfr, ISC_LOG_WARNING,
   1339 			  "detected message ID mismatch on incoming AXFR "
   1340 			  "stream, transfer will fail in BIND 9.17.2 and "
   1341 			  "later if AXFR source is not fixed");
   1342 		xfr->logit = false;
   1343 	}
   1344 
   1345 	/*
   1346 	 * Does the server know about IXFR?  If it doesn't we will get
   1347 	 * a message with a empty answer section or a potentially a CNAME /
   1348 	 * DNAME, the later is handled by xfr_rr() which will return FORMERR
   1349 	 * if the first RR in the answer section is not a SOA record.
   1350 	 */
   1351 	if (xfr->reqtype == dns_rdatatype_ixfr &&
   1352 	    xfr->state == XFRST_INITIALSOA &&
   1353 	    msg->counts[DNS_SECTION_ANSWER] == 0)
   1354 	{
   1355 		xfrin_log(xfr, ISC_LOG_DEBUG(3),
   1356 			  "empty answer section, retrying with AXFR");
   1357 		goto try_axfr;
   1358 	}
   1359 
   1360 	if (xfr->reqtype == dns_rdatatype_soa &&
   1361 	    (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   1362 		FAIL(DNS_R_NOTAUTHORITATIVE);
   1363 	}
   1364 
   1365 	result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
   1366 	if (result != ISC_R_SUCCESS) {
   1367 		xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
   1368 			  isc_result_totext(result));
   1369 		goto failure;
   1370 	}
   1371 
   1372 	for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
   1373 	     result == ISC_R_SUCCESS;
   1374 	     result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
   1375 	{
   1376 		dns_rdataset_t *rds;
   1377 
   1378 		name = NULL;
   1379 		dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
   1380 		for (rds = ISC_LIST_HEAD(name->list); rds != NULL;
   1381 		     rds = ISC_LIST_NEXT(rds, link))
   1382 		{
   1383 			for (result = dns_rdataset_first(rds);
   1384 			     result == ISC_R_SUCCESS;
   1385 			     result = dns_rdataset_next(rds))
   1386 			{
   1387 				dns_rdata_t rdata = DNS_RDATA_INIT;
   1388 				dns_rdataset_current(rds, &rdata);
   1389 				CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
   1390 			}
   1391 		}
   1392 	}
   1393 	if (result != ISC_R_NOMORE) {
   1394 		goto failure;
   1395 	}
   1396 
   1397 	if (dns_message_gettsig(msg, &tsigowner) != NULL) {
   1398 		/*
   1399 		 * Reset the counter.
   1400 		 */
   1401 		xfr->sincetsig = 0;
   1402 
   1403 		/*
   1404 		 * Free the last tsig, if there is one.
   1405 		 */
   1406 		if (xfr->lasttsig != NULL) {
   1407 			isc_buffer_free(&xfr->lasttsig);
   1408 		}
   1409 
   1410 		/*
   1411 		 * Update the last tsig pointer.
   1412 		 */
   1413 		CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
   1414 	} else if (dns_message_gettsigkey(msg) != NULL) {
   1415 		xfr->sincetsig++;
   1416 		if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
   1417 		    xfr->state == XFRST_AXFR_END ||
   1418 		    xfr->state == XFRST_IXFR_END)
   1419 		{
   1420 			result = DNS_R_EXPECTEDTSIG;
   1421 			goto failure;
   1422 		}
   1423 	}
   1424 
   1425 	/*
   1426 	 * Update the number of messages received.
   1427 	 */
   1428 	xfr->nmsg++;
   1429 
   1430 	/*
   1431 	 * Update the number of bytes received.
   1432 	 */
   1433 	xfr->nbytes += tcpmsg->buffer.used;
   1434 
   1435 	/*
   1436 	 * Take the context back.
   1437 	 */
   1438 	INSIST(xfr->tsigctx == NULL);
   1439 	xfr->tsigctx = msg->tsigctx;
   1440 	msg->tsigctx = NULL;
   1441 
   1442 	dns_message_detach(&msg);
   1443 
   1444 	switch (xfr->state) {
   1445 	case XFRST_GOTSOA:
   1446 		xfr->reqtype = dns_rdatatype_axfr;
   1447 		xfr->state = XFRST_INITIALSOA;
   1448 		CHECK(xfrin_send_request(xfr));
   1449 		break;
   1450 	case XFRST_AXFR_END:
   1451 		CHECK(axfr_finalize(xfr));
   1452 	/* FALLTHROUGH */
   1453 	case XFRST_IXFR_END:
   1454 		/*
   1455 		 * Close the journal.
   1456 		 */
   1457 		if (xfr->ixfr.journal != NULL) {
   1458 			dns_journal_destroy(&xfr->ixfr.journal);
   1459 		}
   1460 
   1461 		/*
   1462 		 * Inform the caller we succeeded.
   1463 		 */
   1464 		if (xfr->done != NULL) {
   1465 			(xfr->done)(xfr->zone, ISC_R_SUCCESS);
   1466 			xfr->done = NULL;
   1467 		}
   1468 		/*
   1469 		 * We should have no outstanding events at this
   1470 		 * point, thus maybe_free() should succeed.
   1471 		 */
   1472 		xfr->shuttingdown = true;
   1473 		xfr->shutdown_result = ISC_R_SUCCESS;
   1474 		maybe_free(xfr);
   1475 		break;
   1476 	default:
   1477 		/*
   1478 		 * Read the next message.
   1479 		 */
   1480 		CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
   1481 					     xfrin_recv_done, xfr));
   1482 		xfr->recvs++;
   1483 	}
   1484 	return;
   1485 
   1486 failure:
   1487 	if (msg != NULL) {
   1488 		dns_message_detach(&msg);
   1489 	}
   1490 	if (result != ISC_R_SUCCESS) {
   1491 		xfrin_fail(xfr, result, "failed while receiving responses");
   1492 	}
   1493 }
   1494 
   1495 static void
   1496 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
   1497 	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
   1498 
   1499 	REQUIRE(VALID_XFRIN(xfr));
   1500 
   1501 	UNUSED(task);
   1502 
   1503 	isc_event_free(&event);
   1504 	/*
   1505 	 * This will log "giving up: timeout".
   1506 	 */
   1507 	xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
   1508 }
   1509 
   1510 static void
   1511 maybe_free(dns_xfrin_ctx_t *xfr) {
   1512 	uint64_t msecs;
   1513 	uint64_t persec;
   1514 	const char *result_str;
   1515 
   1516 	REQUIRE(VALID_XFRIN(xfr));
   1517 
   1518 	if (!xfr->shuttingdown || xfr->refcount != 0 || xfr->connects != 0 ||
   1519 	    xfr->sends != 0 || xfr->recvs != 0)
   1520 	{
   1521 		return;
   1522 	}
   1523 
   1524 	INSIST(!xfr->shuttingdown || xfr->shutdown_result != ISC_R_UNSET);
   1525 
   1526 	/* If we're called through dns_xfrin_detach() and are not
   1527 	 * shutting down, we can't know what the transfer status is as
   1528 	 * we are only called when the last reference is lost.
   1529 	 */
   1530 	result_str = (xfr->shuttingdown
   1531 			      ? isc_result_totext(xfr->shutdown_result)
   1532 			      : "unknown");
   1533 	xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str);
   1534 
   1535 	/*
   1536 	 * Calculate the length of time the transfer took,
   1537 	 * and print a log message with the bytes and rate.
   1538 	 */
   1539 	isc_time_now(&xfr->end);
   1540 	msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
   1541 	if (msecs == 0) {
   1542 		msecs = 1;
   1543 	}
   1544 	persec = (xfr->nbytes * 1000) / msecs;
   1545 	xfrin_log(xfr, ISC_LOG_INFO,
   1546 		  "Transfer completed: %d messages, %d records, "
   1547 		  "%" PRIu64 " bytes, "
   1548 		  "%u.%03u secs (%u bytes/sec) (serial %u)",
   1549 		  xfr->nmsg, xfr->nrecs, xfr->nbytes,
   1550 		  (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
   1551 		  (unsigned int)persec, xfr->end_serial);
   1552 
   1553 	if (xfr->socket != NULL) {
   1554 		isc_socket_detach(&xfr->socket);
   1555 	}
   1556 
   1557 	if (xfr->timer != NULL) {
   1558 		isc_timer_detach(&xfr->timer);
   1559 	}
   1560 
   1561 	if (xfr->task != NULL) {
   1562 		isc_task_detach(&xfr->task);
   1563 	}
   1564 
   1565 	if (xfr->tsigkey != NULL) {
   1566 		dns_tsigkey_detach(&xfr->tsigkey);
   1567 	}
   1568 
   1569 	if (xfr->lasttsig != NULL) {
   1570 		isc_buffer_free(&xfr->lasttsig);
   1571 	}
   1572 
   1573 	dns_diff_clear(&xfr->diff);
   1574 
   1575 	if (xfr->ixfr.journal != NULL) {
   1576 		dns_journal_destroy(&xfr->ixfr.journal);
   1577 	}
   1578 
   1579 	if (xfr->axfr.add_private != NULL) {
   1580 		(void)dns_db_endload(xfr->db, &xfr->axfr);
   1581 	}
   1582 
   1583 	if (xfr->tcpmsg_valid) {
   1584 		dns_tcpmsg_invalidate(&xfr->tcpmsg);
   1585 	}
   1586 
   1587 	if (xfr->tsigctx != NULL) {
   1588 		dst_context_destroy(&xfr->tsigctx);
   1589 	}
   1590 
   1591 	if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) {
   1592 		dns_name_free(&xfr->name, xfr->mctx);
   1593 	}
   1594 
   1595 	if (xfr->ver != NULL) {
   1596 		dns_db_closeversion(xfr->db, &xfr->ver, false);
   1597 	}
   1598 
   1599 	if (xfr->db != NULL) {
   1600 		dns_db_detach(&xfr->db);
   1601 	}
   1602 
   1603 	if (xfr->zone != NULL) {
   1604 		if (!xfr->zone_had_db && xfr->shuttingdown &&
   1605 		    xfr->shutdown_result == ISC_R_SUCCESS &&
   1606 		    dns_zone_gettype(xfr->zone) == dns_zone_mirror)
   1607 		{
   1608 			dns_zone_log(xfr->zone, ISC_LOG_INFO,
   1609 				     "mirror zone is now in use");
   1610 		}
   1611 		xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context");
   1612 		/*
   1613 		 * xfr->zone must not be detached before xfrin_log() is called.
   1614 		 */
   1615 		dns_zone_idetach(&xfr->zone);
   1616 	}
   1617 
   1618 	isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
   1619 }
   1620 
   1621 /*
   1622  * Log incoming zone transfer messages in a format like
   1623  * transfer of <zone> from <address>: <message>
   1624  */
   1625 static void
   1626 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
   1627 	   const char *fmt, va_list ap) {
   1628 	char mastertext[ISC_SOCKADDR_FORMATSIZE];
   1629 	char msgtext[2048];
   1630 
   1631 	isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
   1632 	vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
   1633 
   1634 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
   1635 		      level, "transfer of '%s' from %s: %s", zonetext,
   1636 		      mastertext, msgtext);
   1637 }
   1638 
   1639 /*
   1640  * Logging function for use when a xfrin_ctx_t has not yet been created.
   1641  */
   1642 
   1643 static void
   1644 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
   1645 	   const char *fmt, ...) {
   1646 	va_list ap;
   1647 
   1648 	if (!isc_log_wouldlog(dns_lctx, level)) {
   1649 		return;
   1650 	}
   1651 
   1652 	va_start(ap, fmt);
   1653 	xfrin_logv(level, zonetext, masteraddr, fmt, ap);
   1654 	va_end(ap);
   1655 }
   1656 
   1657 /*
   1658  * Logging function for use when there is a xfrin_ctx_t.
   1659  */
   1660 
   1661 static void
   1662 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) {
   1663 	va_list ap;
   1664 	char zonetext[DNS_NAME_MAXTEXT + 32];
   1665 
   1666 	if (!isc_log_wouldlog(dns_lctx, level)) {
   1667 		return;
   1668 	}
   1669 
   1670 	dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
   1671 
   1672 	va_start(ap, fmt);
   1673 	xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);
   1674 	va_end(ap);
   1675 }
   1676