config file is used.

git-svn-id: file:///svn/unbound/trunk@135 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-02-22 13:36:29 +00:00
parent a36b64a9e7
commit 618ef6acbb
17 changed files with 284 additions and 105 deletions

View file

@ -567,8 +567,8 @@ struct sockaddr_storage;
#include "ldns/ldns.h"
/** default port to listen for queries, passed to getaddrinfo */
#define UNBOUND_DNS_PORT "53"
/** default port for DNS traffic. */
#define UNBOUND_DNS_PORT 53
])
AC_CONFIG_FILES([Makefile])

View file

@ -55,15 +55,51 @@ static void usage()
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help\n");
printf("-c file config file to read, unbound.conf(5).\n");
printf("-p port the port to listen on\n");
printf("-v verbose (multiple times increase verbosity)\n");
printf("-f ip set forwarder address\n");
printf("-z port set forwarder port\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
}
/**
* Run the daemon.
* @param cfgfile: the config file name.
* @param cmdline_verbose: verbosity resulting from commandline -v.
* These increase verbosity as specified in the config file.
*/
static void run_daemon(const char* cfgfile, int cmdline_verbose)
{
struct worker* worker = NULL;
struct config_file *cfg = NULL;
if(!(cfg = config_create())) {
fprintf(stderr, "Could not init config defaults.");
exit(1);
}
if(cfgfile) {
if(!config_read(cfg, cfgfile)) {
config_delete(cfg);
exit(1);
}
verbosity = cmdline_verbose + cfg->verbosity;
}
log_info("Start of %s.", PACKAGE_STRING);
/* setup */
worker = worker_init(cfg, BUFSZ);
if(!worker) {
fatal_exit("could not initialize");
}
/* drop user priviliges and chroot if needed */
log_info("start of service (%s).", PACKAGE_STRING);
worker_work(worker);
/* cleanup */
verbose(VERB_ALGO, "Exit cleanup.");
worker_delete(worker);
}
/** getopt global, in case header files fail to declare it. */
extern int optind;
/** getopt global, in case header files fail to declare it. */
@ -78,39 +114,20 @@ extern char* optarg;
int
main(int argc, char* argv[])
{
struct worker* worker = NULL;
int do_ip4=1, do_ip6=1, do_udp=1, do_tcp=1;
size_t numports=3;
int baseport=10000;
const char* port = UNBOUND_DNS_PORT;
int c;
const char* fwd = "127.0.0.1";
const char* fwdport = UNBOUND_DNS_PORT;
const char* cfgfile = NULL;
struct config_file *cfg = NULL;
int cmdline_verbose = 0;
log_init();
/* parse the options */
while( (c=getopt(argc, argv, "c:f:hvp:z:")) != -1) {
while( (c=getopt(argc, argv, "c:hv")) != -1) {
switch(c) {
case 'c':
cfgfile = optarg;
break;
case 'f':
fwd = optarg;
break;
case 'z':
fwdport = optarg;
break;
case 'p':
if(!atoi(optarg))
fatal_exit("invalid port '%s'", optarg);
port = optarg;
baseport = atoi(optarg)+2000;
verbose(VERB_ALGO, "using port: %s", port);
break;
case 'v':
verbosity ++;
cmdline_verbose ++;
verbosity++;
break;
case '?':
case 'h':
@ -127,35 +144,6 @@ main(int argc, char* argv[])
return 1;
}
if(!(cfg = config_create())) {
fprintf(stderr, "Could not init config defaults.");
return 1;
}
if(cfgfile) {
if(!config_read(cfg, cfgfile)) {
config_delete(cfg);
return 1;
}
}
log_info("Start of %s.", PACKAGE_STRING);
/* setup */
worker = worker_init(port, do_ip4, do_ip6, do_udp, do_tcp, BUFSZ,
numports, baseport);
if(!worker) {
fatal_exit("could not initialize");
}
if(!worker_set_fwd(worker, fwd, fwdport)) {
worker_delete(worker);
fatal_exit("could not set forwarder address");
}
/* drop user priviliges and chroot if needed */
log_info("start of service (%s).", PACKAGE_STRING);
worker_work(worker);
/* cleanup */
verbose(VERB_ALGO, "Exit cleanup.");
worker_delete(worker);
run_daemon(cfgfile, cmdline_verbose);
return 0;
}

View file

@ -44,6 +44,7 @@
#include "util/net_help.h"
#include "daemon/worker.h"
#include "util/netevent.h"
#include "util/config_file.h"
#include "services/listen_dnsport.h"
#include "services/outside_network.h"
@ -207,8 +208,7 @@ worker_sighandler(int sig, void* arg)
}
struct worker*
worker_init(const char* port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
size_t buffer_size, size_t numports, int base_port)
worker_init(struct config_file *cfg, size_t buffer_size)
{
struct worker* worker = (struct worker*)calloc(1,
sizeof(struct worker));
@ -229,16 +229,17 @@ worker_init(const char* port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
worker_delete(worker);
return NULL;
}
worker->front = listen_create(worker->base, 0, NULL, port,
do_ip4, do_ip6, do_udp, do_tcp, buffer_size,
worker_handle_request, worker);
worker->front = listen_create(worker->base, 0, NULL, cfg->port,
cfg->do_ip4, cfg->do_ip6, cfg->do_udp, cfg->do_tcp,
buffer_size, worker_handle_request, worker);
if(!worker->front) {
log_err("could not create listening sockets");
worker_delete(worker);
return NULL;
}
worker->back = outside_network_create(worker->base,
buffer_size, numports, NULL, 0, do_ip4, do_ip6, base_port);
buffer_size, (size_t)cfg->outgoing_num_ports, NULL, 0,
cfg->do_ip4, cfg->do_ip6, cfg->outgoing_base_port);
if(!worker->back) {
log_err("could not create outgoing sockets");
worker_delete(worker);
@ -255,6 +256,13 @@ worker_init(const char* port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
worker_delete(worker);
return NULL;
}
/* set forwarder address */
if(cfg->fwd_address && cfg->fwd_address[0]) {
if(!worker_set_fwd(worker, cfg->fwd_address, cfg->fwd_port)) {
worker_delete(worker);
fatal_exit("could not set forwarder address");
}
}
return worker;
}
@ -277,17 +285,11 @@ worker_delete(struct worker* worker)
}
int
worker_set_fwd(struct worker* worker, const char* ip, const char* port)
worker_set_fwd(struct worker* worker, const char* ip, int port)
{
uint16_t p;
log_assert(worker && ip);
if(port)
p = (uint16_t)atoi(port);
else p = (uint16_t)atoi(UNBOUND_DNS_PORT);
if(!p) {
log_err("Bad port number %s", port?port:"default_port");
return 0;
}
p = (uint16_t) port;
if(str_is_ip6(ip)) {
struct sockaddr_in6* sa =
(struct sockaddr_in6*)&worker->fwd_addr;

View file

@ -47,6 +47,7 @@
#include "util/netevent.h"
struct listen_dnsport;
struct outside_network;
struct config_file;
/** size of table used for random numbers. large to be more secure. */
#define RND_STATE_SIZE 256
@ -84,19 +85,11 @@ struct worker {
/**
* Initialize worker.
* Allocates event base, listens to ports
* @param port: the port number to bind to.
* @param do_ip4: listen to ip4 queries.
* @param do_ip6: listen to ip6 queries.
* @param do_udp: listen to udp queries.
* @param do_tcp: listen to tcp queries.
* @param cfg: configuration settings.
* @param buffer_size: size of datagram buffer.
* @param numports: number of outgoing ports.
* @param base_port: -1 or specify base of outgoing port range.
* @return: The worker, or NULL on error.
*/
struct worker* worker_init(const char* port, int do_ip4, int do_ip6,
int do_udp, int do_tcp, size_t buffer_size, size_t numports,
int base_port);
struct worker* worker_init(struct config_file *cfg, size_t buffer_size);
/**
* Make worker work.
@ -115,6 +108,6 @@ void worker_delete(struct worker* worker);
* @param port: port on server or NULL for default 53.
* @return: false on error.
*/
int worker_set_fwd(struct worker* worker, const char* ip, const char* port);
int worker_set_fwd(struct worker* worker, const char* ip, int port);
#endif /* DAEMON_WORKER_H */

View file

@ -1,3 +1,7 @@
22 February 2007: Wouter
- Have a config file. Removed commandline options, moved to config.
- tests use config file.
21 February 2007: Wouter
- put -c option in man page.
- minievent fd array capped by FD_SETSIZE.

54
doc/example.conf Normal file
View file

@ -0,0 +1,54 @@
#
# Example configuration file.
#
# See unbound.conf(5) man page.
#
# this is a comment.
#Use this to include other text into the file.
#include: "otherfile.conf"
# The server clause sets the main parameters.
server:
# whitespace is not necessary, but looks cleaner.
# verbosity number, 0 is least verbose.
verbosity: 2
# number of threads to create. 1 disables threading.
# num-threads: 1
# port to answer queries from
# port: 53
# unbound needs to send packets to authoritative nameservers.
# it uses a range of ports for that.
# the start number of the port range
# outgoing-port: 1053
# number of port to allocate per thread, determines the size of the
# port range. A larger port range gives more resistance to certain
# spoof attacks, as it gets harder to guess which port is used.
# But also takes more system resources (for open sockets).
# outgoing-range: 16
# Enable IPv4, "yes" or "no".
# do-ip4: yes
# Enable IPv6, "yes" or "no".
# do-ip6: yes
# Enable UDP, "yes" or "no".
# do-udp: yes
# 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

View file

@ -42,9 +42,6 @@ unbound
.Nm unbound
.Op Fl h
.Op Fl c Ar cfgfile
.Op Fl p Ar port
.Op Fl f Ar ip
.Op Fl z Ar port
.Op Fl v
.Sh DESCRIPTION
@ -63,17 +60,9 @@ Set the config file to read with settings for unbound. The syntax is
described in
.Xr unbound.conf 5 .
.It Fl p Ar port
Start listening on the given port. Default is port 53(DNS).
.It Fl f Ar ip
Set forwarder address. DNS queries will be forwarded to this server.
.It Fl z Ar ip
Set forwarder port. DNS queries will be forwarded to this port.
.It Fl v
Increase verbosity. If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.El
.Sh SEE ALSO

View file

@ -47,6 +47,30 @@ gives operational information. Level 2 gives query level information,
output per query. Level 3 gives algorithm level information.
.It \fBnum-threads:\fR <number>
The number of threads to create to serve clients. Use 1 for no threading.
.It \fBport:\fR <port number>
The port number, default 53, on which the server responds to queries.
.It \fBoutgoing-port:\fR <port number>
The starting port number where the outgoing query port range is allocated.
Default is 1053.
.It \fBoutgoing-range:\fR <number>
Number of ports to open. This number is opened per thread for every outgoing
query interface. Must be at least 1. Default is 16.
Larger numbers give more protection against spoofing attempts, but need
extra resources from the operating system.
.It \fBdo-ip4:\fR <yes or no>
Enable or disable whether ip4 queries are answered. Default is yes.
.It \fBdo-ip6:\fR <yes or no>
Enable or disable whether ip6 queries are answered. Default is yes.
.It \fBdo-udp:\fR <yes or no>
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.
.Sh FILES
.Bl -tag -width indent

View file

@ -294,15 +294,17 @@ listen_create_if(const char* ifname, struct listen_dnsport* front,
struct listen_dnsport*
listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
const char* port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
int port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
size_t bufsize, comm_point_callback_t* cb, void *cb_arg)
{
struct addrinfo hints;
int i;
char portbuf[10];
struct listen_dnsport* front = (struct listen_dnsport*)
malloc(sizeof(struct listen_dnsport));
if(!front)
return NULL;
snprintf(portbuf, sizeof(portbuf), "%d", port);
front->cps = NULL;
front->udp_buff = ldns_buffer_new(bufsize);
if(!front->udp_buff) {
@ -329,7 +331,7 @@ listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
if(num_ifs == 0) {
if(do_ip6) {
hints.ai_family = AF_INET6;
if(!listen_create_if(NULL, front, base, port,
if(!listen_create_if(NULL, front, base, portbuf,
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
listen_delete(front);
return NULL;
@ -337,7 +339,7 @@ listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
}
if(do_ip4) {
hints.ai_family = AF_INET;
if(!listen_create_if(NULL, front, base, port,
if(!listen_create_if(NULL, front, base, portbuf,
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
listen_delete(front);
return NULL;
@ -348,7 +350,7 @@ listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
if(!do_ip6)
continue;
hints.ai_family = AF_INET6;
if(!listen_create_if(ifs[i], front, base, port,
if(!listen_create_if(ifs[i], front, base, portbuf,
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
listen_delete(front);
return NULL;
@ -357,7 +359,7 @@ listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
if(!do_ip4)
continue;
hints.ai_family = AF_INET;
if(!listen_create_if(ifs[i], front, base, port,
if(!listen_create_if(ifs[i], front, base, portbuf,
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
listen_delete(front);
return NULL;

View file

@ -93,7 +93,7 @@ struct listen_list {
* @return: the malloced listening structure, ready for use. NULL on error.
*/
struct listen_dnsport* listen_create(struct comm_base* base,
int num_ifs, const char* ifs[], const char* port,
int num_ifs, const char* ifs[], int port,
int do_ip4, int do_ip6, int do_udp, int do_tcp,
size_t bufsize, comm_point_callback_t* cb, void* cb_arg);

View file

@ -480,7 +480,7 @@ run_scenario(struct replay_runtime* runtime)
struct listen_dnsport*
listen_create(struct comm_base* base, int ATTR_UNUSED(num_ifs),
const char* ATTR_UNUSED(ifs[]), const char* ATTR_UNUSED(port),
const char* ATTR_UNUSED(ifs[]), int ATTR_UNUSED(port),
int ATTR_UNUSED(do_ip4), int ATTR_UNUSED(do_ip6),
int ATTR_UNUSED(do_udp), int ATTR_UNUSED(do_tcp),
size_t bufsize, comm_point_callback_t* cb, void* cb_arg)

BIN
testdata/fwd_tcp.tpkg vendored

Binary file not shown.

BIN
testdata/fwd_udp.tpkg vendored

Binary file not shown.

View file

@ -70,6 +70,19 @@ config_create()
/* the defaults if no config is present */
cfg->verbosity = 1;
cfg->num_threads = 1;
cfg->port = UNBOUND_DNS_PORT;
cfg->do_ip4 = 1;
cfg->do_ip6 = 1;
cfg->do_udp = 1;
cfg->do_tcp = 1;
cfg->outgoing_base_port = cfg->port + 1000;
cfg->outgoing_num_ports = 16;
cfg->fwd_address = strdup("");
if(!cfg->fwd_address) {
free(cfg);
return NULL;
}
cfg->fwd_port = UNBOUND_DNS_PORT;
return cfg;
}

View file

@ -53,6 +53,22 @@ struct config_file {
/** number of threads to create */
int num_threads;
/** port on which queries are answered. */
int port;
/** do ip4 query support. */
int do_ip4;
/** do ip6 query support. */
int do_ip6;
/** do udp query support. */
int do_udp;
/** do tcp query support. */
int do_tcp;
/** outgoing port range base number */
int outgoing_base_port;
/** outgoing port range number of ports (per thread, per if) */
int outgoing_num_ports;
/** forwarder address. string. If not NULL fwder mode is enabled. */
char* fwd_address;
/** forwarder port */

View file

@ -99,6 +99,15 @@ ANY [^\"\n\r\\]|\\.
server{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER;}
num-threads{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NUM_THREADS;}
verbosity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERBOSITY;}
port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PORT;}
outgoing-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_PORT;}
outgoing-range{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_RANGE;}
do-ip4{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_IP4;}
do-ip6{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_IP6;}
do-udp{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_UDP;}
do-tcp{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_TCP;}
forward-to{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_FORWARD_TO;}
forward-to-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_FORWARD_TO_PORT;}
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
/* Quoted strings. Strip leading and ending quotes */

View file

@ -67,7 +67,11 @@ static int server_settings_seen = 0;
%token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR
%token <str> STRING
%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS
%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
%token VAR_OUTGOING_PORT VAR_OUTGOING_RANGE
%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_FORWARD_TO VAR_FORWARD_TO_PORT
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -83,7 +87,10 @@ serverstart: VAR_SERVER
}
;
contents_server: contents_server content_server | ;
content_server: server_num_threads | server_verbosity;
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_num_threads: VAR_NUM_THREADS STRING
{
OUTYY(("P(server_num_threads:%s)\n", $2));
@ -102,7 +109,85 @@ server_verbosity: VAR_VERBOSITY STRING
free($2);
}
;
server_port: VAR_PORT STRING
{
OUTYY(("P(server_port:%s)\n", $2));
if(atoi($2) == 0)
yyerror("port number expected");
else cfg_parser->cfg->port = atoi($2);
free($2);
}
;
server_outgoing_port: VAR_OUTGOING_PORT STRING
{
OUTYY(("P(server_outgoing_port:%s)\n", $2));
if(atoi($2) == 0)
yyerror("port number expected");
else cfg_parser->cfg->outgoing_base_port = atoi($2);
free($2);
}
;
server_outgoing_range: VAR_OUTGOING_RANGE STRING
{
OUTYY(("P(server_outgoing_range:%s)\n", $2));
if(atoi($2) == 0)
yyerror("number expected");
else cfg_parser->cfg->outgoing_num_ports = atoi($2);
free($2);
}
;
server_do_ip4: VAR_DO_IP4 STRING
{
OUTYY(("P(server_do_ip4:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->do_ip4 = (strcmp($2, "yes")==0);
free($2);
}
;
server_do_ip6: VAR_DO_IP6 STRING
{
OUTYY(("P(server_do_ip6:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->do_ip6 = (strcmp($2, "yes")==0);
free($2);
}
;
server_do_udp: VAR_DO_UDP STRING
{
OUTYY(("P(server_do_udp:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->do_udp = (strcmp($2, "yes")==0);
free($2);
}
;
server_do_tcp: VAR_DO_TCP STRING
{
OUTYY(("P(server_do_tcp:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->do_tcp = (strcmp($2, "yes")==0);
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);
}
;
%%
/* parse helper routines could be here */