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