xfrout.c revision 254897
1/* 2 * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20#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 = NULL; 251 isc_mem_attach(mctx, &s->common.mctx); 252 s->common.methods = &ixfr_rrstream_methods; 253 s->journal = NULL; 254 255 CHECK(dns_journal_open(mctx, journal_filename, 256 DNS_JOURNAL_READ, &s->journal)); 257 CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); 258 259 *sp = (rrstream_t *) s; 260 return (ISC_R_SUCCESS); 261 262 failure: 263 ixfr_rrstream_destroy((rrstream_t **) (void *)&s); 264 return (result); 265} 266 267static isc_result_t 268ixfr_rrstream_first(rrstream_t *rs) { 269 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; 270 return (dns_journal_first_rr(s->journal)); 271} 272 273static isc_result_t 274ixfr_rrstream_next(rrstream_t *rs) { 275 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; 276 return (dns_journal_next_rr(s->journal)); 277} 278 279static void 280ixfr_rrstream_current(rrstream_t *rs, 281 dns_name_t **name, isc_uint32_t *ttl, 282 dns_rdata_t **rdata) 283{ 284 ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; 285 dns_journal_current_rr(s->journal, name, ttl, rdata); 286} 287 288static void 289ixfr_rrstream_destroy(rrstream_t **rsp) { 290 ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; 291 if (s->journal != 0) 292 dns_journal_destroy(&s->journal); 293 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); 294} 295 296static rrstream_methods_t ixfr_rrstream_methods = { 297 ixfr_rrstream_first, 298 ixfr_rrstream_next, 299 ixfr_rrstream_current, 300 rrstream_noop_pause, 301 ixfr_rrstream_destroy 302}; 303 304/**************************************************************************/ 305/* 306 * An 'axfr_rrstream_t' is an 'rrstream_t' that returns 307 * an AXFR-like RR stream from a database. 308 * 309 * The SOAs at the beginning and end of the transfer are 310 * not included in the stream. 311 */ 312 313typedef struct axfr_rrstream { 314 rrstream_t common; 315 dns_rriterator_t it; 316 isc_boolean_t it_valid; 317} axfr_rrstream_t; 318 319/* 320 * Forward declarations. 321 */ 322static void 323axfr_rrstream_destroy(rrstream_t **rsp); 324 325static rrstream_methods_t axfr_rrstream_methods; 326 327static isc_result_t 328axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, 329 rrstream_t **sp) 330{ 331 axfr_rrstream_t *s; 332 isc_result_t result; 333 334 INSIST(sp != NULL && *sp == NULL); 335 336 s = isc_mem_get(mctx, sizeof(*s)); 337 if (s == NULL) 338 return (ISC_R_NOMEMORY); 339 s->common.mctx = NULL; 340 isc_mem_attach(mctx, &s->common.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_putanddetach(&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 = NULL; 461 isc_mem_attach(mctx, &s->common.mctx); 462 s->common.methods = &soa_rrstream_methods; 463 s->soa_tuple = NULL; 464 465 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, 466 &s->soa_tuple)); 467 468 *sp = (rrstream_t *) s; 469 return (ISC_R_SUCCESS); 470 471 failure: 472 soa_rrstream_destroy((rrstream_t **) (void *)&s); 473 return (result); 474} 475 476static isc_result_t 477soa_rrstream_first(rrstream_t *rs) { 478 UNUSED(rs); 479 return (ISC_R_SUCCESS); 480} 481 482static isc_result_t 483soa_rrstream_next(rrstream_t *rs) { 484 UNUSED(rs); 485 return (ISC_R_NOMORE); 486} 487 488static void 489soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, 490 dns_rdata_t **rdata) 491{ 492 soa_rrstream_t *s = (soa_rrstream_t *) rs; 493 *name = &s->soa_tuple->name; 494 *ttl = s->soa_tuple->ttl; 495 *rdata = &s->soa_tuple->rdata; 496} 497 498static void 499soa_rrstream_destroy(rrstream_t **rsp) { 500 soa_rrstream_t *s = (soa_rrstream_t *) *rsp; 501 if (s->soa_tuple != NULL) 502 dns_difftuple_free(&s->soa_tuple); 503 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); 504} 505 506static rrstream_methods_t soa_rrstream_methods = { 507 soa_rrstream_first, 508 soa_rrstream_next, 509 soa_rrstream_current, 510 rrstream_noop_pause, 511 soa_rrstream_destroy 512}; 513 514/**************************************************************************/ 515/* 516 * A 'compound_rrstream_t' objects owns a soa_rrstream 517 * and another rrstream, the "data stream". It returns 518 * a concatenated stream consisting of the soa_rrstream, then 519 * the data stream, then the soa_rrstream again. 520 * 521 * The component streams are owned by the compound_rrstream_t 522 * and are destroyed with it. 523 */ 524 525typedef struct compound_rrstream { 526 rrstream_t common; 527 rrstream_t *components[3]; 528 int state; 529 isc_result_t result; 530} compound_rrstream_t; 531 532/* 533 * Forward declarations. 534 */ 535static void 536compound_rrstream_destroy(rrstream_t **rsp); 537 538static isc_result_t 539compound_rrstream_next(rrstream_t *rs); 540 541static rrstream_methods_t compound_rrstream_methods; 542 543/* 544 * Requires: 545 * soa_stream != NULL && *soa_stream != NULL 546 * data_stream != NULL && *data_stream != NULL 547 * sp != NULL && *sp == NULL 548 * 549 * Ensures: 550 * *soa_stream == NULL 551 * *data_stream == NULL 552 * *sp points to a valid compound_rrstream_t 553 * The soa and data streams will be destroyed 554 * when the compound_rrstream_t is destroyed. 555 */ 556static isc_result_t 557compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, 558 rrstream_t **data_stream, rrstream_t **sp) 559{ 560 compound_rrstream_t *s; 561 562 INSIST(sp != NULL && *sp == NULL); 563 564 s = isc_mem_get(mctx, sizeof(*s)); 565 if (s == NULL) 566 return (ISC_R_NOMEMORY); 567 s->common.mctx = NULL; 568 isc_mem_attach(mctx, &s->common.mctx); 569 s->common.methods = &compound_rrstream_methods; 570 s->components[0] = *soa_stream; 571 s->components[1] = *data_stream; 572 s->components[2] = *soa_stream; 573 s->state = -1; 574 s->result = ISC_R_FAILURE; 575 576 *soa_stream = NULL; 577 *data_stream = NULL; 578 *sp = (rrstream_t *) s; 579 return (ISC_R_SUCCESS); 580} 581 582static isc_result_t 583compound_rrstream_first(rrstream_t *rs) { 584 compound_rrstream_t *s = (compound_rrstream_t *) rs; 585 s->state = 0; 586 do { 587 rrstream_t *curstream = s->components[s->state]; 588 s->result = curstream->methods->first(curstream); 589 } while (s->result == ISC_R_NOMORE && s->state < 2); 590 return (s->result); 591} 592 593static isc_result_t 594compound_rrstream_next(rrstream_t *rs) { 595 compound_rrstream_t *s = (compound_rrstream_t *) rs; 596 rrstream_t *curstream = s->components[s->state]; 597 s->result = curstream->methods->next(curstream); 598 while (s->result == ISC_R_NOMORE) { 599 /* 600 * Make sure locks held by the current stream 601 * are released before we switch streams. 602 */ 603 curstream->methods->pause(curstream); 604 if (s->state == 2) 605 return (ISC_R_NOMORE); 606 s->state++; 607 curstream = s->components[s->state]; 608 s->result = curstream->methods->first(curstream); 609 } 610 return (s->result); 611} 612 613static void 614compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, 615 dns_rdata_t **rdata) 616{ 617 compound_rrstream_t *s = (compound_rrstream_t *) rs; 618 rrstream_t *curstream; 619 INSIST(0 <= s->state && s->state < 3); 620 INSIST(s->result == ISC_R_SUCCESS); 621 curstream = s->components[s->state]; 622 curstream->methods->current(curstream, name, ttl, rdata); 623} 624 625static void 626compound_rrstream_pause(rrstream_t *rs) 627{ 628 compound_rrstream_t *s = (compound_rrstream_t *) rs; 629 rrstream_t *curstream; 630 INSIST(0 <= s->state && s->state < 3); 631 curstream = s->components[s->state]; 632 curstream->methods->pause(curstream); 633} 634 635static void 636compound_rrstream_destroy(rrstream_t **rsp) { 637 compound_rrstream_t *s = (compound_rrstream_t *) *rsp; 638 s->components[0]->methods->destroy(&s->components[0]); 639 s->components[1]->methods->destroy(&s->components[1]); 640 s->components[2] = NULL; /* Copy of components[0]. */ 641 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); 642} 643 644static rrstream_methods_t compound_rrstream_methods = { 645 compound_rrstream_first, 646 compound_rrstream_next, 647 compound_rrstream_current, 648 compound_rrstream_pause, 649 compound_rrstream_destroy 650}; 651 652/**************************************************************************/ 653/* 654 * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR 655 * in progress. 656 */ 657 658typedef struct { 659 isc_mem_t *mctx; 660 ns_client_t *client; 661 unsigned int id; /* ID of request */ 662 dns_name_t *qname; /* Question name of request */ 663 dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ 664 dns_rdataclass_t qclass; 665 dns_zone_t *zone; /* (necessary for stats) */ 666 dns_db_t *db; 667 dns_dbversion_t *ver; 668 isc_quota_t *quota; 669 rrstream_t *stream; /* The XFR RR stream */ 670 isc_boolean_t end_of_stream; /* EOS has been reached */ 671 isc_buffer_t buf; /* Buffer for message owner 672 names and rdatas */ 673 isc_buffer_t txlenbuf; /* Transmit length buffer */ 674 isc_buffer_t txbuf; /* Transmit message buffer */ 675 void *txmem; 676 unsigned int txmemlen; 677 unsigned int nmsg; /* Number of messages sent */ 678 dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ 679 isc_buffer_t *lasttsig; /* the last TSIG */ 680 isc_boolean_t many_answers; 681 int sends; /* Send in progress */ 682 isc_boolean_t shuttingdown; 683 const char *mnemonic; /* Style of transfer */ 684} xfrout_ctx_t; 685 686static isc_result_t 687xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, 688 unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, 689 dns_rdataclass_t qclass, dns_zone_t *zone, 690 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, 691 rrstream_t *stream, dns_tsigkey_t *tsigkey, 692 isc_buffer_t *lasttsig, 693 unsigned int maxtime, 694 unsigned int idletime, 695 isc_boolean_t many_answers, 696 xfrout_ctx_t **xfrp); 697 698static void 699sendstream(xfrout_ctx_t *xfr); 700 701static void 702xfrout_senddone(isc_task_t *task, isc_event_t *event); 703 704static void 705xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); 706 707static void 708xfrout_maybe_destroy(xfrout_ctx_t *xfr); 709 710static void 711xfrout_ctx_destroy(xfrout_ctx_t **xfrp); 712 713static void 714xfrout_client_shutdown(void *arg, isc_result_t result); 715 716static void 717xfrout_log1(ns_client_t *client, dns_name_t *zonename, 718 dns_rdataclass_t rdclass, int level, 719 const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); 720 721static void 722xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) 723 ISC_FORMAT_PRINTF(3, 4); 724 725/**************************************************************************/ 726 727void 728ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { 729 isc_result_t result; 730 dns_name_t *question_name; 731 dns_rdataset_t *question_rdataset; 732 dns_zone_t *zone = NULL; 733 dns_db_t *db = NULL; 734 dns_dbversion_t *ver = NULL; 735 dns_rdataclass_t question_class; 736 rrstream_t *soa_stream = NULL; 737 rrstream_t *data_stream = NULL; 738 rrstream_t *stream = NULL; 739 dns_difftuple_t *current_soa_tuple = NULL; 740 dns_name_t *soa_name; 741 dns_rdataset_t *soa_rdataset; 742 dns_rdata_t soa_rdata = DNS_RDATA_INIT; 743 isc_boolean_t have_soa = ISC_FALSE; 744 const char *mnemonic = NULL; 745 isc_mem_t *mctx = client->mctx; 746 dns_message_t *request = client->message; 747 xfrout_ctx_t *xfr = NULL; 748 isc_quota_t *quota = NULL; 749 dns_transfer_format_t format = client->view->transfer_format; 750 isc_netaddr_t na; 751 dns_peer_t *peer = NULL; 752 isc_buffer_t *tsigbuf = NULL; 753 char *journalfile; 754 char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; 755 char keyname[DNS_NAME_FORMATSIZE]; 756 isc_boolean_t is_poll = ISC_FALSE; 757 isc_boolean_t is_dlz = ISC_FALSE; 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 /* 811 * Normal zone table does not have a match. 812 * Try the DLZ database 813 */ 814 if (client->view->dlzdatabase != NULL) { 815 result = dns_dlzallowzonexfr(client->view, 816 question_name, 817 &client->peeraddr, 818 &db); 819 820 if (result == ISC_R_NOPERM) { 821 char _buf1[DNS_NAME_FORMATSIZE]; 822 char _buf2[DNS_RDATACLASS_FORMATSIZE]; 823 824 result = DNS_R_REFUSED; 825 dns_name_format(question_name, _buf1, 826 sizeof(_buf1)); 827 dns_rdataclass_format(question_class, 828 _buf2, sizeof(_buf2)); 829 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 830 NS_LOGMODULE_XFER_OUT, 831 ISC_LOG_ERROR, 832 "zone transfer '%s/%s' denied", 833 _buf1, _buf2); 834 goto failure; 835 } 836 if (result != ISC_R_SUCCESS) 837 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 838 question_name, question_class); 839 is_dlz = ISC_TRUE; 840 } else { 841 /* 842 * not DLZ and not in normal zone table, we are 843 * not authoritative 844 */ 845 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 846 question_name, question_class); 847 } 848 } else { 849 /* zone table has a match */ 850 switch(dns_zone_gettype(zone)) { 851 /* Master and slave zones are OK for transfer. */ 852 case dns_zone_master: 853 case dns_zone_slave: 854 case dns_zone_dlz: 855 break; 856 default: 857 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", 858 question_name, question_class); 859 } 860 CHECK(dns_zone_getdb(zone, &db)); 861 dns_db_currentversion(db, &ver); 862 } 863 864 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), 865 "%s question section OK", mnemonic); 866 867 /* 868 * Check the authority section. Look for a SOA record with 869 * the same name and class as the question. 870 */ 871 for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); 872 result == ISC_R_SUCCESS; 873 result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) 874 { 875 soa_name = NULL; 876 dns_message_currentname(request, DNS_SECTION_AUTHORITY, 877 &soa_name); 878 879 /* 880 * Ignore data whose owner name is not the zone apex. 881 */ 882 if (! dns_name_equal(soa_name, question_name)) 883 continue; 884 885 for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); 886 soa_rdataset != NULL; 887 soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) 888 { 889 /* 890 * Ignore non-SOA data. 891 */ 892 if (soa_rdataset->type != dns_rdatatype_soa) 893 continue; 894 if (soa_rdataset->rdclass != question_class) 895 continue; 896 897 CHECK(dns_rdataset_first(soa_rdataset)); 898 dns_rdataset_current(soa_rdataset, &soa_rdata); 899 result = dns_rdataset_next(soa_rdataset); 900 if (result == ISC_R_SUCCESS) 901 FAILC(DNS_R_FORMERR, 902 "IXFR authority section " 903 "has multiple SOAs"); 904 have_soa = ISC_TRUE; 905 goto got_soa; 906 } 907 } 908 got_soa: 909 if (result != ISC_R_NOMORE) 910 CHECK(result); 911 912 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), 913 "%s authority section OK", mnemonic); 914 915 /* 916 * If not a DLZ zone, decide whether to allow this transfer. 917 */ 918 if (!is_dlz) { 919 ns_client_aclmsg("zone transfer", question_name, reqtype, 920 client->view->rdclass, msg, sizeof(msg)); 921 CHECK(ns_client_checkacl(client, NULL, msg, 922 dns_zone_getxfracl(zone), 923 ISC_TRUE, ISC_LOG_ERROR)); 924 } 925 926 /* 927 * AXFR over UDP is not possible. 928 */ 929 if (reqtype == dns_rdatatype_axfr && 930 (client->attributes & NS_CLIENTATTR_TCP) == 0) 931 FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); 932 933 /* 934 * Look up the requesting server in the peer table. 935 */ 936 isc_netaddr_fromsockaddr(&na, &client->peeraddr); 937 (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); 938 939 /* 940 * Decide on the transfer format (one-answer or many-answers). 941 */ 942 if (peer != NULL) 943 (void)dns_peer_gettransferformat(peer, &format); 944 945 /* 946 * Get a dynamically allocated copy of the current SOA. 947 */ 948 if (is_dlz) 949 dns_db_currentversion(db, &ver); 950 951 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, 952 ¤t_soa_tuple)); 953 954 if (reqtype == dns_rdatatype_ixfr) { 955 isc_uint32_t begin_serial, current_serial; 956 isc_boolean_t provide_ixfr; 957 958 /* 959 * Outgoing IXFR may have been disabled for this peer 960 * or globally. 961 */ 962 provide_ixfr = client->view->provideixfr; 963 if (peer != NULL) 964 (void) dns_peer_getprovideixfr(peer, &provide_ixfr); 965 if (provide_ixfr == ISC_FALSE) 966 goto axfr_fallback; 967 968 if (! have_soa) 969 FAILC(DNS_R_FORMERR, 970 "IXFR request missing SOA"); 971 972 begin_serial = dns_soa_getserial(&soa_rdata); 973 current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); 974 975 /* 976 * RFC1995 says "If an IXFR query with the same or 977 * newer version number than that of the server 978 * is received, it is replied to with a single SOA 979 * record of the server's current version, just as 980 * in AXFR". The claim about AXFR is incorrect, 981 * but other than that, we do as the RFC says. 982 * 983 * Sending a single SOA record is also how we refuse 984 * IXFR over UDP (currently, we always do). 985 */ 986 if (DNS_SERIAL_GE(begin_serial, current_serial) || 987 (client->attributes & NS_CLIENTATTR_TCP) == 0) 988 { 989 CHECK(soa_rrstream_create(mctx, db, ver, &stream)); 990 is_poll = ISC_TRUE; 991 goto have_stream; 992 } 993 journalfile = is_dlz ? NULL : dns_zone_getjournal(zone); 994 if (journalfile != NULL) 995 result = ixfr_rrstream_create(mctx, 996 journalfile, 997 begin_serial, 998 current_serial, 999 &data_stream); 1000 else 1001 result = ISC_R_NOTFOUND; 1002 if (result == ISC_R_NOTFOUND || 1003 result == ISC_R_RANGE) { 1004 xfrout_log1(client, question_name, question_class, 1005 ISC_LOG_DEBUG(4), 1006 "IXFR version not in journal, " 1007 "falling back to AXFR"); 1008 mnemonic = "AXFR-style IXFR"; 1009 goto axfr_fallback; 1010 } 1011 CHECK(result); 1012 } else { 1013 axfr_fallback: 1014 CHECK(axfr_rrstream_create(mctx, db, ver, 1015 &data_stream)); 1016 } 1017 1018 /* 1019 * Bracket the data stream with SOAs. 1020 */ 1021 CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); 1022 CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, 1023 &stream)); 1024 soa_stream = NULL; 1025 data_stream = NULL; 1026 1027 have_stream: 1028 CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); 1029 /* 1030 * Create the xfrout context object. This transfers the ownership 1031 * of "stream", "db", "ver", and "quota" to the xfrout context object. 1032 */ 1033 1034 1035 1036 if (is_dlz) 1037 CHECK(xfrout_ctx_create(mctx, client, request->id, 1038 question_name, reqtype, question_class, 1039 zone, db, ver, quota, stream, 1040 dns_message_gettsigkey(request), 1041 tsigbuf, 1042 3600, 1043 3600, 1044 (format == dns_many_answers) ? 1045 ISC_TRUE : ISC_FALSE, 1046 &xfr)); 1047 else 1048 CHECK(xfrout_ctx_create(mctx, client, request->id, 1049 question_name, reqtype, question_class, 1050 zone, db, ver, quota, stream, 1051 dns_message_gettsigkey(request), 1052 tsigbuf, 1053 dns_zone_getmaxxfrout(zone), 1054 dns_zone_getidleout(zone), 1055 (format == dns_many_answers) ? 1056 ISC_TRUE : ISC_FALSE, 1057 &xfr)); 1058 1059 xfr->mnemonic = mnemonic; 1060 stream = NULL; 1061 quota = NULL; 1062 1063 CHECK(xfr->stream->methods->first(xfr->stream)); 1064 1065 if (xfr->tsigkey != NULL) 1066 dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); 1067 else 1068 keyname[0] = '\0'; 1069 if (is_poll) 1070 xfrout_log1(client, question_name, question_class, 1071 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", 1072 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); 1073 else 1074 xfrout_log1(client, question_name, question_class, 1075 ISC_LOG_INFO, "%s started%s%s", mnemonic, 1076 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); 1077 1078 /* 1079 * Hand the context over to sendstream(). Set xfr to NULL; 1080 * sendstream() is responsible for either passing the 1081 * context on to a later event handler or destroying it. 1082 */ 1083 sendstream(xfr); 1084 xfr = NULL; 1085 1086 result = ISC_R_SUCCESS; 1087 1088 failure: 1089 if (result == DNS_R_REFUSED) 1090 inc_stats(zone, dns_nsstatscounter_xfrrej); 1091 if (quota != NULL) 1092 isc_quota_detach("a); 1093 if (current_soa_tuple != NULL) 1094 dns_difftuple_free(¤t_soa_tuple); 1095 if (stream != NULL) 1096 stream->methods->destroy(&stream); 1097 if (soa_stream != NULL) 1098 soa_stream->methods->destroy(&soa_stream); 1099 if (data_stream != NULL) 1100 data_stream->methods->destroy(&data_stream); 1101 if (ver != NULL) 1102 dns_db_closeversion(db, &ver, ISC_FALSE); 1103 if (db != NULL) 1104 dns_db_detach(&db); 1105 if (zone != NULL) 1106 dns_zone_detach(&zone); 1107 /* XXX kludge */ 1108 if (xfr != NULL) { 1109 xfrout_fail(xfr, result, "setting up zone transfer"); 1110 } else if (result != ISC_R_SUCCESS) { 1111 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, 1112 NS_LOGMODULE_XFER_OUT, 1113 ISC_LOG_DEBUG(3), "zone transfer setup failed"); 1114 ns_client_error(client, result); 1115 } 1116} 1117 1118static isc_result_t 1119xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, 1120 dns_name_t *qname, dns_rdatatype_t qtype, 1121 dns_rdataclass_t qclass, dns_zone_t *zone, 1122 dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, 1123 rrstream_t *stream, dns_tsigkey_t *tsigkey, 1124 isc_buffer_t *lasttsig, unsigned int maxtime, 1125 unsigned int idletime, isc_boolean_t many_answers, 1126 xfrout_ctx_t **xfrp) 1127{ 1128 xfrout_ctx_t *xfr; 1129 isc_result_t result; 1130 unsigned int len; 1131 void *mem; 1132 1133 INSIST(xfrp != NULL && *xfrp == NULL); 1134 xfr = isc_mem_get(mctx, sizeof(*xfr)); 1135 if (xfr == NULL) 1136 return (ISC_R_NOMEMORY); 1137 xfr->mctx = NULL; 1138 isc_mem_attach(mctx, &xfr->mctx); 1139 xfr->client = NULL; 1140 ns_client_attach(client, &xfr->client); 1141 xfr->id = id; 1142 xfr->qname = qname; 1143 xfr->qtype = qtype; 1144 xfr->qclass = qclass; 1145 xfr->zone = NULL; 1146 xfr->db = NULL; 1147 xfr->ver = NULL; 1148 if (zone != NULL) /* zone will be NULL if it's DLZ */ 1149 dns_zone_attach(zone, &xfr->zone); 1150 dns_db_attach(db, &xfr->db); 1151 dns_db_attachversion(db, ver, &xfr->ver); 1152 xfr->end_of_stream = ISC_FALSE; 1153 xfr->tsigkey = tsigkey; 1154 xfr->lasttsig = lasttsig; 1155 xfr->txmem = NULL; 1156 xfr->txmemlen = 0; 1157 xfr->nmsg = 0; 1158 xfr->many_answers = many_answers, 1159 xfr->sends = 0; 1160 xfr->shuttingdown = ISC_FALSE; 1161 xfr->mnemonic = NULL; 1162 xfr->buf.base = NULL; 1163 xfr->buf.length = 0; 1164 xfr->txmem = NULL; 1165 xfr->txmemlen = 0; 1166 xfr->stream = NULL; 1167 xfr->quota = NULL; 1168 1169 /* 1170 * Allocate a temporary buffer for the uncompressed response 1171 * message data. The size should be no more than 65535 bytes 1172 * so that the compressed data will fit in a TCP message, 1173 * and no less than 65535 bytes so that an almost maximum-sized 1174 * RR will fit. Note that although 65535-byte RRs are allowed 1175 * in principle, they cannot be zone-transferred (at least not 1176 * if uncompressible), because the message and RR headers would 1177 * push the size of the TCP message over the 65536 byte limit. 1178 */ 1179 len = 65535; 1180 mem = isc_mem_get(mctx, len); 1181 if (mem == NULL) { 1182 result = ISC_R_NOMEMORY; 1183 goto failure; 1184 } 1185 isc_buffer_init(&xfr->buf, mem, len); 1186 1187 /* 1188 * Allocate another temporary buffer for the compressed 1189 * response message and its TCP length prefix. 1190 */ 1191 len = 2 + 65535; 1192 mem = isc_mem_get(mctx, len); 1193 if (mem == NULL) { 1194 result = ISC_R_NOMEMORY; 1195 goto failure; 1196 } 1197 isc_buffer_init(&xfr->txlenbuf, mem, 2); 1198 isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); 1199 xfr->txmem = mem; 1200 xfr->txmemlen = len; 1201 1202 CHECK(dns_timer_setidle(xfr->client->timer, 1203 maxtime, idletime, ISC_FALSE)); 1204 1205 /* 1206 * Register a shutdown callback with the client, so that we 1207 * can stop the transfer immediately when the client task 1208 * gets a shutdown event. 1209 */ 1210 xfr->client->shutdown = xfrout_client_shutdown; 1211 xfr->client->shutdown_arg = xfr; 1212 /* 1213 * These MUST be after the last "goto failure;" / CHECK to 1214 * prevent a double free by the caller. 1215 */ 1216 xfr->quota = quota; 1217 xfr->stream = stream; 1218 1219 *xfrp = xfr; 1220 return (ISC_R_SUCCESS); 1221 1222failure: 1223 xfrout_ctx_destroy(&xfr); 1224 return (result); 1225} 1226 1227 1228/* 1229 * Arrange to send as much as we can of "stream" without blocking. 1230 * 1231 * Requires: 1232 * The stream iterator is initialized and points at an RR, 1233 * or possibly at the end of the stream (that is, the 1234 * _first method of the iterator has been called). 1235 */ 1236static void 1237sendstream(xfrout_ctx_t *xfr) { 1238 dns_message_t *tcpmsg = NULL; 1239 dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ 1240 isc_result_t result; 1241 isc_region_t used; 1242 isc_region_t region; 1243 dns_rdataset_t *qrdataset; 1244 dns_name_t *msgname = NULL; 1245 dns_rdata_t *msgrdata = NULL; 1246 dns_rdatalist_t *msgrdl = NULL; 1247 dns_rdataset_t *msgrds = NULL; 1248 dns_compress_t cctx; 1249 isc_boolean_t cleanup_cctx = ISC_FALSE; 1250 1251 int n_rrs; 1252 1253 isc_buffer_clear(&xfr->buf); 1254 isc_buffer_clear(&xfr->txlenbuf); 1255 isc_buffer_clear(&xfr->txbuf); 1256 1257 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) { 1258 /* 1259 * In the UDP case, we put the response data directly into 1260 * the client message. 1261 */ 1262 msg = xfr->client->message; 1263 CHECK(dns_message_reply(msg, ISC_TRUE)); 1264 } else { 1265 /* 1266 * TCP. Build a response dns_message_t, temporarily storing 1267 * the raw, uncompressed owner names and RR data contiguously 1268 * in xfr->buf. We know that if the uncompressed data fits 1269 * in xfr->buf, the compressed data will surely fit in a TCP 1270 * message. 1271 */ 1272 1273 CHECK(dns_message_create(xfr->mctx, 1274 DNS_MESSAGE_INTENTRENDER, &tcpmsg)); 1275 msg = tcpmsg; 1276 1277 msg->id = xfr->id; 1278 msg->rcode = dns_rcode_noerror; 1279 msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; 1280 if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) 1281 msg->flags |= DNS_MESSAGEFLAG_RA; 1282 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1283 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); 1284 if (xfr->lasttsig != NULL) 1285 isc_buffer_free(&xfr->lasttsig); 1286 1287 /* 1288 * Account for reserved space. 1289 */ 1290 if (xfr->tsigkey != NULL) 1291 INSIST(msg->reserved != 0U); 1292 isc_buffer_add(&xfr->buf, msg->reserved); 1293 1294 /* 1295 * Include a question section in the first message only. 1296 * BIND 8.2.1 will not recognize an IXFR if it does not 1297 * have a question section. 1298 */ 1299 if (xfr->nmsg == 0) { 1300 dns_name_t *qname = NULL; 1301 isc_region_t r; 1302 1303 /* 1304 * Reserve space for the 12-byte message header 1305 * and 4 bytes of question. 1306 */ 1307 isc_buffer_add(&xfr->buf, 12 + 4); 1308 1309 qrdataset = NULL; 1310 result = dns_message_gettemprdataset(msg, &qrdataset); 1311 if (result != ISC_R_SUCCESS) 1312 goto failure; 1313 dns_rdataset_init(qrdataset); 1314 dns_rdataset_makequestion(qrdataset, 1315 xfr->client->message->rdclass, 1316 xfr->qtype); 1317 1318 result = dns_message_gettempname(msg, &qname); 1319 if (result != ISC_R_SUCCESS) 1320 goto failure; 1321 dns_name_init(qname, NULL); 1322 isc_buffer_availableregion(&xfr->buf, &r); 1323 INSIST(r.length >= xfr->qname->length); 1324 r.length = xfr->qname->length; 1325 isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, 1326 xfr->qname->length); 1327 dns_name_fromregion(qname, &r); 1328 ISC_LIST_INIT(qname->list); 1329 ISC_LIST_APPEND(qname->list, qrdataset, link); 1330 1331 dns_message_addname(msg, qname, DNS_SECTION_QUESTION); 1332 } else { 1333 /* 1334 * Reserve space for the 12-byte message header 1335 */ 1336 isc_buffer_add(&xfr->buf, 12); 1337 msg->tcp_continuation = 1; 1338 } 1339 } 1340 1341 /* 1342 * Try to fit in as many RRs as possible, unless "one-answer" 1343 * format has been requested. 1344 */ 1345 for (n_rrs = 0; ; n_rrs++) { 1346 dns_name_t *name = NULL; 1347 isc_uint32_t ttl; 1348 dns_rdata_t *rdata = NULL; 1349 1350 unsigned int size; 1351 isc_region_t r; 1352 1353 msgname = NULL; 1354 msgrdata = NULL; 1355 msgrdl = NULL; 1356 msgrds = NULL; 1357 1358 xfr->stream->methods->current(xfr->stream, 1359 &name, &ttl, &rdata); 1360 size = name->length + 10 + rdata->length; 1361 isc_buffer_availableregion(&xfr->buf, &r); 1362 if (size >= r.length) { 1363 /* 1364 * RR would not fit. If there are other RRs in the 1365 * buffer, send them now and leave this RR to the 1366 * next message. If this RR overflows the buffer 1367 * all by itself, fail. 1368 * 1369 * In theory some RRs might fit in a TCP message 1370 * when compressed even if they do not fit when 1371 * uncompressed, but surely we don't want 1372 * to send such monstrosities to an unsuspecting 1373 * slave. 1374 */ 1375 if (n_rrs == 0) { 1376 xfrout_log(xfr, ISC_LOG_WARNING, 1377 "RR too large for zone transfer " 1378 "(%d bytes)", size); 1379 /* XXX DNS_R_RRTOOLARGE? */ 1380 result = ISC_R_NOSPACE; 1381 goto failure; 1382 } 1383 break; 1384 } 1385 1386 if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) 1387 log_rr(name, rdata, ttl); /* XXX */ 1388 1389 result = dns_message_gettempname(msg, &msgname); 1390 if (result != ISC_R_SUCCESS) 1391 goto failure; 1392 dns_name_init(msgname, NULL); 1393 isc_buffer_availableregion(&xfr->buf, &r); 1394 INSIST(r.length >= name->length); 1395 r.length = name->length; 1396 isc_buffer_putmem(&xfr->buf, name->ndata, name->length); 1397 dns_name_fromregion(msgname, &r); 1398 1399 /* Reserve space for RR header. */ 1400 isc_buffer_add(&xfr->buf, 10); 1401 1402 result = dns_message_gettemprdata(msg, &msgrdata); 1403 if (result != ISC_R_SUCCESS) 1404 goto failure; 1405 isc_buffer_availableregion(&xfr->buf, &r); 1406 r.length = rdata->length; 1407 isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); 1408 dns_rdata_init(msgrdata); 1409 dns_rdata_fromregion(msgrdata, 1410 rdata->rdclass, rdata->type, &r); 1411 1412 result = dns_message_gettemprdatalist(msg, &msgrdl); 1413 if (result != ISC_R_SUCCESS) 1414 goto failure; 1415 msgrdl->type = rdata->type; 1416 msgrdl->rdclass = rdata->rdclass; 1417 msgrdl->ttl = ttl; 1418 if (rdata->type == dns_rdatatype_sig || 1419 rdata->type == dns_rdatatype_rrsig) 1420 msgrdl->covers = dns_rdata_covers(rdata); 1421 else 1422 msgrdl->covers = dns_rdatatype_none; 1423 ISC_LINK_INIT(msgrdl, link); 1424 ISC_LIST_INIT(msgrdl->rdata); 1425 ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); 1426 1427 result = dns_message_gettemprdataset(msg, &msgrds); 1428 if (result != ISC_R_SUCCESS) 1429 goto failure; 1430 dns_rdataset_init(msgrds); 1431 result = dns_rdatalist_tordataset(msgrdl, msgrds); 1432 INSIST(result == ISC_R_SUCCESS); 1433 1434 ISC_LIST_APPEND(msgname->list, msgrds, link); 1435 1436 dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); 1437 msgname = NULL; 1438 1439 result = xfr->stream->methods->next(xfr->stream); 1440 if (result == ISC_R_NOMORE) { 1441 xfr->end_of_stream = ISC_TRUE; 1442 break; 1443 } 1444 CHECK(result); 1445 1446 if (! xfr->many_answers) 1447 break; 1448 } 1449 1450 if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { 1451 CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); 1452 dns_compress_setsensitive(&cctx, ISC_TRUE); 1453 cleanup_cctx = ISC_TRUE; 1454 CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); 1455 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); 1456 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); 1457 CHECK(dns_message_renderend(msg)); 1458 dns_compress_invalidate(&cctx); 1459 cleanup_cctx = ISC_FALSE; 1460 1461 isc_buffer_usedregion(&xfr->txbuf, &used); 1462 isc_buffer_putuint16(&xfr->txlenbuf, 1463 (isc_uint16_t)used.length); 1464 region.base = xfr->txlenbuf.base; 1465 region.length = 2 + used.length; 1466 xfrout_log(xfr, ISC_LOG_DEBUG(8), 1467 "sending TCP message of %d bytes", 1468 used.length); 1469 CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ 1470 ®ion, xfr->client->task, 1471 xfrout_senddone, 1472 xfr)); 1473 xfr->sends++; 1474 } else { 1475 xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); 1476 ns_client_send(xfr->client); 1477 xfr->stream->methods->pause(xfr->stream); 1478 xfrout_ctx_destroy(&xfr); 1479 return; 1480 } 1481 1482 /* Advance lasttsig to be the last TSIG generated */ 1483 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); 1484 1485 xfr->nmsg++; 1486 1487 failure: 1488 if (msgname != NULL) { 1489 if (msgrds != NULL) { 1490 if (dns_rdataset_isassociated(msgrds)) 1491 dns_rdataset_disassociate(msgrds); 1492 dns_message_puttemprdataset(msg, &msgrds); 1493 } 1494 if (msgrdl != NULL) { 1495 ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); 1496 dns_message_puttemprdatalist(msg, &msgrdl); 1497 } 1498 if (msgrdata != NULL) 1499 dns_message_puttemprdata(msg, &msgrdata); 1500 dns_message_puttempname(msg, &msgname); 1501 } 1502 1503 if (tcpmsg != NULL) 1504 dns_message_destroy(&tcpmsg); 1505 1506 if (cleanup_cctx) 1507 dns_compress_invalidate(&cctx); 1508 /* 1509 * Make sure to release any locks held by database 1510 * iterators before returning from the event handler. 1511 */ 1512 xfr->stream->methods->pause(xfr->stream); 1513 1514 if (result == ISC_R_SUCCESS) 1515 return; 1516 1517 xfrout_fail(xfr, result, "sending zone data"); 1518} 1519 1520static void 1521xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { 1522 xfrout_ctx_t *xfr = *xfrp; 1523 ns_client_t *client = NULL; 1524 1525 INSIST(xfr->sends == 0); 1526 1527 xfr->client->shutdown = NULL; 1528 xfr->client->shutdown_arg = NULL; 1529 1530 if (xfr->stream != NULL) 1531 xfr->stream->methods->destroy(&xfr->stream); 1532 if (xfr->buf.base != NULL) 1533 isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); 1534 if (xfr->txmem != NULL) 1535 isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); 1536 if (xfr->lasttsig != NULL) 1537 isc_buffer_free(&xfr->lasttsig); 1538 if (xfr->quota != NULL) 1539 isc_quota_detach(&xfr->quota); 1540 if (xfr->ver != NULL) 1541 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); 1542 if (xfr->zone != NULL) 1543 dns_zone_detach(&xfr->zone); 1544 if (xfr->db != NULL) 1545 dns_db_detach(&xfr->db); 1546 1547 /* 1548 * We want to detch the client after we have released the memory 1549 * context as ns_client_detach checks the memory reference count. 1550 */ 1551 ns_client_attach(xfr->client, &client); 1552 ns_client_detach(&xfr->client); 1553 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); 1554 ns_client_detach(&client); 1555 1556 *xfrp = NULL; 1557} 1558 1559static void 1560xfrout_senddone(isc_task_t *task, isc_event_t *event) { 1561 isc_socketevent_t *sev = (isc_socketevent_t *)event; 1562 xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; 1563 isc_result_t evresult = sev->result; 1564 1565 UNUSED(task); 1566 1567 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); 1568 1569 isc_event_free(&event); 1570 xfr->sends--; 1571 INSIST(xfr->sends == 0); 1572 1573 (void)isc_timer_touch(xfr->client->timer); 1574 if (xfr->shuttingdown == ISC_TRUE) { 1575 xfrout_maybe_destroy(xfr); 1576 } else if (evresult != ISC_R_SUCCESS) { 1577 xfrout_fail(xfr, evresult, "send"); 1578 } else if (xfr->end_of_stream == ISC_FALSE) { 1579 sendstream(xfr); 1580 } else { 1581 /* End of zone transfer stream. */ 1582 inc_stats(xfr->zone, dns_nsstatscounter_xfrdone); 1583 xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); 1584 ns_client_next(xfr->client, ISC_R_SUCCESS); 1585 xfrout_ctx_destroy(&xfr); 1586 } 1587} 1588 1589static void 1590xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { 1591 xfr->shuttingdown = ISC_TRUE; 1592 xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", 1593 msg, isc_result_totext(result)); 1594 xfrout_maybe_destroy(xfr); 1595} 1596 1597static void 1598xfrout_maybe_destroy(xfrout_ctx_t *xfr) { 1599 INSIST(xfr->shuttingdown == ISC_TRUE); 1600 if (xfr->sends > 0) { 1601 /* 1602 * If we are currently sending, cancel it and wait for 1603 * cancel event before destroying the context. 1604 */ 1605 isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, 1606 ISC_SOCKCANCEL_SEND); 1607 } else { 1608 ns_client_next(xfr->client, ISC_R_CANCELED); 1609 xfrout_ctx_destroy(&xfr); 1610 } 1611} 1612 1613static void 1614xfrout_client_shutdown(void *arg, isc_result_t result) { 1615 xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; 1616 xfrout_fail(xfr, result, "aborted"); 1617} 1618 1619/* 1620 * Log outgoing zone transfer messages in a format like 1621 * <client>: transfer of <zone>: <message> 1622 */ 1623 1624static void 1625xfrout_logv(ns_client_t *client, dns_name_t *zonename, 1626 dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) 1627 ISC_FORMAT_PRINTF(5, 0); 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{ 1633 char msgbuf[2048]; 1634 char namebuf[DNS_NAME_FORMATSIZE]; 1635 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 1636 1637 dns_name_format(zonename, namebuf, sizeof(namebuf)); 1638 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); 1639 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 1640 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, 1641 NS_LOGMODULE_XFER_OUT, level, 1642 "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); 1643} 1644 1645/* 1646 * Logging function for use when a xfrout_ctx_t has not yet been created. 1647 */ 1648static void 1649xfrout_log1(ns_client_t *client, dns_name_t *zonename, 1650 dns_rdataclass_t rdclass, int level, const char *fmt, ...) { 1651 va_list ap; 1652 va_start(ap, fmt); 1653 xfrout_logv(client, zonename, rdclass, level, fmt, ap); 1654 va_end(ap); 1655} 1656 1657/* 1658 * Logging function for use when there is a xfrout_ctx_t. 1659 */ 1660static void 1661xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { 1662 va_list ap; 1663 va_start(ap, fmt); 1664 xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); 1665 va_end(ap); 1666} 1667