]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
root hints.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 May 2007 14:05:36 +0000 (14:05 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 May 2007 14:05:36 +0000 (14:05 +0000)
git-svn-id: file:///svn/unbound/trunk@335 be551aaa-1e26-0410-a405-d3ace91eadb9

14 files changed:
doc/Changelog
iterator/iter_delegpt.c
iterator/iter_delegpt.h
iterator/iter_hints.c [new file with mode: 0644]
iterator/iter_hints.h [new file with mode: 0644]
iterator/iter_utils.c
iterator/iterator.c
iterator/iterator.h
services/outside_network.c
util/data/dname.c
util/data/dname.h
util/data/packed_rrset.h
util/net_help.c
util/net_help.h

index e196dd365f89fe67da4c420b71e19b7372e67ae2..c667f19d6a9a306348df02f21aa026422468be01 100644 (file)
@@ -3,6 +3,7 @@
          and for setting timeout for UDP. Pending_udp takes milliseconds.
        - cleaner iterator sockaddr conversion of forwarder address.
        - iterator/iter_utils and iter_delegpt setup.
+       - root hints.
 
 22 May 2007: Wouter
        - outbound query list for modules and support to callback with the
index 5f2ef0ef1bc2f06f7038fef7044e788056b79ed7..feba9cab5f238561a00dedbccd194bf235af8304 100644 (file)
@@ -42,6 +42,8 @@
 #include "config.h"
 #include "iterator/iter_delegpt.h"
 #include "util/region-allocator.h"
+#include "util/data/dname.h"
+#include "util/net_help.h"
 
 struct delegpt* 
 delegpt_create(struct region* region)
@@ -52,3 +54,85 @@ delegpt_create(struct region* region)
        memset(dp, 0, sizeof(*dp));
        return dp;
 }
