1 /* $NetBSD: xfrin.c,v 1.4 2019/02/24 20:01:30 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14 15 /*! \file */ 16 17 #include <config.h> 18 19 #include <inttypes.h> 20 #include <stdbool.h> 21 22 #include <isc/mem.h> 23 #include <isc/print.h> 24 #include <isc/random.h> 25 #include <isc/string.h> /* Required for HP/UX (and others?) */ 26 #include <isc/task.h> 27 #include <isc/timer.h> 28 #include <isc/util.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/events.h> 35 #include <dns/journal.h> 36 #include <dns/log.h> 37 #include <dns/message.h> 38 #include <dns/rdataclass.h> 39 #include <dns/rdatalist.h> 40 #include <dns/rdataset.h> 41 #include <dns/result.h> 42 #include <dns/soa.h> 43 #include <dns/tcpmsg.h> 44 #include <dns/timer.h> 45 #include <dns/tsig.h> 46 #include <dns/view.h> 47 #include <dns/xfrin.h> 48 #include <dns/zone.h> 49 50 #include <dst/dst.h> 51 52 /* 53 * Incoming AXFR and IXFR. 54 */ 55 56 /*% 57 * It would be non-sensical (or at least obtuse) to use FAIL() with an 58 * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler 59 * from complaining about "end-of-loop code not reached". 60 */ 61 #define FAIL(code) \ 62 do { result = (code); \ 63 if (result != ISC_R_SUCCESS) goto failure; \ 64 } while (/*CONSTCOND*/0) 65 66 #define CHECK(op) \ 67 do { result = (op); \ 68 if (result != ISC_R_SUCCESS) goto failure; \ 69 } while (/*CONSTCOND*/0) 70 71 /*% 72 * The states of the *XFR state machine. We handle both IXFR and AXFR 73 * with a single integrated state machine because they cannot be distinguished 74 * immediately - an AXFR response to an IXFR request can only be detected 75 * when the first two (2) response RRs have already been received. 76 */ 77 typedef enum { 78 XFRST_SOAQUERY, 79 XFRST_GOTSOA, 80 XFRST_INITIALSOA, 81 XFRST_FIRSTDATA, 82 XFRST_IXFR_DELSOA, 83 XFRST_IXFR_DEL, 84 XFRST_IXFR_ADDSOA, 85 XFRST_IXFR_ADD, 86 XFRST_IXFR_END, 87 XFRST_AXFR, 88 XFRST_AXFR_END 89 } xfrin_state_t; 90 91 /*% 92 * Incoming zone transfer context. 93 */ 94 95 struct dns_xfrin_ctx { 96 unsigned int magic; 97 isc_mem_t *mctx; 98 dns_zone_t *zone; 99 100 int refcount; 101 102 isc_task_t *task; 103 isc_timer_t *timer; 104 isc_socketmgr_t *socketmgr; 105 106 int connects; /*%< Connect in progress */ 107 int sends; /*%< Send in progress */ 108 int recvs; /*%< Receive in progress */ 109 bool shuttingdown; 110 isc_result_t shutdown_result; 111 112 dns_name_t name; /*%< Name of zone to transfer */ 113 dns_rdataclass_t rdclass; 114 115 bool checkid; 116 dns_messageid_t id; 117 118 /*% 119 * Requested transfer type (dns_rdatatype_axfr or 120 * dns_rdatatype_ixfr). The actual transfer type 121 * may differ due to IXFR->AXFR fallback. 122 */ 123 dns_rdatatype_t reqtype; 124 isc_dscp_t dscp; 125 126 isc_sockaddr_t masteraddr; 127 isc_sockaddr_t sourceaddr; 128 isc_socket_t *socket; 129 130 /*% Buffer for IXFR/AXFR request message */ 131 isc_buffer_t qbuffer; 132 unsigned char qbuffer_data[512]; 133 134 /*% Incoming reply TCP message */ 135 dns_tcpmsg_t tcpmsg; 136 bool tcpmsg_valid; 137 138 /*% 139 * Whether the zone originally had a database attached at the time this 140 * transfer context was created. Used by maybe_free() when making 141 * logging decisions. 142 */ 143 bool zone_had_db; 144 145 dns_db_t *db; 146 dns_dbversion_t *ver; 147 dns_diff_t diff; /*%< Pending database changes */ 148 int difflen; /*%< Number of pending tuples */ 149 150 xfrin_state_t state; 151 uint32_t end_serial; 152 bool is_ixfr; 153 154 unsigned int nmsg; /*%< Number of messages recvd */ 155 unsigned int nrecs; /*%< Number of records recvd */ 156 uint64_t nbytes; /*%< Number of bytes received */ 157 158 unsigned int maxrecords; /*%< The maximum number of 159 records set for the zone */ 160 161 isc_time_t start; /*%< Start time of the transfer */ 162 isc_time_t end; /*%< End time of the transfer */ 163 164 dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */ 165 isc_buffer_t *lasttsig; /*%< The last TSIG */ 166 dst_context_t *tsigctx; /*%< TSIG verification context */ 167 unsigned int sincetsig; /*%< recvd since the last TSIG */ 168 dns_xfrindone_t done; 169 170 /*% 171 * AXFR- and IXFR-specific data. Only one is used at a time 172 * according to the is_ixfr flag, so this could be a union, 173 * but keeping them separate makes it a bit simpler to clean 174 * things up when destroying the context. 175 */ 176 dns_rdatacallbacks_t axfr; 177 178 struct { 179 uint32_t request_serial; 180 uint32_t current_serial; 181 dns_journal_t *journal; 182 183 } ixfr; 184 }; 185 186 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I') 187 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC) 188 189 /**************************************************************************/ 190 /* 191 * Forward declarations. 192 */ 193 194 static isc_result_t 195 xfrin_create(isc_mem_t *mctx, 196 dns_zone_t *zone, 197 dns_db_t *db, 198 isc_task_t *task, 199 isc_timermgr_t *timermgr, 200 isc_socketmgr_t *socketmgr, 201 dns_name_t *zonename, 202 dns_rdataclass_t rdclass, 203 dns_rdatatype_t reqtype, 204 const isc_sockaddr_t *masteraddr, 205 const isc_sockaddr_t *sourceaddr, 206 isc_dscp_t dscp, 207 dns_tsigkey_t *tsigkey, 208 dns_xfrin_ctx_t **xfrp); 209 210 static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr); 211 static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp); 212 static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 213 dns_name_t *name, dns_ttl_t ttl, 214 dns_rdata_t *rdata); 215 static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr); 216 static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr); 217 static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr); 218 219 static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr); 220 static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr); 221 static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 222 dns_name_t *name, dns_ttl_t ttl, 223 dns_rdata_t *rdata); 224 static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr); 225 226 static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, 227 uint32_t ttl, dns_rdata_t *rdata); 228 229 static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr); 230 231 static void xfrin_connect_done(isc_task_t *task, isc_event_t *event); 232 static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr); 233 static void xfrin_send_done(isc_task_t *task, isc_event_t *event); 234 static void xfrin_recv_done(isc_task_t *task, isc_event_t *event); 235 static void xfrin_timeout(isc_task_t *task, isc_event_t *event); 236 237 static void maybe_free(dns_xfrin_ctx_t *xfr); 238 239 static void 240 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg); 241 static isc_result_t 242 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf); 243 244 static void 245 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr, 246 const char *fmt, va_list ap) 247 ISC_FORMAT_PRINTF(4, 0); 248 249 static void 250 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr, 251 const char *fmt, ...) 252 ISC_FORMAT_PRINTF(4, 5); 253 254 static void 255 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) 256 ISC_FORMAT_PRINTF(3, 4); 257 258 /**************************************************************************/ 259 /* 260 * AXFR handling 261 */ 262 263 static isc_result_t 264 axfr_init(dns_xfrin_ctx_t *xfr) { 265 isc_result_t result; 266 267 xfr->is_ixfr = false; 268 269 if (xfr->db != NULL) 270 dns_db_detach(&xfr->db); 271 272 CHECK(axfr_makedb(xfr, &xfr->db)); 273 dns_rdatacallbacks_init(&xfr->axfr); 274 CHECK(dns_db_beginload(xfr->db, &xfr->axfr)); 275 result = ISC_R_SUCCESS; 276 failure: 277 return (result); 278 } 279 280 static isc_result_t 281 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) { 282 isc_result_t result; 283 284 result = dns_db_create(xfr->mctx, /* XXX */ 285 "rbt", /* XXX guess */ 286 &xfr->name, 287 dns_dbtype_zone, 288 xfr->rdclass, 289 0, NULL, /* XXX guess */ 290 dbp); 291 if (result == ISC_R_SUCCESS) { 292 dns_zone_rpz_enable_db(xfr->zone, *dbp); 293 dns_zone_catz_enable_db(xfr->zone, *dbp); 294 } 295 return (result); 296 } 297 298 static isc_result_t 299 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 300 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 301 { 302 isc_result_t result; 303 304 dns_difftuple_t *tuple = NULL; 305 306 if (rdata->rdclass != xfr->rdclass) 307 return(DNS_R_BADCLASS); 308 309 CHECK(dns_zone_checknames(xfr->zone, name, rdata)); 310 CHECK(dns_difftuple_create(xfr->diff.mctx, op, 311 name, ttl, rdata, &tuple)); 312 dns_diff_append(&xfr->diff, &tuple); 313 if (++xfr->difflen > 100) 314 CHECK(axfr_apply(xfr)); 315 result = ISC_R_SUCCESS; 316 failure: 317 return (result); 318 } 319 320 /* 321 * Store a set of AXFR RRs in the database. 322 */ 323 static isc_result_t 324 axfr_apply(dns_xfrin_ctx_t *xfr) { 325 isc_result_t result; 326 uint64_t records; 327 328 CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private)); 329 xfr->difflen = 0; 330 dns_diff_clear(&xfr->diff); 331 if (xfr->maxrecords != 0U) { 332 result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL); 333 if (result == ISC_R_SUCCESS && records > xfr->maxrecords) { 334 result = DNS_R_TOOMANYRECORDS; 335 goto failure; 336 } 337 } 338 result = ISC_R_SUCCESS; 339 failure: 340 return (result); 341 } 342 343 static isc_result_t 344 axfr_commit(dns_xfrin_ctx_t *xfr) { 345 isc_result_t result; 346 347 CHECK(axfr_apply(xfr)); 348 CHECK(dns_db_endload(xfr->db, &xfr->axfr)); 349 CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL)); 350 351 result = ISC_R_SUCCESS; 352 failure: 353 return (result); 354 } 355 356 static isc_result_t 357 axfr_finalize(dns_xfrin_ctx_t *xfr) { 358 isc_result_t result; 359 360 CHECK(dns_zone_replacedb(xfr->zone, xfr->db, true)); 361 362 result = ISC_R_SUCCESS; 363 failure: 364 return (result); 365 } 366 367 /**************************************************************************/ 368 /* 369 * IXFR handling 370 */ 371 372 static isc_result_t 373 ixfr_init(dns_xfrin_ctx_t *xfr) { 374 isc_result_t result; 375 char *journalfile; 376 377 if (xfr->reqtype != dns_rdatatype_ixfr) { 378 xfrin_log(xfr, ISC_LOG_ERROR, 379 "got incremental response to AXFR request"); 380 return (DNS_R_FORMERR); 381 } 382 383 xfr->is_ixfr = true; 384 INSIST(xfr->db != NULL); 385 xfr->difflen = 0; 386 387 journalfile = dns_zone_getjournal(xfr->zone); 388 if (journalfile != NULL) 389 CHECK(dns_journal_open(xfr->mctx, journalfile, 390 DNS_JOURNAL_CREATE, &xfr->ixfr.journal)); 391 392 result = ISC_R_SUCCESS; 393 failure: 394 return (result); 395 } 396 397 static isc_result_t 398 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 399 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 400 { 401 isc_result_t result; 402 dns_difftuple_t *tuple = NULL; 403 404 if (rdata->rdclass != xfr->rdclass) 405 return(DNS_R_BADCLASS); 406 407 if (op == DNS_DIFFOP_ADD) 408 CHECK(dns_zone_checknames(xfr->zone, name, rdata)); 409 CHECK(dns_difftuple_create(xfr->diff.mctx, op, 410 name, ttl, rdata, &tuple)); 411 dns_diff_append(&xfr->diff, &tuple); 412 if (++xfr->difflen > 100) 413 CHECK(ixfr_apply(xfr)); 414 result = ISC_R_SUCCESS; 415 failure: 416 return (result); 417 } 418 419 /* 420 * Apply a set of IXFR changes to the database. 421 */ 422 static isc_result_t 423 ixfr_apply(dns_xfrin_ctx_t *xfr) { 424 isc_result_t result; 425 uint64_t records; 426 427 if (xfr->ver == NULL) { 428 CHECK(dns_db_newversion(xfr->db, &xfr->ver)); 429 if (xfr->ixfr.journal != NULL) 430 CHECK(dns_journal_begin_transaction(xfr->ixfr.journal)); 431 } 432 CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver)); 433 if (xfr->maxrecords != 0U) { 434 result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL); 435 if (result == ISC_R_SUCCESS && records > xfr->maxrecords) { 436 result = DNS_R_TOOMANYRECORDS; 437 goto failure; 438 } 439 } 440 if (xfr->ixfr.journal != NULL) { 441 result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff); 442 if (result != ISC_R_SUCCESS) 443 goto failure; 444 } 445 dns_diff_clear(&xfr->diff); 446 xfr->difflen = 0; 447 result = ISC_R_SUCCESS; 448 failure: 449 return (result); 450 } 451 452 static isc_result_t 453 ixfr_commit(dns_xfrin_ctx_t *xfr) { 454 isc_result_t result; 455 456 CHECK(ixfr_apply(xfr)); 457 if (xfr->ver != NULL) { 458 CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver)); 459 /* XXX enter ready-to-commit state here */ 460 if (xfr->ixfr.journal != NULL) 461 CHECK(dns_journal_commit(xfr->ixfr.journal)); 462 dns_db_closeversion(xfr->db, &xfr->ver, true); 463 dns_zone_markdirty(xfr->zone); 464 } 465 result = ISC_R_SUCCESS; 466 failure: 467 return (result); 468 } 469 470 /**************************************************************************/ 471 /* 472 * Common AXFR/IXFR protocol code 473 */ 474 475 /* 476 * Handle a single incoming resource record according to the current 477 * state. 478 */ 479 static isc_result_t 480 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl, 481 dns_rdata_t *rdata) 482 { 483 isc_result_t result; 484 485 xfr->nrecs++; 486 487 if (rdata->type == dns_rdatatype_none || 488 dns_rdatatype_ismeta(rdata->type)) 489 FAIL(DNS_R_FORMERR); 490 491 redo: 492 switch (xfr->state) { 493 case XFRST_SOAQUERY: 494 if (rdata->type != dns_rdatatype_soa) { 495 xfrin_log(xfr, ISC_LOG_ERROR, 496 "non-SOA response to SOA query"); 497 FAIL(DNS_R_FORMERR); 498 } 499 xfr->end_serial = dns_soa_getserial(rdata); 500 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) && 501 !dns_zone_isforced(xfr->zone)) { 502 xfrin_log(xfr, ISC_LOG_DEBUG(3), 503 "requested serial %u, " 504 "master has %u, not updating", 505 xfr->ixfr.request_serial, xfr->end_serial); 506 FAIL(DNS_R_UPTODATE); 507 } 508 xfr->state = XFRST_GOTSOA; 509 break; 510 511 case XFRST_GOTSOA: 512 /* 513 * Skip other records in the answer section. 514 */ 515 break; 516 517 case XFRST_INITIALSOA: 518 if (rdata->type != dns_rdatatype_soa) { 519 xfrin_log(xfr, ISC_LOG_ERROR, 520 "first RR in zone transfer must be SOA"); 521 FAIL(DNS_R_FORMERR); 522 } 523 /* 524 * Remember the serial number in the initial SOA. 525 * We need it to recognize the end of an IXFR. 526 */ 527 xfr->end_serial = dns_soa_getserial(rdata); 528 if (xfr->reqtype == dns_rdatatype_ixfr && 529 ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) 530 && !dns_zone_isforced(xfr->zone)) 531 { 532 /* 533 * This must be the single SOA record that is 534 * sent when the current version on the master 535 * is not newer than the version in the request. 536 */ 537 xfrin_log(xfr, ISC_LOG_DEBUG(3), 538 "requested serial %u, " 539 "master has %u, not updating", 540 xfr->ixfr.request_serial, xfr->end_serial); 541 FAIL(DNS_R_UPTODATE); 542 } 543 if (xfr->reqtype == dns_rdatatype_axfr) 544 xfr->checkid = false; 545 xfr->state = XFRST_FIRSTDATA; 546 break; 547 548 case XFRST_FIRSTDATA: 549 /* 550 * If the transfer begins with one SOA record, it is an AXFR, 551 * if it begins with two SOAs, it is an IXFR. 552 */ 553 if (xfr->reqtype == dns_rdatatype_ixfr && 554 rdata->type == dns_rdatatype_soa && 555 xfr->ixfr.request_serial == dns_soa_getserial(rdata)) { 556 xfrin_log(xfr, ISC_LOG_DEBUG(3), 557 "got incremental response"); 558 CHECK(ixfr_init(xfr)); 559 xfr->state = XFRST_IXFR_DELSOA; 560 } else { 561 xfrin_log(xfr, ISC_LOG_DEBUG(3), 562 "got nonincremental response"); 563 CHECK(axfr_init(xfr)); 564 xfr->state = XFRST_AXFR; 565 } 566 goto redo; 567 568 case XFRST_IXFR_DELSOA: 569 INSIST(rdata->type == dns_rdatatype_soa); 570 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata)); 571 xfr->state = XFRST_IXFR_DEL; 572 break; 573 574 case XFRST_IXFR_DEL: 575 if (rdata->type == dns_rdatatype_soa) { 576 uint32_t soa_serial = dns_soa_getserial(rdata); 577 xfr->state = XFRST_IXFR_ADDSOA; 578 xfr->ixfr.current_serial = soa_serial; 579 goto redo; 580 } 581 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata)); 582 break; 583 584 case XFRST_IXFR_ADDSOA: 585 INSIST(rdata->type == dns_rdatatype_soa); 586 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); 587 xfr->state = XFRST_IXFR_ADD; 588 break; 589 590 case XFRST_IXFR_ADD: 591 if (rdata->type == dns_rdatatype_soa) { 592 uint32_t soa_serial = dns_soa_getserial(rdata); 593 if (soa_serial == xfr->end_serial) { 594 CHECK(ixfr_commit(xfr)); 595 xfr->state = XFRST_IXFR_END; 596 break; 597 } else if (soa_serial != xfr->ixfr.current_serial) { 598 xfrin_log(xfr, ISC_LOG_ERROR, 599 "IXFR out of sync: " 600 "expected serial %u, got %u", 601 xfr->ixfr.current_serial, soa_serial); 602 FAIL(DNS_R_FORMERR); 603 } else { 604 CHECK(ixfr_commit(xfr)); 605 xfr->state = XFRST_IXFR_DELSOA; 606 goto redo; 607 } 608 } 609 if (rdata->type == dns_rdatatype_ns && 610 dns_name_iswildcard(name)) 611 FAIL(DNS_R_INVALIDNS); 612 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); 613 break; 614 615 case XFRST_AXFR: 616 /* 617 * Old BINDs sent cross class A records for non IN classes. 618 */ 619 if (rdata->type == dns_rdatatype_a && 620 rdata->rdclass != xfr->rdclass && 621 xfr->rdclass != dns_rdataclass_in) 622 break; 623 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); 624 if (rdata->type == dns_rdatatype_soa) { 625 CHECK(axfr_commit(xfr)); 626 xfr->state = XFRST_AXFR_END; 627 break; 628 } 629 break; 630 case XFRST_AXFR_END: 631 case XFRST_IXFR_END: 632 FAIL(DNS_R_EXTRADATA); 633 /* NOTREACHED */ 634 /* FALLTHROUGH */ 635 default: 636 INSIST(0); 637 ISC_UNREACHABLE(); 638 } 639 result = ISC_R_SUCCESS; 640 failure: 641 return (result); 642 } 643 644 isc_result_t 645 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, 646 const isc_sockaddr_t *masteraddr, 647 const isc_sockaddr_t *sourceaddr, 648 isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, 649 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 650 isc_task_t *task, dns_xfrindone_t done, 651 dns_xfrin_ctx_t **xfrp) 652 { 653 dns_name_t *zonename = dns_zone_getorigin(zone); 654 dns_xfrin_ctx_t *xfr = NULL; 655 isc_result_t result; 656 dns_db_t *db = NULL; 657 658 REQUIRE(xfrp != NULL && *xfrp == NULL); 659 660 (void)dns_zone_getdb(zone, &db); 661 662 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) 663 REQUIRE(db != NULL); 664 665 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename, 666 dns_zone_getclass(zone), xfrtype, masteraddr, 667 sourceaddr, dscp, tsigkey, &xfr)); 668 669 if (db != NULL) { 670 xfr->zone_had_db = true; 671 } 672 673 CHECK(xfrin_start(xfr)); 674 675 xfr->done = done; 676 if (xfr->done != NULL) 677 xfr->refcount++; 678 *xfrp = xfr; 679 680 failure: 681 if (db != NULL) 682 dns_db_detach(&db); 683 if (result != ISC_R_SUCCESS) { 684 char zonetext[DNS_NAME_MAXTEXT+32]; 685 dns_zone_name(zone, zonetext, sizeof(zonetext)); 686 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr, 687 "zone transfer setup failed"); 688 } 689 return (result); 690 } 691 692 void 693 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) { 694 if (! xfr->shuttingdown) 695 xfrin_fail(xfr, ISC_R_CANCELED, "shut down"); 696 } 697 698 void 699 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) { 700 REQUIRE(target != NULL && *target == NULL); 701 source->refcount++; 702 *target = source; 703 } 704 705 void 706 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) { 707 dns_xfrin_ctx_t *xfr = *xfrp; 708 INSIST(xfr->refcount > 0); 709 xfr->refcount--; 710 maybe_free(xfr); 711 *xfrp = NULL; 712 } 713 714 static void 715 xfrin_cancelio(dns_xfrin_ctx_t *xfr) { 716 if (xfr->connects > 0) { 717 isc_socket_cancel(xfr->socket, xfr->task, 718 ISC_SOCKCANCEL_CONNECT); 719 } else if (xfr->recvs > 0) { 720 dns_tcpmsg_cancelread(&xfr->tcpmsg); 721 } else if (xfr->sends > 0) { 722 isc_socket_cancel(xfr->socket, xfr->task, 723 ISC_SOCKCANCEL_SEND); 724 } 725 } 726 727 static void 728 xfrin_reset(dns_xfrin_ctx_t *xfr) { 729 REQUIRE(VALID_XFRIN(xfr)); 730 731 xfrin_log(xfr, ISC_LOG_INFO, "resetting"); 732 733 xfrin_cancelio(xfr); 734 735 if (xfr->socket != NULL) 736 isc_socket_detach(&xfr->socket); 737 738 if (xfr->lasttsig != NULL) 739 isc_buffer_free(&xfr->lasttsig); 740 741 dns_diff_clear(&xfr->diff); 742 xfr->difflen = 0; 743 744 if (xfr->ixfr.journal != NULL) 745 dns_journal_destroy(&xfr->ixfr.journal); 746 747 if (xfr->axfr.add_private != NULL) 748 (void)dns_db_endload(xfr->db, &xfr->axfr); 749 750 if (xfr->tcpmsg_valid) { 751 dns_tcpmsg_invalidate(&xfr->tcpmsg); 752 xfr->tcpmsg_valid = false; 753 } 754 755 if (xfr->ver != NULL) 756 dns_db_closeversion(xfr->db, &xfr->ver, false); 757 } 758 759 760 static void 761 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) { 762 if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) { 763 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", 764 msg, isc_result_totext(result)); 765 if (xfr->is_ixfr) 766 /* Pass special result code to force AXFR retry */ 767 result = DNS_R_BADIXFR; 768 } 769 xfrin_cancelio(xfr); 770 /* 771 * Close the journal. 772 */ 773 if (xfr->ixfr.journal != NULL) 774 dns_journal_destroy(&xfr->ixfr.journal); 775 if (xfr->done != NULL) { 776 (xfr->done)(xfr->zone, result); 777 xfr->done = NULL; 778 } 779 xfr->shuttingdown = true; 780 xfr->shutdown_result = result; 781 maybe_free(xfr); 782 } 783 784 static isc_result_t 785 xfrin_create(isc_mem_t *mctx, 786 dns_zone_t *zone, 787 dns_db_t *db, 788 isc_task_t *task, 789 isc_timermgr_t *timermgr, 790 isc_socketmgr_t *socketmgr, 791 dns_name_t *zonename, 792 dns_rdataclass_t rdclass, 793 dns_rdatatype_t reqtype, 794 const isc_sockaddr_t *masteraddr, 795 const isc_sockaddr_t *sourceaddr, 796 isc_dscp_t dscp, 797 dns_tsigkey_t *tsigkey, 798 dns_xfrin_ctx_t **xfrp) 799 { 800 dns_xfrin_ctx_t *xfr = NULL; 801 isc_result_t result; 802 803 xfr = isc_mem_get(mctx, sizeof(*xfr)); 804 if (xfr == NULL) 805 return (ISC_R_NOMEMORY); 806 xfr->mctx = NULL; 807 isc_mem_attach(mctx, &xfr->mctx); 808 xfr->refcount = 0; 809 xfr->zone = NULL; 810 dns_zone_iattach(zone, &xfr->zone); 811 xfr->task = NULL; 812 isc_task_attach(task, &xfr->task); 813 xfr->timer = NULL; 814 xfr->socketmgr = socketmgr; 815 xfr->done = NULL; 816 817 xfr->connects = 0; 818 xfr->sends = 0; 819 xfr->recvs = 0; 820 xfr->shuttingdown = false; 821 xfr->shutdown_result = ISC_R_UNSET; 822 823 dns_name_init(&xfr->name, NULL); 824 xfr->rdclass = rdclass; 825 xfr->checkid = true; 826 xfr->id = (dns_messageid_t)isc_random16(); 827 xfr->reqtype = reqtype; 828 xfr->dscp = dscp; 829 830 /* sockaddr */ 831 xfr->socket = NULL; 832 /* qbuffer */ 833 /* qbuffer_data */ 834 /* tcpmsg */ 835 xfr->tcpmsg_valid = false; 836 837 xfr->zone_had_db = false; 838 xfr->db = NULL; 839 if (db != NULL) 840 dns_db_attach(db, &xfr->db); 841 xfr->ver = NULL; 842 dns_diff_init(xfr->mctx, &xfr->diff); 843 xfr->difflen = 0; 844 845 if (reqtype == dns_rdatatype_soa) 846 xfr->state = XFRST_SOAQUERY; 847 else 848 xfr->state = XFRST_INITIALSOA; 849 /* end_serial */ 850 851 xfr->nmsg = 0; 852 xfr->nrecs = 0; 853 xfr->nbytes = 0; 854 xfr->maxrecords = dns_zone_getmaxrecords(zone); 855 isc_time_now(&xfr->start); 856 857 xfr->tsigkey = NULL; 858 if (tsigkey != NULL) 859 dns_tsigkey_attach(tsigkey, &xfr->tsigkey); 860 xfr->lasttsig = NULL; 861 xfr->tsigctx = NULL; 862 xfr->sincetsig = 0; 863 xfr->is_ixfr = false; 864 865 /* ixfr.request_serial */ 866 /* ixfr.current_serial */ 867 xfr->ixfr.journal = NULL; 868 869 xfr->axfr.add = NULL; 870 xfr->axfr.add_private = NULL; 871 872 CHECK(dns_name_dup(zonename, mctx, &xfr->name)); 873 874 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, 875 task, xfrin_timeout, xfr, &xfr->timer)); 876 CHECK(dns_timer_setidle(xfr->timer, 877 dns_zone_getmaxxfrin(xfr->zone), 878 dns_zone_getidlein(xfr->zone), 879 false)); 880 881 xfr->masteraddr = *masteraddr; 882 883 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr)); 884 xfr->sourceaddr = *sourceaddr; 885 isc_sockaddr_setport(&xfr->sourceaddr, 0); 886 887 /* 888 * Reserve 2 bytes for TCP length at the begining of the buffer. 889 */ 890 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2], 891 sizeof(xfr->qbuffer_data) - 2); 892 893 xfr->magic = XFRIN_MAGIC; 894 *xfrp = xfr; 895 return (ISC_R_SUCCESS); 896 897 failure: 898 if (xfr->timer != NULL) 899 isc_timer_detach(&xfr->timer); 900 if (dns_name_dynamic(&xfr->name)) 901 dns_name_free(&xfr->name, xfr->mctx); 902 if (xfr->tsigkey != NULL) 903 dns_tsigkey_detach(&xfr->tsigkey); 904 if (xfr->db != NULL) 905 dns_db_detach(&xfr->db); 906 isc_task_detach(&xfr->task); 907 dns_zone_idetach(&xfr->zone); 908 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); 909 910 return (result); 911 } 912 913 static isc_result_t 914 xfrin_start(dns_xfrin_ctx_t *xfr) { 915 isc_result_t result; 916 CHECK(isc_socket_create(xfr->socketmgr, 917 isc_sockaddr_pf(&xfr->sourceaddr), 918 isc_sockettype_tcp, 919 &xfr->socket)); 920 isc_socket_setname(xfr->socket, "xfrin", NULL); 921 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT 922 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr, 923 ISC_SOCKET_REUSEADDRESS)); 924 #endif 925 isc_socket_dscp(xfr->socket, xfr->dscp); 926 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task, 927 xfrin_connect_done, xfr)); 928 xfr->connects++; 929 return (ISC_R_SUCCESS); 930 failure: 931 xfrin_fail(xfr, result, "failed setting up socket"); 932 return (result); 933 } 934 935 /* XXX the resolver could use this, too */ 936 937 static isc_result_t 938 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) { 939 dns_compress_t cctx; 940 bool cleanup_cctx = false; 941 isc_result_t result; 942 943 CHECK(dns_compress_init(&cctx, -1, mctx)); 944 cleanup_cctx = true; 945 CHECK(dns_message_renderbegin(msg, &cctx, buf)); 946 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); 947 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); 948 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0)); 949 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0)); 950 CHECK(dns_message_renderend(msg)); 951 result = ISC_R_SUCCESS; 952 failure: 953 if (cleanup_cctx) 954 dns_compress_invalidate(&cctx); 955 return (result); 956 } 957 958 /* 959 * A connection has been established. 960 */ 961 static void 962 xfrin_connect_done(isc_task_t *task, isc_event_t *event) { 963 isc_socket_connev_t *cev = (isc_socket_connev_t *) event; 964 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; 965 isc_result_t result = cev->result; 966 char sourcetext[ISC_SOCKADDR_FORMATSIZE]; 967 char signerbuf[DNS_NAME_FORMATSIZE]; 968 const char *signer = "", *sep = ""; 969 isc_sockaddr_t sockaddr; 970 dns_zonemgr_t * zmgr; 971 isc_time_t now; 972 973 REQUIRE(VALID_XFRIN(xfr)); 974 975 UNUSED(task); 976 977 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT); 978 isc_event_free(&event); 979 980 xfr->connects--; 981 if (xfr->shuttingdown) { 982 maybe_free(xfr); 983 return; 984 } 985 986 zmgr = dns_zone_getmgr(xfr->zone); 987 if (zmgr != NULL) { 988 if (result != ISC_R_SUCCESS) { 989 TIME_NOW(&now); 990 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr, 991 &xfr->sourceaddr, &now); 992 goto failure; 993 } else 994 dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr, 995 &xfr->sourceaddr); 996 } 997 998 result = isc_socket_getsockname(xfr->socket, &sockaddr); 999 if (result == ISC_R_SUCCESS) { 1000 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext)); 1001 } else { 1002 strlcpy(sourcetext, "<UNKNOWN>", sizeof(sourcetext)); 1003 } 1004 1005 if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) { 1006 dns_name_format(dst_key_name(xfr->tsigkey->key), 1007 signerbuf, sizeof(signerbuf)); 1008 sep = " TSIG "; 1009 signer = signerbuf; 1010 } 1011 1012 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", 1013 sourcetext, sep, signer); 1014 1015 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg); 1016 xfr->tcpmsg_valid = true; 1017 1018 CHECK(xfrin_send_request(xfr)); 1019 failure: 1020 if (result != ISC_R_SUCCESS) 1021 xfrin_fail(xfr, result, "failed to connect"); 1022 } 1023 1024 /* 1025 * Convert a tuple into a dns_name_t suitable for inserting 1026 * into the given dns_message_t. 1027 */ 1028 static isc_result_t 1029 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) 1030 { 1031 isc_result_t result; 1032 dns_rdata_t *rdata = NULL; 1033 dns_rdatalist_t *rdl = NULL; 1034 dns_rdataset_t *rds = NULL; 1035 dns_name_t *name = NULL; 1036 1037 REQUIRE(target != NULL && *target == NULL); 1038 1039 CHECK(dns_message_gettemprdata(msg, &rdata)); 1040 dns_rdata_init(rdata); 1041 dns_rdata_clone(&tuple->rdata, rdata); 1042 1043 CHECK(dns_message_gettemprdatalist(msg, &rdl)); 1044 dns_rdatalist_init(rdl); 1045 rdl->type = tuple->rdata.type; 1046 rdl->rdclass = tuple->rdata.rdclass; 1047 rdl->ttl = tuple->ttl; 1048 ISC_LIST_APPEND(rdl->rdata, rdata, link); 1049 1050 CHECK(dns_message_gettemprdataset(msg, &rds)); 1051 CHECK(dns_rdatalist_tordataset(rdl, rds)); 1052 1053 CHECK(dns_message_gettempname(msg, &name)); 1054 dns_name_init(name, NULL); 1055 dns_name_clone(&tuple->name, name); 1056 ISC_LIST_APPEND(name->list, rds, link); 1057 1058 *target = name; 1059 return (ISC_R_SUCCESS); 1060 1061 failure: 1062 1063 if (rds != NULL) { 1064 dns_rdataset_disassociate(rds); 1065 dns_message_puttemprdataset(msg, &rds); 1066 } 1067 if (rdl != NULL) { 1068 ISC_LIST_UNLINK(rdl->rdata, rdata, link); 1069 dns_message_puttemprdatalist(msg, &rdl); 1070 } 1071 if (rdata != NULL) 1072 dns_message_puttemprdata(msg, &rdata); 1073 1074 return (result); 1075 } 1076 1077 1078 /* 1079 * Build an *XFR request and send its length prefix. 1080 */ 1081 static isc_result_t 1082 xfrin_send_request(dns_xfrin_ctx_t *xfr) { 1083 isc_result_t result; 1084 isc_region_t region; 1085 dns_rdataset_t *qrdataset = NULL; 1086 dns_message_t *msg = NULL; 1087 dns_difftuple_t *soatuple = NULL; 1088 dns_name_t *qname = NULL; 1089 dns_dbversion_t *ver = NULL; 1090 dns_name_t *msgsoaname = NULL; 1091 1092 /* Create the request message */ 1093 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg)); 1094 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1095 1096 /* Create a name for the question section. */ 1097 CHECK(dns_message_gettempname(msg, &qname)); 1098 dns_name_init(qname, NULL); 1099 dns_name_clone(&xfr->name, qname); 1100 1101 /* Formulate the question and attach it to the question name. */ 1102 CHECK(dns_message_gettemprdataset(msg, &qrdataset)); 1103 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype); 1104 ISC_LIST_APPEND(qname->list, qrdataset, link); 1105 qrdataset = NULL; 1106 1107 dns_message_addname(msg, qname, DNS_SECTION_QUESTION); 1108 qname = NULL; 1109 1110 if (xfr->reqtype == dns_rdatatype_ixfr) { 1111 /* Get the SOA and add it to the authority section. */ 1112 /* XXX is using the current version the right thing? */ 1113 dns_db_currentversion(xfr->db, &ver); 1114 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx, 1115 DNS_DIFFOP_EXISTS, &soatuple)); 1116 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata); 1117 xfr->ixfr.current_serial = xfr->ixfr.request_serial; 1118 xfrin_log(xfr, ISC_LOG_DEBUG(3), 1119 "requesting IXFR for serial %u", 1120 xfr->ixfr.request_serial); 1121 1122 CHECK(tuple2msgname(soatuple, msg, &msgsoaname)); 1123 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY); 1124 } else if (xfr->reqtype == dns_rdatatype_soa) 1125 CHECK(dns_db_getsoaserial(xfr->db, NULL, 1126 &xfr->ixfr.request_serial)); 1127 1128 xfr->checkid = true; 1129 xfr->id++; 1130 xfr->nmsg = 0; 1131 xfr->nrecs = 0; 1132 xfr->nbytes = 0; 1133 isc_time_now(&xfr->start); 1134 msg->id = xfr->id; 1135 if (xfr->tsigctx != NULL) 1136 dst_context_destroy(&xfr->tsigctx); 1137 1138 CHECK(render(msg, xfr->mctx, &xfr->qbuffer)); 1139 1140 /* 1141 * Free the last tsig, if there is one. 1142 */ 1143 if (xfr->lasttsig != NULL) 1144 isc_buffer_free(&xfr->lasttsig); 1145 1146 /* 1147 * Save the query TSIG and don't let message_destroy free it. 1148 */ 1149 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); 1150 1151 isc_buffer_usedregion(&xfr->qbuffer, ®ion); 1152 INSIST(region.length <= 65535); 1153 1154 /* 1155 * Record message length and adjust region to include TCP 1156 * length field. 1157 */ 1158 xfr->qbuffer_data[0] = (region.length >> 8) & 0xff; 1159 xfr->qbuffer_data[1] = region.length & 0xff; 1160 region.base -= 2; 1161 region.length += 2; 1162 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task, 1163 xfrin_send_done, xfr)); 1164 xfr->sends++; 1165 1166 failure: 1167 if (qname != NULL) 1168 dns_message_puttempname(msg, &qname); 1169 if (qrdataset != NULL) 1170 dns_message_puttemprdataset(msg, &qrdataset); 1171 if (msg != NULL) 1172 dns_message_destroy(&msg); 1173 if (soatuple != NULL) 1174 dns_difftuple_free(&soatuple); 1175 if (ver != NULL) 1176 dns_db_closeversion(xfr->db, &ver, false); 1177 return (result); 1178 } 1179 1180 static void 1181 xfrin_send_done(isc_task_t *task, isc_event_t *event) { 1182 isc_socketevent_t *sev = (isc_socketevent_t *) event; 1183 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; 1184 isc_result_t result; 1185 1186 REQUIRE(VALID_XFRIN(xfr)); 1187 1188 UNUSED(task); 1189 1190 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); 1191 1192 xfr->sends--; 1193 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data"); 1194 CHECK(sev->result); 1195 1196 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, 1197 xfrin_recv_done, xfr)); 1198 xfr->recvs++; 1199 failure: 1200 isc_event_free(&event); 1201 if (result != ISC_R_SUCCESS) 1202 xfrin_fail(xfr, result, "failed sending request data"); 1203 } 1204 1205 1206 static void 1207 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { 1208 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg; 1209 isc_result_t result; 1210 dns_message_t *msg = NULL; 1211 dns_name_t *name; 1212 dns_tcpmsg_t *tcpmsg; 1213 const dns_name_t *tsigowner = NULL; 1214 1215 REQUIRE(VALID_XFRIN(xfr)); 1216 1217 UNUSED(task); 1218 1219 INSIST(ev->ev_type == DNS_EVENT_TCPMSG); 1220 tcpmsg = ev->ev_sender; 1221 isc_event_free(&ev); 1222 1223 xfr->recvs--; 1224 if (xfr->shuttingdown) { 1225 maybe_free(xfr); 1226 return; 1227 } 1228 1229 CHECK(tcpmsg->result); 1230 1231 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", 1232 tcpmsg->buffer.used); 1233 1234 CHECK(isc_timer_touch(xfr->timer)); 1235 1236 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg)); 1237 1238 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1239 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); 1240 1241 msg->tsigctx = xfr->tsigctx; 1242 xfr->tsigctx = NULL; 1243 1244 dns_message_setclass(msg, xfr->rdclass); 1245 1246 if (xfr->nmsg > 0) 1247 msg->tcp_continuation = 1; 1248 1249 result = dns_message_parse(msg, &tcpmsg->buffer, 1250 DNS_MESSAGEPARSE_PRESERVEORDER); 1251 1252 if (result == ISC_R_SUCCESS) 1253 dns_message_logpacket(msg, "received message from", 1254 &tcpmsg->address, 1255 DNS_LOGCATEGORY_XFER_IN, 1256 DNS_LOGMODULE_XFER_IN, 1257 ISC_LOG_DEBUG(10), xfr->mctx); 1258 else 1259 xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s", 1260 dns_result_totext(result)); 1261 1262 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror || 1263 msg->opcode != dns_opcode_query ||msg->rdclass != xfr->rdclass || 1264 (xfr->checkid && msg->id != xfr->id)) { 1265 if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror) 1266 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/ 1267 else if (result == ISC_R_SUCCESS && 1268 msg->opcode != dns_opcode_query) 1269 result = DNS_R_UNEXPECTEDOPCODE; 1270 else if (result == ISC_R_SUCCESS && 1271 msg->rdclass != xfr->rdclass) 1272 result = DNS_R_BADCLASS; 1273 else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) 1274 result = DNS_R_UNEXPECTEDID; 1275 if (xfr->reqtype == dns_rdatatype_axfr || 1276 xfr->reqtype == dns_rdatatype_soa) 1277 goto failure; 1278 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR", 1279 isc_result_totext(result)); 1280 try_axfr: 1281 dns_message_destroy(&msg); 1282 xfrin_reset(xfr); 1283 xfr->reqtype = dns_rdatatype_soa; 1284 xfr->state = XFRST_SOAQUERY; 1285 (void)xfrin_start(xfr); 1286 return; 1287 } 1288 1289 /* 1290 * Does the server know about IXFR? If it doesn't we will get 1291 * a message with a empty answer section or a potentially a CNAME / 1292 * DNAME, the later is handled by xfr_rr() which will return FORMERR 1293 * if the first RR in the answer section is not a SOA record. 1294 */ 1295 if (xfr->reqtype == dns_rdatatype_ixfr && 1296 xfr->state == XFRST_INITIALSOA && 1297 msg->counts[DNS_SECTION_ANSWER] == 0) { 1298 xfrin_log(xfr, ISC_LOG_DEBUG(3), 1299 "empty answer section, retrying with AXFR"); 1300 goto try_axfr; 1301 } 1302 1303 if (xfr->reqtype == dns_rdatatype_soa && 1304 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 1305 FAIL(DNS_R_NOTAUTHORITATIVE); 1306 } 1307 1308 1309 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone)); 1310 if (result != ISC_R_SUCCESS) { 1311 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s", 1312 isc_result_totext(result)); 1313 goto failure; 1314 } 1315 1316 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER); 1317 result == ISC_R_SUCCESS; 1318 result = dns_message_nextname(msg, DNS_SECTION_ANSWER)) 1319 { 1320 dns_rdataset_t *rds; 1321 1322 name = NULL; 1323 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); 1324 for (rds = ISC_LIST_HEAD(name->list); 1325 rds != NULL; 1326 rds = ISC_LIST_NEXT(rds, link)) 1327 { 1328 for (result = dns_rdataset_first(rds); 1329 result == ISC_R_SUCCESS; 1330 result = dns_rdataset_next(rds)) 1331 { 1332 dns_rdata_t rdata = DNS_RDATA_INIT; 1333 dns_rdataset_current(rds, &rdata); 1334 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata)); 1335 } 1336 } 1337 } 1338 if (result != ISC_R_NOMORE) 1339 goto failure; 1340 1341 if (dns_message_gettsig(msg, &tsigowner) != NULL) { 1342 /* 1343 * Reset the counter. 1344 */ 1345 xfr->sincetsig = 0; 1346 1347 /* 1348 * Free the last tsig, if there is one. 1349 */ 1350 if (xfr->lasttsig != NULL) 1351 isc_buffer_free(&xfr->lasttsig); 1352 1353 /* 1354 * Update the last tsig pointer. 1355 */ 1356 CHECK(dns_message_getquerytsig(msg, xfr->mctx, 1357 &xfr->lasttsig)); 1358 1359 } else if (dns_message_gettsigkey(msg) != NULL) { 1360 xfr->sincetsig++; 1361 if (xfr->sincetsig > 100 || xfr->nmsg == 0 || 1362 xfr->state == XFRST_AXFR_END || 1363 xfr->state == XFRST_IXFR_END) 1364 { 1365 result = DNS_R_EXPECTEDTSIG; 1366 goto failure; 1367 } 1368 } 1369 1370 /* 1371 * Update the number of messages received. 1372 */ 1373 xfr->nmsg++; 1374 1375 /* 1376 * Update the number of bytes received. 1377 */ 1378 xfr->nbytes += tcpmsg->buffer.used; 1379 1380 /* 1381 * Take the context back. 1382 */ 1383 INSIST(xfr->tsigctx == NULL); 1384 xfr->tsigctx = msg->tsigctx; 1385 msg->tsigctx = NULL; 1386 1387 dns_message_destroy(&msg); 1388 1389 switch (xfr->state) { 1390 case XFRST_GOTSOA: 1391 xfr->reqtype = dns_rdatatype_axfr; 1392 xfr->state = XFRST_INITIALSOA; 1393 CHECK(xfrin_send_request(xfr)); 1394 break; 1395 case XFRST_AXFR_END: 1396 CHECK(axfr_finalize(xfr)); 1397 /* FALLTHROUGH */ 1398 case XFRST_IXFR_END: 1399 /* 1400 * Close the journal. 1401 */ 1402 if (xfr->ixfr.journal != NULL) 1403 dns_journal_destroy(&xfr->ixfr.journal); 1404 1405 /* 1406 * Inform the caller we succeeded. 1407 */ 1408 if (xfr->done != NULL) { 1409 (xfr->done)(xfr->zone, ISC_R_SUCCESS); 1410 xfr->done = NULL; 1411 } 1412 /* 1413 * We should have no outstanding events at this 1414 * point, thus maybe_free() should succeed. 1415 */ 1416 xfr->shuttingdown = true; 1417 xfr->shutdown_result = ISC_R_SUCCESS; 1418 maybe_free(xfr); 1419 break; 1420 default: 1421 /* 1422 * Read the next message. 1423 */ 1424 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, 1425 xfrin_recv_done, xfr)); 1426 xfr->recvs++; 1427 } 1428 return; 1429 1430 failure: 1431 if (msg != NULL) 1432 dns_message_destroy(&msg); 1433 if (result != ISC_R_SUCCESS) 1434 xfrin_fail(xfr, result, "failed while receiving responses"); 1435 } 1436 1437 static void 1438 xfrin_timeout(isc_task_t *task, isc_event_t *event) { 1439 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; 1440 1441 REQUIRE(VALID_XFRIN(xfr)); 1442 1443 UNUSED(task); 1444 1445 isc_event_free(&event); 1446 /* 1447 * This will log "giving up: timeout". 1448 */ 1449 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up"); 1450 } 1451 1452 static void 1453 maybe_free(dns_xfrin_ctx_t *xfr) { 1454 uint64_t msecs; 1455 uint64_t persec; 1456 const char *result_str; 1457 1458 REQUIRE(VALID_XFRIN(xfr)); 1459 1460 if (! xfr->shuttingdown || xfr->refcount != 0 || 1461 xfr->connects != 0 || xfr->sends != 0 || 1462 xfr->recvs != 0) 1463 return; 1464 1465 INSIST(! xfr->shuttingdown || xfr->shutdown_result != ISC_R_UNSET); 1466 1467 /* If we're called through dns_xfrin_detach() and are not 1468 * shutting down, we can't know what the transfer status is as 1469 * we are only called when the last reference is lost. 1470 */ 1471 result_str = (xfr->shuttingdown ? 1472 isc_result_totext(xfr->shutdown_result) : "unknown"); 1473 xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str); 1474 1475 /* 1476 * Calculate the length of time the transfer took, 1477 * and print a log message with the bytes and rate. 1478 */ 1479 isc_time_now(&xfr->end); 1480 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000; 1481 if (msecs == 0) 1482 msecs = 1; 1483 persec = (xfr->nbytes * 1000) / msecs; 1484 xfrin_log(xfr, ISC_LOG_INFO, 1485 "Transfer completed: %d messages, %d records, " 1486 "%" PRIu64 " bytes, " 1487 "%u.%03u secs (%u bytes/sec)", 1488 xfr->nmsg, xfr->nrecs, xfr->nbytes, 1489 (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000), 1490 (unsigned int) persec); 1491 1492 if (xfr->socket != NULL) 1493 isc_socket_detach(&xfr->socket); 1494 1495 if (xfr->timer != NULL) 1496 isc_timer_detach(&xfr->timer); 1497 1498 if (xfr->task != NULL) 1499 isc_task_detach(&xfr->task); 1500 1501 if (xfr->tsigkey != NULL) 1502 dns_tsigkey_detach(&xfr->tsigkey); 1503 1504 if (xfr->lasttsig != NULL) 1505 isc_buffer_free(&xfr->lasttsig); 1506 1507 dns_diff_clear(&xfr->diff); 1508 1509 if (xfr->ixfr.journal != NULL) 1510 dns_journal_destroy(&xfr->ixfr.journal); 1511 1512 if (xfr->axfr.add_private != NULL) 1513 (void)dns_db_endload(xfr->db, &xfr->axfr); 1514 1515 if (xfr->tcpmsg_valid) 1516 dns_tcpmsg_invalidate(&xfr->tcpmsg); 1517 1518 if (xfr->tsigctx != NULL) 1519 dst_context_destroy(&xfr->tsigctx); 1520 1521 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) 1522 dns_name_free(&xfr->name, xfr->mctx); 1523 1524 if (xfr->ver != NULL) 1525 dns_db_closeversion(xfr->db, &xfr->ver, false); 1526 1527 if (xfr->db != NULL) 1528 dns_db_detach(&xfr->db); 1529 1530 if (xfr->zone != NULL) { 1531 if (!xfr->zone_had_db && 1532 xfr->shuttingdown && 1533 xfr->shutdown_result == ISC_R_SUCCESS && 1534 dns_zone_gettype(xfr->zone) == dns_zone_mirror) 1535 { 1536 dns_zone_log(xfr->zone, ISC_LOG_INFO, 1537 "mirror zone is now in use"); 1538 } 1539 xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context"); 1540 /* 1541 * xfr->zone must not be detached before xfrin_log() is called. 1542 */ 1543 dns_zone_idetach(&xfr->zone); 1544 } 1545 1546 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); 1547 } 1548 1549 /* 1550 * Log incoming zone transfer messages in a format like 1551 * transfer of <zone> from <address>: <message> 1552 */ 1553 static void 1554 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr, 1555 const char *fmt, va_list ap) 1556 { 1557 char mastertext[ISC_SOCKADDR_FORMATSIZE]; 1558 char msgtext[2048]; 1559 1560 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext)); 1561 vsnprintf(msgtext, sizeof(msgtext), fmt, ap); 1562 1563 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, 1564 DNS_LOGMODULE_XFER_IN, level, 1565 "transfer of '%s' from %s: %s", 1566 zonetext, mastertext, msgtext); 1567 } 1568 1569 /* 1570 * Logging function for use when a xfrin_ctx_t has not yet been created. 1571 */ 1572 1573 static void 1574 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr, 1575 const char *fmt, ...) 1576 { 1577 va_list ap; 1578 1579 if (isc_log_wouldlog(dns_lctx, level) == false) 1580 return; 1581 1582 va_start(ap, fmt); 1583 xfrin_logv(level, zonetext, masteraddr, fmt, ap); 1584 va_end(ap); 1585 } 1586 1587 /* 1588 * Logging function for use when there is a xfrin_ctx_t. 1589 */ 1590 1591 static void 1592 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) 1593 { 1594 va_list ap; 1595 char zonetext[DNS_NAME_MAXTEXT+32]; 1596 1597 if (isc_log_wouldlog(dns_lctx, level) == false) 1598 return; 1599 1600 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext)); 1601 1602 va_start(ap, fmt); 1603 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap); 1604 va_end(ap); 1605 } 1606