- 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:
Wouter Wijngaards 2012-03-01 13:16:40 +00:00
parent 57199f80c9
commit 1736d8078a
15 changed files with 2150 additions and 1676 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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:");

View file

@ -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);

View file

@ -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
View 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
View 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

View file

@ -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;
} }

View file

@ -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;
}; };
/** /**

File diff suppressed because it is too large Load diff

View file

@ -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) }

File diff suppressed because it is too large Load diff

View file

@ -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 */

View file

@ -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"));