mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
forward zones.
git-svn-id: file:///svn/unbound/trunk@429 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
6907d9a989
commit
62dd62efd0
12 changed files with 571 additions and 44 deletions
|
|
@ -1,3 +1,7 @@
|
|||
17 July 2007: Wouter
|
||||
- forward zone options in config file.
|
||||
- forward per zone in iterator. takes precendence over stubs.
|
||||
|
||||
27 June 2007: Wouter
|
||||
- delete of mesh does a postorder traverse of the tree.
|
||||
- found and fixed a memory leak. For TTL=0 messages, that would
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ server:
|
|||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# subdomains go to the given list of nameservers. list zero or more
|
||||
# 'example.org' go to the given list of nameservers. list zero or more
|
||||
# nameservers by hostname or by ipaddress.
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
|
|
@ -146,3 +146,14 @@ server:
|
|||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
# Forward zones
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of servers. These servers have to handle
|
||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||
# forward-zone:
|
||||
# name: "example.com"
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
||||
|
|
|
|||
|
|
@ -153,11 +153,28 @@ For the stub zone this list of nameservers is used. Class IN is assumed.
|
|||
.It \fBname:\fR <domain name>
|
||||
Name of the stub zone.
|
||||
.It \fBstub-host:\fR <domain name>
|
||||
Name of stub zone nameserver. Will need to be resolved before it can be used.
|
||||
Name of stub zone nameserver. Is itself resolved before it is used.
|
||||
.It \fBstub-addr:\fR <IP address>
|
||||
IP address of stub zone nameserver. Can be IP 4 or IP 6.
|
||||
.El
|
||||
|
||||
.Ss Forward Zone Options
|
||||
There may be multiple
|
||||
.Ic forward-zone:
|
||||
clauses. Each with a name: and zero or more hostnames or IP addresses.
|
||||
For the forward zone this list of nameservers is used to forward the queries
|
||||
to. The servers have to handle further recursion for the query. Class IN is
|
||||
assumed. A forward-zone entry with name "." and a forward-addr target will
|
||||
forward all queries to that other server (unless it can answer from the cache).
|
||||
.Bl -tag -width indent
|
||||
.It \fBname:\fR <domain name>
|
||||
Name of the forward zone.
|
||||
.It \fBforward-host:\fR <domain name>
|
||||
Name of server to forward to. Is itself resolved before it is used.
|
||||
.It \fBforward-addr:\fR <IP address>
|
||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||
.El
|
||||
|
||||
.Sh FILES
|
||||
.Bl -tag -width indent
|
||||
.It Pa unbound.conf
|
||||
|
|
|
|||
285
iterator/iter_fwd.c
Normal file
285
iterator/iter_fwd.c
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* iterator/iter_fwd.c - iterative resolver module forward zones.
|
||||
*
|
||||
* 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 forward zones and config settings.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "util/region-allocator.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
|
||||
/** compare two fwd entries */
|
||||
static int
|
||||
fwd_cmp(const void* k1, const void* k2)
|
||||
{
|
||||
int m;
|
||||
struct iter_forward_zone* n1 = (struct iter_forward_zone*)k1;
|
||||
struct iter_forward_zone* n2 = (struct iter_forward_zone*)k2;
|
||||
if(n1->dclass != n2->dclass) {
|
||||
if(n1->dclass < n2->dclass)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs,
|
||||
&m);
|
||||
}
|
||||
|
||||
struct iter_forwards*
|
||||
forwards_create()
|
||||
{
|
||||
struct iter_forwards* fwd = (struct iter_forwards*)calloc(1,
|
||||
sizeof(struct iter_forwards));
|
||||
if(!fwd)
|
||||
return NULL;
|
||||
fwd->region = region_create(malloc, free);
|
||||
if(!fwd->region) {
|
||||
forwards_delete(fwd);
|
||||
return NULL;
|
||||
}
|
||||
return fwd;
|
||||
}
|
||||
|
||||
void
|
||||
forwards_delete(struct iter_forwards* fwd)
|
||||
{
|
||||
if(!fwd)
|
||||
return;
|
||||
region_destroy(fwd->region);
|
||||
free(fwd->tree);
|
||||
free(fwd);
|
||||
}
|
||||
|
||||
/** insert new info into forward structure */
|
||||
static int
|
||||
forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
|
||||
{
|
||||
struct iter_forward_zone* node = region_alloc(fwd->region,
|
||||
sizeof(struct iter_forward_zone));
|
||||
if(!node)
|
||||
return 0;
|
||||
node->node.key = node;
|
||||
node->dclass = c;
|
||||
node->name = region_alloc_init(fwd->region, dp->name, dp->namelen);
|
||||
if(!node->name)
|
||||
return 0;
|
||||
node->namelen = dp->namelen;
|
||||
node->namelabs = dp->namelabs;
|
||||
node->dp = dp;
|
||||
if(!rbtree_insert(fwd->tree, &node->node)) {
|
||||
log_err("duplicate forward zone ignored.");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** initialise parent pointers in the tree */
|
||||
static void
|
||||
fwd_init_parents(struct iter_forwards* fwd)
|
||||
{
|
||||
struct iter_forward_zone* node, *prev = NULL, *p;
|
||||
int m;
|
||||
RBTREE_FOR(node, struct iter_forward_zone*, fwd->tree) {
|
||||
node->parent = NULL;
|
||||
if(!prev || prev->dclass != node->dclass) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/** set zone name */
|
||||
static int
|
||||
read_fwds_name(struct iter_forwards* fwd, struct config_stub* s,
|
||||
struct delegpt* dp)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
if(!s->name) {
|
||||
log_err("forward zone without a name (use name \".\" to forward everything)");
|
||||
return 0;
|
||||
}
|
||||
rdf = ldns_dname_new_frm_str(s->name);
|
||||
if(!rdf) {
|
||||
log_err("cannot parse forward zone name %s", s->name);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_set_name(dp, fwd->region, ldns_rdf_data(rdf))) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** set fwd host names */
|
||||
static int
|
||||
read_fwds_host(struct iter_forwards* fwd, struct config_stub* s,
|
||||
struct delegpt* dp)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
ldns_rdf* rdf;
|
||||
for(p = s->hosts; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
rdf = ldns_dname_new_frm_str(p->str);
|
||||
if(!rdf) {
|
||||
log_err("cannot parse forward %s server name: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_ns(dp, fwd->region, ldns_rdf_data(rdf))) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** set fwd server addresses */
|
||||
static int
|
||||
read_fwds_addr(struct iter_forwards* fwd, struct config_stub* s,
|
||||
struct delegpt* dp)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!ipstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr, &addrlen)) {
|
||||
log_err("cannot parse forward %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read forwards config */
|
||||
static int
|
||||
read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
{
|
||||
struct config_stub* s;
|
||||
for(s = cfg->forwards; s; s = s->next) {
|
||||
struct delegpt* dp = delegpt_create(fwd->region);
|
||||
if(!dp) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!read_fwds_name(fwd, s, dp) ||
|
||||
!read_fwds_host(fwd, s, dp) ||
|
||||
!read_fwds_addr(fwd, s, dp))
|
||||
return 0;
|
||||
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
|
||||
return 0;
|
||||
log_info("Forward zone server list:");
|
||||
delegpt_log(dp);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
{
|
||||
free(fwd->tree);
|
||||
fwd->tree = rbtree_create(fwd_cmp);
|
||||
if(!fwd->tree)
|
||||
return 0;
|
||||
|
||||
/* read forward zones */
|
||||
if(!read_forwards(fwd, cfg))
|
||||
return 0;
|
||||
fwd_init_parents(fwd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct delegpt*
|
||||
forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
|
||||
{
|
||||
/* lookup the forward zone in the tree */
|
||||
rbnode_t* res = NULL;
|
||||
struct iter_forward_zone *result;
|
||||
struct iter_forward_zone key;
|
||||
key.node.key = &key;
|
||||
key.dclass = qclass;
|
||||
key.name = qname;
|
||||
key.namelabs = dname_count_size_labels(qname, &key.namelen);
|
||||
if(rbtree_find_less_equal(fwd->tree, &key, &res)) {
|
||||
/* exact */
|
||||
result = (struct iter_forward_zone*)res;
|
||||
} else {
|
||||
/* smaller element (or no element) */
|
||||
int m;
|
||||
result = (struct iter_forward_zone*)res;
|
||||
if(!result || result->dclass != qclass)
|
||||
return NULL;
|
||||
/* count number of labels matched */
|
||||
(void)dname_lab_cmp(result->name, result->namelabs, key.name,
|
||||
key.namelabs, &m);
|
||||
while(result) { /* go up until qname is subdomain of stub */
|
||||
if(result->namelabs <= m)
|
||||
break;
|
||||
result = result->parent;
|
||||
}
|
||||
}
|
||||
if(result)
|
||||
return result->dp;
|
||||
return NULL;
|
||||
}
|
||||
121
iterator/iter_fwd.h
Normal file
121
iterator/iter_fwd.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* iterator/iter_fwd.h - iterative resolver module forward zones.
|
||||
*
|
||||
* 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 forward zones, and read those from config.
|
||||
*/
|
||||
|
||||
#ifndef ITERATOR_ITER_FWD_H
|
||||
#define ITERATOR_ITER_FWD_H
|
||||
#include "util/rbtree.h"
|
||||
struct iter_env;
|
||||
struct config_file;
|
||||
struct delegpt;
|
||||
struct region;
|
||||
|
||||
/**
|
||||
* Iterator forward zones structure
|
||||
*/
|
||||
struct iter_forwards {
|
||||
/** region where forward zone server addresses are allocated */
|
||||
struct region* region;
|
||||
/**
|
||||
* Zones 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_forward_zone.
|
||||
*/
|
||||
rbtree_t* tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator forward servers for a particular zone.
|
||||
*/
|
||||
struct iter_forward_zone {
|
||||
/** 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 forward server information for this zone. */
|
||||
struct delegpt* dp;
|
||||
/** pointer to parent in tree (or NULL if none) */
|
||||
struct iter_forward_zone* parent;
|
||||
/** class. host order. */
|
||||
uint16_t dclass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create forwards
|
||||
* @return new forwards or NULL on error.
|
||||
*/
|
||||
struct iter_forwards* forwards_create();
|
||||
|
||||
/**
|
||||
* Delete forwards.
|
||||
* @param fwd: to delete.
|
||||
*/
|
||||
void forwards_delete(struct iter_forwards* fwd);
|
||||
|
||||
/**
|
||||
* Process forwards config.
|
||||
* @param fwd: where to store.
|
||||
* @param cfg: config options.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Find a forward zone information
|
||||
* For this qname/qclass find forward zone information, returns delegation
|
||||
* point with server names and addresses, or NULL if no forwarding is needed.
|
||||
*
|
||||
* @param fwd: forward storage.
|
||||
* @param qname: The qname of the query.
|
||||
* @param qclass: The qclass of the query.
|
||||
* @return: A delegation point if the query has to be forwarded to that list,
|
||||
* otherwise null.
|
||||
*/
|
||||
struct delegpt* forwards_lookup(struct iter_forwards* fwd,
|
||||
uint8_t* qname, uint16_t qclass);
|
||||
|
||||
#endif /* ITERATOR_ITER_FWD_H */
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/dns.h"
|
||||
|
|
@ -131,6 +132,12 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
|||
log_err("Could not set root or stub hints");
|
||||
return 0;
|
||||
}
|
||||
if(!iter_env->fwds)
|
||||
iter_env->fwds = forwards_create();
|
||||
if(!iter_env->fwds || !forwards_apply_cfg(iter_env->fwds, cfg)) {
|
||||
log_err("Could not set forward zones");
|
||||
return 0;
|
||||
}
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
|
||||
/* forwarder address */
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "iterator/iter_resptype.h"
|
||||
#include "iterator/iter_scrub.h"
|
||||
|
|
@ -84,6 +85,7 @@ iter_deinit(struct module_env* env, int id)
|
|||
iter_env = (struct iter_env*)env->modinfo[id];
|
||||
free(iter_env->target_fetch_policy);
|
||||
hints_delete(iter_env->hints);
|
||||
forwards_delete(iter_env->fwds);
|
||||
if(iter_env)
|
||||
free(iter_env);
|
||||
}
|
||||
|
|
@ -603,6 +605,31 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the query needs forwarding.
|
||||
*
|
||||
* @param qstate: query state.
|
||||
* @param iq: iterator query state.
|
||||
* @param ie: iterator shared global environment.
|
||||
* @return true if the request is forwarded, false if not.
|
||||
* If returns true but, iq->dp is NULL then a malloc failure occurred.
|
||||
*/
|
||||
static int
|
||||
forward_request(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct iter_env* ie)
|
||||
{
|
||||
struct delegpt* dp = forwards_lookup(ie->fwds, iq->qchase.qname,
|
||||
iq->qchase.qclass);
|
||||
if(!dp)
|
||||
return 0;
|
||||
/* send recursion desired to forward addr */
|
||||
iq->chase_flags |= BIT_RD;
|
||||
iq->dp = delegpt_copy(dp, qstate->region);
|
||||
/* iq->dp checked by caller */
|
||||
verbose(VERB_ALGO, "forwarding request");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the initial part of the request handling. This state roughly
|
||||
* corresponds to resolver algorithms steps 1 (find answer in cache) and 2
|
||||
|
|
@ -688,35 +715,18 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
return final_state(iq);
|
||||
}
|
||||
|
||||
/* TODO attempt to forward the request */
|
||||
/* if (forwardRequest(event, state, req))
|
||||
{
|
||||
// the request has been forwarded.
|
||||
// forwarded requests need to be immediately sent to the
|
||||
// next state, QUERYTARGETS.
|
||||
return nextState(event, req, state,
|
||||
IterEventState.QUERYTARGETS_STATE);
|
||||
}
|
||||
*/
|
||||
|
||||
/* TODO attempt to find a covering DNAME in the cache */
|
||||
/* resp = mDNSCache.findDNAME(req.getQName(), req.getQType(), req
|
||||
.getQClass());
|
||||
if (resp != null)
|
||||
/* attempt to forward the request */
|
||||
if(forward_request(qstate, iq, ie))
|
||||
{
|
||||
log.trace("returning synthesized CNAME response from cache: " + resp);
|
||||
Name cname = handleCNAMEResponse(state, req, resp);
|
||||
// At this point, we just initiate the query restart.
|
||||
// This might not be a query restart situation (e.g., qtype == CNAME),
|
||||
// but
|
||||
// the answer returned from findDNAME() is likely to be one that we
|
||||
// don't want to return.
|
||||
// Thus we allow the cache and other resolution mojo kick in regardless.
|
||||
req.setQName(cname);
|
||||
state.queryRestartCount++;
|
||||
return nextState(event, req, state, IterEventState.INIT_REQUEST_STATE);
|
||||
}
|
||||
*/
|
||||
if(!iq->dp) {
|
||||
log_err("alloc failure for forward dp");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* the request has been forwarded.
|
||||
* forwarded requests need to be immediately sent to the
|
||||
* next state, QUERYTARGETS. */
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
}
|
||||
|
||||
/* Resolver Algorithm Step 2 -- find the "best" servers. */
|
||||
|
||||
|
|
@ -1002,7 +1012,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
* they will not be show up again. */
|
||||
if(tf_policy != 0) {
|
||||
int extra = 0;
|
||||
verbose(VERB_ALGO, "query for extra %d targets", tf_policy);
|
||||
verbose(VERB_ALGO, "attempt to get extra %d targets",
|
||||
tf_policy);
|
||||
if(!query_for_targets(qstate, iq, ie, id, tf_policy, &extra)) {
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
|
@ -1120,6 +1131,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
}
|
||||
type = response_type_from_server(iq->response, &iq->qchase, iq->dp);
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
|
||||
/* When forwarding (RD bit is set), we handle referrals
|
||||
* differently. No queries should be sent elsewhere */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
|
||||
/* handle each of the type cases */
|
||||
if(type == RESPONSE_TYPE_ANSWER) {
|
||||
/* ANSWER type responses terminate the query algorithm,
|
||||
* so they sent on their */
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
struct module_func_block;
|
||||
struct delegpt;
|
||||
struct iter_hints;
|
||||
struct iter_forwards;
|
||||
struct iter_prep_list;
|
||||
|
||||
/** max number of query restarts. Determines max number of CNAME chain. */
|
||||
|
|
@ -84,7 +85,7 @@ struct iter_env {
|
|||
int supports_ipv6;
|
||||
|
||||
/** Mapping of forwarding zones to targets. */
|
||||
/* struct fwds fwd_map TODO */
|
||||
struct iter_forwards* fwds;
|
||||
|
||||
/** A set of inetaddrs that should never be queried. */
|
||||
/* struct bla donotquery_addrs TODO */
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ config_create()
|
|||
cfg->num_ifs = 0;
|
||||
cfg->ifs = NULL;
|
||||
cfg->stubs = NULL;
|
||||
cfg->forwards = NULL;
|
||||
cfg->harden_short_bufsize = 0;
|
||||
cfg->harden_large_queries = 0;
|
||||
return cfg;
|
||||
|
|
@ -158,6 +159,21 @@ config_delstrlist(struct config_strlist* p)
|
|||
}
|
||||
}
|
||||
|
||||
/** delete config stublist */
|
||||
static void
|
||||
config_delstubs(struct config_stub* p)
|
||||
{
|
||||
struct config_stub* np;
|
||||
while(p) {
|
||||
np = p->next;
|
||||
free(p->name);
|
||||
config_delstrlist(p->hosts);
|
||||
config_delstrlist(p->addrs);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
config_delete(struct config_file* cfg)
|
||||
{
|
||||
|
|
@ -175,17 +191,8 @@ config_delete(struct config_file* cfg)
|
|||
free(cfg->ifs[i]);
|
||||
free(cfg->ifs);
|
||||
}
|
||||
if(cfg->stubs) {
|
||||
struct config_stub* p = cfg->stubs, *np;
|
||||
while(p) {
|
||||
np = p->next;
|
||||
free(p->name);
|
||||
config_delstrlist(p->hosts);
|
||||
config_delstrlist(p->addrs);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
}
|
||||
config_delstubs(cfg->stubs);
|
||||
config_delstubs(cfg->forwards);
|
||||
free(cfg);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ struct config_file {
|
|||
|
||||
/** the stub definitions, linked list */
|
||||
struct config_stub* stubs;
|
||||
/** the forward definitions, linked list */
|
||||
struct config_stub* forwards;
|
||||
|
||||
/** harden against very small edns buffer sizes */
|
||||
int harden_short_bufsize;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,9 @@ stub-zone{COLON} { YDOUT; return VAR_STUB_ZONE;}
|
|||
name{COLON} { YDOUT; return VAR_NAME;}
|
||||
stub-addr{COLON} { YDOUT; return VAR_STUB_ADDR;}
|
||||
stub-host{COLON} { YDOUT; return VAR_STUB_HOST;}
|
||||
forward-zone{COLON} { YDOUT; return VAR_FORWARD_ZONE;}
|
||||
forward-addr{COLON} { YDOUT; return VAR_FORWARD_ADDR;}
|
||||
forward-host{COLON} { YDOUT; return VAR_FORWARD_HOST;}
|
||||
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_INFRA_CACHE_NUMHOSTS VAR_INFRA_CACHE_NUMLAME VAR_NAME
|
||||
%token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
|
||||
%token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
|
||||
%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
|
@ -106,7 +107,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_infra_cache_slabs | server_infra_cache_numhosts |
|
||||
server_infra_cache_numlame | stubstart contents_stub |
|
||||
server_target_fetch_policy | server_harden_short_bufsize |
|
||||
server_harden_large_queries
|
||||
server_harden_large_queries | forwardstart contents_forward
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
|
@ -124,6 +125,22 @@ contents_stub: contents_stub content_stub
|
|||
| ;
|
||||
content_stub: stub_name | stub_host | stub_addr
|
||||
;
|
||||
forwardstart: VAR_FORWARD_ZONE
|
||||
{
|
||||
struct config_stub* s;
|
||||
OUTYY(("\nP(forward_zone:)\n"));
|
||||
s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
|
||||
if(s) {
|
||||
s->next = cfg_parser->cfg->forwards;
|
||||
cfg_parser->cfg->forwards = s;
|
||||
} else
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
contents_forward: contents_forward content_forward
|
||||
| ;
|
||||
content_forward: forward_name | forward_host | forward_addr
|
||||
;
|
||||
server_num_threads: VAR_NUM_THREADS STRING
|
||||
{
|
||||
OUTYY(("P(server_num_threads:%s)\n", $2));
|
||||
|
|
@ -410,6 +427,7 @@ server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING
|
|||
stub_name: VAR_NAME STRING
|
||||
{
|
||||
OUTYY(("P(name:%s)\n", $2));
|
||||
free(cfg_parser->cfg->stubs->name);
|
||||
cfg_parser->cfg->stubs->name = $2;
|
||||
}
|
||||
;
|
||||
|
|
@ -439,6 +457,39 @@ stub_addr: VAR_STUB_ADDR STRING
|
|||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
forward_name: VAR_NAME STRING
|
||||
{
|
||||
OUTYY(("P(name:%s)\n", $2));
|
||||
free(cfg_parser->cfg->forwards->name);
|
||||
cfg_parser->cfg->forwards->name = $2;
|
||||
}
|
||||
;
|
||||
forward_host: VAR_FORWARD_HOST STRING
|
||||
{
|
||||
struct config_strlist *s = (struct config_strlist*)calloc(1,
|
||||
sizeof(struct config_strlist));
|
||||
OUTYY(("P(forward-host:%s)\n", $2));
|
||||
if(s) {
|
||||
s->str = $2;
|
||||
s->next = cfg_parser->cfg->forwards->hosts;
|
||||
cfg_parser->cfg->forwards->hosts = s;
|
||||
} else
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
forward_addr: VAR_FORWARD_ADDR STRING
|
||||
{
|
||||
struct config_strlist *s = (struct config_strlist*)calloc(1,
|
||||
sizeof(struct config_strlist));
|
||||
OUTYY(("P(forward-addr:%s)\n", $2));
|
||||
if(s) {
|
||||
s->str = $2;
|
||||
s->next = cfg_parser->cfg->forwards->addrs;
|
||||
cfg_parser->cfg->forwards->addrs = s;
|
||||
} else
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
/* parse helper routines could be here */
|
||||
|
|
|
|||
Loading…
Reference in a new issue