mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
root hints.
git-svn-id: file:///svn/unbound/trunk@335 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
472e96622c
commit
42312206c9
14 changed files with 602 additions and 17 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
237
iterator/iter_hints.c
Normal file
237
iterator/iter_hints.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
115
iterator/iter_hints.h
Normal file
115
iterator/iter_hints.h
Normal file
|
|
@ -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 */
|
||||
|
|
@ -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"
|
||||
|
|
@ -65,6 +66,14 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
|||
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]) {
|
||||
if(!ipstrtoaddr(cfg->fwd_address, cfg->fwd_port,
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue