+8 Aug 2013: Wouter
+ - Fix#516 dnssec lameness detection for answers that are improper.
+
30 Jun 2013: Wouter
- tag 1.4.21rc1
copy->bogus = dp->bogus;
copy->has_parent_side_NS = dp->has_parent_side_NS;
for(ns = dp->nslist; ns; ns = ns->next) {
- if(!delegpt_add_ns(copy, region, ns->name, (int)ns->lame))
+ if(!delegpt_add_ns(copy, region, ns->name, ns->lame))
return NULL;
copy->nslist->resolved = ns->resolved;
copy->nslist->got4 = ns->got4;
int
delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name,
- int lame)
+ uint8_t lame)
{
struct delegpt_ns* ns;
size_t len;
ns->resolved = 0;
ns->got4 = 0;
ns->got6 = 0;
- ns->lame = (uint8_t)lame;
+ ns->lame = lame;
ns->done_pside4 = 0;
ns->done_pside6 = 0;
return ns->name != 0;
int
delegpt_add_target(struct delegpt* dp, struct regional* region,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
- socklen_t addrlen, int bogus, int lame)
+ socklen_t addrlen, uint8_t bogus, uint8_t lame)
{
struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
log_assert(!dp->dp_type_mlc);
int
delegpt_add_addr(struct delegpt* dp, struct regional* region,
- struct sockaddr_storage* addr, socklen_t addrlen, int bogus,
- int lame)
+ struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
+ uint8_t lame)
{
struct delegpt_addr* a;
log_assert(!dp->dp_type_mlc);
a->attempts = 0;
a->bogus = bogus;
a->lame = lame;
+ a->dnsseclame = 0;
return 1;
}
int
delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
- struct ub_packed_rrset_key* ns_rrset, int lame)
+ struct ub_packed_rrset_key* ns_rrset, uint8_t lame)
{
struct packed_rrset_data* nsdata = (struct packed_rrset_data*)
ns_rrset->entry.data;
int
delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
- struct ub_packed_rrset_key* ak, int lame)
+ struct ub_packed_rrset_key* ak, uint8_t lame)
{
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
size_t i;
int
delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
- struct ub_packed_rrset_key* ak, int lame)
+ struct ub_packed_rrset_key* ak, uint8_t lame)
{
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
size_t i;
int
delegpt_add_rrset(struct delegpt* dp, struct regional* region,
- struct ub_packed_rrset_key* rrset, int lame)
+ struct ub_packed_rrset_key* rrset, uint8_t lame)
{
if(!rrset)
return 1;
return (dp->name != NULL);
}
-int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, int lame)
+int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
{
struct delegpt_ns* ns;
size_t len;
}
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
- socklen_t addrlen, int bogus, int lame)
+ socklen_t addrlen, uint8_t bogus, uint8_t lame)
{
struct delegpt_addr* a;
log_assert(dp->dp_type_mlc);
a->attempts = 0;
a->bogus = bogus;
a->lame = lame;
+ a->dnsseclame = 0;
return 1;
}
int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
- struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame)
+ struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
+ uint8_t lame)
{
struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
log_assert(dp->dp_type_mlc);
int sel_rtt;
/** if true, the A or AAAA RR was bogus, so this address is bad.
* Also check the dp->bogus to see if everything is bogus. */
- int bogus;
+ uint8_t bogus;
/** if true, this address is dispreferred: it is a lame IP address */
- int lame;
+ uint8_t lame;
+ /** if the address is dnsseclame, but this cannot be cached, this
+ * option is useful to mark the address dnsseclame.
+ * This value is not copied in addr-copy and dp-copy. */
+ uint8_t dnsseclame;
};
/**
* @return false on error.
*/
int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
- uint8_t* name, int lame);
+ uint8_t* name, uint8_t lame);
/**
* Add NS rrset; calls add_ns repeatedly.
* @return 0 on alloc error.
*/
int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
- struct ub_packed_rrset_key* ns_rrset, int lame);
+ struct ub_packed_rrset_key* ns_rrset, uint8_t lame);
/**
* Add target address to the delegation point.
*/
int delegpt_add_target(struct delegpt* dp, struct regional* regional,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
- socklen_t addrlen, int bogus, int lame);
+ socklen_t addrlen, uint8_t bogus, uint8_t lame);
/**
* Add A RRset to delegpt.
* @return 0 on alloc error.
*/
int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
- struct ub_packed_rrset_key* rrset, int lame);
+ struct ub_packed_rrset_key* rrset, uint8_t lame);
/**
* Add AAAA RRset to delegpt.
* @return 0 on alloc error.
*/
int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
- struct ub_packed_rrset_key* rrset, int lame);
+ struct ub_packed_rrset_key* rrset, uint8_t lame);
/**
* Add any RRset to delegpt.
* @return 0 on alloc error.
*/
int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
- struct ub_packed_rrset_key* rrset, int lame);
+ struct ub_packed_rrset_key* rrset, uint8_t lame);
/**
* Add address to the delegation point. No servername is associated or checked.
* @return false on error.
*/
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
- struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame);
+ struct sockaddr_storage* addr, socklen_t addrlen,
+ uint8_t bogus, uint8_t lame);
/**
* Find NS record in name list of delegation point.
* @param lame: the name is lame, disprefer.
* @return false on error.
*/
-int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, int lame);
+int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
/**
* add an address to a malloced delegation point.
* @return false on error.
*/
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
- socklen_t addrlen, int bogus, int lame);
+ socklen_t addrlen, uint8_t bogus, uint8_t lame);
/**
* Add target address to the delegation point.
* @return false on error.
*/
int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
- struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame);
+ struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
+ uint8_t lame);
/** get memory in use by dp */
size_t delegpt_get_mem(struct delegpt* dp);
/* select remainder from worst to best */
else if(reclame)
return rtt+USEFUL_SERVER_TOP_TIMEOUT*3; /* nonpref */
- else if(dnsseclame )
+ else if(dnsseclame || a->dnsseclame)
return rtt+USEFUL_SERVER_TOP_TIMEOUT*2; /* nonpref */
else if(a->lame)
return rtt+USEFUL_SERVER_TOP_TIMEOUT+1; /* nonpref */
else return rtt;
}
/* no server information present */
- if(a->lame)
+ if(a->dnsseclame)
+ return rtt+USEFUL_SERVER_TOP_TIMEOUT*2; /* nonpref */
+ else if(a->lame)
return USEFUL_SERVER_TOP_TIMEOUT+1+UNKNOWN_SERVER_NICENESS; /* nonpref */
return UNKNOWN_SERVER_NICENESS;
}
iq->chase_flags &= ~BIT_RD; /* go to authorities */
for(ns = p->nslist; ns; ns=ns->next) {
(void)delegpt_add_ns(iq->dp, qstate->region,
- ns->name, (int)ns->lame);
+ ns->name, ns->lame);
}
for(a = p->target_list; a; a=a->next_target) {
(void)delegpt_add_addr(iq->dp, qstate->region,
&& type != RESPONSE_TYPE_UNTYPED) {
/* a possible answer, see if it is missing DNSSEC */
/* but not when forwarding, so we dont mark fwder lame */
- /* also make sure the answer is from the zone we expected,
- * otherwise, (due to parent,child on same server), we
- * might mark the server,zone lame inappropriately */
- if(!iter_msg_has_dnssec(iq->response) &&
- iter_msg_from_zone(iq->response, iq->dp, type,
- iq->qchase.qclass)) {
+ if(!iter_msg_has_dnssec(iq->response)) {
+ /* Mark this address as dnsseclame in this dp,
+ * because that will make serverselection disprefer
+ * it, but also, once it is the only final option,
+ * use dnssec-lame-bypass if it needs to query there.*/
+ if(qstate->reply) {
+ struct delegpt_addr* a = delegpt_find_addr(
+ iq->dp, &qstate->reply->addr,
+ qstate->reply->addrlen);
+ if(a) a->dnsseclame = 1;
+ }
+ /* test the answer is from the zone we expected,
+ * otherwise, (due to parent,child on same server), we
+ * might mark the server,zone lame inappropriately */
+ if(!iter_msg_from_zone(iq->response, iq->dp, type,
+ iq->qchase.qclass))
+ qstate->reply = NULL;
type = RESPONSE_TYPE_LAME;
dnsseclame = 1;
}
*qstate->env->now, dnsseclame, 0,
iq->qchase.qtype))
log_err("mark host lame: out of memory");
- } else log_err("%slame response from cache",
- dnsseclame?"DNSSEC ":"");
+ }
} else if(type == RESPONSE_TYPE_REC_LAME) {
/* Cache the LAMEness. */
verbose(VERB_DETAIL, "query response REC_LAME: "
rrset->rk.dname_len)) {
/* if dpns->lame then set newcname ns lame too */
if(!delegpt_add_ns(foriq->dp, forq->region,
- rrset->rk.dname, (int)dpns->lame))
+ rrset->rk.dname, dpns->lame))
log_err("out of memory adding cnamed-ns");
}
/* if dpns->lame then set the address(es) lame too */
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset,
- (int)dpns->lame))
+ dpns->lame))
log_err("out of memory adding targets");
verbose(VERB_ALGO, "added target response");
delegpt_log(VERB_ALGO, foriq->dp);
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(akey) {
- if(!delegpt_add_rrset_A(dp, region, akey, (int)ns->lame)) {
+ if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) {
lock_rw_unlock(&akey->entry.lock);
return 0;
}
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
if(akey) {
- if(!delegpt_add_rrset_AAAA(dp, region, akey, (int)ns->lame)) {
+ if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) {
lock_rw_unlock(&akey->entry.lock);
return 0;
}
ENTRY_END
ENTRY_BEGIN
-MATCH opcode subdomain
+MATCH opcode qname qtype
ADJUST copy_id copy_query
REPLY QR
SECTION QUESTION
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
-RANGE_END
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; no AAAA
+ENTRY_END
RANGE_END
STEP 20 QUERY
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; no NSECs to prove this, not needed in test, but could be there
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+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.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+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.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname