xfrin.c revision e44487bfc23599b6b240e09d83d1c862fecfcc82
5785N/A * Copyright (C) 1999, 2000 Internet Software Consortium. 5785N/A * Permission to use, copy, modify, and distribute this software for any 5785N/A * purpose with or without fee is hereby granted, provided that the above 5785N/A * copyright notice and this permission notice appear in all copies. 5785N/A * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 5785N/A * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 5785N/A * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 5785N/A * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 5785N/A * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 5785N/A * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 5785N/A * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 5785N/A * The states of the *XFR state machine. We handle both IXFR and AXFR 5785N/A * with a single integrated state machine because they cannot be distinguished 5785N/A * immediately - an AXFR response to an IXFR request can only be detected 5785N/A * when the first two (2) response RRs have already been received. 5785N/A * Incoming zone transfer context. 5785N/A * Requested transfer type (dns_rdatatype_axfr or 5785N/A * dns_rdatatype_ixfr). The actual transfer type 5785N/A * may differ due to IXFR->AXFR fallback. 5785N/A /* Incoming reply TCP message */ 5785N/A unsigned int nmsg;
/* Number of messages recvd */ 5785N/A * AXFR- and IXFR-specific data. Only one is used at a time 5785N/A * according to the is_ixfr flag, so this could be a union, 5785N/A * but keeping them separate makes it a bit simpler to clean 5785N/A * things up when destroying the context. /**************************************************************************/ /**************************************************************************/ /* Store a set of AXFR RRs in the database. */ /**************************************************************************/ /* Apply a set of IXFR changes to the database. */ /* XXX enter ready-to-commit state here */ /**************************************************************************/ * Handle a single incoming resource record according to the current "master has %u, not updating",
* skip other records in the answer section "first RR in zone transfer must be SOA");
* Remember the serial number in the intial SOA. * We need it to recognize the end of an IXFR. * 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. "master has %u, not updating",
* If the transfer begins with one SOA record, it is an AXFR, * if it begins with two SOAs, it is an IXFR. "got incremental response");
"got nonincremental response");
* Find any configured information about the server we are about * Decide whether we should request IXFR or AXFR. "no database exists yet, " "requesting AXFR of initial version");
;
/* Using peer setting */ "IXFR disabled, requesting AXFR");
* Determine the maximum number of simultaneous transfers * allowed for this server, then count the number of * transfers already in progress and fail if the quota * Count the number of transfers that are in progress from * this master. We linearly scan a list of all transfers; * if this turns out to be too slow, we could hash on the * Note that we must keep the transfer list locked for an * awkwardly long time because the scanning of the list * and the creation of a new entry must be done atomically, * and we don't want to create the transfer object until we * know there is quota available. * Determine if we should attempt to sign the request with TSIG. "zone transfer setup failed");
/* ixfr.request_serial */ /* XXX the resolver could use this, too */ * A connection has been established. * Convert a tuple into a dns_name_t suitable for inserting * into the given dns_message_t. * Build an *XFR request and send its length prefix. /* Create the request message */ /* Create a name for the question section. */ /* Formulate the question and attach it to the question name. */ /* Get the SOA and add it to the authority section. */ /* XXX is using the current version the right thing? */ "requesting IXFR for serial %u",
msg->
id = (
'b' <<
8) |
'9';
/* Arbitrary */ /* Save the query TSIG and don't let message_destroy free it */ /* XXX there should be library support for sending DNS TCP messages */ * Ignore out-of-zone data. /* Free the last tsig, if there is one */ /* Update the last tsig pointer */ /* Reset msg->tsig so it doesn't get freed */ /* Update the number of messages received */ /* Reset msg->querytsig so it doesn't get freed */ /* Copy the context back */ * Inform the caller we succeeded. * We should have no outstanding events at this * point, thus maybe_free() should succeed. /* Read the next message. */ /* This will log "giving up: timeout". */ * Log incoming zone transfer messages in a format like * transfer of <zone> from <address>: <message> "transfer of '%s' from %s: %s",
znbuf,
/* Logging function for use when a xfrin_ctx_t has not yet been created. */ /* Logging function for use when there is a xfrin_ctx_t. */