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