Download | Plain Text | No Line Numbers
- --- unbound-1.5.4.old/Makefile.in 2015-05-01 14:36:16.000000000 +0200
- +++ unbound-1.5.4/Makefile.in 2015-09-10 00:57:00.123513866 +0200
- @@ -110,7 +110,7 @@
- validator/validator.c validator/val_kcache.c validator/val_kentry.c \
- validator/val_neg.c validator/val_nsec3.c validator/val_nsec.c \
- validator/val_secalgo.c validator/val_sigcrypt.c \
- -validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC) $(DNSTAP_SRC)
- +validator/val_utils.c dns64/dns64.c rewrite/rewrite.c $(CHECKLOCK_SRC) $(DNSTAP_SRC)
- COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
- msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
- iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
- @@ -120,7 +120,7 @@
- random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
- slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
- validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
- -val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo \
- +val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo rewrite.lo \
- $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
- COMMON_OBJ=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
- outside_network.lo
- @@ -715,7 +715,7 @@
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
- - $(srcdir)/validator/val_utils.h
- + $(srcdir)/validator/val_utils.h $(srcdir)/rewrite/rewrite.h
- outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/netevent.h
- @@ -760,7 +760,7 @@
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
- - $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h
- + $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/rewrite/rewrite.h
- locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
- log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
- mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
- @@ -893,6 +893,12 @@
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
- +rewrite.lo rewrite.o: $(srcdir)/rewrite/rewrite.c config.h $(srcdir)/rewrite/rewrite.h $(srcdir)/util/module.h \
- + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
- + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/services/cache/dns.h $(srcdir)/util/config_file.h \
- + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- + $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h
- checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h
- dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.h \
- --- unbound-1.5.4.old/services/modstack.c 2014-10-13 11:23:12.000000000 +0200
- +++ unbound-1.5.4/services/modstack.c 2015-09-07 02:52:32.379311303 +0200
- @@ -51,6 +51,8 @@
- #include "pythonmod/pythonmod.h"
- #endif
-
- +#include "rewrite/rewrite.h"
- +
- /** count number of modules (words) in the string */
- static int
- count_modules(const char* s)
- @@ -123,6 +125,7 @@
- #endif
- "validator",
- "iterator",
- + "rewrite",
- NULL};
- return names;
- }
- @@ -141,6 +144,7 @@
- #endif
- &val_get_funcblock,
- &iter_get_funcblock,
- + &rewrite_get_funcblock,
- NULL};
- return fb;
- }
- --- unbound-1.5.4.old/util/config_file.c 2015-05-29 16:51:36.000000000 +0200
- +++ unbound-1.5.4/util/config_file.c 2015-09-08 16:56:47.429577213 +0200
- @@ -237,6 +237,7 @@
- cfg->ratelimit_for_domain = NULL;
- cfg->ratelimit_below_domain = NULL;
- cfg->ratelimit_factor = 10;
- + cfg->rewrite_domain = NULL;
- return cfg;
- error_exit:
- config_delete(cfg);
- @@ -740,6 +741,7 @@
- else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
- else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
- else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
- + else O_LS2(opt, "rewrite-domain", rewrite_domain)
- /* not here:
- * outgoing-permit, outgoing-avoid - have list of ports
- * local-zone - zones and nodefault variables
- @@ -951,6 +953,7 @@
- free(cfg->dnstap_version);
- config_deldblstrlist(cfg->ratelimit_for_domain);
- config_deldblstrlist(cfg->ratelimit_below_domain);
- + config_deldblstrlist(cfg->rewrite_domain);
- free(cfg);
- }
-
- --- unbound-1.5.4.old/util/config_file.h 2015-05-29 16:51:36.000000000 +0200
- +++ unbound-1.5.4/util/config_file.h 2015-09-08 16:56:54.600699034 +0200
- @@ -362,6 +362,8 @@
- struct config_str2list* ratelimit_below_domain;
- /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
- int ratelimit_factor;
- + /** from/to-pairs of domains to rewrite */
- + struct config_str2list* rewrite_domain;
- };
-
- /** from cfg username, after daemonise setup performed */
- --- unbound-1.5.4.old/util/configlexer.lex 2015-05-29 16:51:36.000000000 +0200
- +++ unbound-1.5.4/util/configlexer.lex 2015-09-09 01:22:48.646754172 +0200
- @@ -358,6 +358,7 @@
- ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
- ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
- ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
- +rewrite-domain{COLON} { YDVAR(2, VAR_REWRITE_DOMAIN) }
- <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
-
- /* Quoted strings. Strip leading and ending quotes */
- --- unbound-1.5.4.old/util/configparser.y 2015-05-29 16:51:36.000000000 +0200
- +++ unbound-1.5.4/util/configparser.y 2015-09-08 16:57:19.412120548 +0200
- @@ -122,6 +122,7 @@
- %token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
- %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR
- %token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL
- +%token VAR_REWRITE_DOMAIN
-
- %%
- toplevelvars: /* empty */ | toplevelvars toplevelvar ;
- @@ -185,7 +186,8 @@
- server_ip_transparent | server_ratelimit | server_ratelimit_slabs |
- server_ratelimit_size | server_ratelimit_for_domain |
- server_ratelimit_below_domain | server_ratelimit_factor |
- - server_caps_whitelist | server_cache_max_negative_ttl
- + server_caps_whitelist | server_cache_max_negative_ttl |
- + server_rewrite_domain
- ;
- stubstart: VAR_STUB_ZONE
- {
- @@ -1308,6 +1310,15 @@
- free($2);
- }
- ;
- +server_rewrite_domain: VAR_REWRITE_DOMAIN STRING_ARG STRING_ARG
- + {
- + OUTYY(("P(server_rewrite_domain:%s %s)\n", $2, $3));
- + if(!cfg_str2list_insert(&cfg_parser->cfg->
- + rewrite_domain, $2, $3))
- + fatal_exit("out of memory adding "
- + "rewrite-domain");
- + }
- + ;
- stub_name: VAR_NAME STRING_ARG
- {
- OUTYY(("P(name:%s)\n", $2));
- --- unbound-1.5.4.old/util/fptr_wlist.c 2015-04-10 11:59:57.000000000 +0200
- +++ unbound-1.5.4/util/fptr_wlist.c 2015-09-07 02:54:02.514863282 +0200
- @@ -79,6 +79,8 @@
- #include "pythonmod/pythonmod.h"
- #endif
-
- +#include "rewrite/rewrite.h"
- +
- int
- fptr_whitelist_comm_point(comm_point_callback_t *fptr)
- {
- @@ -315,6 +317,7 @@
- #ifdef WITH_PYTHONMODULE
- else if(fptr == &pythonmod_init) return 1;
- #endif
- + else if(fptr == &rewrite_init) return 1;
- return 0;
- }
-
- @@ -327,6 +330,7 @@
- #ifdef WITH_PYTHONMODULE
- else if(fptr == &pythonmod_deinit) return 1;
- #endif
- + else if(fptr == &rewrite_deinit) return 1;
- return 0;
- }
-
- @@ -340,6 +344,7 @@
- #ifdef WITH_PYTHONMODULE
- else if(fptr == &pythonmod_operate) return 1;
- #endif
- + else if(fptr == &rewrite_operate) return 1;
- return 0;
- }
-
- @@ -353,6 +358,7 @@
- #ifdef WITH_PYTHONMODULE
- else if(fptr == &pythonmod_inform_super) return 1;
- #endif
- + else if(fptr == &rewrite_inform_super) return 1;
- return 0;
- }
-
- @@ -366,6 +372,7 @@
- #ifdef WITH_PYTHONMODULE
- else if(fptr == &pythonmod_clear) return 1;
- #endif
- + else if(fptr == &rewrite_clear) return 1;
- return 0;
- }
-
- @@ -378,6 +385,7 @@
- #ifdef WITH_PYTHONMODULE
- else if(fptr == &pythonmod_get_mem) return 1;
- #endif
- + else if(fptr == &rewrite_get_mem) return 1;
- return 0;
- }
-
- --- /dev/null 1970-01-01 01:00:00.000000000 +0100
- +++ unbound-1.5.4/rewrite/rewrite.c 2015-09-10 14:47:56.866731134 +0200
- @@ -0,0 +1,446 @@
- +/*
- + * Copyright (c) 2015, Manuel Mausz. 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 Viagénie 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.
- + */
- +
- +#include "config.h"
- +#include "rewrite/rewrite.h"
- +#include "sldns/str2wire.h"
- +#include "services/cache/dns.h"
- +#include "util/config_file.h"
- +#include "util/fptr_wlist.h"
- +#include "util/regional.h"
- +#include "util/data/dname.h"
- +
- +/**
- + * This structure contains module configuration information. One instance of
- + * this structure exists per instance of the module. Normally there is only one
- + * instance of the module.
- + */
- +struct rewrite_domain {
- + uint8_t* dname;
- + size_t dname_len;
- + int labs;
- +};
- +
- +struct rewrite_env {
- + struct rewrite_domain from;
- + struct rewrite_domain to;
- + struct rewrite_env *next;
- +};
- +
- +enum rewrite_qstate {
- + REWRITE_IS_SUBQUERY = 1,
- +};
- +
- +/**
- + * This function applies the configuration found in the parsed configuration
- + * file \a cfg to this instance of the rewrite module
- + *
- + * \param rewrite_env Module-specific global parameters.
- + * \param cfg Parsed configuration file.
- + */
- +static int
- +rewrite_apply_cfg(struct rewrite_env** rewrite_env, struct config_file* cfg)
- +{
- + struct rewrite_env** current = rewrite_env;
- + struct config_str2list* p;
- + *current = NULL;
- + for(p = cfg->rewrite_domain; p; p = p->next) {
- + struct rewrite_env* entry =
- + (struct rewrite_env*)calloc(1, sizeof(struct rewrite_env));
- + if (!(entry->from.dname = sldns_str2wire_dname(p->str, &entry->from.dname_len))) {
- + log_err("rewrite-domain: cannot parse source field: %s", p->str);
- + return 0;
- + }
- + entry->from.labs = dname_count_labels(entry->from.dname);
- + if (!(entry->to.dname = sldns_str2wire_dname(p->str2, &entry->to.dname_len))) {
- + log_err("rewrite-domain: cannot parse target field: %s", p->str2);
- + return 0;
- + }
- + entry->to.labs = dname_count_labels(entry->to.dname);
- + if (dname_subdomain_c(entry->to.dname, entry->from.dname)) {
- + log_err("rewrite-domain: target %s cannot be a sub-domain of source %s",
- + p->str, p->str2);
- + return 0;
- + }
- + *current = entry;
- + current = &entry->next;
- + verbose(VERB_ALGO, "rewrite: added %s => %s", p->str, p->str2);
- + }
- + return 1;
- +}
- +
- +/**
- + * Initializes this instance of the rewrite module.
- + *
- + * \param env Global state of all module instances.
- + * \param id This instance's ID number.
- + */
- +int
- +rewrite_init(struct module_env* env, int id)
- +{
- + struct rewrite_env* rewrite_env;
- + if (!rewrite_apply_cfg(&rewrite_env, env->cfg)) {
- + log_err("rewrite: could not apply configuration settings.");
- + return 0;
- + }
- + env->modinfo[id] = (void*)rewrite_env;
- + return 1;
- +}
- +
- +/**
- + * Deinitializes this instance of the rewrite module.
- + *
- + * \param env Global state of all module instances.
- + * \param id This instance's ID number.
- + */
- +void
- +rewrite_deinit(struct module_env* env, int id)
- +{
- + if (!env)
- + return;
- +
- + struct rewrite_env* cur = (struct rewrite_env*)env->modinfo[id];
- + struct rewrite_env* next;
- + while(cur) {
- + next = cur->next;
- + free(cur->from.dname);
- + free(cur->to.dname);
- + free(cur);
- + cur = next;
- + }
- +
- + env->modinfo[id] = NULL;
- +}
- +
- +static int
- +dname_is_subdomain(uint8_t* dname, size_t dname_len,
- + struct rewrite_domain* dom)
- +{
- + return (dname_len > dom->dname_len
- + && dname_strict_subdomain(dname, dname_count_labels(dname),
- + dom->dname, dom->labs));
- +}
- +
- +
- +static struct rewrite_domain
- +rewrite_dname(uint8_t* dname, size_t dname_len, struct rewrite_domain* from,
- + struct rewrite_domain* to, struct regional *region)
- +{
- + struct rewrite_domain new = { NULL, 0 };
- + size_t sub_len = dname_len - from->dname_len;
- + new.dname_len = sub_len + to->dname_len;
- +
- + if (!(new.dname = regional_alloc(region, new.dname_len)))
- + return new;
- + memcpy(new.dname, dname, sub_len);
- + memcpy(new.dname + sub_len, to->dname, to->dname_len);
- +
- + char buf[LDNS_MAX_DOMAINLEN+1];
- + dname_str((uint8_t*)new.dname, buf);
- + verbose(VERB_ALGO, "rewrite: name rewritten to %s", buf);
- +
- + return new;
- +}
- +
- +/**
- + * Handles the "pass" event for a query. This event is received when a new query
- + * is received by this module. The query may have been generated internally by
- + * another module, in which case we don't want to do any special processing
- + * (this is an interesting discussion topic), or it may be brand new, e.g.
- + * received over a socket, in which case we do want to do rewrite processing.
- + *
- + * \param qstate A structure representing the state of the query that has just
- + * received the "pass" event.
- + * \param id This module's instance ID.
- + *
- + * \return The new state of the query.
- + */
- +static enum module_ext_state
- +handle_event_pass(struct module_qstate* qstate, int id)
- +{
- + if (qstate->minfo[id]) {
- + /* we're either inside our sub-query ... */
- + if ((uintptr_t)qstate->minfo[id] == REWRITE_IS_SUBQUERY)
- + return module_wait_module;
- + /* ... or called again after the sub-query has finished */
- + else
- + return module_finished;
- + }
- +
- + struct rewrite_env* rewrite_env;
- + for(rewrite_env = (struct rewrite_env*)qstate->env->modinfo[id];
- + rewrite_env; rewrite_env = rewrite_env->next) {
- + if (dname_is_subdomain(qstate->qinfo.qname, qstate->qinfo.qname_len,
- + &rewrite_env->from)) {
- + struct rewrite_domain new = rewrite_dname(
- + qstate->qinfo.qname, qstate->qinfo.qname_len,
- + &rewrite_env->from, &rewrite_env->to,
- + qstate->region);
- + if (!new.dname)
- + return module_error;
- +
- + qstate->minfo[id] = (void*)rewrite_env;
- +
- + /* start our sub query */
- + struct module_qstate* subq = NULL;
- + struct query_info qinfo = qstate->qinfo;
- + qinfo.qname = new.dname;
- + qinfo.qname_len = new.dname_len;
- + fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
- + if (!(*qstate->env->attach_sub)(qstate, &qinfo,
- + qstate->query_flags, 0, 0, &subq))
- + return module_error;
- + if (subq) {
- + subq->curmod = id;
- + subq->ext_state[id] = module_state_initial;
- + subq->minfo[id] = (void*)REWRITE_IS_SUBQUERY;
- + }
- + return module_wait_subquery;
- + }
- + }
- +
- + /* otherwise, pass request to next module. */
- + return module_wait_module;
- +}
- +
- +/**
- + * This is the module's main() function. It gets called each time a query
- + * receives an event which we may need to handle. We respond by updating the
- + * state of the query.
- + *
- + * \param qstate Structure containing the state of the query.
- + * \param event Event that has just been received.
- + * \param id This module's instance ID.
- + * \param outbound State of a DNS query on an authoritative server. We never do
- + * our own queries ourselves (other modules do it for us), so
- + * this is unused.
- + */
- +void
- +rewrite_operate(struct module_qstate* qstate, enum module_ev event, int id,
- + struct outbound_entry* outbound)
- +{
- + (void)outbound;
- + switch(event) {
- + case module_event_new:
- + case module_event_pass:
- + qstate->ext_state[id] = handle_event_pass(qstate, id);
- + break;
- + case module_event_moddone:
- + default:
- + qstate->ext_state[id] = module_finished;
- + break;
- + }
- +}
- +
- +/** allocate (special) rrset keys, return 0 on error */
- +static int
- +repinfo_alloc_rrset_keys(struct reply_info* rep, struct regional* region)
- +{
- + size_t i;
- + for(i = 0; i < rep->rrset_count; i++) {
- + rep->rrsets[i] = (struct ub_packed_rrset_key*)regional_alloc_zero(
- + region, sizeof(struct ub_packed_rrset_key));
- + if (!rep->rrsets[i])
- + return 0;
- + rep->rrsets[i]->entry.key = rep->rrsets[i];
- + rep->rrsets[i]->entry.data = NULL;
- + }
- + return 1;
- +}
- +
- +/** copy rrsets from replyinfo to dest replyinfo */
- +static int
- +repinfo_copy_rrsets(struct reply_info* dest, struct reply_info* from,
- + struct regional* region, struct rewrite_env* rewrite_env)
- +{
- + size_t i, s;
- + struct packed_rrset_data* fd, *dd;
- + struct ub_packed_rrset_key* fk, *dk;
- +
- + for(i = 0; i < dest->rrset_count; i++) {
- + fk = from->rrsets[i];
- + dk = dest->rrsets[i];
- + fd = (struct packed_rrset_data*)fk->entry.data;
- + dk->rk = fk->rk;
- + dk->id = fk->id;
- +
- + if (dname_is_subdomain(fk->rk.dname, fk->rk.dname_len,
- + &rewrite_env->to)) {
- + struct rewrite_domain new = rewrite_dname(fk->rk.dname,
- + fk->rk.dname_len, &rewrite_env->to,
- + &rewrite_env->from, region);
- + if (!new.dname)
- + return 0;
- + dk->rk.dname = new.dname;
- + dk->rk.dname_len = new.dname_len;
- + dk->entry.hash = rrset_key_hash(&dk->rk);
- + }
- + else {
- + dk->entry.hash = fk->entry.hash;
- + dk->rk.dname = (uint8_t*)regional_alloc_init(region,
- + fk->rk.dname, fk->rk.dname_len);
- + if(!dk->rk.dname)
- + return 0;
- + }
- + s = packed_rrset_sizeof(fd);
- + dd = (struct packed_rrset_data*)regional_alloc_init(region,
- + fd, s);
- + if (!dd)
- + return 0;
- + packed_rrset_ptr_fixup(dd);
- + dk->entry.data = (void*)dd;
- + }
- +
- + return 1;
- +}
- +
- +static int
- +rewrite_copy_rrsets(struct module_qstate* from, int id,
- + struct module_qstate* dest)
- +{
- + struct rewrite_env* rewrite_env = (struct rewrite_env*)dest->minfo[id];
- +
- + /* build the actual reply */
- + struct reply_info* frep = from->return_msg->rep;
- + struct reply_info* drep = construct_reply_info_base(dest->region,
- + frep->flags, frep->qdcount, frep->ttl,
- + frep->prefetch_ttl, frep->an_numrrsets,
- + frep->ns_numrrsets, frep->ar_numrrsets,
- + frep->rrset_count, frep->security);
- + if (!drep)
- + return 0;
- +
- + /* allocate ub_key structures special or not */
- + if (!repinfo_alloc_rrset_keys(drep, dest->region))
- + return 0;
- +
- + /* copy rrsets from replyinfo to dest and replace dname */
- + if (!repinfo_copy_rrsets(drep, frep, dest->region, rewrite_env))
- + return 0;
- +
- + if (!dest->return_msg) {
- + dest->return_msg = (struct dns_msg*)regional_alloc(
- + dest->region, sizeof(struct dns_msg));
- + if (!dest->return_msg)
- + return 0;
- + dest->return_msg->qinfo = dest->qinfo;
- + }
- + dest->return_msg->rep = drep;
- + return 1;
- +}
- +
- +
- +/**
- + * This function is called when a sub-query finishes to inform the parent query.
- + *
- + * We issue two kinds of sub-queries: PTR and A.
- + *
- + * \param qstate State of the sub-query.
- + * \param id This module's instance ID.
- + * \param super State of the super-query.
- + */
- +void
- +rewrite_inform_super(struct module_qstate* qstate, int id,
- + struct module_qstate* super)
- +{
- + log_query_info(VERB_ALGO, "rewrite: inform_super, sub is",
- + &qstate->qinfo);
- + log_query_info(VERB_ALGO, "super is", &super->qinfo);
- +
- + /* sub-query has finished */
- + qstate->minfo[id] = NULL;
- +
- + /* if there is no successful answer, we're done */
- + if (qstate->return_rcode != LDNS_RCODE_NOERROR
- + || !qstate->return_msg
- + || !qstate->return_msg->rep)
- + return;
- +
- + /* copy and rewrite rrsets */
- + if (!rewrite_copy_rrsets(qstate, id, super))
- + log_err("rewrite: cannot copy rrsets from subquery");
- +
- + /* store the generated response in cache */
- + if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
- + 0, 0, 0, NULL, super->query_flags))
- + log_err("out of memory");
- +
- +}
- +
- +/**
- + * Clear module-specific data from query state. Since we do not allocate memory,
- + * it's just a matter of setting a pointer to NULL.
- + *
- + * \param qstate Query state.
- + * \param id This module's instance ID.
- + */
- +void
- +rewrite_clear(struct module_qstate* qstate, int id)
- +{
- + qstate->minfo[id] = NULL;
- +}
- +
- +/**
- + * Returns the amount of global memory that this module uses, not including
- + * per-query data.
- + *
- + * \param env Module environment.
- + * \param id This module's instance ID.
- + */
- +size_t
- +rewrite_get_mem(struct module_env* env, int id)
- +{
- + size_t mem = 0;
- + struct rewrite_env* cur;
- + for(cur = (struct rewrite_env*)env->modinfo[id]; cur; cur = cur->next) {
- + mem += sizeof(*cur);
- + mem += cur->from.dname_len * sizeof(*cur->from.dname);
- + mem += cur->to.dname_len * sizeof(*cur->to.dname);
- + }
- + return mem;
- +}
- +
- +/**
- + * The rewrite function block.
- + */
- +static struct module_func_block rewrite_block = {
- + "rewrite",
- + &rewrite_init, &rewrite_deinit, &rewrite_operate, &rewrite_inform_super,
- + &rewrite_clear, &rewrite_get_mem
- +};
- +
- +struct module_func_block *
- +rewrite_get_funcblock()
- +{
- + return &rewrite_block;
- +}
- --- /dev/null 1970-01-01 01:00:00.000000000 +0100
- +++ unbound-1.5.4/rewrite/rewrite.h 2015-09-08 00:36:02.520835089 +0200
- @@ -0,0 +1,63 @@
- +/*
- + * Copyright (c) 2015, Manuel Mausz. 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.
- + */
- +
- +#ifndef REWRITE_REWRITE_H
- +#define REWRITE_REWRITE_H
- +#include "util/module.h"
- +
- +/**
- + * Get the rewrite function block.
- + * @return: function block with function pointers to rewrite methods.
- + */
- +struct module_func_block *rewrite_get_funcblock(void);
- +
- +/** rewrite init */
- +int rewrite_init(struct module_env* env, int id);
- +
- +/** rewrite deinit */
- +void rewrite_deinit(struct module_env* env, int id);
- +
- +/** rewrite operate on a query */
- +void rewrite_operate(struct module_qstate* qstate, enum module_ev event, int id,
- + struct outbound_entry* outbound);
- +
- +void rewrite_inform_super(struct module_qstate* qstate, int id,
- + struct module_qstate* super);
- +
- +/** rewrite cleanup query state */
- +void rewrite_clear(struct module_qstate* qstate, int id);
- +
- +/** rewrite alloc size routine */
- +size_t rewrite_get_mem(struct module_env* env, int id);
- +
- +#endif
-