summaryrefslogtreecommitdiff
path: root/usr.sbin/unbound/iterator
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2017-02-17 18:53:33 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2017-02-17 18:53:33 +0000
commit3d7e55155dd0acaba23dc19920091ee5580ad180 (patch)
tree128498ff1499e8cde628b28e9707636bd4d161a5 /usr.sbin/unbound/iterator
parent57a7719d7ee152a16a7ac027d83bcce25a6a46ac (diff)
Update to unbound-1.6.1rc3 - thanks millert@ and Brad for tests.
Diffstat (limited to 'usr.sbin/unbound/iterator')
-rw-r--r--usr.sbin/unbound/iterator/iter_delegpt.c200
-rw-r--r--usr.sbin/unbound/iterator/iter_delegpt.h108
-rw-r--r--usr.sbin/unbound/iterator/iter_donotq.h22
-rw-r--r--usr.sbin/unbound/iterator/iter_fwd.c10
-rw-r--r--usr.sbin/unbound/iterator/iter_fwd.h68
-rw-r--r--usr.sbin/unbound/iterator/iter_hints.c6
-rw-r--r--usr.sbin/unbound/iterator/iter_hints.h49
-rw-r--r--usr.sbin/unbound/iterator/iter_priv.h30
-rw-r--r--usr.sbin/unbound/iterator/iter_scrub.c4
-rw-r--r--usr.sbin/unbound/iterator/iter_utils.c36
-rw-r--r--usr.sbin/unbound/iterator/iterator.c166
-rw-r--r--usr.sbin/unbound/iterator/iterator.h4
12 files changed, 519 insertions, 184 deletions
diff --git a/usr.sbin/unbound/iterator/iter_delegpt.c b/usr.sbin/unbound/iterator/iter_delegpt.c
index f49048d5c26..ecf88b293da 100644
--- a/usr.sbin/unbound/iterator/iter_delegpt.c
+++ b/usr.sbin/unbound/iterator/iter_delegpt.c
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -47,6 +47,8 @@
#include "util/data/packed_rrset.h"
#include "util/data/msgreply.h"
#include "util/net_help.h"
+#include "sldns/rrdef.h"
+#include "sldns/sbuffer.h"
struct delegpt*
delegpt_create(struct regional* region)
@@ -70,8 +72,9 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
return NULL;
copy->bogus = dp->bogus;
copy->has_parent_side_NS = dp->has_parent_side_NS;
+ copy->ssl_upstream = dp->ssl_upstream;
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;
@@ -90,6 +93,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
int
delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name)
{
+ log_assert(!dp->dp_type_mlc);
dp->namelabs = dname_count_size_labels(name, &dp->namelen);
dp->name = regional_alloc_init(region, name, dp->namelen);
return dp->name != 0;
@@ -97,11 +101,12 @@ delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name)
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;
(void)dname_count_size_labels(name, &len);
+ log_assert(!dp->dp_type_mlc);
/* slow check for duplicates to avoid counting failures when
* adding the same server as a dependency twice */
if(delegpt_find_ns(dp, name, len))
@@ -117,10 +122,10 @@ delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name,
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 1;
+ return ns->name != 0;
}
struct delegpt_ns*
@@ -143,7 +148,9 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
{
struct delegpt_addr* p = dp->target_list;
while(p) {
- if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0) {
+ if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0
+ && ((struct sockaddr_in*)addr)->sin_port ==
+ ((struct sockaddr_in*)&p->addr)->sin_port) {
return p;
}
p = p->next_target;
@@ -154,9 +161,10 @@ 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, 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);
if(!ns) {
/* ignore it */
return 1;
@@ -173,10 +181,11 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
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);
/* check for duplicates */
if((a = delegpt_find_addr(dp, addr, addrlen))) {
if(bogus)
@@ -200,6 +209,7 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
a->attempts = 0;
a->bogus = bogus;
a->lame = lame;
+ a->dnsseclame = 0;
return 1;
}
@@ -372,17 +382,18 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
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;
size_t i;
+ log_assert(!dp->dp_type_mlc);
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) !=
- (size_t)ldns_read_uint16(nsdata->rr_data[i]))
+ (size_t)sldns_read_uint16(nsdata->rr_data[i]))
continue; /* bad format */
/* add rdata of NS (= wirefmt dname), skip rdatalen bytes */
if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2, lame))
@@ -393,12 +404,13 @@ 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, 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;
struct sockaddr_in sa;
socklen_t len = (socklen_t)sizeof(sa);
+ log_assert(!dp->dp_type_mlc);
memset(&sa, 0, len);
sa.sin_family = AF_INET;
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
@@ -416,12 +428,13 @@ 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, 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;
struct sockaddr_in6 sa;
socklen_t len = (socklen_t)sizeof(sa);
+ log_assert(!dp->dp_type_mlc);
memset(&sa, 0, len);
sa.sin6_family = AF_INET6;
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
@@ -439,7 +452,7 @@ 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, int lame)
+ struct ub_packed_rrset_key* rrset, uint8_t lame)
{
if(!rrset)
return 1;
@@ -492,3 +505,144 @@ void delegpt_no_ipv4(struct delegpt* dp)
ns->resolved = 1;
}
}
+
+struct delegpt* delegpt_create_mlc(uint8_t* name)
+{
+ struct delegpt* dp=(struct delegpt*)calloc(1, sizeof(*dp));
+ if(!dp)
+ return NULL;
+ dp->dp_type_mlc = 1;
+ if(name) {
+ dp->namelabs = dname_count_size_labels(name, &dp->namelen);
+ dp->name = memdup(name, dp->namelen);
+ if(!dp->name) {
+ free(dp);
+ return NULL;
+ }
+ }
+ return dp;
+}
+
+void delegpt_free_mlc(struct delegpt* dp)
+{
+ struct delegpt_ns* n, *nn;
+ struct delegpt_addr* a, *na;
+ if(!dp) return;
+ log_assert(dp->dp_type_mlc);
+ n = dp->nslist;
+ while(n) {
+ nn = n->next;
+ free(n->name);
+ free(n);
+ n = nn;
+ }
+ a = dp->target_list;
+ while(a) {
+ na = a->next_target;
+ free(a);
+ a = na;
+ }
+ free(dp->name);
+ free(dp);
+}
+
+int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name)
+{
+ log_assert(dp->dp_type_mlc);
+ dp->namelabs = dname_count_size_labels(name, &dp->namelen);
+ dp->name = memdup(name, dp->namelen);
+ return (dp->name != NULL);
+}
+
+int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
+{
+ struct delegpt_ns* ns;
+ size_t len;
+ (void)dname_count_size_labels(name, &len);
+ log_assert(dp->dp_type_mlc);
+ /* slow check for duplicates to avoid counting failures when
+ * adding the same server as a dependency twice */
+ if(delegpt_find_ns(dp, name, len))
+ return 1;
+ ns = (struct delegpt_ns*)malloc(sizeof(struct delegpt_ns));
+ if(!ns)
+ return 0;
+ ns->namelen = len;
+ ns->name = memdup(name, ns->namelen);
+ if(!ns->name) {
+ free(ns);
+ return 0;
+ }
+ ns->next = dp->nslist;
+ dp->nslist = ns;
+ ns->resolved = 0;
+ ns->got4 = 0;
+ ns->got6 = 0;
+ ns->lame = (uint8_t)lame;
+ ns->done_pside4 = 0;
+ ns->done_pside6 = 0;
+ return 1;
+}
+
+int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
+ socklen_t addrlen, uint8_t bogus, uint8_t lame)
+{
+ struct delegpt_addr* a;
+ log_assert(dp->dp_type_mlc);
+ /* check for duplicates */
+ if((a = delegpt_find_addr(dp, addr, addrlen))) {
+ if(bogus)
+ a->bogus = bogus;
+ if(!lame)
+ a->lame = 0;
+ return 1;
+ }
+
+ a = (struct delegpt_addr*)malloc(sizeof(struct delegpt_addr));
+ if(!a)
+ return 0;
+ a->next_target = dp->target_list;
+ dp->target_list = a;
+ a->next_result = 0;
+ a->next_usable = dp->usable_list;
+ dp->usable_list = a;
+ memcpy(&a->addr, addr, addrlen);
+ a->addrlen = addrlen;
+ 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, uint8_t bogus,
+ uint8_t lame)
+{
+ struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
+ log_assert(dp->dp_type_mlc);
+ if(!ns) {
+ /* ignore it */
+ return 1;
+ }
+ if(!lame) {
+ if(addr_is_ip6(addr, addrlen))
+ ns->got6 = 1;
+ else ns->got4 = 1;
+ if(ns->got4 && ns->got6)
+ ns->resolved = 1;
+ }
+ return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame);
+}
+
+size_t delegpt_get_mem(struct delegpt* dp)
+{
+ struct delegpt_ns* ns;
+ size_t s;
+ if(!dp) return 0;
+ s = sizeof(*dp) + dp->namelen +
+ delegpt_count_targets(dp)*sizeof(struct delegpt_addr);
+ for(ns=dp->nslist; ns; ns=ns->next)
+ s += sizeof(*ns)+ns->namelen;
+ return s;
+}
diff --git a/usr.sbin/unbound/iterator/iter_delegpt.h b/usr.sbin/unbound/iterator/iter_delegpt.h
index c4ca62dc44d..4bd79c81af0 100644
--- a/usr.sbin/unbound/iterator/iter_delegpt.h
+++ b/usr.sbin/unbound/iterator/iter_delegpt.h
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -79,6 +79,10 @@ struct delegpt {
* Also true if the delegationpoint was created from a delegation
* message and thus contains the parent-side-info already. */
uint8_t has_parent_side_NS;
+ /** for assertions on type of delegpt */
+ uint8_t dp_type_mlc;
+ /** use SSL for upstream query */
+ uint8_t ssl_upstream;
};
/**
@@ -138,9 +142,13 @@ struct delegpt_addr {
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;
};
/**
@@ -177,7 +185,7 @@ int delegpt_set_name(struct delegpt* dp, struct regional* regional,
* @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.
@@ -188,7 +196,7 @@ int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
* @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.
@@ -205,7 +213,7 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
*/
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.
@@ -216,7 +224,7 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional,
* @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.
@@ -227,7 +235,7 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
* @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.
@@ -239,7 +247,7 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
* @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.
@@ -252,7 +260,8 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
* @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.
@@ -346,4 +355,65 @@ void delegpt_no_ipv6(struct delegpt* dp);
*/
void delegpt_no_ipv4(struct delegpt* dp);
+/**
+ * create malloced delegation point, with the given name
+ * @param name: uncompressed wireformat of delegpt name.
+ * @return NULL on alloc failure
+ */
+struct delegpt* delegpt_create_mlc(uint8_t* name);
+
+/**
+ * free malloced delegation point.
+ * @param dp: must have been created with delegpt_create_mlc, free'd.
+ */
+void delegpt_free_mlc(struct delegpt* dp);
+
+/**
+ * Set name of delegation point.
+ * @param dp: delegation point. malloced.
+ * @param name: name to use.
+ * @return false on error.
+ */
+int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name);
+
+/**
+ * add a name to malloced delegation point.
+ * @param dp: must have been created with delegpt_create_mlc.
+ * @param name: the name to add.
+ * @param lame: the name is lame, disprefer.
+ * @return false on error.
+ */
+int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
+
+/**
+ * add an address to a malloced delegation point.
+ * @param dp: must have been created with delegpt_create_mlc.
+ * @param addr: the address.
+ * @param addrlen: the length of addr.
+ * @param bogus: if address is bogus.
+ * @param lame: if address is lame.
+ * @return false on error.
+ */
+int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
+ socklen_t addrlen, uint8_t bogus, uint8_t lame);
+
+/**
+ * Add target address to the delegation point.
+ * @param dp: must have been created with delegpt_create_mlc.
+ * @param name: name for which target was found (must be in nslist).
+ * This name is marked resolved.
+ * @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.
+ * @param lame: address is lame.
+ * @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, uint8_t bogus,
+ uint8_t lame);
+
+/** get memory in use by dp */
+size_t delegpt_get_mem(struct delegpt* dp);
+
#endif /* ITERATOR_ITER_DELEGPT_H */
diff --git a/usr.sbin/unbound/iterator/iter_donotq.h b/usr.sbin/unbound/iterator/iter_donotq.h
index 4c4fcb289dc..14105073aa3 100644
--- a/usr.sbin/unbound/iterator/iter_donotq.h
+++ b/usr.sbin/unbound/iterator/iter_donotq.h
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -58,7 +58,7 @@ struct iter_donotq {
* contents of type addr_tree_node. Each node is an address span
* that must not be used to send queries to.
*/
- rbtree_t tree;
+ rbtree_type tree;
};
/**
diff --git a/usr.sbin/unbound/iterator/iter_fwd.c b/usr.sbin/unbound/iterator/iter_fwd.c
index 3e580ca3551..0ba6c6ddfa9 100644
--- a/usr.sbin/unbound/iterator/iter_fwd.c
+++ b/usr.sbin/unbound/iterator/iter_fwd.c
@@ -82,7 +82,7 @@ static void fwd_zone_free(struct iter_forward_zone* n)
free(n);
}
-static void delfwdnode(rbnode_t* n, void* ATTR_UNUSED(arg))
+static void delfwdnode(rbnode_type* n, void* ATTR_UNUSED(arg))
{
struct iter_forward_zone* node = (struct iter_forward_zone*)n;
fwd_zone_free(node);
@@ -265,6 +265,8 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
* last resort will ask for parent-side NS record and thus
* fallback to the internet name servers on a failure */
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
+ /* use SSL for queries to this forwarder */
+ dp->ssl_upstream = (uint8_t)s->ssl_upstream;
verbose(VERB_QUERY, "Forward zone server list:");
delegpt_log(VERB_QUERY, dp);
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
@@ -330,7 +332,7 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
struct delegpt*
forwards_find(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
{
- rbnode_t* res = NULL;
+ rbnode_type* res = NULL;
struct iter_forward_zone key;
key.node.key = &key;
key.dclass = qclass;
@@ -345,7 +347,7 @@ struct delegpt*
forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
{
/* lookup the forward zone in the tree */
- rbnode_t* res = NULL;
+ rbnode_type* res = NULL;
struct iter_forward_zone *result;
struct iter_forward_zone key;
key.node.key = &key;
@@ -386,7 +388,7 @@ int
forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
{
struct iter_forward_zone key;
- rbnode_t* n;
+ rbnode_type* n;
struct iter_forward_zone* p;
if(*dclass == 0) {
/* first root item is first item in tree */
diff --git a/usr.sbin/unbound/iterator/iter_fwd.h b/usr.sbin/unbound/iterator/iter_fwd.h
index 8f3bc1fa2f2..e90b74c16a5 100644
--- a/usr.sbin/unbound/iterator/iter_fwd.h
+++ b/usr.sbin/unbound/iterator/iter_fwd.h
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -45,14 +45,11 @@
#include "util/rbtree.h"
struct config_file;
struct delegpt;
-struct regional;
/**
* Iterator forward zones structure
*/
struct iter_forwards {
- /** regional where forward zone server addresses are allocated */
- struct regional* region;
/**
* Zones are stored in this tree. Sort order is specially chosen.
* first sorted on qclass. Then on dname in nsec-like order, so that
@@ -60,7 +57,7 @@ struct iter_forwards {
* match which gives the ancestor needed.
* contents of type iter_forward_zone.
*/
- rbtree_t* tree;
+ rbtree_type* tree;
};
/**
@@ -68,7 +65,7 @@ struct iter_forwards {
*/
struct iter_forward_zone {
/** redblacktree node, key is this structure: class and name */
- rbnode_t node;
+ rbnode_type node;
/** name */
uint8_t* name;
/** length of name */
@@ -77,7 +74,9 @@ struct iter_forward_zone {
int namelabs;
/** delegation point with forward server information for this zone.
* If NULL then this forward entry is used to indicate that a
- * stub-zone with the same name exists, and should be used. */
+ * stub-zone with the same name exists, and should be used.
+ * This delegation point is malloced.
+ */
struct delegpt* dp;
/** pointer to parent in tree (or NULL if none) */
struct iter_forward_zone* parent;
@@ -106,6 +105,16 @@ void forwards_delete(struct iter_forwards* fwd);
int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
/**
+ * Find forward zone exactly by name
+ * @param fwd: forward storage.
+ * @param qname: The qname of the query.
+ * @param qclass: The qclass of the query.
+ * @return: A delegation point or null.
+ */
+struct delegpt* forwards_find(struct iter_forwards* fwd, uint8_t* qname,
+ uint16_t qclass);
+
+/**
* Find forward zone information
* For this qname/qclass find forward zone information, returns delegation
* point with server names and addresses, or NULL if no forwarding is needed.
@@ -152,9 +161,7 @@ int fwd_cmp(const void* k1, const void* k2);
* @param fwd: the forward data structure
* @param c: class of zone
* @param dp: delegation point with name and target nameservers for new
- * forward zone. This delegation point and all its data must be
- * malloced in the fwd->region. (then it is freed when the fwd is
- * deleted).
+ * forward zone. malloced.
* @return false on failure (out of memory);
*/
int forwards_add_zone(struct iter_forwards* fwd, uint16_t c,
@@ -162,12 +169,31 @@ int forwards_add_zone(struct iter_forwards* fwd, uint16_t c,
/**
* Remove zone from forward structure. For external use since it
- * recalcs the tree parents. Does not actually release any memory, the region
- * is unchanged.
+ * recalcs the tree parents.
* @param fwd: the forward data structure
* @param c: class of zone
* @param nm: name of zone (in uncompressed wireformat).
*/
void forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm);
+/**
+ * Add stub hole (empty entry in forward table, that makes resolution skip
+ * a forward-zone because the stub zone should override the forward zone).
+ * Does not add one if not necessary.
+ * @param fwd: the forward data structure
+ * @param c: class of zone
+ * @param nm: name of zone (in uncompressed wireformat).
+ * @return false on failure (out of memory);
+ */
+int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm);
+
+/**
+ * Remove stub hole, if one exists.
+ * @param fwd: the forward data structure
+ * @param c: class of zone
+ * @param nm: name of zone (in uncompressed wireformat).
+ */
+void forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c,
+ uint8_t* nm);
+
#endif /* ITERATOR_ITER_FWD_H */
diff --git a/usr.sbin/unbound/iterator/iter_hints.c b/usr.sbin/unbound/iterator/iter_hints.c
index 217dfa2578b..74869d35547 100644
--- a/usr.sbin/unbound/iterator/iter_hints.c
+++ b/usr.sbin/unbound/iterator/iter_hints.c
@@ -67,7 +67,7 @@ static void hints_stub_free(struct iter_hints_stub* s)
free(s);
}
-static void delhintnode(rbnode_t* n, void* ATTR_UNUSED(arg))
+static void delhintnode(rbnode_type* n, void* ATTR_UNUSED(arg))
{
struct iter_hints_stub* node = (struct iter_hints_stub*)n;
hints_stub_free(node);
@@ -147,7 +147,9 @@ compile_time_root_prime(int do_ip4, int do_ip6)
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:84::b")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "2001:500:2::c")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) goto failed;
+ if(!ah(dp, "E.ROOT-SERVERS.NET.", "2001:500:a8::e")) goto failed;
if(!ah(dp, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) goto failed;
+ if(!ah(dp, "G.ROOT-SERVERS.NET.", "2001:500:12::d0d")) goto failed;
if(!ah(dp, "H.ROOT-SERVERS.NET.", "2001:500:1::53")) goto failed;
if(!ah(dp, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) goto failed;
if(!ah(dp, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) goto failed;
@@ -274,6 +276,8 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
* last resort will ask for parent-side NS record and thus
* fallback to the internet name servers on a failure */
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
+ /* ssl_upstream */
+ dp->ssl_upstream = (uint8_t)s->ssl_upstream;
delegpt_log(VERB_QUERY, dp);
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, !s->isprime))
return 0;
diff --git a/usr.sbin/unbound/iterator/iter_hints.h b/usr.sbin/unbound/iterator/iter_hints.h
index 4540971b0a4..06b4b9667d1 100644
--- a/usr.sbin/unbound/iterator/iter_hints.h
+++ b/usr.sbin/unbound/iterator/iter_hints.h
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -46,14 +46,11 @@
struct iter_env;
struct config_file;
struct delegpt;
-struct regional;
/**
* Iterator hints structure
*/
struct iter_hints {
- /** regional where hints are allocated */
- struct regional* region;
/**
* Hints are stored in this tree. Sort order is specially chosen.
* first sorted on qclass. Then on dname in nsec-like order, so that
@@ -62,7 +59,7 @@ struct iter_hints {
* contents of type iter_hints_stub. The class IN root is in here.
* uses name_tree_node from dnstree.h.
*/
- rbtree_t tree;
+ rbtree_type tree;
};
/**
@@ -71,7 +68,7 @@ struct iter_hints {
struct iter_hints_stub {
/** tree sorted by name, class */
struct name_tree_node node;
- /** delegation point with hint information for this stub. */
+ /** delegation point with hint information for this stub. malloced. */
struct delegpt* dp;
/** does the stub need to forego priming (like on other ports) */
uint8_t noprime;
@@ -139,4 +136,26 @@ struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
*/
size_t hints_get_mem(struct iter_hints* hints);
+/**
+ * Add stub to hints structure. For external use since it recalcs
+ * the tree parents.
+ * @param hints: the hints data structure
+ * @param c: class of zone
+ * @param dp: delegation point with name and target nameservers for new
+ * hints stub. malloced.
+ * @param noprime: set noprime option to true or false on new hint stub.
+ * @return false on failure (out of memory);
+ */
+int hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp,
+ int noprime);
+
+/**
+ * Remove stub from hints structure. For external use since it
+ * recalcs the tree parents.
+ * @param hints: the hints data structure
+ * @param c: class of stub zone
+ * @param nm: name of stub zone (in uncompressed wireformat).
+ */
+void hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm);
+
#endif /* ITERATOR_ITER_HINTS_H */
diff --git a/usr.sbin/unbound/iterator/iter_priv.h b/usr.sbin/unbound/iterator/iter_priv.h
index f6264f8d0c9..0430d57e3e3 100644
--- a/usr.sbin/unbound/iterator/iter_priv.h
+++ b/usr.sbin/unbound/iterator/iter_priv.h
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -43,7 +43,7 @@
#ifndef ITERATOR_ITER_PRIV_H
#define ITERATOR_ITER_PRIV_H
#include "util/rbtree.h"
-#include <ldns/buffer.h>
+struct sldns_buffer;
struct iter_env;
struct config_file;
struct regional;
@@ -60,14 +60,14 @@ struct iter_priv {
* contents of type addr_tree_node.
* No further data need, only presence or absence.
*/
- rbtree_t a;
+ rbtree_type a;
/**
* Tree of the domains spans that are allowed to contain
* the blocked address spans.
* contents of type name_tree_node.
* No further data need, only presence or absence.
*/
- rbtree_t n;
+ rbtree_type n;
};
/**
@@ -92,12 +92,14 @@ int priv_apply_cfg(struct iter_priv* priv, struct config_file* cfg);
/**
* See if rrset is bad.
+ * Will remove individual RRs that are bad (if possible) to
+ * sanitize the RRset without removing it completely.
* @param priv: structure for private address storage.
* @param pkt: packet to decompress rrset name in.
* @param rrset: the rrset to examine, A or AAAA.
* @return true if the rrset is bad and should be removed.
*/
-int priv_rrset_bad(struct iter_priv* priv, ldns_buffer* pkt,
+int priv_rrset_bad(struct iter_priv* priv, struct sldns_buffer* pkt,
struct rrset_parse* rrset);
/**
diff --git a/usr.sbin/unbound/iterator/iter_scrub.c b/usr.sbin/unbound/iterator/iter_scrub.c
index 8a3fc170c05..1bee85c0b99 100644
--- a/usr.sbin/unbound/iterator/iter_scrub.c
+++ b/usr.sbin/unbound/iterator/iter_scrub.c
@@ -161,8 +161,8 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,
for(rr = rrset->rr_first; rr; rr = rr->next) {
if(get_additional_name(rrset, rr, &nm, &nmlen, pkt)) {
/* mark A */
- hashvalue_t h = pkt_hash_rrset(pkt, nm, LDNS_RR_TYPE_A,
- rrset->rrset_class, 0);
+ hashvalue_type h = pkt_hash_rrset(pkt, nm,
+ LDNS_RR_TYPE_A, rrset->rrset_class, 0);
struct rrset_parse* r = msgparse_hashtable_lookup(
msg, pkt, h, 0, nm, nmlen,
LDNS_RR_TYPE_A, rrset->rrset_class);
diff --git a/usr.sbin/unbound/iterator/iter_utils.c b/usr.sbin/unbound/iterator/iter_utils.c
index a5aefa9602c..0b1b456113f 100644
--- a/usr.sbin/unbound/iterator/iter_utils.c
+++ b/usr.sbin/unbound/iterator/iter_utils.c
@@ -108,7 +108,7 @@ read_fetch_policy(struct iter_env* ie, const char* str)
/** apply config caps whitelist items to name tree */
static int
-caps_white_apply_cfg(rbtree_t* ntree, struct config_file* cfg)
+caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
{
struct config_strlist* p;
for(p=cfg->caps_whitelist; p; p=p->next) {
@@ -360,6 +360,39 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
}
}
*selected_rtt = low_rtt;
+
+ if (env->cfg->prefer_ip6) {
+ int got_num6 = 0;
+ int low_rtt6 = 0;
+ int i;
+ prev = NULL;
+ a = dp->result_list;
+ for(i = 0; i < got_num; i++) {
+ swap_to_front = 0;
+ if(a->addr.ss_family == AF_INET6) {
+ got_num6++;
+ swap_to_front = 1;
+ if(low_rtt6 == 0 || a->sel_rtt < low_rtt6) {
+ low_rtt6 = a->sel_rtt;
+ }
+ }
+ /* swap to front if IPv6, or move to next result */
+ if(swap_to_front && prev) {
+ n = a->next_result;
+ prev->next_result = n;
+ a->next_result = dp->result_list;
+ dp->result_list = a;
+ a = n;
+ } else {
+ prev = a;
+ a = a->next_result;
+ }
+ }
+ if(got_num6 > 0) {
+ got_num = got_num6;
+ *selected_rtt = low_rtt6;
+ }
+ }
return got_num;
}
@@ -499,6 +532,7 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
qinf.qname_len = namelen;
qinf.qtype = t;
qinf.qclass = c;
+ qinf.local_alias = NULL;
fptr_ok(fptr_whitelist_modenv_detect_cycle(
qstate->env->detect_cycle));
return (*qstate->env->detect_cycle)(qstate, &qinf,
diff --git a/usr.sbin/unbound/iterator/iterator.c b/usr.sbin/unbound/iterator/iterator.c
index 1f5132b8282..99ce96f384e 100644
--- a/usr.sbin/unbound/iterator/iterator.c
+++ b/usr.sbin/unbound/iterator/iterator.c
@@ -88,7 +88,7 @@ iter_init(struct module_env* env, int id)
/** delete caps_whitelist element */
static void
-caps_free(struct rbnode_t* n, void* ATTR_UNUSED(d))
+caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
{
if(n) {
free(((struct name_tree_node*)n)->name);
@@ -230,9 +230,8 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
return;
} else {
/* see if the failure did get (parent-lame) info */
- if(!cache_fill_missing(super->env,
- super_iq->qchase.qclass, super->region,
- super_iq->dp))
+ if(!cache_fill_missing(super->env, super_iq->qchase.qclass,
+ super->region, super_iq->dp))
log_err("out of memory adding missing");
}
dpns->resolved = 1; /* mark as failed */
@@ -278,27 +277,29 @@ error_response(struct module_qstate* qstate, int id, int rcode)
static int
error_response_cache(struct module_qstate* qstate, int id, int rcode)
{
- /* store in cache */
- struct reply_info err;
- if(qstate->prefetch_leeway > NORR_TTL) {
- verbose(VERB_ALGO, "error response for prefetch in cache");
- /* attempt to adjust the cache entry prefetch */
- if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
- NORR_TTL, qstate->query_flags))
- return error_response(qstate, id, rcode);
- /* if that fails (not in cache), fall through to store err */
- }
- memset(&err, 0, sizeof(err));
- err.flags = (uint16_t)(BIT_QR | BIT_RA);
- FLAGS_SET_RCODE(err.flags, rcode);
- err.qdcount = 1;
- err.ttl = NORR_TTL;
- err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl);
- /* do not waste time trying to validate this servfail */
- err.security = sec_status_indeterminate;
- verbose(VERB_ALGO, "store error response in message cache");
- iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
- qstate->query_flags);
+ if(!qstate->no_cache_store) {
+ /* store in cache */
+ struct reply_info err;
+ if(qstate->prefetch_leeway > NORR_TTL) {
+ verbose(VERB_ALGO, "error response for prefetch in cache");
+ /* attempt to adjust the cache entry prefetch */
+ if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
+ NORR_TTL, qstate->query_flags))
+ return error_response(qstate, id, rcode);
+ /* if that fails (not in cache), fall through to store err */
+ }
+ memset(&err, 0, sizeof(err));
+ err.flags = (uint16_t)(BIT_QR | BIT_RA);
+ FLAGS_SET_RCODE(err.flags, rcode);
+ err.qdcount = 1;
+ err.ttl = NORR_TTL;
+ err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl);
+ /* do not waste time trying to validate this servfail */
+ err.security = sec_status_indeterminate;
+ verbose(VERB_ALGO, "store error response in message cache");
+ iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
+ qstate->query_flags);
+ }
return error_response(qstate, id, rcode);
}
@@ -551,6 +552,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
qinf.qname_len = qnamelen;
qinf.qtype = qtype;
qinf.qclass = qclass;
+ qinf.local_alias = NULL;
/* RD should be set only when sending the query back through the INIT
* state. */
@@ -968,7 +970,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
{
uint8_t* delname;
size_t delnamelen;
- struct dns_msg* msg;
+ struct dns_msg* msg = NULL;
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
/* check effort */
@@ -1008,13 +1010,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
* getting older results from cache is a bad idea, no cache */
verbose(VERB_ALGO, "cache blacklisted, going to the network");
msg = NULL;
- } else {
+ } else if(!qstate->no_cache_lookup) {
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
iq->qchase.qname_len, iq->qchase.qtype,
iq->qchase.qclass, qstate->query_flags,
qstate->region, qstate->env->scratch);
if(!msg && qstate->env->neg_cache) {
- /* lookup in negative cache; may result in
+ /* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
qstate->region, qstate->env->rrset_cache,
@@ -1700,10 +1702,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
/* if this was a parent-side glue query itself, then store that
* failure in cache. */
- if(iq->query_for_pside_glue && !iq->pside_glue)
- iter_store_parentside_neg(qstate->env, &qstate->qinfo,
- iq->deleg_msg?iq->deleg_msg->rep:
- (iq->response?iq->response->rep:NULL));
+ if(!qstate->no_cache_store && iq->query_for_pside_glue
+ && !iq->pside_glue)
+ iter_store_parentside_neg(qstate->env, &qstate->qinfo,
+ iq->deleg_msg?iq->deleg_msg->rep:
+ (iq->response?iq->response->rep:NULL));
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
/* fail -- no more targets, no more hope of targets, no hope
@@ -1787,8 +1790,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int tf_policy;
struct delegpt_addr* target;
struct outbound_entry* outq;
- /* EDNS options to set on outgoing packet */
- struct edns_option* opt_list = NULL;
/* NOTE: a request will encounter this state for each target it
* needs to send a query to. That is, at least one per referral,
@@ -2011,6 +2012,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qinfo_out.qname_len = iq->dp->namelen;
iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
iq->qinfo_out.qclass = iq->qchase.qclass;
+ iq->qinfo_out.local_alias = NULL;
iq->minimise_count = 0;
}
@@ -2026,6 +2028,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->minimise_count++;
iq->minimise_timeout_count = 0;
+ iter_dec_attempts(iq->dp, 1);
+
/* Limit number of iterations for QNAMEs with more
* than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
* labels of QNAME always individually.
@@ -2066,7 +2070,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|| iq->qchase.qtype == LDNS_RR_TYPE_A)))
/* Stop minimising this query, resolve "as usual" */
iq->minimisation_state = DONOT_MINIMISE_STATE;
- else {
+ else if(!qstate->no_cache_lookup) {
struct dns_msg* msg = dns_cache_lookup(qstate->env,
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
@@ -2086,7 +2090,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
/* Do not increment qname, continue incrementing next
* iteration */
iq->minimisation_state = MINIMISE_STATE;
- else
+ else if(!qstate->env->cfg->qname_minimisation_strict)
/* Too many time-outs detected for this QNAME and QTYPE.
* We give up, disable QNAME minimisation. */
iq->minimisation_state = DONOT_MINIMISE_STATE;
@@ -2104,9 +2108,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dnssec_lame_query?" but lame_query anyway": "");
}
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
- outq = (*qstate->env->send_query)(
- iq->qinfo_out.qname, iq->qinfo_out.qname_len,
- iq->qinfo_out.qtype, iq->qinfo_out.qclass,
+ outq = (*qstate->env->send_query)(&iq->qinfo_out,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
/* unset CD if to forwarder(RD set) and not dnssec retry
* (blacklist nonempty) and no trust-anchors are configured
@@ -2115,8 +2117,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
!qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
- ie, iq), opt_list, &target->addr, target->addrlen,
- iq->dp->name, iq->dp->namelen, qstate);
+ ie, iq), &target->addr, target->addrlen,
+ iq->dp->name, iq->dp->namelen,
+ (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
if(!outq) {
log_addr(VERB_DETAIL, "error sending query to auth server",
&target->addr, target->addrlen);
@@ -2257,10 +2260,11 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_target_queries = 0;
return processDSNSFind(qstate, iq, id);
}
- iter_dns_store(qstate->env, &iq->response->qinfo,
- iq->response->rep, 0, qstate->prefetch_leeway,
- iq->dp&&iq->dp->has_parent_side_NS,
- qstate->region, qstate->query_flags);
+ if(!qstate->no_cache_store)
+ iter_dns_store(qstate->env, &iq->response->qinfo,
+ iq->response->rep, 0, qstate->prefetch_leeway,
+ iq->dp&&iq->dp->has_parent_side_NS,
+ qstate->region, qstate->query_flags);
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
@@ -2273,12 +2277,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
&qstate->reply->addr, qstate->reply->addrlen,
qstate->region);
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
- /* Best effort qname-minimisation.
- * Stop minimising and send full query when RCODE
- * is not NOERROR. */
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
- LDNS_RCODE_NOERROR)
+ LDNS_RCODE_NOERROR) {
+ if(qstate->env->cfg->qname_minimisation_strict)
+ return final_state(iq);
+ /* Best effort qname-minimisation.
+ * Stop minimising and send full query when
+ * RCODE is not NOERROR. */
iq->minimisation_state = DONOT_MINIMISE_STATE;
+ }
if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
LDNS_RCODE_NXDOMAIN) {
/* Stop resolving when NXDOMAIN is DNSSEC
@@ -2325,7 +2332,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* if hardened, only store referral if we asked for it */
- if(!qstate->env->cfg->harden_referral_path ||
+ if(!qstate->no_cache_store &&
+ (!qstate->env->cfg->harden_referral_path ||
( qstate->qinfo.qtype == LDNS_RR_TYPE_NS
&& (qstate->query_flags&BIT_RD)
&& !(qstate->query_flags&BIT_CD)
@@ -2340,7 +2348,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qchase.qname, iq->qchase.qname_len,
LDNS_RR_TYPE_NS, iq->qchase.qclass)
)
- )) {
+ ))) {
/* Store the referral under the current query */
/* no prefetch-leeway, since its not the answer */
iter_dns_store(qstate->env, &iq->response->qinfo,
@@ -2353,16 +2361,17 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response->rep, iq->dp->name);
}
/* store parent-side-in-zone-glue, if directly queried for */
- if(iq->query_for_pside_glue && !iq->pside_glue) {
- iq->pside_glue = reply_find_rrset(iq->response->rep,
- iq->qchase.qname, iq->qchase.qname_len,
- iq->qchase.qtype, iq->qchase.qclass);
- if(iq->pside_glue) {
- log_rrset_key(VERB_ALGO, "found parent-side "
- "glue", iq->pside_glue);
- iter_store_parentside_rrset(qstate->env,
- iq->pside_glue);
- }
+ if(!qstate->no_cache_store && iq->query_for_pside_glue
+ && !iq->pside_glue) {
+ iq->pside_glue = reply_find_rrset(iq->response->rep,
+ iq->qchase.qname, iq->qchase.qname_len,
+ iq->qchase.qtype, iq->qchase.qclass);
+ if(iq->pside_glue) {
+ log_rrset_key(VERB_ALGO, "found parent-side "
+ "glue", iq->pside_glue);
+ iter_store_parentside_rrset(qstate->env,
+ iq->pside_glue);
+ }
}
/* Reset the event state, setting the current delegation
@@ -2443,10 +2452,11 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* NOTE : set referral=1, so that rrsets get stored but not
* the partial query answer (CNAME only). */
/* prefetchleeway applied because this updates answer parts */
- iter_dns_store(qstate->env, &iq->response->qinfo,
- iq->response->rep, 1, qstate->prefetch_leeway,
- iq->dp&&iq->dp->has_parent_side_NS, NULL,
- qstate->query_flags);
+ if(!qstate->no_cache_store)
+ iter_dns_store(qstate->env, &iq->response->qinfo,
+ iq->response->rep, 1, qstate->prefetch_leeway,
+ iq->dp&&iq->dp->has_parent_side_NS, NULL,
+ qstate->query_flags);
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
@@ -2525,7 +2535,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* LAME, THROWAWAY and "unknown" all end up here.
* Recycle to the QUERYTARGETS state to hopefully try a
* different target. */
- if (qstate->env->cfg->qname_minimisation)
+ if (qstate->env->cfg->qname_minimisation &&
+ !qstate->env->cfg->qname_minimisation_strict)
iq->minimisation_state = DONOT_MINIMISE_STATE;
return next_state(iq, QUERYTARGETS_STATE);
}
@@ -2925,10 +2936,11 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
&qstate->qinfo);
/* store negative cache element for parent side glue. */
- if(iq->query_for_pside_glue && !iq->pside_glue)
- iter_store_parentside_neg(qstate->env, &qstate->qinfo,
- iq->deleg_msg?iq->deleg_msg->rep:
- (iq->response?iq->response->rep:NULL));
+ if(!qstate->no_cache_store && iq->query_for_pside_glue
+ && !iq->pside_glue)
+ iter_store_parentside_neg(qstate->env, &qstate->qinfo,
+ iq->deleg_msg?iq->deleg_msg->rep:
+ (iq->response?iq->response->rep:NULL));
if(!iq->response) {
verbose(VERB_ALGO, "No response is set, servfail");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
@@ -2964,7 +2976,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
/* store message with the finished prepended items,
* but only if we did recursion. The nonrecursion referral
* from cache does not need to be stored in the msg cache. */
- if(qstate->query_flags&BIT_RD) {
+ if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
@@ -3139,6 +3151,18 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
LDNS_RCODE_NOERROR)
goto handle_it;
+
+ /* Copy the edns options we may got from the back end */
+ if(edns.opt_list) {
+ qstate->edns_opts_back_in = edns_opt_copy_region(edns.opt_list,
+ qstate->region);
+ if(!qstate->edns_opts_back_in) {
+ log_err("out of memory on incoming message");
+ /* like packet got dropped */
+ goto handle_it;
+ }
+ }
+
/* remove CD-bit, we asked for in case we handle validation ourself */
prs->flags &= ~BIT_CD;
diff --git a/usr.sbin/unbound/iterator/iterator.h b/usr.sbin/unbound/iterator/iterator.h
index 5585f578958..37b0ab0dc24 100644
--- a/usr.sbin/unbound/iterator/iterator.h
+++ b/usr.sbin/unbound/iterator/iterator.h
@@ -51,7 +51,7 @@ struct iter_forwards;
struct iter_donotq;
struct iter_prep_list;
struct iter_priv;
-struct rbtree_t;
+struct rbtree_type;
/** max number of targets spawned for a query and its subqueries */
#define MAX_TARGET_COUNT 64
@@ -115,7 +115,7 @@ struct iter_env {
struct iter_priv* priv;
/** whitelist for capsforid names */
- struct rbtree_t* caps_white;
+ struct rbtree_type* caps_white;
/** The maximum dependency depth that this resolver will pursue. */
int max_dependency_depth;