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