]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
module configuration option.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 1 Aug 2007 11:17:30 +0000 (11:17 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 1 Aug 2007 11:17:30 +0000 (11:17 +0000)
git-svn-id: file:///svn/unbound/trunk@468 be551aaa-1e26-0410-a405-d3ace91eadb9

18 files changed:
Makefile.in
configure.ac
daemon/daemon.c
doc/Changelog
doc/example.conf
doc/unbound.conf.5
iterator/iterator.c
services/mesh.c
services/mesh.h
services/outside_network.c
services/outside_network.h
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/module.h
validator/validator.c [new file with mode: 0644]
validator/validator.h [new file with mode: 0644]

index ada1c6c314d7278247e2b5d72e1e9a7253c3f698..5b9e9bc8a6abbfa8358d8a743eb5ada044a44e4c 100644 (file)
@@ -53,8 +53,8 @@ LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int
 INSTALL=$(srcdir)/install-sh
 
 COMMON_SRC=$(wildcard services/*.c services/cache/*.c util/*.c \
-       util/data/*.c util/storage/*.c iterator/*.c) util/configparser.c \
-       util/configlexer.c testcode/checklocks.c
+       util/data/*.c util/storage/*.c iterator/*.c validator/*.c) \
+       util/configparser.c util/configlexer.c testcode/checklocks.c
 COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o))
 COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS))
 UNITTEST_SRC=$(wildcard testcode/unit*.c) testcode/readhex.c $(COMMON_SRC)
index 61680f309f6604d69e86d9fa0cd8aecd847a4ac8..a35a0ec45c4c20665ab8af047d0fea560df30763 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.57)
 
-AC_INIT(unbound, 0.4, wouter@nlnetlabs.nl, unbound)
+AC_INIT(unbound, 0.5, wouter@nlnetlabs.nl, unbound)
 
 CFLAGS=
 AC_AIX
index f9873314e5712ece875a26452db979cc7d7cf4eb..b24a9f59f503420e14536cc24de886c0a22ca2fd 100644 (file)
@@ -54,6 +54,7 @@
 #include "services/cache/infra.h"
 #include "util/module.h"
 #include "iterator/iterator.h"
+#include "validator/validator.h"
 #include <signal.h>
 
 /** How many quit requests happened. */
@@ -148,6 +149,93 @@ daemon_open_shared_ports(struct daemon* daemon)
        return 1;
 }
 
+/** count number of modules (words) in the string */
+static int
+count_modules(const char* s)
+{
+       int num = 0;
+       if(!s)
+               return 0;
+       while(*s) {
+               /* skip whitespace */
+               while(*s && isspace(*s))
+                       s++;
+               if(*s && !isspace(*s)) {
+                       /* skip identifier */
+                       num++;
+                       while(*s && !isspace(*s))
+                               s++;
+               }
+       }
+       return num;
+}
+
+/**
+ * Get funcblock for module name
+ * @param str: string with module name. Advanced to next value.
+ * @return funcblock or NULL on error.
+ */
+static struct module_func_block*
+daemon_module_factory(const char** str)
+{
+       /* these are the modules available */
+       int num = 2;
+       const char* names[] = {"iterator", "validator", NULL};
+       struct module_func_block* (*fb[])(void) = 
+               {&iter_get_funcblock, &val_get_funcblock, NULL};
+
+       int i;
+       const char* s = *str;
+       while(*s && isspace(*s))
+               s++;
+       for(i=0; i<num; i++) {
+               if(strncmp(names[i], s, strlen(names[i])) == 0) {
+                       s += strlen(names[i]);
+                       *str = s;
+                       return (*fb[i])();
+               }
+       }
+       return NULL;
+}
+
+/**
+ * Read config file module settings and set up the modfunc block
+ * @param daemon: the daemon.
+ * @return false on error
+ */
+static int
+daemon_config_modules(struct daemon* daemon)
+{
+       const char* str = daemon->cfg->module_conf;
+       int i;
+       verbose(VERB_DETAIL, "module config: \"%s\"", str);
+       daemon->num_modules = count_modules(str);
+       if(daemon->num_modules == 0) {
+               log_err("error: no modules specified");
+               return 0;
+       }
+       if(daemon->num_modules > MAX_MODULE) {
+               log_err("error: too many modules (%d max %d)",
+                       daemon->num_modules, MAX_MODULE);
+               return 0;
+       }
+       daemon->modfunc = (struct module_func_block**)calloc((size_t)
+               daemon->num_modules, sizeof(struct module_func_block*));
+       if(!daemon->modfunc) {
+               log_err("out of memory");
+               return 0;
+       }
+       for(i=0; i<daemon->num_modules; i++) {
+               daemon->modfunc[i] = daemon_module_factory(&str);
+               if(!daemon->modfunc[i]) {
+                       log_err("Unknown value for first module in: '%s'",
+                               str);
+                       return 0;
+               }
+       }
+       return 1;
+}
+
 /**
  * Desetup the modules, deinit, delete.
  * @param daemon: the daemon.
@@ -174,13 +262,9 @@ static void daemon_setup_modules(struct daemon* daemon)
        if(daemon->num_modules != 0)
                daemon_desetup_modules(daemon);
        /* fixed setup of the modules */
-       daemon->num_modules = 1;
-       daemon->modfunc = (struct module_func_block**)calloc((size_t)
-               daemon->num_modules, sizeof(struct module_func_block*));
-       if(!daemon->modfunc) {
-               fatal_exit("malloc failure allocating function callbacks");
+       if(!daemon_config_modules(daemon)) {
+               fatal_exit("failed to setup modules");
        }
-       daemon->modfunc[0] = iter_get_funcblock();
        daemon->env->cfg = daemon->cfg;
        daemon->env->alloc = &daemon->superalloc;
        daemon->env->worker = NULL;
index 4a936b6d9879d5db51ade0f34ab2a74d743a1c0d..280d8bc4da158f8ba3c5d4b72427dbfed19bc1f3 100644 (file)
@@ -1,3 +1,8 @@
+1 August 2007: Wouter
+       - set version to 0.5
+       - module work for module to module interconnections.
+       - config of modules.
+
 31 July 2007: Wouter
        - updated plan
        - release 0.4 tag.
index def4e1bca76066284be6caefa2caa31183a923be..49c636cc0b6702b447e4bc8ff16446f2ac8a15e8 100644 (file)
@@ -147,6 +147,10 @@ server:
        # DNS port, use "1.2.3.4@123" to block port 123 for 1.2.3.4.
        # do-not-query-address: 127.0.0.1
        # do-not-query-address: ::1
+       
+       # module configuration of the server. A string with identifiers
+       # separated by spaces. "iterator" or "validator iterator"
+       # module-config: "validator iterator"
 
 # Stub zones.
 # Create entries like below, to make all queries for 'example.com' and 
index 5c82450754b867d28343634c575f8873876e20d9..3811b36879dd28ec520b23d255e22a07f627bdfb 100644 (file)
@@ -183,6 +183,11 @@ Will trust glue only if it is within the servers authority. Default is on.
 Do not query the given IP address. Can be IP4 or IP6. By default the
 DNS port is blocked for that address. Appending the character '@' and then
 the portnumber will block other port numbers. 
+.It \fBmodule-config:\fR <"module names">
+Module configuration, a list of module names separated by spaces, surround
+the string with quotes (""). The modules can be validator, iterator.
+Setting this to "iterator" will result in a non-validating server.
+Setting this to "validator iterator" will turn on validation.
 .El
 
 .Ss Stub Zone Options
index f2cff2b47fff2796bae21d5e423bc677038e0ccc..2234f065772113f1ff6f7d952ba19bea8325b974 100644 (file)
@@ -81,15 +81,14 @@ static void
 iter_deinit(struct module_env* env, int id)
 {
        struct iter_env* iter_env;
-       if(!env || !env->modinfo)
+       if(!env || !env->modinfo || !env->modinfo[id])
                return;
        iter_env = (struct iter_env*)env->modinfo[id];
        free(iter_env->target_fetch_policy);
        hints_delete(iter_env->hints);
        forwards_delete(iter_env->fwds);
        donotq_delete(iter_env->donotq);
-       if(iter_env)
-               free(iter_env);
+       free(iter_env);
 }
 
 /** new query for iterator */
@@ -1015,7 +1014,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
        outq = (*qstate->env->send_query)(
                iq->qchase.qname, iq->qchase.qname_len, 
                iq->qchase.qtype, iq->qchase.qclass, 
-               iq->chase_flags, 1, &target->addr, target->addrlen, qstate);
+               iq->chase_flags, EDNS_DO|BIT_CD, 
+               &target->addr, target->addrlen, qstate);
        if(!outq) {
                log_err("error sending query to auth server; skip this address");
                log_addr("error for address:", &target->addr, target->addrlen);
index 3d8c48ea955edbbdddcb61a3269b23115d44d22b..4abd77c9a044ae8c14ef1598636a822fde793370 100644 (file)
@@ -69,6 +69,11 @@ mesh_state_compare(const void* ap, const void* bp)
        if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD))
                return 1;
 
