Remove old forwarder mode, new @port option and tests ported over.

git-svn-id: file:///svn/unbound/trunk@432 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-07-17 15:26:45 +00:00
parent ab7a6bc2b9
commit c7883a9ebe
31 changed files with 77 additions and 181 deletions

View file

@ -2,6 +2,13 @@
- forward zone options in config file.
- forward per zone in iterator. takes precendence over stubs.
- fixup commithooks.
- removed forward-to and forward-to-port features, subsumed by
new forward zones.
- fix parser to handle absent server: clause.
- change untrusted rrset test to account for scrubber that is now
applied during the test (which removes the poison, by the way).
- feature, addresses can be specified with @portnumber, like nsd.conf.
- test config files changed over to new forwarder syntax.
27 June 2007: Wouter
- delete of mesh does a postorder traverse of the tree.

View file

@ -93,14 +93,6 @@ server:
# Enable TCP, "yes" or "no".
# do-tcp: yes
# Set this to configure unbound to act as a forwarder. All queries are
# sent to the remote nameserver that will resolve them.
# Set to "" to disable forwarding, or give ip-address to enable.
# forward-to: ""
# The port number to send forwarded queries to.
# forward-to-port: 53
# if given, a chroot(2) is done to the given directory.
# i.e. you can chroot to the working directory, for example,
# for extra security, but make sure all files are in that directory.
@ -154,6 +146,7 @@ server:
# forward-zone:
# name: "example.com"
# forward-addr: 192.0.2.68
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
# forward-zone:
# name: "example.org"
# forward-host: fwd.example.com

View file

@ -99,12 +99,6 @@ Enable or disable whether ip6 queries are answered. Default is yes.
Enable or disable whether UDP queries are answered. Default is yes.
.It \fBdo-tcp:\fR <yes or no>
Enable or disable whether TCP queries are answered. Default is yes.
.It \fBforward-to:\fR <ip address>
If set (not "") then forwarder mode is enabled. Default is "" (disabled).
The ip address is used to forward all DNS queries to.
.It \fBforward-to-port:\fR <port number>
The port on which the remote server is running that answers forwarded queries.
Default is 53.
.It \fBchroot:\fR <directory>
If given a chroot is done to the given directory. The default is none ("").
.It \fBusername:\fR <name>
@ -156,6 +150,7 @@ Name of the stub zone.
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.
To use a nondefault port for DNS communication append '@' with the port number.
.El
.Ss Forward Zone Options
@ -173,6 +168,7 @@ Name of the forward zone.
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.
To use a nondefault port for DNS communication append '@' with the port number.
.El
.Sh FILES

View file

