]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
config file is used.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 22 Feb 2007 13:36:29 +0000 (13:36 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 22 Feb 2007 13:36:29 +0000 (13:36 +0000)
git-svn-id: file:///svn/unbound/trunk@135 be551aaa-1e26-0410-a405-d3ace91eadb9

17 files changed:
configure.ac
daemon/unbound.c
daemon/worker.c
daemon/worker.h
doc/Changelog
doc/example.conf [new file with mode: 0644]
doc/unbound.8
doc/unbound.conf.5
services/listen_dnsport.c
services/listen_dnsport.h
testcode/fake_event.c
testdata/fwd_tcp.tpkg
testdata/fwd_udp.tpkg
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y

index 3ffe1cbcf19ba8034b997a9b880775a855c38131..fe6e1b19c0ba7d1e85b72d3237b3554564326fa6 100644 (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])
index 9abd10a4a9e01b06aaad7cf5638380019ae4b4af..06c0beb4e896f67146a7aab9948b5d7f440abd4d 100644 (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;
 }
index cd4b79a3cfa16cf3fb526dcf0df632702e9b18a5..65f8edb7553f451635548b16d115b32fa65c0a2f 100644 (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;
index f27371adffd5593602c479a024c164aff7ba9fb9..703e0805aeca8336fbe043d1de6f0d92e9191fb6 100644 (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 */
index 96f53ccb49e0406658e8512e763e332089f24454..43d0511a28022240cfebd9d148e22491b10ef35c 100644 (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.
diff --git a/doc/example.conf b/doc/example.conf
new file mode 100644 (file)
index 0000000..7a945ea
--- /dev/null
@@ -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
+
index af4cecff4a0916ced56bcd4f0b7a24e629fea58b..5b8cba8a62ca83de1d070ad111cfbc98dbe287bb 100644 (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
index 6dd4a0a684f05508a77dcbf650932b7ea9944d35..3dbbb50bf6e945a95dad7dd8e7c36cfb8087766f 100644 (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
index a24d55ff7f43ee6f6accb760373f7511902ca1fa..d9a7b889a62e933182807c73a1c5964ea58f6d6a 100644 (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;
index d07ac1eaf3840031e7d314e1c8838f55ed92d1f2..289c8709da4e69c8cc53b6bf06fdb05d1234d6e3 100644 (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);
 
index 5d3bd79cf4b425e9cc610307264c2a13c5685099..9a88c521b6e657e1dac7106484a38e5bfbf3af7a 100644 (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)
index 6b8cda115c1a7c2101a8b248d8014972eb49c9b0..f8d35662f04d65e7fcf12decc71d26c5f9d9293e 100644 (file)
Binary files a/testdata/fwd_tcp.tpkg and b/testdata/fwd_tcp.tpkg differ
index 57229abd86faed71461b683cbaa7b81e05371d78..8a079cdef0e6860f477bbe10ac9d82aaa145b0d7 100644 (file)
Binary files a/testdata/fwd_udp.tpkg and b/testdata/fwd_udp.tpkg differ
index 038e601a02dacbf54a94ea3b6299026d42ad736c..30d201b4fed6d19914f1ef3b5de5f7b2665f23d2 100644 (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;
 }
 
index f11c65a4f4c8105f9227657fdb2a39515f6271d7..8e00d32c837c3241800d03310d8123f76af3dd10 100644 (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 */
index 55bdb95e4d64c0c0850dd926d6251d587b4b8edf..8068da8c563c6b27026d4092b06975b54b2c1b56 100644 (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 */
index 2bffa5955186d6f967578e38534745a16960a94d..3632062b83b4b254fa96297b5597dc398d42d157 100644 (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 */