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