mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
1226. [func] Use EDNS for zone refresh queries. [RT #2551]
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
|||||||
|
1226. [func] Use EDNS for zone refresh queries. [RT #2551]
|
||||||
|
|
||||||
1225. [func] dns_message_setopt() no longer requires that
|
1225. [func] dns_message_setopt() no longer requires that
|
||||||
dns_message_renderbegin() to have been called.
|
dns_message_renderbegin() to have been called.
|
||||||
|
|
||||||
|
149
lib/dns/zone.c
149
lib/dns/zone.c
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.363 2002/02/20 03:34:24 marka Exp $ */
|
/* $Id: zone.c,v 1.364 2002/03/11 04:41:53 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -256,6 +256,7 @@ struct dns_zone {
|
|||||||
#define DNS_ZONEFLG_SHUTDOWN 0x00080000U
|
#define DNS_ZONEFLG_SHUTDOWN 0x00080000U
|
||||||
#define DNS_ZONEFLAG_NOIXFR 0x00100000U /* IXFR failed, force AXFR */
|
#define DNS_ZONEFLAG_NOIXFR 0x00100000U /* IXFR failed, force AXFR */
|
||||||
#define DNS_ZONEFLG_FLUSH 0x00200000U
|
#define DNS_ZONEFLG_FLUSH 0x00200000U
|
||||||
|
#define DNS_ZONEFLG_NOEDNS 0x00400000U
|
||||||
|
|
||||||
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
|
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
|
||||||
|
|
||||||
@@ -362,6 +363,8 @@ struct dns_io {
|
|||||||
isc_event_t *event;
|
isc_event_t *event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SEND_BUFFER_SIZE 2048
|
||||||
|
|
||||||
static void zone_settimer(dns_zone_t *, isc_time_t *);
|
static void zone_settimer(dns_zone_t *, isc_time_t *);
|
||||||
static void cancel_refresh(dns_zone_t *);
|
static void cancel_refresh(dns_zone_t *);
|
||||||
static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
|
static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
|
||||||
@@ -2133,6 +2136,7 @@ dns_zone_refresh(dns_zone_t *zone) {
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
|
||||||
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
|
if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
@@ -3086,6 +3090,16 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
|
isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
|
||||||
|
|
||||||
if (revent->result != ISC_R_SUCCESS) {
|
if (revent->result != ISC_R_SUCCESS) {
|
||||||
|
if (revent->result == ISC_R_TIMEDOUT &&
|
||||||
|
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
|
||||||
|
LOCK_ZONE(zone);
|
||||||
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||||
|
"refreshing stub: timeout retrying "
|
||||||
|
" without EDNS master %s", master);
|
||||||
|
goto same_master;
|
||||||
|
}
|
||||||
dns_zone_log(zone, ISC_LOG_INFO,
|
dns_zone_log(zone, ISC_LOG_INFO,
|
||||||
"could not refresh stub from master %s: %s",
|
"could not refresh stub from master %s: %s",
|
||||||
master, dns_result_totext(revent->result));
|
master, dns_result_totext(revent->result));
|
||||||
@@ -3110,6 +3124,20 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_buffer_init(&rb, rcode, sizeof(rcode));
|
isc_buffer_init(&rb, rcode, sizeof(rcode));
|
||||||
(void)dns_rcode_totext(msg->rcode, &rb);
|
(void)dns_rcode_totext(msg->rcode, &rb);
|
||||||
|
|
||||||
|
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
|
||||||
|
(msg->rcode == dns_rcode_servfail ||
|
||||||
|
msg->rcode == dns_rcode_notimp ||
|
||||||
|
msg->rcode == dns_rcode_formerr)) {
|
||||||
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||||
|
"refreshing stub: rcode (%.*s) retrying "
|
||||||
|
"without EDNS master %s",
|
||||||
|
(int)rb.used, rcode, master);
|
||||||
|
LOCK_ZONE(zone);
|
||||||
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
goto same_master;
|
||||||
|
}
|
||||||
|
|
||||||
dns_zone_log(zone, ISC_LOG_INFO,
|
dns_zone_log(zone, ISC_LOG_INFO,
|
||||||
"refreshing stub: "
|
"refreshing stub: "
|
||||||
"unexpected rcode (%.*s) from %s",
|
"unexpected rcode (%.*s) from %s",
|
||||||
@@ -3213,6 +3241,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
dns_request_destroy(&zone->request);
|
dns_request_destroy(&zone->request);
|
||||||
zone->curmaster++;
|
zone->curmaster++;
|
||||||
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
if (exiting || zone->curmaster >= zone->masterscnt) {
|
if (exiting || zone->curmaster >= zone->masterscnt) {
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
|
||||||
|
|
||||||
@@ -3280,6 +3309,16 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
TIME_NOW(&now);
|
TIME_NOW(&now);
|
||||||
|
|
||||||
if (revent->result != ISC_R_SUCCESS) {
|
if (revent->result != ISC_R_SUCCESS) {
|
||||||
|
if (revent->result == ISC_R_TIMEDOUT &&
|
||||||
|
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
|
||||||
|
LOCK_ZONE(zone);
|
||||||
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||||
|
"refresh: timeout retrying without EDNS "
|
||||||
|
"master %s", master);
|
||||||
|
goto same_master;
|
||||||
|
}
|
||||||
if (revent->result == ISC_R_TIMEDOUT &&
|
if (revent->result == ISC_R_TIMEDOUT &&
|
||||||
!dns_request_usedtcp(revent->request)) {
|
!dns_request_usedtcp(revent->request)) {
|
||||||
dns_zone_log(zone, ISC_LOG_INFO,
|
dns_zone_log(zone, ISC_LOG_INFO,
|
||||||
@@ -3314,6 +3353,19 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_buffer_init(&rb, rcode, sizeof(rcode));
|
isc_buffer_init(&rb, rcode, sizeof(rcode));
|
||||||
(void)dns_rcode_totext(msg->rcode, &rb);
|
(void)dns_rcode_totext(msg->rcode, &rb);
|
||||||
|
|
||||||
|
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
|
||||||
|
(msg->rcode == dns_rcode_servfail ||
|
||||||
|
msg->rcode == dns_rcode_notimp ||
|
||||||
|
msg->rcode == dns_rcode_formerr)) {
|
||||||
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||||
|
"refresh: rcode (%.*s) retrying without "
|
||||||
|
"EDNS master %s", (int)rb.used, rcode,
|
||||||
|
master);
|
||||||
|
LOCK_ZONE(zone);
|
||||||
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
goto same_master;
|
||||||
|
}
|
||||||
dns_zone_log(zone, ISC_LOG_INFO,
|
dns_zone_log(zone, ISC_LOG_INFO,
|
||||||
"refresh: unexpected rcode (%.*s) from master %s",
|
"refresh: unexpected rcode (%.*s) from master %s",
|
||||||
(int)rb.used, rcode, master);
|
(int)rb.used, rcode, master);
|
||||||
@@ -3481,6 +3533,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
dns_request_destroy(&zone->request);
|
dns_request_destroy(&zone->request);
|
||||||
zone->curmaster++;
|
zone->curmaster++;
|
||||||
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
if (zone->curmaster >= zone->masterscnt) {
|
if (zone->curmaster >= zone->masterscnt) {
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
|
||||||
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
|
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
|
||||||
@@ -3598,6 +3651,64 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
add_opt(dns_message_t *message) {
|
||||||
|
dns_rdataset_t *rdataset = NULL;
|
||||||
|
dns_rdatalist_t *rdatalist = NULL;
|
||||||
|
dns_rdata_t *rdata = NULL;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
result = dns_message_gettemprdatalist(message, &rdatalist);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
result = dns_message_gettemprdata(message, &rdata);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
result = dns_message_gettemprdataset(message, &rdataset);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
dns_rdataset_init(rdataset);
|
||||||
|
|
||||||
|
rdatalist->type = dns_rdatatype_opt;
|
||||||
|
rdatalist->covers = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set Maximum UDP buffer size.
|
||||||
|
*/
|
||||||
|
rdatalist->rdclass = SEND_BUFFER_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set EXTENDED-RCODE, VERSION, DO and Z to 0.
|
||||||
|
*/
|
||||||
|
rdatalist->ttl = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No EDNS options.
|
||||||
|
*/
|
||||||
|
rdata->data = NULL;
|
||||||
|
rdata->length = 0;
|
||||||
|
rdata->rdclass = rdatalist->rdclass;
|
||||||
|
rdata->type = rdatalist->type;
|
||||||
|
rdata->flags = 0;
|
||||||
|
|
||||||
|
ISC_LIST_INIT(rdatalist->rdata);
|
||||||
|
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
|
||||||
|
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
|
||||||
|
== ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
return (dns_message_setopt(message, rdataset));
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (rdatalist != NULL)
|
||||||
|
dns_message_puttemprdatalist(message, &rdatalist);
|
||||||
|
if (rdataset != NULL)
|
||||||
|
dns_message_puttemprdataset(message, &rdataset);
|
||||||
|
if (rdata != NULL)
|
||||||
|
dns_message_puttemprdata(message, &rdata);
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
soa_query(isc_task_t *task, isc_event_t *event) {
|
soa_query(isc_task_t *task, isc_event_t *event) {
|
||||||
const char me[] = "soa_query";
|
const char me[] = "soa_query";
|
||||||
@@ -3641,6 +3752,24 @@ soa_query(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
|
isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
|
||||||
(void)dns_view_getpeertsig(zone->view, &masterip, &key);
|
(void)dns_view_getpeertsig(zone->view, &masterip, &key);
|
||||||
|
|
||||||
|
if (zone->view->peers != NULL) {
|
||||||
|
dns_peer_t *peer = NULL;
|
||||||
|
isc_boolean_t edns;
|
||||||
|
result = dns_peerlist_peerbyaddr(zone->view->peers,
|
||||||
|
&masterip, &peer);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
result = dns_peer_getsupportedns(peer, &edns);
|
||||||
|
if (result == ISC_R_SUCCESS && !edns)
|
||||||
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
|
}
|
||||||
|
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
|
||||||
|
result = add_opt(message);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
zone_debuglog(zone, me, 1,
|
||||||
|
"unable to add opt record: %s",
|
||||||
|
dns_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
|
options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
|
||||||
DNS_REQUESTOPT_TCP : 0;
|
DNS_REQUESTOPT_TCP : 0;
|
||||||
switch (isc_sockaddr_pf(&zone->masteraddr)) {
|
switch (isc_sockaddr_pf(&zone->masteraddr)) {
|
||||||
@@ -3782,6 +3911,24 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
|
|||||||
isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
|
isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
|
||||||
(void)dns_view_getpeertsig(zone->view, &masterip, &key);
|
(void)dns_view_getpeertsig(zone->view, &masterip, &key);
|
||||||
|
|
||||||
|
if (zone->view->peers != NULL) {
|
||||||
|
dns_peer_t *peer = NULL;
|
||||||
|
isc_boolean_t edns;
|
||||||
|
result = dns_peerlist_peerbyaddr(zone->view->peers,
|
||||||
|
&masterip, &peer);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
result = dns_peer_getsupportedns(peer, &edns);
|
||||||
|
if (result == ISC_R_SUCCESS && !edns)
|
||||||
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
|
||||||
|
}
|
||||||
|
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
|
||||||
|
result = add_opt(message);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
zone_debuglog(zone, me, 1,
|
||||||
|
"unable to add opt record: %s",
|
||||||
|
dns_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always use TCP so that we shouldn't truncate in additional section.
|
* Always use TCP so that we shouldn't truncate in additional section.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user