Commit 2db8db63 authored by Mark Andrews's avatar Mark Andrews
Browse files

2049. [bug] Restore SOA before AXFR when falling back from

                        a attempted IXFR when transfering in a zone.
                        Allow a initial SOA query before attempting
                        a AXFR to be requested. [RT #16156]
parent 7076f000
2049. [bug] Restore SOA before AXFR when falling back from
a attempted IXFR when transfering in a zone.
Allow a initial SOA query before attempting
a AXFR to be requested. [RT #16156]
2048. [bug] It was possible to loop forever when using
avoid-v4-udp-ports / avoid-v6-udp-ports when
the OS always returned the same local port.
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: xfrin.h,v 1.22 2005/04/29 00:23:06 marka Exp $ */
/* $Id: xfrin.h,v 1.23 2006/07/19 00:53:42 marka Exp $ */
#ifndef DNS_XFRIN_H
#define DNS_XFRIN_H 1
......@@ -77,10 +77,12 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
* code as arguments when the transfer finishes.
*
* Requires:
*\li 'xfrtype' is dns_rdatatype_axfr or dns_rdatatype_ixfr.
*\li 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr
* of dns_rdatatype_soa (soa query followed by axfr if
* serial is greater than current serial).
*
*\li If 'xfrtype' is dns_rdatatype_ixfr, the zone has a
* database.
*\li If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa,
* the zone has a database.
*/
void
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: xfrin.c,v 1.146 2006/03/01 02:05:11 marka Exp $ */
/* $Id: xfrin.c,v 1.147 2006/07/19 00:53:42 marka Exp $ */
/*! \file */
......@@ -75,6 +75,8 @@
* when the first two (2) response RRs have already been received.
*/
typedef enum {
XFRST_SOAQUERY,
XFRST_GOTSOA,
XFRST_INITIALSOA,
XFRST_FIRSTDATA,
XFRST_IXFR_DELSOA,
......@@ -426,6 +428,30 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
redo:
switch (xfr->state) {
case XFRST_SOAQUERY:
if (rdata->type != dns_rdatatype_soa) {
xfrin_log(xfr, ISC_LOG_ERROR,
"non-SOA response to SOA query");
FAIL(DNS_R_FORMERR);
}
xfr->end_serial = dns_soa_getserial(rdata);
if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
!dns_zone_isforced(xfr->zone)) {
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);
}
xfr->state = XFRST_GOTSOA;
break;
case XFRST_GOTSOA:
/*
* Skip other records in the answer section.
*/
break;
case XFRST_INITIALSOA:
if (rdata->type != dns_rdatatype_soa) {
xfrin_log(xfr, ISC_LOG_ERROR,
......@@ -591,6 +617,9 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
(void)dns_zone_getdb(zone, &db);
if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
REQUIRE(db != NULL);
CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
dns_zone_getclass(zone), xfrtype, masteraddr,
sourceaddr, tsigkey, &xfr));
......@@ -759,7 +788,10 @@ xfrin_create(isc_mem_t *mctx,
dns_diff_init(xfr->mctx, &xfr->diff);
xfr->difflen = 0;
xfr->state = XFRST_INITIALSOA;
if (reqtype == dns_rdatatype_soa)
xfr->state = XFRST_SOAQUERY;
else
xfr->state = XFRST_INITIALSOA;
/* end_serial */
xfr->nmsg = 0;
......@@ -1005,7 +1037,9 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) {
CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
}
} else if (xfr->reqtype == dns_rdatatype_soa)
CHECK(dns_db_getsoaserial(xfr->db, NULL,
&xfr->ixfr.request_serial));
xfr->checkid = ISC_TRUE;
xfr->id++;
......@@ -1166,8 +1200,8 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
try_axfr:
dns_message_destroy(&msg);
xfrin_reset(xfr);
xfr->reqtype = dns_rdatatype_axfr;
xfr->state = XFRST_INITIALSOA;
xfr->reqtype = dns_rdatatype_soa;
xfr->state = XFRST_SOAQUERY;
(void)xfrin_start(xfr);
return;
}
......@@ -1264,7 +1298,11 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
dns_message_destroy(&msg);
if (xfr->state == XFRST_END) {
if (xfr->state == XFRST_GOTSOA) {
xfr->reqtype = dns_rdatatype_axfr;
xfr->state = XFRST_INITIALSOA;
CHECK(xfrin_send_request(xfr));
} else if (xfr->state == XFRST_END) {
/*
* Inform the caller we succeeded.
*/
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.c,v 1.456 2006/06/04 23:17:06 marka Exp $ */
/* $Id: zone.c,v 1.457 2006/07/19 00:53:42 marka Exp $ */
/*! \file */
......@@ -297,6 +297,7 @@ struct dns_zone {
#define DNS_ZONEFLG_FLUSH 0x00200000U
#define DNS_ZONEFLG_NOEDNS 0x00400000U
#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
......@@ -4286,8 +4287,13 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
master, source);
/* Try with slave with TCP. */
if (zone->type == dns_zone_slave &&
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
LOCK_ZONE(zone);
DNS_ZONE_SETFLAG(zone,
DNS_ZONEFLG_SOABEFOREAXFR);
UNLOCK_ZONE(zone);
goto tcp_transfer;
}
} else
dns_zone_log(zone, ISC_LOG_INFO,
"refresh: failure trying master "
......@@ -4354,6 +4360,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
"initiating TCP zone xfer "
"for master %s (source %s)",
master, source);
LOCK_ZONE(zone);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
UNLOCK_ZONE(zone);
goto tcp_transfer;
} else {
INSIST(zone->type == dns_zone_stub);
......@@ -6334,6 +6343,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
LOCK_ZONE(zone);
INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
TIME_NOW(&now);
switch (result) {
......@@ -6691,7 +6701,10 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
"IXFR disabled, "
"requesting AXFR from %s",
mastertext);
xfrtype = dns_rdatatype_axfr;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
xfrtype = dns_rdatatype_soa;
else
xfrtype = dns_rdatatype_axfr;
} else {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"requesting IXFR from %s",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment