setup of state; delegation point setup.

git-svn-id: file:///svn/unbound/trunk@334 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-05-23 09:34:01 +00:00
parent 5fa0d10608
commit 472e96622c
9 changed files with 477 additions and 49 deletions

View file

@ -1,6 +1,8 @@
23 May 2007: Wouter 23 May 2007: Wouter
- outside network does precise timers for roundtrip estimates for rtt - outside network does precise timers for roundtrip estimates for rtt
and for setting timeout for UDP. Pending_udp takes milliseconds. and for setting timeout for UDP. Pending_udp takes milliseconds.
- cleaner iterator sockaddr conversion of forwarder address.
- iterator/iter_utils and iter_delegpt setup.
22 May 2007: Wouter 22 May 2007: Wouter
- outbound query list for modules and support to callback with the - outbound query list for modules and support to callback with the

54
iterator/iter_delegpt.c Normal file
View file

@ -0,0 +1,54 @@
/*
* iterator/iter_delegpt.c - delegation point with NS and address information.
*
* 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 implements the Delegation Point. It contains a list of name servers
* and their addresses if known.
*/
#include "config.h"
#include "iterator/iter_delegpt.h"
#include "util/region-allocator.h"
struct delegpt*
delegpt_create(struct region* region)
{
struct delegpt* dp=(struct delegpt*)region_alloc(region, sizeof(*dp));
if(!dp)
return NULL;
memset(dp, 0, sizeof(*dp));
return dp;
}

112
iterator/iter_delegpt.h Normal file
View file

@ -0,0 +1,112 @@
/*
* iterator/iter_delegpt.h - delegation point with NS and address information.
*
* 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 implements the Delegation Point. It contains a list of name servers
* and their addresses if known.
*/
#ifndef ITERATOR_ITER_DELEGPT_H
#define ITERATOR_ITER_DELEGPT_H
struct region;
struct delegpt_ns;
struct delegpt_addr;
/**
* Delegation Point.
* For a domain name, the NS rrset, and the A and AAAA records for those.
*/
struct delegpt {
/** the domain name of the delegation point. */
uint8_t* name;
/** length of the delegation point name */
size_t namelen;
/** number of labels in delegation point */
int namelabs;
/** the nameservers, names from the NS RRset rdata. */
struct delegpt_ns* nslist;
/** the target addresses for delegation */
struct delegpt_addr* target_list;
/** the list of usable targets; subset of target_list */
struct delegpt_addr* usable_list;
/** the list of returned targets; subset of target_list */
struct delegpt_addr* result_list;
};
/**
* Nameservers for a delegation point.
*/
struct delegpt_ns {
/** next in list */
struct delegpt_ns* next;
/** name of nameserver */
uint8_t* name;
/** length of name */
size_t namelen;
/**
* If the name has been resolved. false if not queried for yet.
* true if the address is known, or marked true if failed.
*/
int resolved;
};
/**
* Address of target nameserver in delegation point.
*/
struct delegpt_addr {
/** next delegation point in results */
struct delegpt_addr* next_result;
/** next delegation point in usable list */
struct delegpt_addr* next_usable;
/** next delegation point in all targets list */
struct delegpt_addr* next_target;
/** delegation point address */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
};
/**
* Create new delegation point.
* @param region: where to allocate it.
* @return new delegation point or NULL on error.
*/
struct delegpt* delegpt_create(struct region* region);
#endif /* ITERATOR_ITER_DELEGPT_H */

80
iterator/iter_utils.c Normal file
View file

@ -0,0 +1,80 @@
/*
* iterator/iter_utils.c - iterative resolver module utility functions.
*
* 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.
* Configuration options. Forward zones.
*/
#include "config.h"
#include "iterator/iter_utils.h"
#include "iterator/iterator.h"
#include "util/net_help.h"
#include "util/log.h"
#include "util/config_file.h"
int
iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
{
int i;
/* target fetch policy */
iter_env->max_dependency_depth = 4;
iter_env->target_fetch_policy = (int*)calloc(
(size_t)iter_env->max_dependency_depth+1, sizeof(int));
if(iter_env->max_dependency_depth >= 1)
iter_env->target_fetch_policy[1] = 3;
if(iter_env->max_dependency_depth >= 2)
iter_env->target_fetch_policy[2] = 1;
/* TODO read setting from config */
if(!iter_env->target_fetch_policy)
return 0;
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]);
/* forwarder address */
if(cfg->fwd_address && cfg->fwd_address[0]) {
if(!ipstrtoaddr(cfg->fwd_address, cfg->fwd_port,
&iter_env->fwd_addr, &iter_env->fwd_addrlen)) {
log_err("iterator: could not set forwarder address");
return 0;
}
verbose(VERB_ALGO, "iterator: fwd queries to: %s %d",
cfg->fwd_address, cfg->fwd_port);
}
return 1;
}