+
+int 
+delegpt_set_name(struct delegpt* dp, struct region* region, uint8_t* name)
+{
+       dp->namelabs = dname_count_size_labels(name, &dp->namelen);
+       dp->name = region_alloc_init(region, name, dp->namelen);
+       return dp->name != 0;
+}
+
+int 
+delegpt_add_ns(struct delegpt* dp, struct region* region, uint8_t* name)
+{
+       struct delegpt_ns* ns = (struct delegpt_ns*)region_alloc(region,
+               sizeof(struct delegpt_ns));
+       if(!ns)
+               return 0;
+       ns->next = dp->nslist;
+       dp->nslist = ns;
+       (void)dname_count_size_labels(name, &ns->namelen);
+       ns->name = region_alloc_init(region, name, ns->namelen);
+       ns->resolved = 0;
+       return 1;
+}
+
+/** find name in deleg list */
+static struct delegpt_ns*
+delegpt_find_ns(struct delegpt* dp, uint8_t* name, size_t namelen)
+{
+       struct delegpt_ns* p = dp->nslist;
+       while(p) {
+               if(namelen == p->namelen && 
+                       memcmp(name, p->name, namelen) == 0) {
+                       return p;
+               }
+               p = p->next;
+       }
+       return NULL;
+}
+
+int 
+delegpt_add_target(struct delegpt* dp, struct region* region, 
+       uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 
+       socklen_t addrlen)
+{
+       struct delegpt_addr* a;
+       struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
+       if(!ns) {
+               /* ignore it */
+               return 1;
+       }
+       ns->resolved = 1;
+       
+       a = (struct delegpt_addr*)region_alloc(region,
+               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;
+       return 1;
+
+}
+
+void delegpt_log(struct delegpt* dp)
+{
+       char buf[LDNS_MAX_DOMAINLEN+1];
+       struct delegpt_ns* ns;
+       struct delegpt_addr* a;
+       dname_str(dp->name, buf);
+       log_info("DelegationPoint<%s>:", buf);
+       for(ns = dp->nslist; ns; ns = ns->next) {
+               dname_str(ns->name, buf);
+               log_info("  %s%s", buf, (ns->resolved?"*":""));
+       }
+       for(a = dp->target_list; a; a = a->next_target) {
+               log_addr("  ", &a->addr, a->addrlen);
+       }
+}
index 0e2ffed381d8054b108464e7dc33fa540440642e..b1ef8acb03dc1d9e86880a24ed42f256355a4c2a 100644 (file)
@@ -109,4 +109,43 @@ struct delegpt_addr {
  */
 struct delegpt* delegpt_create(struct region* region);
 
+/**
+ * Set name of delegation point.
+ * @param dp: delegation point.
+ * @param region: where to allocate the name copy.
+ * @param name: name to use.
+ * @return false on error.
+ */
+int delegpt_set_name(struct delegpt* dp, struct region* region, uint8_t* name);
+
+/**
+ * Add a name to the delegation point.
+ * @param dp: delegation point.
+ * @param region: where to allocate the info.
+ * @param name: domain name in wire format.
+ * @return false on error.
+ */
+int delegpt_add_ns(struct delegpt* dp, struct region* region, uint8_t* name);
+
+/**
+ * Add address to the delegation point.
+ * @param dp: delegation point.
+ * @param region: where to allocate the info.
+ * @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.
+ * @return false on error.
+ */
+int delegpt_add_target(struct delegpt* dp, struct region* region, 
+       uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 
+       socklen_t addrlen);
+
+/**
+ * Print the delegation point to the log. For debugging.
+ * @param dp: delegation point.
+ */
+void delegpt_log(struct delegpt* dp);
+
 #endif /* ITERATOR_ITER_DELEGPT_H */
diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c
new file mode 100644 (file)
index 0000000..78b74c9
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * iterator/iter_hints.c - iterative resolver module stub and root hints.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * 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.
+ */
+
+/**
+ * \file
+ *
+ * This file contains functions to assist the iterator module.
+ * Keep track of stub and root hints, and read those from config.
+ */
+#include "config.h"
+#include "iterator/iter_hints.h"
+#include "iterator/iter_delegpt.h"
+#include "util/region-allocator.h"
+#include "util/log.h"
+#include "util/net_help.h"
+#include "util/data/dname.h"
+
+/** compare two hint entries */
+static int
+stub_cmp(const void* k1, const void* k2)
+{
+       int m;
+       struct iter_hints_stub* n1 = (struct iter_hints_stub*)k1;
+       struct iter_hints_stub* n2 = (struct iter_hints_stub*)k2;
+       if(n1->hint_class != n2->hint_class) {
+               if(n1->hint_class < n2->hint_class)
+                       return -1;
+               return 1;
+       }
+       return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs, 
+               &m);
+}
+
+struct iter_hints* 
+hints_create()
+{
+       struct iter_hints* hints = (struct iter_hints*)calloc(1,
+               sizeof(struct iter_hints));
+       if(!hints)
+               return NULL;
+       hints->region = region_create(malloc, free);
+       if(!hints->region) {
+               hints_delete(hints);
+               return NULL;
+       }
+       return hints;
+}
+
+void 
+hints_delete(struct iter_hints* hints)
+{
+       if(!hints) 
+               return;
+       region_destroy(hints->region);
+       free(hints->tree);
+       free(hints);
+}
+
+/** add hint to delegation hints */
+static int
+ah(struct delegpt* dp, struct region* r, const char* sv, const char* ip)
+{
+       struct sockaddr_storage addr;
+       socklen_t addrlen;
+       ldns_rdf* rdf = ldns_dname_new_frm_str(sv);
+       if(!rdf) {
+               log_err("could not parse %s", sv);
+               return 0;
+       }
+       if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf)) ||
+          !ipstrtoaddr(ip, UNBOUND_DNS_PORT, &addr, &addrlen) ||
+          !delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
+               &addr, addrlen)) {
+               ldns_rdf_deep_free(rdf);
+               return 0;
+       }
+       ldns_rdf_deep_free(rdf);
+       return 1;
+}
+
+/** obtain compiletime provided root hints */
+static struct delegpt* 
+compile_time_root_prime(struct region* r)
+{
+       /* from:
+        ;       This file is made available by InterNIC
+        ;       under anonymous FTP as
+        ;           file                /domain/named.cache
+        ;           on server           FTP.INTERNIC.NET
+        ;       -OR-                    RS.INTERNIC.NET
+        ;
+        ;       last update:    Jan 29, 2004
+        ;       related version of root zone:   2004012900
+        */
+       struct delegpt* dp = delegpt_create(r);
+       if(!dp)
+               return NULL;
+       if(!delegpt_set_name(dp, r, (uint8_t*)"\000"))
+               return NULL;
+       if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "198.41.0.4"))     return 0;
+       if(!ah(dp, r, "B.ROOT-SERVERS.NET.", "192.228.79.201")) return 0;
+       if(!ah(dp, r, "C.ROOT-SERVERS.NET.", "192.33.4.12"))    return 0;
+       if(!ah(dp, r, "D.ROOT-SERVERS.NET.", "128.8.10.90"))    return 0;
+       if(!ah(dp, r, "E.ROOT-SERVERS.NET.", "192.203.230.10")) return 0;
+       if(!ah(dp, r, "F.ROOT-SERVERS.NET.", "192.5.5.241"))    return 0;
+       if(!ah(dp, r, "G.ROOT-SERVERS.NET.", "192.112.36.4"))   return 0;
+       if(!ah(dp, r, "H.ROOT-SERVERS.NET.", "128.63.2.53"))    return 0;
+       if(!ah(dp, r, "I.ROOT-SERVERS.NET.", "192.36.148.17"))  return 0;
+       if(!ah(dp, r, "J.ROOT-SERVERS.NET.", "192.58.128.30"))  return 0;
+       if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "193.0.14.129"))   return 0;
+       if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "198.32.64.12"))   return 0;
+       if(!ah(dp, r, "M.ROOT-SERVERS.NET.", "202.12.27.33"))   return 0;
+       return dp;
+}
+
+/** insert new hint info into hint structure */
+static int
+hints_insert(struct iter_hints* hints, uint16_t c, uint8_t* name, 
+       size_t namelen, int namelabs, struct delegpt* dp)
+{
+       struct iter_hints_stub* node = region_alloc(hints->region,
+               sizeof(struct iter_hints_stub));
+       if(!node)
+               return 0;
+       node->node.key = node;
+       node->hint_class = c;
+       node->name = region_alloc_init(hints->region, name, namelen);
+       if(!node->name)
+               return 0;
+       node->namelen = namelen;
+       node->namelabs = namelabs;
+       node->dp = dp;
+       if(!rbtree_insert(hints->tree, &node->node)) {
+               log_err("second hints ignored.");
+       }
+       return 1;
+}
+
+/** initialise parent pointers in the tree */
+static void
+init_parents(struct iter_hints* hints)
+{
+       struct iter_hints_stub* node, *prev = NULL, *p;
+       int m;
+       RBTREE_FOR(node, struct iter_hints_stub*, hints->tree) {
+               node->parent = NULL;
+               if(!prev || prev->hint_class != node->hint_class) {
+                       prev = node;
+                       continue;
+               }
+               (void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
+                       node->namelabs, &m); /* we know prev is smaller */
+               /* sort order like: . com. bla.com. zwb.com. net. */
+               /* find the previous, or parent-parent-parent */
+               for(p = prev; p; p = p->parent)
+                       /* looking for name with few labels, a parent */
+                       if(p->namelabs <= m) {
+                               /* ==: since prev matched m, this is closest*/
+                               /* <: prev matches more, but is not a parent,
+                                * this one is a (grand)parent */
+                               node->parent = p;
+                               break;
+                       }
+               prev = node;
+       }
+}
+
+int 
+hints_apply_cfg(struct iter_hints* hints, struct config_file* ATTR_UNUSED(cfg))
+{
+       struct delegpt* dp;
+       free(hints->tree);
+       hints->tree = rbtree_create(stub_cmp);
+       if(!hints->tree)
+               return 0;
+       /* TODO: read hints from file named in cfg */
+
+       /* use fallback compiletime root hints */
+       dp = compile_time_root_prime(hints->region);
+       if(!dp) 
+               return 0;
+       if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp->name, dp->namelen, 
+               dp->namelabs, dp))
+               return 0;
+       delegpt_log(dp);
+
+       init_parents(hints);
+       return 1;
+}
+
+struct delegpt* 
+hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
+{
+       uint8_t rootlab = 0;
+       struct iter_hints_stub key, *stub;
+       key.node.key = &key;
+       key.hint_class = qclass;
+       key.name = &rootlab;
+       key.namelen = 1;
+       key.namelabs = 1;
+       stub = (struct iter_hints_stub*)rbtree_search(hints->tree, &key);
+       if(!stub)
+               return NULL;
+       return stub->dp;
+}
diff --git a/iterator/iter_hints.h b/iterator/iter_hints.h
new file mode 100644 (file)
index 0000000..61cf1d9
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * iterator/iter_hints.h - iterative resolver module stub and root hints.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * 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.
+ */
+
+/**
+ * \file
+ *
+ * This file contains functions to assist the iterator module.
+ * Keep track of stub and root hints, and read those from config.
+ */
+
+#ifndef ITERATOR_ITER_HINTS_H
+#define ITERATOR_ITER_HINTS_H
+#include "util/rbtree.h"
+struct iter_env;
+struct config_file;
+struct delegpt;
+struct region;
+
+/**
+ * Iterator hints structure
+ */
+struct iter_hints {
+       /** region where hints are allocated */
+       struct region* region;
+       /** 
+        * Hints are stored in this tree. Sort order is specially chosen.
+        * first sorted on qtype. Then on dname in nsec-like order, so that
+        * a lookup on class, name will return an exact match or the closest
+        * match which gives the ancestor needed.
+        * contents of type iter_hints_stub. The class IN root is in here.
+        */
+       rbtree_t* tree;
+};
+
+/**
+ * Iterator hints for a particular stub.
+ */
+struct iter_hints_stub {
+       /** redblacktree node, key is this structure: class and name */
+       rbnode_t node;
+       /** name */
+       uint8_t* name;
+       /** length of name */
+       size_t namelen;
+       /** number of labels in name */
+       int namelabs;
+       /** delegation point with hint information for this stub. */
+       struct delegpt* dp;
+       /** pointer to parent in stub hint tree (or NULL if none) */
+       struct iter_hints_stub* parent;
+       /** class of hints. host order. */
+       uint16_t hint_class;
+};
+
+/**
+ * Create hints 
+ * @return new hints or NULL on error.
+ */
+struct iter_hints* hints_create();
+
+/**
+ * Delete hints.
+ * @param hints: to delete.
+ */
+void hints_delete(struct iter_hints* hints);
+
+/**
+ * Process hints config. Sets default values for root hints if no config.
+ * @param hints: where to store.
+ * @param cfg: config options.
+ * @return 0 on error.
+ */
+int hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg);
+
+/**
+ * Find root hints for the given class.
+ * @param hints: hint storage.
+ * @param qclass: class for which root hints are requested. host order.
+ * @return: NULL if no hints, or a ptr to stored hints.
+ */
+struct delegpt* hints_lookup_root(struct iter_hints* hints, uint16_t qclass);
+
+#endif /* ITERATOR_ITER_HINTS_H */
index 5af8317af55aea6f131ba89a4d744ce33e3fd45a..3b87a14bef5acce845b7bf21c23b206585cce700 100644 (file)
@@ -42,6 +42,7 @@
 #include "config.h"
 #include "iterator/iter_utils.h"
 #include "iterator/iterator.h"
