1 /* $NetBSD: xfrin.c,v 1.11 2015/07/08 17:28:59 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2008, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id */ 21 22 /*! \file */ 23 24 #include <config.h> 25 26 #include <isc/mem.h> 27 #include <isc/print.h> 28 #include <isc/random.h> 29 #include <isc/string.h> /* Required for HP/UX (and others?) */ 30 #include <isc/task.h> 31 #include <isc/timer.h> 32 #include <isc/util.h> 33 34 #include <dns/callbacks.h> 35 #include <dns/db.h> 36 #include <dns/diff.h> 37 #include <dns/events.h> 38 #include <dns/journal.h> 39 #include <dns/log.h> 40 #include <dns/message.h> 41 #include <dns/rdataclass.h> 42 #include <dns/rdatalist.h> 43 #include <dns/rdataset.h> 44 #include <dns/result.h> 45 #include <dns/soa.h> 46 #include <dns/tcpmsg.h> 47 #include <dns/timer.h> 48 #include <dns/tsig.h> 49 #include <dns/view.h> 50 #include <dns/xfrin.h> 51 #include <dns/zone.h> 52 53 #include <dst/dst.h> 54 55 /* 56 * Incoming AXFR and IXFR. 57 */ 58 59 /*% 60 * It would be non-sensical (or at least obtuse) to use FAIL() with an 61 * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler 62 * from complaining about "end-of-loop code not reached". 63 */ 64 #define FAIL(code) \ 65 do { result = (code); \ 66 if (result != ISC_R_SUCCESS) goto failure; \ 67 } while (/*CONSTCOND*/0) 68 69 #define CHECK(op) \ 70 do { result = (op); \ 71 if (result != ISC_R_SUCCESS) goto failure; \ 72 } while (/*CONSTCOND*/0) 73 74 /*% 75 * The states of the *XFR state machine. We handle both IXFR and AXFR 76 * with a single integrated state machine because they cannot be distinguished 77 * immediately - an AXFR response to an IXFR request can only be detected 78 * when the first two (2) response RRs have already been received. 79 */ 80 typedef enum { 81 XFRST_SOAQUERY, 82 XFRST_GOTSOA, 83 XFRST_INITIALSOA, 84 XFRST_FIRSTDATA, 85 XFRST_IXFR_DELSOA, 86 XFRST_IXFR_DEL, 87 XFRST_IXFR_ADDSOA, 88 XFRST_IXFR_ADD, 89 XFRST_IXFR_END, 90 XFRST_AXFR, 91 XFRST_AXFR_END 92 } xfrin_state_t; 93 94 /*% 95 * Incoming zone transfer context. 96 */ 97 98 struct dns_xfrin_ctx { 99 unsigned int magic; 100 isc_mem_t *mctx; 101 dns_zone_t *zone; 102 103 int refcount; 104 105 isc_task_t *task; 106 isc_timer_t *timer; 107 isc_socketmgr_t *socketmgr; 108 109 int connects; /*%< Connect in progress */ 110 int sends; /*%< Send in progress */ 111 int recvs; /*%< Receive in progress */ 112 isc_boolean_t shuttingdown; 113 114 dns_name_t name; /*%< Name of zone to transfer */ 115 dns_rdataclass_t rdclass; 116 117 isc_boolean_t checkid; 118 dns_messageid_t id; 119 120 /*% 121 * Requested transfer type (dns_rdatatype_axfr or 122 * dns_rdatatype_ixfr). The actual transfer type 123 * may differ due to IXFR->AXFR fallback. 124 */ 125 dns_rdatatype_t reqtype; 126 isc_dscp_t dscp; 127 128 isc_sockaddr_t masteraddr; 129 isc_sockaddr_t sourceaddr; 130 isc_socket_t *socket; 131 132 /*% Buffer for IXFR/AXFR request message */ 133 isc_buffer_t qbuffer; 134 unsigned char qbuffer_data[512]; 135 136 /*% Incoming reply TCP message */ 137 dns_tcpmsg_t tcpmsg; 138 isc_boolean_t tcpmsg_valid; 139 140 dns_db_t *db; 141 dns_dbversion_t *ver; 142 dns_diff_t diff; /*%< Pending database changes */ 143 int difflen; /*%< Number of pending tuples */ 144 145 xfrin_state_t state; 146 isc_uint32_t end_serial; 147 isc_boolean_t is_ixfr; 148 149 unsigned int nmsg; /*%< Number of messages recvd */ 150 unsigned int nrecs; /*%< Number of records recvd */ 151 isc_uint64_t nbytes; /*%< Number of bytes received */ 152 153 isc_time_t start; /*%< Start time of the transfer */ 154 isc_time_t end; /*%< End time of the transfer */ 155 156 dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */ 157 isc_buffer_t *lasttsig; /*%< The last TSIG */ 158 dst_context_t *tsigctx; /*%< TSIG verification context */ 159 unsigned int sincetsig; /*%< recvd since the last TSIG */ 160 dns_xfrindone_t done; 161 162 /*% 163 * AXFR- and IXFR-specific data. Only one is used at a time 164 * according to the is_ixfr flag, so this could be a union, 165 * but keeping them separate makes it a bit simpler to clean 166 * things up when destroying the context. 167 */ 168 dns_rdatacallbacks_t axfr; 169 170 struct { 171 isc_uint32_t request_serial; 172 isc_uint32_t current_serial; 173 dns_journal_t *journal; 174 175 } ixfr; 176 }; 177 178 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I') 179 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC) 180 181 /**************************************************************************/ 182 /* 183 * Forward declarations. 184 */ 185 186 static isc_result_t 187 xfrin_create(isc_mem_t *mctx, 188 dns_zone_t *zone, 189 dns_db_t *db, 190 isc_task_t *task, 191 isc_timermgr_t *timermgr, 192 isc_socketmgr_t *socketmgr, 193 dns_name_t *zonename, 194 dns_rdataclass_t rdclass, 195 dns_rdatatype_t reqtype, 196 isc_sockaddr_t *masteraddr, 197 isc_sockaddr_t *sourceaddr, 198 isc_dscp_t dscp, 199 dns_tsigkey_t *tsigkey, 200 dns_xfrin_ctx_t **xfrp); 201 202 static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr); 203 static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp); 204 static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 205 dns_name_t *name, dns_ttl_t ttl, 206 dns_rdata_t *rdata); 207 static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr); 208 static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr); 209 static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr); 210 211 static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr); 212 static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr); 213 static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 214 dns_name_t *name, dns_ttl_t ttl, 215 dns_rdata_t *rdata); 216 static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr); 217 218 static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, 219 isc_uint32_t ttl, dns_rdata_t *rdata); 220 221 static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr); 222 223 static void xfrin_connect_done(isc_task_t *task, isc_event_t *event); 224 static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr); 225 static void xfrin_send_done(isc_task_t *task, isc_event_t *event); 226 static void xfrin_recv_done(isc_task_t *task, isc_event_t *event); 227 static void xfrin_timeout(isc_task_t *task, isc_event_t *event); 228 229 static void maybe_free(dns_xfrin_ctx_t *xfr); 230 231 static void 232 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg); 233 static isc_result_t 234 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf); 235 236 static void 237 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr, 238 const char *fmt, va_list ap) 239 ISC_FORMAT_PRINTF(4, 0); 240 241 static void 242 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr, 243 const char *fmt, ...) 244 ISC_FORMAT_PRINTF(4, 5); 245 246 static void 247 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) 248 ISC_FORMAT_PRINTF(3, 4); 249 250 /**************************************************************************/ 251 /* 252 * AXFR handling 253 */ 254 255 static isc_result_t 256 axfr_init(dns_xfrin_ctx_t *xfr) { 257 isc_result_t result; 258 259 xfr->is_ixfr = ISC_FALSE; 260 261 if (xfr->db != NULL) 262 dns_db_detach(&xfr->db); 263 264 CHECK(axfr_makedb(xfr, &xfr->db)); 265 dns_rdatacallbacks_init(&xfr->axfr); 266 CHECK(dns_db_beginload(xfr->db, &xfr->axfr)); 267 result = ISC_R_SUCCESS; 268 failure: 269 return (result); 270 } 271 272 static isc_result_t 273 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) { 274 isc_result_t result; 275 276 result = dns_db_create(xfr->mctx, /* XXX */ 277 "rbt", /* XXX guess */ 278 &xfr->name, 279 dns_dbtype_zone, 280 xfr->rdclass, 281 0, NULL, /* XXX guess */ 282 dbp); 283 if (result == ISC_R_SUCCESS) 284 dns_zone_rpz_enable_db(xfr->zone, *dbp); 285 return (result); 286 } 287 288 static isc_result_t 289 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 290 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 291 { 292 isc_result_t result; 293 294 dns_difftuple_t *tuple = NULL; 295 296 CHECK(dns_zone_checknames(xfr->zone, name, rdata)); 297 CHECK(dns_difftuple_create(xfr->diff.mctx, op, 298 name, ttl, rdata, &tuple)); 299 dns_diff_append(&xfr->diff, &tuple); 300 if (++xfr->difflen > 100) 301 CHECK(axfr_apply(xfr)); 302 result = ISC_R_SUCCESS; 303 failure: 304 return (result); 305 } 306 307 /* 308 * Store a set of AXFR RRs in the database. 309 */ 310 static isc_result_t 311 axfr_apply(dns_xfrin_ctx_t *xfr) { 312 isc_result_t result; 313 314 CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private)); 315 xfr->difflen = 0; 316 dns_diff_clear(&xfr->diff); 317 result = ISC_R_SUCCESS; 318 failure: 319 return (result); 320 } 321 322 static isc_result_t 323 axfr_commit(dns_xfrin_ctx_t *xfr) { 324 isc_result_t result; 325 326 CHECK(axfr_apply(xfr)); 327 CHECK(dns_db_endload(xfr->db, &xfr->axfr)); 328 329 result = ISC_R_SUCCESS; 330 failure: 331 return (result); 332 } 333 334 static isc_result_t 335 axfr_finalize(dns_xfrin_ctx_t *xfr) { 336 isc_result_t result; 337 338 CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE)); 339 340 result = ISC_R_SUCCESS; 341 failure: 342 return (result); 343 } 344 345 /**************************************************************************/ 346 /* 347 * IXFR handling 348 */ 349 350 static isc_result_t 351 ixfr_init(dns_xfrin_ctx_t *xfr) { 352 isc_result_t result; 353 char *journalfile; 354 355 if (xfr->reqtype != dns_rdatatype_ixfr) { 356 xfrin_log(xfr, ISC_LOG_ERROR, 357 "got incremental response to AXFR request"); 358 return (DNS_R_FORMERR); 359 } 360 361 xfr->is_ixfr = ISC_TRUE; 362 INSIST(xfr->db != NULL); 363 xfr->difflen = 0; 364 365 journalfile = dns_zone_getjournal(xfr->zone); 366 if (journalfile != NULL) 367 CHECK(dns_journal_open(xfr->mctx, journalfile, 368 DNS_JOURNAL_CREATE, &xfr->ixfr.journal)); 369 370 result = ISC_R_SUCCESS; 371 failure: 372 return (result); 373 } 374 375 static isc_result_t 376 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, 377 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 378 { 379 isc_result_t result; 380 381 dns_difftuple_t *tuple = NULL; 382 if (op == DNS_DIFFOP_ADD) 383 CHECK(dns_zone_checknames(xfr->zone, name, rdata)); 384 CHECK(dns_difftuple_create(xfr->diff.mctx, op, 385 name, ttl, rdata, &tuple)); 386 dns_diff_append(&xfr->diff, &tuple); 387 if (++xfr->difflen > 100) 388 CHECK(ixfr_apply(xfr)); 389 result = ISC_R_SUCCESS; 390 failure: 391 return (result); 392 } 393 394 /* 395 * Apply a set of IXFR changes to the database. 396 */ 397 static isc_result_t 398 ixfr_apply(dns_xfrin_ctx_t *xfr) { 399 isc_result_t result; 400 401 if (xfr->ver == NULL) { 402 CHECK(dns_db_newversion(xfr->db, &xfr->ver)); 403 if (xfr->ixfr.journal != NULL) 404 CHECK(dns_journal_begin_transaction(xfr->ixfr.journal)); 405 } 406 CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver)); 407 if (xfr->ixfr.journal != NULL) { 408 result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff); 409 if (result != ISC_R_SUCCESS) 410 goto failure; 411 } 412 dns_diff_clear(&xfr->diff); 413 xfr->difflen = 0; 414 result = ISC_R_SUCCESS; 415 failure: 416 return (result); 417 } 418 419 static isc_result_t 420 ixfr_commit(dns_xfrin_ctx_t *xfr) { 421 isc_result_t result; 422 423 CHECK(ixfr_apply(xfr)); 424 if (xfr->ver != NULL) { 425 /* XXX enter ready-to-commit state here */ 426 if (xfr->ixfr.journal != NULL) 427 CHECK(dns_journal_commit(xfr->ixfr.journal)); 428 dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE); 429 dns_zone_markdirty(xfr->zone); 430 } 431 result = ISC_R_SUCCESS; 432 failure: 433 return (result); 434 } 435 436 /**************************************************************************/ 437 /* 438 * Common AXFR/IXFR protocol code 439 */ 440 441 /* 442 * Handle a single incoming resource record according to the current 443 * state. 444 */ 445 static isc_result_t 446 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, 447 dns_rdata_t *rdata) 448 { 449 isc_result_t result; 450 451 xfr->nrecs++; 452 453 if (rdata->type == dns_rdatatype_none || 454 dns_rdatatype_ismeta(rdata->type)) 455 FAIL(DNS_R_FORMERR); 456 457 redo: 458 switch (xfr->state) { 459 case XFRST_SOAQUERY: 460 if (rdata->type != dns_rdatatype_soa) { 461 xfrin_log(xfr, ISC_LOG_ERROR, 462 "non-SOA response to SOA query"); 463 FAIL(DNS_R_FORMERR); 464 } 465 xfr->end_serial = dns_soa_getserial(rdata); 466 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) && 467 !dns_zone_isforced(xfr->zone)) { 468 xfrin_log(xfr, ISC_LOG_DEBUG(3), 469 "requested serial %u, " 470 "master has %u, not updating", 471 xfr->ixfr.request_serial, xfr->end_serial); 472 FAIL(DNS_R_UPTODATE); 473 } 474 xfr->state = XFRST_GOTSOA; 475 break; 476 477 case XFRST_GOTSOA: 478 /* 479 * Skip other records in the answer section. 480 */ 481 break; 482 483 case XFRST_INITIALSOA: 484 if (rdata->type != dns_rdatatype_soa) { 485 xfrin_log(xfr, ISC_LOG_ERROR, 486 "first RR in zone transfer must be SOA"); 487 FAIL(DNS_R_FORMERR); 488 } 489 /* 490 * Remember the serial number in the initial SOA. 491 * We need it to recognize the end of an IXFR. 492 */ 493 xfr->end_serial = dns_soa_getserial(rdata); 494 if (xfr->reqtype == dns_rdatatype_ixfr && 495 ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) 496 && !dns_zone_isforced(xfr->zone)) 497 { 498 /* 499 * This must be the single SOA record that is 500 * sent when the current version on the master 501 * is not newer than the version in the request. 502 */ 503 xfrin_log(xfr, ISC_LOG_DEBUG(3), 504 "requested serial %u, " 505 "master has %u, not updating", 506 xfr->ixfr.request_serial, xfr->end_serial); 507 FAIL(DNS_R_UPTODATE); 508 } 509 if (xfr->reqtype == dns_rdatatype_axfr) 510 xfr->checkid = ISC_FALSE; 511 xfr->state = XFRST_FIRSTDATA; 512 break; 513 514 case XFRST_FIRSTDATA: 515 /* 516 * If the transfer begins with one SOA record, it is an AXFR, 517 * if it begins with two SOAs, it is an IXFR. 518 */ 519 if (xfr->reqtype == dns_rdatatype_ixfr && 520 rdata->type == dns_rdatatype_soa && 521 xfr->ixfr.request_serial == dns_soa_getserial(rdata)) { 522 xfrin_log(xfr, ISC_LOG_DEBUG(3), 523 "got incremental response"); 524 CHECK(ixfr_init(xfr)); 525 xfr->state = XFRST_IXFR_DELSOA; 526 } else { 527 xfrin_log(xfr, ISC_LOG_DEBUG(3), 528 "got nonincremental response"); 529 CHECK(axfr_init(xfr)); 530 xfr->state = XFRST_AXFR; 531 } 532 goto redo; 533 534 case XFRST_IXFR_DELSOA: 535 INSIST(rdata->type == dns_rdatatype_soa); 536 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata)); 537 xfr->state = XFRST_IXFR_DEL; 538 break; 539 540 case XFRST_IXFR_DEL: 541 if (rdata->type == dns_rdatatype_soa) { 542 isc_uint32_t soa_serial = dns_soa_getserial(rdata); 543 xfr->state = XFRST_IXFR_ADDSOA; 544 xfr->ixfr.current_serial = soa_serial; 545 goto redo; 546 } 547 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata)); 548 break; 549 550 case XFRST_IXFR_ADDSOA: 551 INSIST(rdata->type == dns_rdatatype_soa); 552 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); 553 xfr->state = XFRST_IXFR_ADD; 554 break; 555 556 case XFRST_IXFR_ADD: 557 if (rdata->type == dns_rdatatype_soa) { 558 isc_uint32_t soa_serial = dns_soa_getserial(rdata); 559 if (soa_serial == xfr->end_serial) { 560 CHECK(ixfr_commit(xfr)); 561 xfr->state = XFRST_IXFR_END; 562 break; 563 } else if (soa_serial != xfr->ixfr.current_serial) { 564 xfrin_log(xfr, ISC_LOG_ERROR, 565 "IXFR out of sync: " 566 "expected serial %u, got %u", 567 xfr->ixfr.current_serial, soa_serial); 568 FAIL(DNS_R_FORMERR); 569 } else { 570 CHECK(ixfr_commit(xfr)); 571 xfr->state = XFRST_IXFR_DELSOA; 572 goto redo; 573 } 574 } 575 if (rdata->type == dns_rdatatype_ns && 576 dns_name_iswildcard(name)) 577 FAIL(DNS_R_INVALIDNS); 578 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); 579 break; 580 581 case XFRST_AXFR: 582 /* 583 * Old BINDs sent cross class A records for non IN classes. 584 */ 585 if (rdata->type == dns_rdatatype_a && 586 rdata->rdclass != xfr->rdclass && 587 xfr->rdclass != dns_rdataclass_in) 588 break; 589 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); 590 if (rdata->type == dns_rdatatype_soa) { 591 CHECK(axfr_commit(xfr)); 592 xfr->state = XFRST_AXFR_END; 593 break; 594 } 595 break; 596 case XFRST_AXFR_END: 597 case XFRST_IXFR_END: 598 FAIL(DNS_R_EXTRADATA); 599 /* NOTREACHED */ 600 default: 601 INSIST(0); 602 break; 603 } 604 result = ISC_R_SUCCESS; 605 failure: 606 return (result); 607 } 608 609 isc_result_t 610 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, 611 isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey, 612 isc_mem_t *mctx, isc_timermgr_t *timermgr, 613 isc_socketmgr_t *socketmgr, isc_task_t *task, 614 dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) 615 { 616 isc_sockaddr_t sourceaddr; 617 isc_dscp_t dscp; 618 619 switch (isc_sockaddr_pf(masteraddr)) { 620 case PF_INET: 621 sourceaddr = *dns_zone_getxfrsource4(zone); 622 dscp = dns_zone_getxfrsource4dscp(zone); 623 break; 624 case PF_INET6: 625 sourceaddr = *dns_zone_getxfrsource6(zone); 626 dscp = dns_zone_getxfrsource6dscp(zone); 627 break; 628 default: 629 INSIST(0); 630 } 631 632 return(dns_xfrin_create3(zone, xfrtype, masteraddr, &sourceaddr, 633 dscp, tsigkey, mctx, timermgr, socketmgr, 634 task, done, xfrp)); 635 } 636 637 isc_result_t 638 dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, 639 isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, 640 dns_tsigkey_t *tsigkey, isc_mem_t *mctx, 641 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 642 isc_task_t *task, dns_xfrindone_t done, 643 dns_xfrin_ctx_t **xfrp) 644 { 645 return (dns_xfrin_create3(zone, xfrtype, masteraddr, sourceaddr, -1, 646 tsigkey, mctx, timermgr, socketmgr, task, 647 done, xfrp)); 648 } 649 650 isc_result_t 651 dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype, 652 isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, 653 isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, 654 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 655 isc_task_t *task, dns_xfrindone_t done, 656 dns_xfrin_ctx_t **xfrp) 657 { 658 dns_name_t *zonename = dns_zone_getorigin(zone); 659 dns_xfrin_ctx_t *xfr = NULL; 660 isc_result_t result; 661 dns_db_t *db = NULL; 662 663 REQUIRE(xfrp != NULL && *xfrp == NULL); 664 665 (void)dns_zone_getdb(zone, &db); 666 667 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) 668 REQUIRE(db != NULL); 669 670 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename, 671 dns_zone_getclass(zone), xfrtype, masteraddr, 672 sourceaddr, dscp, tsigkey, &xfr)); 673 674 CHECK(xfrin_start(xfr)); 675 676 xfr->done = done; 677 xfr->refcount++; 678 *xfrp = xfr; 679 680 failure: 681 if (db != NULL) 682 dns_db_detach(&db); 683 if (result != ISC_R_SUCCESS) { 684 char zonetext[DNS_NAME_MAXTEXT+32]; 685 dns_zone_name(zone, zonetext, sizeof(zonetext)); 686 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr, 687 "zone transfer setup failed"); 688 } 689 return (result); 690 } 691 692 void 693 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) { 694 if (! xfr->shuttingdown) 695 xfrin_fail(xfr, ISC_R_CANCELED, "shut down"); 696 } 697 698 void 699 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) { 700 REQUIRE(target != NULL && *target == NULL); 701 source->refcount++; 702 *target = source; 703 } 704 705 void 706 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) { 707 dns_xfrin_ctx_t *xfr = *xfrp; 708 INSIST(xfr->refcount > 0); 709 xfr->refcount--; 710 maybe_free(xfr); 711 *xfrp = NULL; 712 } 713 714 static void 715 xfrin_cancelio(dns_xfrin_ctx_t *xfr) { 716 if (xfr->connects > 0) { 717 isc_socket_cancel(xfr->socket, xfr->task, 718 ISC_SOCKCANCEL_CONNECT); 719 } else if (xfr->recvs > 0) { 720 dns_tcpmsg_cancelread(&xfr->tcpmsg); 721 } else if (xfr->sends > 0) { 722 isc_socket_cancel(xfr->socket, xfr->task, 723 ISC_SOCKCANCEL_SEND); 724 } 725 } 726 727 static void 728 xfrin_reset(dns_xfrin_ctx_t *xfr) { 729 REQUIRE(VALID_XFRIN(xfr)); 730 731 xfrin_log(xfr, ISC_LOG_INFO, "resetting"); 732 733 xfrin_cancelio(xfr); 734 735 if (xfr->socket != NULL) 736 isc_socket_detach(&xfr->socket); 737 738 if (xfr->lasttsig != NULL) 739 isc_buffer_free(&xfr->lasttsig); 740 741 dns_diff_clear(&xfr->diff); 742 xfr->difflen = 0; 743 744 if (xfr->ixfr.journal != NULL) 745 dns_journal_destroy(&xfr->ixfr.journal); 746 747 if (xfr->axfr.add_private != NULL) 748 (void)dns_db_endload(xfr->db, &xfr->axfr); 749 750 if (xfr->tcpmsg_valid) { 751 dns_tcpmsg_invalidate(&xfr->tcpmsg); 752 xfr->tcpmsg_valid = ISC_FALSE; 753 } 754 755 if (xfr->ver != NULL) 756 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); 757 } 758 759 760 static void 761 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) { 762 if (result != DNS_R_UPTODATE) { 763 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", 764 msg, isc_result_totext(result)); 765 if (xfr->is_ixfr) 766 /* Pass special result code to force AXFR retry */ 767 result = DNS_R_BADIXFR; 768 } 769 xfrin_cancelio(xfr); 770 /* 771 * Close the journal. 772 */ 773 if (xfr->ixfr.journal != NULL) 774 dns_journal_destroy(&xfr->ixfr.journal); 775 if (xfr->done != NULL) { 776 (xfr->done)(xfr->zone, result); 777 xfr->done = NULL; 778 } 779 xfr->shuttingdown = ISC_TRUE; 780 maybe_free(xfr); 781 } 782 783 static isc_result_t 784 xfrin_create(isc_mem_t *mctx, 785 dns_zone_t *zone, 786 dns_db_t *db, 787 isc_task_t *task, 788 isc_timermgr_t *timermgr, 789 isc_socketmgr_t *socketmgr, 790 dns_name_t *zonename, 791 dns_rdataclass_t rdclass, 792 dns_rdatatype_t reqtype, 793 isc_sockaddr_t *masteraddr, 794 isc_sockaddr_t *sourceaddr, 795 isc_dscp_t dscp, 796 dns_tsigkey_t *tsigkey, 797 dns_xfrin_ctx_t **xfrp) 798 { 799 dns_xfrin_ctx_t *xfr = NULL; 800 isc_result_t result; 801 isc_uint32_t tmp; 802 803 xfr = isc_mem_get(mctx, sizeof(*xfr)); 804 if (xfr == NULL) 805 return (ISC_R_NOMEMORY); 806 xfr->mctx = NULL; 807 isc_mem_attach(mctx, &xfr->mctx); 808 xfr->refcount = 0; 809 xfr->zone = NULL; 810 dns_zone_iattach(zone, &xfr->zone); 811 xfr->task = NULL; 812 isc_task_attach(task, &xfr->task); 813 xfr->timer = NULL; 814 xfr->socketmgr = socketmgr; 815 xfr->done = NULL; 816 817 xfr->connects = 0; 818 xfr->sends = 0; 819 xfr->recvs = 0; 820 xfr->shuttingdown = ISC_FALSE; 821 822 dns_name_init(&xfr->name, NULL); 823 xfr->rdclass = rdclass; 824 isc_random_get(&tmp); 825 xfr->checkid = ISC_TRUE; 826 xfr->id = (isc_uint16_t)(tmp & 0xffff); 827 xfr->reqtype = reqtype; 828 xfr->dscp = dscp; 829 830 /* sockaddr */ 831 xfr->socket = NULL; 832 /* qbuffer */ 833 /* qbuffer_data */ 834 /* tcpmsg */ 835 xfr->tcpmsg_valid = ISC_FALSE; 836 837 xfr->db = NULL; 838 if (db != NULL) 839 dns_db_attach(db, &xfr->db); 840 xfr->ver = NULL; 841 dns_diff_init(xfr->mctx, &xfr->diff); 842 xfr->difflen = 0; 843 844 if (reqtype == dns_rdatatype_soa) 845 xfr->state = XFRST_SOAQUERY; 846 else 847 xfr->state = XFRST_INITIALSOA; 848 /* end_serial */ 849 850 xfr->nmsg = 0; 851 xfr->nrecs = 0; 852 xfr->nbytes = 0; 853 isc_time_now(&xfr->start); 854 855 xfr->tsigkey = NULL; 856 if (tsigkey != NULL) 857 dns_tsigkey_attach(tsigkey, &xfr->tsigkey); 858 xfr->lasttsig = NULL; 859 xfr->tsigctx = NULL; 860 xfr->sincetsig = 0; 861 xfr->is_ixfr = ISC_FALSE; 862 863 /* ixfr.request_serial */ 864 /* ixfr.current_serial */ 865 xfr->ixfr.journal = NULL; 866 867 xfr->axfr.add = NULL; 868 xfr->axfr.add_private = NULL; 869 870 CHECK(dns_name_dup(zonename, mctx, &xfr->name)); 871 872 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, 873 task, xfrin_timeout, xfr, &xfr->timer)); 874 CHECK(dns_timer_setidle(xfr->timer, 875 dns_zone_getmaxxfrin(xfr->zone), 876 dns_zone_getidlein(xfr->zone), 877 ISC_FALSE)); 878 879 xfr->masteraddr = *masteraddr; 880 881 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr)); 882 xfr->sourceaddr = *sourceaddr; 883 isc_sockaddr_setport(&xfr->sourceaddr, 0); 884 885 /* 886 * Reserve 2 bytes for TCP length at the begining of the buffer. 887 */ 888 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2], 889 sizeof(xfr->qbuffer_data) - 2); 890 891 xfr->magic = XFRIN_MAGIC; 892 *xfrp = xfr; 893 return (ISC_R_SUCCESS); 894 895 failure: 896 if (xfr->timer != NULL) 897 isc_timer_detach(&xfr->timer); 898 if (dns_name_dynamic(&xfr->name)) 899 dns_name_free(&xfr->name, xfr->mctx); 900 if (xfr->tsigkey != NULL) 901 dns_tsigkey_detach(&xfr->tsigkey); 902 if (xfr->db != NULL) 903 dns_db_detach(&xfr->db); 904 isc_task_detach(&xfr->task); 905 dns_zone_idetach(&xfr->zone); 906 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); 907 908 return (result); 909 } 910 911 static isc_result_t 912 xfrin_start(dns_xfrin_ctx_t *xfr) { 913 isc_result_t result; 914 CHECK(isc_socket_create(xfr->socketmgr, 915 isc_sockaddr_pf(&xfr->sourceaddr), 916 isc_sockettype_tcp, 917 &xfr->socket)); 918 isc_socket_setname(xfr->socket, "xfrin", NULL); 919 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT 920 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr, 921 ISC_SOCKET_REUSEADDRESS)); 922 #endif 923 isc_socket_dscp(xfr->socket, xfr->dscp); 924 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task, 925 xfrin_connect_done, xfr)); 926 xfr->connects++; 927 return (ISC_R_SUCCESS); 928 failure: 929 xfrin_fail(xfr, result, "failed setting up socket"); 930 return (result); 931 } 932 933 /* XXX the resolver could use this, too */ 934 935 static isc_result_t 936 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) { 937 dns_compress_t cctx; 938 isc_boolean_t cleanup_cctx = ISC_FALSE; 939 isc_result_t result; 940 941 CHECK(dns_compress_init(&cctx, -1, mctx)); 942 cleanup_cctx = ISC_TRUE; 943 CHECK(dns_message_renderbegin(msg, &cctx, buf)); 944 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); 945 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); 946 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0)); 947 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0)); 948 CHECK(dns_message_renderend(msg)); 949 result = ISC_R_SUCCESS; 950 failure: 951 if (cleanup_cctx) 952 dns_compress_invalidate(&cctx); 953 return (result); 954 } 955 956 /* 957 * A connection has been established. 958 */ 959 static void 960 xfrin_connect_done(isc_task_t *task, isc_event_t *event) { 961 isc_socket_connev_t *cev = (isc_socket_connev_t *) event; 962 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; 963 isc_result_t result = cev->result; 964 char sourcetext[ISC_SOCKADDR_FORMATSIZE]; 965 isc_sockaddr_t sockaddr; 966 dns_zonemgr_t * zmgr; 967 isc_time_t now; 968 969 REQUIRE(VALID_XFRIN(xfr)); 970 971 UNUSED(task); 972 973 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT); 974 isc_event_free(&event); 975 976 xfr->connects--; 977 if (xfr->shuttingdown) { 978 maybe_free(xfr); 979 return; 980 } 981 982 zmgr = dns_zone_getmgr(xfr->zone); 983 if (zmgr != NULL) { 984 if (result != ISC_R_SUCCESS) { 985 TIME_NOW(&now); 986 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr, 987 &xfr->sourceaddr, &now); 988 goto failure; 989 } else 990 dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr, 991 &xfr->sourceaddr); 992 } 993 994 result = isc_socket_getsockname(xfr->socket, &sockaddr); 995 if (result == ISC_R_SUCCESS) { 996 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext)); 997 } else 998 strcpy(sourcetext, "<UNKNOWN>"); 999 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext); 1000 1001 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg); 1002 xfr->tcpmsg_valid = ISC_TRUE; 1003 1004 CHECK(xfrin_send_request(xfr)); 1005 failure: 1006 if (result != ISC_R_SUCCESS) 1007 xfrin_fail(xfr, result, "failed to connect"); 1008 } 1009 1010 /* 1011 * Convert a tuple into a dns_name_t suitable for inserting 1012 * into the given dns_message_t. 1013 */ 1014 static isc_result_t 1015 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) 1016 { 1017 isc_result_t result; 1018 dns_rdata_t *rdata = NULL; 1019 dns_rdatalist_t *rdl = NULL; 1020 dns_rdataset_t *rds = NULL; 1021 dns_name_t *name = NULL; 1022 1023 REQUIRE(target != NULL && *target == NULL); 1024 1025 CHECK(dns_message_gettemprdata(msg, &rdata)); 1026 dns_rdata_init(rdata); 1027 dns_rdata_clone(&tuple->rdata, rdata); 1028 1029 CHECK(dns_message_gettemprdatalist(msg, &rdl)); 1030 dns_rdatalist_init(rdl); 1031 rdl->type = tuple->rdata.type; 1032 rdl->rdclass = tuple->rdata.rdclass; 1033 rdl->ttl = tuple->ttl; 1034 ISC_LIST_APPEND(rdl->rdata, rdata, link); 1035 1036 CHECK(dns_message_gettemprdataset(msg, &rds)); 1037 CHECK(dns_rdatalist_tordataset(rdl, rds)); 1038 1039 CHECK(dns_message_gettempname(msg, &name)); 1040 dns_name_init(name, NULL); 1041 dns_name_clone(&tuple->name, name); 1042 ISC_LIST_APPEND(name->list, rds, link); 1043 1044 *target = name; 1045 return (ISC_R_SUCCESS); 1046 1047 failure: 1048 1049 if (rds != NULL) { 1050 dns_rdataset_disassociate(rds); 1051 dns_message_puttemprdataset(msg, &rds); 1052 } 1053 if (rdl != NULL) { 1054 ISC_LIST_UNLINK(rdl->rdata, rdata, link); 1055 dns_message_puttemprdatalist(msg, &rdl); 1056 } 1057 if (rdata != NULL) 1058 dns_message_puttemprdata(msg, &rdata); 1059 1060 return (result); 1061 } 1062 1063 1064 /* 1065 * Build an *XFR request and send its length prefix. 1066 */ 1067 static isc_result_t 1068 xfrin_send_request(dns_xfrin_ctx_t *xfr) { 1069 isc_result_t result; 1070 isc_region_t region; 1071 dns_rdataset_t *qrdataset = NULL; 1072 dns_message_t *msg = NULL; 1073 dns_difftuple_t *soatuple = NULL; 1074 dns_name_t *qname = NULL; 1075 dns_dbversion_t *ver = NULL; 1076 dns_name_t *msgsoaname = NULL; 1077 1078 /* Create the request message */ 1079 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg)); 1080 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1081 1082 /* Create a name for the question section. */ 1083 CHECK(dns_message_gettempname(msg, &qname)); 1084 dns_name_init(qname, NULL); 1085 dns_name_clone(&xfr->name, qname); 1086 1087 /* Formulate the question and attach it to the question name. */ 1088 CHECK(dns_message_gettemprdataset(msg, &qrdataset)); 1089 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype); 1090 ISC_LIST_APPEND(qname->list, qrdataset, link); 1091 qrdataset = NULL; 1092 1093 dns_message_addname(msg, qname, DNS_SECTION_QUESTION); 1094 qname = NULL; 1095 1096 if (xfr->reqtype == dns_rdatatype_ixfr) { 1097 /* Get the SOA and add it to the authority section. */ 1098 /* XXX is using the current version the right thing? */ 1099 dns_db_currentversion(xfr->db, &ver); 1100 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx, 1101 DNS_DIFFOP_EXISTS, &soatuple)); 1102 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata); 1103 xfr->ixfr.current_serial = xfr->ixfr.request_serial; 1104 xfrin_log(xfr, ISC_LOG_DEBUG(3), 1105 "requesting IXFR for serial %u", 1106 xfr->ixfr.request_serial); 1107 1108 CHECK(tuple2msgname(soatuple, msg, &msgsoaname)); 1109 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY); 1110 } else if (xfr->reqtype == dns_rdatatype_soa) 1111 CHECK(dns_db_getsoaserial(xfr->db, NULL, 1112 &xfr->ixfr.request_serial)); 1113 1114 xfr->checkid = ISC_TRUE; 1115 xfr->id++; 1116 xfr->nmsg = 0; 1117 xfr->nrecs = 0; 1118 xfr->nbytes = 0; 1119 isc_time_now(&xfr->start); 1120 msg->id = xfr->id; 1121 if (xfr->tsigctx != NULL) 1122 dst_context_destroy(&xfr->tsigctx); 1123 1124 CHECK(render(msg, xfr->mctx, &xfr->qbuffer)); 1125 1126 /* 1127 * Free the last tsig, if there is one. 1128 */ 1129 if (xfr->lasttsig != NULL) 1130 isc_buffer_free(&xfr->lasttsig); 1131 1132 /* 1133 * Save the query TSIG and don't let message_destroy free it. 1134 */ 1135 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); 1136 1137 isc_buffer_usedregion(&xfr->qbuffer, ®ion); 1138 INSIST(region.length <= 65535); 1139 1140 /* 1141 * Record message length and adjust region to include TCP 1142 * length field. 1143 */ 1144 xfr->qbuffer_data[0] = (region.length >> 8) & 0xff; 1145 xfr->qbuffer_data[1] = region.length & 0xff; 1146 region.base -= 2; 1147 region.length += 2; 1148 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task, 1149 xfrin_send_done, xfr)); 1150 xfr->sends++; 1151 1152 failure: 1153 if (qname != NULL) 1154 dns_message_puttempname(msg, &qname); 1155 if (qrdataset != NULL) 1156 dns_message_puttemprdataset(msg, &qrdataset); 1157 if (msg != NULL) 1158 dns_message_destroy(&msg); 1159 if (soatuple != NULL) 1160 dns_difftuple_free(&soatuple); 1161 if (ver != NULL) 1162 dns_db_closeversion(xfr->db, &ver, ISC_FALSE); 1163 return (result); 1164 } 1165 1166 static void 1167 xfrin_send_done(isc_task_t *task, isc_event_t *event) { 1168 isc_socketevent_t *sev = (isc_socketevent_t *) event; 1169 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; 1170 isc_result_t result; 1171 1172 REQUIRE(VALID_XFRIN(xfr)); 1173 1174 UNUSED(task); 1175 1176 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); 1177 1178 xfr->sends--; 1179 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data"); 1180 CHECK(sev->result); 1181 1182 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, 1183 xfrin_recv_done, xfr)); 1184 xfr->recvs++; 1185 failure: 1186 isc_event_free(&event); 1187 if (result != ISC_R_SUCCESS) 1188 xfrin_fail(xfr, result, "failed sending request data"); 1189 } 1190 1191 1192 static void 1193 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { 1194 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg; 1195 isc_result_t result; 1196 dns_message_t *msg = NULL; 1197 dns_name_t *name; 1198 dns_tcpmsg_t *tcpmsg; 1199 dns_name_t *tsigowner = NULL; 1200 1201 REQUIRE(VALID_XFRIN(xfr)); 1202 1203 UNUSED(task); 1204 1205 INSIST(ev->ev_type == DNS_EVENT_TCPMSG); 1206 tcpmsg = ev->ev_sender; 1207 isc_event_free(&ev); 1208 1209 xfr->recvs--; 1210 if (xfr->shuttingdown) { 1211 maybe_free(xfr); 1212 return; 1213 } 1214 1215 CHECK(tcpmsg->result); 1216 1217 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", 1218 tcpmsg->buffer.used); 1219 1220 CHECK(isc_timer_touch(xfr->timer)); 1221 1222 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg)); 1223 1224 CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); 1225 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); 1226 1227 msg->tsigctx = xfr->tsigctx; 1228 xfr->tsigctx = NULL; 1229 1230 if (xfr->nmsg > 0) 1231 msg->tcp_continuation = 1; 1232 1233 result = dns_message_parse(msg, &tcpmsg->buffer, 1234 DNS_MESSAGEPARSE_PRESERVEORDER); 1235 1236 if (result == ISC_R_SUCCESS) 1237 dns_message_logpacket(msg, "received message:\n", 1238 DNS_LOGCATEGORY_XFER_IN, 1239 DNS_LOGMODULE_XFER_IN, 1240 ISC_LOG_DEBUG(10), xfr->mctx); 1241 else 1242 xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s", 1243 dns_result_totext(result)); 1244 1245 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror || 1246 (xfr->checkid && msg->id != xfr->id)) { 1247 if (result == ISC_R_SUCCESS) 1248 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/ 1249 if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) 1250 result = DNS_R_UNEXPECTEDID; 1251 if (xfr->reqtype == dns_rdatatype_axfr || 1252 xfr->reqtype == dns_rdatatype_soa) 1253 goto failure; 1254 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR", 1255 isc_result_totext(result)); 1256 try_axfr: 1257 dns_message_destroy(&msg); 1258 xfrin_reset(xfr); 1259 xfr->reqtype = dns_rdatatype_soa; 1260 xfr->state = XFRST_SOAQUERY; 1261 (void)xfrin_start(xfr); 1262 return; 1263 } 1264 1265 /* 1266 * Does the server know about IXFR? If it doesn't we will get 1267 * a message with a empty answer section or a potentially a CNAME / 1268 * DNAME, the later is handled by xfr_rr() which will return FORMERR 1269 * if the first RR in the answer section is not a SOA record. 1270 */ 1271 if (xfr->reqtype == dns_rdatatype_ixfr && 1272 xfr->state == XFRST_INITIALSOA && 1273 msg->counts[DNS_SECTION_ANSWER] == 0) { 1274 xfrin_log(xfr, ISC_LOG_DEBUG(3), 1275 "empty answer section, retrying with AXFR"); 1276 goto try_axfr; 1277 } 1278 1279 if (xfr->reqtype == dns_rdatatype_soa && 1280 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 1281 FAIL(DNS_R_NOTAUTHORITATIVE); 1282 } 1283 1284 1285 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone)); 1286 if (result != ISC_R_SUCCESS) { 1287 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s", 1288 isc_result_totext(result)); 1289 goto failure; 1290 } 1291 1292 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER); 1293 result == ISC_R_SUCCESS; 1294 result = dns_message_nextname(msg, DNS_SECTION_ANSWER)) 1295 { 1296 dns_rdataset_t *rds; 1297 1298 name = NULL; 1299 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); 1300 for (rds = ISC_LIST_HEAD(name->list); 1301 rds != NULL; 1302 rds = ISC_LIST_NEXT(rds, link)) 1303 { 1304 for (result = dns_rdataset_first(rds); 1305 result == ISC_R_SUCCESS; 1306 result = dns_rdataset_next(rds)) 1307 { 1308 dns_rdata_t rdata = DNS_RDATA_INIT; 1309 dns_rdataset_current(rds, &rdata); 1310 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata)); 1311 } 1312 } 1313 } 1314 if (result != ISC_R_NOMORE) 1315 goto failure; 1316 1317 if (dns_message_gettsig(msg, &tsigowner) != NULL) { 1318 /* 1319 * Reset the counter. 1320 */ 1321 xfr->sincetsig = 0; 1322 1323 /* 1324 * Free the last tsig, if there is one. 1325 */ 1326 if (xfr->lasttsig != NULL) 1327 isc_buffer_free(&xfr->lasttsig); 1328 1329 /* 1330 * Update the last tsig pointer. 1331 */ 1332 CHECK(dns_message_getquerytsig(msg, xfr->mctx, 1333 &xfr->lasttsig)); 1334 1335 } else if (dns_message_gettsigkey(msg) != NULL) { 1336 xfr->sincetsig++; 1337 if (xfr->sincetsig > 100 || xfr->nmsg == 0 || 1338 xfr->state == XFRST_AXFR_END || 1339 xfr->state == XFRST_IXFR_END) 1340 { 1341 result = DNS_R_EXPECTEDTSIG; 1342 goto failure; 1343 } 1344 } 1345 1346 /* 1347 * Update the number of messages received. 1348 */ 1349 xfr->nmsg++; 1350 1351 /* 1352 * Update the number of bytes received. 1353 */ 1354 xfr->nbytes += tcpmsg->buffer.used; 1355 1356 /* 1357 * Take the context back. 1358 */ 1359 INSIST(xfr->tsigctx == NULL); 1360 xfr->tsigctx = msg->tsigctx; 1361 msg->tsigctx = NULL; 1362 1363 dns_message_destroy(&msg); 1364 1365 switch (xfr->state) { 1366 case XFRST_GOTSOA: 1367 xfr->reqtype = dns_rdatatype_axfr; 1368 xfr->state = XFRST_INITIALSOA; 1369 CHECK(xfrin_send_request(xfr)); 1370 break; 1371 case XFRST_AXFR_END: 1372 CHECK(axfr_finalize(xfr)); 1373 /* FALLTHROUGH */ 1374 case XFRST_IXFR_END: 1375 /* 1376 * Close the journal. 1377 */ 1378 if (xfr->ixfr.journal != NULL) 1379 dns_journal_destroy(&xfr->ixfr.journal); 1380 1381 /* 1382 * Inform the caller we succeeded. 1383 */ 1384 if (xfr->done != NULL) { 1385 (xfr->done)(xfr->zone, ISC_R_SUCCESS); 1386 xfr->done = NULL; 1387 } 1388 /* 1389 * We should have no outstanding events at this 1390 * point, thus maybe_free() should succeed. 1391 */ 1392 xfr->shuttingdown = ISC_TRUE; 1393 maybe_free(xfr); 1394 break; 1395 default: 1396 /* 1397 * Read the next message. 1398 */ 1399 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, 1400 xfrin_recv_done, xfr)); 1401 xfr->recvs++; 1402 } 1403 return; 1404 1405 failure: 1406 if (msg != NULL) 1407 dns_message_destroy(&msg); 1408 if (result != ISC_R_SUCCESS) 1409 xfrin_fail(xfr, result, "failed while receiving responses"); 1410 } 1411 1412 static void 1413 xfrin_timeout(isc_task_t *task, isc_event_t *event) { 1414 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; 1415 1416 REQUIRE(VALID_XFRIN(xfr)); 1417 1418 UNUSED(task); 1419 1420 isc_event_free(&event); 1421 /* 1422 * This will log "giving up: timeout". 1423 */ 1424 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up"); 1425 } 1426 1427 static void 1428 maybe_free(dns_xfrin_ctx_t *xfr) { 1429 isc_uint64_t msecs; 1430 isc_uint64_t persec; 1431 1432 REQUIRE(VALID_XFRIN(xfr)); 1433 1434 if (! xfr->shuttingdown || xfr->refcount != 0 || 1435 xfr->connects != 0 || xfr->sends != 0 || 1436 xfr->recvs != 0) 1437 return; 1438 1439 /* 1440 * Calculate the length of time the transfer took, 1441 * and print a log message with the bytes and rate. 1442 */ 1443 isc_time_now(&xfr->end); 1444 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000; 1445 if (msecs == 0) 1446 msecs = 1; 1447 persec = (xfr->nbytes * 1000) / msecs; 1448 xfrin_log(xfr, ISC_LOG_INFO, 1449 "Transfer completed: %d messages, %d records, " 1450 "%" ISC_PRINT_QUADFORMAT "u bytes, " 1451 "%u.%03u secs (%u bytes/sec)", 1452 xfr->nmsg, xfr->nrecs, xfr->nbytes, 1453 (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000), 1454 (unsigned int) persec); 1455 1456 if (xfr->socket != NULL) 1457 isc_socket_detach(&xfr->socket); 1458 1459 if (xfr->timer != NULL) 1460 isc_timer_detach(&xfr->timer); 1461 1462 if (xfr->task != NULL) 1463 isc_task_detach(&xfr->task); 1464 1465 if (xfr->tsigkey != NULL) 1466 dns_tsigkey_detach(&xfr->tsigkey); 1467 1468 if (xfr->lasttsig != NULL) 1469 isc_buffer_free(&xfr->lasttsig); 1470 1471 dns_diff_clear(&xfr->diff); 1472 1473 if (xfr->ixfr.journal != NULL) 1474 dns_journal_destroy(&xfr->ixfr.journal); 1475 1476 if (xfr->axfr.add_private != NULL) 1477 (void)dns_db_endload(xfr->db, &xfr->axfr); 1478 1479 if (xfr->tcpmsg_valid) 1480 dns_tcpmsg_invalidate(&xfr->tcpmsg); 1481 1482 if (xfr->tsigctx != NULL) 1483 dst_context_destroy(&xfr->tsigctx); 1484 1485 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) 1486 dns_name_free(&xfr->name, xfr->mctx); 1487 1488 if (xfr->ver != NULL) 1489 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); 1490 1491 if (xfr->db != NULL) 1492 dns_db_detach(&xfr->db); 1493 1494 if (xfr->zone != NULL) 1495 dns_zone_idetach(&xfr->zone); 1496 1497 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); 1498 } 1499 1500 /* 1501 * Log incoming zone transfer messages in a format like 1502 * transfer of <zone> from <address>: <message> 1503 */ 1504 static void 1505 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr, 1506 const char *fmt, va_list ap) 1507 { 1508 char mastertext[ISC_SOCKADDR_FORMATSIZE]; 1509 char msgtext[2048]; 1510 1511 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext)); 1512 vsnprintf(msgtext, sizeof(msgtext), fmt, ap); 1513 1514 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, 1515 DNS_LOGMODULE_XFER_IN, level, 1516 "transfer of '%s' from %s: %s", 1517 zonetext, mastertext, msgtext); 1518 } 1519 1520 /* 1521 * Logging function for use when a xfrin_ctx_t has not yet been created. 1522 */ 1523 1524 static void 1525 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr, 1526 const char *fmt, ...) 1527 { 1528 va_list ap; 1529 1530 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 1531 return; 1532 1533 va_start(ap, fmt); 1534 xfrin_logv(level, zonetext, masteraddr, fmt, ap); 1535 va_end(ap); 1536 } 1537 1538 /* 1539 * Logging function for use when there is a xfrin_ctx_t. 1540 */ 1541 1542 static void 1543 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) 1544 { 1545 va_list ap; 1546 char zonetext[DNS_NAME_MAXTEXT+32]; 1547 1548 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 1549 return; 1550 1551 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext)); 1552 1553 va_start(ap, fmt); 1554 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap); 1555 va_end(ap); 1556 } 1557