xref: /netbsd/external/mpl/bind/dist/lib/dns/xfrin.c (revision a706c3b7)
1 /*	$NetBSD: xfrin.c,v 1.13 2023/06/26 22:03:00 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  */
80 typedef enum {
81 	XFRST_SOAQUERY,
82 	XFRST_GOTSOA,
83 	XFRST_INITIALSOA,
84 	XFRST_FIRSTDATA,
85 	XFRST_IXFR_DELSOA,
86 	XFRST_IXFR_DEL,
87 	XFRST_IXFR_ADDSOA,
88 	XFRST_IXFR_ADD,
89 	XFRST_IXFR_END,
90 	XFRST_AXFR,
91 	XFRST_AXFR_END
92 } xfrin_state_t;
93 
94 /*%
95  * Incoming zone transfer context.
96  */
97 
98 struct dns_xfrin_ctx {
99 	unsigned int magic;
100 	isc_mem_t *mctx;
101 	dns_zone_t *zone;
102 
103 	int refcount;
104 
105 	isc_task_t *task;
106 	isc_timer_t *timer;
107 	isc_socketmgr_t *socketmgr;
108 
109 	int connects; /*%< Connect in progress */
110 	int sends;    /*%< Send in progress */
111 	int recvs;    /*%< Receive in progress */
112 	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 
199 static isc_result_t
200 xfrin_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 
207 static isc_result_t
208 axfr_init(dns_xfrin_ctx_t *xfr);
209 static isc_result_t
210 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
211 static isc_result_t
212 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
213 	     dns_ttl_t ttl, dns_rdata_t *rdata);
214 static isc_result_t
215 axfr_apply(dns_xfrin_ctx_t *xfr);
216 static isc_result_t
217 axfr_commit(dns_xfrin_ctx_t *xfr);
218 static isc_result_t
219 axfr_finalize(dns_xfrin_ctx_t *xfr);
220 
221 static isc_result_t
222 ixfr_init(dns_xfrin_ctx_t *xfr);
223 static isc_result_t
224 ixfr_apply(dns_xfrin_ctx_t *xfr);
225 static isc_result_t
226 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
227 	     dns_ttl_t ttl, dns_rdata_t *rdata);
228 static isc_result_t
229 ixfr_commit(dns_xfrin_ctx_t *xfr);
230 
231 static isc_result_t
232 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
233        dns_rdata_t *rdata);
234 
235 static isc_result_t
236 xfrin_start(dns_xfrin_ctx_t *xfr);
237 
238 static void
239 xfrin_connect_done(isc_task_t *task, isc_event_t *event);
240 static isc_result_t
241 xfrin_send_request(dns_xfrin_ctx_t *xfr);
242 static void
243 xfrin_send_done(isc_task_t *task, isc_event_t *event);
244 static void
245 xfrin_recv_done(isc_task_t *task, isc_event_t *event);
246 static void
247 xfrin_timeout(isc_task_t *task, isc_event_t *event);
248 
249 static void
250 maybe_free(dns_xfrin_ctx_t *xfr);
251 
252 static void
253 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
254 static isc_result_t
255 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
256 
257 static void
258 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
259 	   const char *fmt, va_list ap) ISC_FORMAT_PRINTF(4, 0);
260 
261 static void
262 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
263 	   const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
264 
265 static void
266 xfrin_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 
274 static isc_result_t
axfr_init(dns_xfrin_ctx_t * xfr)275 axfr_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;
288 failure:
289 	return (result);
290 }
291 
292 static isc_result_t
axfr_makedb(dns_xfrin_ctx_t * xfr,dns_db_t ** dbp)293 axfr_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 
308 static isc_result_t
axfr_putdata(dns_xfrin_ctx_t * xfr,dns_diffop_t op,dns_name_t * name,dns_ttl_t ttl,dns_rdata_t * rdata)309 axfr_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;
327 failure:
328 	return (result);
329 }
330 
331 /*
332  * Store a set of AXFR RRs in the database.
333  */
334 static isc_result_t
axfr_apply(dns_xfrin_ctx_t * xfr)335 axfr_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;
350 failure:
351 	return (result);
352 }
353 
354 static isc_result_t
axfr_commit(dns_xfrin_ctx_t * xfr)355 axfr_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;
363 failure:
364 	return (result);
365 }
366 
367 static isc_result_t
axfr_finalize(dns_xfrin_ctx_t * xfr)368 axfr_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;
374 failure:
375 	return (result);
376 }
377 
378 /**************************************************************************/
379 /*
380  * IXFR handling
381  */
382 
383 static isc_result_t
ixfr_init(dns_xfrin_ctx_t * xfr)384 ixfr_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;
405 failure:
406 	return (result);
407 }
408 
409 static isc_result_t
ixfr_putdata(dns_xfrin_ctx_t * xfr,dns_diffop_t op,dns_name_t * name,dns_ttl_t ttl,dns_rdata_t * rdata)410 ixfr_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;
429 failure:
430 	return (result);
431 }
432 
433 /*
434  * Apply a set of IXFR changes to the database.
435  */
436 static isc_result_t
ixfr_apply(dns_xfrin_ctx_t * xfr)437 ixfr_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;
464 failure:
465 	return (result);
466 }
467 
468 static isc_result_t
ixfr_commit(dns_xfrin_ctx_t * xfr)469 ixfr_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;
483 failure:
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  */
496 static isc_result_t
xfr_rr(dns_xfrin_ctx_t * xfr,dns_name_t * name,uint32_t ttl,dns_rdata_t * rdata)497 xfr_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 
524 redo:
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;
695 failure:
696 	return (result);
697 }
698 
699 isc_result_t
dns_xfrin_create(dns_zone_t * zone,dns_rdatatype_t xfrtype,const isc_sockaddr_t * masteraddr,const isc_sockaddr_t * sourceaddr,isc_dscp_t dscp,dns_tsigkey_t * tsigkey,isc_mem_t * mctx,isc_timermgr_t * timermgr,isc_socketmgr_t * socketmgr,isc_task_t * task,dns_xfrindone_t done,dns_xfrin_ctx_t ** xfrp)700 dns_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 
736 failure:
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 
749 void
dns_xfrin_shutdown(dns_xfrin_ctx_t * xfr)750 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
751 	if (!xfr->shuttingdown) {
752 		xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
753 	}
754 }
755 
756 void
dns_xfrin_attach(dns_xfrin_ctx_t * source,dns_xfrin_ctx_t ** target)757 dns_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 
763 void
dns_xfrin_detach(dns_xfrin_ctx_t ** xfrp)764 dns_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 
772 static void
xfrin_cancelio(dns_xfrin_ctx_t * xfr)773 xfrin_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 
784 static void
xfrin_reset(dns_xfrin_ctx_t * xfr)785 xfrin_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 
821 static void
xfrin_fail(dns_xfrin_ctx_t * xfr,isc_result_t result,const char * msg)822 xfrin_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 
847 static isc_result_t
xfrin_create(isc_mem_t * mctx,dns_zone_t * zone,dns_db_t * db,isc_task_t * task,isc_timermgr_t * timermgr,isc_socketmgr_t * socketmgr,dns_name_t * zonename,dns_rdataclass_t rdclass,dns_rdatatype_t reqtype,const isc_sockaddr_t * masteraddr,const isc_sockaddr_t * sourceaddr,isc_dscp_t dscp,dns_tsigkey_t * tsigkey,dns_xfrin_ctx_t ** xfrp)848 xfrin_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 
953 failure:
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 
973 static isc_result_t
xfrin_start(dns_xfrin_ctx_t * xfr)974 xfrin_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);
989 failure:
990 	xfrin_fail(xfr, result, "failed setting up socket");
991 	return (result);
992 }
993 
994 /* XXX the resolver could use this, too */
995 
996 static isc_result_t
render(dns_message_t * msg,isc_mem_t * mctx,isc_buffer_t * buf)997 render(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;
1011 failure:
1012 	if (cleanup_cctx) {
1013 		dns_compress_invalidate(&cctx);
1014 	}
1015 	return (result);
1016 }
1017 
1018 /*
1019  * A connection has been established.
1020  */
1021 static void
xfrin_connect_done(isc_task_t * task,isc_event_t * event)1022 xfrin_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));
1080 failure:
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  */
1090 static isc_result_t
tuple2msgname(dns_difftuple_t * tuple,dns_message_t * msg,dns_name_t ** target)1091 tuple2msgname(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 
1121 failure:
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  */
1141 static isc_result_t
xfrin_send_request(dns_xfrin_ctx_t * xfr)1142 xfrin_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 
1229 failure:
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 
1248 static void
xfrin_send_done(isc_task_t * task,isc_event_t * event)1249 xfrin_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++;
1267 failure:
1268 	isc_event_free(&event);
1269 	if (result != ISC_R_SUCCESS) {
1270 		xfrin_fail(xfr, result, "failed sending request data");
1271 	}
1272 }
1273 
1274 static void
xfrin_recv_done(isc_task_t * task,isc_event_t * ev)1275 xfrin_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 
1513 failure:
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 
1522 static void
xfrin_timeout(isc_task_t * task,isc_event_t * event)1523 xfrin_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 
1537 static void
maybe_free(dns_xfrin_ctx_t * xfr)1538 maybe_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  */
1656 static void
xfrin_logv(int level,const char * zonetext,const isc_sockaddr_t * masteraddr,const char * fmt,va_list ap)1657 xfrin_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 
1674 static void
xfrin_log1(int level,const char * zonetext,const isc_sockaddr_t * masteraddr,const char * fmt,...)1675 xfrin_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 
1692 static void
xfrin_log(dns_xfrin_ctx_t * xfr,int level,const char * fmt,...)1693 xfrin_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