+#include "iterator/iter_hints.h"
 #include "util/net_help.h"
 #include "util/log.h"
 #include "util/config_file.h"
@@ -64,6 +65,14 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
        for(i=0; i<iter_env->max_dependency_depth+1; i++)
                verbose(VERB_DETAIL, "target fetch policy for level %d is %d",
                        i, iter_env->target_fetch_policy[i]);
+       
+       if(!iter_env->hints)
+               iter_env->hints = hints_create();
+       if(!iter_env->hints || !hints_apply_cfg(iter_env->hints, cfg)) {
+               log_err("Could not set root or stub hints");
+               return 0;
+       }
+       
 
        /* forwarder address */
        if(cfg->fwd_address && cfg->fwd_address[0]) {
index 5867276f01a7f55d9cddf8dbefa529e1548d5fd6..1f6e033e1ad894a87bb8c139a1b8f5c5fa97af62 100644 (file)
@@ -49,6 +49,7 @@
 #include "util/region-allocator.h"
 #include "services/cache/rrset.h"
 #include "iterator/iter_utils.h"
+#include "iterator/iter_hints.h"
 
 /** iterator init */
 static int 
@@ -76,6 +77,8 @@ iter_deinit(struct module_env* env, int id)
        if(!env || !env->modinfo)
                return;
        iter_env = (struct iter_env*)env->modinfo[id];
+       free(iter_env->target_fetch_policy);
+       hints_delete(iter_env->hints);
        if(iter_env)
                free(iter_env);
 }
@@ -135,6 +138,7 @@ iter_new(struct module_qstate* qstate, int id)
                return 0;
        memset(iq, 0, sizeof(*iq));
        outbound_list_init(&iq->outlist);
+       iq->num_target_queries = -1; /* default our targetQueries counter. */
        if(qstate->qinfo.has_cd)
                flags |= BIT_CD;
        e = (*env->send_query)(qstate->qinfo.qname, qstate->qinfo.qnamesize,
@@ -232,3 +236,29 @@ iter_get_funcblock()
 {
        return &iter_block;
 }
+
+const char* 
+iter_state_to_string(enum iter_state state)
+{
+       switch (state)
+       {
+       case INIT_REQUEST_STATE :
+               return "INIT REQUEST STATE";
+       case INIT_REQUEST_2_STATE :
+               return "INIT REQUEST STATE (stage 2)";
+       case INIT_REQUEST_3_STATE:
+               return "INIT REQUEST STATE (stage 3)";
+       case QUERYTARGETS_STATE :
+               return "QUERY TARGETS STATE";
+       case PRIME_RESP_STATE :
+               return "PRIME RESPONSE STATE";
+       case QUERY_RESP_STATE :
+               return "QUERY RESPONSE STATE";
+       case TARGET_RESP_STATE :
+               return "TARGET RESPONSE STATE";
+       case FINISHED_STATE :
+               return "FINISHED RESPONSE STATE";
+       default :
+               return "UNKNOWN ITER STATE";
+       }
+}
index 981579beeb0358ebb8288c9e03e986806edbc7fb..482ee413d0c54386e74063d1ba5c8ee6662639b0 100644 (file)
@@ -45,6 +45,8 @@
 #include "services/outbound_list.h"
 struct module_func_block;
 struct delegpt;
+struct packed_rrset_list;
+struct iter_hints;
 
 /**
  * Global state for the iterator. 
@@ -61,7 +63,7 @@ struct iter_env {
         * that both root hints and stub zone "hints" are stored in this 
         * data structure.
         */
-       /* struct hints* hints TODO */
+       struct iter_hints* hints;
 
        /** A flag to indicate whether or not we have an IPv6 route */
        int supports_ipv6;
@@ -156,7 +158,7 @@ struct iter_qstate {
         * This is a list of RRsets that must be prepended to the 
         * ANSWER section of a response before being sent upstream.
         */
-       /* TODO list of struct rrsets or something */
+       struct packed_rrset_list* prepend_list;
 
        /** 
         * This is the current delegation point for an in-progress query. This
@@ -193,4 +195,11 @@ struct iter_qstate {
  */
 struct module_func_block* iter_get_funcblock();
 
+/**
+ * Get iterator state as a string
+ * @param state: to convert
+ * @return constant string that is printable.
+ */
+const char* iter_state_to_string(enum iter_state state);
+
 #endif /* ITERATOR_ITERATOR_H */
index fa5f7c7668eece266610b848f54e90ed39dc3305..fdb0974291d264574e815d43de9c974a13313602 100644 (file)
@@ -180,14 +180,14 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt)
                s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(s == -1) {
                log_err("outgoing tcp: socket: %s", strerror(errno));
-               log_addr(&w->addr, w->addrlen);
+               log_addr("failed address", &w->addr, w->addrlen);
                return 0;
        }
        fd_set_nonblock(s);
        if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) {
                if(errno != EINPROGRESS) {
                        log_err("outgoing tcp: connect: %s", strerror(errno));
-                       log_addr(&w->addr, w->addrlen);
+                       log_addr("failed address", &w->addr, w->addrlen);
                        close(s);
                        return 0;
                }
@@ -252,8 +252,8 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
                /* check ID */
                if(ldns_buffer_limit(c->buffer) < sizeof(uint16_t) ||
                        LDNS_ID_WIRE(ldns_buffer_begin(c->buffer))!=pend->id) {
-                       log_info("outnettcp: bad ID in reply, from:");
-                       log_addr(&pend->query->addr, pend->query->addrlen);
+                       log_addr("outnettcp: bad ID in reply, from:",
+                               &pend->query->addr, pend->query->addrlen);
                        error = NETEVENT_CLOSED;
                }
        }
index 3d1ca464e54aca66dc666e773cce92302b8855b5..38ce5fa80faa0fc13833abd15d025d263a51d04a 100644 (file)
@@ -471,3 +471,41 @@ dname_buffer_write(ldns_buffer* pkt, uint8_t* dname)
        }
        return 1;
 }
+
+void dname_str(uint8_t* dname, char* str)
+{
+       size_t len = 0;
+       uint8_t lablen = 0;
+       char* s = str;
+       if(!dname || !*dname) {
+               *s++ = '.';
+               *s = 0;
+               return;
+       }
+       lablen = *dname++;
+       while(lablen) {
+               if(lablen > LDNS_MAX_LABELLEN) {
+                       *s++ = '#';
+                       *s = 0;
+                       return;
+               }
+               len += lablen+1;
+               if(len >= LDNS_MAX_DOMAINLEN-1) {
+                       *s++ = '&';
+                       *s = 0;
+                       return;
+               }
+               while(lablen--) {
+                       if(isalnum((int)*dname) 
+                               || *dname == '-' || *dname == '_')
+                               *s++ = *(char*)dname++;
+                       else    {
+                               *s++ = '?';
+                               dname++;
+                       }
+               }
+               *s++ = '.';
+               lablen = *dname++;
+       }
+       *s = 0;
+}
index b10b66f1cbb81fccd5e66e5d607ab23e3f5824cb..f25754dfc56da927c6934f211f40b2664d233fcf 100644 (file)
@@ -127,13 +127,6 @@ void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname);
  */
 int dname_buffer_write(ldns_buffer* pkt, uint8_t* dname);
 
-/** debug helper. Print wireformat dname to output. 
- * @param out: like stdout or a file.
- * @param pkt: if not NULL, the packet for resolving compression ptrs.
- * @param dname: pointer to (start of) dname.
- */
-void dname_print(FILE* out, ldns_buffer* pkt, uint8_t* dname);
-
 /**
  * Count the number of labels in an uncompressed dname in memory.
  * @param dname: pointer to uncompressed dname.
@@ -161,4 +154,22 @@ int dname_count_size_labels(uint8_t* dname, size_t* size);
  */
 int dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs);
 
+/** 
+ * Debug helper. Print wireformat dname to output. 
+ * @param out: like stdout or a file.
+ * @param pkt: if not NULL, the packet for resolving compression ptrs.
+ * @param dname: pointer to (start of) dname.
+ */
+void dname_print(FILE* out, ldns_buffer* pkt, uint8_t* dname);
+
+/** 
+ * Debug helper. Print dname to given string buffer (string buffer must
+ * be at least 255 chars + 1 for the 0, in printable form.
+ * This may lose information (? for nonprintable characters, or & if
+ * the name is too long, # for a bad label length).
+ * @param dname: uncompressed wireformat.
+ * @param str: buffer of 255+1 length.
+ */
+void dname_str(uint8_t* dname, char* str);
+
 #endif /* UTIL_DATA_DNAME_H */
index caa00b9e8d5151ee3c3499d3c06ced500cd12206..3570fafb36060d25f13111067b1a8dea008687ab 100644 (file)
@@ -218,6 +218,16 @@ struct packed_rrset {
        struct packed_rrset_data* d;
 };
 
+/**
+ * list of packed rrsets
+ */
+struct packed_rrset_list {
+       /** next in list */
+       struct packed_rrset_list* next;
+       /** rrset key and data */
+       struct packed_rrset rrset;
+};
+
 /**
  * Delete packed rrset key and data, not entered in hashtables yet.
  * Used during parsing.
index 1cb52f0d0863c07f84a3ea86b550dc7dfc680aa4..efe82281d4a94e1c67573c2b26f87da9595f1e29 100644 (file)
@@ -123,7 +123,7 @@ memdup(void* data, size_t len)
 }
 
 void
-log_addr(struct sockaddr_storage* addr, socklen_t addrlen)
+log_addr(const char* str, struct sockaddr_storage* addr, socklen_t addrlen)
 {
         uint16_t port;
         const char* family = "unknown";
@@ -142,8 +142,8 @@ log_addr(struct sockaddr_storage* addr, socklen_t addrlen)
                 strncpy(dest, "(inet_ntop error)", sizeof(dest));
         }
         port = ntohs(((struct sockaddr_in*)addr)->sin_port);
-        verbose(VERB_DETAIL, "addr fam=%s port=%d dest=%s len=%d",
-                family, (int)port, dest, (int)addrlen);
+        verbose(VERB_DETAIL, "%s %s %s:%d (len %d)",
+                str, family, dest, (int)port, (int)addrlen);
 }
 
 int 
index 7b1c78f789edc2b80c98a0d49780d10cff3affde..a223fa4bfc501d0d59b1ae61fc9894e3cf51adbe 100644 (file)
@@ -112,10 +112,12 @@ void* memdup(void* data, size_t len);
 
 /**
  * Prints the sockaddr in readable format with log_info. Debug helper.
+ * @param str: descriptive string printed with it.
  * @param addr: the sockaddr to print. Can be ip4 or ip6.
  * @param addrlen: length of addr.
  */
-void log_addr(struct sockaddr_storage* addr, socklen_t addrlen);
+void log_addr(const char* str, struct sockaddr_storage* addr, 
+       socklen_t addrlen);
 
 /**
  * Convert ip address string and port to sockaddr.