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