1/*	$NetBSD: xfrin.c,v 1.14 2024/02/21 22:52:08 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/netmgr.h>
23#include <isc/print.h>
24#include <isc/random.h>
25#include <isc/result.h>
26#include <isc/string.h> /* Required for HP/UX (and others?) */
27#include <isc/task.h>
28#include <isc/timer.h>
29#include <isc/util.h>
30
31#include <dns/callbacks.h>
32#include <dns/catz.h>
33#include <dns/db.h>
34#include <dns/diff.h>
35#include <dns/events.h>
36#include <dns/journal.h>
37#include <dns/log.h>
38#include <dns/message.h>
39#include <dns/rdataclass.h>
40#include <dns/rdatalist.h>
41#include <dns/rdataset.h>
42#include <dns/result.h>
43#include <dns/soa.h>
44#include <dns/transport.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 {                                 \
63		result = (code);             \
64		if (result != ISC_R_SUCCESS) \
65			goto failure;        \
66	} while (0)
67
68#define CHECK(op)                            \
69	do {                                 \
70		result = (op);               \
71		if (result != ISC_R_SUCCESS) \
72			goto failure;        \
73	} while (0)
74
75/*%
76 * The states of the *XFR state machine.  We handle both IXFR and AXFR
77 * with a single integrated state machine because they cannot be distinguished
78 * immediately - an AXFR response to an IXFR request can only be detected
79 * when the first two (2) response RRs have already been received.
80 */
81typedef enum {
82	XFRST_SOAQUERY,
83	XFRST_GOTSOA,
84	XFRST_INITIALSOA,
85	XFRST_FIRSTDATA,
86	XFRST_IXFR_DELSOA,
87	XFRST_IXFR_DEL,
88	XFRST_IXFR_ADDSOA,
89	XFRST_IXFR_ADD,
90	XFRST_IXFR_END,
91	XFRST_AXFR,
92	XFRST_AXFR_END
93} xfrin_state_t;
94
95/*%
96 * Incoming zone transfer context.
97 */
98
99struct dns_xfrin_ctx {
100	unsigned int magic;
101	isc_mem_t *mctx;
102	dns_zone_t *zone;
103
104	isc_refcount_t references;
105
106	isc_nm_t *netmgr;
107
108	isc_refcount_t connects; /*%< Connect in progress */
109	isc_refcount_t sends;	 /*%< Send in progress */
110	isc_refcount_t recvs;	 /*%< Receive in progress */
111
112	atomic_bool shuttingdown;
113
114	isc_result_t shutdown_result;
115
116	dns_name_t name; /*%< Name of zone to transfer */
117	dns_rdataclass_t rdclass;
118
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
128	isc_sockaddr_t primaryaddr;
129	isc_sockaddr_t sourceaddr;
130
131	isc_nmhandle_t *handle;
132	isc_nmhandle_t *readhandle;
133	isc_nmhandle_t *sendhandle;
134
135	/*% Buffer for IXFR/AXFR request message */
136	isc_buffer_t qbuffer;
137	unsigned char qbuffer_data[512];
138
139	/*%
140	 * Whether the zone originally had a database attached at the time this
141	 * transfer context was created.  Used by xfrin_destroy() when making
142	 * logging decisions.
143	 */
144	bool zone_had_db;
145
146	dns_db_t *db;
147	dns_dbversion_t *ver;
148	dns_diff_t diff; /*%< Pending database changes */
149	int difflen;	 /*%< Number of pending tuples */
150
151	xfrin_state_t state;
152	uint32_t end_serial;
153	bool is_ixfr;
154
155	unsigned int nmsg;  /*%< Number of messages recvd */
156	unsigned int nrecs; /*%< Number of records recvd */
157	uint64_t nbytes;    /*%< Number of bytes received */
158
159	unsigned int maxrecords; /*%< The maximum number of
160				  *   records set for the zone */
161
162	isc_time_t start; /*%< Start time of the transfer */
163	isc_time_t end;	  /*%< End time of the transfer */
164
165	dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
166	isc_buffer_t *lasttsig; /*%< The last TSIG */
167	dst_context_t *tsigctx; /*%< TSIG verification context */
168	unsigned int sincetsig; /*%< recvd since the last TSIG */
169
170	dns_transport_t *transport;
171
172	dns_xfrindone_t done;
173
174	/*%
175	 * AXFR- and IXFR-specific data.  Only one is used at a time
176	 * according to the is_ixfr flag, so this could be a union,
177	 * but keeping them separate makes it a bit simpler to clean
178	 * things up when destroying the context.
179	 */
180	dns_rdatacallbacks_t axfr;
181
182	struct {
183		uint32_t request_serial;
184		uint32_t current_serial;
185		dns_journal_t *journal;
186	} ixfr;
187
188	dns_rdata_t firstsoa;
189	unsigned char *firstsoa_data;
190
191	isc_tlsctx_cache_t *tlsctx_cache;
192
193	isc_timer_t *max_time_timer;
194	isc_timer_t *max_idle_timer;
195};
196
197#define XFRIN_MAGIC    ISC_MAGIC('X', 'f', 'r', 'I')
198#define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
199
200/**************************************************************************/
201/*
202 * Forward declarations.
203 */
204
205static void
206xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
207	     dns_name_t *zonename, dns_rdataclass_t rdclass,
208	     dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
209	     const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
210	     dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
211	     dns_xfrin_ctx_t **xfrp);
212
213static isc_result_t
214axfr_init(dns_xfrin_ctx_t *xfr);
215static isc_result_t
216axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
217static isc_result_t
218axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
219	     dns_ttl_t ttl, dns_rdata_t *rdata);
220static isc_result_t
221axfr_apply(dns_xfrin_ctx_t *xfr);
222static isc_result_t
223axfr_commit(dns_xfrin_ctx_t *xfr);
224static isc_result_t
225axfr_finalize(dns_xfrin_ctx_t *xfr);
226
227static isc_result_t
228ixfr_init(dns_xfrin_ctx_t *xfr);
229static isc_result_t
230ixfr_apply(dns_xfrin_ctx_t *xfr);
231static isc_result_t
232ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
233	     dns_ttl_t ttl, dns_rdata_t *rdata);
234static isc_result_t
235ixfr_commit(dns_xfrin_ctx_t *xfr);
236
237static isc_result_t
238xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
239       dns_rdata_t *rdata);
240
241static isc_result_t
242xfrin_start(dns_xfrin_ctx_t *xfr);
243
244static void
245xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
246static isc_result_t
247xfrin_send_request(dns_xfrin_ctx_t *xfr);
248static void
249xfrin_send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
250static void
251xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
252		isc_region_t *region, void *cbarg);
253
254static void
255xfrin_destroy(dns_xfrin_ctx_t *xfr);
256
257static void
258xfrin_timedout(struct isc_task *, struct isc_event *);
259static void
260xfrin_idledout(struct isc_task *, struct isc_event *);
261static void
262xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
263static isc_result_t
264render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
265
266static void
267xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *primaryaddr,
268	   const char *fmt, va_list ap) ISC_FORMAT_PRINTF(4, 0);
269
270static void
271xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *primaryaddr,
272	   const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
273
274static void
275xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
276	ISC_FORMAT_PRINTF(3, 4);
277
278/**************************************************************************/
279/*
280 * AXFR handling
281 */
282
283static isc_result_t
284axfr_init(dns_xfrin_ctx_t *xfr) {
285	isc_result_t result;
286
287	xfr->is_ixfr = false;
288
289	if (xfr->db != NULL) {
290		dns_db_detach(&xfr->db);
291	}
292
293	CHECK(axfr_makedb(xfr, &xfr->db));
294	dns_rdatacallbacks_init(&xfr->axfr);
295	CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
296	result = ISC_R_SUCCESS;
297failure:
298	return (result);
299}
300
301static isc_result_t
302axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
303	isc_result_t result;
304
305	result = dns_db_create(xfr->mctx, /* XXX */
306			       "rbt",	  /* XXX guess */
307			       &xfr->name, dns_dbtype_zone, xfr->rdclass, 0,
308			       NULL, /* XXX guess */
309			       dbp);
310	if (result == ISC_R_SUCCESS) {
311		dns_zone_rpz_enable_db(xfr->zone, *dbp);
312		dns_zone_catz_enable_db(xfr->zone, *dbp);
313	}
314	return (result);
315}
316
317static isc_result_t
318axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
319	     dns_ttl_t ttl, dns_rdata_t *rdata) {
320	isc_result_t result;
321
322	dns_difftuple_t *tuple = NULL;
323
324	if (rdata->rdclass != xfr->rdclass) {
325		return (DNS_R_BADCLASS);
326	}
327
328	CHECK(dns_zone_checknames(xfr->zone, name, rdata));
329	CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
330				   &tuple));
331	dns_diff_append(&xfr->diff, &tuple);
332	if (++xfr->difflen > 100) {
333		CHECK(axfr_apply(xfr));
334	}
335	result = ISC_R_SUCCESS;
336failure:
337	return (result);
338}
339
340/*
341 * Store a set of AXFR RRs in the database.
342 */
343static isc_result_t
344axfr_apply(dns_xfrin_ctx_t *xfr) {
345	isc_result_t result;
346	uint64_t records;
347
348	CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private));
349	xfr->difflen = 0;
350	dns_diff_clear(&xfr->diff);
351	if (xfr->maxrecords != 0U) {
352		result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
353		if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
354			result = DNS_R_TOOMANYRECORDS;
355			goto failure;
356		}
357	}
358	result = ISC_R_SUCCESS;
359failure:
360	return (result);
361}
362
363static isc_result_t
364axfr_commit(dns_xfrin_ctx_t *xfr) {
365	isc_result_t result;
366
367	CHECK(axfr_apply(xfr));
368	CHECK(dns_db_endload(xfr->db, &xfr->axfr));
369	CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL));
370
371	result = ISC_R_SUCCESS;
372failure:
373	return (result);
374}
375
376static isc_result_t
377axfr_finalize(dns_xfrin_ctx_t *xfr) {
378	isc_result_t result;
379
380	CHECK(dns_zone_replacedb(xfr->zone, xfr->db, true));
381
382	result = ISC_R_SUCCESS;
383failure:
384	return (result);
385}
386
387/**************************************************************************/
388/*
389 * IXFR handling
390 */
391
392static isc_result_t
393ixfr_init(dns_xfrin_ctx_t *xfr) {
394	isc_result_t result;
395	char *journalfile = NULL;
396
397	if (xfr->reqtype != dns_rdatatype_ixfr) {
398		xfrin_log(xfr, ISC_LOG_NOTICE,
399			  "got incremental response to AXFR request");
400		return (DNS_R_FORMERR);
401	}
402
403	xfr->is_ixfr = true;
404	INSIST(xfr->db != NULL);
405	xfr->difflen = 0;
406
407	journalfile = dns_zone_getjournal(xfr->zone);
408	if (journalfile != NULL) {
409		CHECK(dns_journal_open(xfr->mctx, journalfile,
410				       DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
411	}
412
413	result = ISC_R_SUCCESS;
414failure:
415	return (result);
416}
417
418static isc_result_t
419ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
420	     dns_ttl_t ttl, dns_rdata_t *rdata) {
421	isc_result_t result;
422	dns_difftuple_t *tuple = NULL;
423
424	if (rdata->rdclass != xfr->rdclass) {
425		return (DNS_R_BADCLASS);
426	}
427
428	if (op == DNS_DIFFOP_ADD) {
429		CHECK(dns_zone_checknames(xfr->zone, name, rdata));
430	}
431	CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
432				   &tuple));
433	dns_diff_append(&xfr->diff, &tuple);
434	if (++xfr->difflen > 100) {
435		CHECK(ixfr_apply(xfr));
436	}
437	result = ISC_R_SUCCESS;
438failure:
439	return (result);
440}
441
442/*
443 * Apply a set of IXFR changes to the database.
444 */
445static isc_result_t
446ixfr_apply(dns_xfrin_ctx_t *xfr) {
447	isc_result_t result;
448	uint64_t records;
449
450	if (xfr->ver == NULL) {
451		CHECK(dns_db_newversion(xfr->db, &xfr->ver));
452		if (xfr->ixfr.journal != NULL) {
453			CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
454		}
455	}
456	CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
457	if (xfr->maxrecords != 0U) {
458		result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
459		if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
460			result = DNS_R_TOOMANYRECORDS;
461			goto failure;
462		}
463	}
464	if (xfr->ixfr.journal != NULL) {
465		result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
466		if (result != ISC_R_SUCCESS) {
467			goto failure;
468		}
469	}
470	dns_diff_clear(&xfr->diff);
471	xfr->difflen = 0;
472	result = ISC_R_SUCCESS;
473failure:
474	return (result);
475}
476
477static isc_result_t
478ixfr_commit(dns_xfrin_ctx_t *xfr) {
479	isc_result_t result;
480
481	CHECK(ixfr_apply(xfr));
482	if (xfr->ver != NULL) {
483		CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver));
484		/* XXX enter ready-to-commit state here */
485		if (xfr->ixfr.journal != NULL) {
486			CHECK(dns_journal_commit(xfr->ixfr.journal));
487		}
488		dns_db_closeversion(xfr->db, &xfr->ver, true);
489		dns_zone_markdirty(xfr->zone);
490	}
491	result = ISC_R_SUCCESS;
492failure:
493	return (result);
494}
495
496/**************************************************************************/
497/*
498 * Common AXFR/IXFR protocol code
499 */
500
501/*
502 * Handle a single incoming resource record according to the current
503 * state.
504 */
505static isc_result_t
506xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
507       dns_rdata_t *rdata) {
508	isc_result_t result;
509
510	xfr->nrecs++;
511
512	if (rdata->type == dns_rdatatype_none ||
513	    dns_rdatatype_ismeta(rdata->type))
514	{
515		char buf[64];
516		dns_rdatatype_format(rdata->type, buf, sizeof(buf));
517		xfrin_log(xfr, ISC_LOG_NOTICE,
518			  "Unexpected %s record in zone transfer", buf);
519		FAIL(DNS_R_FORMERR);
520	}
521
522	/*
523	 * Immediately reject the entire transfer if the RR that is currently
524	 * being processed is an SOA record that is not placed at the zone
525	 * apex.
526	 */
527	if (rdata->type == dns_rdatatype_soa &&
528	    !dns_name_equal(&xfr->name, name))
529	{
530		char namebuf[DNS_NAME_FORMATSIZE];
531		dns_name_format(name, namebuf, sizeof(namebuf));
532		xfrin_log(xfr, ISC_LOG_DEBUG(3), "SOA name mismatch: '%s'",
533			  namebuf);
534		FAIL(DNS_R_NOTZONETOP);
535	}
536
537redo:
538	switch (xfr->state) {
539	case XFRST_SOAQUERY:
540		if (rdata->type != dns_rdatatype_soa) {
541			xfrin_log(xfr, ISC_LOG_NOTICE,
542				  "non-SOA response to SOA query");
543			FAIL(DNS_R_FORMERR);
544		}
545		xfr->end_serial = dns_soa_getserial(rdata);
546		if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
547		    !dns_zone_isforced(xfr->zone))
548		{
549			xfrin_log(xfr, ISC_LOG_DEBUG(3),
550				  "requested serial %u, "
551				  "primary has %u, not updating",
552				  xfr->ixfr.request_serial, xfr->end_serial);
553			FAIL(DNS_R_UPTODATE);
554		}
555		xfr->state = XFRST_GOTSOA;
556		break;
557
558	case XFRST_GOTSOA:
559		/*
560		 * Skip other records in the answer section.
561		 */
562		break;
563
564	case XFRST_INITIALSOA:
565		if (rdata->type != dns_rdatatype_soa) {
566			xfrin_log(xfr, ISC_LOG_NOTICE,
567				  "first RR in zone transfer must be SOA");
568			FAIL(DNS_R_FORMERR);
569		}
570		/*
571		 * Remember the serial number in the initial SOA.
572		 * We need it to recognize the end of an IXFR.
573		 */
574		xfr->end_serial = dns_soa_getserial(rdata);
575		if (xfr->reqtype == dns_rdatatype_ixfr &&
576		    !DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
577		    !dns_zone_isforced(xfr->zone))
578		{
579			/*
580			 * This must be the single SOA record that is
581			 * sent when the current version on the primary
582			 * is not newer than the version in the request.
583			 */
584			xfrin_log(xfr, ISC_LOG_DEBUG(3),
585				  "requested serial %u, "
586				  "primary has %u, not updating",
587				  xfr->ixfr.request_serial, xfr->end_serial);
588			FAIL(DNS_R_UPTODATE);
589		}
590		xfr->firstsoa = *rdata;
591		if (xfr->firstsoa_data != NULL) {
592			isc_mem_free(xfr->mctx, xfr->firstsoa_data);
593		}
594		xfr->firstsoa_data = isc_mem_allocate(xfr->mctx, rdata->length);
595		memcpy(xfr->firstsoa_data, rdata->data, rdata->length);
596		xfr->firstsoa.data = xfr->firstsoa_data;
597		xfr->state = XFRST_FIRSTDATA;
598		break;
599
600	case XFRST_FIRSTDATA:
601		/*
602		 * If the transfer begins with one SOA record, it is an AXFR,
603		 * if it begins with two SOAs, it is an IXFR.
604		 */
605		if (xfr->reqtype == dns_rdatatype_ixfr &&
606		    rdata->type == dns_rdatatype_soa &&
607		    xfr->ixfr.request_serial == dns_soa_getserial(rdata))
608		{
609			xfrin_log(xfr, ISC_LOG_DEBUG(3),
610				  "got incremental response");
611			CHECK(ixfr_init(xfr));
612			xfr->state = XFRST_IXFR_DELSOA;
613		} else {
614			xfrin_log(xfr, ISC_LOG_DEBUG(3),
615				  "got nonincremental response");
616			CHECK(axfr_init(xfr));
617			xfr->state = XFRST_AXFR;
618		}
619		goto redo;
620
621	case XFRST_IXFR_DELSOA:
622		INSIST(rdata->type == dns_rdatatype_soa);
623		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
624		xfr->state = XFRST_IXFR_DEL;
625		break;
626
627	case XFRST_IXFR_DEL:
628		if (rdata->type == dns_rdatatype_soa) {
629			uint32_t soa_serial = dns_soa_getserial(rdata);
630			xfr->state = XFRST_IXFR_ADDSOA;
631			xfr->ixfr.current_serial = soa_serial;
632			goto redo;
633		}
634		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
635		break;
636
637	case XFRST_IXFR_ADDSOA:
638		INSIST(rdata->type == dns_rdatatype_soa);
639		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
640		xfr->state = XFRST_IXFR_ADD;
641		break;
642
643	case XFRST_IXFR_ADD:
644		if (rdata->type == dns_rdatatype_soa) {
645			uint32_t soa_serial = dns_soa_getserial(rdata);
646			if (soa_serial == xfr->end_serial) {
647				CHECK(ixfr_commit(xfr));
648				xfr->state = XFRST_IXFR_END;
649				break;
650			} else if (soa_serial != xfr->ixfr.current_serial) {
651				xfrin_log(xfr, ISC_LOG_NOTICE,
652					  "IXFR out of sync: "
653					  "expected serial %u, got %u",
654					  xfr->ixfr.current_serial, soa_serial);
655				FAIL(DNS_R_FORMERR);
656			} else {
657				CHECK(ixfr_commit(xfr));
658				xfr->state = XFRST_IXFR_DELSOA;
659				goto redo;
660			}
661		}
662		if (rdata->type == dns_rdatatype_ns &&
663		    dns_name_iswildcard(name))
664		{
665			FAIL(DNS_R_INVALIDNS);
666		}
667		CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
668		break;
669
670	case XFRST_AXFR:
671		/*
672		 * Old BINDs sent cross class A records for non IN classes.
673		 */
674		if (rdata->type == dns_rdatatype_a &&
675		    rdata->rdclass != xfr->rdclass &&
676		    xfr->rdclass != dns_rdataclass_in)
677		{
678			break;
679		}
680		CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
681		if (rdata->type == dns_rdatatype_soa) {
682			/*
683			 * Use dns_rdata_compare instead of memcmp to
684			 * allow for case differences.
685			 */
686			if (dns_rdata_compare(rdata, &xfr->firstsoa) != 0) {
687				xfrin_log(xfr, ISC_LOG_NOTICE,
688					  "start and ending SOA records "
689					  "mismatch");
690				FAIL(DNS_R_FORMERR);
691			}
692			CHECK(axfr_commit(xfr));
693			xfr->state = XFRST_AXFR_END;
694			break;
695		}
696		break;
697	case XFRST_AXFR_END:
698	case XFRST_IXFR_END:
699		FAIL(DNS_R_EXTRADATA);
700		FALLTHROUGH;
701	default:
702		UNREACHABLE();
703	}
704	result = ISC_R_SUCCESS;
705failure:
706	return (result);
707}
708
709isc_result_t
710dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
711		 const isc_sockaddr_t *primaryaddr,
712		 const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
713		 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
714		 isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
715		 dns_xfrin_ctx_t **xfrp) {
716	dns_name_t *zonename = dns_zone_getorigin(zone);
717	dns_xfrin_ctx_t *xfr = NULL;
718	isc_result_t result;
719	dns_db_t *db = NULL;
720
721	REQUIRE(xfrp != NULL && *xfrp == NULL);
722	REQUIRE(done != NULL);
723	REQUIRE(isc_sockaddr_getport(primaryaddr) != 0);
724
725	(void)dns_zone_getdb(zone, &db);
726
727	if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) {
728		REQUIRE(db != NULL);
729	}
730
731	xfrin_create(mctx, zone, db, netmgr, zonename, dns_zone_getclass(zone),
732		     xfrtype, primaryaddr, sourceaddr, tsigkey, transport,
733		     tlsctx_cache, &xfr);
734
735	if (db != NULL) {
736		xfr->zone_had_db = true;
737	}
738
739	xfr->done = done;
740
741	isc_refcount_init(&xfr->references, 1);
742
743	/*
744	 * Set *xfrp now, before calling xfrin_start(). Asynchronous
745	 * netmgr processing could cause the 'done' callback to run in
746	 * another thread before we reached the end of the present
747	 * function. In that case, if *xfrp hadn't already been
748	 * attached, the 'done' function would be unable to detach it.
749	 */
750	*xfrp = xfr;
751
752	result = xfrin_start(xfr);
753	if (result != ISC_R_SUCCESS) {
754		atomic_store(&xfr->shuttingdown, true);
755		xfr->shutdown_result = result;
756		dns_xfrin_detach(xfrp);
757	}
758
759	if (db != NULL) {
760		dns_db_detach(&db);
761	}
762
763	if (result != ISC_R_SUCCESS) {
764		char zonetext[DNS_NAME_MAXTEXT + 32];
765		dns_zone_name(zone, zonetext, sizeof(zonetext));
766		xfrin_log1(ISC_LOG_ERROR, zonetext, primaryaddr,
767			   "zone transfer setup failed");
768	}
769
770	return (result);
771}
772
773static void
774xfrin_cancelio(dns_xfrin_ctx_t *xfr);
775
776static void
777xfrin_timedout(struct isc_task *task, struct isc_event *event) {
778	UNUSED(task);
779
780	dns_xfrin_ctx_t *xfr = event->ev_arg;
781	REQUIRE(VALID_XFRIN(xfr));
782
783	xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum transfer time exceeded");
784	isc_event_free(&event);
785}
786
787static void
788xfrin_idledout(struct isc_task *task, struct isc_event *event) {
789	UNUSED(task);
790
791	dns_xfrin_ctx_t *xfr = event->ev_arg;
792	REQUIRE(VALID_XFRIN(xfr));
793
794	xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum idle time exceeded");
795	isc_event_free(&event);
796}
797
798void
799dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
800	REQUIRE(VALID_XFRIN(xfr));
801
802	xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
803}
804
805void
806dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
807	REQUIRE(VALID_XFRIN(source));
808	REQUIRE(target != NULL && *target == NULL);
809	(void)isc_refcount_increment(&source->references);
810
811	*target = source;
812}
813
814void
815dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
816	dns_xfrin_ctx_t *xfr = NULL;
817
818	REQUIRE(xfrp != NULL && VALID_XFRIN(*xfrp));
819
820	xfr = *xfrp;
821	*xfrp = NULL;
822
823	if (isc_refcount_decrement(&xfr->references) == 1) {
824		xfrin_destroy(xfr);
825	}
826}
827
828static void
829xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
830	if (xfr->readhandle == NULL) {
831		return;
832	}
833
834	isc_nm_cancelread(xfr->readhandle);
835	/* The xfr->readhandle detach will happen in xfrin_recv_done callback */
836}
837
838static void
839xfrin_reset(dns_xfrin_ctx_t *xfr) {
840	REQUIRE(VALID_XFRIN(xfr));
841
842	xfrin_log(xfr, ISC_LOG_INFO, "resetting");
843
844	REQUIRE(xfr->readhandle == NULL);
845	REQUIRE(xfr->sendhandle == NULL);
846
847	if (xfr->lasttsig != NULL) {
848		isc_buffer_free(&xfr->lasttsig);
849	}
850
851	dns_diff_clear(&xfr->diff);
852	xfr->difflen = 0;
853
854	if (xfr->ixfr.journal != NULL) {
855		dns_journal_destroy(&xfr->ixfr.journal);
856	}
857
858	if (xfr->axfr.add_private != NULL) {
859		(void)dns_db_endload(xfr->db, &xfr->axfr);
860	}
861
862	if (xfr->ver != NULL) {
863		dns_db_closeversion(xfr->db, &xfr->ver, false);
864	}
865}
866
867static void
868xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
869	/* Make sure only the first xfrin_fail() trumps */
870	if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false },
871					   true))
872	{
873		(void)isc_timer_reset(xfr->max_time_timer,
874				      isc_timertype_inactive, NULL, NULL, true);
875		(void)isc_timer_reset(xfr->max_idle_timer,
876				      isc_timertype_inactive, NULL, NULL, true);
877
878		if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS)
879		{
880			xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
881				  isc_result_totext(result));
882			if (xfr->is_ixfr) {
883				/* Pass special result code to force AXFR retry
884				 */
885				result = DNS_R_BADIXFR;
886			}
887		}
888		xfrin_cancelio(xfr);
889		/*
890		 * Close the journal.
891		 */
892		if (xfr->ixfr.journal != NULL) {
893			dns_journal_destroy(&xfr->ixfr.journal);
894		}
895		if (xfr->done != NULL) {
896			(xfr->done)(xfr->zone, result);
897			xfr->done = NULL;
898		}
899		xfr->shutdown_result = result;
900	}
901}
902
903static void
904xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
905	     dns_name_t *zonename, dns_rdataclass_t rdclass,
906	     dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
907	     const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
908	     dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
909	     dns_xfrin_ctx_t **xfrp) {
910	dns_xfrin_ctx_t *xfr = NULL;
911	dns_zonemgr_t *zmgr = dns_zone_getmgr(zone);
912	isc_timermgr_t *timermgr = dns_zonemgr_gettimermgr(zmgr);
913	isc_task_t *ztask = NULL;
914
915	xfr = isc_mem_get(mctx, sizeof(*xfr));
916	*xfr = (dns_xfrin_ctx_t){ .netmgr = netmgr,
917				  .shutdown_result = ISC_R_UNSET,
918				  .rdclass = rdclass,
919				  .reqtype = reqtype,
920				  .id = (dns_messageid_t)isc_random16(),
921				  .maxrecords = dns_zone_getmaxrecords(zone),
922				  .primaryaddr = *primaryaddr,
923				  .sourceaddr = *sourceaddr,
924				  .firstsoa = DNS_RDATA_INIT,
925				  .magic = XFRIN_MAGIC };
926
927	isc_mem_attach(mctx, &xfr->mctx);
928	dns_zone_iattach(zone, &xfr->zone);
929	dns_name_init(&xfr->name, NULL);
930
931	isc_refcount_init(&xfr->connects, 0);
932	isc_refcount_init(&xfr->sends, 0);
933	isc_refcount_init(&xfr->recvs, 0);
934
935	atomic_init(&xfr->shuttingdown, false);
936
937	if (db != NULL) {
938		dns_db_attach(db, &xfr->db);
939	}
940
941	dns_diff_init(xfr->mctx, &xfr->diff);
942
943	if (reqtype == dns_rdatatype_soa) {
944		xfr->state = XFRST_SOAQUERY;
945	} else {
946		xfr->state = XFRST_INITIALSOA;
947	}
948
949	isc_time_now(&xfr->start);
950
951	if (tsigkey != NULL) {
952		dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
953	}
954
955	if (transport != NULL) {
956		dns_transport_attach(transport, &xfr->transport);
957	}
958
959	dns_name_dup(zonename, mctx, &xfr->name);
960
961	INSIST(isc_sockaddr_pf(primaryaddr) == isc_sockaddr_pf(sourceaddr));
962	isc_sockaddr_setport(&xfr->sourceaddr, 0);
963
964	/*
965	 * Reserve 2 bytes for TCP length at the beginning of the buffer.
966	 */
967	isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
968			sizeof(xfr->qbuffer_data) - 2);
969
970	isc_tlsctx_cache_attach(tlsctx_cache, &xfr->tlsctx_cache);
971
972	dns_zone_gettask(zone, &ztask);
973	isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, ztask,
974			 xfrin_timedout, xfr, &xfr->max_time_timer);
975	isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, ztask,
976			 xfrin_idledout, xfr, &xfr->max_idle_timer);
977	isc_task_detach(&ztask); /* dns_zone_task() attaches to the task */
978
979	*xfrp = xfr;
980}
981
982static isc_result_t
983get_create_tlsctx(const dns_xfrin_ctx_t *xfr, isc_tlsctx_t **pctx,
984		  isc_tlsctx_client_session_cache_t **psess_cache) {
985	isc_result_t result = ISC_R_FAILURE;
986	isc_tlsctx_t *tlsctx = NULL, *found = NULL;
987	isc_tls_cert_store_t *store = NULL, *found_store = NULL;
988	isc_tlsctx_client_session_cache_t *sess_cache = NULL,
989					  *found_sess_cache = NULL;
990	uint32_t tls_versions;
991	const char *ciphers = NULL;
992	bool prefer_server_ciphers;
993	const uint16_t family = isc_sockaddr_pf(&xfr->primaryaddr) == PF_INET6
994					? AF_INET6
995					: AF_INET;
996	const char *tlsname = NULL;
997
998	REQUIRE(psess_cache != NULL && *psess_cache == NULL);
999	REQUIRE(pctx != NULL && *pctx == NULL);
1000
1001	INSIST(xfr->transport != NULL);
1002	tlsname = dns_transport_get_tlsname(xfr->transport);
1003	INSIST(tlsname != NULL && *tlsname != '\0');
1004
1005	/*
1006	 * Let's try to re-use the already created context. This way
1007	 * we have a chance to resume the TLS session, bypassing the
1008	 * full TLS handshake procedure, making establishing
1009	 * subsequent TLS connections for XoT faster.
1010	 */
1011	result = isc_tlsctx_cache_find(xfr->tlsctx_cache, tlsname,
1012				       isc_tlsctx_cache_tls, family, &found,
1013				       &found_store, &found_sess_cache);
1014	if (result != ISC_R_SUCCESS) {
1015		const char *hostname =
1016			dns_transport_get_remote_hostname(xfr->transport);
1017		const char *ca_file = dns_transport_get_cafile(xfr->transport);
1018		const char *cert_file =
1019			dns_transport_get_certfile(xfr->transport);
1020		const char *key_file =
1021			dns_transport_get_keyfile(xfr->transport);
1022		char primary_addr_str[INET6_ADDRSTRLEN] = { 0 };
1023		isc_netaddr_t primary_netaddr = { 0 };
1024		bool hostname_ignore_subject;
1025		/*
1026		 * So, no context exists. Let's create one using the
1027		 * parameters from the configuration file and try to
1028		 * store it for further reuse.
1029		 */
1030		result = isc_tlsctx_createclient(&tlsctx);
1031		if (result != ISC_R_SUCCESS) {
1032			goto failure;
1033		}
1034		tls_versions = dns_transport_get_tls_versions(xfr->transport);
1035		if (tls_versions != 0) {
1036			isc_tlsctx_set_protocols(tlsctx, tls_versions);
1037		}
1038		ciphers = dns_transport_get_ciphers(xfr->transport);
1039		if (ciphers != NULL) {
1040			isc_tlsctx_set_cipherlist(tlsctx, ciphers);
1041		}
1042
1043		if (dns_transport_get_prefer_server_ciphers(
1044			    xfr->transport, &prefer_server_ciphers))
1045		{
1046			isc_tlsctx_prefer_server_ciphers(tlsctx,
1047							 prefer_server_ciphers);
1048		}
1049
1050		if (hostname != NULL || ca_file != NULL) {
1051			/*
1052			 * The situation when 'found_store != NULL' while 'found
1053			 * == NULL' might appear as there is one to many
1054			 * relation between per transport TLS contexts and cert
1055			 * stores. That is, there could be one store shared
1056			 * between multiple contexts.
1057			 */
1058			if (found_store == NULL) {
1059				/*
1060				 * 'ca_file' can equal 'NULL' here, in
1061				 * that case the store with system-wide
1062				 * CA certificates will be created, just
1063				 * as planned.
1064				 */
1065				result = isc_tls_cert_store_create(ca_file,
1066								   &store);
1067
1068				if (result != ISC_R_SUCCESS) {
1069					goto failure;
1070				}
1071			} else {
1072				store = found_store;
1073			}
1074
1075			INSIST(store != NULL);
1076			if (hostname == NULL) {
1077				/*
1078				 * If CA bundle file is specified, but
1079				 * hostname is not, then use the primary
1080				 * IP address for validation, just like
1081				 * dig does.
1082				 */
1083				INSIST(ca_file != NULL);
1084				isc_netaddr_fromsockaddr(&primary_netaddr,
1085							 &xfr->primaryaddr);
1086				isc_netaddr_format(&primary_netaddr,
1087						   primary_addr_str,
1088						   sizeof(primary_addr_str));
1089				hostname = primary_addr_str;
1090			}
1091			/*
1092			 * According to RFC 8310, Subject field MUST NOT
1093			 * be inspected when verifying hostname for DoT.
1094			 * Only SubjectAltName must be checked.
1095			 */
1096			hostname_ignore_subject = true;
1097			result = isc_tlsctx_enable_peer_verification(
1098				tlsctx, false, store, hostname,
1099				hostname_ignore_subject);
1100			if (result != ISC_R_SUCCESS) {
1101				goto failure;
1102			}
1103
1104			/*
1105			 * Let's load client certificate and enable
1106			 * Mutual TLS. We do that only in the case when
1107			 * Strict TLS is enabled, because Mutual TLS is
1108			 * an extension of it.
1109			 */
1110			if (cert_file != NULL) {
1111				INSIST(key_file != NULL);
1112
1113				result = isc_tlsctx_load_certificate(
1114					tlsctx, key_file, cert_file);
1115				if (result != ISC_R_SUCCESS) {
1116					goto failure;
1117				}
1118			}
1119		}
1120
1121		isc_tlsctx_enable_dot_client_alpn(tlsctx);
1122
1123		isc_tlsctx_client_session_cache_create(
1124			xfr->mctx, tlsctx,
1125			ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE,
1126			&sess_cache);
1127
1128		found_store = NULL;
1129		result = isc_tlsctx_cache_add(xfr->tlsctx_cache, tlsname,
1130					      isc_tlsctx_cache_tls, family,
1131					      tlsctx, store, sess_cache, &found,
1132					      &found_store, &found_sess_cache);
1133		if (result == ISC_R_EXISTS) {
1134			/*
1135			 * It seems the entry has just been created from within
1136			 * another thread while we were initialising
1137			 * ours. Although this is unlikely, it could happen
1138			 * after startup/re-initialisation. In such a case,
1139			 * discard the new context and associated data and use
1140			 * the already established one from now on.
1141			 *
1142			 * Such situation will not occur after the
1143			 * initial 'warm-up', so it is not critical
1144			 * performance-wise.
1145			 */
1146			INSIST(found != NULL);
1147			isc_tlsctx_free(&tlsctx);
1148			/*
1149			 * The 'store' variable can be 'NULL' when remote server
1150			 * verification is not enabled (that is, when Strict or
1151			 * Mutual TLS are not used).
1152			 *
1153			 * The 'found_store' might be equal to 'store' as there
1154			 * is one-to-many relation between a store and
1155			 * per-transport TLS contexts. In that case, the call to
1156			 * 'isc_tlsctx_cache_find()' above could have returned a
1157			 * store via the 'found_store' variable, whose value we
1158			 * can assign to 'store' later. In that case,
1159			 * 'isc_tlsctx_cache_add()' will return the same value.
1160			 * When that happens, we should not free the store
1161			 * object, as it is managed by the TLS context cache.
1162			 */
1163			if (store != NULL && store != found_store) {
1164				isc_tls_cert_store_free(&store);
1165			}
1166			isc_tlsctx_client_session_cache_detach(&sess_cache);
1167			/* Let's return the data from the cache. */
1168			*psess_cache = found_sess_cache;
1169			*pctx = found;
1170		} else {
1171			/*
1172			 * Adding the fresh values into the cache has been
1173			 * successful, let's return them
1174			 */
1175			INSIST(result == ISC_R_SUCCESS);
1176			*psess_cache = sess_cache;
1177			*pctx = tlsctx;
1178		}
1179	} else {
1180		/*
1181		 * The cache lookup has been successful, let's return the
1182		 * results.
1183		 */
1184		INSIST(result == ISC_R_SUCCESS);
1185		*psess_cache = found_sess_cache;
1186		*pctx = found;
1187	}
1188
1189	return (ISC_R_SUCCESS);
1190
1191failure:
1192	if (tlsctx != NULL) {
1193		isc_tlsctx_free(&tlsctx);
1194	}
1195
1196	/*
1197	 * The 'found_store' is being managed by the TLS context
1198	 * cache. Thus, we should keep it as it is, as it will get
1199	 * destroyed alongside the cache. As there is one store per
1200	 * multiple TLS contexts, we need to handle store deletion in a
1201	 * special way.
1202	 */
1203	if (store != NULL && store != found_store) {
1204		isc_tls_cert_store_free(&store);
1205	}
1206
1207	return (result);
1208}
1209
1210static isc_result_t
1211xfrin_start(dns_xfrin_ctx_t *xfr) {
1212	isc_result_t result;
1213	dns_xfrin_ctx_t *connect_xfr = NULL;
1214	dns_transport_type_t transport_type = DNS_TRANSPORT_TCP;
1215	isc_tlsctx_t *tlsctx = NULL;
1216	isc_tlsctx_client_session_cache_t *sess_cache = NULL;
1217	isc_interval_t interval;
1218	isc_time_t next;
1219
1220	(void)isc_refcount_increment0(&xfr->connects);
1221	dns_xfrin_attach(xfr, &connect_xfr);
1222
1223	if (xfr->transport != NULL) {
1224		transport_type = dns_transport_get_type(xfr->transport);
1225	}
1226
1227	/* Set the maximum timer */
1228	isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
1229	isc_time_nowplusinterval(&next, &interval);
1230	result = isc_timer_reset(xfr->max_time_timer, isc_timertype_once, &next,
1231				 NULL, true);
1232	RUNTIME_CHECK(result == ISC_R_SUCCESS);
1233
1234	/* Set the idle timer */
1235	isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
1236	isc_time_nowplusinterval(&next, &interval);
1237	result = isc_timer_reset(xfr->max_idle_timer, isc_timertype_once, &next,
1238				 NULL, true);
1239	RUNTIME_CHECK(result == ISC_R_SUCCESS);
1240
1241	/*
1242	 * XXX: timeouts are hard-coded to 30 seconds; this needs to be
1243	 * configurable.
1244	 */
1245	switch (transport_type) {
1246	case DNS_TRANSPORT_TCP:
1247		isc_nm_tcpdnsconnect(xfr->netmgr, &xfr->sourceaddr,
1248				     &xfr->primaryaddr, xfrin_connect_done,
1249				     connect_xfr, 30000, 0);
1250		break;
1251	case DNS_TRANSPORT_TLS: {
1252		result = get_create_tlsctx(xfr, &tlsctx, &sess_cache);
1253		if (result != ISC_R_SUCCESS) {
1254			goto failure;
1255		}
1256		INSIST(tlsctx != NULL);
1257		isc_nm_tlsdnsconnect(xfr->netmgr, &xfr->sourceaddr,
1258				     &xfr->primaryaddr, xfrin_connect_done,
1259				     connect_xfr, 30000, 0, tlsctx, sess_cache);
1260	} break;
1261	default:
1262		UNREACHABLE();
1263	}
1264
1265	return (ISC_R_SUCCESS);
1266
1267failure:
1268	isc_refcount_decrement0(&xfr->connects);
1269	dns_xfrin_detach(&connect_xfr);
1270	return (result);
1271}
1272
1273/* XXX the resolver could use this, too */
1274
1275static isc_result_t
1276render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
1277	dns_compress_t cctx;
1278	bool cleanup_cctx = false;
1279	isc_result_t result;
1280
1281	CHECK(dns_compress_init(&cctx, -1, mctx));
1282	cleanup_cctx = true;
1283	CHECK(dns_message_renderbegin(msg, &cctx, buf));
1284	CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
1285	CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
1286	CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
1287	CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
1288	CHECK(dns_message_renderend(msg));
1289	result = ISC_R_SUCCESS;
1290failure:
1291	if (cleanup_cctx) {
1292		dns_compress_invalidate(&cctx);
1293	}
1294	return (result);
1295}
1296
1297/*
1298 * A connection has been established.
1299 */
1300static void
1301xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
1302	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)cbarg;
1303	char sourcetext[ISC_SOCKADDR_FORMATSIZE];
1304	char signerbuf[DNS_NAME_FORMATSIZE];
1305	const char *signer = "", *sep = "";
1306	isc_sockaddr_t sockaddr;
1307	dns_zonemgr_t *zmgr = NULL;
1308
1309	REQUIRE(VALID_XFRIN(xfr));
1310
1311	isc_refcount_decrement0(&xfr->connects);
1312
1313	if (atomic_load(&xfr->shuttingdown)) {
1314		result = ISC_R_SHUTTINGDOWN;
1315	}
1316
1317	if (result != ISC_R_SUCCESS) {
1318		xfrin_fail(xfr, result, "failed to connect");
1319		goto failure;
1320	}
1321
1322	result = isc_nm_xfr_checkperm(handle);
1323	if (result != ISC_R_SUCCESS) {
1324		xfrin_fail(xfr, result, "connected but unable to transfer");
1325		goto failure;
1326	}
1327
1328	zmgr = dns_zone_getmgr(xfr->zone);
1329	if (zmgr != NULL) {
1330		dns_zonemgr_unreachabledel(zmgr, &xfr->primaryaddr,
1331					   &xfr->sourceaddr);
1332	}
1333
1334	xfr->handle = handle;
1335	sockaddr = isc_nmhandle_peeraddr(handle);
1336	isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
1337
1338	if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
1339		dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
1340				sizeof(signerbuf));
1341		sep = " TSIG ";
1342		signer = signerbuf;
1343	}
1344
1345	xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", sourcetext, sep,
1346		  signer);
1347
1348	result = xfrin_send_request(xfr);
1349	if (result != ISC_R_SUCCESS) {
1350		xfrin_fail(xfr, result, "connected but unable to send");
1351	}
1352
1353failure:
1354	switch (result) {
1355	case ISC_R_SUCCESS:
1356		break;
1357	case ISC_R_NETDOWN:
1358	case ISC_R_HOSTDOWN:
1359	case ISC_R_NETUNREACH:
1360	case ISC_R_HOSTUNREACH:
1361	case ISC_R_CONNREFUSED:
1362	case ISC_R_TIMEDOUT:
1363		/*
1364		 * Add the server to unreachable primaries table if
1365		 * the server has a permanent networking error or
1366		 * the connection attempt as timed out.
1367		 */
1368		zmgr = dns_zone_getmgr(xfr->zone);
1369		if (zmgr != NULL) {
1370			isc_time_t now;
1371
1372			TIME_NOW(&now);
1373
1374			dns_zonemgr_unreachableadd(zmgr, &xfr->primaryaddr,
1375						   &xfr->sourceaddr, &now);
1376		}
1377		break;
1378	default:
1379		/* Retry sooner than in 10 minutes */
1380		break;
1381	}
1382
1383	dns_xfrin_detach(&xfr);
1384}
1385
1386/*
1387 * Convert a tuple into a dns_name_t suitable for inserting
1388 * into the given dns_message_t.
1389 */
1390static isc_result_t
1391tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
1392	isc_result_t result;
1393	dns_rdata_t *rdata = NULL;
1394	dns_rdatalist_t *rdl = NULL;
1395	dns_rdataset_t *rds = NULL;
1396	dns_name_t *name = NULL;
1397
1398	REQUIRE(target != NULL && *target == NULL);
1399
1400	CHECK(dns_message_gettemprdata(msg, &rdata));
1401	dns_rdata_init(rdata);
1402	dns_rdata_clone(&tuple->rdata, rdata);
1403
1404	CHECK(dns_message_gettemprdatalist(msg, &rdl));
1405	dns_rdatalist_init(rdl);
1406	rdl->type = tuple->rdata.type;
1407	rdl->rdclass = tuple->rdata.rdclass;
1408	rdl->ttl = tuple->ttl;
1409	ISC_LIST_APPEND(rdl->rdata, rdata, link);
1410
1411	CHECK(dns_message_gettemprdataset(msg, &rds));
1412	CHECK(dns_rdatalist_tordataset(rdl, rds));
1413
1414	CHECK(dns_message_gettempname(msg, &name));
1415	dns_name_clone(&tuple->name, name);
1416	ISC_LIST_APPEND(name->list, rds, link);
1417
1418	*target = name;
1419	return (ISC_R_SUCCESS);
1420
1421failure:
1422
1423	if (rds != NULL) {
1424		dns_rdataset_disassociate(rds);
1425		dns_message_puttemprdataset(msg, &rds);
1426	}
1427	if (rdl != NULL) {
1428		ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1429		dns_message_puttemprdatalist(msg, &rdl);
1430	}
1431	if (rdata != NULL) {
1432		dns_message_puttemprdata(msg, &rdata);
1433	}
1434
1435	return (result);
1436}
1437
1438/*
1439 * Build an *XFR request and send its length prefix.
1440 */
1441static isc_result_t
1442xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1443	isc_result_t result;
1444	isc_region_t region;
1445	dns_rdataset_t *qrdataset = NULL;
1446	dns_message_t *msg = NULL;
1447	dns_difftuple_t *soatuple = NULL;
1448	dns_name_t *qname = NULL;
1449	dns_dbversion_t *ver = NULL;
1450	dns_name_t *msgsoaname = NULL;
1451	dns_xfrin_ctx_t *send_xfr = NULL;
1452
1453	/* Create the request message */
1454	dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg);
1455	CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1456
1457	/* Create a name for the question section. */
1458	CHECK(dns_message_gettempname(msg, &qname));
1459	dns_name_clone(&xfr->name, qname);
1460
1461	/* Formulate the question and attach it to the question name. */
1462	CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1463	dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1464	ISC_LIST_APPEND(qname->list, qrdataset, link);
1465	qrdataset = NULL;
1466
1467	dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1468	qname = NULL;
1469
1470	if (xfr->reqtype == dns_rdatatype_ixfr) {
1471		/* Get the SOA and add it to the authority section. */
1472		/* XXX is using the current version the right thing? */
1473		dns_db_currentversion(xfr->db, &ver);
1474		CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1475					    DNS_DIFFOP_EXISTS, &soatuple));
1476		xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1477		xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1478		xfrin_log(xfr, ISC_LOG_DEBUG(3),
1479			  "requesting IXFR for serial %u",
1480			  xfr->ixfr.request_serial);
1481
1482		CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1483		dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1484	} else if (xfr->reqtype == dns_rdatatype_soa) {
1485		CHECK(dns_db_getsoaserial(xfr->db, NULL,
1486					  &xfr->ixfr.request_serial));
1487	}
1488
1489	xfr->id++;
1490	xfr->nmsg = 0;
1491	xfr->nrecs = 0;
1492	xfr->nbytes = 0;
1493	isc_time_now(&xfr->start);
1494	msg->id = xfr->id;
1495	if (xfr->tsigctx != NULL) {
1496		dst_context_destroy(&xfr->tsigctx);
1497	}
1498
1499	CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1500
1501	/*
1502	 * Free the last tsig, if there is one.
1503	 */
1504	if (xfr->lasttsig != NULL) {
1505		isc_buffer_free(&xfr->lasttsig);
1506	}
1507
1508	/*
1509	 * Save the query TSIG and don't let message_destroy free it.
1510	 */
1511	CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1512
1513	isc_buffer_usedregion(&xfr->qbuffer, &region);
1514	INSIST(region.length <= 65535);
1515
1516	dns_xfrin_attach(xfr, &send_xfr);
1517	isc_nmhandle_attach(send_xfr->handle, &xfr->sendhandle);
1518	isc_refcount_increment0(&send_xfr->sends);
1519	isc_nm_send(xfr->handle, &region, xfrin_send_done, send_xfr);
1520
1521failure:
1522	if (qname != NULL) {
1523		dns_message_puttempname(msg, &qname);
1524	}
1525	if (qrdataset != NULL) {
1526		dns_message_puttemprdataset(msg, &qrdataset);
1527	}
1528	if (msg != NULL) {
1529		dns_message_detach(&msg);
1530	}
1531	if (soatuple != NULL) {
1532		dns_difftuple_free(&soatuple);
1533	}
1534	if (ver != NULL) {
1535		dns_db_closeversion(xfr->db, &ver, false);
1536	}
1537
1538	return (result);
1539}
1540
1541static void
1542xfrin_send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
1543	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)cbarg;
1544	dns_xfrin_ctx_t *recv_xfr = NULL;
1545
1546	REQUIRE(VALID_XFRIN(xfr));
1547
1548	isc_refcount_decrement0(&xfr->sends);
1549	if (atomic_load(&xfr->shuttingdown)) {
1550		result = ISC_R_SHUTTINGDOWN;
1551	}
1552
1553	CHECK(result);
1554
1555	xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1556
1557	dns_xfrin_attach(xfr, &recv_xfr);
1558	isc_nmhandle_attach(handle, &recv_xfr->readhandle);
1559	isc_refcount_increment0(&recv_xfr->recvs);
1560	isc_nm_read(recv_xfr->handle, xfrin_recv_done, recv_xfr);
1561
1562failure:
1563	if (result != ISC_R_SUCCESS) {
1564		xfrin_fail(xfr, result, "failed sending request data");
1565	}
1566
1567	isc_nmhandle_detach(&xfr->sendhandle);
1568	dns_xfrin_detach(&xfr); /* send_xfr */
1569}
1570
1571static void
1572xfrin_recv_done(isc_nmhandle_t *handle, isc_result_t result,
1573		isc_region_t *region, void *cbarg) {
1574	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)cbarg;
1575	dns_message_t *msg = NULL;
1576	dns_name_t *name = NULL;
1577	const dns_name_t *tsigowner = NULL;
1578	isc_buffer_t buffer;
1579	isc_sockaddr_t peer;
1580
1581	REQUIRE(VALID_XFRIN(xfr));
1582
1583	isc_refcount_decrement0(&xfr->recvs);
1584
1585	if (atomic_load(&xfr->shuttingdown)) {
1586		result = ISC_R_SHUTTINGDOWN;
1587	}
1588
1589	/* Stop the idle timer */
1590	(void)isc_timer_reset(xfr->max_idle_timer, isc_timertype_inactive, NULL,
1591			      NULL, true);
1592
1593	CHECK(result);
1594
1595	xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", region->length);
1596
1597	dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
1598
1599	CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1600	CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1601
1602	msg->tsigctx = xfr->tsigctx;
1603	xfr->tsigctx = NULL;
1604
1605	dns_message_setclass(msg, xfr->rdclass);
1606
1607	if (xfr->nmsg > 0) {
1608		msg->tcp_continuation = 1;
1609	}
1610
1611	isc_buffer_init(&buffer, region->base, region->length);
1612	isc_buffer_add(&buffer, region->length);
1613	peer = isc_nmhandle_peeraddr(handle);
1614
1615	result = dns_message_parse(msg, &buffer,
1616				   DNS_MESSAGEPARSE_PRESERVEORDER);
1617	if (result == ISC_R_SUCCESS) {
1618		dns_message_logpacket(msg, "received message from", &peer,
1619				      DNS_LOGCATEGORY_XFER_IN,
1620				      DNS_LOGMODULE_XFER_IN, ISC_LOG_DEBUG(10),
1621				      xfr->mctx);
1622	} else {
1623		xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
1624			  isc_result_totext(result));
1625	}
1626
1627	if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1628	    msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass ||
1629	    msg->id != xfr->id)
1630	{
1631		if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
1632		{
1633			result = dns_result_fromrcode(msg->rcode);
1634		} else if (result == ISC_R_SUCCESS &&
1635			   msg->opcode != dns_opcode_query)
1636		{
1637			result = DNS_R_UNEXPECTEDOPCODE;
1638		} else if (result == ISC_R_SUCCESS &&
1639			   msg->rdclass != xfr->rdclass)
1640		{
1641			result = DNS_R_BADCLASS;
1642		} else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) {
1643			result = DNS_R_UNEXPECTEDID;
1644		}
1645
1646		if (xfr->reqtype == dns_rdatatype_axfr ||
1647		    xfr->reqtype == dns_rdatatype_soa)
1648		{
1649			goto failure;
1650		}
1651
1652		xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1653			  isc_result_totext(result));
1654	try_axfr:
1655		isc_nmhandle_detach(&xfr->readhandle);
1656		dns_message_detach(&msg);
1657		xfrin_reset(xfr);
1658		xfr->reqtype = dns_rdatatype_soa;
1659		xfr->state = XFRST_SOAQUERY;
1660		result = xfrin_start(xfr);
1661		if (result != ISC_R_SUCCESS) {
1662			xfrin_fail(xfr, result, "failed setting up socket");
1663		}
1664		dns_xfrin_detach(&xfr); /* recv_xfr */
1665		return;
1666	}
1667
1668	/*
1669	 * The question section should exist for SOA and in the first
1670	 * message of a AXFR or IXFR response.  The question section
1671	 * may exist in the 2nd and subsequent messages in a AXFR or
1672	 * IXFR response.  If the question section exists it should
1673	 * match the question that was sent.
1674	 */
1675	if (msg->counts[DNS_SECTION_QUESTION] > 1) {
1676		xfrin_log(xfr, ISC_LOG_NOTICE, "too many questions (%u)",
1677			  msg->counts[DNS_SECTION_QUESTION]);
1678		result = DNS_R_FORMERR;
1679		goto failure;
1680	}
1681
1682	if ((xfr->state == XFRST_SOAQUERY || xfr->state == XFRST_INITIALSOA) &&
1683	    msg->counts[DNS_SECTION_QUESTION] != 1)
1684	{
1685		xfrin_log(xfr, ISC_LOG_NOTICE, "missing question section");
1686		result = DNS_R_FORMERR;
1687		goto failure;
1688	}
1689
1690	for (result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
1691	     result == ISC_R_SUCCESS;
1692	     result = dns_message_nextname(msg, DNS_SECTION_QUESTION))
1693	{
1694		dns_rdataset_t *rds = NULL;
1695
1696		name = NULL;
1697		dns_message_currentname(msg, DNS_SECTION_QUESTION, &name);
1698		if (!dns_name_equal(name, &xfr->name)) {
1699			result = DNS_R_FORMERR;
1700			xfrin_log(xfr, ISC_LOG_NOTICE,
1701				  "question name mismatch");
1702			goto failure;
1703		}
1704		rds = ISC_LIST_HEAD(name->list);
1705		INSIST(rds != NULL);
1706		if (rds->type != xfr->reqtype) {
1707			result = DNS_R_FORMERR;
1708			xfrin_log(xfr, ISC_LOG_NOTICE,
1709				  "question type mismatch");
1710			goto failure;
1711		}
1712		if (rds->rdclass != xfr->rdclass) {
1713			result = DNS_R_FORMERR;
1714			xfrin_log(xfr, ISC_LOG_NOTICE,
1715				  "question class mismatch");
1716			goto failure;
1717		}
1718	}
1719	if (result != ISC_R_NOMORE) {
1720		goto failure;
1721	}
1722
1723	/*
1724	 * Does the server know about IXFR?  If it doesn't we will get
1725	 * a message with a empty answer section or a potentially a CNAME /
1726	 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1727	 * if the first RR in the answer section is not a SOA record.
1728	 */
1729	if (xfr->reqtype == dns_rdatatype_ixfr &&
1730	    xfr->state == XFRST_INITIALSOA &&
1731	    msg->counts[DNS_SECTION_ANSWER] == 0)
1732	{
1733		xfrin_log(xfr, ISC_LOG_DEBUG(3),
1734			  "empty answer section, retrying with AXFR");
1735		goto try_axfr;
1736	}
1737
1738	if (xfr->reqtype == dns_rdatatype_soa &&
1739	    (msg->flags & DNS_MESSAGEFLAG_AA) == 0)
1740	{
1741		FAIL(DNS_R_NOTAUTHORITATIVE);
1742	}
1743
1744	result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1745	if (result != ISC_R_SUCCESS) {
1746		xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1747			  isc_result_totext(result));
1748		goto failure;
1749	}
1750
1751	for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1752	     result == ISC_R_SUCCESS;
1753	     result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1754	{
1755		dns_rdataset_t *rds = NULL;
1756
1757		name = NULL;
1758		dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1759		for (rds = ISC_LIST_HEAD(name->list); rds != NULL;
1760		     rds = ISC_LIST_NEXT(rds, link))
1761		{
1762			for (result = dns_rdataset_first(rds);
1763			     result == ISC_R_SUCCESS;
1764			     result = dns_rdataset_next(rds))
1765			{
1766				dns_rdata_t rdata = DNS_RDATA_INIT;
1767				dns_rdataset_current(rds, &rdata);
1768				CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1769			}
1770		}
1771	}
1772	if (result != ISC_R_NOMORE) {
1773		goto failure;
1774	}
1775
1776	if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1777		/*
1778		 * Reset the counter.
1779		 */
1780		xfr->sincetsig = 0;
1781
1782		/*
1783		 * Free the last tsig, if there is one.
1784		 */
1785		if (xfr->lasttsig != NULL) {
1786			isc_buffer_free(&xfr->lasttsig);
1787		}
1788
1789		/*
1790		 * Update the last tsig pointer.
1791		 */
1792		CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1793	} else if (dns_message_gettsigkey(msg) != NULL) {
1794		xfr->sincetsig++;
1795		if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1796		    xfr->state == XFRST_AXFR_END ||
1797		    xfr->state == XFRST_IXFR_END)
1798		{
1799			result = DNS_R_EXPECTEDTSIG;
1800			goto failure;
1801		}
1802	}
1803
1804	/*
1805	 * Update the number of messages received.
1806	 */
1807	xfr->nmsg++;
1808
1809	/*
1810	 * Update the number of bytes received.
1811	 */
1812	xfr->nbytes += buffer.used;
1813
1814	/*
1815	 * Take the context back.
1816	 */
1817	INSIST(xfr->tsigctx == NULL);
1818	xfr->tsigctx = msg->tsigctx;
1819	msg->tsigctx = NULL;
1820
1821	switch (xfr->state) {
1822	case XFRST_GOTSOA:
1823		xfr->reqtype = dns_rdatatype_axfr;
1824		xfr->state = XFRST_INITIALSOA;
1825		CHECK(xfrin_send_request(xfr));
1826		break;
1827	case XFRST_AXFR_END:
1828		CHECK(axfr_finalize(xfr));
1829		FALLTHROUGH;
1830	case XFRST_IXFR_END:
1831		/*
1832		 * Close the journal.
1833		 */
1834		if (xfr->ixfr.journal != NULL) {
1835			dns_journal_destroy(&xfr->ixfr.journal);
1836		}
1837
1838		/*
1839		 * Inform the caller we succeeded.
1840		 */
1841		if (xfr->done != NULL) {
1842			(xfr->done)(xfr->zone, ISC_R_SUCCESS);
1843			xfr->done = NULL;
1844		}
1845
1846		atomic_store(&xfr->shuttingdown, true);
1847		(void)isc_timer_reset(xfr->max_time_timer,
1848				      isc_timertype_inactive, NULL, NULL, true);
1849		xfr->shutdown_result = ISC_R_SUCCESS;
1850		break;
1851	default:
1852		/*
1853		 * Read the next message.
1854		 */
1855		/* The readhandle is still attached */
1856		/* The recv_xfr is still attached */
1857		dns_message_detach(&msg);
1858		isc_refcount_increment0(&xfr->recvs);
1859		isc_nm_read(xfr->handle, xfrin_recv_done, xfr);
1860		isc_time_t next;
1861		isc_interval_t interval;
1862		isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
1863		isc_time_nowplusinterval(&next, &interval);
1864		result = isc_timer_reset(xfr->max_idle_timer,
1865					 isc_timertype_once, &next, NULL, true);
1866		RUNTIME_CHECK(result == ISC_R_SUCCESS);
1867		return;
1868	}
1869
1870failure:
1871	if (result != ISC_R_SUCCESS) {
1872		xfrin_fail(xfr, result, "failed while receiving responses");
1873	}
1874
1875	if (msg != NULL) {
1876		dns_message_detach(&msg);
1877	}
1878	isc_nmhandle_detach(&xfr->readhandle);
1879	dns_xfrin_detach(&xfr); /* recv_xfr */
1880}
1881
1882static void
1883xfrin_destroy(dns_xfrin_ctx_t *xfr) {
1884	uint64_t msecs;
1885	uint64_t persec;
1886	const char *result_str;
1887
1888	REQUIRE(VALID_XFRIN(xfr));
1889
1890	/* Safe-guards */
1891	REQUIRE(atomic_load(&xfr->shuttingdown));
1892	isc_refcount_destroy(&xfr->references);
1893	isc_refcount_destroy(&xfr->connects);
1894	isc_refcount_destroy(&xfr->recvs);
1895	isc_refcount_destroy(&xfr->sends);
1896
1897	INSIST(xfr->shutdown_result != ISC_R_UNSET);
1898
1899	/*
1900	 * If we're called through dns_xfrin_detach() and are not
1901	 * shutting down, we can't know what the transfer status is as
1902	 * we are only called when the last reference is lost.
1903	 */
1904	result_str = isc_result_totext(xfr->shutdown_result);
1905	xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str);
1906
1907	/*
1908	 * Calculate the length of time the transfer took,
1909	 * and print a log message with the bytes and rate.
1910	 */
1911	isc_time_now(&xfr->end);
1912	msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1913	if (msecs == 0) {
1914		msecs = 1;
1915	}
1916	persec = (xfr->nbytes * 1000) / msecs;
1917	xfrin_log(xfr, ISC_LOG_INFO,
1918		  "Transfer completed: %d messages, %d records, "
1919		  "%" PRIu64 " bytes, "
1920		  "%u.%03u secs (%u bytes/sec) (serial %u)",
1921		  xfr->nmsg, xfr->nrecs, xfr->nbytes,
1922		  (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
1923		  (unsigned int)persec, xfr->end_serial);
1924
1925	if (xfr->readhandle != NULL) {
1926		isc_nmhandle_detach(&xfr->readhandle);
1927	}
1928	if (xfr->sendhandle != NULL) {
1929		isc_nmhandle_detach(&xfr->sendhandle);
1930	}
1931
1932	if (xfr->transport != NULL) {
1933		dns_transport_detach(&xfr->transport);
1934	}
1935
1936	if (xfr->tsigkey != NULL) {
1937		dns_tsigkey_detach(&xfr->tsigkey);
1938	}
1939
1940	if (xfr->lasttsig != NULL) {
1941		isc_buffer_free(&xfr->lasttsig);
1942	}
1943
1944	dns_diff_clear(&xfr->diff);
1945
1946	if (xfr->ixfr.journal != NULL) {
1947		dns_journal_destroy(&xfr->ixfr.journal);
1948	}
1949
1950	if (xfr->axfr.add_private != NULL) {
1951		(void)dns_db_endload(xfr->db, &xfr->axfr);
1952	}
1953
1954	if (xfr->tsigctx != NULL) {
1955		dst_context_destroy(&xfr->tsigctx);
1956	}
1957
1958	if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) {
1959		dns_name_free(&xfr->name, xfr->mctx);
1960	}
1961
1962	if (xfr->ver != NULL) {
1963		dns_db_closeversion(xfr->db, &xfr->ver, false);
1964	}
1965
1966	if (xfr->db != NULL) {
1967		dns_db_detach(&xfr->db);
1968	}
1969
1970	if (xfr->zone != NULL) {
1971		if (!xfr->zone_had_db &&
1972		    xfr->shutdown_result == ISC_R_SUCCESS &&
1973		    dns_zone_gettype(xfr->zone) == dns_zone_mirror)
1974		{
1975			dns_zone_log(xfr->zone, ISC_LOG_INFO,
1976				     "mirror zone is now in use");
1977		}
1978		xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context");
1979		/*
1980		 * xfr->zone must not be detached before xfrin_log() is called.
1981		 */
1982		dns_zone_idetach(&xfr->zone);
1983	}
1984
1985	if (xfr->firstsoa_data != NULL) {
1986		isc_mem_free(xfr->mctx, xfr->firstsoa_data);
1987	}
1988
1989	if (xfr->tlsctx_cache != NULL) {
1990		isc_tlsctx_cache_detach(&xfr->tlsctx_cache);
1991	}
1992
1993	isc_timer_destroy(&xfr->max_idle_timer);
1994	isc_timer_destroy(&xfr->max_time_timer);
1995
1996	isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1997}
1998
1999/*
2000 * Log incoming zone transfer messages in a format like
2001 * transfer of <zone> from <address>: <message>
2002 */
2003static void
2004xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *primaryaddr,
2005	   const char *fmt, va_list ap) {
2006	char primarytext[ISC_SOCKADDR_FORMATSIZE];
2007	char msgtext[2048];
2008
2009	isc_sockaddr_format(primaryaddr, primarytext, sizeof(primarytext));
2010	vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
2011
2012	isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
2013		      level, "transfer of '%s' from %s: %s", zonetext,
2014		      primarytext, msgtext);
2015}
2016
2017/*
2018 * Logging function for use when a xfrin_ctx_t has not yet been created.
2019 */
2020
2021static void
2022xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *primaryaddr,
2023	   const char *fmt, ...) {
2024	va_list ap;
2025
2026	if (!isc_log_wouldlog(dns_lctx, level)) {
2027		return;
2028	}
2029
2030	va_start(ap, fmt);
2031	xfrin_logv(level, zonetext, primaryaddr, fmt, ap);
2032	va_end(ap);
2033}
2034
2035/*
2036 * Logging function for use when there is a xfrin_ctx_t.
2037 */
2038
2039static void
2040xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) {
2041	va_list ap;
2042	char zonetext[DNS_NAME_MAXTEXT + 32];
2043
2044	if (!isc_log_wouldlog(dns_lctx, level)) {
2045		return;
2046	}
2047
2048	dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
2049
2050	va_start(ap, fmt);
2051	xfrin_logv(level, zonetext, &xfr->primaryaddr, fmt, ap);
2052	va_end(ap);
2053}
2054