summaryrefslogtreecommitdiff
path: root/contrib/bind9/lib/dns/xfrin.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns/xfrin.c')
-rw-r--r--contrib/bind9/lib/dns/xfrin.c1404
1 files changed, 0 insertions, 1404 deletions
diff --git a/contrib/bind9/lib/dns/xfrin.c b/contrib/bind9/lib/dns/xfrin.c
deleted file mode 100644
index 8a824a73ef5e..000000000000
--- a/contrib/bind9/lib/dns/xfrin.c
+++ /dev/null
@@ -1,1404 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: xfrin.c,v 1.124.2.4.2.12 2005/11/03 23:08:41 marka Exp $ */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/random.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/task.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/diff.h>
-#include <dns/events.h>
-#include <dns/journal.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/rdataclass.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/result.h>
-#include <dns/soa.h>
-#include <dns/tcpmsg.h>
-#include <dns/timer.h>
-#include <dns/tsig.h>
-#include <dns/view.h>
-#include <dns/xfrin.h>
-#include <dns/zone.h>
-
-#include <dst/dst.h>
-
-/*
- * Incoming AXFR and IXFR.
- */
-
-/*
- * It would be non-sensical (or at least obtuse) to use FAIL() with an
- * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
- * from complaining about "end-of-loop code not reached".
- */
-#define FAIL(code) \
- do { result = (code); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-/*
- * The states of the *XFR state machine. We handle both IXFR and AXFR
- * with a single integrated state machine because they cannot be distinguished
- * immediately - an AXFR response to an IXFR request can only be detected
- * when the first two (2) response RRs have already been received.
- */
-typedef enum {
- XFRST_INITIALSOA,
- XFRST_FIRSTDATA,
- XFRST_IXFR_DELSOA,
- XFRST_IXFR_DEL,
- XFRST_IXFR_ADDSOA,
- XFRST_IXFR_ADD,
- XFRST_AXFR,
- XFRST_END
-} xfrin_state_t;
-
-/*
- * Incoming zone transfer context.
- */
-
-struct dns_xfrin_ctx {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_zone_t *zone;
-
- int refcount;
-
- isc_task_t *task;
- isc_timer_t *timer;
- isc_socketmgr_t *socketmgr;
-
- int connects; /* Connect in progress */
- int sends; /* Send in progress */
- int recvs; /* Receive in progress */
- isc_boolean_t shuttingdown;
-
- dns_name_t name; /* Name of zone to transfer */
- dns_rdataclass_t rdclass;
-
- isc_boolean_t checkid;
- dns_messageid_t id;
-
- /*
- * Requested transfer type (dns_rdatatype_axfr or
- * dns_rdatatype_ixfr). The actual transfer type
- * may differ due to IXFR->AXFR fallback.
- */
- dns_rdatatype_t reqtype;
-
- isc_sockaddr_t masteraddr;
- isc_sockaddr_t sourceaddr;
- isc_socket_t *socket;
-
- /* Buffer for IXFR/AXFR request message */
- isc_buffer_t qbuffer;
- unsigned char qbuffer_data[512];
-
- /* Incoming reply TCP message */
- dns_tcpmsg_t tcpmsg;
- isc_boolean_t tcpmsg_valid;
-
- dns_db_t *db;
- dns_dbversion_t *ver;
- dns_diff_t diff; /* Pending database changes */
- int difflen; /* Number of pending tuples */
-
- xfrin_state_t state;
- isc_uint32_t end_serial;
- isc_boolean_t is_ixfr;
-
- unsigned int nmsg; /* Number of messages recvd */
-
- dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
- isc_buffer_t *lasttsig; /* The last TSIG */
- dst_context_t *tsigctx; /* TSIG verification context */
- unsigned int sincetsig; /* recvd since the last TSIG */
- dns_xfrindone_t done;
-
- /*
- * AXFR- and IXFR-specific data. Only one is used at a time
- * according to the is_ixfr flag, so this could be a union,
- * but keeping them separate makes it a bit simpler to clean
- * things up when destroying the context.
- */
- struct {
- dns_addrdatasetfunc_t add_func;
- dns_dbload_t *add_private;
- } axfr;
-
- struct {
- isc_uint32_t request_serial;
- isc_uint32_t current_serial;
- dns_journal_t *journal;
-
- } ixfr;
-};
-
-#define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
-#define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
-
-/**************************************************************************/
-/*
- * Forward declarations.
- */
-
-static isc_result_t
-xfrin_create(isc_mem_t *mctx,
- dns_zone_t *zone,
- dns_db_t *db,
- isc_task_t *task,
- isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr,
- dns_name_t *zonename,
- dns_rdataclass_t rdclass,
- dns_rdatatype_t reqtype,
- isc_sockaddr_t *masteraddr,
- isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey,
- dns_xfrin_ctx_t **xfrp);
-
-static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
-static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
-static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl,
- dns_rdata_t *rdata);
-static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
-static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
-
-static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
-static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
-static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl,
- dns_rdata_t *rdata);
-static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
-
-static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
- isc_uint32_t ttl, dns_rdata_t *rdata);
-
-static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
-
-static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
-static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
-static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
-static void xfrin_sendlen_done(isc_task_t *task, isc_event_t *event);
-static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
-static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
-
-static void maybe_free(dns_xfrin_ctx_t *xfr);
-
-static void
-xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
-static isc_result_t
-render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
-
-static void
-xfrin_logv(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,
- isc_sockaddr_t *masteraddr, const char *fmt, va_list ap)
- ISC_FORMAT_PRINTF(5, 0);
-
-static void
-xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,
- isc_sockaddr_t *masteraddr, const char *fmt, ...)
- ISC_FORMAT_PRINTF(5, 6);
-
-static void
-xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-
-/**************************************************************************/
-/*
- * AXFR handling
- */
-
-static isc_result_t
-axfr_init(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- xfr->is_ixfr = ISC_FALSE;
-
- if (xfr->db != NULL)
- dns_db_detach(&xfr->db);
-
- CHECK(axfr_makedb(xfr, &xfr->db));
- CHECK(dns_db_beginload(xfr->db, &xfr->axfr.add_func,
- &xfr->axfr.add_private));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
- return (dns_db_create(xfr->mctx, /* XXX */
- "rbt", /* XXX guess */
- &xfr->name,
- dns_dbtype_zone,
- xfr->rdclass,
- 0, NULL, /* XXX guess */
- dbp));
-}
-
-static isc_result_t
-axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- dns_difftuple_t *tuple = NULL;
-
- CHECK(dns_zone_checknames(xfr->zone, name, rdata));
- CHECK(dns_difftuple_create(xfr->diff.mctx, op,
- name, ttl, rdata, &tuple));
- dns_diff_append(&xfr->diff, &tuple);
- if (++xfr->difflen > 100)
- CHECK(axfr_apply(xfr));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/*
- * Store a set of AXFR RRs in the database.
- */
-static isc_result_t
-axfr_apply(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- CHECK(dns_diff_load(&xfr->diff,
- xfr->axfr.add_func, xfr->axfr.add_private));
- xfr->difflen = 0;
- dns_diff_clear(&xfr->diff);
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-axfr_commit(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- CHECK(axfr_apply(xfr));
- CHECK(dns_db_endload(xfr->db, &xfr->axfr.add_private));
- CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE));
-
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/**************************************************************************/
-/*
- * IXFR handling
- */
-
-static isc_result_t
-ixfr_init(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
- char *journalfile;
-
- if (xfr->reqtype != dns_rdatatype_ixfr) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "got incremental response to AXFR request");
- return (DNS_R_FORMERR);
- }
-
- xfr->is_ixfr = ISC_TRUE;
- INSIST(xfr->db != NULL);
- xfr->difflen = 0;
-
- journalfile = dns_zone_getjournal(xfr->zone);
- if (journalfile != NULL)
- CHECK(dns_journal_open(xfr->mctx, journalfile,
- ISC_TRUE, &xfr->ixfr.journal));
-
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- dns_difftuple_t *tuple = NULL;
- if (op == DNS_DIFFOP_ADD)
- CHECK(dns_zone_checknames(xfr->zone, name, rdata));
- CHECK(dns_difftuple_create(xfr->diff.mctx, op,
- name, ttl, rdata, &tuple));
- dns_diff_append(&xfr->diff, &tuple);
- if (++xfr->difflen > 100)
- CHECK(ixfr_apply(xfr));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/*
- * Apply a set of IXFR changes to the database.
- */
-static isc_result_t
-ixfr_apply(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- if (xfr->ver == NULL) {
- CHECK(dns_db_newversion(xfr->db, &xfr->ver));
- if (xfr->ixfr.journal != NULL)
- CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
- }
- CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
- if (xfr->ixfr.journal != NULL) {
- result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
- if (result != ISC_R_SUCCESS)
- goto failure;
- }
- dns_diff_clear(&xfr->diff);
- xfr->difflen = 0;
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-ixfr_commit(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- CHECK(ixfr_apply(xfr));
- if (xfr->ver != NULL) {
- /* XXX enter ready-to-commit state here */
- if (xfr->ixfr.journal != NULL)
- CHECK(dns_journal_commit(xfr->ixfr.journal));
- dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE);
- dns_zone_markdirty(xfr->zone);
- }
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/**************************************************************************/
-/*
- * Common AXFR/IXFR protocol code
- */
-
-/*
- * Handle a single incoming resource record according to the current
- * state.
- */
-static isc_result_t
-xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
- dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- redo:
- switch (xfr->state) {
- case XFRST_INITIALSOA:
- if (rdata->type != dns_rdatatype_soa) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "first RR in zone transfer must be SOA");
- FAIL(DNS_R_FORMERR);
- }
- /*
- * Remember the serial number in the intial SOA.
- * We need it to recognize the end of an IXFR.
- */
- xfr->end_serial = dns_soa_getserial(rdata);
- if (xfr->reqtype == dns_rdatatype_ixfr &&
- ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial)
- && !dns_zone_isforced(xfr->zone))
- {
- /*
- * This must be the single SOA record that is
- * sent when the current version on the master
- * is not newer than the version in the request.
- */
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "requested serial %u, "
- "master has %u, not updating",
- xfr->ixfr.request_serial, xfr->end_serial);
- FAIL(DNS_R_UPTODATE);
- }
- if (xfr->reqtype == dns_rdatatype_axfr)
- xfr->checkid = ISC_FALSE;
- xfr->state = XFRST_FIRSTDATA;
- break;
-
- case XFRST_FIRSTDATA:
- /*
- * If the transfer begins with one SOA record, it is an AXFR,
- * if it begins with two SOAs, it is an IXFR.
- */
- if (xfr->reqtype == dns_rdatatype_ixfr &&
- rdata->type == dns_rdatatype_soa &&
- xfr->ixfr.request_serial == dns_soa_getserial(rdata)) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "got incremental response");
- CHECK(ixfr_init(xfr));
- xfr->state = XFRST_IXFR_DELSOA;
- } else {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "got nonincremental response");
- CHECK(axfr_init(xfr));
- xfr->state = XFRST_AXFR;
- }
- goto redo;
-
- case XFRST_IXFR_DELSOA:
- INSIST(rdata->type == dns_rdatatype_soa);
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
- xfr->state = XFRST_IXFR_DEL;
- break;
-
- case XFRST_IXFR_DEL:
- if (rdata->type == dns_rdatatype_soa) {
- isc_uint32_t soa_serial = dns_soa_getserial(rdata);
- xfr->state = XFRST_IXFR_ADDSOA;
- xfr->ixfr.current_serial = soa_serial;
- goto redo;
- }
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
- break;
-
- case XFRST_IXFR_ADDSOA:
- INSIST(rdata->type == dns_rdatatype_soa);
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
- xfr->state = XFRST_IXFR_ADD;
- break;
-
- case XFRST_IXFR_ADD:
- if (rdata->type == dns_rdatatype_soa) {
- isc_uint32_t soa_serial = dns_soa_getserial(rdata);
- if (soa_serial == xfr->end_serial) {
- CHECK(ixfr_commit(xfr));
- xfr->state = XFRST_END;
- break;
- } else if (soa_serial != xfr->ixfr.current_serial) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "IXFR out of sync: "
- "expected serial %u, got %u",
- xfr->ixfr.current_serial, soa_serial);
- FAIL(DNS_R_FORMERR);
- } else {
- CHECK(ixfr_commit(xfr));
- xfr->state = XFRST_IXFR_DELSOA;
- goto redo;
- }
- }
- if (rdata->type == dns_rdatatype_ns &&
- dns_name_iswildcard(name))
- FAIL(DNS_R_INVALIDNS);
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
- break;
-
- case XFRST_AXFR:
- /*
- * Old BINDs sent cross class A records for non IN classes.
- */
- if (rdata->type == dns_rdatatype_a &&
- rdata->rdclass != xfr->rdclass &&
- xfr->rdclass != dns_rdataclass_in)
- break;
- CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
- if (rdata->type == dns_rdatatype_soa) {
- CHECK(axfr_commit(xfr));
- xfr->state = XFRST_END;
- break;
- }
- break;
- case XFRST_END:
- FAIL(DNS_R_EXTRADATA);
- default:
- INSIST(0);
- break;
- }
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-isc_result_t
-dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
- isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
- isc_mem_t *mctx, isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr, isc_task_t *task,
- dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
-{
- isc_sockaddr_t sourceaddr;
-
- switch (isc_sockaddr_pf(masteraddr)) {
- case PF_INET:
- sourceaddr = *dns_zone_getxfrsource4(zone);
- break;
- case PF_INET6:
- sourceaddr = *dns_zone_getxfrsource6(zone);
- break;
- default:
- INSIST(0);
- }
-
- return(dns_xfrin_create2(zone, xfrtype, masteraddr, &sourceaddr,
- tsigkey, mctx, timermgr, socketmgr,
- task, done, xfrp));
-}
-
-isc_result_t
-dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
- isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
- isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
- isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
-{
- dns_name_t *zonename = dns_zone_getorigin(zone);
- dns_xfrin_ctx_t *xfr = NULL;
- isc_result_t result;
- dns_db_t *db = NULL;
-
- REQUIRE(xfrp != NULL && *xfrp == NULL);
-
- (void)dns_zone_getdb(zone, &db);
-
- CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
- dns_zone_getclass(zone), xfrtype, masteraddr,
- sourceaddr, tsigkey, &xfr));
-
- CHECK(xfrin_start(xfr));
-
- xfr->done = done;
- xfr->refcount++;
- *xfrp = xfr;
-
- failure:
- if (db != NULL)
- dns_db_detach(&db);
- if (result != ISC_R_SUCCESS)
- xfrin_log1(ISC_LOG_ERROR, zonename, dns_zone_getclass(zone),
- masteraddr, "zone transfer setup failed");
- return (result);
-}
-
-void
-dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
- if (! xfr->shuttingdown)
- xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
-}
-
-void
-dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
- REQUIRE(target != NULL && *target == NULL);
- source->refcount++;
- *target = source;
-}
-
-void
-dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
- dns_xfrin_ctx_t *xfr = *xfrp;
- INSIST(xfr->refcount > 0);
- xfr->refcount--;
- maybe_free(xfr);
- *xfrp = NULL;
-}
-
-static void
-xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
- if (xfr->connects > 0) {
- isc_socket_cancel(xfr->socket, xfr->task,
- ISC_SOCKCANCEL_CONNECT);
- } else if (xfr->recvs > 0) {
- dns_tcpmsg_cancelread(&xfr->tcpmsg);
- } else if (xfr->sends > 0) {
- isc_socket_cancel(xfr->socket, xfr->task,
- ISC_SOCKCANCEL_SEND);
- }
-}
-
-static void
-xfrin_reset(dns_xfrin_ctx_t *xfr) {
- REQUIRE(VALID_XFRIN(xfr));
-
- xfrin_log(xfr, ISC_LOG_INFO, "resetting");
-
- xfrin_cancelio(xfr);
-
- if (xfr->socket != NULL)
- isc_socket_detach(&xfr->socket);
-
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- dns_diff_clear(&xfr->diff);
- xfr->difflen = 0;
-
- if (xfr->ixfr.journal != NULL)
- dns_journal_destroy(&xfr->ixfr.journal);
-
- if (xfr->axfr.add_private != NULL) {
- (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
- xfr->axfr.add_func = NULL;
- }
-
- if (xfr->tcpmsg_valid) {
- dns_tcpmsg_invalidate(&xfr->tcpmsg);
- xfr->tcpmsg_valid = ISC_FALSE;
- }
-
- if (xfr->ver != NULL)
- dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
-}
-
-
-static void
-xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
- if (result != DNS_R_UPTODATE) {
- xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
- msg, isc_result_totext(result));
- if (xfr->is_ixfr)
- /* Pass special result code to force AXFR retry */
- result = DNS_R_BADIXFR;
- }
- xfrin_cancelio(xfr);
- if (xfr->done != NULL) {
- (xfr->done)(xfr->zone, result);
- xfr->done = NULL;
- }
- xfr->shuttingdown = ISC_TRUE;
- maybe_free(xfr);
-}
-
-static isc_result_t
-xfrin_create(isc_mem_t *mctx,
- dns_zone_t *zone,
- dns_db_t *db,
- isc_task_t *task,
- isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr,
- dns_name_t *zonename,
- dns_rdataclass_t rdclass,
- dns_rdatatype_t reqtype,
- isc_sockaddr_t *masteraddr,
- isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey,
- dns_xfrin_ctx_t **xfrp)
-{
- dns_xfrin_ctx_t *xfr = NULL;
- isc_result_t result;
- isc_uint32_t tmp;
-
- xfr = isc_mem_get(mctx, sizeof(*xfr));
- if (xfr == NULL)
- return (ISC_R_NOMEMORY);
- xfr->mctx = mctx;
- xfr->refcount = 0;
- xfr->zone = NULL;
- dns_zone_iattach(zone, &xfr->zone);
- xfr->task = NULL;
- isc_task_attach(task, &xfr->task);
- xfr->timer = NULL;
- xfr->socketmgr = socketmgr;
- xfr->done = NULL;
-
- xfr->connects = 0;
- xfr->sends = 0;
- xfr->recvs = 0;
- xfr->shuttingdown = ISC_FALSE;
-
- dns_name_init(&xfr->name, NULL);
- xfr->rdclass = rdclass;
- isc_random_get(&tmp);
- xfr->checkid = ISC_TRUE;
- xfr->id = (isc_uint16_t)(tmp & 0xffff);
- xfr->reqtype = reqtype;
-
- /* sockaddr */
- xfr->socket = NULL;
- /* qbuffer */
- /* qbuffer_data */
- /* tcpmsg */
- xfr->tcpmsg_valid = ISC_FALSE;
-
- xfr->db = NULL;
- if (db != NULL)
- dns_db_attach(db, &xfr->db);
- xfr->ver = NULL;
- dns_diff_init(xfr->mctx, &xfr->diff);
- xfr->difflen = 0;
-
- xfr->state = XFRST_INITIALSOA;
- /* end_serial */
-
- xfr->nmsg = 0;
-
- xfr->tsigkey = NULL;
- if (tsigkey != NULL)
- dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
- xfr->lasttsig = NULL;
- xfr->tsigctx = NULL;
- xfr->sincetsig = 0;
- xfr->is_ixfr = ISC_FALSE;
-
- /* ixfr.request_serial */
- /* ixfr.current_serial */
- xfr->ixfr.journal = NULL;
-
- xfr->axfr.add_func = NULL;
- xfr->axfr.add_private = NULL;
-
- CHECK(dns_name_dup(zonename, mctx, &xfr->name));
-
- CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
- task, xfrin_timeout, xfr, &xfr->timer));
- CHECK(dns_timer_setidle(xfr->timer,
- dns_zone_getmaxxfrin(xfr->zone),
- dns_zone_getidlein(xfr->zone),
- ISC_FALSE));
-
- xfr->masteraddr = *masteraddr;
-
- INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
- xfr->sourceaddr = *sourceaddr;
- isc_sockaddr_setport(&xfr->sourceaddr, 0);
-
- isc_buffer_init(&xfr->qbuffer, xfr->qbuffer_data,
- sizeof(xfr->qbuffer_data));
-
- xfr->magic = XFRIN_MAGIC;
- *xfrp = xfr;
- return (ISC_R_SUCCESS);
-
- failure:
- xfrin_fail(xfr, result, "failed creating transfer context");
- return (result);
-}
-
-static isc_result_t
-xfrin_start(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
- CHECK(isc_socket_create(xfr->socketmgr,
- isc_sockaddr_pf(&xfr->sourceaddr),
- isc_sockettype_tcp,
- &xfr->socket));
- CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr));
- CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
- xfrin_connect_done, xfr));
- xfr->connects++;
- return (ISC_R_SUCCESS);
- failure:
- xfrin_fail(xfr, result, "failed setting up socket");
- return (result);
-}
-
-/* XXX the resolver could use this, too */
-
-static isc_result_t
-render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
- dns_compress_t cctx;
- isc_boolean_t cleanup_cctx = ISC_FALSE;
- isc_result_t result;
-
- CHECK(dns_compress_init(&cctx, -1, mctx));
- cleanup_cctx = ISC_TRUE;
- CHECK(dns_message_renderbegin(msg, &cctx, buf));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
- CHECK(dns_message_renderend(msg));
- result = ISC_R_SUCCESS;
- failure:
- if (cleanup_cctx)
- dns_compress_invalidate(&cctx);
- return (result);
-}
-
-/*
- * A connection has been established.
- */
-static void
-xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
- isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
- isc_result_t evresult = cev->result;
- isc_result_t result;
- char sourcetext[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_t sockaddr;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
- isc_event_free(&event);
-
- xfr->connects--;
- if (xfr->shuttingdown) {
- maybe_free(xfr);
- return;
- }
-
- CHECK(evresult);
- result = isc_socket_getsockname(xfr->socket, &sockaddr);
- if (result == ISC_R_SUCCESS) {
- isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
- } else
- strcpy(sourcetext, "<UNKNOWN>");
- xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext);
-
- dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
- xfr->tcpmsg_valid = ISC_TRUE;
-
- CHECK(xfrin_send_request(xfr));
- failure:
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed to connect");
-}
-
-/*
- * Convert a tuple into a dns_name_t suitable for inserting
- * into the given dns_message_t.
- */
-static isc_result_t
-tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
-{
- isc_result_t result;
- dns_rdata_t *rdata = NULL;
- dns_rdatalist_t *rdl = NULL;
- dns_rdataset_t *rds = NULL;
- dns_name_t *name = NULL;
-
- REQUIRE(target != NULL && *target == NULL);
-
- CHECK(dns_message_gettemprdata(msg, &rdata));
- dns_rdata_init(rdata);
- dns_rdata_clone(&tuple->rdata, rdata);
-
- CHECK(dns_message_gettemprdatalist(msg, &rdl));
- dns_rdatalist_init(rdl);
- rdl->type = tuple->rdata.type;
- rdl->rdclass = tuple->rdata.rdclass;
- rdl->ttl = tuple->ttl;
- ISC_LIST_APPEND(rdl->rdata, rdata, link);
-
- CHECK(dns_message_gettemprdataset(msg, &rds));
- dns_rdataset_init(rds);
- CHECK(dns_rdatalist_tordataset(rdl, rds));
-
- CHECK(dns_message_gettempname(msg, &name));
- dns_name_init(name, NULL);
- dns_name_clone(&tuple->name, name);
- ISC_LIST_APPEND(name->list, rds, link);
-
- *target = name;
- return (ISC_R_SUCCESS);
-
- failure:
-
- if (rds != NULL) {
- dns_rdataset_disassociate(rds);
- dns_message_puttemprdataset(msg, &rds);
- }
- if (rdl != NULL) {
- ISC_LIST_UNLINK(rdl->rdata, rdata, link);
- dns_message_puttemprdatalist(msg, &rdl);
- }
- if (rdata != NULL)
- dns_message_puttemprdata(msg, &rdata);
-
- return (result);
-}
-
-
-/*
- * Build an *XFR request and send its length prefix.
- */
-static isc_result_t
-xfrin_send_request(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
- isc_region_t region;
- isc_region_t lregion;
- dns_rdataset_t *qrdataset = NULL;
- dns_message_t *msg = NULL;
- unsigned char length[2];
- dns_difftuple_t *soatuple = NULL;
- dns_name_t *qname = NULL;
- dns_dbversion_t *ver = NULL;
- dns_name_t *msgsoaname = NULL;
-
- /* Create the request message */
- CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
- CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
-
- /* Create a name for the question section. */
- CHECK(dns_message_gettempname(msg, &qname));
- dns_name_init(qname, NULL);
- dns_name_clone(&xfr->name, qname);
-
- /* Formulate the question and attach it to the question name. */
- CHECK(dns_message_gettemprdataset(msg, &qrdataset));
- dns_rdataset_init(qrdataset);
- dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
- ISC_LIST_APPEND(qname->list, qrdataset, link);
- qrdataset = NULL;
-
- dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
- qname = NULL;
-
- if (xfr->reqtype == dns_rdatatype_ixfr) {
- /* Get the SOA and add it to the authority section. */
- /* XXX is using the current version the right thing? */
- dns_db_currentversion(xfr->db, &ver);
- CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
- DNS_DIFFOP_EXISTS, &soatuple));
- xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
- xfr->ixfr.current_serial = xfr->ixfr.request_serial;
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "requesting IXFR for serial %u",
- xfr->ixfr.request_serial);
-
- CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
- dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
- }
-
- xfr->checkid = ISC_TRUE;
- xfr->id++;
- msg->id = xfr->id;
-
- CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
-
- /*
- * Free the last tsig, if there is one.
- */
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- /*
- * Save the query TSIG and don't let message_destroy free it.
- */
- CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
-
- isc_buffer_usedregion(&xfr->qbuffer, &region);
- INSIST(region.length <= 65535);
-
- length[0] = region.length >> 8;
- length[1] = region.length & 0xFF;
- lregion.base = length;
- lregion.length = 2;
- CHECK(isc_socket_send(xfr->socket, &lregion, xfr->task,
- xfrin_sendlen_done, xfr));
- xfr->sends++;
-
- failure:
- if (qname != NULL)
- dns_message_puttempname(msg, &qname);
- if (qrdataset != NULL)
- dns_message_puttemprdataset(msg, &qrdataset);
- if (msg != NULL)
- dns_message_destroy(&msg);
- if (soatuple != NULL)
- dns_difftuple_free(&soatuple);
- if (ver != NULL)
- dns_db_closeversion(xfr->db, &ver, ISC_FALSE);
- return (result);
-}
-
-/* XXX there should be library support for sending DNS TCP messages */
-
-static void
-xfrin_sendlen_done(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sev = (isc_socketevent_t *) event;
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
- isc_result_t evresult = sev->result;
- isc_result_t result;
- isc_region_t region;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
- isc_event_free(&event);
-
- xfr->sends--;
- if (xfr->shuttingdown) {
- maybe_free(xfr);
- return;
- }
-
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request length prefix");
- CHECK(evresult);
-
- isc_buffer_usedregion(&xfr->qbuffer, &region);
- CHECK(isc_socket_send(xfr->socket, &region, xfr->task,
- xfrin_send_done, xfr));
- xfr->sends++;
- failure:
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed sending request length prefix");
-}
-
-
-static void
-xfrin_send_done(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sev = (isc_socketevent_t *) event;
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
- isc_result_t result;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
-
- xfr->sends--;
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
- CHECK(sev->result);
-
- CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
- xfrin_recv_done, xfr));
- xfr->recvs++;
- failure:
- isc_event_free(&event);
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed sending request data");
-}
-
-
-static void
-xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
- isc_result_t result;
- dns_message_t *msg = NULL;
- dns_name_t *name;
- dns_tcpmsg_t *tcpmsg;
- dns_name_t *tsigowner = NULL;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
- tcpmsg = ev->ev_sender;
- isc_event_free(&ev);
-
- xfr->recvs--;
- if (xfr->shuttingdown) {
- maybe_free(xfr);
- return;
- }
-
- CHECK(tcpmsg->result);
-
- xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
- tcpmsg->buffer.used);
-
- CHECK(isc_timer_touch(xfr->timer));
-
- CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
-
- CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
- CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
- msg->tsigctx = xfr->tsigctx;
- if (xfr->nmsg > 0)
- msg->tcp_continuation = 1;
-
- result = dns_message_parse(msg, &tcpmsg->buffer,
- DNS_MESSAGEPARSE_PRESERVEORDER);
-
- if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
- (xfr->checkid && msg->id != xfr->id)) {
- if (result == ISC_R_SUCCESS)
- result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
- if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
- result = DNS_R_UNEXPECTEDID;
- if (xfr->reqtype == dns_rdatatype_axfr ||
- xfr->reqtype == dns_rdatatype_soa)
- FAIL(result);
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
- isc_result_totext(result));
- try_axfr:
- dns_message_destroy(&msg);
- xfrin_reset(xfr);
- xfr->reqtype = dns_rdatatype_axfr;
- xfr->state = XFRST_INITIALSOA;
- (void)xfrin_start(xfr);
- return;
- }
-
- /*
- * Does the server know about IXFR? If it doesn't we will get
- * a message with a empty answer section or a potentially a CNAME /
- * DNAME, the later is handled by xfr_rr() which will return FORMERR
- * if the first RR in the answer section is not a SOA record.
- */
- if (xfr->reqtype == dns_rdatatype_ixfr &&
- xfr->state == XFRST_INITIALSOA &&
- msg->counts[DNS_SECTION_ANSWER] == 0) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "empty answer section, retrying with AXFR");
- goto try_axfr;
- }
-
- if (xfr->reqtype == dns_rdatatype_soa &&
- (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
- FAIL(DNS_R_NOTAUTHORITATIVE);
- }
-
-
- result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
- if (result != ISC_R_SUCCESS) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
- isc_result_totext(result));
- FAIL(result);
- }
-
- for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
- {
- dns_rdataset_t *rds;
-
- name = NULL;
- dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
- for (rds = ISC_LIST_HEAD(name->list);
- rds != NULL;
- rds = ISC_LIST_NEXT(rds, link))
- {
- for (result = dns_rdataset_first(rds);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rds))
- {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(rds, &rdata);
- CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
- }
- }
- }
- if (result != ISC_R_NOMORE)
- goto failure;
-
- if (dns_message_gettsig(msg, &tsigowner) != NULL) {
- /*
- * Reset the counter.
- */
- xfr->sincetsig = 0;
-
- /*
- * Free the last tsig, if there is one.
- */
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- /*
- * Update the last tsig pointer.
- */
- CHECK(dns_message_getquerytsig(msg, xfr->mctx,
- &xfr->lasttsig));
-
- } else if (dns_message_gettsigkey(msg) != NULL) {
- xfr->sincetsig++;
- if (xfr->sincetsig > 100 ||
- xfr->nmsg == 0 || xfr->state == XFRST_END)
- {
- result = DNS_R_EXPECTEDTSIG;
- goto failure;
- }
- }
-
- /*
- * Update the number of messages received.
- */
- xfr->nmsg++;
-
- /*
- * Copy the context back.
- */
- xfr->tsigctx = msg->tsigctx;
-
- dns_message_destroy(&msg);
-
- if (xfr->state == XFRST_END) {
- /*
- * Inform the caller we succeeded.
- */
- if (xfr->done != NULL) {
- (xfr->done)(xfr->zone, ISC_R_SUCCESS);
- xfr->done = NULL;
- }
- /*
- * We should have no outstanding events at this
- * point, thus maybe_free() should succeed.
- */
- xfr->shuttingdown = ISC_TRUE;
- maybe_free(xfr);
- } else {
- /*
- * Read the next message.
- */
- CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
- xfrin_recv_done, xfr));
- xfr->recvs++;
- }
- return;
-
- failure:
- if (msg != NULL)
- dns_message_destroy(&msg);
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed while receiving responses");
-}
-
-static void
-xfrin_timeout(isc_task_t *task, isc_event_t *event) {
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- isc_event_free(&event);
- /*
- * This will log "giving up: timeout".
- */
- xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
-}
-
-static void
-maybe_free(dns_xfrin_ctx_t *xfr) {
- REQUIRE(VALID_XFRIN(xfr));
-
- if (! xfr->shuttingdown || xfr->refcount != 0 ||
- xfr->connects != 0 || xfr->sends != 0 ||
- xfr->recvs != 0)
- return;
-
- xfrin_log(xfr, ISC_LOG_INFO, "end of transfer");
-
- if (xfr->socket != NULL)
- isc_socket_detach(&xfr->socket);
-
- if (xfr->timer != NULL)
- isc_timer_detach(&xfr->timer);
-
- if (xfr->task != NULL)
- isc_task_detach(&xfr->task);
-
- if (xfr->tsigkey != NULL)
- dns_tsigkey_detach(&xfr->tsigkey);
-
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- dns_diff_clear(&xfr->diff);
-
- if (xfr->ixfr.journal != NULL)
- dns_journal_destroy(&xfr->ixfr.journal);
-
- if (xfr->axfr.add_private != NULL)
- (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
-
- if (xfr->tcpmsg_valid)
- dns_tcpmsg_invalidate(&xfr->tcpmsg);
-
- if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
- dns_name_free(&xfr->name, xfr->mctx);
-
- if (xfr->ver != NULL)
- dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
-
- if (xfr->db != NULL)
- dns_db_detach(&xfr->db);
-
- if (xfr->zone != NULL)
- dns_zone_idetach(&xfr->zone);
-
- isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));
-}
-
-/*
- * Log incoming zone transfer messages in a format like
- * transfer of <zone> from <address>: <message>
- */
-static void
-xfrin_logv(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,
- isc_sockaddr_t *masteraddr, const char *fmt, va_list ap)
-{
- char zntext[DNS_NAME_FORMATSIZE];
- char mastertext[ISC_SOCKADDR_FORMATSIZE];
- char classtext[DNS_RDATACLASS_FORMATSIZE];
- char msgtext[2048];
-
- dns_name_format(zonename, zntext, sizeof(zntext));
- dns_rdataclass_format(rdclass, classtext, sizeof(classtext));
- isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
- vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
- DNS_LOGMODULE_XFER_IN, level,
- "transfer of '%s/%s' from %s: %s",
- zntext, classtext, mastertext, msgtext);
-}
-
-/*
- * Logging function for use when a xfrin_ctx_t has not yet been created.
- */
-
-static void
-xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,
- isc_sockaddr_t *masteraddr, const char *fmt, ...)
-{
- va_list ap;
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- xfrin_logv(level, zonename, rdclass, masteraddr, fmt, ap);
- va_end(ap);
-}
-
-/*
- * Logging function for use when there is a xfrin_ctx_t.
- */
-
-static void
-xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
-{
- va_list ap;
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- xfrin_logv(level, &xfr->name, xfr->rdclass, &xfr->masteraddr, fmt, ap);
- va_end(ap);
-}