Detect recursion-lameness.

git-svn-id: file:///svn/unbound/trunk@713 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-10-22 12:05:46 +00:00
parent 63aa7463e8
commit b247774236
5 changed files with 245 additions and 7 deletions

View file

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

View file

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

View file

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

View file

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