@ -199,7 +199,7 @@ read_fwds_addr(struct iter_forwards* fwd, struct config_stub* s,
socklen_t addrlen;
for(p = s->addrs; p; p = p->next) {
log_assert(p->str);
if(!ipstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr, &addrlen)) {
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
log_err("cannot parse forward %s ip address: '%s'",
s->name, p->str);
return 0;

View file

@ -101,7 +101,7 @@ ah(struct delegpt* dp, struct region* r, const char* sv, const char* ip)
return 0;
}
if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf)) ||
!ipstrtoaddr(ip, UNBOUND_DNS_PORT, &addr, &addrlen) ||
!extstrtoaddr(ip, &addr, &addrlen) ||
!delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
&addr, addrlen)) {
ldns_rdf_deep_free(rdf);
@ -256,7 +256,7 @@ read_stubs_addr(struct iter_hints* hints, struct config_stub* s,
socklen_t addrlen;
for(p = s->addrs; p; p = p->next) {
log_assert(p->str);
if(!ipstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr, &addrlen)) {
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
log_err("cannot parse stub %s ip address: '%s'",
s->name, p->str);
return 0;

View file

@ -139,17 +139,6 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
return 0;
}
iter_env->supports_ipv6 = cfg->do_ip6;
/* 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;
}

View file

@ -119,101 +119,6 @@ iter_new(struct module_qstate* qstate, int id)
return 1;
}
/** new query for iterator in forward mode */
static int
fwd_new(struct module_qstate* qstate, int id)
{
struct iter_qstate* iq = (struct iter_qstate*)region_alloc(
qstate->region, sizeof(struct iter_qstate));
struct module_env* env = qstate->env;
struct iter_env* ie = (struct iter_env*)env->modinfo[id];
struct outbound_entry* e;
uint16_t flags = 0; /* opcode=query, no flags */
int dnssec = 1; /* always get dnssec info */
qstate->minfo[id] = iq;
if(!iq)
return 0;
memset(iq, 0, sizeof(*iq));
outbound_list_init(&iq->outlist);
e = (*env->send_query)(qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass, flags, dnssec,
&ie->fwd_addr, ie->fwd_addrlen, qstate);
if(!e)
return 0;
outbound_list_insert(&iq->outlist, e);
qstate->ext_state[id] = module_wait_reply;
return 1;
}
/** iterator handle reply from authoritative server */
static int
iter_handlereply(struct module_qstate* qstate, int id)
{
struct module_env* env = qstate->env;
struct query_info reply_qinfo;
struct reply_info* reply_msg;
struct edns_data reply_edns;
hashvalue_t h;
int r;
if((r=reply_info_parse(qstate->reply->c->buffer, env->alloc,
&reply_qinfo, &reply_msg, qstate->env->scratch,
&reply_edns))!=0)
return 0;
h = query_info_hash(&qstate->qinfo);
(*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR, reply_msg);
/* there should be no dependencies in this forwarding mode */
(*qstate->env->walk_supers)(qstate, id, NULL);
dns_cache_store_msg(qstate->env, &reply_qinfo, h, reply_msg);
qstate->ext_state[id] = module_finished;
return 1;
}
/** perform forwarder functionality */
static void
perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
verbose(VERB_ALGO, "iterator: forwarding");
if(event == module_event_new) {
if(!fwd_new(qstate, id)) {
(*qstate->env->query_done)(qstate,
LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
return;
}
return;
}
/* it must be a query reply */
if(!outbound) {
verbose(VERB_ALGO, "query reply was not serviced");
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
return;
}
if(event == module_event_timeout || event == module_event_error) {
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
return;
}
if(event == module_event_reply) {
if(!iter_handlereply(qstate, id)) {
(*qstate->env->query_done)(qstate,
LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
}
return;
}
log_err("bad event for iterator[forwarding]");
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
}
/**
* Transition to the next state. This can be used to advance a currently
* processing event. It cannot be used to reactivate a forEvent.
@ -1599,10 +1504,6 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
log_query_info(VERB_DETAIL, "iterator operate: chased to",
&iq->qchase);
if(ie->fwd_addrlen != 0) {
perform_forward(qstate, event, id, outbound);
return;
}
/* perform iterator state machine */
if(event == module_event_new && iq == NULL) {
if(!iter_new(qstate, id)) {

View file

@ -68,11 +68,6 @@ struct iter_prep_list;
* Global state for the iterator.
*/
struct iter_env {
/** address to forward to */
struct sockaddr_storage fwd_addr;
/** length of fwd_addr, if not 0, forward mode is used */
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

2
testdata/fwd.rpl vendored
View file

@ -1,6 +1,6 @@
; This is a comment.
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Sample of a valid query

View file

@ -1,6 +1,6 @@
; This is a comment.
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Query receives answer from the cache

View file

@ -1,5 +1,5 @@
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Forwarder and an error happens on server query.
STEP 1 QUERY

View file

@ -4,7 +4,7 @@
server:
msg-cache-size: 1 # one whole byte!
msg-cache-slabs: 1
forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Old answer is dropped from the cache

Binary file not shown.

View file

@ -5,7 +5,9 @@
; here config file options:
server:
msg-cache-size: 1024
forward-to: "127.0.0.1"
forward-zone:
name: "."
forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Query receives answer not from the cache

BIN
testdata/fwd_tcp.tpkg vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,5 @@
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Forwarder and a timeout happens on server query.
STEP 1 QUERY

Binary file not shown.

View file

@ -1,7 +1,9 @@
; config options go here.
server:
num-queries-per-thread: 1
forward-to: "127.0.0.1"
forward-zone:
name: "."
forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Sample of a valid query

BIN
testdata/fwd_udp.tpkg vendored

Binary file not shown.

View file

@ -1,6 +1,6 @@
; This is a comment.
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN RRset TTL is updated from message.

View file

@ -1,6 +1,6 @@
; This is a comment.
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN Untrusted rrset not used for update
@ -91,8 +91,6 @@ ENTRY_BEGIN
SECTION ADDITIONAL
example.com. IN NS ns.eeeek.com.
example.com. IN NS ns2.eeeek.com.
ns.eeeek.com. IN A 55.44.33.22
ns2.eeeek.com. IN A 55.44.33.24
ENTRY_END

View file

@ -1,6 +1,6 @@
; This is a comment.
; config options go here.
server: forward-to: "127.0.0.1"
forward-zone: name: "." forward-addr: 127.0.0.1
CONFIG_END
SCENARIO_BEGIN RRset is updated from other message that passes by.

View file

@ -88,14 +88,12 @@ config_create()
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 1000;
cfg->infra_cache_numlame = 1000;
if(!(cfg->fwd_address = strdup(""))) goto error_exit;
if(!(cfg->username = strdup(""))) goto error_exit;
if(!(cfg->chrootdir = strdup(""))) goto error_exit;
if(!(cfg->directory = strdup("/etc/unbound"))) goto error_exit;
if(!(cfg->logfile = strdup(""))) goto error_exit;
if(!(cfg->pidfile = strdup("unbound.pid"))) goto error_exit;
if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
cfg->fwd_port = UNBOUND_DNS_PORT;
cfg->do_daemonize = 1;
cfg->num_ifs = 0;
cfg->ifs = NULL;
@ -178,7 +176,6 @@ void
config_delete(struct config_file* cfg)
{
if(!cfg) return;
free(cfg->fwd_address);
free(cfg->username);
free(cfg->chrootdir);
free(cfg->directory);

View file

@ -94,11 +94,6 @@ struct config_file {
/** max number of lame zones per host in the infra cache */
size_t infra_cache_numlame;
/** forwarder address. string. If not NULL fwder mode is enabled. */
char* fwd_address;
/** forwarder port */
int fwd_port;
/** the target fetch policy for the iterator */
char* target_fetch_policy;
@ -109,7 +104,7 @@ struct config_file {
/** the stub definitions, linked list */
struct config_stub* stubs;
/** the forward definitions, linked list */
/** the forward zone definitions, linked list */
struct config_stub* forwards;
/** harden against very small edns buffer sizes */

View file

@ -109,8 +109,6 @@ do-ip4{COLON} { YDOUT; return VAR_DO_IP4;}
do-ip6{COLON} { YDOUT; return VAR_DO_IP6;}
do-udp{COLON} { YDOUT; return VAR_DO_UDP;}
do-tcp{COLON} { YDOUT; return VAR_DO_TCP;}
forward-to{COLON} { YDOUT; return VAR_FORWARD_TO;}
forward-to-port{COLON} { YDOUT; return VAR_FORWARD_TO_PORT;}
interface{COLON} { YDOUT; return VAR_INTERFACE;}
chroot{COLON} { YDOUT; return VAR_CHROOT;}
username{COLON} { YDOUT; return VAR_USERNAME;}

View file

@ -69,9 +69,8 @@ extern struct config_parser_state* cfg_parser;
%token <str> STRING
%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
%token VAR_OUTGOING_PORT VAR_OUTGOING_RANGE VAR_INTERFACE
%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_FORWARD_TO VAR_FORWARD_TO_PORT VAR_CHROOT
%token VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
%token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS
@ -82,7 +81,9 @@ extern struct config_parser_state* cfg_parser;
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
toplevelvar: serverstart contents_server ;
toplevelvar: serverstart contents_server | stubstart contents_stub |
forwardstart contents_forward
;
/* server: declaration */
serverstart: VAR_SERVER
@ -97,17 +98,16 @@ contents_server: contents_server content_server
| ;
content_server: server_num_threads | server_verbosity | server_port |
server_outgoing_port | server_outgoing_range | server_do_ip4 |
server_do_ip6 | server_do_udp | server_do_tcp | server_forward_to |
server_forward_to_port | server_interface | server_chroot |
server_username | server_directory | server_logfile | server_pidfile |
server_do_ip6 | server_do_udp | server_do_tcp |
server_interface | server_chroot | server_username |
server_directory | server_logfile | server_pidfile |
server_msg_cache_size | server_msg_cache_slabs |
server_num_queries_per_thread | server_rrset_cache_size |
server_rrset_cache_slabs | server_outgoing_num_tcp |
server_infra_host_ttl | server_infra_lame_ttl |
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 | forwardstart contents_forward
server_infra_cache_numlame | server_target_fetch_policy |
server_harden_short_bufsize | server_harden_large_queries
;
stubstart: VAR_STUB_ZONE
{
@ -244,22 +244,6 @@ server_do_tcp: VAR_DO_TCP STRING
free($2);
}
;
server_forward_to: VAR_FORWARD_TO STRING
{
OUTYY(("P(server_forward_to:%s)\n", $2));
free(cfg_parser->cfg->fwd_address);
cfg_parser->cfg->fwd_address = $2;
}
;
server_forward_to_port: VAR_FORWARD_TO_PORT STRING
{
OUTYY(("P(server_forward_to_port:%s)\n", $2));
if(atoi($2) == 0)
yyerror("number expected");
else cfg_parser->cfg->fwd_port = atoi($2);
free($2);
}
;
server_chroot: VAR_CHROOT STRING
{
OUTYY(("P(server_chroot:%s)\n", $2));

View file

@ -43,6 +43,9 @@
#include "util/data/dname.h"
#include <fcntl.h>
/** max length of an IP address (the address portion) that we allow */
#define MAX_ADDR_STRLEN 128 /* characters */
/** returns true is string addr is an ip6 specced address */
int
str_is_ip6(const char* str)
@ -147,6 +150,31 @@ log_addr(const char* str, struct sockaddr_storage* addr, socklen_t addrlen)
str, family, dest, (int)port, (int)addrlen);
}
int
extstrtoaddr(const char* str, struct sockaddr_storage* addr,
socklen_t* addrlen)
{
char* s;
int port = UNBOUND_DNS_PORT;
if((s=strchr(str, '@'))) {
char buf[MAX_ADDR_STRLEN];
if(s-str >= MAX_ADDR_STRLEN) {
log_err("address too long: '%s'", str);
return 0;
}
strncpy(buf, str, MAX_ADDR_STRLEN);
buf[s-str] = 0;
port = atoi(s+1);
if(port == 0 && strcmp(s+1,"0")!=0) {
log_err("bad port spec in address: '%s", str);
return 0;
}
return ipstrtoaddr(buf, port, addr, addrlen);
}
return ipstrtoaddr(str, port, addr, addrlen);
}
int
ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen)

View file

@ -139,6 +139,17 @@ void log_addr(const char* str, struct sockaddr_storage* addr,
void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
struct sockaddr_storage* addr, socklen_t addrlen);
/**
* Convert address string, with @port appendix, to sockaddr.
* Uses DNS port by default.
* @param str: the string
* @param addr: where to store sockaddr.
* @param addrlen: length of stored sockaddr is returned.
* @return 0 on error.
*/
int extstrtoaddr(const char* str, struct sockaddr_storage* addr,
socklen_t* addrlen);
/**
* Convert ip address string and port to sockaddr.
* @param ip: ip4 or ip6 address string.