| |
@@ -1,944 +0,0 @@
|
| |
- diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c
|
| |
- index f88b3e1..522e0e9 100644
|
| |
- --- a/iterator/iter_delegpt.c
|
| |
- +++ b/iterator/iter_delegpt.c
|
| |
- @@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
| |
- }
|
| |
- for(a = dp->target_list; a; a = a->next_target) {
|
| |
- if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
| |
- - a->bogus, a->lame, a->tls_auth_name))
|
| |
- + a->bogus, a->lame, a->tls_auth_name, NULL))
|
| |
- return NULL;
|
| |
- }
|
| |
- return copy;
|
| |
- @@ -161,7 +161,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
|
| |
- int
|
| |
- delegpt_add_target(struct delegpt* dp, struct regional* region,
|
| |
- uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
|
| |
- - socklen_t addrlen, uint8_t bogus, uint8_t lame)
|
| |
- + socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions)
|
| |
- {
|
| |
- struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
|
| |
- log_assert(!dp->dp_type_mlc);
|
| |
- @@ -176,13 +176,14 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
|
| |
- if(ns->got4 && ns->got6)
|
| |
- ns->resolved = 1;
|
| |
- }
|
| |
- - return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
|
| |
- + return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL,
|
| |
- + additions);
|
| |
- }
|
| |
-
|
| |
- int
|
| |
- delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
| |
- struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
|
| |
- - uint8_t lame, char* tls_auth_name)
|
| |
- + uint8_t lame, char* tls_auth_name, int* additions)
|
| |
- {
|
| |
- struct delegpt_addr* a;
|
| |
- log_assert(!dp->dp_type_mlc);
|
| |
- @@ -195,6 +196,9 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
| |
- return 1;
|
| |
- }
|
| |
-
|
| |
- + if(additions)
|
| |
- + *additions = 1;
|
| |
- +
|
| |
- a = (struct delegpt_addr*)regional_alloc(region,
|
| |
- sizeof(struct delegpt_addr));
|
| |
- if(!a)
|
| |
- @@ -382,10 +386,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
|
| |
- continue;
|
| |
-
|
| |
- if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) {
|
| |
- - if(!delegpt_add_rrset_A(dp, region, s, 0))
|
| |
- + if(!delegpt_add_rrset_A(dp, region, s, 0, NULL))
|
| |
- return NULL;
|
| |
- } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) {
|
| |
- - if(!delegpt_add_rrset_AAAA(dp, region, s, 0))
|
| |
- + if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL))
|
| |
- return NULL;
|
| |
- }
|
| |
- }
|
| |
- @@ -416,7 +420,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
|
| |
-
|
| |
- int
|
| |
- delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
| |
- - struct ub_packed_rrset_key* ak, uint8_t lame)
|
| |
- + struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
|
| |
- {
|
| |
- struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
|
| |
- size_t i;
|
| |
- @@ -432,7 +436,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
| |
- 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, (d->security==sec_status_bogus), lame))
|
| |
- + len, (d->security==sec_status_bogus), lame, additions))
|
| |
- return 0;
|
| |
- }
|
| |
- return 1;
|
| |
- @@ -440,7 +444,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
| |
-
|
| |
- int
|
| |
- delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
| |
- - struct ub_packed_rrset_key* ak, uint8_t lame)
|
| |
- + struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
|
| |
- {
|
| |
- struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
|
| |
- size_t i;
|
| |
- @@ -456,7 +460,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
| |
- 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, (d->security==sec_status_bogus), lame))
|
| |
- + len, (d->security==sec_status_bogus), lame, additions))
|
| |
- return 0;
|
| |
- }
|
| |
- return 1;
|
| |
- @@ -464,20 +468,32 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
| |
-
|
| |
- int
|
| |
- delegpt_add_rrset(struct delegpt* dp, struct regional* region,
|
| |
- - struct ub_packed_rrset_key* rrset, uint8_t lame)
|
| |
- + struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions)
|
| |
- {
|
| |
- if(!rrset)
|
| |
- return 1;
|
| |
- if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
|
| |
- return delegpt_rrset_add_ns(dp, region, rrset, lame);
|
| |
- else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
|
| |
- - return delegpt_add_rrset_A(dp, region, rrset, lame);
|
| |
- + return delegpt_add_rrset_A(dp, region, rrset, lame, additions);
|
| |
- else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
|
| |
- - return delegpt_add_rrset_AAAA(dp, region, rrset, lame);
|
| |
- + return delegpt_add_rrset_AAAA(dp, region, rrset, lame, additions);
|
| |
- log_warn("Unknown rrset type added to delegpt");
|
| |
- return 1;
|
| |
- }
|
| |
-
|
| |
- +void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype)
|
| |
- +{
|
| |
- + if(ns) {
|
| |
- + if(qtype == LDNS_RR_TYPE_A)
|
| |
- + ns->got4 = 2;
|
| |
- + else if(qtype == LDNS_RR_TYPE_AAAA)
|
| |
- + ns->got6 = 2;
|
| |
- + if(ns->got4 && ns->got6)
|
| |
- + ns->resolved = 1;
|
| |
- + }
|
| |
- +}
|
| |
- +
|
| |
- void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
|
| |
- {
|
| |
- struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
| |
- @@ -487,14 +503,7 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
|
| |
- if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {
|
| |
- struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname,
|
| |
- msg->key.qname_len);
|
| |
- - if(ns) {
|
| |
- - if(msg->key.qtype == LDNS_RR_TYPE_A)
|
| |
- - ns->got4 = 1;
|
| |
- - else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)
|
| |
- - ns->got6 = 1;
|
| |
- - if(ns->got4 && ns->got6)
|
| |
- - ns->resolved = 1;
|
| |
- - }
|
| |
- + delegpt_mark_neg(ns, msg->key.qtype);
|
| |
- }
|
| |
- }
|
| |
-
|
| |
- diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h
|
| |
- index 354bd61..3aded22 100644
|
| |
- --- a/iterator/iter_delegpt.h
|
| |
- +++ b/iterator/iter_delegpt.h
|
| |
- @@ -104,9 +104,10 @@ struct delegpt_ns {
|
| |
- * and marked true if got4 and got6 are both true.
|
| |
- */
|
| |
- int resolved;
|
| |
- - /** if the ipv4 address is in the delegpt */
|
| |
- + /** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative,
|
| |
- + * negative means it was done, but no content. */
|
| |
- uint8_t got4;
|
| |
- - /** if the ipv6 address is in the delegpt */
|
| |
- + /** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */
|
| |
- uint8_t got6;
|
| |
- /**
|
| |
- * If the name is parent-side only and thus dispreferred.
|
| |
- @@ -213,11 +214,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
|
| |
- * @param addrlen: the length of addr.
|
| |
- * @param bogus: security status for the address, pass true if bogus.
|
| |
- * @param lame: address is lame.
|
| |
- + * @param additions: will be set to 1 if a new address is added
|
| |
- * @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, uint8_t bogus, uint8_t lame);
|
| |
- + socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions);
|
| |
-
|
| |
- /**
|
| |
- * Add A RRset to delegpt.
|
| |
- @@ -225,10 +227,11 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional,
|
| |
- * @param regional: where to allocate the info.
|
| |
- * @param rrset: RRset A to add.
|
| |
- * @param lame: rrset is lame, disprefer it.
|
| |
- + * @param additions: will be set to 1 if a new address is added
|
| |
- * @return 0 on alloc error.
|
| |
- */
|
| |
- int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
|
| |
- - struct ub_packed_rrset_key* rrset, uint8_t lame);
|
| |
- + struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
|
| |
-
|
| |
- /**
|
| |
- * Add AAAA RRset to delegpt.
|
| |
- @@ -236,10 +239,11 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
|
| |
- * @param regional: where to allocate the info.
|
| |
- * @param rrset: RRset AAAA to add.
|
| |
- * @param lame: rrset is lame, disprefer it.
|
| |
- + * @param additions: will be set to 1 if a new address is added
|
| |
- * @return 0 on alloc error.
|
| |
- */
|
| |
- int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
|
| |
- - struct ub_packed_rrset_key* rrset, uint8_t lame);
|
| |
- + struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
|
| |
-
|
| |
- /**
|
| |
- * Add any RRset to delegpt.
|
| |
- @@ -248,10 +252,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
|
| |
- * @param regional: where to allocate the info.
|
| |
- * @param rrset: RRset to add, NS, A, AAAA.
|
| |
- * @param lame: rrset is lame, disprefer it.
|
| |
- + * @param additions: will be set to 1 if a new address is added
|
| |
- * @return 0 on alloc error.
|
| |
- */
|
| |
- int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
| |
- - struct ub_packed_rrset_key* rrset, uint8_t lame);
|
| |
- + struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
|
| |
-
|
| |
- /**
|
| |
- * Add address to the delegation point. No servername is associated or checked.
|
| |
- @@ -262,11 +267,13 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
| |
- * @param bogus: if address is bogus.
|
| |
- * @param lame: if address is lame.
|
| |
- * @param tls_auth_name: TLS authentication name (or NULL).
|
| |
- + * @param additions: will be set to 1 if a new address is added
|
| |
- + * @return 0 on alloc error.
|
| |
- * @return false on error.
|
| |
- */
|
| |
- int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
|
| |
- struct sockaddr_storage* addr, socklen_t addrlen,
|
| |
- - uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
| |
- + uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions);
|
| |
-
|
| |
- /**
|
| |
- * Find NS record in name list of delegation point.
|
| |
- @@ -339,6 +346,14 @@ size_t delegpt_count_targets(struct delegpt* dp);
|
| |
- struct delegpt* delegpt_from_message(struct dns_msg* msg,
|
| |
- struct regional* regional);
|
| |
-
|
| |
- +/**
|
| |
- +* Mark negative return in delegation point for specific nameserver.
|
| |
- +* sets the got4 or got6 to negative, updates the ns->resolved.
|
| |
- +* @param ns: the nameserver in the delegpt.
|
| |
- +* @param qtype: A or AAAA (host order).
|
| |
- +*/
|
| |
- +void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype);
|
| |
- +
|
| |
- /**
|
| |
- * Add negative message to delegation point.
|
| |
- * @param dp: delegation point.
|
| |
- diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
|
| |
- index 12580dc..8230d17 100644
|
| |
- --- a/iterator/iter_scrub.c
|
| |
- +++ b/iterator/iter_scrub.c
|
| |
- @@ -185,8 +185,9 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,
|
| |
- /** Get target name of a CNAME */
|
| |
- static int
|
| |
- parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
|
| |
- - size_t* snamelen)
|
| |
- + size_t* snamelen, sldns_buffer* pkt)
|
| |
- {
|
| |
- + size_t oldpos, dlen;
|
| |
- if(rrset->rr_count != 1) {
|
| |
- struct rr_parse* sig;
|
| |
- verbose(VERB_ALGO, "Found CNAME rrset with "
|
| |
- @@ -204,6 +205,19 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
|
| |
- *sname = rrset->rr_first->ttl_data + sizeof(uint32_t)
|
| |
- + sizeof(uint16_t); /* skip ttl, rdatalen */
|
| |
- *snamelen = rrset->rr_first->size - sizeof(uint16_t);
|
| |
- +
|
| |
- + if(rrset->rr_first->outside_packet) {
|
| |
- + if(!dname_valid(*sname, *snamelen))
|
| |
- + return 0;
|
| |
- + return 1;
|
| |
- + }
|
| |
- + oldpos = sldns_buffer_position(pkt);
|
| |
- + sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt)));
|
| |
- + dlen = pkt_dname_len(pkt);
|
| |
- + sldns_buffer_set_position(pkt, oldpos);
|
| |
- + if(dlen == 0)
|
| |
- + return 0; /* parse fail on the rdata name */
|
| |
- + *snamelen = dlen;
|
| |
- return 1;
|
| |
- }
|
| |
-
|
| |
- @@ -215,7 +229,7 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
|
| |
- /* we already know that sname is a strict subdomain of DNAME owner */
|
| |
- uint8_t* dtarg = NULL;
|
| |
- size_t dtarglen;
|
| |
- - if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen))
|
| |
- + if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt))
|
| |
- return 0;
|
| |
- log_assert(qnamelen > dname_rrset->dname_len);
|
| |
- /* DNAME from com. to net. with qname example.com. -> example.net. */
|
| |
- @@ -372,7 +386,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
| |
- /* check next cname */
|
| |
- uint8_t* t = NULL;
|
| |
- size_t tlen = 0;
|
| |
- - if(!parse_get_cname_target(nx, &t, &tlen))
|
| |
- + if(!parse_get_cname_target(nx, &t, &tlen, pkt))
|
| |
- return 0;
|
| |
- if(dname_pkt_compare(pkt, alias, t) == 0) {
|
| |
- /* it's OK and better capitalized */
|
| |
- @@ -423,7 +437,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
| |
- size_t tlen = 0;
|
| |
- if(synth_cname(sname, snamelen, nx, alias,
|
| |
- &aliaslen, pkt) &&
|
| |
- - parse_get_cname_target(rrset, &t, &tlen) &&
|
| |
- + parse_get_cname_target(rrset, &t, &tlen, pkt) &&
|
| |
- dname_pkt_compare(pkt, alias, t) == 0) {
|
| |
- /* the synthesized CNAME equals the
|
| |
- * current CNAME. This CNAME is the
|
| |
- @@ -442,7 +456,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
| |
- }
|
| |
-
|
| |
- /* move to next name in CNAME chain */
|
| |
- - if(!parse_get_cname_target(rrset, &sname, &snamelen))
|
| |
- + if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt))
|
| |
- return 0;
|
| |
- prev = rrset;
|
| |
- rrset = rrset->rrset_all_next;
|
| |
- diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
|
| |
- index 0a8f770..a107bee 100644
|
| |
- --- a/iterator/iter_utils.c
|
| |
- +++ b/iterator/iter_utils.c
|
| |
- @@ -1008,7 +1008,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
| |
- log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
| |
- ns->done_pside4 = 1;
|
| |
- /* a negative-cache-element has no addresses it adds */
|
| |
- - if(!delegpt_add_rrset_A(dp, region, akey, 1))
|
| |
- + if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL))
|
| |
- log_err("malloc failure in lookup_parent_glue");
|
| |
- lock_rw_unlock(&akey->entry.lock);
|
| |
- }
|
| |
- @@ -1020,7 +1020,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
| |
- log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
| |
- ns->done_pside6 = 1;
|
| |
- /* a negative-cache-element has no addresses it adds */
|
| |
- - if(!delegpt_add_rrset_AAAA(dp, region, akey, 1))
|
| |
- + if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL))
|
| |
- log_err("malloc failure in lookup_parent_glue");
|
| |
- lock_rw_unlock(&akey->entry.lock);
|
| |
- }
|
| |
- diff --git a/iterator/iterator.c b/iterator/iterator.c
|
| |
- index 58a9bff..a4ad319 100644
|
| |
- --- a/iterator/iterator.c
|
| |
- +++ b/iterator/iterator.c
|
| |
- @@ -69,6 +69,8 @@
|
| |
- #include "sldns/parseutil.h"
|
| |
- #include "sldns/sbuffer.h"
|
| |
-
|
| |
- +static void target_count_increase_nx(struct iter_qstate* iq, int num);
|
| |
- +
|
| |
- int
|
| |
- iter_init(struct module_env* env, int id)
|
| |
- {
|
| |
- @@ -147,6 +149,7 @@ iter_new(struct module_qstate* qstate, int id)
|
| |
- iq->sent_count = 0;
|
| |
- iq->ratelimit_ok = 0;
|
| |
- iq->target_count = NULL;
|
| |
- + iq->dp_target_count = 0;
|
| |
- iq->wait_priming_stub = 0;
|
| |
- iq->refetch_glue = 0;
|
| |
- iq->dnssec_expected = 0;
|
| |
- @@ -218,6 +221,7 @@ final_state(struct iter_qstate* iq)
|
| |
- static void
|
| |
- error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
| |
- {
|
| |
- + struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
|
| |
- struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
|
| |
-
|
| |
- if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
|
| |
- @@ -242,7 +246,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
| |
- super->region, super_iq->dp))
|
| |
- log_err("out of memory adding missing");
|
| |
- }
|
| |
- + delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
| |
- dpns->resolved = 1; /* mark as failed */
|
| |
- + if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
| |
- + (dpns->got6 == 2 || !ie->supports_ipv6))
|
| |
- + target_count_increase_nx(super_iq, 1);
|
| |
- }
|
| |
- if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
|
| |
- /* prime failed to get delegation */
|
| |
- @@ -577,7 +585,7 @@ static void
|
| |
- target_count_create(struct iter_qstate* iq)
|
| |
- {
|
| |
- if(!iq->target_count) {
|
| |
- - iq->target_count = (int*)calloc(2, sizeof(int));
|
| |
- + iq->target_count = (int*)calloc(3, sizeof(int));
|
| |
- /* if calloc fails we simply do not track this number */
|
| |
- if(iq->target_count)
|
| |
- iq->target_count[0] = 1;
|
| |
- @@ -590,6 +598,15 @@ target_count_increase(struct iter_qstate* iq, int num)
|
| |
- target_count_create(iq);
|
| |
- if(iq->target_count)
|
| |
- iq->target_count[1] += num;
|
| |
- + iq->dp_target_count++;
|
| |
- +}
|
| |
- +
|
| |
- +static void
|
| |
- +target_count_increase_nx(struct iter_qstate* iq, int num)
|
| |
- +{
|
| |
- + target_count_create(iq);
|
| |
- + if(iq->target_count)
|
| |
- + iq->target_count[2] += num;
|
| |
- }
|
| |
-
|
| |
- /**
|
| |
- @@ -612,13 +629,15 @@ target_count_increase(struct iter_qstate* iq, int num)
|
| |
- * @param subq_ret: if newly allocated, the subquerystate, or NULL if it does
|
| |
- * not need initialisation.
|
| |
- * @param v: if true, validation is done on the subquery.
|
| |
- + * @param detached: true if this qstate should not attach to the subquery
|
| |
- * @return false on error (malloc).
|
| |
- */
|
| |
- static int
|
| |
- generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
| |
- uint16_t qclass, struct module_qstate* qstate, int id,
|
| |
- struct iter_qstate* iq, enum iter_state initial_state,
|
| |
- - enum iter_state finalstate, struct module_qstate** subq_ret, int v)
|
| |
- + enum iter_state finalstate, struct module_qstate** subq_ret, int v,
|
| |
- + int detached)
|
| |
- {
|
| |
- struct module_qstate* subq = NULL;
|
| |
- struct iter_qstate* subiq = NULL;
|
| |
- @@ -645,12 +664,24 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
| |
- valrec = 1;
|
| |
- }
|
| |
-
|
| |
- - /* attach subquery, lookup existing or make a new one */
|
| |
- - fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
| |
- - if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
|
| |
- - &subq)) {
|
| |
- - return 0;
|
| |
- - }
|
| |
- + if(detached) {
|
| |
- + struct mesh_state* sub = NULL;
|
| |
- + fptr_ok(fptr_whitelist_modenv_add_sub(
|
| |
- + qstate->env->add_sub));
|
| |
- + if(!(*qstate->env->add_sub)(qstate, &qinf,
|
| |
- + qflags, prime, valrec, &subq, &sub)){
|
| |
- + return 0;
|
| |
- + }
|
| |
- + }
|
| |
- + else {
|
| |
- + /* attach subquery, lookup existing or make a new one */
|
| |
- + fptr_ok(fptr_whitelist_modenv_attach_sub(
|
| |
- + qstate->env->attach_sub));
|
| |
- + if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
|
| |
- + valrec, &subq)) {
|
| |
- + return 0;
|
| |
- + }
|
| |
- + }
|
| |
- *subq_ret = subq;
|
| |
- if(subq) {
|
| |
- /* initialise the new subquery */
|
| |
- @@ -672,6 +703,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
| |
- subiq->target_count = iq->target_count;
|
| |
- if(iq->target_count)
|
| |
- iq->target_count[0] ++; /* extra reference */
|
| |
- + subiq->dp_target_count = 0;
|
| |
- subiq->num_current_queries = 0;
|
| |
- subiq->depth = iq->depth+1;
|
| |
- outbound_list_init(&subiq->outlist);
|
| |
- @@ -715,7 +747,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
| |
- * the normal INIT state logic (which would cause an infloop). */
|
| |
- if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS,
|
| |
- qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE,
|
| |
- - &subq, 0)) {
|
| |
- + &subq, 0, 0)) {
|
| |
- verbose(VERB_ALGO, "could not prime root");
|
| |
- return 0;
|
| |
- }
|
| |
- @@ -805,7 +837,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
| |
- * redundant INIT state processing. */
|
| |
- if(!generate_sub_request(stub_dp->name, stub_dp->namelen,
|
| |
- LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
|
| |
- - QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
|
| |
- + QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) {
|
| |
- verbose(VERB_ALGO, "could not prime stub");
|
| |
- (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
| |
- return 1; /* return 1 to make module stop, with error */
|
| |
- @@ -976,7 +1008,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq,
|
| |
- if(!generate_sub_request(s->rk.dname, s->rk.dname_len,
|
| |
- ntohs(s->rk.type), ntohs(s->rk.rrset_class),
|
| |
- qstate, id, iq,
|
| |
- - INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
| |
- + INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
| |
- verbose(VERB_ALGO, "could not generate addr check");
|
| |
- return;
|
| |
- }
|
| |
- @@ -1020,7 +1052,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
| |
- iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
| |
- if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
|
| |
- LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
|
| |
- - INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
| |
- + INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
| |
- verbose(VERB_ALGO, "could not generate ns check");
|
| |
- return;
|
| |
- }
|
| |
- @@ -1077,7 +1109,7 @@ generate_dnskey_prefetch(struct module_qstate* qstate,
|
| |
- iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass);
|
| |
- if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
|
| |
- LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq,
|
| |
- - INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
|
| |
- + INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
|
| |
- /* we'll be slower, but it'll work */
|
| |
- verbose(VERB_ALGO, "could not generate dnskey prefetch");
|
| |
- return;
|
| |
- @@ -1251,6 +1283,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
| |
- iq->refetch_glue = 0;
|
| |
- iq->query_restart_count++;
|
| |
- iq->sent_count = 0;
|
| |
- + iq->dp_target_count = 0;
|
| |
- sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
| |
- if(qstate->env->cfg->qname_minimisation)
|
| |
- iq->minimisation_state = INIT_MINIMISE_STATE;
|
| |
- @@ -1613,7 +1646,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
|
| |
- {
|
| |
- struct module_qstate* subq;
|
| |
- if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
| |
- - id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
| |
- + id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
|
| |
- return 0;
|
| |
- if(subq) {
|
| |
- struct iter_qstate* subiq =
|
| |
- @@ -1664,7 +1697,7 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,
|
| |
- {
|
| |
- struct module_qstate* subq;
|
| |
- if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
| |
- - id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
| |
- + id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
|
| |
- return 0;
|
| |
- log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);
|
| |
- return 1;
|
| |
- @@ -1703,6 +1736,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
| |
- "number of glue fetches %d", s, iq->target_count[1]);
|
| |
- return 0;
|
| |
- }
|
| |
- + if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
|
| |
- + char s[LDNS_MAX_DOMAINLEN+1];
|
| |
- + dname_str(qstate->qinfo.qname, s);
|
| |
- + verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
| |