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