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]
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
||||
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",
|
||||
|
||||
Reference in New Issue
Block a user