xfrin.c revision 1.1.1.16 1 /* $NetBSD: xfrin.c,v 1.1.1.16 2026/01/29 18:19:53 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/async.h>
22 #include <isc/atomic.h>
23 #include <isc/mem.h>
24 #include <isc/random.h>
25 #include <isc/result.h>
26 #include <isc/string.h>
27 #include <isc/util.h>
28 #include <isc/work.h>
29
30 #include <dns/callbacks.h>
31 #include <dns/catz.h>
32 #include <dns/db.h>
33 #include <dns/diff.h>
34 #include <dns/dispatch.h>
35 #include <dns/journal.h>
36 #include <dns/log.h>
37 #include <dns/message.h>
38 #include <dns/peer.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/trace.h>
45 #include <dns/transport.h>
46 #include <dns/tsig.h>
47 #include <dns/view.h>
48 #include <dns/xfrin.h>
49 #include <dns/zone.h>
50
51 #include <dst/dst.h>
52
53 #include "probes.h"
54
55 /*
56 * Incoming AXFR and IXFR.
57 */
58
59 /*%
60 * The states of the *XFR state machine. We handle both IXFR and AXFR
61 * with a single integrated state machine because they cannot be distinguished
62 * immediately - an AXFR response to an IXFR request can only be detected
63 * when the first two (2) response RRs have already been received.
64 */
65 typedef enum {
66 XFRST_SOAQUERY,
67 XFRST_GOTSOA,
68 XFRST_ZONEXFRREQUEST,
69 XFRST_FIRSTDATA,
70 XFRST_IXFR_DELSOA,
71 XFRST_IXFR_DEL,
72 XFRST_IXFR_ADDSOA,
73 XFRST_IXFR_ADD,
74 XFRST_IXFR_END,
75 XFRST_AXFR,
76 XFRST_AXFR_END
77 } xfrin_state_t;
78
79 /*%
80 * Incoming zone transfer context.
81 */
82
83 struct dns_xfrin {
84 unsigned int magic;
85 isc_mem_t *mctx;
86 dns_zone_t *zone;
87 dns_view_t *view;
88
89 isc_refcount_t references;
90
91 atomic_bool shuttingdown;
92
93 isc_result_t shutdown_result;
94
95 dns_name_t name; /*%< Name of zone to transfer */
96 dns_rdataclass_t rdclass;
97
98 dns_messageid_t id;
99
100 /*%
101 * Requested transfer type (dns_rdatatype_axfr or
102 * dns_rdatatype_ixfr). The actual transfer type
103 * may differ due to IXFR->AXFR fallback.
104 */
105 dns_rdatatype_t reqtype;
106
107 isc_sockaddr_t primaryaddr;
108 isc_sockaddr_t sourceaddr;
109
110 dns_dispatch_t *disp;
111 dns_dispentry_t *dispentry;
112
113 /*% Buffer for IXFR/AXFR request message */
114 isc_buffer_t qbuffer;
115 unsigned char qbuffer_data[512];
116
117 /*%
118 * Whether the zone originally had a database attached at the time this
119 * transfer context was created. Used by xfrin_destroy() when making
120 * logging decisions.
121 */
122 bool zone_had_db;
123
124 dns_db_t *db;
125 dns_dbversion_t *ver;
126 dns_diff_t diff; /*%< Pending database changes */
127
128 /* Diff queue */
129 bool diff_running;
130 struct __cds_wfcq_head diff_head;
131 struct cds_wfcq_tail diff_tail;
132
133 _Atomic xfrin_state_t state;
134 uint32_t expireopt;
135 bool edns, expireoptset;
136 atomic_bool is_ixfr;
137
138 /*
139 * Following variable were made atomic only for loading the values for
140 * the statistics channel, thus all accesses can be **relaxed** because
141 * all store and load operations that affect XFR are done on the same
142 * thread and only the statistics channel thread could perform a load
143 * operation from a different thread and it's ok to not be precise in
144 * the statistics.
145 */
146 atomic_uint nmsg; /*%< Number of messages recvd */
147 atomic_uint nrecs; /*%< Number of records recvd */
148 atomic_uint_fast64_t nbytes; /*%< Number of bytes received */
149 _Atomic(isc_time_t) start; /*%< Start time of the transfer */
150 atomic_uint_fast64_t rate_bytes_per_second;
151 _Atomic(dns_transport_type_t) soa_transport_type;
152 atomic_uint_fast32_t end_serial;
153
154 unsigned int maxrecords; /*%< The maximum number of
155 * records set for the zone */
156 uint64_t nbytes_saved; /*%< For enforcing the minimum transfer rate */
157
158 dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
159 isc_buffer_t *lasttsig; /*%< The last TSIG */
160 dst_context_t *tsigctx; /*%< TSIG verification context */
161 unsigned int sincetsig; /*%< recvd since the last TSIG */
162
163 dns_transport_t *transport;
164
165 dns_xfrindone_t done;
166
167 /*%
168 * AXFR- and IXFR-specific data. Only one is used at a time
169 * according to the is_ixfr flag, so this could be a union,
170 * but keeping them separate makes it a bit simpler to clean
171 * things up when destroying the context.
172 */
173 dns_rdatacallbacks_t axfr;
174
175 struct {
176 uint32_t request_serial;
177 uint32_t current_serial;
178 dns_journal_t *journal;
179 } ixfr;
180
181 dns_rdata_t firstsoa;
182 unsigned char *firstsoa_data;
183
184 isc_tlsctx_cache_t *tlsctx_cache;
185
186 isc_loop_t *loop;
187
188 isc_timer_t *min_rate_timer;
189 isc_timer_t *max_time_timer;
190 isc_timer_t *max_idle_timer;
191
192 char info[DNS_NAME_MAXTEXT + 32];
193 };
194
195 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
196 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
197
198 #define XFRIN_WORK_MAGIC ISC_MAGIC('X', 'f', 'r', 'W')
199 #define VALID_XFRIN_WORK(x) ISC_MAGIC_VALID(x, XFRIN_WORK_MAGIC)
200
201 typedef struct xfrin_work {
202 unsigned int magic;
203 isc_result_t result;
204 dns_xfrin_t *xfr;
205 } xfrin_work_t;
206
207 /**************************************************************************/
208 /*
209 * Forward declarations.
210 */
211
212 static void
213 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop,
214 dns_name_t *zonename, dns_rdataclass_t rdclass,
215 dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
216 const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
217 dns_transport_type_t soa_transport_type,
218 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
219 dns_xfrin_t **xfrp);
220
221 static isc_result_t
222 axfr_init(dns_xfrin_t *xfr);
223 static isc_result_t
224 axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
225 dns_rdata_t *rdata);
226 static void
227 axfr_commit(dns_xfrin_t *xfr);
228 static isc_result_t
229 axfr_finalize(dns_xfrin_t *xfr);
230
231 static isc_result_t
232 ixfr_init(dns_xfrin_t *xfr);
233 static isc_result_t
234 ixfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
235 dns_rdata_t *rdata);
236 static isc_result_t
237 ixfr_commit(dns_xfrin_t *xfr);
238
239 static isc_result_t
240 xfr_rr(dns_xfrin_t *xfr, dns_name_t *name, uint32_t ttl, dns_rdata_t *rdata);
241
242 static isc_result_t
243 xfrin_start(dns_xfrin_t *xfr);
244
245 static void
246 xfrin_connect_done(isc_result_t result, isc_region_t *region, void *arg);
247 static isc_result_t
248 xfrin_send_request(dns_xfrin_t *xfr);
249 static void
250 xfrin_send_done(isc_result_t eresult, isc_region_t *region, void *arg);
251 static void
252 xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg);
253
254 static void
255 xfrin_end(dns_xfrin_t *xfr, isc_result_t result);
256
257 static void
258 xfrin_destroy(dns_xfrin_t *xfr);
259
260 static void
261 xfrin_timedout(void *);
262 static void
263 xfrin_idledout(void *);
264 static void
265 xfrin_minratecheck(void *);
266 static void
267 xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg);
268 static isc_result_t
269 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
270
271 static void
272 xfrin_log(dns_xfrin_t *xfr, int level, const char *fmt, ...)
273 ISC_FORMAT_PRINTF(3, 4);
274
275 /**************************************************************************/
276 /*
277 * AXFR handling
278 */
279
280 static isc_result_t
281 axfr_init(dns_xfrin_t *xfr) {
282 isc_result_t result;
283
284 atomic_store(&xfr->is_ixfr, false);
285
286 if (xfr->db != NULL) {
287 dns_db_detach(&xfr->db);
288 }
289
290 CHECK(dns_zone_makedb(xfr->zone, &xfr->db));
291
292 dns_zone_rpz_enable_db(xfr->zone, xfr->db);
293 dns_zone_catz_enable_db(xfr->zone, xfr->db);
294
295 dns_rdatacallbacks_init(&xfr->axfr);
296 CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
297 result = ISC_R_SUCCESS;
298 cleanup:
299 return result;
300 }
301
302 static void
303 axfr_apply(void *arg);
304
305 static isc_result_t
306 axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
307 dns_rdata_t *rdata) {
308 isc_result_t result;
309
310 dns_difftuple_t *tuple = NULL;
311
312 if (rdata->rdclass != xfr->rdclass) {
313 return DNS_R_BADCLASS;
314 }
315
316 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
317
318 if (dns_diff_size(&xfr->diff) > 128 &&
319 dns_diff_is_boundary(&xfr->diff, name))
320 {
321 xfrin_work_t work = (xfrin_work_t){
322 .magic = XFRIN_WORK_MAGIC,
323 .result = ISC_R_UNSET,
324 .xfr = xfr,
325 };
326 axfr_apply((void *)&work);
327 CHECK(work.result);
328 }
329
330 CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
331 &tuple));
332 dns_diff_append(&xfr->diff, &tuple);
333
334 result = ISC_R_SUCCESS;
335 cleanup:
336 return result;
337 }
338
339 /*
340 * Store a set of AXFR RRs in the database.
341 */
342 static void
343 axfr_apply(void *arg) {
344 xfrin_work_t *work = arg;
345 REQUIRE(VALID_XFRIN_WORK(work));
346
347 dns_xfrin_t *xfr = work->xfr;
348 REQUIRE(VALID_XFRIN(xfr));
349
350 isc_result_t result = ISC_R_SUCCESS;
351 uint64_t records;
352
353 if (atomic_load(&xfr->shuttingdown)) {
354 CHECK(ISC_R_SHUTTINGDOWN);
355 }
356
357 CHECK(dns_diff_load(&xfr->diff, &xfr->axfr));
358 if (xfr->maxrecords != 0U) {
359 result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
360 if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
361 CHECK(DNS_R_TOOMANYRECORDS);
362 }
363 }
364
365 cleanup:
366 dns_diff_clear(&xfr->diff);
367 work->result = result;
368 }
369
370 static void
371 axfr_apply_done(void *arg) {
372 xfrin_work_t *work = arg;
373 REQUIRE(VALID_XFRIN_WORK(work));
374
375 dns_xfrin_t *xfr = work->xfr;
376 isc_result_t result = work->result;
377
378 REQUIRE(VALID_XFRIN(xfr));
379
380 if (atomic_load(&xfr->shuttingdown)) {
381 result = ISC_R_SHUTTINGDOWN;
382 }
383
384 if (result == ISC_R_SUCCESS) {
385 CHECK(dns_db_endload(xfr->db, &xfr->axfr));
386 CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL));
387 CHECK(axfr_finalize(xfr));
388 } else {
389 (void)dns_db_endload(xfr->db, &xfr->axfr);
390 }
391
392 cleanup:
393 xfr->diff_running = false;
394
395 isc_mem_put(xfr->mctx, work, sizeof(*work));
396
397 if (result == ISC_R_SUCCESS) {
398 if (atomic_load(&xfr->state) == XFRST_AXFR_END) {
399 xfrin_end(xfr, result);
400 }
401 } else {
402 xfrin_fail(xfr, result, "failed while processing responses");
403 }
404
405 dns_xfrin_detach(&xfr);
406 }
407
408 static void
409 axfr_commit(dns_xfrin_t *xfr) {
410 REQUIRE(!xfr->diff_running);
411
412 xfrin_work_t *work = isc_mem_get(xfr->mctx, sizeof(*work));
413 *work = (xfrin_work_t){
414 .magic = XFRIN_WORK_MAGIC,
415 .result = ISC_R_UNSET,
416 .xfr = dns_xfrin_ref(xfr),
417 };
418 xfr->diff_running = true;
419 isc_work_enqueue(xfr->loop, axfr_apply, axfr_apply_done, work);
420 }
421
422 static isc_result_t
423 axfr_finalize(dns_xfrin_t *xfr) {
424 isc_result_t result;
425
426 LIBDNS_XFRIN_AXFR_FINALIZE_BEGIN(xfr, xfr->info);
427 result = dns_zone_replacedb(xfr->zone, xfr->db, true);
428 LIBDNS_XFRIN_AXFR_FINALIZE_END(xfr, xfr->info, result);
429
430 return result;
431 }
432
433 /**************************************************************************/
434 /*
435 * IXFR handling
436 */
437
438 typedef struct ixfr_apply_data {
439 dns_diff_t diff; /*%< Pending database changes */
440 struct cds_wfcq_node wfcq_node;
441 } ixfr_apply_data_t;
442
443 static isc_result_t
444 ixfr_init(dns_xfrin_t *xfr) {
445 isc_result_t result;
446 char *journalfile = NULL;
447
448 if (xfr->reqtype != dns_rdatatype_ixfr) {
449 xfrin_log(xfr, ISC_LOG_NOTICE,
450 "got incremental response to AXFR request");
451 return DNS_R_FORMERR;
452 }
453
454 atomic_store(&xfr->is_ixfr, true);
455 INSIST(xfr->db != NULL);
456
457 journalfile = dns_zone_getjournal(xfr->zone);
458 if (journalfile != NULL) {
459 CHECK(dns_journal_open(xfr->mctx, journalfile,
460 DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
461 }
462
463 result = ISC_R_SUCCESS;
464 cleanup:
465 return result;
466 }
467
468 static isc_result_t
469 ixfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
470 dns_rdata_t *rdata) {
471 isc_result_t result;
472 dns_difftuple_t *tuple = NULL;
473
474 if (rdata->rdclass != xfr->rdclass) {
475 return DNS_R_BADCLASS;
476 }
477
478 if (op == DNS_DIFFOP_ADD) {
479 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
480 }
481 CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
482 &tuple));
483 dns_diff_append(&xfr->diff, &tuple);
484 result = ISC_R_SUCCESS;
485 cleanup:
486 return result;
487 }
488
489 static isc_result_t
490 ixfr_begin_transaction(dns_xfrin_t *xfr) {
491 isc_result_t result = ISC_R_SUCCESS;
492
493 if (xfr->ixfr.journal != NULL) {
494 CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
495 }
496 cleanup:
497 return result;
498 }
499
500 static isc_result_t
501 ixfr_end_transaction(dns_xfrin_t *xfr) {
502 isc_result_t result = ISC_R_SUCCESS;
503
504 CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver));
505 /* XXX enter ready-to-commit state here */
506 if (xfr->ixfr.journal != NULL) {
507 CHECK(dns_journal_commit(xfr->ixfr.journal));
508 }
509 cleanup:
510 return result;
511 }
512
513 static isc_result_t
514 ixfr_apply_one(dns_xfrin_t *xfr, ixfr_apply_data_t *data) {
515 isc_result_t result = ISC_R_SUCCESS;
516 uint64_t records;
517
518 CHECK(ixfr_begin_transaction(xfr));
519
520 CHECK(dns_diff_apply(&data->diff, xfr->db, xfr->ver));
521 if (xfr->maxrecords != 0U) {
522 result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
523 if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
524 CHECK(DNS_R_TOOMANYRECORDS);
525 }
526 }
527 if (xfr->ixfr.journal != NULL) {
528 CHECK(dns_journal_writediff(xfr->ixfr.journal, &data->diff));
529 }
530
531 result = ixfr_end_transaction(xfr);
532
533 return result;
534 cleanup:
535 /* We need to end the transaction, but keep the previous error */
536 (void)ixfr_end_transaction(xfr);
537
538 return result;
539 }
540
541 static void
542 ixfr_apply(void *arg) {
543 xfrin_work_t *work = arg;
544 dns_xfrin_t *xfr = work->xfr;
545 isc_result_t result = ISC_R_SUCCESS;
546
547 REQUIRE(VALID_XFRIN(xfr));
548 REQUIRE(VALID_XFRIN_WORK(work));
549
550 struct __cds_wfcq_head diff_head;
551 struct cds_wfcq_tail diff_tail;
552
553 /* Initialize local wfcqueue */
554 __cds_wfcq_init(&diff_head, &diff_tail);
555
556 enum cds_wfcq_ret ret = __cds_wfcq_splice_blocking(
557 &diff_head, &diff_tail, &xfr->diff_head, &xfr->diff_tail);
558 INSIST(ret == CDS_WFCQ_RET_DEST_EMPTY);
559
560 struct cds_wfcq_node *node, *next;
561 __cds_wfcq_for_each_blocking_safe(&diff_head, &diff_tail, node, next) {
562 ixfr_apply_data_t *data =
563 caa_container_of(node, ixfr_apply_data_t, wfcq_node);
564
565 if (atomic_load(&xfr->shuttingdown)) {
566 result = ISC_R_SHUTTINGDOWN;
567 }
568
569 /* Apply only until first failure */
570 if (result == ISC_R_SUCCESS) {
571 /* This also checks for shuttingdown condition */
572 result = ixfr_apply_one(xfr, data);
573 }
574
575 /* We need to clear and free all data chunks */
576 dns_diff_clear(&data->diff);
577 isc_mem_put(xfr->mctx, data, sizeof(*data));
578 }
579
580 work->result = result;
581 }
582
583 static void
584 ixfr_apply_done(void *arg) {
585 xfrin_work_t *work = arg;
586 REQUIRE(VALID_XFRIN_WORK(work));
587
588 dns_xfrin_t *xfr = work->xfr;
589 REQUIRE(VALID_XFRIN(xfr));
590
591 isc_result_t result = work->result;
592
593 if (atomic_load(&xfr->shuttingdown)) {
594 result = ISC_R_SHUTTINGDOWN;
595 }
596
597 CHECK(result);
598
599 /* Reschedule */
600 if (!cds_wfcq_empty(&xfr->diff_head, &xfr->diff_tail)) {
601 isc_work_enqueue(xfr->loop, ixfr_apply, ixfr_apply_done, work);
602 return;
603 }
604
605 cleanup:
606 xfr->diff_running = false;
607
608 isc_mem_put(xfr->mctx, work, sizeof(*work));
609
610 if (result == ISC_R_SUCCESS) {
611 dns_db_closeversion(xfr->db, &xfr->ver, true);
612 dns_zone_markdirty(xfr->zone);
613
614 if (atomic_load(&xfr->state) == XFRST_IXFR_END) {
615 xfrin_end(xfr, result);
616 }
617 } else {
618 dns_db_closeversion(xfr->db, &xfr->ver, false);
619
620 xfrin_fail(xfr, result, "failed while processing responses");
621 }
622
623 dns_xfrin_detach(&xfr);
624 }
625
626 /*
627 * Apply a set of IXFR changes to the database.
628 */
629 static isc_result_t
630 ixfr_commit(dns_xfrin_t *xfr) {
631 isc_result_t result = ISC_R_SUCCESS;
632 ixfr_apply_data_t *data = isc_mem_get(xfr->mctx, sizeof(*data));
633
634 *data = (ixfr_apply_data_t){ 0 };
635 cds_wfcq_node_init(&data->wfcq_node);
636
637 if (xfr->ver == NULL) {
638 CHECK(dns_db_newversion(xfr->db, &xfr->ver));
639 }
640
641 dns_diff_init(xfr->mctx, &data->diff);
642 /* FIXME: Should we add dns_diff_move() */
643 ISC_LIST_MOVE(data->diff.tuples, xfr->diff.tuples);
644
645 (void)cds_wfcq_enqueue(&xfr->diff_head, &xfr->diff_tail,
646 &data->wfcq_node);
647
648 if (!xfr->diff_running) {
649 xfrin_work_t *work = isc_mem_get(xfr->mctx, sizeof(*work));
650 *work = (xfrin_work_t){
651 .magic = XFRIN_WORK_MAGIC,
652 .result = ISC_R_UNSET,
653 .xfr = dns_xfrin_ref(xfr),
654 };
655 xfr->diff_running = true;
656 isc_work_enqueue(xfr->loop, ixfr_apply, ixfr_apply_done, work);
657 }
658
659 cleanup:
660 return result;
661 }
662
663 /**************************************************************************/
664 /*
665 * Common AXFR/IXFR protocol code
666 */
667
668 /*
669 * Handle a single incoming resource record according to the current
670 * state.
671 */
672 static isc_result_t
673 xfr_rr(dns_xfrin_t *xfr, dns_name_t *name, uint32_t ttl, dns_rdata_t *rdata) {
674 isc_result_t result;
675 uint_fast32_t end_serial;
676
677 atomic_fetch_add_relaxed(&xfr->nrecs, 1);
678
679 if (rdata->type == dns_rdatatype_none ||
680 dns_rdatatype_ismeta(rdata->type))
681 {
682 char buf[64];
683 dns_rdatatype_format(rdata->type, buf, sizeof(buf));
684 xfrin_log(xfr, ISC_LOG_NOTICE,
685 "Unexpected %s record in zone transfer", buf);
686 CHECK(DNS_R_FORMERR);
687 }
688
689 /*
690 * Immediately reject the entire transfer if the RR that is currently
691 * being processed is an SOA record that is not placed at the zone
692 * apex.
693 */
694 if (rdata->type == dns_rdatatype_soa &&
695 !dns_name_equal(&xfr->name, name))
696 {
697 char namebuf[DNS_NAME_FORMATSIZE];
698 dns_name_format(name, namebuf, sizeof(namebuf));
699 xfrin_log(xfr, ISC_LOG_DEBUG(3), "SOA name mismatch: '%s'",
700 namebuf);
701 CHECK(DNS_R_NOTZONETOP);
702 }
703
704 redo:
705 switch (atomic_load(&xfr->state)) {
706 case XFRST_SOAQUERY:
707 if (rdata->type != dns_rdatatype_soa) {
708 xfrin_log(xfr, ISC_LOG_NOTICE,
709 "non-SOA response to SOA query");
710 CHECK(DNS_R_FORMERR);
711 }
712 end_serial = dns_soa_getserial(rdata);
713 atomic_store_relaxed(&xfr->end_serial, end_serial);
714 if (!DNS_SERIAL_GT(end_serial, xfr->ixfr.request_serial) &&
715 !dns_zone_isforced(xfr->zone))
716 {
717 xfrin_log(xfr, ISC_LOG_DEBUG(3),
718 "requested serial %u, "
719 "primary has %" PRIuFAST32 ", not updating",
720 xfr->ixfr.request_serial, end_serial);
721 CHECK(DNS_R_UPTODATE);
722 }
723 atomic_store(&xfr->state, XFRST_GOTSOA);
724 break;
725
726 case XFRST_GOTSOA:
727 /*
728 * Skip other records in the answer section.
729 */
730 break;
731
732 case XFRST_ZONEXFRREQUEST:
733 if (rdata->type != dns_rdatatype_soa) {
734 xfrin_log(xfr, ISC_LOG_NOTICE,
735 "first RR in zone transfer must be SOA");
736 CHECK(DNS_R_FORMERR);
737 }
738 /*
739 * Remember the serial number in the initial SOA.
740 * We need it to recognize the end of an IXFR.
741 */
742 end_serial = dns_soa_getserial(rdata);
743 atomic_store_relaxed(&xfr->end_serial, end_serial);
744 if (xfr->reqtype == dns_rdatatype_ixfr &&
745 !DNS_SERIAL_GT(end_serial, xfr->ixfr.request_serial) &&
746 !dns_zone_isforced(xfr->zone))
747 {
748 /*
749 * This must be the single SOA record that is
750 * sent when the current version on the primary
751 * is not newer than the version in the request.
752 */
753 xfrin_log(xfr, ISC_LOG_DEBUG(3),
754 "requested serial %u, "
755 "primary has %" PRIuFAST32 ", not updating",
756 xfr->ixfr.request_serial, end_serial);
757 CHECK(DNS_R_UPTODATE);
758 }
759 xfr->firstsoa = *rdata;
760 if (xfr->firstsoa_data != NULL) {
761 isc_mem_free(xfr->mctx, xfr->firstsoa_data);
762 }
763 xfr->firstsoa_data = isc_mem_allocate(xfr->mctx, rdata->length);
764 memcpy(xfr->firstsoa_data, rdata->data, rdata->length);
765 xfr->firstsoa.data = xfr->firstsoa_data;
766 atomic_store(&xfr->state, XFRST_FIRSTDATA);
767 break;
768
769 case XFRST_FIRSTDATA:
770 /*
771 * If the transfer begins with one SOA record, it is an AXFR,
772 * if it begins with two SOAs, it is an IXFR.
773 */
774 if (xfr->reqtype == dns_rdatatype_ixfr &&
775 rdata->type == dns_rdatatype_soa &&
776 xfr->ixfr.request_serial == dns_soa_getserial(rdata))
777 {
778 xfrin_log(xfr, ISC_LOG_DEBUG(3),
779 "got incremental response");
780 CHECK(ixfr_init(xfr));
781 atomic_store(&xfr->state, XFRST_IXFR_DELSOA);
782 } else {
783 xfrin_log(xfr, ISC_LOG_DEBUG(3),
784 "got nonincremental response");
785 CHECK(axfr_init(xfr));
786 atomic_store(&xfr->state, XFRST_AXFR);
787 }
788 goto redo;
789
790 case XFRST_IXFR_DELSOA:
791 INSIST(rdata->type == dns_rdatatype_soa);
792 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
793 atomic_store(&xfr->state, XFRST_IXFR_DEL);
794 break;
795
796 case XFRST_IXFR_DEL:
797 if (rdata->type == dns_rdatatype_soa) {
798 uint32_t soa_serial = dns_soa_getserial(rdata);
799 atomic_store(&xfr->state, XFRST_IXFR_ADDSOA);
800 xfr->ixfr.current_serial = soa_serial;
801 goto redo;
802 }
803 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
804 break;
805
806 case XFRST_IXFR_ADDSOA:
807 INSIST(rdata->type == dns_rdatatype_soa);
808 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
809 atomic_store(&xfr->state, XFRST_IXFR_ADD);
810 break;
811
812 case XFRST_IXFR_ADD:
813 if (rdata->type == dns_rdatatype_soa) {
814 uint32_t soa_serial = dns_soa_getserial(rdata);
815 if (soa_serial == atomic_load_relaxed(&xfr->end_serial))
816 {
817 CHECK(ixfr_commit(xfr));
818 atomic_store(&xfr->state, XFRST_IXFR_END);
819 break;
820 } else if (soa_serial != xfr->ixfr.current_serial) {
821 xfrin_log(xfr, ISC_LOG_NOTICE,
822 "IXFR out of sync: "
823 "expected serial %u, got %u",
824 xfr->ixfr.current_serial, soa_serial);
825 CHECK(DNS_R_FORMERR);
826 } else {
827 CHECK(ixfr_commit(xfr));
828 atomic_store(&xfr->state, XFRST_IXFR_DELSOA);
829 goto redo;
830 }
831 }
832 if (rdata->type == dns_rdatatype_ns &&
833 dns_name_iswildcard(name))
834 {
835 CHECK(DNS_R_INVALIDNS);
836 }
837 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
838 break;
839
840 case XFRST_AXFR:
841 /*
842 * Old BINDs sent cross class A records for non IN classes.
843 */
844 if (rdata->type == dns_rdatatype_a &&
845 rdata->rdclass != xfr->rdclass &&
846 xfr->rdclass != dns_rdataclass_in)
847 {
848 break;
849 }
850 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
851 if (rdata->type == dns_rdatatype_soa) {
852 /*
853 * Use dns_rdata_compare instead of memcmp to
854 * allow for case differences.
855 */
856 if (dns_rdata_compare(rdata, &xfr->firstsoa) != 0) {
857 xfrin_log(xfr, ISC_LOG_NOTICE,
858 "start and ending SOA records "
859 "mismatch");
860 CHECK(DNS_R_FORMERR);
861 }
862 axfr_commit(xfr);
863 atomic_store(&xfr->state, XFRST_AXFR_END);
864 break;
865 }
866 break;
867 case XFRST_AXFR_END:
868 case XFRST_IXFR_END:
869 CHECK(DNS_R_EXTRADATA);
870 break;
871 default:
872 UNREACHABLE();
873 }
874 result = ISC_R_SUCCESS;
875 cleanup:
876 return result;
877 }
878
879 void
880 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
881 const isc_sockaddr_t *primaryaddr,
882 const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
883 dns_transport_type_t soa_transport_type,
884 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
885 isc_mem_t *mctx, dns_xfrin_t **xfrp) {
886 dns_name_t *zonename = dns_zone_getorigin(zone);
887 dns_xfrin_t *xfr = NULL;
888 dns_db_t *db = NULL;
889 isc_loop_t *loop = NULL;
890
891 REQUIRE(xfrp != NULL && *xfrp == NULL);
892 REQUIRE(isc_sockaddr_getport(primaryaddr) != 0);
893 REQUIRE(zone != NULL);
894 REQUIRE(dns_zone_getview(zone) != NULL);
895
896 loop = dns_zone_getloop(zone);
897
898 (void)dns_zone_getdb(zone, &db);
899
900 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) {
901 REQUIRE(db != NULL);
902 }
903
904 xfrin_create(mctx, zone, db, loop, zonename, dns_zone_getclass(zone),
905 xfrtype, primaryaddr, sourceaddr, tsigkey,
906 soa_transport_type, transport, tlsctx_cache, &xfr);
907
908 if (db != NULL) {
909 xfr->zone_had_db = true;
910 dns_db_detach(&db);
911 }
912
913 *xfrp = xfr;
914 }
915
916 isc_result_t
917 dns_xfrin_start(dns_xfrin_t *xfr, dns_xfrindone_t done) {
918 isc_result_t result;
919
920 REQUIRE(xfr != NULL);
921 REQUIRE(xfr->zone != NULL);
922 REQUIRE(done != NULL);
923
924 xfr->done = done;
925
926 result = xfrin_start(xfr);
927 if (result != ISC_R_SUCCESS) {
928 xfr->done = NULL;
929 xfrin_fail(xfr, result, "zone transfer start failed");
930 }
931
932 return result;
933 }
934
935 static void
936 xfrin_timedout(void *xfr) {
937 REQUIRE(VALID_XFRIN(xfr));
938
939 xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum transfer time exceeded");
940 }
941
942 static void
943 xfrin_idledout(void *xfr) {
944 REQUIRE(VALID_XFRIN(xfr));
945
946 xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum idle time exceeded");
947 }
948
949 static void
950 xfrin_minratecheck(void *arg) {
951 dns_xfrin_t *xfr = arg;
952
953 REQUIRE(VALID_XFRIN(xfr));
954
955 const uint64_t nbytes = atomic_load_relaxed(&xfr->nbytes);
956 const uint64_t min = dns_zone_getminxfrratebytesin(xfr->zone);
957 uint64_t rate = nbytes - xfr->nbytes_saved;
958
959 if (rate < min) {
960 isc_timer_stop(xfr->min_rate_timer);
961 xfrin_fail(xfr, ISC_R_TIMEDOUT,
962 "minimum transfer rate reached");
963 } else {
964 xfr->nbytes_saved = nbytes;
965
966 /*
967 * Calculate and store for the statistics channel the transfer
968 * rate in bytes-per-second for the latest interval.
969 */
970 rate /= dns_zone_getminxfrratesecondsin(xfr->zone);
971 atomic_store_relaxed(&xfr->rate_bytes_per_second, rate);
972 }
973 }
974
975 isc_time_t
976 dns_xfrin_getstarttime(dns_xfrin_t *xfr) {
977 REQUIRE(VALID_XFRIN(xfr));
978
979 return atomic_load_relaxed(&xfr->start);
980 }
981
982 void
983 dns_xfrin_getstate(const dns_xfrin_t *xfr, const char **statestr,
984 bool *is_first_data_received, bool *is_ixfr) {
985 xfrin_state_t state;
986
987 REQUIRE(VALID_XFRIN(xfr));
988 REQUIRE(statestr != NULL && *statestr == NULL);
989 REQUIRE(is_ixfr != NULL);
990
991 state = atomic_load(&xfr->state);
992 *statestr = "";
993 *is_first_data_received = (state > XFRST_FIRSTDATA);
994 *is_ixfr = atomic_load(&xfr->is_ixfr);
995
996 switch (state) {
997 case XFRST_SOAQUERY:
998 *statestr = "SOA Query";
999 break;
1000 case XFRST_GOTSOA:
1001 *statestr = "Got SOA";
1002 break;
1003 case XFRST_ZONEXFRREQUEST:
1004 *statestr = "Zone Transfer Request";
1005 break;
1006 case XFRST_FIRSTDATA:
1007 *statestr = "First Data";
1008 break;
1009 case XFRST_IXFR_DELSOA:
1010 case XFRST_IXFR_DEL:
1011 case XFRST_IXFR_ADDSOA:
1012 case XFRST_IXFR_ADD:
1013 *statestr = "Receiving IXFR Data";
1014 break;
1015 case XFRST_IXFR_END:
1016 *statestr = "Finalizing IXFR";
1017 break;
1018 case XFRST_AXFR:
1019 *statestr = "Receiving AXFR Data";
1020 break;
1021 case XFRST_AXFR_END:
1022 *statestr = "Finalizing AXFR";
1023 break;
1024 }
1025 }
1026
1027 uint32_t
1028 dns_xfrin_getendserial(dns_xfrin_t *xfr) {
1029 REQUIRE(VALID_XFRIN(xfr));
1030
1031 return atomic_load_relaxed(&xfr->end_serial);
1032 }
1033
1034 void
1035 dns_xfrin_getstats(dns_xfrin_t *xfr, unsigned int *nmsgp, unsigned int *nrecsp,
1036 uint64_t *nbytesp, uint64_t *ratep) {
1037 REQUIRE(VALID_XFRIN(xfr));
1038 REQUIRE(nmsgp != NULL && nrecsp != NULL && nbytesp != NULL);
1039
1040 uint64_t rate = atomic_load_relaxed(&xfr->rate_bytes_per_second);
1041 if (rate == 0) {
1042 /*
1043 * Likely the first 'min-transfer-rate-in <bytes> <minutes>'
1044 * minutes interval hasn't passed yet. Calculate the overall
1045 * average transfer rate instead.
1046 */
1047 isc_time_t now = isc_time_now();
1048 isc_time_t start = atomic_load_relaxed(&xfr->start);
1049 uint64_t sec = isc_time_microdiff(&now, &start) / US_PER_SEC;
1050 if (sec > 0) {
1051 rate = atomic_load_relaxed(&xfr->nbytes) / sec;
1052 }
1053 }
1054
1055 SET_IF_NOT_NULL(nmsgp, atomic_load_relaxed(&xfr->nmsg));
1056 SET_IF_NOT_NULL(nrecsp, atomic_load_relaxed(&xfr->nrecs));
1057 SET_IF_NOT_NULL(nbytesp, atomic_load_relaxed(&xfr->nbytes));
1058 SET_IF_NOT_NULL(ratep, rate);
1059 }
1060
1061 const isc_sockaddr_t *
1062 dns_xfrin_getsourceaddr(const dns_xfrin_t *xfr) {
1063 REQUIRE(VALID_XFRIN(xfr));
1064
1065 return &xfr->sourceaddr;
1066 }
1067
1068 const isc_sockaddr_t *
1069 dns_xfrin_getprimaryaddr(const dns_xfrin_t *xfr) {
1070 REQUIRE(VALID_XFRIN(xfr));
1071
1072 return &xfr->primaryaddr;
1073 }
1074
1075 dns_transport_type_t
1076 dns_xfrin_gettransporttype(const dns_xfrin_t *xfr) {
1077 REQUIRE(VALID_XFRIN(xfr));
1078
1079 if (xfr->transport != NULL) {
1080 return dns_transport_get_type(xfr->transport);
1081 }
1082
1083 return DNS_TRANSPORT_TCP;
1084 }
1085
1086 dns_transport_type_t
1087 dns_xfrin_getsoatransporttype(dns_xfrin_t *xfr) {
1088 REQUIRE(VALID_XFRIN(xfr));
1089
1090 return atomic_load_relaxed(&xfr->soa_transport_type);
1091 }
1092
1093 const dns_name_t *
1094 dns_xfrin_gettsigkeyname(const dns_xfrin_t *xfr) {
1095 REQUIRE(VALID_XFRIN(xfr));
1096
1097 if (xfr->tsigkey == NULL || xfr->tsigkey->key == NULL) {
1098 return NULL;
1099 }
1100
1101 return dst_key_name(xfr->tsigkey->key);
1102 }
1103
1104 static void
1105 xfrin_shutdown(void *arg) {
1106 dns_xfrin_t *xfr = arg;
1107
1108 REQUIRE(VALID_XFRIN(xfr));
1109
1110 xfrin_fail(xfr, ISC_R_SHUTTINGDOWN, "shut down");
1111 dns_xfrin_detach(&xfr);
1112 }
1113
1114 void
1115 dns_xfrin_shutdown(dns_xfrin_t *xfr) {
1116 REQUIRE(VALID_XFRIN(xfr));
1117
1118 if (xfr->loop != isc_loop()) {
1119 dns_xfrin_ref(xfr);
1120 isc_async_run(xfr->loop, xfrin_shutdown, xfr);
1121 } else {
1122 xfrin_fail(xfr, ISC_R_SHUTTINGDOWN, "shut down");
1123 }
1124 }
1125
1126 #if DNS_XFRIN_TRACE
1127 ISC_REFCOUNT_TRACE_IMPL(dns_xfrin, xfrin_destroy);
1128 #else
1129 ISC_REFCOUNT_IMPL(dns_xfrin, xfrin_destroy);
1130 #endif
1131
1132 static void
1133 xfrin_cancelio(dns_xfrin_t *xfr) {
1134 if (xfr->dispentry != NULL) {
1135 dns_dispatch_done(&xfr->dispentry);
1136 }
1137 if (xfr->disp != NULL) {
1138 dns_dispatch_detach(&xfr->disp);
1139 }
1140 }
1141
1142 static void
1143 xfrin_reset(dns_xfrin_t *xfr) {
1144 REQUIRE(VALID_XFRIN(xfr));
1145
1146 xfrin_log(xfr, ISC_LOG_INFO, "resetting");
1147
1148 if (xfr->lasttsig != NULL) {
1149 isc_buffer_free(&xfr->lasttsig);
1150 }
1151
1152 dns_diff_clear(&xfr->diff);
1153
1154 if (xfr->ixfr.journal != NULL) {
1155 dns_journal_destroy(&xfr->ixfr.journal);
1156 }
1157
1158 if (xfr->axfr.add_private != NULL) {
1159 (void)dns_db_endload(xfr->db, &xfr->axfr);
1160 }
1161
1162 if (xfr->ver != NULL) {
1163 dns_db_closeversion(xfr->db, &xfr->ver, false);
1164 }
1165 }
1166
1167 static void
1168 xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) {
1169 REQUIRE(VALID_XFRIN(xfr));
1170
1171 dns_xfrin_ref(xfr);
1172
1173 /* Make sure only the first xfrin_fail() trumps */
1174 if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false },
1175 true))
1176 {
1177 if (result != DNS_R_UPTODATE) {
1178 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
1179 isc_result_totext(result));
1180 if (atomic_load(&xfr->is_ixfr) &&
1181 result != ISC_R_CANCELED &&
1182 result != ISC_R_SHUTTINGDOWN)
1183 {
1184 /*
1185 * Pass special result code to force AXFR retry
1186 */
1187 result = DNS_R_BADIXFR;
1188 }
1189 }
1190
1191 xfrin_cancelio(xfr);
1192
1193 xfrin_end(xfr, result);
1194 }
1195
1196 dns_xfrin_detach(&xfr);
1197 }
1198
1199 static void
1200 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop,
1201 dns_name_t *zonename, dns_rdataclass_t rdclass,
1202 dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
1203 const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
1204 dns_transport_type_t soa_transport_type,
1205 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
1206 dns_xfrin_t **xfrp) {
1207 dns_xfrin_t *xfr = NULL;
1208
1209 xfr = isc_mem_get(mctx, sizeof(*xfr));
1210 *xfr = (dns_xfrin_t){
1211 .shutdown_result = ISC_R_UNSET,
1212 .rdclass = rdclass,
1213 .reqtype = reqtype,
1214 .maxrecords = dns_zone_getmaxrecords(zone),
1215 .primaryaddr = *primaryaddr,
1216 .sourceaddr = *sourceaddr,
1217 .soa_transport_type = soa_transport_type,
1218 .firstsoa = DNS_RDATA_INIT,
1219 .edns = true,
1220 .references = 1,
1221 .magic = XFRIN_MAGIC,
1222 };
1223
1224 isc_loop_attach(loop, &xfr->loop);
1225 isc_mem_attach(mctx, &xfr->mctx);
1226 dns_zone_iattach(zone, &xfr->zone);
1227 dns_view_weakattach(dns_zone_getview(zone), &xfr->view);
1228 dns_name_init(&xfr->name, NULL);
1229
1230 __cds_wfcq_init(&xfr->diff_head, &xfr->diff_tail);
1231
1232 atomic_init(&xfr->is_ixfr, false);
1233
1234 if (db != NULL) {
1235 dns_db_attach(db, &xfr->db);
1236 }
1237
1238 dns_diff_init(xfr->mctx, &xfr->diff);
1239
1240 if (reqtype == dns_rdatatype_soa) {
1241 atomic_init(&xfr->state, XFRST_SOAQUERY);
1242 } else {
1243 atomic_init(&xfr->state, XFRST_ZONEXFRREQUEST);
1244 }
1245
1246 atomic_init(&xfr->start, isc_time_now());
1247
1248 if (tsigkey != NULL) {
1249 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
1250 }
1251
1252 if (transport != NULL) {
1253 dns_transport_attach(transport, &xfr->transport);
1254 }
1255
1256 dns_name_dup(zonename, mctx, &xfr->name);
1257
1258 INSIST(isc_sockaddr_pf(primaryaddr) == isc_sockaddr_pf(sourceaddr));
1259 isc_sockaddr_setport(&xfr->sourceaddr, 0);
1260
1261 /*
1262 * Reserve 2 bytes for TCP length at the beginning of the buffer.
1263 */
1264 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
1265 sizeof(xfr->qbuffer_data) - 2);
1266
1267 isc_tlsctx_cache_attach(tlsctx_cache, &xfr->tlsctx_cache);
1268
1269 dns_zone_name(xfr->zone, xfr->info, sizeof(xfr->info));
1270
1271 *xfrp = xfr;
1272 }
1273
1274 static isc_result_t
1275 xfrin_start(dns_xfrin_t *xfr) {
1276 isc_result_t result = ISC_R_FAILURE;
1277 isc_interval_t interval;
1278
1279 dns_xfrin_ref(xfr);
1280
1281 /* If this is a retry, we need to cancel the previous dispentry */
1282 xfrin_cancelio(xfr);
1283
1284 dns_dispatchmgr_t *dispmgr = dns_view_getdispatchmgr(xfr->view);
1285 if (dispmgr == NULL) {
1286 CHECK(ISC_R_SHUTTINGDOWN);
1287 } else {
1288 result = dns_dispatch_createtcp(
1289 dispmgr, &xfr->sourceaddr, &xfr->primaryaddr,
1290 xfr->transport, DNS_DISPATCHOPT_UNSHARED, &xfr->disp);
1291 dns_dispatchmgr_detach(&dispmgr);
1292 CHECK(result);
1293 }
1294
1295 LIBDNS_XFRIN_START(xfr, xfr->info);
1296
1297 /*
1298 * If the transfer is started when the 'state' is XFRST_SOAQUERY, it
1299 * means the SOA query will be performed by xfrin. A transfer could also
1300 * be initiated starting from the XFRST_ZONEXFRREQUEST state, which
1301 * means that the SOA query was already performed by other means (e.g.
1302 * by zone.c:soa_query()), or that it's a transfer without a preceding
1303 * SOA request, and 'soa_transport_type' is already correctly
1304 * set by the creator of the xfrin.
1305 */
1306 if (atomic_load(&xfr->state) == XFRST_SOAQUERY) {
1307 /*
1308 * The "SOA before" mode is used, where the SOA request is
1309 * using the same transport as the XFR.
1310 */
1311 atomic_store_relaxed(&xfr->soa_transport_type,
1312 dns_xfrin_gettransporttype(xfr));
1313 }
1314
1315 CHECK(dns_dispatch_add(
1316 xfr->disp, xfr->loop, 0, 0, &xfr->primaryaddr, xfr->transport,
1317 xfr->tlsctx_cache, xfrin_connect_done, xfrin_send_done,
1318 xfrin_recv_done, xfr, &xfr->id, &xfr->dispentry));
1319
1320 /* Set the maximum timer */
1321 if (xfr->max_time_timer == NULL) {
1322 isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_timedout,
1323 xfr, &xfr->max_time_timer);
1324 }
1325 isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
1326 isc_timer_start(xfr->max_time_timer, isc_timertype_once, &interval);
1327
1328 /* Set the idle timer */
1329 if (xfr->max_idle_timer == NULL) {
1330 isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_idledout,
1331 xfr, &xfr->max_idle_timer);
1332 }
1333 isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
1334 isc_timer_start(xfr->max_idle_timer, isc_timertype_once, &interval);
1335
1336 /* Set the minimum transfer rate checking timer */
1337 if (xfr->min_rate_timer == NULL) {
1338 isc_timer_create(dns_zone_getloop(xfr->zone),
1339 xfrin_minratecheck, xfr, &xfr->min_rate_timer);
1340 }
1341 isc_interval_set(&interval, dns_zone_getminxfrratesecondsin(xfr->zone),
1342 0);
1343 isc_timer_start(xfr->min_rate_timer, isc_timertype_ticker, &interval);
1344
1345 /*
1346 * The connect has to be the last thing that is called before returning,
1347 * as it can end synchronously and destroy the xfr object.
1348 */
1349 CHECK(dns_dispatch_connect(xfr->dispentry));
1350
1351 return ISC_R_SUCCESS;
1352
1353 cleanup:
1354 xfrin_cancelio(xfr);
1355 dns_xfrin_detach(&xfr);
1356
1357 return result;
1358 }
1359
1360 /* XXX the resolver could use this, too */
1361
1362 static isc_result_t
1363 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
1364 dns_compress_t cctx;
1365 isc_result_t result;
1366
1367 dns_compress_init(&cctx, mctx, 0);
1368 CHECK(dns_message_renderbegin(msg, &cctx, buf));
1369 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
1370 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
1371 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
1372 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
1373 CHECK(dns_message_renderend(msg));
1374 result = ISC_R_SUCCESS;
1375 cleanup:
1376 dns_compress_invalidate(&cctx);
1377 return result;
1378 }
1379
1380 /*
1381 * A connection has been established.
1382 */
1383 static void
1384 xfrin_connect_done(isc_result_t result, isc_region_t *region ISC_ATTR_UNUSED,
1385 void *arg) {
1386 dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
1387 char addrtext[ISC_SOCKADDR_FORMATSIZE];
1388 char signerbuf[DNS_NAME_FORMATSIZE];
1389 const char *signer = "", *sep = "";
1390 dns_zonemgr_t *zmgr = NULL;
1391
1392 REQUIRE(VALID_XFRIN(xfr));
1393
1394 if (atomic_load(&xfr->shuttingdown)) {
1395 result = ISC_R_SHUTTINGDOWN;
1396 }
1397
1398 LIBDNS_XFRIN_CONNECTED(xfr, xfr->info, result);
1399
1400 if (result != ISC_R_SUCCESS) {
1401 xfrin_fail(xfr, result, "failed to connect");
1402 goto cleanup;
1403 }
1404
1405 result = dns_dispatch_checkperm(xfr->disp);
1406 if (result != ISC_R_SUCCESS) {
1407 xfrin_fail(xfr, result, "connected but unable to transfer");
1408 goto cleanup;
1409 }
1410
1411 zmgr = dns_zone_getmgr(xfr->zone);
1412 if (zmgr != NULL) {
1413 dns_zonemgr_unreachabledel(zmgr, &xfr->primaryaddr,
1414 &xfr->sourceaddr);
1415 }
1416
1417 if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
1418 dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
1419 sizeof(signerbuf));
1420 sep = " TSIG ";
1421 signer = signerbuf;
1422 }
1423
1424 isc_sockaddr_format(&xfr->primaryaddr, addrtext, sizeof(addrtext));
1425 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", addrtext, sep,
1426 signer);
1427
1428 result = xfrin_send_request(xfr);
1429 if (result != ISC_R_SUCCESS) {
1430 xfrin_fail(xfr, result, "connected but unable to send");
1431 goto detach;
1432 }
1433
1434 return;
1435
1436 cleanup:
1437 switch (result) {
1438 case ISC_R_NETDOWN:
1439 case ISC_R_HOSTDOWN:
1440 case ISC_R_NETUNREACH:
1441 case ISC_R_HOSTUNREACH:
1442 case ISC_R_CONNREFUSED:
1443 case ISC_R_TIMEDOUT:
1444 /*
1445 * Add the server to unreachable primaries table if
1446 * the server has a permanent networking error or
1447 * the connection attempt as timed out.
1448 */
1449 zmgr = dns_zone_getmgr(xfr->zone);
1450 if (zmgr != NULL) {
1451 isc_time_t now = isc_time_now();
1452
1453 dns_zonemgr_unreachableadd(zmgr, &xfr->primaryaddr,
1454 &xfr->sourceaddr, &now);
1455 }
1456 break;
1457 default:
1458 /* Retry sooner than in 10 minutes */
1459 break;
1460 }
1461
1462 detach:
1463 dns_xfrin_detach(&xfr);
1464 }
1465
1466 /*
1467 * Convert a tuple into a dns_name_t suitable for inserting
1468 * into the given dns_message_t.
1469 */
1470 static void
1471 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
1472 dns_rdata_t *rdata = NULL;
1473 dns_rdatalist_t *rdl = NULL;
1474 dns_rdataset_t *rds = NULL;
1475 dns_name_t *name = NULL;
1476
1477 REQUIRE(target != NULL && *target == NULL);
1478
1479 dns_message_gettemprdata(msg, &rdata);
1480 dns_rdata_init(rdata);
1481 dns_rdata_clone(&tuple->rdata, rdata);
1482
1483 dns_message_gettemprdatalist(msg, &rdl);
1484 dns_rdatalist_init(rdl);
1485 rdl->type = tuple->rdata.type;
1486 rdl->rdclass = tuple->rdata.rdclass;
1487 rdl->ttl = tuple->ttl;
1488 ISC_LIST_APPEND(rdl->rdata, rdata, link);
1489
1490 dns_message_gettemprdataset(msg, &rds);
1491 dns_rdatalist_tordataset(rdl, rds);
1492
1493 dns_message_gettempname(msg, &name);
1494 dns_name_clone(&tuple->name, name);
1495 ISC_LIST_APPEND(name->list, rds, link);
1496
1497 *target = name;
1498 }
1499
1500 static const char *
1501 request_type(dns_xfrin_t *xfr) {
1502 switch (xfr->reqtype) {
1503 case dns_rdatatype_soa:
1504 return "SOA";
1505 case dns_rdatatype_axfr:
1506 return "AXFR";
1507 case dns_rdatatype_ixfr:
1508 return "IXFR";
1509 default:
1510 ISC_UNREACHABLE();
1511 }
1512 }
1513
1514 static isc_result_t
1515 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
1516 bool reqexpire) {
1517 isc_result_t result;
1518 dns_rdataset_t *rdataset = NULL;
1519 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
1520 int count = 0;
1521
1522 /* Set EDNS options if applicable. */
1523 if (reqnsid) {
1524 INSIST(count < DNS_EDNSOPTIONS);
1525 ednsopts[count].code = DNS_OPT_NSID;
1526 ednsopts[count].length = 0;
1527 ednsopts[count].value = NULL;
1528 count++;
1529 }
1530 if (reqexpire) {
1531 INSIST(count < DNS_EDNSOPTIONS);
1532 ednsopts[count].code = DNS_OPT_EXPIRE;
1533 ednsopts[count].length = 0;
1534 ednsopts[count].value = NULL;
1535 count++;
1536 }
1537 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
1538 ednsopts, count);
1539 if (result != ISC_R_SUCCESS) {
1540 return result;
1541 }
1542
1543 return dns_message_setopt(message, rdataset);
1544 }
1545
1546 /*
1547 * Build an *XFR request and send its length prefix.
1548 */
1549 static isc_result_t
1550 xfrin_send_request(dns_xfrin_t *xfr) {
1551 isc_result_t result;
1552 isc_region_t region;
1553 dns_rdataset_t *qrdataset = NULL;
1554 dns_message_t *msg = NULL;
1555 dns_difftuple_t *soatuple = NULL;
1556 dns_name_t *qname = NULL;
1557 dns_dbversion_t *ver = NULL;
1558 dns_name_t *msgsoaname = NULL;
1559 bool edns = xfr->edns;
1560 bool reqnsid = xfr->view->requestnsid;
1561 bool reqexpire = dns_zone_getrequestexpire(xfr->zone);
1562 uint16_t udpsize = dns_view_getudpsize(xfr->view);
1563
1564 LIBDNS_XFRIN_RECV_SEND_REQUEST(xfr, xfr->info);
1565
1566 /* Create the request message */
1567 dns_message_create(xfr->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER,
1568 &msg);
1569 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1570
1571 /* Create a name for the question section. */
1572 dns_message_gettempname(msg, &qname);
1573 dns_name_clone(&xfr->name, qname);
1574
1575 /* Formulate the question and attach it to the question name. */
1576 dns_message_gettemprdataset(msg, &qrdataset);
1577 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1578 ISC_LIST_APPEND(qname->list, qrdataset, link);
1579 qrdataset = NULL;
1580
1581 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1582 qname = NULL;
1583
1584 if (xfr->reqtype == dns_rdatatype_ixfr) {
1585 /* Get the SOA and add it to the authority section. */
1586 dns_db_currentversion(xfr->db, &ver);
1587 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1588 DNS_DIFFOP_EXISTS, &soatuple));
1589 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1590 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1591 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1592 "requesting IXFR for serial %u",
1593 xfr->ixfr.request_serial);
1594
1595 tuple2msgname(soatuple, msg, &msgsoaname);
1596 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1597 } else if (xfr->reqtype == dns_rdatatype_soa) {
1598 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1599 &xfr->ixfr.request_serial));
1600 }
1601
1602 if (edns && xfr->view->peers != NULL) {
1603 dns_peer_t *peer = NULL;
1604 isc_netaddr_t primaryip;
1605 isc_netaddr_fromsockaddr(&primaryip, &xfr->primaryaddr);
1606 result = dns_peerlist_peerbyaddr(xfr->view->peers, &primaryip,
1607 &peer);
1608 if (result == ISC_R_SUCCESS) {
1609 (void)dns_peer_getsupportedns(peer, &edns);
1610 (void)dns_peer_getudpsize(peer, &udpsize);
1611 (void)dns_peer_getrequestnsid(peer, &reqnsid);
1612 (void)dns_peer_getrequestexpire(peer, &reqexpire);
1613 }
1614 }
1615
1616 if (edns) {
1617 CHECK(add_opt(msg, udpsize, reqnsid, reqexpire));
1618 }
1619
1620 atomic_store_relaxed(&xfr->nmsg, 0);
1621 atomic_store_relaxed(&xfr->nrecs, 0);
1622 atomic_store_relaxed(&xfr->nbytes, 0);
1623 atomic_store_relaxed(&xfr->start, isc_time_now());
1624
1625 xfr->nbytes_saved = 0;
1626
1627 msg->id = xfr->id;
1628 if (xfr->tsigctx != NULL) {
1629 dst_context_destroy(&xfr->tsigctx);
1630 }
1631
1632 CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1633
1634 /*
1635 * Free the last tsig, if there is one.
1636 */
1637 if (xfr->lasttsig != NULL) {
1638 isc_buffer_free(&xfr->lasttsig);
1639 }
1640
1641 /*
1642 * Save the query TSIG and don't let message_destroy free it.
1643 */
1644 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1645
1646 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1647 INSIST(region.length <= 65535);
1648
1649 dns_xfrin_ref(xfr);
1650 dns_dispatch_send(xfr->dispentry, ®ion);
1651 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sending %s request, QID %d",
1652 request_type(xfr), xfr->id);
1653
1654 cleanup:
1655 dns_message_detach(&msg);
1656 if (soatuple != NULL) {
1657 dns_difftuple_free(&soatuple);
1658 }
1659 if (ver != NULL) {
1660 dns_db_closeversion(xfr->db, &ver, false);
1661 }
1662
1663 return result;
1664 }
1665
1666 static void
1667 xfrin_send_done(isc_result_t result, isc_region_t *region, void *arg) {
1668 dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
1669
1670 UNUSED(region);
1671
1672 REQUIRE(VALID_XFRIN(xfr));
1673
1674 if (atomic_load(&xfr->shuttingdown)) {
1675 result = ISC_R_SHUTTINGDOWN;
1676 }
1677
1678 LIBDNS_XFRIN_SENT(xfr, xfr->info, result);
1679
1680 CHECK(result);
1681
1682 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1683
1684 cleanup:
1685 if (result != ISC_R_SUCCESS) {
1686 xfrin_fail(xfr, result, "failed sending request data");
1687 }
1688
1689 dns_xfrin_detach(&xfr);
1690 }
1691
1692 static void
1693 get_edns_expire(dns_xfrin_t *xfr, dns_message_t *msg) {
1694 isc_result_t result;
1695 dns_rdata_t rdata = DNS_RDATA_INIT;
1696 isc_buffer_t optbuf;
1697 uint16_t optcode;
1698 uint16_t optlen;
1699
1700 result = dns_rdataset_first(msg->opt);
1701 if (result == ISC_R_SUCCESS) {
1702 dns_rdataset_current(msg->opt, &rdata);
1703 isc_buffer_init(&optbuf, rdata.data, rdata.length);
1704 isc_buffer_add(&optbuf, rdata.length);
1705 while (isc_buffer_remaininglength(&optbuf) >= 4) {
1706 optcode = isc_buffer_getuint16(&optbuf);
1707 optlen = isc_buffer_getuint16(&optbuf);
1708 /*
1709 * A EDNS EXPIRE response has a length of 4.
1710 */
1711 if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
1712 isc_buffer_forward(&optbuf, optlen);
1713 continue;
1714 }
1715 xfr->expireopt = isc_buffer_getuint32(&optbuf);
1716 xfr->expireoptset = true;
1717 dns_zone_log(xfr->zone, ISC_LOG_DEBUG(1),
1718 "got EDNS EXPIRE of %u", xfr->expireopt);
1719 break;
1720 }
1721 }
1722 }
1723
1724 static void
1725 xfrin_end(dns_xfrin_t *xfr, isc_result_t result) {
1726 /* Inform the caller. */
1727 if (xfr->done != NULL) {
1728 LIBDNS_XFRIN_DONE_CALLBACK_BEGIN(xfr, xfr->info, result);
1729 (xfr->done)(xfr->zone,
1730 xfr->expireoptset ? &xfr->expireopt : NULL, result);
1731 xfr->done = NULL;
1732 LIBDNS_XFRIN_DONE_CALLBACK_END(xfr, xfr->info, result);
1733 }
1734
1735 atomic_store(&xfr->shuttingdown, true);
1736
1737 if (xfr->max_time_timer != NULL) {
1738 isc_timer_stop(xfr->max_time_timer);
1739 isc_timer_destroy(&xfr->max_time_timer);
1740 }
1741 if (xfr->max_idle_timer != NULL) {
1742 isc_timer_stop(xfr->max_idle_timer);
1743 isc_timer_destroy(&xfr->max_idle_timer);
1744 }
1745 if (xfr->min_rate_timer != NULL) {
1746 isc_timer_stop(xfr->min_rate_timer);
1747 isc_timer_destroy(&xfr->min_rate_timer);
1748 }
1749
1750 if (xfr->shutdown_result == ISC_R_UNSET) {
1751 xfr->shutdown_result = result;
1752 }
1753 }
1754
1755 static void
1756 xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) {
1757 dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
1758 dns_message_t *msg = NULL;
1759 dns_name_t *name = NULL;
1760 const dns_name_t *tsigowner = NULL;
1761 isc_buffer_t buffer;
1762
1763 REQUIRE(VALID_XFRIN(xfr));
1764
1765 if (atomic_load(&xfr->shuttingdown)) {
1766 result = ISC_R_SHUTTINGDOWN;
1767 }
1768
1769 /* Stop the idle timer */
1770 isc_timer_stop(xfr->max_idle_timer);
1771
1772 LIBDNS_XFRIN_RECV_START(xfr, xfr->info, result);
1773
1774 CHECK(result);
1775
1776 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", region->length);
1777
1778 dns_message_create(xfr->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE,
1779 &msg);
1780
1781 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1782 dns_message_setquerytsig(msg, xfr->lasttsig);
1783
1784 msg->tsigctx = xfr->tsigctx;
1785 xfr->tsigctx = NULL;
1786
1787 dns_message_setclass(msg, xfr->rdclass);
1788
1789 msg->tcp_continuation = (atomic_load_relaxed(&xfr->nmsg) > 0) ? 1 : 0;
1790
1791 isc_buffer_init(&buffer, region->base, region->length);
1792 isc_buffer_add(&buffer, region->length);
1793
1794 result = dns_message_parse(msg, &buffer,
1795 DNS_MESSAGEPARSE_PRESERVEORDER);
1796 if (result == ISC_R_SUCCESS) {
1797 dns_message_logpacket(
1798 msg, "received message from", &xfr->primaryaddr,
1799 DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
1800 ISC_LOG_DEBUG(10), xfr->mctx);
1801 } else {
1802 xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
1803 isc_result_totext(result));
1804 }
1805
1806 LIBDNS_XFRIN_RECV_PARSED(xfr, xfr->info, result);
1807
1808 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1809 msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass)
1810 {
1811 if (result == ISC_R_SUCCESS &&
1812 msg->rcode == dns_rcode_formerr && xfr->edns &&
1813 (atomic_load(&xfr->state) == XFRST_SOAQUERY ||
1814 atomic_load(&xfr->state) == XFRST_ZONEXFRREQUEST))
1815 {
1816 xfr->edns = false;
1817 dns_message_detach(&msg);
1818 xfrin_reset(xfr);
1819 goto try_again;
1820 } else if (result == ISC_R_SUCCESS &&
1821 msg->rcode != dns_rcode_noerror)
1822 {
1823 result = dns_result_fromrcode(msg->rcode);
1824 } else if (result == ISC_R_SUCCESS &&
1825 msg->opcode != dns_opcode_query)
1826 {
1827 result = DNS_R_UNEXPECTEDOPCODE;
1828 } else if (result == ISC_R_SUCCESS &&
1829 msg->rdclass != xfr->rdclass)
1830 {
1831 result = DNS_R_BADCLASS;
1832 } else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) {
1833 result = DNS_R_UNEXPECTEDID;
1834 }
1835
1836 if (xfr->reqtype == dns_rdatatype_axfr ||
1837 xfr->reqtype == dns_rdatatype_soa)
1838 {
1839 goto cleanup;
1840 }
1841
1842 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1843 isc_result_totext(result));
1844 try_axfr:
1845 LIBDNS_XFRIN_RECV_TRY_AXFR(xfr, xfr->info, result);
1846 dns_message_detach(&msg);
1847 xfrin_reset(xfr);
1848 xfr->reqtype = dns_rdatatype_soa;
1849 atomic_store(&xfr->state, XFRST_SOAQUERY);
1850 try_again:
1851 result = xfrin_start(xfr);
1852 if (result != ISC_R_SUCCESS) {
1853 xfrin_fail(xfr, result, "failed setting up socket");
1854 }
1855 dns_xfrin_detach(&xfr);
1856 return;
1857 }
1858
1859 /*
1860 * The question section should exist for SOA and in the first
1861 * message of a AXFR or IXFR response. The question section
1862 * may exist in the 2nd and subsequent messages in a AXFR or
1863 * IXFR response. If the question section exists it should
1864 * match the question that was sent.
1865 */
1866 if (msg->counts[DNS_SECTION_QUESTION] > 1) {
1867 xfrin_log(xfr, ISC_LOG_NOTICE, "too many questions (%u)",
1868 msg->counts[DNS_SECTION_QUESTION]);
1869 CHECK(DNS_R_FORMERR);
1870 }
1871
1872 if ((atomic_load(&xfr->state) == XFRST_SOAQUERY ||
1873 atomic_load(&xfr->state) == XFRST_ZONEXFRREQUEST) &&
1874 msg->counts[DNS_SECTION_QUESTION] != 1)
1875 {
1876 xfrin_log(xfr, ISC_LOG_NOTICE, "missing question section");
1877 CHECK(DNS_R_FORMERR);
1878 }
1879
1880 for (result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
1881 result == ISC_R_SUCCESS;
1882 result = dns_message_nextname(msg, DNS_SECTION_QUESTION))
1883 {
1884 dns_rdataset_t *rds = NULL;
1885
1886 LIBDNS_XFRIN_RECV_QUESTION(xfr, xfr->info, msg);
1887
1888 name = NULL;
1889 dns_message_currentname(msg, DNS_SECTION_QUESTION, &name);
1890 if (!dns_name_equal(name, &xfr->name)) {
1891 xfrin_log(xfr, ISC_LOG_NOTICE,
1892 "question name mismatch");
1893 CHECK(DNS_R_FORMERR);
1894 }
1895 rds = ISC_LIST_HEAD(name->list);
1896 INSIST(rds != NULL);
1897 if (rds->type != xfr->reqtype) {
1898 xfrin_log(xfr, ISC_LOG_NOTICE,
1899 "question type mismatch");
1900 CHECK(DNS_R_FORMERR);
1901 }
1902 if (rds->rdclass != xfr->rdclass) {
1903 xfrin_log(xfr, ISC_LOG_NOTICE,
1904 "question class mismatch");
1905 CHECK(DNS_R_FORMERR);
1906 }
1907 }
1908 if (result != ISC_R_NOMORE) {
1909 goto cleanup;
1910 }
1911
1912 /*
1913 * Does the server know about IXFR? If it doesn't we will get
1914 * a message with a empty answer section or a potentially a CNAME /
1915 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1916 * if the first RR in the answer section is not a SOA record.
1917 */
1918 if (xfr->reqtype == dns_rdatatype_ixfr &&
1919 atomic_load(&xfr->state) == XFRST_ZONEXFRREQUEST &&
1920 msg->counts[DNS_SECTION_ANSWER] == 0)
1921 {
1922 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1923 "empty answer section, retrying with AXFR");
1924 goto try_axfr;
1925 }
1926
1927 if (xfr->reqtype == dns_rdatatype_soa &&
1928 (msg->flags & DNS_MESSAGEFLAG_AA) == 0)
1929 {
1930 CHECK(DNS_R_NOTAUTHORITATIVE);
1931 }
1932
1933 result = dns_message_checksig(msg, xfr->view);
1934 if (result != ISC_R_SUCCESS) {
1935 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1936 isc_result_totext(result));
1937 goto cleanup;
1938 }
1939
1940 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1941 result == ISC_R_SUCCESS;
1942 result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1943 {
1944 dns_rdataset_t *rds = NULL;
1945
1946 LIBDNS_XFRIN_RECV_ANSWER(xfr, xfr->info, msg);
1947
1948 name = NULL;
1949 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1950 for (rds = ISC_LIST_HEAD(name->list); rds != NULL;
1951 rds = ISC_LIST_NEXT(rds, link))
1952 {
1953 for (result = dns_rdataset_first(rds);
1954 result == ISC_R_SUCCESS;
1955 result = dns_rdataset_next(rds))
1956 {
1957 dns_rdata_t rdata = DNS_RDATA_INIT;
1958 dns_rdataset_current(rds, &rdata);
1959 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1960 }
1961 }
1962 }
1963 if (result == ISC_R_NOMORE) {
1964 result = ISC_R_SUCCESS;
1965 }
1966 CHECK(result);
1967
1968 if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1969 /*
1970 * Reset the counter.
1971 */
1972 xfr->sincetsig = 0;
1973
1974 /*
1975 * Free the last tsig, if there is one.
1976 */
1977 if (xfr->lasttsig != NULL) {
1978 isc_buffer_free(&xfr->lasttsig);
1979 }
1980
1981 /*
1982 * Update the last tsig pointer.
1983 */
1984 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1985 } else if (dns_message_gettsigkey(msg) != NULL) {
1986 xfr->sincetsig++;
1987 if (xfr->sincetsig > 100 ||
1988 atomic_load_relaxed(&xfr->nmsg) == 0 ||
1989 atomic_load(&xfr->state) == XFRST_AXFR_END ||
1990 atomic_load(&xfr->state) == XFRST_IXFR_END)
1991 {
1992 CHECK(DNS_R_EXPECTEDTSIG);
1993 }
1994 }
1995
1996 /*
1997 * Update the number of messages and bytes received.
1998 */
1999 atomic_fetch_add_relaxed(&xfr->nmsg, 1);
2000 atomic_fetch_add_relaxed(&xfr->nbytes, buffer.used);
2001
2002 /*
2003 * Take the context back.
2004 */
2005 INSIST(xfr->tsigctx == NULL);
2006 xfr->tsigctx = msg->tsigctx;
2007 msg->tsigctx = NULL;
2008
2009 if (!xfr->expireoptset && msg->opt != NULL) {
2010 get_edns_expire(xfr, msg);
2011 }
2012
2013 switch (atomic_load(&xfr->state)) {
2014 case XFRST_GOTSOA:
2015 xfr->reqtype = dns_rdatatype_axfr;
2016 atomic_store(&xfr->state, XFRST_ZONEXFRREQUEST);
2017 CHECK(xfrin_start(xfr));
2018 break;
2019 case XFRST_AXFR_END:
2020 case XFRST_IXFR_END:
2021 /* We are at the end, cancel the timers and IO */
2022 isc_timer_stop(xfr->min_rate_timer);
2023 isc_timer_stop(xfr->max_idle_timer);
2024 isc_timer_stop(xfr->max_time_timer);
2025 xfrin_cancelio(xfr);
2026 break;
2027 default:
2028 /*
2029 * Read the next message.
2030 */
2031 dns_message_detach(&msg);
2032 CHECK(dns_dispatch_getnext(xfr->dispentry));
2033
2034 isc_interval_t interval;
2035 isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
2036 isc_timer_start(xfr->max_idle_timer, isc_timertype_once,
2037 &interval);
2038
2039 LIBDNS_XFRIN_READ(xfr, xfr->info, result);
2040 return;
2041 }
2042
2043 cleanup:
2044 if (result != ISC_R_SUCCESS) {
2045 xfrin_fail(xfr, result, "failed while receiving responses");
2046 }
2047
2048 if (msg != NULL) {
2049 dns_message_detach(&msg);
2050 }
2051 dns_xfrin_detach(&xfr);
2052 LIBDNS_XFRIN_RECV_DONE(xfr, xfr->info, result);
2053 }
2054
2055 static void
2056 xfrin_destroy(dns_xfrin_t *xfr) {
2057 uint64_t msecs, persec;
2058 isc_time_t now = isc_time_now();
2059 char expireopt[sizeof("4000000000")] = { 0 };
2060 const char *sep = "";
2061
2062 REQUIRE(VALID_XFRIN(xfr));
2063
2064 /* Safe-guards */
2065 REQUIRE(atomic_load(&xfr->shuttingdown));
2066
2067 INSIST(xfr->shutdown_result != ISC_R_UNSET);
2068
2069 /*
2070 * If we're called through dns_xfrin_detach() and are not
2071 * shutting down, we can't know what the transfer status is as
2072 * we are only called when the last reference is lost.
2073 */
2074 xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s",
2075 isc_result_totext(xfr->shutdown_result));
2076
2077 /*
2078 * Calculate the length of time the transfer took,
2079 * and print a log message with the bytes and rate.
2080 */
2081 isc_time_t start = atomic_load_relaxed(&xfr->start);
2082 msecs = isc_time_microdiff(&now, &start) / 1000;
2083 if (msecs == 0) {
2084 msecs = 1;
2085 }
2086 persec = (atomic_load_relaxed(&xfr->nbytes) * 1000) / msecs;
2087
2088 if (xfr->expireoptset) {
2089 sep = ", expire option ";
2090 snprintf(expireopt, sizeof(expireopt), "%u", xfr->expireopt);
2091 }
2092
2093 xfrin_log(xfr, ISC_LOG_INFO,
2094 "Transfer completed: %d messages, %d records, "
2095 "%" PRIu64 " bytes, "
2096 "%u.%03u secs (%u bytes/sec) (serial %" PRIuFAST32 "%s%s)",
2097 atomic_load_relaxed(&xfr->nmsg),
2098 atomic_load_relaxed(&xfr->nrecs),
2099 atomic_load_relaxed(&xfr->nbytes),
2100 (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
2101 (unsigned int)persec, atomic_load_relaxed(&xfr->end_serial),
2102 sep, expireopt);
2103
2104 /* Cleanup unprocessed IXFR data */
2105 struct cds_wfcq_node *node, *next;
2106 __cds_wfcq_for_each_blocking_safe(&xfr->diff_head, &xfr->diff_tail,
2107 node, next) {
2108 ixfr_apply_data_t *data =
2109 caa_container_of(node, ixfr_apply_data_t, wfcq_node);
2110 /* We need to clear and free all data chunks */
2111 dns_diff_clear(&data->diff);
2112 isc_mem_put(xfr->mctx, data, sizeof(*data));
2113 }
2114
2115 /* Cleanup unprocessed AXFR data */
2116 dns_diff_clear(&xfr->diff);
2117
2118 xfrin_cancelio(xfr);
2119
2120 if (xfr->transport != NULL) {
2121 dns_transport_detach(&xfr->transport);
2122 }
2123
2124 if (xfr->tsigkey != NULL) {
2125 dns_tsigkey_detach(&xfr->tsigkey);
2126 }
2127
2128 if (xfr->lasttsig != NULL) {
2129 isc_buffer_free(&xfr->lasttsig);
2130 }
2131
2132 if (xfr->ixfr.journal != NULL) {
2133 dns_journal_destroy(&xfr->ixfr.journal);
2134 }
2135
2136 if (xfr->axfr.add_private != NULL) {
2137 (void)dns_db_endload(xfr->db, &xfr->axfr);
2138 }
2139
2140 if (xfr->tsigctx != NULL) {
2141 dst_context_destroy(&xfr->tsigctx);
2142 }
2143
2144 if (xfr->name.attributes.dynamic) {
2145 dns_name_free(&xfr->name, xfr->mctx);
2146 }
2147
2148 if (xfr->ver != NULL) {
2149 dns_db_closeversion(xfr->db, &xfr->ver, false);
2150 }
2151
2152 if (xfr->db != NULL) {
2153 dns_db_detach(&xfr->db);
2154 }
2155
2156 if (xfr->zone != NULL) {
2157 if (!xfr->zone_had_db &&
2158 xfr->shutdown_result == ISC_R_SUCCESS &&
2159 dns_zone_gettype(xfr->zone) == dns_zone_mirror)
2160 {
2161 dns_zone_log(xfr->zone, ISC_LOG_INFO,
2162 "mirror zone is now in use");
2163 }
2164 xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context");
2165 /*
2166 * xfr->zone must not be detached before xfrin_log() is called.
2167 */
2168 dns_zone_idetach(&xfr->zone);
2169 }
2170
2171 if (xfr->view != NULL) {
2172 dns_view_weakdetach(&xfr->view);
2173 }
2174
2175 if (xfr->firstsoa_data != NULL) {
2176 isc_mem_free(xfr->mctx, xfr->firstsoa_data);
2177 }
2178
2179 if (xfr->tlsctx_cache != NULL) {
2180 isc_tlsctx_cache_detach(&xfr->tlsctx_cache);
2181 }
2182
2183 INSIST(xfr->max_time_timer == NULL);
2184 INSIST(xfr->max_idle_timer == NULL);
2185 INSIST(xfr->min_rate_timer == NULL);
2186
2187 isc_loop_detach(&xfr->loop);
2188
2189 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
2190 }
2191
2192 /*
2193 * Log incoming zone transfer messages in a format like
2194 * transfer of <zone> from <address>: <message>
2195 */
2196
2197 static void
2198 xfrin_log(dns_xfrin_t *xfr, int level, const char *fmt, ...) {
2199 va_list ap;
2200 char primarytext[ISC_SOCKADDR_FORMATSIZE];
2201 char msgtext[2048];
2202
2203 if (!isc_log_wouldlog(dns_lctx, level)) {
2204 return;
2205 }
2206
2207 isc_sockaddr_format(&xfr->primaryaddr, primarytext,
2208 sizeof(primarytext));
2209 va_start(ap, fmt);
2210 vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
2211 va_end(ap);
2212
2213 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
2214 level, "%p: transfer of '%s' from %s: %s", xfr, xfr->info,
2215 primarytext, msgtext);
2216 }
2217