57
iterator/iter_utils.h Normal file
View file

@ -0,0 +1,57 @@
/*
* iterator/iter_utils.h - iterative resolver module utility functions.
*
* 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.
* Configuration options. Forward zones.
*/
#ifndef ITERATOR_ITER_UTILS_H
#define ITERATOR_ITER_UTILS_H
struct iter_env;
struct config_file;
/**
* Process config options and set iterator module state.
* Sets default values if no config is found.
* @param iter_env: iterator module state.
* @param cfg: config options.
* @return 0 on error.
*/
int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
#endif /* ITERATOR_ITER_UTILS_H */

View file

@ -44,51 +44,11 @@
#include "iterator/iterator.h" #include "iterator/iterator.h"
#include "util/module.h" #include "util/module.h"
#include "util/netevent.h" #include "util/netevent.h"
#include "util/config_file.h"
#include "util/net_help.h" #include "util/net_help.h"
#include "util/storage/slabhash.h" #include "util/storage/slabhash.h"
#include "util/region-allocator.h" #include "util/region-allocator.h"
#include "services/cache/rrset.h" #include "services/cache/rrset.h"
#include "iterator/iter_utils.h"
/**
* Set forwarder address
* @param ie: iterator global state.
* @param ip: the server name.
* @param port: port on server or NULL for default 53.
* @return: false on error.
*/
static int
iter_set_fwd(struct iter_env* ie, const char* ip, int port)
{
uint16_t p;
log_assert(ie && ip);
p = (uint16_t) port;
if(str_is_ip6(ip)) {
struct sockaddr_in6* sa =
(struct sockaddr_in6*)&ie->fwd_addr;
ie->fwd_addrlen = (socklen_t)sizeof(struct sockaddr_in6);
memset(sa, 0, ie->fwd_addrlen);
sa->sin6_family = AF_INET6;
sa->sin6_port = (in_port_t)htons(p);
if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
log_err("Bad ip6 address %s", ip);
return 0;
}
} else { /* ip4 */
struct sockaddr_in* sa =
(struct sockaddr_in*)&ie->fwd_addr;
ie->fwd_addrlen = (socklen_t)sizeof(struct sockaddr_in);
memset(sa, 0, ie->fwd_addrlen);
sa->sin_family = AF_INET;
sa->sin_port = (in_port_t)htons(p);
if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
log_err("Bad ip4 address %s", ip);
return 0;
}
}
verbose(VERB_ALGO, "iterator: fwd queries to: %s %d", ip, p);
return 1;
}
/** iterator init */ /** iterator init */
static int static int
@ -101,14 +61,10 @@ iter_init(struct module_env* env, int id)
return 0; return 0;
} }
env->modinfo[id] = (void*)iter_env; env->modinfo[id] = (void*)iter_env;
/* set forwarder address */ if(!iter_apply_cfg(iter_env, env->cfg)) {
if(env->cfg->fwd_address && env->cfg->fwd_address[0]) { log_err("iterator: could not apply configuration settings.");
if(!iter_set_fwd(iter_env, env->cfg->fwd_address,
env->cfg->fwd_port)) {
log_err("iterator: could not set forwarder address");
return 0; return 0;
} }
}
return 1; return 1;
} }
@ -177,6 +133,7 @@ iter_new(struct module_qstate* qstate, int id)
qstate->minfo[id] = iq; qstate->minfo[id] = iq;
if(!iq) if(!iq)
return 0; return 0;
memset(iq, 0, sizeof(*iq));
outbound_list_init(&iq->outlist); outbound_list_init(&iq->outlist);
if(qstate->qinfo.has_cd) if(qstate->qinfo.has_cd)
flags |= BIT_CD; flags |= BIT_CD;

View file

