From: Wouter Wijngaards Date: Thu, 22 Feb 2007 13:36:29 +0000 (+0000) Subject: config file is used. X-Git-Tag: release-0.1~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=618ef6acbb14ad90d19196e9253b4b2180423705;p=thirdparty%2Funbound.git config file is used. git-svn-id: file:///svn/unbound/trunk@135 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/configure.ac b/configure.ac index 3ffe1cbcf..fe6e1b19c 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/daemon/unbound.c b/daemon/unbound.c index 9abd10a4a..06c0beb4e 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -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; } diff --git a/daemon/worker.c b/daemon/worker.c index cd4b79a3c..65f8edb75 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -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; diff --git a/daemon/worker.h b/daemon/worker.h index f27371adf..703e0805a 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -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 */ diff --git a/doc/Changelog b/doc/Changelog index 96f53ccb4..43d0511a2 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/doc/example.conf b/doc/example.conf new file mode 100644 index 000000000..7a945ea26 --- /dev/null +++ b/doc/example.conf @@ -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 + diff --git a/doc/unbound.8 b/doc/unbound.8 index af4cecff4..5b8cba8a6 100644 --- a/doc/unbound.8 +++ b/doc/unbound.8 @@ -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 diff --git a/doc/unbound.conf.5 b/doc/unbound.conf.5 index 6dd4a0a68..3dbbb50bf 100644 --- a/doc/unbound.conf.5 +++ b/doc/unbound.conf.5 @@ -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 The number of threads to create to serve clients. Use 1 for no threading. +.It \fBport:\fR +The port number, default 53, on which the server responds to queries. +.It \fBoutgoing-port:\fR +The starting port number where the outgoing query port range is allocated. +Default is 1053. +.It \fBoutgoing-range:\fR +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 +Enable or disable whether ip4 queries are answered. Default is yes. +.It \fBdo-ip6:\fR +Enable or disable whether ip6 queries are answered. Default is yes. +.It \fBdo-udp:\fR +Enable or disable whether UDP queries are answered. Default is yes. +.It \fBdo-tcp:\fR +Enable or disable whether TCP queries are answered. Default is yes. +.It \fBforward-to:\fR +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 +The port on which the remote server is running that answers forwarded queries. +Default is 53. .Sh FILES .Bl -tag -width indent diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index a24d55ff7..d9a7b889a 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -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; diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h index d07ac1eaf..289c8709d 100644 --- a/services/listen_dnsport.h +++ b/services/listen_dnsport.h @@ -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); diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 5d3bd79cf..9a88c521b 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -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) diff --git a/testdata/fwd_tcp.tpkg b/testdata/fwd_tcp.tpkg index 6b8cda115..f8d35662f 100644 Binary files a/testdata/fwd_tcp.tpkg and b/testdata/fwd_tcp.tpkg differ diff --git a/testdata/fwd_udp.tpkg b/testdata/fwd_udp.tpkg index 57229abd8..8a079cdef 100644 Binary files a/testdata/fwd_udp.tpkg and b/testdata/fwd_udp.tpkg differ diff --git a/util/config_file.c b/util/config_file.c index 038e601a0..30d201b4f 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -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; } diff --git a/util/config_file.h b/util/config_file.h index f11c65a4f..8e00d32c8 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -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 */ diff --git a/util/configlexer.lex b/util/configlexer.lex index 55bdb95e4..8068da8c5 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -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 */ diff --git a/util/configparser.y b/util/configparser.y index 2bffa5955..3632062b8 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -67,7 +67,11 @@ static int server_settings_seen = 0; %token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR %token 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 */