+       if((a->s.query_flags&BIT_CD) && !(b->s.query_flags&BIT_CD))
+               return -1;
+       if(!(a->s.query_flags&BIT_CD) && (b->s.query_flags&BIT_CD))
+               return 1;
+
        return query_info_compare(&a->s.qinfo, &b->s.qinfo);
 }
 
@@ -222,7 +227,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
                return NULL;
        }
        /* remove all weird bits from qflags */
-       mstate->s.query_flags = (qflags & BIT_RD);
+       mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD));
        mstate->s.reply = NULL;
        mstate->s.region = region;
        mstate->s.curmod = 0;
index dc260a615303e6e3d23550787688c717c8436668..82e1a92e43b9cd062ed4faebf4e69ef879c28f9e 100644 (file)
@@ -95,7 +95,7 @@ struct mesh_area {
 /**
  * A mesh query state
  * Unique per qname, qtype, qclass (from the qstate).
- * And RD flag; in case a client turns it off.
+ * And RD / CD flag; in case a client turns it off.
  * And priming queries are different from ordinary queries (because of hints).
  *
  * The entire structure is allocated in a region, this region is the qstate
@@ -226,7 +226,7 @@ void mesh_detach_subs(struct module_qstate* qstate);
  * @param qstate: the state to find mesh state, and that wants to receive
  *     the results from the new subquery.
  * @param qinfo: what to query for (copied).
- * @param qflags: what flags to use (RD flag or not).
+ * @param qflags: what flags to use (RD / CD flag or not).
  * @param prime: if it is a (stub) priming query.
  * @param newq: If the new subquery needs initialisation, it is returned,
  *     otherwise NULL is returned.
@@ -281,7 +281,7 @@ void mesh_state_delete(struct module_qstate* qstate);
  * Does not put the mesh state into rbtrees and so on.
  * @param env: module environment to set.
  * @param qinfo: query info that the mesh is for.
- * @param qflags: flags for query (RD flag).
+ * @param qflags: flags for query (RD / CD flag).
  * @param prime: if true, it is a priming query, set is_priming on mesh state.
  * @return: new mesh state or NULL on allocation error.
  */
@@ -301,7 +301,7 @@ void mesh_state_cleanup(struct mesh_state* mstate);
  *
  * @param mesh: the mesh area to look in.
  * @param qinfo: what query
- * @param qflags: if RD bit is set or not.
+ * @param qflags: if RD / CD bit is set or not.
  * @param prime: if it is a priming query.
  * @return: mesh state or NULL if not found.
  */
index da0aec649184d6451ce1a41e6b45492eff22ab1c..3cc81b9b07f82bb80c5fcd20529e677c5d60877b 100644 (file)
@@ -921,8 +921,10 @@ serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns)
                edns.edns_version = EDNS_ADVERTISED_VERSION;
                edns.udp_size = EDNS_ADVERTISED_SIZE;
                edns.bits = 0;