@ -44,6 +44,7 @@
#define ITERATOR_ITERATOR_H #define ITERATOR_ITERATOR_H
#include "services/outbound_list.h" #include "services/outbound_list.h"
struct module_func_block; struct module_func_block;
struct delegpt;
/** /**
* Global state for the iterator. * Global state for the iterator.
@ -51,14 +52,138 @@ struct module_func_block;
struct iter_env { struct iter_env {
/** address to forward to */ /** address to forward to */
struct sockaddr_storage fwd_addr; struct sockaddr_storage fwd_addr;
/** length of fwd_addr */ /** length of fwd_addr, if not 0, forward mode is used */
socklen_t fwd_addrlen; socklen_t fwd_addrlen;
/**
* The hints -- these aren't stored in the cache because they don't
* expire. The hints are always used to "prime" the cache. Note
* that both root hints and stub zone "hints" are stored in this
* data structure.
*/
/* struct hints* hints TODO */
/** A flag to indicate whether or not we have an IPv6 route */
int supports_ipv6;
/** Mapping of forwarding zones to targets. */
/* struct fwds fwd_map TODO */
/** A set of inetaddrs that should never be queried. */
/* struct bla donotquery_addrs TODO */
/** The maximum dependency depth that this resolver will pursue. */
int max_dependency_depth;
/**
* The target fetch policy for each dependency level. This is
* described as a simple number (per dependency level):
* negative numbers (usually just -1) mean fetch-all,
* 0 means only fetch on demand, and
* positive numbers mean to fetch at most that many targets.
* array of max_dependency_depth+1 size.
*/
int* target_fetch_policy;
};
/**
* State of the iterator for a query.
*/
enum iter_state {
/**
* Externally generated queries start at this state. Query restarts are
* reset to this state.
*/
INIT_REQUEST_STATE = 0,
/**
* Root priming events reactivate here, most other events pass
* through this naturally as the 2nd part of the INIT_REQUEST_STATE.
*/
INIT_REQUEST_2_STATE,
/**
* Stub priming events reactivate here, most other events pass
* through this naturally as the 3rd part of the INIT_REQUEST_STATE.
*/
INIT_REQUEST_3_STATE,
/**
* Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited.
* This state is reponsible for iterating through a list of
* nameserver targets.
*/
QUERYTARGETS_STATE,
/**
* Responses to queries start at this state. This state handles
* the decision tree associated with handling responses.
*/
QUERY_RESP_STATE,
/** Responses to priming queries finish at this state. */
PRIME_RESP_STATE,
/** Responses to target queries start at this state. */
TARGET_RESP_STATE,
/** Responses that are to be returned upstream end at this state. */
FINISHED_STATE
}; };
/** /**
* Per query state for the iterator module. * Per query state for the iterator module.
*/ */
struct iter_qstate { struct iter_qstate {
/** state of the iterator module
* This is the state that event is in or should sent to -- all
* requests should start with the INIT_REQUEST_STATE. All
* responses should start with QUERY_RESP_STATE. Subsequent
* processing of the event will change this state.
*/
enum iter_state state;
/** final state for the iterator module
* This is the state that responses should be routed to once the
* response is final. For externally initiated queries, this
* will be FINISHED_STATE, locally initiated queries will have
* different final states.
*/
enum iter_state final_state;
/**
* 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 */
/**
* This is the current delegation point for an in-progress query. This
* object retains state as to which delegation targets need to be
* (sub)queried for vs which ones have already been visited.
*/
struct delegpt* dp;
/** number of outstanding target sub queries */
int num_target_queries;
/** outstanding direct queries */
int num_current_queries;
/** the number of times this query has been restarted. */
int query_restart_count;
/** the number of times this query as followed a referral. */
int referral_count;
/**
* This is flag that, if true, means that this event is
* representing a stub priming query. It is meaningless unless
* the finalState is the PRIMING_RESP_STATE.
*/
int priming_stub;
/** list of pending queries to authoritative servers. */ /** list of pending queries to authoritative servers. */
struct outbound_list outlist; struct outbound_list outlist;
}; };

View file

@ -145,3 +145,34 @@ log_addr(struct sockaddr_storage* addr, socklen_t addrlen)
verbose(VERB_DETAIL, "addr fam=%s port=%d dest=%s len=%d", verbose(VERB_DETAIL, "addr fam=%s port=%d dest=%s len=%d",
family, (int)port, dest, (int)addrlen); family, (int)port, dest, (int)addrlen);
} }
int
ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen)
{
uint16_t p;
if(!ip) return 0;
p = (uint16_t) port;
if(str_is_ip6(ip)) {
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
memset(sa, 0, *addrlen);
sa->sin6_family = AF_INET6;
sa->sin6_port = (in_port_t)htons(p);
if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
log_err("Bad ip6 address %s", ip);
return 0;
}
} else { /* ip4 */
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
*addrlen = (socklen_t)sizeof(struct sockaddr_in);
memset(sa, 0, *addrlen);
sa->sin_family = AF_INET;
sa->sin_port = (in_port_t)htons(p);
if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
log_err("Bad ip4 address %s", ip);
return 0;
}
}
return 1;
}

View file

@ -117,5 +117,15 @@ void* memdup(void* data, size_t len);
*/ */
void log_addr(struct sockaddr_storage* addr, socklen_t addrlen); void log_addr(struct sockaddr_storage* addr, socklen_t addrlen);
/**
* Convert ip address string and port to sockaddr.
* @param ip: ip4 or ip6 address string.
* @param port: port number, host format.
* @param addr: where to store sockaddr.
* @param addrlen: length of stored sockaddr is returned.
* @return 0 on error.
*/
int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen);
#endif /* NET_HELP_H */ #endif /* NET_HELP_H */