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