-               if(sq->dnssec)
+               if(sq->dnssec & EDNS_DO)
                        edns.bits = EDNS_DO;
+               if(sq->dnssec & BIT_CD)
+                       LDNS_CD_SET(ldns_buffer_begin(buff));
                attach_edns_record(buff, &edns);
        }
 }
index 8765c93e8631035e024349e17a34b7b0e54f82e6..06555f863769fb1108d62ac95a9619da0a440c3b 100644 (file)
@@ -210,7 +210,7 @@ struct serviced_query {
        uint8_t* qbuf;
        /** length of qbuf. */
        size_t qbuflen;
-       /** If an EDNS section is included, the DO bit will be turned on. */
+       /** If an EDNS section is included, the DO/CD bit will be turned on. */
        int dnssec;
        /** where to send it */
        struct sockaddr_storage addr;
@@ -337,6 +337,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
  * @param qclass: query class. (host format)
  * @param flags: flags u16 (host format), includes opcode, CD bit.
  * @param dnssec: if set, DO bit is set in EDNS queries.
+ *     If the value includes BIT_CD, CD bit is set when in EDNS queries.
+ *     If the value includes BIT_DO, DO bit is set when in EDNS queries.
  * @param callback: callback function.
  * @param callback_arg: user argument to callback function.
  * @param addr: to which server to send the query.
index ef5a9b225f52844def9bfbac582fba91b06da1ba..c803cebf26a3b8e99b9be4f5939b3a35bd6325cb 100644 (file)
@@ -111,6 +111,7 @@ config_create()
        cfg->hide_version = 0;
        cfg->identity = NULL;
        cfg->version = NULL;
+       if(!(cfg->module_conf = strdup("iterator"))) goto error_exit;
        return cfg;
 error_exit:
        config_delete(cfg); 
@@ -203,6 +204,7 @@ config_delete(struct config_file* cfg)
        config_delstrlist(cfg->donotqueryaddrs);
        free(cfg->identity);
        free(cfg->version);
+       free(cfg->module_conf);
        free(cfg);
 }
 
