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