mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Detect recursion-lameness.
git-svn-id: file:///svn/unbound/trunk@713 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
63aa7463e8
commit
b247774236
5 changed files with 245 additions and 7 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
- added donotquerylocalhost config option. Can be turned off for
|
- added donotquerylocalhost config option. Can be turned off for
|
||||||
out test cases.
|
out test cases.
|
||||||
- ISO C compat changes.
|
- ISO C compat changes.
|
||||||
|
- detect RA-no-AA lameness, as LAME.
|
||||||
|
|
||||||
19 October 2007: Wouter
|
19 October 2007: Wouter
|
||||||
- added configure (and its files) to svn, so that the trunk is easier
|
- added configure (and its files) to svn, so that the trunk is easier
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,8 @@ response_type_from_cache(struct dns_msg* msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum response_type
|
enum response_type
|
||||||
response_type_from_server(struct dns_msg* msg, struct query_info* request,
|
response_type_from_server(int rdset,
|
||||||
struct delegpt* dp)
|
struct dns_msg* msg, struct query_info* request, struct delegpt* dp)
|
||||||
{
|
{
|
||||||
uint8_t* origzone = (uint8_t*)"\000"; /* the default */
|
uint8_t* origzone = (uint8_t*)"\000"; /* the default */
|
||||||
size_t origzonelen = 1;
|
size_t origzonelen = 1;
|
||||||
|
|
@ -111,8 +111,13 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
|
||||||
return RESPONSE_TYPE_THROWAWAY;
|
return RESPONSE_TYPE_THROWAWAY;
|
||||||
|
|
||||||
/* If the message is NXDOMAIN, then it answers the question. */
|
/* If the message is NXDOMAIN, then it answers the question. */
|
||||||
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN)
|
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) {
|
||||||
|
/* make sure its not recursive when we don't want it to */
|
||||||
|
if( (msg->rep->flags&BIT_RA) &&
|
||||||
|
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||||
|
return RESPONSE_TYPE_LAME;
|
||||||
return RESPONSE_TYPE_ANSWER;
|
return RESPONSE_TYPE_ANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
/* Other response codes mean (so far) to throw the response away as
|
/* Other response codes mean (so far) to throw the response away as
|
||||||
* meaningless and move on to the next nameserver. */
|
* meaningless and move on to the next nameserver. */
|
||||||
|
|
@ -193,6 +198,10 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
|
||||||
/* The normal way of detecting NOERROR/NODATA. */
|
/* The normal way of detecting NOERROR/NODATA. */
|
||||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA &&
|
if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA &&
|
||||||
dname_subdomain_c(request->qname, s->rk.dname)) {
|
dname_subdomain_c(request->qname, s->rk.dname)) {
|
||||||
|
/* we do our own recursion, thank you */
|
||||||
|
if( (msg->rep->flags&BIT_RA) &&
|
||||||
|
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||||
|
return RESPONSE_TYPE_LAME;
|
||||||
return RESPONSE_TYPE_ANSWER;
|
return RESPONSE_TYPE_ANSWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,6 +212,11 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
|
||||||
* thought we were contacting, then it is an answer.*/
|
* thought we were contacting, then it is an answer.*/
|
||||||
/* FIXME: is this correct? */
|
/* FIXME: is this correct? */
|
||||||
if(query_dname_compare(s->rk.dname, origzone) == 0) {
|
if(query_dname_compare(s->rk.dname, origzone) == 0) {
|
||||||
|
/* see if mistakenly a recursive server was
|
||||||
|
* deployed and is responding nonAA */
|
||||||
|
if( (msg->rep->flags&BIT_RA) &&
|
||||||
|
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||||
|
return RESPONSE_TYPE_LAME;
|
||||||
return RESPONSE_TYPE_ANSWER;
|
return RESPONSE_TYPE_ANSWER;
|
||||||
}
|
}
|
||||||
/* If we are getting a referral upwards (or to
|
/* If we are getting a referral upwards (or to
|
||||||
|
|
@ -231,5 +245,8 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
|
||||||
|
|
||||||
/* If we've gotten this far, this is NOERROR/NODATA (which could
|
/* If we've gotten this far, this is NOERROR/NODATA (which could
|
||||||
* be an entirely empty message) */
|
* be an entirely empty message) */
|
||||||
|
/* check if recursive answer; saying it has empty cache */
|
||||||
|
if( (msg->rep->flags&BIT_RA) && !(msg->rep->flags&BIT_AA) && !rdset)
|
||||||
|
return RESPONSE_TYPE_LAME;
|
||||||
return RESPONSE_TYPE_ANSWER;
|
return RESPONSE_TYPE_ANSWER;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,13 +107,14 @@ enum response_type response_type_from_cache(struct dns_msg* msg,
|
||||||
* relies somewhat on the originating zone to be accurate (for lameness
|
* relies somewhat on the originating zone to be accurate (for lameness
|
||||||
* detection, mostly).
|
* detection, mostly).
|
||||||
*
|
*
|
||||||
|
* @param rdset: if RD bit was sent in query sent by unbound.
|
||||||
* @param msg: the message from the cache.
|
* @param msg: the message from the cache.
|
||||||
* @param request: the request that generated the response.
|
* @param request: the request that generated the response.
|
||||||
* @param dp: The delegation point that was being queried
|
* @param dp: The delegation point that was being queried
|
||||||
* when the response was returned.
|
* when the response was returned.
|
||||||
* @return the response type (CNAME or ANSWER).
|
* @return the response type (CNAME or ANSWER).
|
||||||
*/
|
*/
|
||||||
enum response_type response_type_from_server(struct dns_msg* msg,
|
enum response_type response_type_from_server(int rdset,
|
||||||
struct query_info* request, struct delegpt* dp);
|
struct dns_msg* msg, struct query_info* request, struct delegpt* dp);
|
||||||
|
|
||||||
#endif /* ITERATOR_ITER_RESPTYPE_H */
|
#endif /* ITERATOR_ITER_RESPTYPE_H */
|
||||||
|
|
|
||||||
|
|
@ -1179,7 +1179,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
verbose(VERB_ALGO, "query response was timeout");
|
verbose(VERB_ALGO, "query response was timeout");
|
||||||
return next_state(iq, QUERYTARGETS_STATE);
|
return next_state(iq, QUERYTARGETS_STATE);
|
||||||
}
|
}
|
||||||
type = response_type_from_server(iq->response, &iq->qchase, iq->dp);
|
type = response_type_from_server((int)(iq->chase_flags&BIT_RD),
|
||||||
|
iq->response, &iq->qchase, iq->dp);
|
||||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
|
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
|
||||||
/* When forwarding (RD bit is set), we handle referrals
|
/* When forwarding (RD bit is set), we handle referrals
|
||||||
* differently. No queries should be sent elsewhere */
|
* differently. No queries should be sent elsewhere */
|
||||||
|
|
@ -1373,7 +1374,7 @@ static int
|
||||||
processPrimeResponse(struct module_qstate* qstate, int id)
|
processPrimeResponse(struct module_qstate* qstate, int id)
|
||||||
{
|
{
|
||||||
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
|
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
|
||||||
enum response_type type = response_type_from_server(iq->response,
|
enum response_type type = response_type_from_server(0, iq->response,
|
||||||
&iq->qchase, iq->dp);
|
&iq->qchase, iq->dp);
|
||||||
if(type == RESPONSE_TYPE_ANSWER) {
|
if(type == RESPONSE_TYPE_ANSWER) {
|
||||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||||
|
|
|
||||||
218
testdata/iter_ranoaa_lame.rpl
vendored
Normal file
218
testdata/iter_ranoaa_lame.rpl
vendored
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
; config options
|
||||||
|
stub-zone:
|
||||||
|
name: "."
|
||||||
|
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||||
|
CONFIG_END
|
||||||
|
|
||||||
|
SCENARIO_BEGIN Test detection of RA but no AA lameness
|
||||||
|
; in this scenario mistakenly, a recursive server is deployed, instead
|
||||||
|
; of an authoritative server. It gives answers from cache.
|
||||||
|
; However, unbound is doing recursion on behalf of its client, and does
|
||||||
|
; not trust the server to do so.
|
||||||
|
|
||||||
|
; 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 qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.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
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
net. IN NS e.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
e.gtld-servers.net. IN A 192.12.94.30
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN AAAA
|
||||||
|
SECTION AUTHORITY
|
||||||
|
net. IN NS e.gtld-servers.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
e.gtld-servers.net. IN A 192.12.94.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
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
example.com. IN NS ns.example.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
; this entry; glue will make unbound take this reference first.
|
||||||
|
; it is however, the lame server.
|
||||||
|
ns.example.com. IN A 1.2.3.55
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; e.gtld-servers.net.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 192.12.94.30
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN A
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.net. IN NS ns.example.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.net. IN A 1.2.3.44
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN AAAA
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.net. IN NS ns.example.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.net. IN A 1.2.3.44
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.net.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.44
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.net. IN A 1.2.3.44
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.net. IN NS ns.example.net.
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN AAAA
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.net. IN NS ns.example.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
www.example.net. IN A 1.2.3.44
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR AA 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.
|
||||||
|
example.com. IN NS ns.example.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.net IN A 1.2.3.44
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
; ns.example.com.
|
||||||
|
RANGE_BEGIN 0 100
|
||||||
|
ADDRESS 1.2.3.55
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
ns.example.com. IN A 1.2.3.55
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
ns.example.net. IN AAAA
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; the lame response.
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
ADJUST copy_id
|
||||||
|
REPLY QR RA NOERROR
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
; the wrong answer.
|
||||||
|
www.example.com. IN A 10.20.30.50
|
||||||
|
SECTION AUTHORITY
|
||||||
|
example.com. IN NS ns.example.com.
|
||||||
|
example.com. IN NS ns.example.net.
|
||||||
|
SECTION ADDITIONAL
|
||||||
|
ns.example.com. IN A 1.2.3.55
|
||||||
|
ENTRY_END
|
||||||
|
RANGE_END
|
||||||
|
|
||||||
|
STEP 1 QUERY
|
||||||
|
ENTRY_BEGIN
|
||||||
|
REPLY RD
|
||||||
|
SECTION QUESTION
|
||||||
|
www.example.com. IN A
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; recursion happens here.
|
||||||
|
STEP 20 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.
|
||||||
|
example.com. IN NS ns.example.net.
|
||||||
|
; scrubbed off
|
||||||
|
;SECTION ADDITIONAL
|
||||||
|
;ns.example.net IN A 1.2.3.44
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
SCENARIO_END
|
||||||
Loading…
Reference in a new issue