struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
struct packed_rrset_data* d =
(struct packed_rrset_data*)k->entry.data;
+ if(d->security == sec_status_bogus) {
+ if(!ssl_printf(ssl, "Address is BOGUS:\n"))
+ return 0;
+ }
if(!dump_rrset(ssl, k, d, 0))
return 0;
}
/* since dp has not been used by iterator, all are available*/
if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
"have no addresses in cache.\n"
- "It provides %d IP addresses.\n",
- (int)n_ns, (int)n_miss, (int)n_addr))
+ "It provides %d IP addresses. %s\n",
+ (int)n_ns, (int)n_miss, (int)n_addr,
+ (dp->bogus?"It is BOGUS":"") ))
return 0;
/* go up? */
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
20 October 2008: Wouter
- quench a log message that is debug only.
- iana portlist updated.
+ - do not query bogus nameservers. It is like nameservers that have
+ the NS or A or AAAA record bogus are listed as donotquery.
17 October 2008: Wouter
- port Leopard/G5: fixup type conversion size_t/uint32.
+ off-path validation
+ root NS, root glue validation after prime
-* ignore bogus nameservers, pretend they always return a servfail.
++ ignore bogus nameservers, pretend they always return a servfail.
*** Features features, for later
copy->nslist->resolved = ns->resolved;
}
for(a = dp->target_list; a; a = a->next_target) {
- if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen))
+ if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
+ a->bogus))
return NULL;
}
return copy;
int
delegpt_add_target(struct delegpt* dp, struct regional* region,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
- socklen_t addrlen)
+ socklen_t addrlen, int bogus)
{
struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
if(!ns) {
return 1;
}
ns->resolved = 1;
- return delegpt_add_addr(dp, region, addr, addrlen);
+ return delegpt_add_addr(dp, region, addr, addrlen, bogus);
}
int
delegpt_add_addr(struct delegpt* dp, struct regional* region,
- struct sockaddr_storage* addr, socklen_t addrlen)
+ struct sockaddr_storage* addr, socklen_t addrlen, int bogus)
{
struct delegpt_addr* a = (struct delegpt_addr*)regional_alloc(region,
sizeof(struct delegpt_addr));
memcpy(&a->addr, addr, addrlen);
a->addrlen = addrlen;
a->attempts = 0;
+ a->bogus = bogus;
return 1;
}
if(verbosity >= VERB_ALGO) {
for(ns = dp->nslist; ns; ns = ns->next) {
dname_str(ns->name, buf);
- log_info(" %s%s", buf, (ns->resolved?"*":""));
+ log_info(" %s%s%s", buf, (ns->resolved?"*":""),
+ (dp->bogus?" BOGUS":"") );
}
for(a = dp->target_list; a; a = a->next_target) {
- log_addr(VERB_ALGO, " ", &a->addr, a->addrlen);
+ if(a->bogus)
+ log_addr(VERB_ALGO, " BOGUS ",
+ &a->addr, a->addrlen);
+ else log_addr(VERB_ALGO, " ", &a->addr, a->addrlen);
}
}
}
struct packed_rrset_data* nsdata = (struct packed_rrset_data*)
ns_rrset->entry.data;
size_t i;
+ if(nsdata->security == sec_status_bogus)
+ dp->bogus = 1;
for(i=0; i<nsdata->count; i++) {
if(nsdata->rr_len[i] < 2+1) continue; /* len + root label */
if(dname_valid(nsdata->rr_data[i]+2, nsdata->rr_len[i]-2) !=
memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);
if(!delegpt_add_target(dp, region, ak->rk.dname,
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
- len))
+ len, (d->security==sec_status_bogus) ))
return 0;
}
return 1;
memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);
if(!delegpt_add_target(dp, region, ak->rk.dname,
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
- len))
+ len, (d->security==sec_status_bogus) ))
return 0;
}
return 1;
struct delegpt_addr* usable_list;
/** the list of returned targets; subset of target_list */
struct delegpt_addr* result_list;
+
+ /** if true, the NS RRset was bogus. All info is bad. */
+ int bogus;
};
/**
int attempts;
/** rtt stored here in the selection algorithm */
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;
};
/**
* @param namelen: length of name.
* @param addr: the address.
* @param addrlen: the length of addr.
+ * @param bogus: security status for the address, pass true if bogus.
* @return false on error.
*/
int delegpt_add_target(struct delegpt* dp, struct regional* regional,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
- socklen_t addrlen);
+ socklen_t addrlen, int bogus);
/**
* Add A RRset to delegpt.
* @param regional: where to allocate the info.
* @param addr: the address.
* @param addrlen: the length of addr.
+ * @param bogus: if address is bogus.
* @return false on error.
*/
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
- struct sockaddr_storage* addr, socklen_t addrlen);
+ struct sockaddr_storage* addr, socklen_t addrlen, int bogus);
/**
* Find NS record in name list of delegation point.
s->name, p->str);
return 0;
}
- if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen)) {
+ if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen, 0)) {
log_err("out of memory");
return 0;
}
if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf)) ||
!extstrtoaddr(ip, &addr, &addrlen) ||
!delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
- &addr, addrlen)) {
+ &addr, addrlen, 0)) {
ldns_rdf_deep_free(rdf);
return 0;
}
s->name, p->str);
return 0;
}
- if(!delegpt_add_addr(dp, hints->region, &addr, addrlen)) {
+ if(!delegpt_add_addr(dp, hints->region, &addr, addrlen, 0)) {
log_err("out of memory");
return 0;
}
if(!delegpt_add_target(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
- (struct sockaddr_storage*)&sa, len)) {
+ (struct sockaddr_storage*)&sa, len,
+ 0)) {
log_err("out of memory reading root hints");
goto stop_read;
}
if(!delegpt_add_target(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
- (struct sockaddr_storage*)&sa, len)) {
+ (struct sockaddr_storage*)&sa, len,
+ 0)) {
log_err("out of memory reading root hints");
goto stop_read;
}
struct delegpt_addr* a)
{
int rtt, lame, reclame, dnsseclame;
+ if(a->bogus)
+ return -1; /* address of server is bogus */
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
return -1; /* server is on the donotquery list */
}
{
int got_it = 0;
struct delegpt_addr* a;
+ if(dp->bogus)
+ return 0; /* NS bogus, all bogus, nothing found */
for(a=dp->result_list; a; a = a->next_result) {
a->sel_rtt = iter_filter_unsuitable(iter_env, env,
name, namelen, qtype, now, a);