root-hints can be read from file.

git-svn-id: file:///svn/unbound/trunk@708 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-10-19 14:02:53 +00:00
parent 90df76f931
commit 253a6e0143
11 changed files with 1717 additions and 1391 deletions

View file

@ -12,6 +12,7 @@
ldns-src make is done during unbound make, and so inherits the
make arguments from the unbound make invocation.
- nicer error when libevent problem causes instant exit on signal.
- read root hints from a root hint file (like BIND does).
18 October 2007: Wouter
- addresses are logged with errors.

View file

@ -130,6 +130,10 @@ server:
# the pid file.
# pidfile: "unbound.pid"
# file to read root hints from.
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
# root-hints: ""
# enable to not answer id.server and hostname.bind queries.
# hide-identity: no

View file

@ -173,6 +173,11 @@ The default is to log to syslog.
The process id is written to the file. Default is "unbound.pid". So,
kill -HUP `cat /etc/unbound/unbound.pid` will trigger a reload,
kill -QUIT `cat /etc/unbound/unbound.pid` will gracefully terminate.
.It \fBroot-hints:\fR <filename>
Read the root hints from this file. Default is nothing, using builtin hints
for the IN class. The file has the format of zone files, with root
nameserver names and addresses only. The default may become outdated,
when servers change, therefore it is good practice to use a root-hints file.
.It \fBhide-identity:\fR <yes or no>
If enabled id.server and hostname.bind queries are refused.
.It \fBidentity:\fR <string>

View file

