1/* $NetBSD$ */ 2 3/* 4 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20/* Id */ 21 22#include <config.h> 23 24#include <isc/formatcheck.h> 25#include <isc/mem.h> 26#include <isc/timer.h> 27#include <isc/print.h> 28#include <isc/stats.h> 29#include <isc/util.h> 30 31#include <dns/db.h> 32#include <dns/dbiterator.h> 33#include <dns/dlz.h> 34#include <dns/fixedname.h> 35#include <dns/journal.h> 36#include <dns/message.h> 37#include <dns/peer.h> 38#include <dns/rdataclass.h> 39#include <dns/rdatalist.h> 40#include <dns/rdataset.h> 41#include <dns/rdatasetiter.h> 42#include <dns/result.h> 43#include <dns/rriterator.h> 44#include <dns/soa.h> 45#include <dns/stats.h> 46#include <dns/timer.h> 47#include <dns/tsig.h> 48#include <dns/view.h> 49#include <dns/zone.h> 50#include <dns/zt.h> 51 52#include <named/client.h> 53#include <named/log.h> 54#include <named/server.h> 55#include <named/xfrout.h> 56 57/*! \file 58 * \brief 59 * Outgoing AXFR and IXFR. 60 */ 61 62/* 63 * TODO: 64 * - IXFR over UDP 65 */ 66 67#define XFROUT_COMMON_LOGARGS \ 68 ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT 69 70#define XFROUT_PROTOCOL_LOGARGS \ 71 XFROUT_COMMON_LOGARGS, ISC_LOG_INFO 72 73#define XFROUT_DEBUG_LOGARGS(n) \ 74 XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n) 75 76#define XFROUT_RR_LOGARGS \ 77 XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL 78 79#define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8) 80 81/*% 82 * Fail unconditionally and log as a client error. 83 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler 84 * from complaining about "end-of-loop code not reached". 85 */ 86#define FAILC(code, msg) \ 87 do { \ 88 result = (code); \ 89 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ 90 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ 91 "bad zone transfer request: %s (%s)", \ 92 msg, isc_result_totext(code)); \ 93 if (result != ISC_R_SUCCESS) goto failure; \ 94 } while (/*CONSTCOND*/0) 95 96#define FAILQ(code, msg, question, rdclass) \ 97 do { \ 98 char _buf1[DNS_NAME_FORMATSIZE]; \ 99 char _buf2[DNS_RDATACLASS_FORMATSIZE]; \ 100 result = (code); \ 101 dns_name_format(question, _buf1, sizeof(_buf1)); \ 102 dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \ 103 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ 104 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ 105 "bad zone transfer request: '%s/%s': %s (%s)", \ 106 _buf1, _buf2, msg, isc_result_totext(code)); \ 107 if (result != ISC_R_SUCCESS) goto failure; \ 108 } while (/*CONSTCOND*/0) 109 110#define CHECK(op) \ 111 do { result = (op); \ 112 if (result != ISC_R_SUCCESS) goto failure; \ 113 } while (/*CONSTCOND*/0) 114 115/**************************************************************************/ 116 117static inline void 118inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 119 isc_stats_increment(ns_g_server->nsstats, counter); 120 if (zone != NULL) { 121 isc_stats_t *zonestats = dns_zone_getrequeststats(zone); 122 if (zonestats != NULL) 123 isc_stats_increment(zonestats, counter); 124 } 125} 126 127/**************************************************************************/ 128 129/*% Log an RR (for debugging) */ 130 131static void 132log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) { 133 isc_result_t result; 134 isc_buffer_t buf; 135 char mem[2000]; 136 dns_rdatalist_t rdl; 137 dns_rdataset_t rds; 138 dns_rdata_t rd = DNS_RDATA_INIT; 139 140 rdl.type = rdata->type; 141 rdl.rdclass = rdata->rdclass; 142 rdl.ttl = ttl; 143 if (rdata->type == dns_rdatatype_sig || 144 rdata->type == dns_rdatatype_rrsig) 145 rdl.covers = dns_rdata_covers(rdata); 146 else 147 rdl.covers = dns_rdatatype_none; 148 ISC_LIST_INIT(rdl.rdata); 149 ISC_LINK_INIT(&rdl, link); 150 dns_rdataset_init(&rds); 151 dns_rdata_init(&rd); 152 dns_rdata_clone(rdata, &rd); 153 ISC_LIST_APPEND(rdl.rdata, &rd, link); 154 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS); 155 156 isc_buffer_init(&buf, mem, sizeof(mem)); 157 result = dns_rdataset_totext(&rds, name, 158 ISC_FALSE, ISC_FALSE, &buf); 159 160 /* 161 * We could use xfrout_log(), but that would produce 162 * very long lines with a repetitive prefix. 163 */ 164 if (result == ISC_R_SUCCESS) { 165 /* 166 * Get rid of final newline. 167 */ 168 INSIST(buf.used >= 1 && 169 ((char *) buf.base)[buf.used - 1] == '\n'); 170 buf.used--; 171 172 isc_log_write(XFROUT_RR_LOGARGS, "%.*s", 173 (int)isc_buffer_usedlength(&buf), 174 (char *)isc_buffer_base(&buf)); 175 } else { 176 isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>"); 177 } 178} 179 180/**************************************************************************/ 181/* 182 * An 'rrstream_t' is a polymorphic iterator that returns 183 * a stream of resource records. There are multiple implementations, 184 * e.g. for generating AXFR and IXFR records streams. 185 */ 186 187typedef struct rrstream_methods rrstream_methods_t; 188 189typedef struct rrstream { 190 isc_mem_t *mctx; 191 rrstream_methods_t *methods; 192} rrstream_t; 193 194struct rrstream_methods { 195 isc_result_t (*first)(rrstream_t *); 196 isc_result_t (*next)(rrstream_t *); 197 void (*current)(rrstream_t *, 198 dns_name_t **, 199 isc_uint32_t *, 200 dns_rdata_t **); 201 void (*pause)(rrstream_t *); 202 void (*destroy)(rrstream_t **); 203}; 204 205static void 206rrstream_noop_pause(rrstream_t *rs) { 207 UNUSED(rs); 208} 209 210/**************************************************************************/ 211/* 212 * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns 213 * an IXFR-like RR stream from a journal file. 214 * 215 * The SOA at the beginning of each sequence of additions 216 * or deletions are included in the stream, but the extra 217 * SOAs at the beginning and end of the entire transfer are 218 * not included. 219 */ 220 221typedef struct ixfr_rrstream { 222 rrstream_t common; 223 dns_journal_t *journal; 224} ixfr_rrstream_t; 225 226/* Forward declarations. */ 227static void 228ixfr_rrstream_destroy(rrstream_t **sp); 229 230static rrstream_methods_t ixfr_rrstream_methods; 231 232/* 233 * Returns: anything dns_journal_open() or dns_journal_iter_init() 234 * may return. 235 */ 236 237static isc_result_t 238ixfr_rrstream_create(isc_mem_t *mctx, 239 const char *journal_filename, 240 isc_uint32_t begin_serial, 241 isc_uint32_t end_serial, 242 rrstream_t **sp) 243{ 244 ixfr_rrstream_t *s; 245 isc_result_t result; 246 247 INSIST(sp != NULL && *sp == NULL); 248 249 s = isc_mem_get(mctx, sizeof(*s)); 250 if (s == NULL) 251 return (ISC_R_NOMEMORY); 252 s->common.mctx = mctx; 253 s->common.methods = &ixfr_rrstream_methods; 254 s->journal = NULL; 255 256 CHECK(dns_journal_open(mctx, journal_filename, 257 DNS_JOURNAL_READ, &s->journal)); 258 CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); 259 260 *sp = (rrstream_t *) s; 261 return (ISC_R_SUCCESS); 262 263 failure: 264 ixfr_rrstream_destroy((rrstream_t **) (void *)&s); 265 return (result); 266} 267 268static isc_result_t 269ixfr_rrstream_first(rrstream_t *rs) { 270 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; 271 return (dns_journal_first_rr(s->journal)); 272} 273 274static isc_result_t 275ixfr_rrstream_next(rrstream_t *rs) { 276 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; 277 return (dns_journal_next_rr(s->journal)); 278} 279 280static void 281ixfr_rrstream_current(rrstream_t *rs, 282 dns_name_t **name, isc_uint32_t *ttl, 283 dns_rdata_t **rdata) 284{ 285 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; 286 dns_journal_current_rr(s->journal, name, ttl, rdata); 287} 288 289static void 290ixfr_rrstream_destroy(rrstream_t **rsp) { 291 ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; 292 if (s->journal != 0) 293 dns_journal_destroy(&s->journal); 294 isc_mem_put(s->common.mctx, s, sizeof(*s)); 295} 296 297static rrstream_methods_t ixfr_rrstream_methods = { 298 ixfr_rrstream_first, 299 ixfr_rrstream_next, 300 ixfr_rrstream_current, 301 rrstream_noop_pause, 302 ixfr_rrstream_destroy 303}; 304 305/**************************************************************************/ 306/* 307 * An 'axfr_rrstream_t' is an 'rrstream_t' that returns 308 * an AXFR-like RR stream from a database. 309 * 310 * The SOAs at the beginning and end of the transfer are 311 * not included in the stream. 312 */ 313 314typedef struct axfr_rrstream { 315 rrstream_t common; 316 dns_rriterator_t it; 317 isc_boolean_t it_valid; 318} axfr_rrstream_t; 319 320/* 321 * Forward declarations. 322 */ 323static void 324axfr_rrstream_destroy(rrstream_t **rsp); 325 326static rrstream_methods_t axfr_rrstream_methods; 327 328static isc_result_t 329axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, 330 rrstream_t **sp) 331{ 332 axfr_rrstream_t *s; 333 isc_result_t result; 334 335 INSIST(sp != NULL && *sp == NULL); 336 337 s = isc_mem_get(mctx, sizeof(*s)); 338 if (s == NULL) 339 return (ISC_R_NOMEMORY); 340 s->common.mctx = mctx; 341 s->common.methods = &axfr_rrstream_methods; 342 s->it_valid = ISC_FALSE; 343 344 CHECK(dns_rriterator_init(&s->it, db, ver, 0)); 345 s->it_valid = ISC_TRUE; 346 347 *sp = (rrstream_t *) s; 348 return (ISC_R_SUCCESS); 349 350 failure: 351 axfr_rrstream_destroy((rrstream_t **) (void *)&s); 352 return (result); 353} 354 355static isc_result_t 356axfr_rrstream_first(rrstream_t *rs) { 357 axfr_rrstream_t *s = (axfr_rrstream_t *) rs; 358 isc_result_t result; 359 result = dns_rriterator_first(&s->it); 360 if (result != ISC_R_SUCCESS) 361 return (result); 362 /* Skip SOA records. */ 363 for (;;) { 364 dns_name_t *name_dummy = NULL; 365 isc_uint32_t ttl_dummy; 366 dns_rdata_t *rdata = NULL; 367 dns_rriterator_current(&s->it, &name_dummy, 368 &ttl_dummy, NULL, &rdata); 369 if (rdata->type != dns_rdatatype_soa) 370 break; 371 result = dns_rriterator_next(&s->it); 372 if (result != ISC_R_SUCCESS) 373 break; 374 } 375 return (result); 376} 377 378static isc_result_t 379axfr_rrstream_next(rrstream_t *rs) { 380 axfr_rrstream_t *s = (axfr_rrstream_t *) rs; 381 isc_result_t result; 382 383 /* Skip SOA records. */ 384 for (;;) { 385 dns_name_t *name_dummy = NULL; 386 isc_uint32_t ttl_dummy; 387 dns_rdata_t *rdata = NULL; 388 result = dns_rriterator_next(&s->it); 389 if (result != ISC_R_SUCCESS) 390 break; 391 dns_rriterator_current(&s->it, &name_dummy, 392 &ttl_dummy, NULL, &rdata); 393 if (rdata->type != dns_rdatatype_soa) 394 break; 395 } 396 return (result); 397} 398 399static void 400axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, 401 dns_rdata_t **rdata) 402{ 403 axfr_rrstream_t *s = (axfr_rrstream_t *) rs; 404 dns_rriterator_current(&s->it, name, ttl, NULL, rdata); 405} 406 407static void 408axfr_rrstream_pause(rrstream_t *rs) { 409 axfr_rrstream_t *s = (axfr_rrstream_t *) rs; 410 dns_rriterator_pause(&s->it); 411} 412 413static void 414axfr_rrstream_destroy(rrstream_t **rsp) { 415 axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; 416 if (s->it_valid) 417 dns_rriterator_destroy(&s->it); 418 isc_mem_put(s->common.mctx, s, sizeof(*s)); 419} 420 421static rrstream_methods_t axfr_rrstream_methods = { 422 axfr_rrstream_first, 423 axfr_rrstream_next, 424 axfr_rrstream_current, 425 axfr_rrstream_pause, 426 axfr_rrstream_destroy 427}; 428 429/**************************************************************************/ 430/* 431 * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns 432 * a single SOA record. 433 */ 434 435typedef struct soa_rrstream { 436 rrstream_t common; 437 dns_difftuple_t *soa_tuple; 438} soa_rrstream_t; 439 440/* 441 * Forward declarations. 442 */ 443static void 444soa_rrstream_destroy(rrstream_t **rsp); 445 446static rrstream_methods_t soa_rrstream_methods; 447 448static isc_result_t 449soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, 450 rrstream_t **sp) 451{ 452 soa_rrstream_t *s; 453 isc_result_t result; 454 455 INSIST(sp != NULL && *sp == NULL); 456 457 s = isc_mem_get(mctx, sizeof(*s)); 458 if (s == NULL) 459 return (ISC_R_NOMEMORY); 460 s->common.mctx = mctx; 461 s->common.methods = &soa_rrstream_methods; 462 s->soa_tuple = NULL; 463 464 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, 465 &s->soa_tuple)); 466 467 *sp = (rrstream_t *) s; 468 return (ISC_R_SUCCESS); 469 470 failure: 471 soa_rrstream_destroy((rrstream_t **) (void *)&s); 472 return (result); 473} 474 475static isc_result_t 476soa_rrstream_first(rrstream_t *rs) { 477 UNUSED(rs); 478 return (ISC_R_SUCCESS); 479} 480 481static isc_result_t 482soa_rrstream_next(rrstream_t *rs) { 483 UNUSED(rs); 484 return (ISC_R_NOMORE); 485} 486 487static void 488soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, 489 dns_rdata_t **rdata) 490{ 491 soa_rrstream_t *s = (soa_rrstream_t *) rs; 492 *name = &s->soa_tuple->name; 493 *ttl = s->soa_tuple->ttl; 494 *rdata = &s->soa_tuple->rdata; 495} 496 497static void 498soa_rrstream_destroy(rrstream_t **rsp) { 499 soa_rrstream_t *s = (soa_rrstream_t *) *rsp; 500 if (s->soa_tuple != NULL) 501 dns_difftuple_free(&s->soa_tuple); 502 isc_mem_put(s->common.mctx, s, sizeof(*s)); 503} 504 505static rrstream_methods_t soa_rrstream_methods = { 506 soa_rrstream_first, 507 soa_rrstream_next, 508 soa_rrstream_current, 509 rrstream_noop_pause, 510 soa_rrstream_destroy 511}; 512 513/**************************************************************************/ 514/* 515 * A 'compound_rrstream_t' objects owns a soa_rrstream 516 * and another rrstream, the "data stream". It returns 517 * a concatenated stream consisting of the soa_rrstream, then 518 * the data stream, then the soa_rrstream again. 519 * 520 * The component streams are owned by the compound_rrstream_t 521 * and are destroyed with it. 522 */ 523 524typedef struct compound_rrstream { 525 rrstream_t common; 526 rrstream_t *components[3]; 527 int state; 528 isc_result_t result; 529} compound_rrstream_t; 530 531/* 532 * Forward declarations. 533 */ 534static void 535compound_rrstream_destroy(rrstream_t **rsp); 536 537static isc_result_t 538compound_rrstream_next(rrstream_t *rs); 539 540static rrstream_methods_t compound_rrstream_methods; 541 542/* 543 * Requires: 544 * soa_stream != NULL && *soa_stream != NULL 545 * data_stream != NULL && *data_stream != NULL 546 * sp != NULL && *sp == NULL 547 * 548 * Ensures: 549 * *soa_stream == NULL 550 * *data_stream == NULL 551 * *sp points to a valid compound_rrstream_t 552 * The soa and data streams will be destroyed 553 * when the compound_rrstream_t is destroyed. 554 */ 555static isc_result_t 556compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, 557 rrstream_t **data_stream, rrstream_t **sp) 558{ 559 compound_rrstream_t *s; 560 561 INSIST(sp != NULL && *sp == NULL); 562 563 s = isc_mem_get(mctx, sizeof(*s)); 564 if (s == NULL) 565 return (ISC_R_NOMEMORY); 566 s->common.mctx = mctx; 567 s->common.methods = &compound_rrstream_methods; 568 s->components[0] = *soa_stream; 569 s->components[1] = *data_stream; 570 s->components[2] = *soa_stream; 571 s->state = -1; 572 s->result = ISC_R_FAILURE; 573 574 *soa_stream = NULL; 575 *data_stream = NULL; 576 *sp = (rrstream_t *) s; 577 return (ISC_R_SUCCESS); 578} 579 580static isc_result_t 581compound_rrstream_first(rrstream_t *rs) { 582 compound_rrstream_t *s = (compound_rrstream_t *) rs; 583 s->state = 0; 584 do { 585 rrstream_t *curstream = s->components[s->state]; 586 s->result = curstream->methods->first(curstream); 587 } while (s->result == ISC_R_NOMORE && s->state < 2); 588 return (s->result); 589} 590 591static isc_result_t 592compound_rrstream_next(rrstream_t *rs) { 593 compound_rrstream_t *s = (compound_rrstream_t *) rs; 594 rrstream_t *curstream = s->components[s->state]; 595 s->result = curstream->methods->next(curstream); 596 while (s->result == ISC_R_NOMORE) { 597 /* 598 * Make sure locks held by the current stream 599 * are released before we switch streams. 600 */ 601 curstream->methods->pause(curstream); 602 if (s->state == 2) 603 return (ISC_R_NOMORE); 604 s->state++; 605 curstream = s->components[s->state]; 606 s->result = curstream->methods->first(curstream); 607 } 608 return (s->result); 609} 610 611static void 612compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, 613 dns_rdata_t **rdata) 614{ 615 compound_rrstream_t *s = (compound_rrstream_t *) rs; 616 rrstream_t *curstream; 617 INSIST(0 <= s->state && s->state < 3); 618 INSIST(s->result == ISC_R_SUCCESS); 619 curstream = s->components[s->state]; 620 curstream->methods->current(curstream, name, ttl, rdata); 621} 622 623static void 624compound_rrstream_pause(rrstream_t *rs) 625{ 626 compound_rrstream_t *s = (compound_rrstream_t *) rs; 627 rrstream_t *curstream; 628 INSIST(0 <= s->state && s->state < 3); 629 curstream = s->components[s->state]; 630 curstream->methods->pause(curstream); 631} 632 633static void 634compound_rrstream_destroy(rrstream_t **rsp) { 635 compound_rrstream_t *s = (compound_rrstream_t *) *rsp; 636 s->components[0]->methods->destroy(&s->components[0]); 637 s->components[1]->methods->destroy(&s->components[1]); 638 s->components[2] = NULL; /* Copy of components[0]. */ 639 isc_mem_put(s->common.mctx, s, sizeof(*s)); 640} 641 642static rrstream_methods_t compound_rrstream_methods = { 643 compound_rrstream_first, 644 compound_rrstream_next, 645 compound_rrstream_current, 646 compound_rrstream_pause, 647 compound_rrstream_destroy 648}; 649 650/**************************************************************************/ 651/* 652 * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR 653 * in progress. 654 */ 655 656typedef struct { 657 isc_mem_t *mctx; 658 ns_client_t *client; 659 unsigned int id; /* ID of request */ 660 dns_name_t *qname; /* Question name of request */ 661 dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ 662 dns_rdataclass_t qclass; 663 dns_zone_t *zone; /* (necessary for stats) */ 664 dns_db_t *db; 665 dns_dbversion_t *ver; 666 isc_quota_t *quota; 667 rrstream_t *stream; /* The XFR RR stream */ 668 isc_boolean_t end_of_stream; /* EOS has been reached */ 669 isc_buffer_t buf; /* Buffer for message owner 670 names and rdatas */ 671 isc_buffer_t txlenbuf; /* Transmit length buffer */ 672 isc_buffer_t txbuf; /* Transmit message buffer */ 673 void *txmem; 674 unsigned int txmemlen; 675 unsigned int nmsg; /* Number of messages sent */ 676 dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ 677 isc_buffer_t *lasttsig; /* the last TSIG */ 678 isc_boolean_t many_answers; 679 int sends; /* Send in progress */ 680 isc_boolean_t shuttingdown; 681 const char *mnemonic; /* Style of transfer */ 682} xfrout_ctx_t; 683 684static isc_result_t 685xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, 686 unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, 687 dns_rdataclass_t qclass, dns_zone_t *zone, 688 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, 689 rrstream_t *stream, dns_tsigkey_t *tsigkey, 690 isc_buffer_t *lasttsig, 691 unsigned int maxtime, 692 unsigned int idletime, 693 isc_boolean_t many_answers, 694 xfrout_ctx_t **xfrp); 695 696static void 697sendstream(xfrout_ctx_t *xfr); 698 699static void 700xfrout_senddone(isc_task_t *task, isc_event_t *event); 701 702static void 703xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); 704 705static void 706xfrout_maybe_destroy(xfrout_ctx_t *xfr); 707 708static void 709xfrout_ctx_destroy(xfrout_ctx_t **xfrp); 710 711static void 712xfrout_client_shutdown(void *arg, isc_result_t result); 713 714static void 715xfrout_log1(ns_client_t *client, dns_name_t *zonename, 716 dns_rdataclass_t rdclass, int level, 717 const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); 718 719static void 720xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) 721 ISC_FORMAT_PRINTF(3, 4); 722 723/**************************************************************************/ 724 725void 726ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { 727 isc_result_t result; 728 dns_name_t *question_name; 729 dns_rdataset_t *question_rdataset; 730 dns_zone_t *zone = NULL; 731 dns_db_t *db = NULL; 732 dns_dbversion_t *ver = NULL; 733 dns_rdataclass_t question_class; 734 rrstream_t *soa_stream = NULL; 735 rrstream_t *data_stream = NULL; 736 rrstream_t *stream = NULL; 737 dns_difftuple_t *current_soa_tuple = NULL; 738 dns_name_t *soa_name; 739 dns_rdataset_t *soa_rdataset; 740 dns_rdata_t soa_rdata = DNS_RDATA_INIT; 741 isc_boolean_t have_soa = ISC_FALSE; 742 const char *mnemonic = NULL; 743 isc_mem_t *mctx = client->mctx; 744 dns_message_t *request = client->message; 745 xfrout_ctx_t *xfr = NULL; 746 isc_quota_t *quota = NULL; 747 dns_transfer_format_t format = client->view->transfer_format; 748 isc_netaddr_t na; 749 dns_peer_t *peer = NULL; 750 isc_buffer_t *tsigbuf = NULL; 751 char *journalfile; 752 char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; 753 char keyname[DNS_NAME_FORMATSIZE]; 754 isc_boolean_t is_poll = ISC_FALSE; 755 isc_boolean_t is_dlz = ISC_FALSE; 756 757 switch (reqtype) { 758 case dns_rdatatype_axfr: 759 mnemonic = "AXFR"; 760 break; 761 case dns_rdatatype_ixfr: 762 mnemonic = "IXFR"; 763 break; 764 default: 765 INSIST(0); 766 break; 767 } 768 769 ns_client_log(client, 770 DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, 771 ISC_LOG_DEBUG(6), "%s request", mnemonic); 772 /* 773 * Apply quota. 774 */ 775 result = isc_quota_attach(&ns_g_server->xfroutquota, "a); 776 if (result != ISC_R_SUCCESS) { 777 isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, 778 "%s request denied: %s", mnemonic, 779 isc_result_totext(result)); 780 goto failure; 781 } 782 783 /* 784 * Interpret the question section. 785 */ 786 result = dns_message_firstname(request, DNS_SECTION_QUESTION); 787 INSIST(result == ISC_R_SUCCESS); 788 789 /* 790 * The question section must contain exactly one question, and 791 * it must be for AXFR/IXFR as appropriate. 792 */ 793 question_name = NULL; 794 dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); 795 question_rdataset = ISC_LIST_HEAD(question_name->list); 796 question_class = question_rdataset->rdclass; 797 INSIST(question_rdataset->type == reqtype); 798 if (ISC_LIST_NEXT(question_rdataset, link) != NULL) 799 FAILC(DNS_R_FORMERR, "multiple questions"); 800 result = dns_message_nextname(request, DNS_SECTION_QUESTION); 801 if (result != ISC_R_NOMORE) 802 FAILC(DNS_R_FORMERR, "multiple questions"); 803 804 result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, 805 &zone); 806 807 if (result != ISC_R_SUCCESS) { 808 /* 809 * Normal zone table does not have a match. 810 * Try the DLZ database 811 */ 812 if (client->view->dlzdatabase != NULL) { 813 result = dns_dlzallowzonexfr(client->view, 814 question_name, 815 &client->peeraddr, 816 &db); 817 818 if (result == ISC_R_NOPERM) { 819 char _buf1[DNS_NAME_FORMATSIZE]; 820 char _buf2[DNS_RDATACLASS_FORMATSIZE]; 821 822 result = DNS_R_REFUSED; 823 dns_name_format(question_name, _buf1, 824 sizeof(_buf1)); 825 dns_rdataclass_format(question_class, 826 _buf2, sizeof(_buf2)); 827 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 828 NS_LOGMODULE_XFER_OUT, 829 ISC_LOG_ERROR, 830 "zone transfer '%s/%s' denied", 831 _buf1, _buf2); 832 goto failure; 833 } 834 if (result != ISC_R_SUCCESS) 835 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 836 question_name, question_class); 837 is_dlz = ISC_TRUE; 838 /* 839 * DLZ only support full zone transfer, not incremental 840 */ 841 if (reqtype != dns_rdatatype_axfr) { 842 mnemonic = "AXFR-style IXFR"; 843 reqtype = dns_rdatatype_axfr; 844 } 845 846 } else { 847 /* 848 * not DLZ and not in normal zone table, we are 849 * not authoritative 850 */ 851 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 852 question_name, question_class); 853 } 854 } else { 855 /* zone table has a match */ 856 switch(dns_zone_gettype(zone)) { 857 case dns_zone_master: 858 case dns_zone_slave: 859 case dns_zone_dlz: 860 break; /* Master and slave zones are OK for transfer. */ 861 default: 862 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); 863 } 864 CHECK(dns_zone_getdb(zone, &db)); 865 dns_db_currentversion(db, &ver); 866 } 867 868 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), 869 "%s question section OK", mnemonic); 870 871 /* 872 * Check the authority section. Look for a SOA record with 873 * the same name and class as the question. 874 */ 875 for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); 876 result == ISC_R_SUCCESS; 877 result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) 878 { 879 soa_name = NULL; 880 dns_message_currentname(request, DNS_SECTION_AUTHORITY, 881 &soa_name); 882 883 /* 884 * Ignore data whose owner name is not the zone apex. 885 */ 886 if (! dns_name_equal(soa_name, question_name)) 887 continue; 888 889 for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); 890 soa_rdataset != NULL; 891 soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) 892 { 893 /* 894 * Ignore non-SOA data. 895 */ 896 if (soa_rdataset->type != dns_rdatatype_soa) 897 continue; 898 if (soa_rdataset->rdclass != question_class) 899 continue; 900 901 CHECK(dns_rdataset_first(soa_rdataset)); 902 dns_rdataset_current(soa_rdataset, &soa_rdata); 903 result = dns_rdataset_next(soa_rdataset); 904 if (result == ISC_R_SUCCESS) 905 FAILC(DNS_R_FORMERR, 906 "IXFR authority section " 907 "has multiple SOAs"); 908 have_soa = ISC_TRUE; 909 goto got_soa; 910 } 911 } 912 got_soa: 913 if (result != ISC_R_NOMORE) 914 CHECK(result); 915 916 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), 917 "%s authority section OK", mnemonic); 918 919 /* 920 * If not a DLZ zone, decide whether to allow this transfer. 921 */ 922 if (!is_dlz) { 923 ns_client_aclmsg("zone transfer", question_name, reqtype, 924 client->view->rdclass, msg, sizeof(msg)); 925 CHECK(ns_client_checkacl(client, NULL, msg, 926 dns_zone_getxfracl(zone), 927 ISC_TRUE, ISC_LOG_ERROR)); 928 } 929 930 /* 931 * AXFR over UDP is not possible. 932 */ 933 if (reqtype == dns_rdatatype_axfr && 934 (client->attributes & NS_CLIENTATTR_TCP) == 0) 935 FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); 936 937 /* 938 * Look up the requesting server in the peer table. 939 */ 940 isc_netaddr_fromsockaddr(&na, &client->peeraddr); 941 (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); 942 943 /* 944 * Decide on the transfer format (one-answer or many-answers). 945 */ 946 if (peer != NULL) 947 (void)dns_peer_gettransferformat(peer, &format); 948 949 /* 950 * Get a dynamically allocated copy of the current SOA. 951 */ 952 if (is_dlz) 953 dns_db_currentversion(db, &ver); 954 955 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, 956 ¤t_soa_tuple)); 957 958 if (reqtype == dns_rdatatype_ixfr) { 959 isc_uint32_t begin_serial, current_serial; 960 isc_boolean_t provide_ixfr; 961 962 /* 963 * Outgoing IXFR may have been disabled for this peer 964 * or globally. 965 */ 966 provide_ixfr = client->view->provideixfr; 967 if (peer != NULL) 968 (void) dns_peer_getprovideixfr(peer, &provide_ixfr); 969 if (provide_ixfr == ISC_FALSE) 970 goto axfr_fallback; 971 972 if (! have_soa) 973 FAILC(DNS_R_FORMERR, 974 "IXFR request missing SOA"); 975 976 begin_serial = dns_soa_getserial(&soa_rdata); 977 current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); 978 979 /* 980 * RFC1995 says "If an IXFR query with the same or 981 * newer version number than that of the server 982 * is received, it is replied to with a single SOA 983 * record of the server's current version, just as 984 * in AXFR". The claim about AXFR is incorrect, 985 * but other than that, we do as the RFC says. 986 * 987 * Sending a single SOA record is also how we refuse 988 * IXFR over UDP (currently, we always do). 989 */ 990 if (DNS_SERIAL_GE(begin_serial, current_serial) || 991 (client->attributes & NS_CLIENTATTR_TCP) == 0) 992 { 993 CHECK(soa_rrstream_create(mctx, db, ver, &stream)); 994 is_poll = ISC_TRUE; 995 goto have_stream; 996 } 997 journalfile = dns_zone_getjournal(zone); 998 if (journalfile != NULL) 999 result = ixfr_rrstream_create(mctx, 1000 journalfile, 1001 begin_serial, 1002 current_serial, 1003 &data_stream); 1004 else 1005 result = ISC_R_NOTFOUND; 1006 if (result == ISC_R_NOTFOUND || 1007 result == ISC_R_RANGE) { 1008 xfrout_log1(client, question_name, question_class, 1009 ISC_LOG_DEBUG(4), 1010 "IXFR version not in journal, " 1011 "falling back to AXFR"); 1012 mnemonic = "AXFR-style IXFR"; 1013 goto axfr_fallback; 1014 } 1015 CHECK(result); 1016 } else { 1017 axfr_fallback: 1018 CHECK(axfr_rrstream_create(mctx, db, ver, 1019 &data_stream)); 1020 } 1021 1022 /* 1023 * Bracket the data stream with SOAs. 1024 */ 1025 CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); 1026 CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, 1027 &stream)); 1028 soa_stream = NULL; 1029 data_stream = NULL; 1030 1031 have_stream: 1032 CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); 1033 /* 1034 * Create the xfrout context object. This transfers the ownership 1035 * of "stream", "db", "ver", and "quota" to the xfrout context object. 1036 */ 1037 1038 1039 1040 if (is_dlz) 1041 CHECK(xfrout_ctx_create(mctx, client, request->id, 1042 question_name, reqtype, question_class, 1043 zone, db, ver, quota, stream, 1044 dns_message_gettsigkey(request), 1045 tsigbuf, 1046 3600, 1047 3600, 1048 (format == dns_many_answers) ? 1049 ISC_TRUE : ISC_FALSE, 1050 &xfr)); 1051 else 1052 CHECK(xfrout_ctx_create(mctx, client, request->id, 1053 question_name, reqtype, question_class, 1054 zone, db, ver, quota, stream, 1055 dns_message_gettsigkey(request), 1056 tsigbuf, 1057 dns_zone_getmaxxfrout(zone), 1058 dns_zone_getidleout(zone), 1059 (format == dns_many_answers) ? 1060 ISC_TRUE : ISC_FALSE, 1061 &xfr)); 1062 1063 xfr->mnemonic = mnemonic; 1064 stream = NULL; 1065 quota = NULL; 1066 1067 CHECK(xfr->stream->methods->first(xfr->stream)); 1068 1069 if (xfr->tsigkey != NULL) 1070 dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); 1071 else 1072 keyname[0] = '\0'; 1073 if (is_poll) 1074 xfrout_log1(client, question_name, question_class, 1075 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", 1076 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); 1077 else 1078 xfrout_log1(client, question_name, question_class, 1079 ISC_LOG_INFO, "%s started%s%s", mnemonic, 1080 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); 1081 1082 /* 1083 * Hand the context over to sendstream(). Set xfr to NULL; 1084 * sendstream() is responsible for either passing the 1085 * context on to a later event handler or destroying it. 1086 */ 1087 sendstream(xfr); 1088 xfr = NULL; 1089 1090 result = ISC_R_SUCCESS; 1091 1092 failure: 1093 if (result == DNS_R_REFUSED) 1094 inc_stats(zone, dns_nsstatscounter_xfrrej); 1095 if (quota != NULL) 1096 isc_quota_detach("a); 1097 if (current_soa_tuple != NULL) 1098 dns_difftuple_free(¤t_soa_tuple); 1099 if (stream != NULL) 1100 stream->methods->destroy(&stream); 1101 if (soa_stream != NULL) 1102 soa_stream->methods->destroy(&soa_stream); 1103 if (data_stream != NULL) 1104 data_stream->methods->destroy(&data_stream); 1105 if (ver != NULL) 1106 dns_db_closeversion(db, &ver, ISC_FALSE); 1107 if (db != NULL) 1108 dns_db_detach(&db); 1109 if (zone != NULL) 1110 dns_zone_detach(&zone); 1111 /* XXX kludge */ 1112 if (xfr != NULL) { 1113 xfrout_fail(xfr, result, "setting up zone transfer"); 1114 } else if (result != ISC_R_SUCCESS) { 1115 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, 1116 NS_LOGMODULE_XFER_OUT, 1117 ISC_LOG_DEBUG(3), "zone transfer setup failed"); 1118 ns_client_error(client, result); 1119 } 1120} 1121 1122static isc_result_t 1123xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, 1124 dns_name_t *qname, dns_rdatatype_t qtype, 1125 dns_rdataclass_t qclass, dns_zone_t *zone, 1126 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, 1127 rrstream_t *stream, dns_tsigkey_t *tsigkey, 1128 isc_buffer_t *lasttsig, unsigned int maxtime, 1129 unsigned int idletime, isc_boolean_t many_answers, 1130 xfrout_ctx_t **xfrp) 1131{ 1132 xfrout_ctx_t *xfr; 1133 isc_result_t result; 1134 unsigned int len; 1135 void *mem; 1136 1137 INSIST(xfrp != NULL && *xfrp == NULL); 1138 xfr = isc_mem_get(mctx, sizeof(*xfr)); 1139 if (xfr == NULL) 1140 return (ISC_R_NOMEMORY); 1141 xfr->mctx = NULL; 1142 isc_mem_attach(mctx, &xfr->mctx); 1143 xfr->client = NULL; 1144 ns_client_attach(client, &xfr->client); 1145 xfr->id = id; 1146 xfr->qname = qname; 1147 xfr->qtype = qtype; 1148 xfr->qclass = qclass; 1149 xfr->zone = NULL; 1150 xfr->db = NULL; 1151 xfr->ver = NULL; 1152 if (zone != NULL) /* zone will be NULL if it's DLZ */ 1153 dns_zone_attach(zone, &xfr->zone); 1154 dns_db_attach(db, &xfr->db); 1155 dns_db_attachversion(db, ver, &xfr->ver); 1156 xfr->end_of_stream = ISC_FALSE; 1157 xfr->tsigkey = tsigkey; 1158 xfr->lasttsig = lasttsig; 1159 xfr->txmem = NULL; 1160 xfr->txmemlen = 0; 1161 xfr->nmsg = 0; 1162 xfr->many_answers = many_answers, 1163 xfr->sends = 0; 1164 xfr->shuttingdown = ISC_FALSE; 1165 xfr->mnemonic = NULL; 1166 xfr->buf.base = NULL; 1167 xfr->buf.length = 0; 1168 xfr->txmem = NULL; 1169 xfr->txmemlen = 0; 1170 xfr->stream = NULL; 1171 xfr->quota = NULL; 1172 1173 /* 1174 * Allocate a temporary buffer for the uncompressed response 1175 * message data. The size should be no more than 65535 bytes 1176 * so that the compressed data will fit in a TCP message, 1177 * and no less than 65535 bytes so that an almost maximum-sized 1178 * RR will fit. Note that although 65535-byte RRs are allowed 1179 * in principle, they cannot be zone-transferred (at least not 1180 * if uncompressible), because the message and RR headers would 1181 * push the size of the TCP message over the 65536 byte limit. 1182 */ 1183 len = 65535; 1184 mem = isc_mem_get(mctx, len); 1185 if (mem == NULL) { 1186 result = ISC_R_NOMEMORY; 1187 goto failure; 1188 } 1189 isc_buffer_init(&xfr->buf, mem, len); 1190 1191 /* 1192 * Allocate another temporary buffer for the compressed 1193 * response message and its TCP length prefix. 1194 */ 1195 len = 2 + 65535; 1196 mem = isc_mem_get(mctx, len); 1197 if (mem == NULL) { 1198 result = ISC_R_NOMEMORY; 1199 goto failure; 1200 } 1201 isc_buffer_init(&xfr->txlenbuf, mem, 2); 1202 isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); 1203 xfr->txmem = mem; 1204 xfr->txmemlen = len; 1205 1206 CHECK(dns_timer_setidle(xfr->client->timer, 1207 maxtime, idletime, ISC_FALSE)); 1208 1209 /* 1210 * Register a shutdown callback with the client, so that we 1211 * can stop the transfer immediately when the client task 1212 * gets a shutdown event. 1213 */ 1214 xfr->client->shutdown = xfrout_client_shutdown; 1215 xfr->client->shutdown_arg = xfr; 1216 /* 1217 * These MUST be after the last "goto failure;" / CHECK to 1218 * prevent a double free by the caller. 1219 */ 1220 xfr->quota = quota; 1221 xfr->stream = stream; 1222 1223 *xfrp = xfr; 1224 return (ISC_R_SUCCESS); 1225 1226failure: 1227 xfrout_ctx_destroy(&xfr); 1228 return (result); 1229} 1230 1231 1232/* 1233 * Arrange to send as much as we can of "stream" without blocking. 1234 * 1235 * Requires: 1236 * The stream iterator is initialized and points at an RR, 1237 * or possibly at the end of the stream (that is, the 1238 * _first method of the iterator has been called). 1239 */ 1240static void 1241sendstream(xfrout_ctx_t *xfr) { 1242 dns_message_t *tcpmsg = NULL; 1243 dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ 1244 isc_result_t result; 1245 isc_region_t used; 1246 isc_region_t region; 1247 dns_rdataset_t *qrdataset; 1248 dns_name_t *msgname = NULL; 1249 dns_rdata_t *msgrdata = NULL; 1250 dns_rdatalist_t *msgrdl = NULL; 1251 dns_rdataset_t *msgrds = NULL; 1252 dns_compress_t cctx; 1253 isc_boolean_t cleanup_cctx = ISC_FALSE; 1254 1255 int n_rrs; 1256 1257 isc_buffer_clear(&xfr->buf); 1258 isc_buffer_clear(&xfr->txlenbuf); 1259 isc_buffer_clear(&xfr->txbuf); 1260 1261 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) { 1262 /* 1263 * In the UDP case, we put the response data directly into 1264 * the client message. 1265 */ 1266 msg = xfr->client->message; 1267 CHECK(dns_message_reply(msg, ISC_TRUE)); 1268 } else { 1269 /* 1270 * TCP. Build a response dns_message_t, temporarily storing 1271 * the raw, uncompressed owner names and RR data contiguously 1272 * in xfr->buf. We know that if the uncompressed data fits 1273 * in xfr->buf, the compressed data will surely fit in a TCP 1274 * message. 1275 */ 1276 1277 CHECK(dns_message_create(xfr->mctx, 1278 DNS_MESSAGE_INTENTRENDER, &tcpmsg)); 1279 msg = tcpmsg; 1280 1281 msg->id = xfr->id; 1282 msg->rcode = dns_rcode_noerror; 1283 msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; 1284 if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) 1285 msg->flags |= DNS_MESSAGEFLAG_RA; 1286 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1287 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); 1288 if (xfr->lasttsig != NULL) 1289 isc_buffer_free(&xfr->lasttsig); 1290 1291 /* 1292 * Account for reserved space. 1293 */ 1294 if (xfr->tsigkey != NULL) 1295 INSIST(msg->reserved != 0U); 1296 isc_buffer_add(&xfr->buf, msg->reserved); 1297 1298 /* 1299 * Include a question section in the first message only. 1300 * BIND 8.2.1 will not recognize an IXFR if it does not 1301 * have a question section. 1302 */ 1303 if (xfr->nmsg == 0) { 1304 dns_name_t *qname = NULL; 1305 isc_region_t r; 1306 1307 /* 1308 * Reserve space for the 12-byte message header 1309 * and 4 bytes of question. 1310 */ 1311 isc_buffer_add(&xfr->buf, 12 + 4); 1312 1313 qrdataset = NULL; 1314 result = dns_message_gettemprdataset(msg, &qrdataset); 1315 if (result != ISC_R_SUCCESS) 1316 goto failure; 1317 dns_rdataset_init(qrdataset); 1318 dns_rdataset_makequestion(qrdataset, 1319 xfr->client->message->rdclass, 1320 xfr->qtype); 1321 1322 result = dns_message_gettempname(msg, &qname); 1323 if (result != ISC_R_SUCCESS) 1324 goto failure; 1325 dns_name_init(qname, NULL); 1326 isc_buffer_availableregion(&xfr->buf, &r); 1327 INSIST(r.length >= xfr->qname->length); 1328 r.length = xfr->qname->length; 1329 isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, 1330 xfr->qname->length); 1331 dns_name_fromregion(qname, &r); 1332 ISC_LIST_INIT(qname->list); 1333 ISC_LIST_APPEND(qname->list, qrdataset, link); 1334 1335 dns_message_addname(msg, qname, DNS_SECTION_QUESTION); 1336 } else { 1337 /* 1338 * Reserve space for the 12-byte message header 1339 */ 1340 isc_buffer_add(&xfr->buf, 12); 1341 msg->tcp_continuation = 1; 1342 } 1343 } 1344 1345 /* 1346 * Try to fit in as many RRs as possible, unless "one-answer" 1347 * format has been requested. 1348 */ 1349 for (n_rrs = 0; ; n_rrs++) { 1350 dns_name_t *name = NULL; 1351 isc_uint32_t ttl; 1352 dns_rdata_t *rdata = NULL; 1353 1354 unsigned int size; 1355 isc_region_t r; 1356 1357 msgname = NULL; 1358 msgrdata = NULL; 1359 msgrdl = NULL; 1360 msgrds = NULL; 1361 1362 xfr->stream->methods->current(xfr->stream, 1363 &name, &ttl, &rdata); 1364 size = name->length + 10 + rdata->length; 1365 isc_buffer_availableregion(&xfr->buf, &r); 1366 if (size >= r.length) { 1367 /* 1368 * RR would not fit. If there are other RRs in the 1369 * buffer, send them now and leave this RR to the 1370 * next message. If this RR overflows the buffer 1371 * all by itself, fail. 1372 * 1373 * In theory some RRs might fit in a TCP message 1374 * when compressed even if they do not fit when 1375 * uncompressed, but surely we don't want 1376 * to send such monstrosities to an unsuspecting 1377 * slave. 1378 */ 1379 if (n_rrs == 0) { 1380 xfrout_log(xfr, ISC_LOG_WARNING, 1381 "RR too large for zone transfer " 1382 "(%d bytes)", size); 1383 /* XXX DNS_R_RRTOOLARGE? */ 1384 result = ISC_R_NOSPACE; 1385 goto failure; 1386 } 1387 break; 1388 } 1389 1390 if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) 1391 log_rr(name, rdata, ttl); /* XXX */ 1392 1393 result = dns_message_gettempname(msg, &msgname); 1394 if (result != ISC_R_SUCCESS) 1395 goto failure; 1396 dns_name_init(msgname, NULL); 1397 isc_buffer_availableregion(&xfr->buf, &r); 1398 INSIST(r.length >= name->length); 1399 r.length = name->length; 1400 isc_buffer_putmem(&xfr->buf, name->ndata, name->length); 1401 dns_name_fromregion(msgname, &r); 1402 1403 /* Reserve space for RR header. */ 1404 isc_buffer_add(&xfr->buf, 10); 1405 1406 result = dns_message_gettemprdata(msg, &msgrdata); 1407 if (result != ISC_R_SUCCESS) 1408 goto failure; 1409 isc_buffer_availableregion(&xfr->buf, &r); 1410 r.length = rdata->length; 1411 isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); 1412 dns_rdata_init(msgrdata); 1413 dns_rdata_fromregion(msgrdata, 1414 rdata->rdclass, rdata->type, &r); 1415 1416 result = dns_message_gettemprdatalist(msg, &msgrdl); 1417 if (result != ISC_R_SUCCESS) 1418 goto failure; 1419 msgrdl->type = rdata->type; 1420 msgrdl->rdclass = rdata->rdclass; 1421 msgrdl->ttl = ttl; 1422 if (rdata->type == dns_rdatatype_sig || 1423 rdata->type == dns_rdatatype_rrsig) 1424 msgrdl->covers = dns_rdata_covers(rdata); 1425 else 1426 msgrdl->covers = dns_rdatatype_none; 1427 ISC_LINK_INIT(msgrdl, link); 1428 ISC_LIST_INIT(msgrdl->rdata); 1429 ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); 1430 1431 result = dns_message_gettemprdataset(msg, &msgrds); 1432 if (result != ISC_R_SUCCESS) 1433 goto failure; 1434 dns_rdataset_init(msgrds); 1435 result = dns_rdatalist_tordataset(msgrdl, msgrds); 1436 INSIST(result == ISC_R_SUCCESS); 1437 1438 ISC_LIST_APPEND(msgname->list, msgrds, link); 1439 1440 dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); 1441 msgname = NULL; 1442 1443 result = xfr->stream->methods->next(xfr->stream); 1444 if (result == ISC_R_NOMORE) { 1445 xfr->end_of_stream = ISC_TRUE; 1446 break; 1447 } 1448 CHECK(result); 1449 1450 if (! xfr->many_answers) 1451 break; 1452 } 1453 1454 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { 1455 CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); 1456 dns_compress_setsensitive(&cctx, ISC_TRUE); 1457 cleanup_cctx = ISC_TRUE; 1458 CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); 1459 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); 1460 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); 1461 CHECK(dns_message_renderend(msg)); 1462 dns_compress_invalidate(&cctx); 1463 cleanup_cctx = ISC_FALSE; 1464 1465 isc_buffer_usedregion(&xfr->txbuf, &used); 1466 isc_buffer_putuint16(&xfr->txlenbuf, 1467 (isc_uint16_t)used.length); 1468 region.base = xfr->txlenbuf.base; 1469 region.length = 2 + used.length; 1470 xfrout_log(xfr, ISC_LOG_DEBUG(8), 1471 "sending TCP message of %d bytes", 1472 used.length); 1473 CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ 1474 ®ion, xfr->client->task, 1475 xfrout_senddone, 1476 xfr)); 1477 xfr->sends++; 1478 } else { 1479 xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); 1480 ns_client_send(xfr->client); 1481 xfr->stream->methods->pause(xfr->stream); 1482 xfrout_ctx_destroy(&xfr); 1483 return; 1484 } 1485 1486 /* Advance lasttsig to be the last TSIG generated */ 1487 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); 1488 1489 xfr->nmsg++; 1490 1491 failure: 1492 if (msgname != NULL) { 1493 if (msgrds != NULL) { 1494 if (dns_rdataset_isassociated(msgrds)) 1495 dns_rdataset_disassociate(msgrds); 1496 dns_message_puttemprdataset(msg, &msgrds); 1497 } 1498 if (msgrdl != NULL) { 1499 ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); 1500 dns_message_puttemprdatalist(msg, &msgrdl); 1501 } 1502 if (msgrdata != NULL) 1503 dns_message_puttemprdata(msg, &msgrdata); 1504 dns_message_puttempname(msg, &msgname); 1505 } 1506 1507 if (tcpmsg != NULL) 1508 dns_message_destroy(&tcpmsg); 1509 1510 if (cleanup_cctx) 1511 dns_compress_invalidate(&cctx); 1512 /* 1513 * Make sure to release any locks held by database 1514 * iterators before returning from the event handler. 1515 */ 1516 xfr->stream->methods->pause(xfr->stream); 1517 1518 if (result == ISC_R_SUCCESS) 1519 return; 1520 1521 xfrout_fail(xfr, result, "sending zone data"); 1522} 1523 1524static void 1525xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { 1526 xfrout_ctx_t *xfr = *xfrp; 1527 ns_client_t *client = NULL; 1528 1529 INSIST(xfr->sends == 0); 1530 1531 xfr->client->shutdown = NULL; 1532 xfr->client->shutdown_arg = NULL; 1533 1534 if (xfr->stream != NULL) 1535 xfr->stream->methods->destroy(&xfr->stream); 1536 if (xfr->buf.base != NULL) 1537 isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); 1538 if (xfr->txmem != NULL) 1539 isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); 1540 if (xfr->lasttsig != NULL) 1541 isc_buffer_free(&xfr->lasttsig); 1542 if (xfr->quota != NULL) 1543 isc_quota_detach(&xfr->quota); 1544 if (xfr->ver != NULL) 1545 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); 1546 if (xfr->zone != NULL) 1547 dns_zone_detach(&xfr->zone); 1548 if (xfr->db != NULL) 1549 dns_db_detach(&xfr->db); 1550 1551 /* 1552 * We want to detch the client after we have released the memory 1553 * context as ns_client_detach checks the memory reference count. 1554 */ 1555 ns_client_attach(xfr->client, &client); 1556 ns_client_detach(&xfr->client); 1557 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); 1558 ns_client_detach(&client); 1559 1560 *xfrp = NULL; 1561} 1562 1563static void 1564xfrout_senddone(isc_task_t *task, isc_event_t *event) { 1565 isc_socketevent_t *sev = (isc_socketevent_t *)event; 1566 xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; 1567 isc_result_t evresult = sev->result; 1568 1569 UNUSED(task); 1570 1571 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); 1572 1573 isc_event_free(&event); 1574 xfr->sends--; 1575 INSIST(xfr->sends == 0); 1576 1577 (void)isc_timer_touch(xfr->client->timer); 1578 if (xfr->shuttingdown == ISC_TRUE) { 1579 xfrout_maybe_destroy(xfr); 1580 } else if (evresult != ISC_R_SUCCESS) { 1581 xfrout_fail(xfr, evresult, "send"); 1582 } else if (xfr->end_of_stream == ISC_FALSE) { 1583 sendstream(xfr); 1584 } else { 1585 /* End of zone transfer stream. */ 1586 inc_stats(xfr->zone, dns_nsstatscounter_xfrdone); 1587 xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); 1588 ns_client_next(xfr->client, ISC_R_SUCCESS); 1589 xfrout_ctx_destroy(&xfr); 1590 } 1591} 1592 1593static void 1594xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { 1595 xfr->shuttingdown = ISC_TRUE; 1596 xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", 1597 msg, isc_result_totext(result)); 1598 xfrout_maybe_destroy(xfr); 1599} 1600 1601static void 1602xfrout_maybe_destroy(xfrout_ctx_t *xfr) { 1603 INSIST(xfr->shuttingdown == ISC_TRUE); 1604 if (xfr->sends > 0) { 1605 /* 1606 * If we are currently sending, cancel it and wait for 1607 * cancel event before destroying the context. 1608 */ 1609 isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, 1610 ISC_SOCKCANCEL_SEND); 1611 } else { 1612 ns_client_next(xfr->client, ISC_R_CANCELED); 1613 xfrout_ctx_destroy(&xfr); 1614 } 1615} 1616 1617static void 1618xfrout_client_shutdown(void *arg, isc_result_t result) { 1619 xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; 1620 xfrout_fail(xfr, result, "aborted"); 1621} 1622 1623/* 1624 * Log outgoing zone transfer messages in a format like 1625 * <client>: transfer of <zone>: <message> 1626 */ 1627 1628static void 1629xfrout_logv(ns_client_t *client, dns_name_t *zonename, 1630 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) 1631 ISC_FORMAT_PRINTF(5, 0); 1632 1633static void 1634xfrout_logv(ns_client_t *client, dns_name_t *zonename, 1635 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) 1636{ 1637 char msgbuf[2048]; 1638 char namebuf[DNS_NAME_FORMATSIZE]; 1639 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 1640 1641 dns_name_format(zonename, namebuf, sizeof(namebuf)); 1642 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); 1643 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 1644 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, 1645 NS_LOGMODULE_XFER_OUT, level, 1646 "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); 1647} 1648 1649/* 1650 * Logging function for use when a xfrout_ctx_t has not yet been created. 1651 */ 1652static void 1653xfrout_log1(ns_client_t *client, dns_name_t *zonename, 1654 dns_rdataclass_t rdclass, int level, const char *fmt, ...) { 1655 va_list ap; 1656 va_start(ap, fmt); 1657 xfrout_logv(client, zonename, rdclass, level, fmt, ap); 1658 va_end(ap); 1659} 1660 1661/* 1662 * Logging function for use when there is a xfrout_ctx_t. 1663 */ 1664static void 1665xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { 1666 va_list ap; 1667 va_start(ap, fmt); 1668 xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); 1669 va_end(ap); 1670} 1671