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