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