index 037695d13ab78d2bf33bbe23fd07238f9c4227f9..0a66e25e428d93cbb4022d3835855db825cdc19e 100644 (file)
@@ -135,6 +135,9 @@ struct config_file {
        char* identity;
        /** version, package version returned if "". */
        char* version;
+
+       /** the module configuration string */
+       char* module_conf;
        
        /** daemonize, i.e. fork into the background. */
        int do_daemonize;
index 1c6594f87b2cdc04af464a4aec822851d8e4cbe9..365b887b592317f09ce97829389d3d5cbf0067a0 100644 (file)
@@ -141,6 +141,7 @@ hide-identity{COLON}        { YDOUT; return VAR_HIDE_IDENTITY;}
 hide-version{COLON}     { YDOUT; return VAR_HIDE_VERSION;}
 identity{COLON}                { YDOUT; return VAR_IDENTITY;}
 version{COLON}         { YDOUT; return VAR_VERSION;}
+module-conf{COLON}             { YDOUT; return VAR_MODULE_CONF;}
 {NEWLINE}              { LEXOUT(("NL\n")); cfg_parser->line++;}
 
        /* Quoted strings. Strip leading and ending quotes */
index 56b94412f48e98b6cf8efd1087b566d703b72d0e..6e2e688752a433419b2d6535d491444e03443824 100644 (file)
@@ -79,7 +79,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
 %token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
 %token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
-%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE
+%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -112,7 +112,7 @@ content_server: server_num_threads | server_verbosity | server_port |
        server_harden_short_bufsize | server_harden_large_queries |
        server_do_not_query_address | server_hide_identity |
        server_hide_version | server_identity | server_version |
-       server_harden_glue
+       server_harden_glue | server_module_conf
        ;
 stubstart: VAR_STUB_ZONE
        {
@@ -462,6 +462,13 @@ server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING
                        yyerror("out of memory");
        }
        ;
+server_module_conf: VAR_MODULE_CONF STRING
+       {
+               OUTYY(("P(server_module_conf:%s)\n", $2));
+               free(cfg_parser->cfg->module_conf);
+               cfg_parser->cfg->module_conf = $2;
+       }
+       ;
 stub_name: VAR_NAME STRING
        {
                OUTYY(("P(name:%s)\n", $2));
index 687aea63e4c416fa4d8a1158d8072f8d18d04eec..f6d7f058f06f5e4dab3f300adc86f169e8a2d053 100644 (file)
@@ -58,7 +58,7 @@ struct mesh_area;
 struct mesh_state;
 
 /** Maximum number of modules in operation */
-#define MAX_MODULE 2
+#define MAX_MODULE 5
 
 /**
  * Module environment.
@@ -105,7 +105,9 @@ struct module_env {
         * @param qtype: query type. (host order)
         * @param qclass: query class. (host order)
         * @param flags: host order flags word, with opcode and CD bit.
-        * @param dnssec: if set, EDNS record will have DO bit set.
+        * @param dnssec: if set, EDNS record will have bits set.
+        *      If EDNS_DO bit is set, DO bit is set in EDNS records.
+        *      If BIT_CD is set, CD bit is set in queries with EDNS records.
         * @param addr: where to.
         * @param addrlen: length of addr.
         * @param q: wich query state to reactivate upon return.
@@ -143,7 +145,7 @@ struct module_env {
         * @param qstate: the state to find mesh state, and that wants to 
         *      receive the results from the new subquery.
         * @param qinfo: what to query for (copied).
-        * @param qflags: what flags to use (RD flag or not).
+        * @param qflags: what flags to use (RD, CD flag or not).
         * @param prime: if it is a (stub) priming query.
         * @param newq: If the new subquery needs initialisation, it is 
         *      returned, otherwise NULL is returned.
@@ -314,6 +316,10 @@ struct module_func_block {
         * @param ev: event that causes the module state machine to 
         *      (re-)activate.
         * @param qstate: the query state. 
+        *      Note that this method is not allowed to change the
+        *      query state 'identity', that is query info, qflags,
+        *      and priming status.
+        *      Attach a subquery to get results to a different query.
         * @param id: module id number that operate() is called on. 
         * @param outbound: if not NULL this event is due to the reply/timeout
         *      or error on this outbound query.
diff --git a/validator/validator.c b/validator/validator.c
new file mode 100644 (file)
index 0000000..adf472a
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * validator/validator.c - secure validator DNS query response module
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains a module that performs validation of DNS queries.
+ * According to RFC 4034.
+ */
+#include "config.h"
+#include "validator/validator.h"
+#include "util/module.h"
+#include "util/log.h"
+
+/** validator init */
+static int
+val_init(struct module_env* env, int id)
+{
+       struct val_env* val_env = (struct val_env*)calloc(1,
+       sizeof(struct val_env));
+       if(!val_env) {
+               log_err("malloc failure");
+               return 0;
+       }
+       env->modinfo[id] = (void*)val_env;
+       /*if(!val_apply_cfg(val_env, env->cfg)) {
+               log_err("validator: could not apply configuration settings.");
+               return 0;
+       }*/
+       return 1;
+}
+
+/** validator deinit */
+static void
+val_deinit(struct module_env* env, int id)
+{
+       struct val_env* val_env;
+       if(!env || !env->modinfo || !env->modinfo[id])
+               return;
+       val_env = (struct val_env*)env->modinfo[id];
+       free(val_env);
+}
+
+/** validator operate on a query */
+static void
+val_operate(struct module_qstate* qstate, enum module_ev event, int id,
+        struct outbound_entry* outbound)
+{
+       struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
+       struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id];
+       verbose(VERB_DETAIL, "validator[module %d] operate: extstate:%s "
+               "event:%s", id, strextstate(qstate->ext_state[id]), 
+               strmodulevent(event));
+       if(vq) log_query_info(VERB_DETAIL, "iterator operate: query",
+               &qstate->qinfo);
+       (void)ve;
+       (void)outbound;
+}
+
+/** validator cleanup query state */
+static void
+val_clear(struct module_qstate* qstate, int id)
+{
+       if(!qstate)
+               return;
+       /* everything is allocated in the region, so assign NULL */
+       qstate->minfo[id] = NULL;
+}
+
+/**
+ * The validator function block 
+ */
+static struct module_func_block val_block = {
+       "validator",
+       &val_init, &val_deinit, &val_operate, &val_clear
+};
+
+struct module_func_block* 
+val_get_funcblock()
+{
+       return &val_block;
+}
+
+const char* 
+val_state_to_string(enum val_state state)
+{
+       switch(state) {
+               case VAL_STATE_INIT: return "VAL_STATE_INIT";
+       }
+       return "UNKNOWN VALIDATOR STATE";
+}
diff --git a/validator/validator.h b/validator/validator.h
new file mode 100644 (file)
index 0000000..b25dfc1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * validator/validator.h - secure validator DNS query response module
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains a module that performs validation of DNS queries.
+ * According to RFC 4034.
+ */
+
+#ifndef VALIDATOR_VALIDATOR_H
+#define VALIDATOR_VALIDATOR_H
+struct module_func_block;
+
+/**
+ * Global state for the validator. 
+ */
+struct val_env {
+       /** global state placeholder */
+       int option;
+};
+
+/**
+ * State of the validator for a query.
+ */
+enum val_state {
+       /** initial state for validation */
+       VAL_STATE_INIT = 0
+};
+
+/**
+ * Per query state for the validator module.
+ */
+struct val_qstate {
+       /** 
+        * State of the validator module.
+        */
+       enum val_state state;
+};
+
+/**
+ * Get the validator function block.
+ * @return: function block with function pointers to validator methods.
+ */
+struct module_func_block* val_get_funcblock();
+
+/**
+ * Get validator state as a string
+ * @param state: to convert
+ * @return constant string that is printable.
+ */
+const char* val_state_to_string(enum val_state state);
+
+#endif /* VALIDATOR_VALIDATOR_H */