xfrin.c revision f30785f506a522ed6a5e394af2bb13b6f883927e
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Copyright (C) 2004-2008, 2011 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 1999-2003 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews * purpose with or without fee is hereby granted, provided that the above
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews * copyright notice and this permission notice appear in all copies.
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
2bef3713093349af52ba61eaab07adf3207da873Mark Andrews/* $Id: xfrin.c,v 1.172 2011/12/22 07:32:41 each Exp $ */
a27bbd21cf07371fc71e7ade75c3d78a5b98b7f9Mark Andrews#include <isc/string.h> /* Required for HP/UX (and others?) */
8f1ed05dc0aae7ae6c3da6ec6d405df61257a61eMark Andrews * Incoming AXFR and IXFR.
8f1ed05dc0aae7ae6c3da6ec6d405df61257a61eMark Andrews * It would be non-sensical (or at least obtuse) to use FAIL() with an
8f1ed05dc0aae7ae6c3da6ec6d405df61257a61eMark Andrews * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
8f1ed05dc0aae7ae6c3da6ec6d405df61257a61eMark Andrews * from complaining about "end-of-loop code not reached".
8f25faf9720a0c2730c4ac80ea4c12ca1f25599fMukund Sivaraman if (result != ISC_R_SUCCESS) goto failure; \
8f25faf9720a0c2730c4ac80ea4c12ca1f25599fMukund Sivaraman if (result != ISC_R_SUCCESS) goto failure; \
8f25faf9720a0c2730c4ac80ea4c12ca1f25599fMukund Sivaraman * The states of the *XFR state machine. We handle both IXFR and AXFR
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * with a single integrated state machine because they cannot be distinguished
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * immediately - an AXFR response to an IXFR request can only be detected
d999ca28d40337907b55eebc28a255b638702379Evan Hunt * when the first two (2) response RRs have already been received.
d1f1f13c7fc1f1515930053508f1645cfafaa478Mark Andrewstypedef enum {
e45d0508c3460db87afb1f743bc5210522721bb3Evan Hunt * Incoming zone transfer context.
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews unsigned int magic;
820fdd61dd35e359a8e616031209d074a7140d97Evan Hunt * Requested transfer type (dns_rdatatype_axfr or
820fdd61dd35e359a8e616031209d074a7140d97Evan Hunt * dns_rdatatype_ixfr). The actual transfer type
820fdd61dd35e359a8e616031209d074a7140d97Evan Hunt * may differ due to IXFR->AXFR fallback.
076bda8c2e2b2f41775bd7b1694dd2cab287aeebMark Andrews /*% Buffer for IXFR/AXFR request message */
076bda8c2e2b2f41775bd7b1694dd2cab287aeebMark Andrews /*% Incoming reply TCP message */
820fdd61dd35e359a8e616031209d074a7140d97Evan Hunt unsigned int nmsg; /*%< Number of messages recvd */
820fdd61dd35e359a8e616031209d074a7140d97Evan Hunt unsigned int nrecs; /*%< Number of records recvd */
820fdd61dd35e359a8e616031209d074a7140d97Evan Hunt isc_uint64_t nbytes; /*%< Number of bytes received */
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews isc_time_t start; /*%< Start time of the transfer */
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews dst_context_t *tsigctx; /*%< TSIG verification context */
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews unsigned int sincetsig; /*%< recvd since the last TSIG */
1e34fe9044874422104e84373988d07876f716b6Mark Andrews * AXFR- and IXFR-specific data. Only one is used at a time
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * according to the is_ixfr flag, so this could be a union,
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * but keeping them separate makes it a bit simpler to clean
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * things up when destroying the context.
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews#define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
c14ba7107063650e7f4329e8c54adca57913381bEvan Hunt/**************************************************************************/
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * Forward declarations.
35f6a21f5f8114542c050bfcb484b39ce513d4bdEvan Huntstatic isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
35f6a21f5f8114542c050bfcb484b39ce513d4bdEvan Huntstatic isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
35f6a21f5f8114542c050bfcb484b39ce513d4bdEvan Huntstatic isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsstatic isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
35f6a21f5f8114542c050bfcb484b39ce513d4bdEvan Huntstatic isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
35f6a21f5f8114542c050bfcb484b39ce513d4bdEvan Huntstatic isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr);
c14ba7107063650e7f4329e8c54adca57913381bEvan Huntstatic isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
c14ba7107063650e7f4329e8c54adca57913381bEvan Huntstatic isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsstatic isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
baad8d9fd8dd054ce1edf350ff0c0f2038a1519eEvan Huntstatic isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
baad8d9fd8dd054ce1edf350ff0c0f2038a1519eEvan Huntstatic isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsstatic isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
baad8d9fd8dd054ce1edf350ff0c0f2038a1519eEvan Huntstatic void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
baad8d9fd8dd054ce1edf350ff0c0f2038a1519eEvan Huntstatic isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
baad8d9fd8dd054ce1edf350ff0c0f2038a1519eEvan Huntstatic void xfrin_send_done(isc_task_t *task, isc_event_t *event);
baad8d9fd8dd054ce1edf350ff0c0f2038a1519eEvan Huntstatic void xfrin_sendlen_done(isc_task_t *task, isc_event_t *event);
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsstatic void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsstatic void xfrin_timeout(isc_task_t *task, isc_event_t *event);
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaramanstatic void maybe_free(dns_xfrin_ctx_t *xfr);
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaramanxfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsrender(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaramanxfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaramanxfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaraman const char *fmt, ...)
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsxfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaraman/**************************************************************************/
0c29904b27c9ab3b85ecbde159b22ae1323bdbcdMukund Sivaraman * AXFR handling
0c2313eb367de3b58801d643d52c0fd9bc0e5df7Evan Hunt CHECK(dns_db_beginload(xfr->db, &xfr->axfr.add_func,
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsaxfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrewsaxfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews CHECK(dns_zone_checknames(xfr->zone, name, rdata));
43e2c588ba773f471a7a2459b10a67a800c576c6Mark Andrews * Store a set of AXFR RRs in the database.
075a3d60c23140f05db10d70126ff271ef6469c9Mark Andrews CHECK(dns_db_endload(xfr->db, &xfr->axfr.add_private));
7382f5160274938d143d82bda1941b32822dac53Mark Andrews CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE));
7382f5160274938d143d82bda1941b32822dac53Mark Andrews/**************************************************************************/
7382f5160274938d143d82bda1941b32822dac53Mark Andrews * IXFR handling
7382f5160274938d143d82bda1941b32822dac53Mark Andrews "got incremental response to AXFR request");
30ca20f720ad0887772a79e7abb25b4fa0e4b5b0Mark Andrewsixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
30ca20f720ad0887772a79e7abb25b4fa0e4b5b0Mark Andrews dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
30ca20f720ad0887772a79e7abb25b4fa0e4b5b0Mark Andrews CHECK(dns_zone_checknames(xfr->zone, name, rdata));
static isc_result_t
goto failure;
return (result);
static isc_result_t
return (result);
static isc_result_t
redo:
case XFRST_SOAQUERY:
case XFRST_GOTSOA:
case XFRST_INITIALSOA:
case XFRST_FIRSTDATA:
goto redo;
case XFRST_IXFR_DELSOA:
case XFRST_IXFR_DEL:
goto redo;
case XFRST_IXFR_ADDSOA:
case XFRST_IXFR_ADD:
goto redo;
case XFRST_AXFR:
case XFRST_AXFR_END:
case XFRST_IXFR_END:
INSIST(0);
return (result);
case PF_INET:
case PF_INET6:
INSIST(0);
return (result);
static isc_result_t
return (ISC_R_NOMEMORY);
/* ixfr.current_serial */
ISC_FALSE));
return (ISC_R_SUCCESS);
return (result);
static isc_result_t
#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
return (ISC_R_SUCCESS);
return (result);
static isc_result_t
if (cleanup_cctx)
return (result);
goto failure;
static isc_result_t
return (ISC_R_SUCCESS);
return (result);
static isc_result_t
return (result);
goto failure;
goto try_axfr;
goto failure;
goto failure;
goto failure;
case XFRST_GOTSOA:
case XFRST_AXFR_END:
case XFRST_IXFR_END:
if (msecs == 0)
(unsigned int) persec);
const char *fmt, ...)