mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-21 07:10:43 -05:00
- forward-first option. Tries without forward if a query fails.
Also stub-first option that is similar. git-svn-id: file:///svn/unbound/trunk@2637 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
57199f80c9
commit
1736d8078a
15 changed files with 2150 additions and 1676 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
1 March 2012: Wouter
|
||||||
|
- forward-first option. Tries without forward if a query fails.
|
||||||
|
Also stub-first option that is similar.
|
||||||
|
|
||||||
28 February 2012: Wouter
|
28 February 2012: Wouter
|
||||||
- Fix from code review, if EINPROGRESS not defined chain if statement
|
- Fix from code review, if EINPROGRESS not defined chain if statement
|
||||||
differently.
|
differently.
|
||||||
|
|
|
||||||
|
|
@ -503,10 +503,12 @@ remote-control:
|
||||||
# 'example.org' go to the given list of nameservers. list zero or more
|
# 'example.org' go to the given list of nameservers. list zero or more
|
||||||
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
||||||
# the list is treated as priming hints (default is no).
|
# the list is treated as priming hints (default is no).
|
||||||
|
# With stub-first yes, it attempts without the stub if it fails.
|
||||||
# stub-zone:
|
# stub-zone:
|
||||||
# name: "example.com"
|
# name: "example.com"
|
||||||
# stub-addr: 192.0.2.68
|
# stub-addr: 192.0.2.68
|
||||||
# stub-prime: no
|
# stub-prime: no
|
||||||
|
# stub-first: no
|
||||||
# stub-zone:
|
# stub-zone:
|
||||||
# name: "example.org"
|
# name: "example.org"
|
||||||
# stub-host: ns.example.com.
|
# stub-host: ns.example.com.
|
||||||
|
|
@ -516,10 +518,12 @@ remote-control:
|
||||||
# 'example.org' go to the given list of servers. These servers have to handle
|
# 'example.org' go to the given list of servers. These servers have to handle
|
||||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||||
|
# If you enable forward-first, it attempts without the forward if it fails.
|
||||||
# forward-zone:
|
# forward-zone:
|
||||||
# name: "example.com"
|
# name: "example.com"
|
||||||
# forward-addr: 192.0.2.68
|
# forward-addr: 192.0.2.68
|
||||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||||
|
# forward-first: no
|
||||||
# forward-zone:
|
# forward-zone:
|
||||||
# name: "example.org"
|
# name: "example.org"
|
||||||
# forward-host: fwd.example.com
|
# forward-host: fwd.example.com
|
||||||
|
|
|
||||||
|
|
@ -979,6 +979,10 @@ This option is by default off. If enabled it performs NS set priming,
|
||||||
which is similar to root hints, where it starts using the list of nameservers
|
which is similar to root hints, where it starts using the list of nameservers
|
||||||
currently published by the zone. Thus, if the hint list is slightly outdated,
|
currently published by the zone. Thus, if the hint list is slightly outdated,
|
||||||
the resolver picks up a correct list online.
|
the resolver picks up a correct list online.
|
||||||
|
.TP
|
||||||
|
.B stub\-first: \fI<yes or no>
|
||||||
|
If enabled, a query is attempted without the stub clause if it fails.
|
||||||
|
The default is no.
|
||||||
.SS "Forward Zone Options"
|
.SS "Forward Zone Options"
|
||||||
.LP
|
.LP
|
||||||
There may be multiple
|
There may be multiple
|
||||||
|
|
@ -1003,6 +1007,10 @@ Name of server to forward to. Is itself resolved before it is used.
|
||||||
.B forward\-addr: \fI<IP address>
|
.B forward\-addr: \fI<IP address>
|
||||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||||
To use a nondefault port for DNS communication append '@' with the port number.
|
To use a nondefault port for DNS communication append '@' with the port number.
|
||||||
|
.TP
|
||||||
|
.B forward\-first: \fI<yes or no>
|
||||||
|
If enabled, a query is attempted without the forward clause if it fails.
|
||||||
|
The default is no.
|
||||||
.SS "Python Module Options"
|
.SS "Python Module Options"
|
||||||
.LP
|
.LP
|
||||||
The
|
The
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,10 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
|
||||||
return 0;
|
return 0;
|
||||||
/* set flag that parent side NS information is included.
|
/* set flag that parent side NS information is included.
|
||||||
* Asking a (higher up) server on the internet is not useful */
|
* Asking a (higher up) server on the internet is not useful */
|
||||||
dp->has_parent_side_NS = 1;
|
/* the flag is turned off for 'forward-first' so that the
|
||||||
|
* last resort will ask for parent-side NS record and thus
|
||||||
|
* fallback to the internet name servers on a failure */
|
||||||
|
dp->has_parent_side_NS = !s->isfirst;
|
||||||
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
|
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
|
||||||
return 0;
|
return 0;
|
||||||
verbose(VERB_QUERY, "Forward zone server list:");
|
verbose(VERB_QUERY, "Forward zone server list:");
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
||||||
!read_stubs_host(s, dp) ||
|
!read_stubs_host(s, dp) ||
|
||||||
!read_stubs_addr(s, dp))
|
!read_stubs_addr(s, dp))
|
||||||
return 0;
|
return 0;
|
||||||
dp->has_parent_side_NS = 1;
|
dp->has_parent_side_NS = !s->isfirst;
|
||||||
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, !s->isprime))
|
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, !s->isprime))
|
||||||
return 0;
|
return 0;
|
||||||
delegpt_log(VERB_QUERY, dp);
|
delegpt_log(VERB_QUERY, dp);
|
||||||
|
|
|
||||||
|
|
@ -589,7 +589,8 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||||
* @param qstate: the qtstate that triggered the need to prime.
|
* @param qstate: the qtstate that triggered the need to prime.
|
||||||
* @param iq: iterator query state.
|
* @param iq: iterator query state.
|
||||||
* @param id: module id.
|
* @param id: module id.
|
||||||
* @param q: request name.
|
* @param qname: request name.
|
||||||
|
* @param qclass: request class.
|
||||||
* @return true if a priming subrequest was made, false if not. The will only
|
* @return true if a priming subrequest was made, false if not. The will only
|
||||||
* issue a priming request if it detects an unprimed stub.
|
* issue a priming request if it detects an unprimed stub.
|
||||||
* Uses value of 2 to signal during stub-prime in root-prime situation
|
* Uses value of 2 to signal during stub-prime in root-prime situation
|
||||||
|
|
@ -597,22 +598,16 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||||
struct query_info* q)
|
uint8_t* qname, uint16_t qclass)
|
||||||
{
|
{
|
||||||
/* Lookup the stub hint. This will return null if the stub doesn't
|
/* Lookup the stub hint. This will return null if the stub doesn't
|
||||||
* need to be re-primed. */
|
* need to be re-primed. */
|
||||||
struct iter_hints_stub* stub;
|
struct iter_hints_stub* stub;
|
||||||
struct delegpt* stub_dp;
|
struct delegpt* stub_dp;
|
||||||
struct module_qstate* subq;
|
struct module_qstate* subq;
|
||||||
uint8_t* delname = q->qname;
|
|
||||||
size_t delnamelen = q->qname_len;
|
|
||||||
|
|
||||||
if(q->qtype == LDNS_RR_TYPE_DS && !dname_is_root(q->qname))
|
if(!qname) return 0;
|
||||||
/* remove first label, but not for root */
|
stub = hints_lookup_stub(qstate->env->hints, qname, qclass, iq->dp);
|
||||||
dname_remove_label(&delname, &delnamelen);
|
|
||||||
|
|
||||||
stub = hints_lookup_stub(qstate->env->hints, delname, q->qclass,
|
|
||||||
iq->dp);
|
|
||||||
/* The stub (if there is one) does not need priming. */
|
/* The stub (if there is one) does not need priming. */
|
||||||
if(!stub)
|
if(!stub)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -631,18 +626,18 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||||
return 1; /* return 1 to make module stop, with error */
|
return 1; /* return 1 to make module stop, with error */
|
||||||
}
|
}
|
||||||
log_nametypeclass(VERB_DETAIL, "use stub", stub_dp->name,
|
log_nametypeclass(VERB_DETAIL, "use stub", stub_dp->name,
|
||||||
LDNS_RR_TYPE_NS, q->qclass);
|
LDNS_RR_TYPE_NS, qclass);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, we need to (re)prime the stub. */
|
/* Otherwise, we need to (re)prime the stub. */
|
||||||
log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name,
|
log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name,
|
||||||
LDNS_RR_TYPE_NS, q->qclass);
|
LDNS_RR_TYPE_NS, qclass);
|
||||||
|
|
||||||
/* Stub priming events start at the QUERYTARGETS state to avoid the
|
/* Stub priming events start at the QUERYTARGETS state to avoid the
|
||||||
* redundant INIT state processing. */
|
* redundant INIT state processing. */
|
||||||
if(!generate_sub_request(stub_dp->name, stub_dp->namelen,
|
if(!generate_sub_request(stub_dp->name, stub_dp->namelen,
|
||||||
LDNS_RR_TYPE_NS, q->qclass, qstate, id, iq,
|
LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
|
||||||
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
|
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
|
||||||
verbose(VERB_ALGO, "could not prime stub");
|
verbose(VERB_ALGO, "could not prime stub");
|
||||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
|
@ -848,8 +843,12 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||||
struct delegpt* dp;
|
struct delegpt* dp;
|
||||||
uint8_t* delname = iq->qchase.qname;
|
uint8_t* delname = iq->qchase.qname;
|
||||||
size_t delnamelen = iq->qchase.qname_len;
|
size_t delnamelen = iq->qchase.qname_len;
|
||||||
|
if(iq->refetch_glue) {
|
||||||
|
delname = iq->dp->name;
|
||||||
|
delnamelen = iq->dp->namelen;
|
||||||
|
}
|
||||||
/* strip one label off of DS query to lookup higher for it */
|
/* strip one label off of DS query to lookup higher for it */
|
||||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS
|
if( (iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue)
|
||||||
&& !dname_is_root(iq->qchase.qname))
|
&& !dname_is_root(iq->qchase.qname))
|
||||||
dname_remove_label(&delname, &delnamelen);
|
dname_remove_label(&delname, &delnamelen);
|
||||||
dp = forwards_lookup(qstate->env->fwds, delname, iq->qchase.qclass);
|
dp = forwards_lookup(qstate->env->fwds, delname, iq->qchase.qclass);
|
||||||
|
|
@ -1030,7 +1029,6 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
qstate->prefetch_leeway)))
|
qstate->prefetch_leeway)))
|
||||||
delname = NULL; /* go to root priming */
|
delname = NULL; /* go to root priming */
|
||||||
else dname_remove_label(&delname, &delnamelen);
|
else dname_remove_label(&delname, &delnamelen);
|
||||||
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
|
|
||||||
}
|
}
|
||||||
/* delname is the name to lookup a delegation for. If NULL rootprime */
|
/* delname is the name to lookup a delegation for. If NULL rootprime */
|
||||||
while(1) {
|
while(1) {
|
||||||
|
|
@ -1048,7 +1046,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* root priming situation. */
|
* root priming situation. */
|
||||||
if(iq->dp == NULL) {
|
if(iq->dp == NULL) {
|
||||||
/* if there is a stub, then no root prime needed */
|
/* if there is a stub, then no root prime needed */
|
||||||
int r = prime_stub(qstate, iq, id, &iq->qchase);
|
int r = prime_stub(qstate, iq, id, delname,
|
||||||
|
iq->qchase.qclass);
|
||||||
if(r == 2)
|
if(r == 2)
|
||||||
break; /* got noprime-stub-zone, continue */
|
break; /* got noprime-stub-zone, continue */
|
||||||
else if(r)
|
else if(r)
|
||||||
|
|
@ -1158,11 +1157,29 @@ static int
|
||||||
processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
int id)
|
int id)
|
||||||
{
|
{
|
||||||
|
uint8_t* delname;
|
||||||
|
size_t delnamelen;
|
||||||
log_query_info(VERB_QUERY, "resolving (init part 2): ",
|
log_query_info(VERB_QUERY, "resolving (init part 2): ",
|
||||||
&qstate->qinfo);
|
&qstate->qinfo);
|
||||||
|
|
||||||
|
if(iq->refetch_glue) {
|
||||||
|
if(!iq->dp) {
|
||||||
|
log_err("internal or malloc fail: no dp for refetch");
|
||||||
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
|
delname = iq->dp->name;
|
||||||
|
delnamelen = iq->dp->namelen;
|
||||||
|
} else {
|
||||||
|
delname = iq->qchase.qname;
|
||||||
|
delnamelen = iq->qchase.qname_len;
|
||||||
|
}
|
||||||
|
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue) {
|
||||||
|
if(!dname_is_root(delname))
|
||||||
|
dname_remove_label(&delname, &delnamelen);
|
||||||
|
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
|
||||||
|
}
|
||||||
/* Check to see if we need to prime a stub zone. */
|
/* Check to see if we need to prime a stub zone. */
|
||||||
if(prime_stub(qstate, iq, id, &iq->qchase)) {
|
if(prime_stub(qstate, iq, id, delname, iq->qchase.qclass)) {
|
||||||
/* A priming sub request was made */
|
/* A priming sub request was made */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
157
testdata/iter_fwdfirst.rpl
vendored
Normal file
157
testdata/iter_fwdfirst.rpl
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
; config options
|
||||||
|
server:
|
||||||
|
target-fetch-policy: "0 0 0 0 0"
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "."
|
||||||
|
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||||
|
|
||||||
|
forward-zone:
|
||||||
|
name: "example.com"
|
||||||
|
forward-addr: 1.2.3.6 # failing resolver
|
||||||
|
forward-first: yes
|
||||||
|
|
||||||
|
CONFIG_END
|
||||||
|
|
||||||
|
SCENARIO_BEGIN Test forward-first directive
|
||||||
|
|
||||||
|
; K.ROOT-SERVERS.NET.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 193.0.14.129
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
. IN NS K.ROOT-SERVERS.NET.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode subdomain
|
||||||
|
ADJUST copy_id copy_query
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; a.gtld-servers.net.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 192.5.6.30
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode subdomain
|
||||||
|
ADJUST copy_id copy_query
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.com.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; local resolver (that fails a lot)
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.6
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR RA SERVFAIL
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
;example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
;ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR RA SERVFAIL
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
;www.example.com. IN A 10.20.30.50
|
||||||
|
SECTION AUTHORITY
|
||||||
|
;example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
;ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
STEP 1 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 10 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RD RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
SCENARIO_END
|
||||||
157
testdata/iter_stubfirst.rpl
vendored
Normal file
157
testdata/iter_stubfirst.rpl
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
; config options
|
||||||
|
server:
|
||||||
|
target-fetch-policy: "0 0 0 0 0"
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "."
|
||||||
|
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "example.com"
|
||||||
|
stub-addr: 1.2.3.6 # failing server
|
||||||
|
stub-first: yes
|
||||||
|
|
||||||
|
CONFIG_END
|
||||||
|
|
||||||
|
SCENARIO_BEGIN Test stub-first directive
|
||||||
|
|
||||||
|
; K.ROOT-SERVERS.NET.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 193.0.14.129
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
. IN NS K.ROOT-SERVERS.NET.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode subdomain
|
||||||
|
ADJUST copy_id copy_query
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; a.gtld-servers.net.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 192.5.6.30
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
com. IN NS a.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
a.gtld-servers.net. IN A 192.5.6.30
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode subdomain
|
||||||
|
ADJUST copy_id copy_query
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.com.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.4
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; local authority (that fails a lot)
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.6
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR AA SERVFAIL
|
||||||
|
SECTION QUESTION
|
||||||
|
example.com. IN NS
|
||||||
|
SECTION ANSWER
|
||||||
|
;example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
;ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR AA SERVFAIL
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
;www.example.com. IN A 10.20.30.50
|
||||||
|
SECTION AUTHORITY
|
||||||
|
;example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
;ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
STEP 1 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 10 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RD RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www.example.com. IN A 10.20.30.40
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
SCENARIO_END
|
||||||
|
|
@ -423,6 +423,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
/* unknown or unsupported (from the set_option interface):
|
/* unknown or unsupported (from the set_option interface):
|
||||||
* interface, outgoing-interface, access-control,
|
* interface, outgoing-interface, access-control,
|
||||||
* stub-zone, name, stub-addr, stub-host, stub-prime
|
* stub-zone, name, stub-addr, stub-host, stub-prime
|
||||||
|
* forward-first, stub-first,
|
||||||
* forward-zone, name, forward-addr, forward-host */
|
* forward-zone, name, forward-addr, forward-host */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,8 @@ struct config_stub {
|
||||||
struct config_strlist* addrs;
|
struct config_strlist* addrs;
|
||||||
/** if stub-prime is set */
|
/** if stub-prime is set */
|
||||||
int isprime;
|
int isprime;
|
||||||
|
/** if forward-first is set (failover to without if fails) */
|
||||||
|
int isfirst;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
1785
util/configlexer.c
1785
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -186,9 +186,11 @@ name{COLON} { YDVAR(1, VAR_NAME) }
|
||||||
stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) }
|
stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) }
|
||||||
stub-host{COLON} { YDVAR(1, VAR_STUB_HOST) }
|
stub-host{COLON} { YDVAR(1, VAR_STUB_HOST) }
|
||||||
stub-prime{COLON} { YDVAR(1, VAR_STUB_PRIME) }
|
stub-prime{COLON} { YDVAR(1, VAR_STUB_PRIME) }
|
||||||
|
stub-first{COLON} { YDVAR(1, VAR_STUB_FIRST) }
|
||||||
forward-zone{COLON} { YDVAR(0, VAR_FORWARD_ZONE) }
|
forward-zone{COLON} { YDVAR(0, VAR_FORWARD_ZONE) }
|
||||||
forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) }
|
forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) }
|
||||||
forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) }
|
forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) }
|
||||||
|
forward-first{COLON} { YDVAR(1, VAR_FORWARD_FIRST) }
|
||||||
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
|
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
|
||||||
do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
|
do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
|
||||||
access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) }
|
access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) }
|
||||||
|
|
|
||||||
1502
util/configparser.c
1502
util/configparser.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +1,8 @@
|
||||||
/* A Bison parser, made by GNU Bison 2.4.3. */
|
/* A Bison parser, made by GNU Bison 2.5. */
|
||||||
|
|
||||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
|
||||||
2009, 2010 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -160,7 +159,9 @@
|
||||||
VAR_SSL_UPSTREAM = 377,
|
VAR_SSL_UPSTREAM = 377,
|
||||||
VAR_SSL_SERVICE_KEY = 378,
|
VAR_SSL_SERVICE_KEY = 378,
|
||||||
VAR_SSL_SERVICE_PEM = 379,
|
VAR_SSL_SERVICE_PEM = 379,
|
||||||
VAR_SSL_PORT = 380
|
VAR_SSL_PORT = 380,
|
||||||
|
VAR_FORWARD_FIRST = 381,
|
||||||
|
VAR_STUB_FIRST = 382
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
|
|
@ -287,6 +288,8 @@
|
||||||
#define VAR_SSL_SERVICE_KEY 378
|
#define VAR_SSL_SERVICE_KEY 378
|
||||||
#define VAR_SSL_SERVICE_PEM 379
|
#define VAR_SSL_SERVICE_PEM 379
|
||||||
#define VAR_SSL_PORT 380
|
#define VAR_SSL_PORT 380
|
||||||
|
#define VAR_FORWARD_FIRST 381
|
||||||
|
#define VAR_STUB_FIRST 382
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -295,15 +298,15 @@
|
||||||
typedef union YYSTYPE
|
typedef union YYSTYPE
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Line 1685 of yacc.c */
|
/* Line 2068 of yacc.c */
|
||||||
#line 64 "util/configparser.y"
|
#line 64 "./util/configparser.y"
|
||||||
|
|
||||||
char* str;
|
char* str;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Line 1685 of yacc.c */
|
/* Line 2068 of yacc.c */
|
||||||
#line 307 "util/configparser.h"
|
#line 310 "util/configparser.h"
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,8 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
|
%token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
|
||||||
%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_HARDEN_BELOW_NXDOMAIN
|
%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_HARDEN_BELOW_NXDOMAIN
|
||||||
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
|
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
|
||||||
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT
|
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
|
||||||
|
%token VAR_STUB_FIRST
|
||||||
|
|
||||||
%%
|
%%
|
||||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||||
|
|
@ -175,7 +176,7 @@ stubstart: VAR_STUB_ZONE
|
||||||
;
|
;
|
||||||
contents_stub: contents_stub content_stub
|
contents_stub: contents_stub content_stub
|
||||||
| ;
|
| ;
|
||||||
content_stub: stub_name | stub_host | stub_addr | stub_prime
|
content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first
|
||||||
;
|
;
|
||||||
forwardstart: VAR_FORWARD_ZONE
|
forwardstart: VAR_FORWARD_ZONE
|
||||||
{
|
{
|
||||||
|
|
@ -191,7 +192,7 @@ forwardstart: VAR_FORWARD_ZONE
|
||||||
;
|
;
|
||||||
contents_forward: contents_forward content_forward
|
contents_forward: contents_forward content_forward
|
||||||
| ;
|
| ;
|
||||||
content_forward: forward_name | forward_host | forward_addr
|
content_forward: forward_name | forward_host | forward_addr | forward_first
|
||||||
;
|
;
|
||||||
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
||||||
{
|
{
|
||||||
|
|
@ -1119,6 +1120,15 @@ stub_addr: VAR_STUB_ADDR STRING_ARG
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
stub_first: VAR_STUB_FIRST STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(stub-first:%s)\n", $2));
|
||||||
|
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||||
|
yyerror("expected yes or no.");
|
||||||
|
else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
stub_prime: VAR_STUB_PRIME STRING_ARG
|
stub_prime: VAR_STUB_PRIME STRING_ARG
|
||||||
{
|
{
|
||||||
OUTYY(("P(stub-prime:%s)\n", $2));
|
OUTYY(("P(stub-prime:%s)\n", $2));
|
||||||
|
|
@ -1153,6 +1163,15 @@ forward_addr: VAR_FORWARD_ADDR STRING_ARG
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
forward_first: VAR_FORWARD_FIRST STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(forward-first:%s)\n", $2));
|
||||||
|
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||||
|
yyerror("expected yes or no.");
|
||||||
|
else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
rcstart: VAR_REMOTE_CONTROL
|
rcstart: VAR_REMOTE_CONTROL
|
||||||
{
|
{
|
||||||
OUTYY(("\nP(remote-control:)\n"));
|
OUTYY(("\nP(remote-control:)\n"));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue