From 42312206c9a650847b8df45aede2ce56220ea2bd Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Wed, 23 May 2007 14:05:36 +0000 Subject: [PATCH] root hints. git-svn-id: file:///svn/unbound/trunk@335 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + iterator/iter_delegpt.c | 84 +++++++++++++ iterator/iter_delegpt.h | 39 ++++++ iterator/iter_hints.c | 237 +++++++++++++++++++++++++++++++++++++ iterator/iter_hints.h | 115 ++++++++++++++++++ iterator/iter_utils.c | 9 ++ iterator/iterator.c | 30 +++++ iterator/iterator.h | 13 +- services/outside_network.c | 8 +- util/data/dname.c | 38 ++++++ util/data/dname.h | 25 ++-- util/data/packed_rrset.h | 10 ++ util/net_help.c | 6 +- util/net_help.h | 4 +- 14 files changed, 602 insertions(+), 17 deletions(-) create mode 100644 iterator/iter_hints.c create mode 100644 iterator/iter_hints.h diff --git a/doc/Changelog b/doc/Changelog index e196dd365..c667f19d6 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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 diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c index 5f2ef0ef1..feba9cab5 100644 --- a/iterator/iter_delegpt.c +++ b/iterator/iter_delegpt.c @@ -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); + } +} diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h index 0e2ffed38..b1ef8acb0 100644 --- a/iterator/iter_delegpt.h +++ b/iterator/iter_delegpt.h @@ -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 index 000000000..78b74c977 --- /dev/null +++ b/iterator/iter_hints.c @@ -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 index 000000000..61cf1d96f --- /dev/null +++ b/iterator/iter_hints.h @@ -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 */ diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 5af8317af..3b87a14be 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -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; imax_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]) { diff --git a/iterator/iterator.c b/iterator/iterator.c index 5867276f0..1f6e033e1 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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"; + } +} diff --git a/iterator/iterator.h b/iterator/iterator.h index 981579bee..482ee413d 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -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 */ diff --git a/services/outside_network.c b/services/outside_network.c index fa5f7c766..fdb097429 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -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; } } diff --git a/util/data/dname.c b/util/data/dname.c index 3d1ca464e..38ce5fa80 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -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; +} diff --git a/util/data/dname.h b/util/data/dname.h index b10b66f1c..f25754dfc 100644 --- a/util/data/dname.h +++ b/util/data/dname.h @@ -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 */ diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h index caa00b9e8..3570fafb3 100644 --- a/util/data/packed_rrset.h +++ b/util/data/packed_rrset.h @@ -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. diff --git a/util/net_help.c b/util/net_help.c index 1cb52f0d0..efe82281d 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -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 diff --git a/util/net_help.h b/util/net_help.h index 7b1c78f78..a223fa4bf 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -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. -- 2.47.2