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