xfrout.c revision 224092
1/* 2 * Copyright (C) 2004-2010 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: xfrout.c,v 1.139 2010-12-18 01:56:19 each Exp $ */ 19 20#include <config.h> 21 22#include <isc/formatcheck.h> 23#include <isc/mem.h> 24#include <isc/timer.h> 25#include <isc/print.h> 26#include <isc/stats.h> 27#include <isc/util.h> 28 29#include <dns/db.h> 30#include <dns/dbiterator.h> 31#ifdef DLZ 32#include <dns/dlz.h> 33#endif 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 (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 (0) 109 110#define CHECK(op) \ 111 do { result = (op); \ 112 if (result != ISC_R_SUCCESS) goto failure; \ 113 } while (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 ISC_FALSE, &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#ifdef DLZ 756 isc_boolean_t is_dlz = ISC_FALSE; 757#endif 758 759 switch (reqtype) { 760 case dns_rdatatype_axfr: 761 mnemonic = "AXFR"; 762 break; 763 case dns_rdatatype_ixfr: 764 mnemonic = "IXFR"; 765 break; 766 default: 767 INSIST(0); 768 break; 769 } 770 771 ns_client_log(client, 772 DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, 773 ISC_LOG_DEBUG(6), "%s request", mnemonic); 774 /* 775 * Apply quota. 776 */ 777 result = isc_quota_attach(&ns_g_server->xfroutquota, "a); 778 if (result != ISC_R_SUCCESS) { 779 isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, 780 "%s request denied: %s", mnemonic, 781 isc_result_totext(result)); 782 goto failure; 783 } 784 785 /* 786 * Interpret the question section. 787 */ 788 result = dns_message_firstname(request, DNS_SECTION_QUESTION); 789 INSIST(result == ISC_R_SUCCESS); 790 791 /* 792 * The question section must contain exactly one question, and 793 * it must be for AXFR/IXFR as appropriate. 794 */ 795 question_name = NULL; 796 dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); 797 question_rdataset = ISC_LIST_HEAD(question_name->list); 798 question_class = question_rdataset->rdclass; 799 INSIST(question_rdataset->type == reqtype); 800 if (ISC_LIST_NEXT(question_rdataset, link) != NULL) 801 FAILC(DNS_R_FORMERR, "multiple questions"); 802 result = dns_message_nextname(request, DNS_SECTION_QUESTION); 803 if (result != ISC_R_NOMORE) 804 FAILC(DNS_R_FORMERR, "multiple questions"); 805 806 result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, 807 &zone); 808 809 if (result != ISC_R_SUCCESS) 810#ifdef DLZ 811 { 812 /* 813 * Normal zone table does not have a match. 814 * Try the DLZ database 815 */ 816 if (client->view->dlzdatabase != NULL) { 817 result = dns_dlzallowzonexfr(client->view, 818 question_name, 819 &client->peeraddr, 820 &db); 821 822 if (result == ISC_R_NOPERM) { 823 char _buf1[DNS_NAME_FORMATSIZE]; 824 char _buf2[DNS_RDATACLASS_FORMATSIZE]; 825 826 result = DNS_R_REFUSED; 827 dns_name_format(question_name, _buf1, 828 sizeof(_buf1)); 829 dns_rdataclass_format(question_class, 830 _buf2, sizeof(_buf2)); 831 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 832 NS_LOGMODULE_XFER_OUT, 833 ISC_LOG_ERROR, 834 "zone transfer '%s/%s' denied", 835 _buf1, _buf2); 836 goto failure; 837 } 838 if (result != ISC_R_SUCCESS) 839#endif 840 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 841 question_name, question_class); 842#ifdef DLZ 843 is_dlz = ISC_TRUE; 844 /* 845 * DLZ only support full zone transfer, not incremental 846 */ 847 if (reqtype != dns_rdatatype_axfr) { 848 mnemonic = "AXFR-style IXFR"; 849 reqtype = dns_rdatatype_axfr; 850 } 851 852 } else { 853 /* 854 * not DLZ and not in normal zone table, we are 855 * not authoritative 856 */ 857 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 858 question_name, question_class); 859 } 860 } else { 861 /* zone table has a match */ 862#endif 863 switch(dns_zone_gettype(zone)) { 864 case dns_zone_master: 865 case dns_zone_slave: 866 case dns_zone_dlz: 867 break; /* Master and slave zones are OK for transfer. */ 868 default: 869 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); 870 } 871 CHECK(dns_zone_getdb(zone, &db)); 872 dns_db_currentversion(db, &ver); 873#ifdef DLZ 874 } 875#endif 876 877 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), 878 "%s question section OK", mnemonic); 879 880 /* 881 * Check the authority section. Look for a SOA record with 882 * the same name and class as the question. 883 */ 884 for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); 885 result == ISC_R_SUCCESS; 886 result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) 887 { 888 soa_name = NULL; 889 dns_message_currentname(request, DNS_SECTION_AUTHORITY, 890 &soa_name); 891 892 /* 893 * Ignore data whose owner name is not the zone apex. 894 */ 895 if (! dns_name_equal(soa_name, question_name)) 896 continue; 897 898 for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); 899 soa_rdataset != NULL; 900 soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) 901 { 902 /* 903 * Ignore non-SOA data. 904 */ 905 if (soa_rdataset->type != dns_rdatatype_soa) 906 continue; 907 if (soa_rdataset->rdclass != question_class) 908 continue; 909 910 CHECK(dns_rdataset_first(soa_rdataset)); 911 dns_rdataset_current(soa_rdataset, &soa_rdata); 912 result = dns_rdataset_next(soa_rdataset); 913 if (result == ISC_R_SUCCESS) 914 FAILC(DNS_R_FORMERR, 915 "IXFR authority section " 916 "has multiple SOAs"); 917 have_soa = ISC_TRUE; 918 goto got_soa; 919 } 920 } 921 got_soa: 922 if (result != ISC_R_NOMORE) 923 CHECK(result); 924 925 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), 926 "%s authority section OK", mnemonic); 927 928 /* 929 * Decide whether to allow this transfer. 930 */ 931#ifdef DLZ 932 /* 933 * if not a DLZ zone decide whether to allow this transfer. 934 */ 935 if (!is_dlz) { 936#endif 937 ns_client_aclmsg("zone transfer", question_name, reqtype, 938 client->view->rdclass, msg, sizeof(msg)); 939 CHECK(ns_client_checkacl(client, NULL, msg, 940 dns_zone_getxfracl(zone), 941 ISC_TRUE, ISC_LOG_ERROR)); 942#ifdef DLZ 943 } 944#endif 945 946 /* 947 * AXFR over UDP is not possible. 948 */ 949 if (reqtype == dns_rdatatype_axfr && 950 (client->attributes & NS_CLIENTATTR_TCP) == 0) 951 FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); 952 953 /* 954 * Look up the requesting server in the peer table. 955 */ 956 isc_netaddr_fromsockaddr(&na, &client->peeraddr); 957 (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); 958 959 /* 960 * Decide on the transfer format (one-answer or many-answers). 961 */ 962 if (peer != NULL) 963 (void)dns_peer_gettransferformat(peer, &format); 964 965 /* 966 * Get a dynamically allocated copy of the current SOA. 967 */ 968#ifdef DLZ 969 if (is_dlz) 970 dns_db_currentversion(db, &ver); 971#endif 972 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, 973 ¤t_soa_tuple)); 974 975 if (reqtype == dns_rdatatype_ixfr) { 976 isc_uint32_t begin_serial, current_serial; 977 isc_boolean_t provide_ixfr; 978 979 /* 980 * Outgoing IXFR may have been disabled for this peer 981 * or globally. 982 */ 983 provide_ixfr = client->view->provideixfr; 984 if (peer != NULL) 985 (void) dns_peer_getprovideixfr(peer, &provide_ixfr); 986 if (provide_ixfr == ISC_FALSE) 987 goto axfr_fallback; 988 989 if (! have_soa) 990 FAILC(DNS_R_FORMERR, 991 "IXFR request missing SOA"); 992 993 begin_serial = dns_soa_getserial(&soa_rdata); 994 current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); 995 996 /* 997 * RFC1995 says "If an IXFR query with the same or 998 * newer version number than that of the server 999 * is received, it is replied to with a single SOA 1000 * record of the server's current version, just as 1001 * in AXFR". The claim about AXFR is incorrect, 1002 * but other than that, we do as the RFC says. 1003 * 1004 * Sending a single SOA record is also how we refuse 1005 * IXFR over UDP (currently, we always do). 1006 */ 1007 if (DNS_SERIAL_GE(begin_serial, current_serial) || 1008 (client->attributes & NS_CLIENTATTR_TCP) == 0) 1009 { 1010 CHECK(soa_rrstream_create(mctx, db, ver, &stream)); 1011 is_poll = ISC_TRUE; 1012 goto have_stream; 1013 } 1014 journalfile = dns_zone_getjournal(zone); 1015 if (journalfile != NULL) 1016 result = ixfr_rrstream_create(mctx, 1017 journalfile, 1018 begin_serial, 1019 current_serial, 1020 &data_stream); 1021 else 1022 result = ISC_R_NOTFOUND; 1023 if (result == ISC_R_NOTFOUND || 1024 result == ISC_R_RANGE) { 1025 xfrout_log1(client, question_name, question_class, 1026 ISC_LOG_DEBUG(4), 1027 "IXFR version not in journal, " 1028 "falling back to AXFR"); 1029 mnemonic = "AXFR-style IXFR"; 1030 goto axfr_fallback; 1031 } 1032 CHECK(result); 1033 } else { 1034 axfr_fallback: 1035 CHECK(axfr_rrstream_create(mctx, db, ver, 1036 &data_stream)); 1037 } 1038 1039 /* 1040 * Bracket the data stream with SOAs. 1041 */ 1042 CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); 1043 CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, 1044 &stream)); 1045 soa_stream = NULL; 1046 data_stream = NULL; 1047 1048 have_stream: 1049 CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); 1050 /* 1051 * Create the xfrout context object. This transfers the ownership 1052 * of "stream", "db", "ver", and "quota" to the xfrout context object. 1053 */ 1054 1055 1056 1057#ifdef DLZ 1058 if (is_dlz) 1059 CHECK(xfrout_ctx_create(mctx, client, request->id, 1060 question_name, reqtype, question_class, 1061 zone, db, ver, quota, stream, 1062 dns_message_gettsigkey(request), 1063 tsigbuf, 1064 3600, 1065 3600, 1066 (format == dns_many_answers) ? 1067 ISC_TRUE : ISC_FALSE, 1068 &xfr)); 1069 else 1070#endif 1071 CHECK(xfrout_ctx_create(mctx, client, request->id, 1072 question_name, reqtype, question_class, 1073 zone, db, ver, quota, stream, 1074 dns_message_gettsigkey(request), 1075 tsigbuf, 1076 dns_zone_getmaxxfrout(zone), 1077 dns_zone_getidleout(zone), 1078 (format == dns_many_answers) ? 1079 ISC_TRUE : ISC_FALSE, 1080 &xfr)); 1081 1082 xfr->mnemonic = mnemonic; 1083 stream = NULL; 1084 quota = NULL; 1085 1086 CHECK(xfr->stream->methods->first(xfr->stream)); 1087 1088 if (xfr->tsigkey != NULL) { 1089 dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); 1090 } else 1091 keyname[0] = '\0'; 1092 if (is_poll) 1093 xfrout_log1(client, question_name, question_class, 1094 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", 1095 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); 1096 else 1097 xfrout_log1(client, question_name, question_class, 1098 ISC_LOG_INFO, "%s started%s%s", mnemonic, 1099 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); 1100 1101 /* 1102 * Hand the context over to sendstream(). Set xfr to NULL; 1103 * sendstream() is responsible for either passing the 1104 * context on to a later event handler or destroying it. 1105 */ 1106 sendstream(xfr); 1107 xfr = NULL; 1108 1109 result = ISC_R_SUCCESS; 1110 1111 failure: 1112 if (result == DNS_R_REFUSED) 1113 inc_stats(zone, dns_nsstatscounter_xfrrej); 1114 if (quota != NULL) 1115 isc_quota_detach("a); 1116 if (current_soa_tuple != NULL) 1117 dns_difftuple_free(¤t_soa_tuple); 1118 if (stream != NULL) 1119 stream->methods->destroy(&stream); 1120 if (soa_stream != NULL) 1121 soa_stream->methods->destroy(&soa_stream); 1122 if (data_stream != NULL) 1123 data_stream->methods->destroy(&data_stream); 1124 if (ver != NULL) 1125 dns_db_closeversion(db, &ver, ISC_FALSE); 1126 if (db != NULL) 1127 dns_db_detach(&db); 1128 if (zone != NULL) 1129 dns_zone_detach(&zone); 1130 /* XXX kludge */ 1131 if (xfr != NULL) { 1132 xfrout_fail(xfr, result, "setting up zone transfer"); 1133 } else if (result != ISC_R_SUCCESS) { 1134 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, 1135 NS_LOGMODULE_XFER_OUT, 1136 ISC_LOG_DEBUG(3), "zone transfer setup failed"); 1137 ns_client_error(client, result); 1138 } 1139} 1140 1141static isc_result_t 1142xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, 1143 dns_name_t *qname, dns_rdatatype_t qtype, 1144 dns_rdataclass_t qclass, dns_zone_t *zone, 1145 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, 1146 rrstream_t *stream, dns_tsigkey_t *tsigkey, 1147 isc_buffer_t *lasttsig, unsigned int maxtime, 1148 unsigned int idletime, isc_boolean_t many_answers, 1149 xfrout_ctx_t **xfrp) 1150{ 1151 xfrout_ctx_t *xfr; 1152 isc_result_t result; 1153 unsigned int len; 1154 void *mem; 1155 1156 INSIST(xfrp != NULL && *xfrp == NULL); 1157 xfr = isc_mem_get(mctx, sizeof(*xfr)); 1158 if (xfr == NULL) 1159 return (ISC_R_NOMEMORY); 1160 xfr->mctx = mctx; 1161 xfr->client = NULL; 1162 ns_client_attach(client, &xfr->client); 1163 xfr->id = id; 1164 xfr->qname = qname; 1165 xfr->qtype = qtype; 1166 xfr->qclass = qclass; 1167 xfr->zone = NULL; 1168 xfr->db = NULL; 1169 xfr->ver = NULL; 1170 if (zone != NULL) /* zone will be NULL if it's DLZ */ 1171 dns_zone_attach(zone, &xfr->zone); 1172 dns_db_attach(db, &xfr->db); 1173 dns_db_attachversion(db, ver, &xfr->ver); 1174 xfr->end_of_stream = ISC_FALSE; 1175 xfr->tsigkey = tsigkey; 1176 xfr->lasttsig = lasttsig; 1177 xfr->txmem = NULL; 1178 xfr->txmemlen = 0; 1179 xfr->nmsg = 0; 1180 xfr->many_answers = many_answers, 1181 xfr->sends = 0; 1182 xfr->shuttingdown = ISC_FALSE; 1183 xfr->mnemonic = NULL; 1184 xfr->buf.base = NULL; 1185 xfr->buf.length = 0; 1186 xfr->txmem = NULL; 1187 xfr->txmemlen = 0; 1188 xfr->stream = NULL; 1189 xfr->quota = NULL; 1190 1191 /* 1192 * Allocate a temporary buffer for the uncompressed response 1193 * message data. The size should be no more than 65535 bytes 1194 * so that the compressed data will fit in a TCP message, 1195 * and no less than 65535 bytes so that an almost maximum-sized 1196 * RR will fit. Note that although 65535-byte RRs are allowed 1197 * in principle, they cannot be zone-transferred (at least not 1198 * if uncompressible), because the message and RR headers would 1199 * push the size of the TCP message over the 65536 byte limit. 1200 */ 1201 len = 65535; 1202 mem = isc_mem_get(mctx, len); 1203 if (mem == NULL) { 1204 result = ISC_R_NOMEMORY; 1205 goto failure; 1206 } 1207 isc_buffer_init(&xfr->buf, mem, len); 1208 1209 /* 1210 * Allocate another temporary buffer for the compressed 1211 * response message and its TCP length prefix. 1212 */ 1213 len = 2 + 65535; 1214 mem = isc_mem_get(mctx, len); 1215 if (mem == NULL) { 1216 result = ISC_R_NOMEMORY; 1217 goto failure; 1218 } 1219 isc_buffer_init(&xfr->txlenbuf, mem, 2); 1220 isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); 1221 xfr->txmem = mem; 1222 xfr->txmemlen = len; 1223 1224 CHECK(dns_timer_setidle(xfr->client->timer, 1225 maxtime, idletime, ISC_FALSE)); 1226 1227 /* 1228 * Register a shutdown callback with the client, so that we 1229 * can stop the transfer immediately when the client task 1230 * gets a shutdown event. 1231 */ 1232 xfr->client->shutdown = xfrout_client_shutdown; 1233 xfr->client->shutdown_arg = xfr; 1234 /* 1235 * These MUST be after the last "goto failure;" / CHECK to 1236 * prevent a double free by the caller. 1237 */ 1238 xfr->quota = quota; 1239 xfr->stream = stream; 1240 1241 *xfrp = xfr; 1242 return (ISC_R_SUCCESS); 1243 1244failure: 1245 xfrout_ctx_destroy(&xfr); 1246 return (result); 1247} 1248 1249 1250/* 1251 * Arrange to send as much as we can of "stream" without blocking. 1252 * 1253 * Requires: 1254 * The stream iterator is initialized and points at an RR, 1255 * or possibly at the end of the stream (that is, the 1256 * _first method of the iterator has been called). 1257 */ 1258static void 1259sendstream(xfrout_ctx_t *xfr) { 1260 dns_message_t *tcpmsg = NULL; 1261 dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ 1262 isc_result_t result; 1263 isc_region_t used; 1264 isc_region_t region; 1265 dns_rdataset_t *qrdataset; 1266 dns_name_t *msgname = NULL; 1267 dns_rdata_t *msgrdata = NULL; 1268 dns_rdatalist_t *msgrdl = NULL; 1269 dns_rdataset_t *msgrds = NULL; 1270 dns_compress_t cctx; 1271 isc_boolean_t cleanup_cctx = ISC_FALSE; 1272 1273 int n_rrs; 1274 1275 isc_buffer_clear(&xfr->buf); 1276 isc_buffer_clear(&xfr->txlenbuf); 1277 isc_buffer_clear(&xfr->txbuf); 1278 1279 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) { 1280 /* 1281 * In the UDP case, we put the response data directly into 1282 * the client message. 1283 */ 1284 msg = xfr->client->message; 1285 CHECK(dns_message_reply(msg, ISC_TRUE)); 1286 } else { 1287 /* 1288 * TCP. Build a response dns_message_t, temporarily storing 1289 * the raw, uncompressed owner names and RR data contiguously 1290 * in xfr->buf. We know that if the uncompressed data fits 1291 * in xfr->buf, the compressed data will surely fit in a TCP 1292 * message. 1293 */ 1294 1295 CHECK(dns_message_create(xfr->mctx, 1296 DNS_MESSAGE_INTENTRENDER, &tcpmsg)); 1297 msg = tcpmsg; 1298 1299 msg->id = xfr->id; 1300 msg->rcode = dns_rcode_noerror; 1301 msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; 1302 if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) 1303 msg->flags |= DNS_MESSAGEFLAG_RA; 1304 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1305 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); 1306 if (xfr->lasttsig != NULL) 1307 isc_buffer_free(&xfr->lasttsig); 1308 1309 /* 1310 * Include a question section in the first message only. 1311 * BIND 8.2.1 will not recognize an IXFR if it does not 1312 * have a question section. 1313 */ 1314 if (xfr->nmsg == 0) { 1315 dns_name_t *qname = NULL; 1316 isc_region_t r; 1317 1318 /* 1319 * Reserve space for the 12-byte message header 1320 * and 4 bytes of question. 1321 */ 1322 isc_buffer_add(&xfr->buf, 12 + 4); 1323 1324 qrdataset = NULL; 1325 result = dns_message_gettemprdataset(msg, &qrdataset); 1326 if (result != ISC_R_SUCCESS) 1327 goto failure; 1328 dns_rdataset_init(qrdataset); 1329 dns_rdataset_makequestion(qrdataset, 1330 xfr->client->message->rdclass, 1331 xfr->qtype); 1332 1333 result = dns_message_gettempname(msg, &qname); 1334 if (result != ISC_R_SUCCESS) 1335 goto failure; 1336 dns_name_init(qname, NULL); 1337 isc_buffer_availableregion(&xfr->buf, &r); 1338 INSIST(r.length >= xfr->qname->length); 1339 r.length = xfr->qname->length; 1340 isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, 1341 xfr->qname->length); 1342 dns_name_fromregion(qname, &r); 1343 ISC_LIST_INIT(qname->list); 1344 ISC_LIST_APPEND(qname->list, qrdataset, link); 1345 1346 dns_message_addname(msg, qname, DNS_SECTION_QUESTION); 1347 } 1348 else 1349 msg->tcp_continuation = 1; 1350 } 1351 1352 /* 1353 * Try to fit in as many RRs as possible, unless "one-answer" 1354 * format has been requested. 1355 */ 1356 for (n_rrs = 0; ; n_rrs++) { 1357 dns_name_t *name = NULL; 1358 isc_uint32_t ttl; 1359 dns_rdata_t *rdata = NULL; 1360 1361 unsigned int size; 1362 isc_region_t r; 1363 1364 msgname = NULL; 1365 msgrdata = NULL; 1366 msgrdl = NULL; 1367 msgrds = NULL; 1368 1369 xfr->stream->methods->current(xfr->stream, 1370 &name, &ttl, &rdata); 1371 size = name->length + 10 + rdata->length; 1372 isc_buffer_availableregion(&xfr->buf, &r); 1373 if (size >= r.length) { 1374 /* 1375 * RR would not fit. If there are other RRs in the 1376 * buffer, send them now and leave this RR to the 1377 * next message. If this RR overflows the buffer 1378 * all by itself, fail. 1379 * 1380 * In theory some RRs might fit in a TCP message 1381 * when compressed even if they do not fit when 1382 * uncompressed, but surely we don't want 1383 * to send such monstrosities to an unsuspecting 1384 * slave. 1385 */ 1386 if (n_rrs == 0) { 1387 xfrout_log(xfr, ISC_LOG_WARNING, 1388 "RR too large for zone transfer " 1389 "(%d bytes)", size); 1390 /* XXX DNS_R_RRTOOLARGE? */ 1391 result = ISC_R_NOSPACE; 1392 goto failure; 1393 } 1394 break; 1395 } 1396 1397 if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) 1398 log_rr(name, rdata, ttl); /* XXX */ 1399 1400 result = dns_message_gettempname(msg, &msgname); 1401 if (result != ISC_R_SUCCESS) 1402 goto failure; 1403 dns_name_init(msgname, NULL); 1404 isc_buffer_availableregion(&xfr->buf, &r); 1405 INSIST(r.length >= name->length); 1406 r.length = name->length; 1407 isc_buffer_putmem(&xfr->buf, name->ndata, name->length); 1408 dns_name_fromregion(msgname, &r); 1409 1410 /* Reserve space for RR header. */ 1411 isc_buffer_add(&xfr->buf, 10); 1412 1413 result = dns_message_gettemprdata(msg, &msgrdata); 1414 if (result != ISC_R_SUCCESS) 1415 goto failure; 1416 isc_buffer_availableregion(&xfr->buf, &r); 1417 r.length = rdata->length; 1418 isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); 1419 dns_rdata_init(msgrdata); 1420 dns_rdata_fromregion(msgrdata, 1421 rdata->rdclass, rdata->type, &r); 1422 1423 result = dns_message_gettemprdatalist(msg, &msgrdl); 1424 if (result != ISC_R_SUCCESS) 1425 goto failure; 1426 msgrdl->type = rdata->type; 1427 msgrdl->rdclass = rdata->rdclass; 1428 msgrdl->ttl = ttl; 1429 if (rdata->type == dns_rdatatype_sig || 1430 rdata->type == dns_rdatatype_rrsig) 1431 msgrdl->covers = dns_rdata_covers(rdata); 1432 else 1433 msgrdl->covers = dns_rdatatype_none; 1434 ISC_LINK_INIT(msgrdl, link); 1435 ISC_LIST_INIT(msgrdl->rdata); 1436 ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); 1437 1438 result = dns_message_gettemprdataset(msg, &msgrds); 1439 if (result != ISC_R_SUCCESS) 1440 goto failure; 1441 dns_rdataset_init(msgrds); 1442 result = dns_rdatalist_tordataset(msgrdl, msgrds); 1443 INSIST(result == ISC_R_SUCCESS); 1444 1445 ISC_LIST_APPEND(msgname->list, msgrds, link); 1446 1447 dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); 1448 msgname = NULL; 1449 1450 result = xfr->stream->methods->next(xfr->stream); 1451 if (result == ISC_R_NOMORE) { 1452 xfr->end_of_stream = ISC_TRUE; 1453 break; 1454 } 1455 CHECK(result); 1456 1457 if (! xfr->many_answers) 1458 break; 1459 } 1460 1461 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { 1462 CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); 1463 dns_compress_setsensitive(&cctx, ISC_TRUE); 1464 cleanup_cctx = ISC_TRUE; 1465 CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); 1466 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); 1467 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); 1468 CHECK(dns_message_renderend(msg)); 1469 dns_compress_invalidate(&cctx); 1470 cleanup_cctx = ISC_FALSE; 1471 1472 isc_buffer_usedregion(&xfr->txbuf, &used); 1473 isc_buffer_putuint16(&xfr->txlenbuf, 1474 (isc_uint16_t)used.length); 1475 region.base = xfr->txlenbuf.base; 1476 region.length = 2 + used.length; 1477 xfrout_log(xfr, ISC_LOG_DEBUG(8), 1478 "sending TCP message of %d bytes", 1479 used.length); 1480 CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ 1481 ®ion, xfr->client->task, 1482 xfrout_senddone, 1483 xfr)); 1484 xfr->sends++; 1485 } else { 1486 xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); 1487 ns_client_send(xfr->client); 1488 xfr->stream->methods->pause(xfr->stream); 1489 xfrout_ctx_destroy(&xfr); 1490 return; 1491 } 1492 1493 /* Advance lasttsig to be the last TSIG generated */ 1494 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); 1495 1496 xfr->nmsg++; 1497 1498 failure: 1499 if (msgname != NULL) { 1500 if (msgrds != NULL) { 1501 if (dns_rdataset_isassociated(msgrds)) 1502 dns_rdataset_disassociate(msgrds); 1503 dns_message_puttemprdataset(msg, &msgrds); 1504 } 1505 if (msgrdl != NULL) { 1506 ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); 1507 dns_message_puttemprdatalist(msg, &msgrdl); 1508 } 1509 if (msgrdata != NULL) 1510 dns_message_puttemprdata(msg, &msgrdata); 1511 dns_message_puttempname(msg, &msgname); 1512 } 1513 1514 if (tcpmsg != NULL) 1515 dns_message_destroy(&tcpmsg); 1516 1517 if (cleanup_cctx) 1518 dns_compress_invalidate(&cctx); 1519 /* 1520 * Make sure to release any locks held by database 1521 * iterators before returning from the event handler. 1522 */ 1523 xfr->stream->methods->pause(xfr->stream); 1524 1525 if (result == ISC_R_SUCCESS) 1526 return; 1527 1528 xfrout_fail(xfr, result, "sending zone data"); 1529} 1530 1531static void 1532xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { 1533 xfrout_ctx_t *xfr = *xfrp; 1534 1535 INSIST(xfr->sends == 0); 1536 1537 xfr->client->shutdown = NULL; 1538 xfr->client->shutdown_arg = NULL; 1539 1540 if (xfr->stream != NULL) 1541 xfr->stream->methods->destroy(&xfr->stream); 1542 if (xfr->buf.base != NULL) 1543 isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); 1544 if (xfr->txmem != NULL) 1545 isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); 1546 if (xfr->lasttsig != NULL) 1547 isc_buffer_free(&xfr->lasttsig); 1548 if (xfr->quota != NULL) 1549 isc_quota_detach(&xfr->quota); 1550 if (xfr->ver != NULL) 1551 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); 1552 if (xfr->zone != NULL) 1553 dns_zone_detach(&xfr->zone); 1554 if (xfr->db != NULL) 1555 dns_db_detach(&xfr->db); 1556 1557 ns_client_detach(&xfr->client); 1558 1559 isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); 1560 1561 *xfrp = NULL; 1562} 1563 1564static void 1565xfrout_senddone(isc_task_t *task, isc_event_t *event) { 1566 isc_socketevent_t *sev = (isc_socketevent_t *)event; 1567 xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; 1568 isc_result_t evresult = sev->result; 1569 1570 UNUSED(task); 1571 1572 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); 1573 1574 isc_event_free(&event); 1575 xfr->sends--; 1576 INSIST(xfr->sends == 0); 1577 1578 (void)isc_timer_touch(xfr->client->timer); 1579 if (xfr->shuttingdown == ISC_TRUE) { 1580 xfrout_maybe_destroy(xfr); 1581 } else if (evresult != ISC_R_SUCCESS) { 1582 xfrout_fail(xfr, evresult, "send"); 1583 } else if (xfr->end_of_stream == ISC_FALSE) { 1584 sendstream(xfr); 1585 } else { 1586 /* End of zone transfer stream. */ 1587 inc_stats(xfr->zone, dns_nsstatscounter_xfrdone); 1588 xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); 1589 ns_client_next(xfr->client, ISC_R_SUCCESS); 1590 xfrout_ctx_destroy(&xfr); 1591 } 1592} 1593 1594static void 1595xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { 1596 xfr->shuttingdown = ISC_TRUE; 1597 xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", 1598 msg, isc_result_totext(result)); 1599 xfrout_maybe_destroy(xfr); 1600} 1601 1602static void 1603xfrout_maybe_destroy(xfrout_ctx_t *xfr) { 1604 INSIST(xfr->shuttingdown == ISC_TRUE); 1605 if (xfr->sends > 0) { 1606 /* 1607 * If we are currently sending, cancel it and wait for 1608 * cancel event before destroying the context. 1609 */ 1610 isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, 1611 ISC_SOCKCANCEL_SEND); 1612 } else { 1613 ns_client_next(xfr->client, ISC_R_CANCELED); 1614 xfrout_ctx_destroy(&xfr); 1615 } 1616} 1617 1618static void 1619xfrout_client_shutdown(void *arg, isc_result_t result) { 1620 xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; 1621 xfrout_fail(xfr, result, "aborted"); 1622} 1623 1624/* 1625 * Log outgoing zone transfer messages in a format like 1626 * <client>: transfer of <zone>: <message> 1627 */ 1628 1629static void 1630xfrout_logv(ns_client_t *client, dns_name_t *zonename, 1631 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) 1632 ISC_FORMAT_PRINTF(5, 0); 1633 1634static void 1635xfrout_logv(ns_client_t *client, dns_name_t *zonename, 1636 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) 1637{ 1638 char msgbuf[2048]; 1639 char namebuf[DNS_NAME_FORMATSIZE]; 1640 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 1641 1642 dns_name_format(zonename, namebuf, sizeof(namebuf)); 1643 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); 1644 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 1645 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, 1646 NS_LOGMODULE_XFER_OUT, level, 1647 "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); 1648} 1649 1650/* 1651 * Logging function for use when a xfrout_ctx_t has not yet been created. 1652 */ 1653static void 1654xfrout_log1(ns_client_t *client, dns_name_t *zonename, 1655 dns_rdataclass_t rdclass, int level, const char *fmt, ...) { 1656 va_list ap; 1657 va_start(ap, fmt); 1658 xfrout_logv(client, zonename, rdclass, level, fmt, ap); 1659 va_end(ap); 1660} 1661 1662/* 1663 * Logging function for use when there is a xfrout_ctx_t. 1664 */ 1665static void 1666xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { 1667 va_list ap; 1668 va_start(ap, fmt); 1669 xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); 1670 va_end(ap); 1671} 1672