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