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