@ -290,6 +290,126 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
return 1;
}
/** read root hints from file */
static int
read_root_hints(struct iter_hints* hints, char* fname)
{
int lineno = 0;
uint32_t default_ttl = 0;
ldns_rdf* origin = NULL;
ldns_rdf* prev_rr = NULL;
struct delegpt* dp;
ldns_rr* rr = NULL;
ldns_status status;
uint16_t c = LDNS_RR_CLASS_IN;
FILE* f = fopen(fname, "r");
if(!f) {
log_err("could not read root hints %s: %s",
fname, strerror(errno));
return 0;
}
dp = delegpt_create(hints->region);
if(!dp) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
verbose(VERB_DETAIL, "Reading root hints from %s", fname);
while(!feof(f)) {
status = ldns_rr_new_frm_fp_l(&rr, f,
&default_ttl, &origin, &prev_rr, &lineno);
if(status == LDNS_STATUS_SYNTAX_EMPTY ||
status == LDNS_STATUS_SYNTAX_TTL ||
status == LDNS_STATUS_SYNTAX_ORIGIN)
continue;
if(status != LDNS_STATUS_OK) {
log_err("reading root hints %s %d: %s", fname,
lineno, ldns_get_errorstr_by_id(status));
fclose(f);
return 0;
}
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
if(!delegpt_add_ns(dp, hints->region,
ldns_rdf_data(ldns_rr_rdf(rr, 0)))) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
c = ldns_rr_get_class(rr);
if(!dp->name) {
if(!delegpt_set_name(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)))){
log_err("out of memory.");
fclose(f);
return 0;
}
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) {
struct sockaddr_in sa;
socklen_t len = (socklen_t)sizeof(sa);
memset(&sa, 0, len);
sa.sin_family = AF_INET;
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa.sin_addr,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET_SIZE);
if(!delegpt_add_target(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
(struct sockaddr_storage*)&sa, len)) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
struct sockaddr_in6 sa;
socklen_t len = (socklen_t)sizeof(sa);
memset(&sa, 0, len);
sa.sin6_family = AF_INET6;
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa.sin6_addr,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET6_SIZE);
if(!delegpt_add_target(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
(struct sockaddr_storage*)&sa, len)) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
} else {
log_warn("root hints %s:%d skipping type %d",
fname, lineno, ldns_rr_get_type(rr));
}
ldns_rr_free(rr);
}
fclose(f);
if(!dp->name) {
log_warn("root hints %s: no NS content", fname);
return 1;
}
if(!hints_insert(hints, c, dp)) {
return 0;
}
delegpt_log(VERB_DETAIL, dp);
return 1;
}
/** read root hints list */
static int
read_root_hints_list(struct iter_hints* hints, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->root_hints; p; p = p->next) {
log_assert(p->str);
if(p->str && p->str[0]) {
if(!read_root_hints(hints, p->str))
return 0;
}
}
return 1;
}
int
hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
{
@ -297,7 +417,10 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
hints->tree = rbtree_create(stub_cmp);
if(!hints->tree)
return 0;
/* TODO: read root hints from file named in cfg */
/* read root hints */
if(!read_root_hints_list(hints, cfg))
return 0;
/* read stub hints */
if(!read_stubs(hints, cfg))

View file

@ -103,6 +103,7 @@ config_create()
goto error_exit;
if(!cfg_strlist_insert(&cfg->donotqueryaddrs, strdup("::1")))
goto error_exit;
cfg->root_hints = NULL;
cfg->do_daemonize = 1;
cfg->num_ifs = 0;
cfg->ifs = NULL;
@ -223,6 +224,7 @@ config_delete(struct config_file* cfg)
config_delstubs(cfg->stubs);
config_delstubs(cfg->forwards);
config_delstrlist(cfg->donotqueryaddrs);
config_delstrlist(cfg->root_hints);
free(cfg->identity);
free(cfg->version);
free(cfg->module_conf);

View file

@ -112,6 +112,8 @@ struct config_file {
/** outgoing interface description strings (IP addresses) */
char **out_ifs;
/** the root hints */
struct config_strlist* root_hints;
/** the stub definitions, linked list */
struct config_stub* stubs;
/** the forward zone definitions, linked list */

File diff suppressed because it is too large Load diff

View file

@ -117,6 +117,7 @@ username{COLON} { YDOUT; return VAR_USERNAME;}
directory{COLON} { YDOUT; return VAR_DIRECTORY;}
logfile{COLON} { YDOUT; return VAR_LOGFILE;}
pidfile{COLON} { YDOUT; return VAR_PIDFILE;}
root-hints{COLON} { YDOUT; return VAR_ROOT_HINTS;}
msg-buffer-size{COLON} { YDOUT; return VAR_MSG_BUFFER_SIZE;}
msg-cache-size{COLON} { YDOUT; return VAR_MSG_CACHE_SIZE;}
msg-cache-slabs{COLON} { YDOUT; return VAR_MSG_CACHE_SLABS;}

File diff suppressed because it is too large Load diff

View file

@ -104,7 +104,8 @@
VAR_TRUSTED_KEYS_FILE = 320,
VAR_VAL_NSEC3_KEYSIZE_ITERATIONS = 321,
VAR_USE_SYSLOG = 322,
VAR_OUTGOING_INTERFACE = 323
VAR_OUTGOING_INTERFACE = 323,
VAR_ROOT_HINTS = 324
};
#endif
/* Tokens. */
@ -174,6 +175,7 @@
#define VAR_VAL_NSEC3_KEYSIZE_ITERATIONS 321
#define VAR_USE_SYSLOG 322
#define VAR_OUTGOING_INTERFACE 323
#define VAR_ROOT_HINTS 324
@ -185,7 +187,7 @@ typedef union YYSTYPE
char* str;
}
/* Line 1489 of yacc.c. */
#line 189 "util/configparser.h"
#line 191 "util/configparser.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1

View file

@ -85,7 +85,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
%token VAR_OUTGOING_INTERFACE
%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -121,7 +121,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_incoming_num_tcp | server_msg_buffer_size |
server_key_cache_size | server_key_cache_slabs |
server_trusted_keys_file | server_val_nsec3_keysize_iterations |
server_use_syslog | server_outgoing_interface
server_use_syslog | server_outgoing_interface | server_root_hints
;
stubstart: VAR_STUB_ZONE
{
@ -332,6 +332,13 @@ server_pidfile: VAR_PIDFILE STRING
cfg_parser->cfg->pidfile = $2;
}
;
server_root_hints: VAR_ROOT_HINTS STRING
{
OUTYY(("P(server_root_hints:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, $2))
yyerror("out of memory");
}
;
server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING
{
OUTYY(("P(server_trust_anchor_file:%s)\n", $2));