dns64 patch for unbound

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

dns64 patch for unbound

Ryan McBride-3
This is the patch from http://ecdysis.viagenie.ca/, updated for
unbound-1.4.9. Needed for nat64 in pf being tested now, but also useful
if you're running nat64 on another box.

ok?

Index: Makefile
===================================================================
RCS file: /cvs/ports/net/unbound/Makefile,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile
--- Makefile 24 Mar 2011 20:30:42 -0000 1.28
+++ Makefile 13 May 2011 22:14:35 -0000
@@ -3,6 +3,7 @@
 COMMENT= validating DNS resolver
 
 DISTNAME= unbound-1.4.9
+REVISION= 0
 CATEGORIES= net
 
 MASTER_SITES= http://www.unbound.net/downloads/
@@ -36,7 +37,16 @@ CONFIGURE_ARGS+= --with-ssl=/usr \
  --with-pidfile=/var/unbound/var/run/unbound.pid \
  --with-conf-file=/var/unbound/etc/unbound.conf \
  --with-username=_unbound
+
+FLAVORS= dns64
+FLAVOR?=
+
 USE_GROFF = Yes
+
+.if ${FLAVOR:L:Mdns64}
+post-patch:
+  patch -p0 -d ${WRKSRC} < ${FILESDIR}/ecdysis-unbound.patch
+.endif
 
 post-install:
  ${INSTALL_DATA_DIR} ${PREFIX}/share/examples/unbound
--- /dev/null Sat May 14 07:14:55 2011
+++ files/ecdysis-unbound.patch Sat May 14 06:12:54 2011
@@ -0,0 +1,1159 @@
+--- Makefile.in.orig Sat May 14 06:00:54 2011
++++ Makefile.in Sat May 14 06:01:09 2011
+@@ -92,7 +92,8 @@ endif
+ COMMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/services/*.c \
+ $(srcdir)/services/cache/*.c $(srcdir)/util/*.c \
+ $(srcdir)/util/data/*.c $(srcdir)/util/storage/*.c \
+- $(srcdir)/iterator/*.c $(srcdir)/validator/*.c $(PYTHONMOD_SRC))) \
++ $(srcdir)/dns64/*.c $(srcdir)/iterator/*.c $(srcdir)/validator/*.c \
++ $(PYTHONMOD_SRC))) \
+ util/configparser.c util/configlexer.c $(CHECKLOCK_SRC)
+ COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.lo))
+ COMPAT_SRC=$(addprefix compat/,$(LIBOBJS:.o=.c))
+--- /dev/null Sat May 14 06:12:54 2011
++++ dns64/dns64.c Sat May 14 06:01:09 2011
+@@ -0,0 +1,865 @@
++/*
++ * iterator/iterator.h - DNS64 module
++ *
++ * Copyright (c) 2009, Viagénie. 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.
++ */
++
++/**
++ * \file
++ *
++ * This file contains a module that performs DNS64 query processing.
++ */
++
++#include <config.h>
++#include "dns64/dns64.h"
++#include "services/cache/dns.h"
++#include "services/cache/rrset.h"
++#include "util/config_file.h"
++#include "util/data/msgreply.h"
++#include "util/fptr_wlist.h"
++#include "util/net_help.h"
++#include "util/regional.h"
++
++/******************************************************************************
++ *                                                                            *
++ *                             STATIC CONSTANTS                               *
++ *                                                                            *
++ ******************************************************************************/
++
++/**
++ * This is the default DNS64 prefix that is used whent he dns64 module is listed
++ * in module-config but when the dns64-prefix variable is not present.
++ *
++ * It will be change when/if IANA assigns a well-known prefix for DNS64.
++ */
++static const char DEFAULT_DNS64_PREFIX[] = "DEAD:BEEF::/96";
++
++/**
++ * Maximum length of a domain name in a PTR query in the .in-addr.arpa tree.
++ */
++static const int MAX_PTR_QNAME_IPV4 = 30;
++
++/**
++ * Per-query module-specific state. This is usually a dynamically-allocated
++ * structure, but in our case we only need to store one variable describing the
++ * state the query is in. So we repurpose the minfo pointer by storing an
++ * integer in there.
++ */
++enum dns64_qstate {
++    DNS64_INTERNAL_QUERY,    /**< Internally-generated query, no DNS64
++                                  processing. */
++    DNS64_NEW_QUERY,         /**< Query for which we're the first module in
++                                  line. */
++    DNS64_SUBQUERY_FINISHED  /**< Query for which we generated a sub-query, and
++                                  for which this sub-query is finished. */
++};
++
++
++/******************************************************************************
++ *                                                                            *
++ *                                 STRUCTURES                                 *
++ *                                                                            *
++ ******************************************************************************/
++
++/**
++ * 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 dns64_env {
++    /**
++     * DNS64 prefix address. We're using a full sockaddr instead of just an
++     * in6_addr because we can reuse Unbound's generic string parsing functions.
++     * It will always contain a sockaddr_in6, and only the sin6_addr member will
++     * ever be used.
++     */
++    struct sockaddr_storage prefix_addr;
++
++    /**
++     * This is always sizeof(sockaddr_in6).
++     */
++    socklen_t prefix_addrlen;
++
++    /**
++     * This is the CIDR length of the prefix. It needs to be between 0 and 96.
++     */
++    int prefix_net;
++};
++
++
++/******************************************************************************
++ *                                                                            *
++ *                             UTILITY FUNCTIONS                              *
++ *                                                                            *
++ ******************************************************************************/
++
++/**
++ * Generic macro for swapping two variables.
++ *
++ * \param t Type of the variables. (e.g. int)
++ * \param a First variable.
++ * \param b Second variable.
++ *
++ * \warning Do not attempt something foolish such as swap(int,a++,b++)!
++ */
++#define swap(t,a,b) do {t x = a; a = b; b = x;} while(0)
++
++/**
++ * Reverses a string.
++ *
++ * \param begin Points to the first character of the string.
++ * \param end   Points one past the last character of the string.
++ */
++static void
++reverse(char* begin, char* end)
++{
++    while ( begin < --end ) {
++        swap(char, *begin, *end);
++        ++begin;
++    }
++}
++
++/**
++ * Convert an unsigned integer to a string. The point of this function is that
++ * of being faster than sprintf().
++ *
++ * \param n The number to be converted.
++ * \param s The result will be written here. Must be large enough, be careful!
++ *
++ * \return The number of characters written.
++ */
++static int
++uitoa(unsigned n, char* s)
++{
++    char* ss = s;
++    do {
++        *ss++ = '0' + n % 10;
++    } while (n /= 10);
++    reverse(s, ss);
++    return ss - s;
++}
++
++/**
++ * Extract an IPv4 address embedded in the IPv6 address \a ipv6 at offset \a
++ * offset (in bits). Note that bits are not necessarily aligned on bytes so we
++ * need to be careful.
++ *
++ * \param ipv6   IPv6 address represented as a 128-bit array in big-endian
++ *               order.
++ * \param offset Index of the MSB of the IPv4 address embedded in the IPv6
++ *               address.
++ */
++static uint32_t
++extract_ipv4(const uint8_t ipv6[16], const int offset)
++{
++    uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
++                  | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
++                  | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
++                  | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
++    if (offset/8+4 < 16)
++        ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
++    return ipv4;
++}
++
++/**
++ * Builds the PTR query name corresponding to an IPv4 address. For example,
++ * given the number 3,464,175,361, this will build the string
++ * "\03206\03123\0231\011\07in-addr\04arpa".
++ *
++ * \param ipv4 IPv4 address represented as an unsigned 32-bit number.
++ * \param ptr  The result will be written here. Must be large enough, be
++ *             careful!
++ *
++ * \return The number of characters written.
++ */
++static int
++ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
++{
++    static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
++    int i;
++    char* c = ptr;
++
++    for (i = 0; i < 4; ++i) {
++        *c = uitoa(ipv4 % 256, c + 1);
++        c += *c + 1;
++        ipv4 /= 256;
++    }
++
++    strcpy(c, IPV4_PTR_SUFFIX);
++
++    return c + sizeof(IPV4_PTR_SUFFIX) - ptr;
++}
++
++/**
++ * Converts an IPv6-related domain name string from a PTR query into an IPv6
++ * address represented as a 128-bit array.
++ *
++ * \param ptr  The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa")
++ * \param ipv6 The result will be written here, in network byte order.
++ *
++ * \return 1 on success, 0 on failure.
++ */
++static int
++ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
++{
++    int i;
++
++    for (i = 0; i < 64; i++) {
++        int x;
++
++        if (ptr[i++] != 1)
++            return 0;
++
++        if (ptr[i] >= '0' && ptr[i] <= '9') {
++            x = ptr[i] - '0';
++        } else if (ptr[i] >= 'a' && ptr[i] <= 'f') {
++            x = ptr[i] - 'a' + 10;
++        } else if (ptr[i] >= 'A' && ptr[i] <= 'F') {
++            x = ptr[i] - 'A' + 10;
++        } else {
++            return 0;
++        }
++
++        ipv6[15-i/4] |= x << (2 * ((i-1) % 4));
++    }
++
++    return 1;
++}
++
++/**
++ * Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
++ *
++ * \param prefix_addr DNS64 prefix address.
++ * \param prefix_net  CIDR length of the DNS64 prefix. Must be between 0 and 96.
++ * \param a           IPv4 address.
++ * \param aaaa        IPv6 address. The result will be written here.
++ */
++static void
++synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
++        const uint8_t a[4], uint8_t aaaa[16])
++{
++    memcpy(aaaa, prefix_addr, 16);
++    aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8);
++    aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8);
++    aaaa[prefix_net/8+1] |= a[1] >> (0+prefix_net%8);
++    aaaa[prefix_net/8+2] |= a[1] << (8-prefix_net%8);
++    aaaa[prefix_net/8+2] |= a[2] >> (0+prefix_net%8);
++    aaaa[prefix_net/8+3] |= a[2] << (8-prefix_net%8);
++    aaaa[prefix_net/8+3] |= a[3] >> (0+prefix_net%8);
++    if (prefix_net/8/4 < 16)  /* <-- my beautiful symmetry is destroyed! */
++    aaaa[prefix_net/8+4] |= a[3] << (8-prefix_net%8);
++}
++
++
++/******************************************************************************
++ *                                                                            *
++ *                           DNS64 MODULE FUNCTIONS                           *
++ *                                                                            *
++ ******************************************************************************/
++
++/**
++ * This function applies the configuration found in the parsed configuration
++ * file \a cfg to this instance of the dns64 module. Currently only the DNS64
++ * prefix (a.k.a. Pref64) is configurable.
++ *
++ * \param dns64_env Module-specific global parameters.
++ * \param cfg       Parsed configuration file.
++ */
++static int
++dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
++{
++    verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
++    if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
++                DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
++                &dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
++        log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
++        return 0;
++    }
++    if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
++        log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
++        return 0;
++    }
++    if (dns64_env->prefix_net < 0 || dns64_env->prefix_net > 96) {
++        log_err("dns64-prefix length it not between 0 and 96: %s",
++                cfg->dns64_prefix);
++        return 0;
++    }
++    return 1;
++}
++
++/**
++ * Initializes this instance of the dns64 module.
++ *
++ * \param env Global state of all module instances.
++ * \param id  This instance's ID number.
++ */
++int
++dns64_init(struct module_env* env, int id)
++{
++    struct dns64_env* dns64_env =
++        (struct dns64_env*)calloc(1, sizeof(struct dns64_env));
++    if (!dns64_env) {
++        log_err("malloc failure");
++        return 0;
++    }
++ env->modinfo[id] = (void*)dns64_env;
++    if (!dns64_apply_cfg(dns64_env, env->cfg)) {
++        log_err("dns64: could not apply configuration settings.");
++        return 0;
++    }
++ return 1;
++}
++
++/**
++ * Deinitializes this instance of the dns64 module.
++ *
++ * \param env Global state of all module instances.
++ * \param id  This instance's ID number.
++ */
++void
++dns64_deinit(struct module_env* env, int id)
++{
++    if (!env)
++        return;
++    free(env->modinfo[id]);
++    env->modinfo[id] = NULL;
++}
++
++/**
++ * Handle PTR queries for IPv6 addresses. If the address belongs to the DNS64
++ * prefix, we must do a PTR query for the corresponding IPv4 address instead.
++ *
++ * \param qstate Query state structure.
++ * \param id     This module instance's ID number.
++ *
++ * \return The new state of the query.
++ */
++static enum module_ext_state
++handle_ipv6_ptr(struct module_qstate* qstate, int id)
++{
++    struct dns64_env* dns64_env = (struct dns64_env*)qstate->env->modinfo[id];
++    struct module_qstate* subq = NULL;
++    struct query_info qinfo;
++    struct sockaddr_in6 sin6;
++
++    /* Convert the PTR query string to an IPv6 address. */
++    memset(&sin6, 0, sizeof(sin6));
++    sin6.sin6_family = AF_INET6;
++    if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr))
++        return module_wait_module;  /* Let other module handle this. */
++
++    /*
++     * If this IPv6 address is not part of our DNS64 prefix, then we don't need
++     * to do anything. Let another module handle the query.
++     */
++    if (!addr_in_common((struct sockaddr_storage*)&sin6, 128,
++                &dns64_env->prefix_addr, dns64_env->prefix_net,
++                sizeof(sin6)) == dns64_env->prefix_net)
++        return module_wait_module;
++
++    verbose(VERB_ALGO, "dns64: rewrite PTR record");
++
++    /*
++     * Create a new PTR query info for the domain name corresponding to the IPv4
++     * address corresponding to the IPv6 address corresponding to the original
++     * PTR query domain name.
++     */
++    qinfo = qstate->qinfo;
++    if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4)))
++        return module_error;
++    qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr,
++                dns64_env->prefix_net), (char*)qinfo.qname);
++
++    /* Create the new sub-query. */
++    fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
++    if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
++                &subq))
++        return module_error;
++    if (subq) {
++        subq->curmod = id;
++        subq->ext_state[id] = module_state_initial;
++        subq->minfo[id] = NULL;
++    }
++
++    return module_wait_subquery;
++}
++
++/** 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++) {
++ if(region) {
++ rep->rrsets[i] = (struct ub_packed_rrset_key*)
++ regional_alloc(region,
++ sizeof(struct ub_packed_rrset_key));
++ if(rep->rrsets[i]) {
++ memset(rep->rrsets[i], 0,
++ sizeof(struct ub_packed_rrset_key));
++ rep->rrsets[i]->entry.key = rep->rrsets[i];
++ }
++ }
++ else return 0;/* rep->rrsets[i] = alloc_special_obtain(alloc);*/
++ if(!rep->rrsets[i])
++ return 0;
++ rep->rrsets[i]->entry.data = NULL;
++ }
++ return 1;
++}
++
++static enum module_ext_state
++generate_type_A_query(struct module_qstate* qstate, int id)
++{
++ struct module_qstate* subq = NULL;
++ struct query_info qinfo;
++
++ verbose(VERB_ALGO, "dns64: query A record");
++
++ /* Create a new query info. */
++ qinfo = qstate->qinfo;
++ qinfo.qtype = LDNS_RR_TYPE_A;
++
++ /* Start the sub-query. */
++ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
++ if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
++       &subq))
++ {
++ verbose(VERB_ALGO, "dns64: sub-query creation failed");
++ return module_error;
++ }
++ if (subq) {
++ subq->curmod = id;
++ subq->ext_state[id] = module_state_initial;
++ subq->minfo[id] = NULL;
++ }
++
++ return module_wait_subquery;
++}
++
++/**
++ * 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 apply DNS64 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 ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
++            && qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
++            && qstate->qinfo.qname_len == 74
++            && !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
++        /* Handle PTR queries for IPv6 addresses. */
++        return handle_ipv6_ptr(qstate, id);
++
++ if (qstate->env->cfg->dns64_synthall &&
++    (uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
++    && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
++ return generate_type_A_query(qstate, id);
++
++    /* We are finished when our sub-query is finished. */
++ if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
++ return module_finished;
++
++    /* Otherwise, pass request to next module. */
++    verbose(VERB_ALGO, "dns64: pass to next module");
++    return module_wait_module;
++}
++
++/**
++ * Handles the "done" event for a query. We need to analyze the response and
++ * maybe issue a new sub-query for the A record.
++ *
++ * \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_moddone(struct module_qstate* qstate, int id)
++{
++    /*
++     * In many cases we have nothing special to do. From most to least common:
++     *
++     *   - An internal query.
++     *   - A query for a record type other than AAAA.
++     *   - An AAAA query for which an error was returned.
++     *   - A successful AAAA query with an answer.
++     */
++ if (qstate->minfo[id] == DNS64_INTERNAL_QUERY
++            || qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
++    || qstate->return_rcode != LDNS_RCODE_NOERROR  
++    || (qstate->return_msg &&
++    qstate->return_msg->rep &&
++    reply_find_answer_rrset(&qstate->qinfo,
++    qstate->return_msg->rep)))
++ return module_finished;
++
++ return generate_type_A_query(qstate, id);
++}
++
++/**
++ * 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
++dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
++ struct outbound_entry* ATTR_UNUSED(outbound))
++{
++ verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
++ id, strextstate(qstate->ext_state[id]),
++ strmodulevent(event));
++ log_query_info(VERB_QUERY, "dns64 operate: query", &qstate->qinfo);
++
++ switch(event) {
++ case module_event_new:
++ /* Tag this query as being new and fall through. */
++ qstate->minfo[id] = (void*)DNS64_NEW_QUERY;
++ case module_event_pass:
++ qstate->ext_state[id] = handle_event_pass(qstate, id);
++ break;
++ case module_event_moddone:
++ qstate->ext_state[id] = handle_event_moddone(qstate, id);
++ break;
++ default:
++ qstate->ext_state[id] = module_finished;
++ break;
++ }
++}
++
++static void
++dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
++      const struct packed_rrset_data* fd,
++      struct ub_packed_rrset_key *dk,
++      struct packed_rrset_data **dd_out, struct regional *region,
++      struct dns64_env* dns64_env )
++{
++ struct packed_rrset_data *dd;
++ size_t i;
++ /*
++ * Create synthesized AAAA RR set data. We need to allocated extra memory
++ * for the RRs themselves. Each RR has a length, TTL, pointer to wireformat
++ * data, 2 bytes of data length, and 16 bytes of IPv6 address.
++ */
++ if (!(dd = *dd_out = regional_alloc(region,
++  sizeof(struct packed_rrset_data)
++  + fd->count * (sizeof(size_t) + sizeof(uint32_t) +
++     sizeof(uint8_t*) + 2 + 16)))) {
++ log_err("out of memory");
++ return;
++ }
++
++ /* Copy attributes from A RR set. */
++ dd->ttl = fd->ttl;
++ dd->count = fd->count;
++ dd->rrsig_count = 0;
++ dd->trust = fd->trust;
++ dd->security = fd->security;
++
++ /*
++ * Synthesize AAAA records. Adjust pointers in structure.
++ */
++ dd->rr_len =
++    (size_t*)((uint8_t*)dd + sizeof(struct packed_rrset_data));
++ dd->rr_data = (uint8_t**)&dd->rr_len[dd->count];
++ dd->rr_ttl = (uint32_t*)&dd->rr_data[dd->count];
++ for(i = 0; i < fd->count; ++i) {
++ if (fd->rr_len[i] != 6 || fd->rr_data[i][0] != 0
++    || fd->rr_data[i][1] != 4)
++ return;
++ dd->rr_len[i] = 18;
++ dd->rr_data[i] =
++    (uint8_t*)&dd->rr_ttl[dd->count] + 18*i;
++ dd->rr_data[i][0] = 0;
++ dd->rr_data[i][1] = 16;
++ synthesize_aaaa(
++ ((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
++ dns64_env->prefix_net, &fd->rr_data[i][2],
++ &dd->rr_data[i][2] );
++ dd->rr_ttl[i] = fd->rr_ttl[i];
++ }
++
++ /*
++ * Create synthesized AAAA RR set key. This is mostly just bookkeeping,
++ * nothing interesting here.
++ */
++ if(!dk) {
++ log_err("no key");
++ return;
++ }
++
++ dk->rk.dname = (uint8_t*)regional_alloc_init(region,
++     fk->rk.dname, fk->rk.dname_len);
++
++ if(!dk->rk.dname) {
++ log_err("out of memory");
++ return;
++ }
++
++ dk->rk.type = htons(LDNS_RR_TYPE_AAAA);
++ memset(&dk->entry, 0, sizeof(dk->entry));
++ dk->entry.key = dk;
++ dk->entry.hash = rrset_key_hash(&dk->rk);
++ dk->entry.data = dd;
++
++}
++
++/**
++ * Synthesize an AAAA RR set from an A sub-query's answer and add it to the
++ * original empty response.
++ *
++ * \param id     This module's instance ID.
++ * \param answer The answer RR set located in the sub-query's response.
++ * \param super  Original AAAA query.
++ * \param qstate A query.
++ */
++static void
++dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate)
++{
++ struct dns64_env* dns64_env = (struct dns64_env*)super->env->modinfo[id];
++ struct reply_info *rep, *cp;
++ size_t i, s;
++ struct packed_rrset_data* fd, *dd;
++ struct ub_packed_rrset_key* fk, *dk;
++
++ verbose(VERB_ALGO, "converting A answers to AAAA answers");
++
++ log_assert(super->region);
++ log_assert(qstate->return_msg);
++ log_assert(qstate->return_msg->rep);
++ log_assert(qstate->region);
++
++ /* If dns64-synthall is enabled, return_msg is not initialized */
++ if(!super->return_msg) {
++ super->return_msg = (struct dns_msg*)regional_alloc(
++    super->region, sizeof(struct dns_msg));
++ if(!super->return_msg)
++ return;
++ memset(super->return_msg, 0, sizeof(*super->return_msg));
++ super->return_msg->qinfo = super->qinfo;
++ }
++
++ rep = qstate->return_msg->rep;
++
++ /*
++ * Build the actual reply.
++ */
++ cp = construct_reply_info_base(qstate->region, rep->flags, rep->qdcount,
++ rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets,
++ rep->ar_numrrsets, rep->rrset_count, rep->security);
++ if(!cp)
++ return;
++
++ /* allocate ub_key structures special or not */
++ if(!repinfo_alloc_rrset_keys(cp, qstate->region)) {
++ return;
++ }
++
++ /* copy everything and replace A by AAAA */
++ for(i=0; i<cp->rrset_count; i++) {
++ fk = rep->rrsets[i];
++ dk = cp->rrsets[i];
++ fd = (struct packed_rrset_data*)fk->entry.data;
++ dk->entry.hash = fk->entry.hash;
++ dk->rk = fk->rk;
++ dk->id = fk->id;
++
++ if(i<rep->an_numrrsets && fk->rk.type == htons(LDNS_RR_TYPE_A)) {
++ dns64_synth_aaaa_data(fk, fd, dk, &dd, super->region, dns64_env);
++ /* Delete negative AAAA record from cache stored by
++ * the iterator module */
++ rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
++   dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
++   LDNS_RR_CLASS_IN, 0);
++ } else {
++ dk->rk.dname = (uint8_t*)regional_alloc_init(qstate->region,
++ fk->rk.dname, fk->rk.dname_len);
++
++ if(!dk->rk.dname)
++ return;
++
++ s = packed_rrset_sizeof(fd);
++ dd = (struct packed_rrset_data*)regional_alloc_init(
++ qstate->region, fd, s);
++
++ if(!dd)
++ return;
++ }
++
++ packed_rrset_ptr_fixup(dd);
++ dk->entry.data = (void*)dd;
++ }
++
++ /* Commit changes. */
++ super->return_msg->rep = cp;
++}
++
++/**
++ * Generate a response for the original IPv6 PTR query based on an IPv4 PTR
++ * sub-query's response.
++ *
++ * \param qstate IPv4 PTR sub-query.
++ * \param super  Original IPv6 PTR query.
++ */
++static void
++dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
++{
++    struct ub_packed_rrset_key* answer;
++
++    verbose(VERB_ALGO, "adjusting PTR reply");
++
++    /* Copy the sub-query's reply to the parent. */
++    if (!(super->return_msg = (struct dns_msg*)regional_alloc(super->region,
++                    sizeof(struct dns_msg))))
++        return;
++    super->return_msg->qinfo = super->qinfo;
++    super->return_msg->rep = reply_info_copy(qstate->return_msg->rep, NULL,
++            super->region);
++
++    /*
++     * Adjust the domain name of the answer RR set so that it matches the
++     * initial query's domain name.
++     */
++    answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
++    log_assert(answer);
++    answer->rk.dname = super->qinfo.qname;
++    answer->rk.dname_len = super->qinfo.qname_len;
++}
++
++/**
++ * 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
++dns64_inform_super(struct module_qstate* qstate, int id,
++ struct module_qstate* super)
++{
++ log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
++       &qstate->qinfo);
++ log_query_info(VERB_ALGO, "super is", &super->qinfo);
++
++ /*
++ * Signal that the sub-query is finished, no matter whether we are
++ * successful or not. This lets the state machine terminate.
++ */
++ super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED;
++
++ /* If there is no successful answer, we're done. */
++ if (qstate->return_rcode != LDNS_RCODE_NOERROR
++    || !qstate->return_msg
++    || !qstate->return_msg->rep
++    || !reply_find_answer_rrset(&qstate->qinfo,
++ qstate->return_msg->rep))
++ return;
++
++ /* Generate a response suitable for the original query. */
++ if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) {
++ dns64_adjust_a(id, super, qstate);
++ } else {
++ log_assert(qstate->qinfo.qtype == LDNS_RR_TYPE_PTR);
++ dns64_adjust_ptr(qstate, super);
++ }
++
++ /* Store the generated response in cache. */
++ if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, 0, 0))
++ 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
++dns64_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
++dns64_get_mem(struct module_env* env, int id)
++{
++    struct dns64_env* dns64_env = (struct dns64_env*)env->modinfo[id];
++    if (!dns64_env)
++        return 0;
++    return sizeof(*dns64_env);
++}
++
++/**
++ * The dns64 function block.
++ */
++static struct module_func_block dns64_block = {
++ "dns64",
++ &dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
++ &dns64_clear, &dns64_get_mem
++};
++
++/**
++ * Function for returning the above function block.
++ */
++struct module_func_block*
++dns64_get_funcblock()
++{
++ return &dns64_block;
++}
+--- /dev/null Sat May 14 06:12:54 2011
++++ dns64/dns64.h Sat May 14 06:01:09 2011
+@@ -0,0 +1,71 @@
++/*
++ * dns64/dns64.h - DNS64 module
++ *
++ * Copyright (c) 2009, Viagénie. 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 DNS64 query processing.
++ */
++
++#ifndef DNS64_DNS64_H
++#define DNS64_DNS64_H
++#include "util/module.h"
++
++/**
++ * Get the dns64 function block.
++ * @return: function block with function pointers to dns64 methods.
++ */
++struct module_func_block* dns64_get_funcblock();
++
++/** dns64 init */
++int dns64_init(struct module_env* env, int id);
++
++/** dns64 deinit */
++void dns64_deinit(struct module_env* env, int id);
++
++/** dns64 operate on a query */
++void dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
++ struct outbound_entry* outbound);
++
++void dns64_inform_super(struct module_qstate* qstate, int id,
++    struct module_qstate* super);
++
++/** dns64 cleanup query state */
++void dns64_clear(struct module_qstate* qstate, int id);
++
++/** dns64 alloc size routine */
++size_t dns64_get_mem(struct module_env* env, int id);
++
++#endif /* DNS64_DNS64_H */
+--- /dev/null Sat May 14 06:12:54 2011
++++ doc/README.DNS64 Sat May 14 06:01:09 2011
+@@ -0,0 +1,26 @@
++To enable DNS64 functionality in Unbound, two directives in unbound.conf must
++be edited:
++
++1. The "module-config" directive must start with "dns64". For example:
++
++    module-config: "dns64 validator iterator"
++
++If you're not using DNSSEC then you may remove "validator".
++
++2. The "dns64-prefix" directive indicates your DNS64 prefix. For example:
++
++    dns64-prefix: 64:FF9B::/96
++
++The prefix must be a /96 or shorter.
++
++To test that things are working right, perform a query against Unbound for a
++domain name for which no AAAA record exists. You should see a AAAA record in
++the answer section. The corresponding IPv6 address will be inside the DNS64
++prefix. For example:
++
++    $ unbound -c unbound.conf
++    $ dig @localhost jazz-v4.viagenie.ca aaaa
++    [...]
++    ;; ANSWER SECTION:
++    jazz-v4.viagenie.ca.        86400   IN      AAAA    64:ff9b::ce7b:1f02
++
+--- doc/example.conf.in.orig Sat May 14 06:00:54 2011
++++ doc/example.conf.in Sat May 14 06:01:09 2011
+@@ -41,7 +41,7 @@ server:
+
+ # enable this feature to copy the source address of queries to reply.
+ # Socket options are not supported on all platforms. experimental.
+- # interface-automatic: no
++ interface-automatic: yes
+
+ # port to answer queries from
+ # port: 53
+@@ -166,6 +166,8 @@ server:
+ # access-control: ::0/0 refuse
+ # access-control: ::1 allow
+ # access-control: ::ffff:127.0.0.1 allow
++ access-control: ::0/0 allow
++        access-control: 0.0.0.0/0 allow
+
+ # if given, a chroot(2) is done to the given directory.
+ # i.e. you can chroot to the working directory, for example,
+@@ -310,8 +312,8 @@ server:
+ # prefetch-key: no
+
+ # module configuration of the server. A string with identifiers
+- # separated by spaces. "iterator" or "validator iterator"
+- # module-config: "validator iterator"
++ # separated by spaces. Syntax: [dns64] [validator] iterator
++ module-config: "dns64 iterator"
+
+ # File with trusted keys, kept uptodate using RFC5011 probes,
+ # initial file like trust-anchor-file, then it stores metadata.
+@@ -447,6 +449,9 @@ server:
+ # You can also add PTR records using local-data directly, but then
+ # you need to do the reverse notation yourself.
+ # local-data-ptr: "192.0.2.3 www.example.com"
++
++ # DNS64 prefix. Must be specified when DNS64 is in use.
++ dns64-prefix: 64:ff9b::0/96
+
+ # Python config section. To enable:
+ # o use --with-pythonmodule to configure before compiling.
+--- services/modstack.c.orig Sat Mar 13 00:17:48 2010
++++ services/modstack.c Sat May 14 06:01:09 2011
+@@ -43,6 +43,7 @@
+ #include "services/modstack.h"
+ #include "util/module.h"
+ #include "util/fptr_wlist.h"
++#include "dns64/dns64.h"
+ #include "iterator/iterator.h"
+ #include "validator/validator.h"
+
+@@ -116,6 +117,7 @@ module_list_avail(void)
+ {
+         /* these are the modules available */
+         static const char* names[] = {
++ "dns64",
+ #ifdef WITH_PYTHONMODULE
+ "python",
+ #endif
+@@ -133,6 +135,7 @@ static fbgetfunctype*
+ module_funcs_avail(void)
+ {
+         static struct module_func_block* (*fb[])(void) = {
++ &dns64_get_funcblock,
+ #ifdef WITH_PYTHONMODULE
+ &pythonmod_get_funcblock,
+ #endif
+--- util/config_file.h.orig Thu Nov 18 17:49:15 2010
++++ util/config_file.h Sat May 14 06:01:09 2011
+@@ -279,6 +279,12 @@ struct config_file {
+
+ /** daemonize, i.e. fork into the background. */
+ int do_daemonize;
++
++ /** DNS64 prefix */
++ char* dns64_prefix;
++
++ /** Synthetize all AAAA record despite the presence of an authoritative one */
++ int dns64_synthall;
+ };
+
+ /**
+--- util/configlexer.lex.orig Thu Nov 18 17:49:15 2010
++++ util/configlexer.lex Sat May 14 06:01:09 2011
+@@ -232,6 +232,8 @@ control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_F
+ python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) }
+ python{COLON} { YDVAR(0, VAR_PYTHON) }
+ domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) }
++dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
++dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
+ <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
+
+ /* Quoted strings. Strip leading and ending quotes */
+--- util/data/msgreply.c.orig Fri Aug 20 22:30:41 2010
++++ util/data/msgreply.c Sat May 14 06:01:09 2011
+@@ -77,7 +77,7 @@ parse_create_qinfo(ldns_buffer* pkt, struct msg_parse*
+ }
+
+ /** constructor for replyinfo */
+-static struct reply_info*
++struct reply_info*
+ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
+ uint32_t ttl, uint32_t prettl, size_t an, size_t ns, size_t ar,
+ size_t total, enum sec_status sec)
+--- util/data/msgreply.h.orig Fri Aug 20 22:30:41 2010
++++ util/data/msgreply.h Sat May 14 06:01:09 2011
+@@ -191,6 +191,11 @@ struct msgreply_entry {
+ struct lruhash_entry entry;
+ };
+
++struct reply_info*
++construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
++ uint32_t ttl, uint32_t prettl, size_t an, size_t ns, size_t ar,
++ size_t total, enum sec_status sec);
++
+ /**
+  * Parse wire query into a queryinfo structure, return 0 on parse error.
+  * initialises the (prealloced) queryinfo structure as well.
+--- util/fptr_wlist.c.orig Fri Aug 20 22:30:41 2010
++++ util/fptr_wlist.c Sat May 14 06:01:09 2011
+@@ -53,6 +53,7 @@
+ #include "services/localzone.h"
+ #include "services/cache/infra.h"
+ #include "services/cache/rrset.h"
++#include "dns64/dns64.h"
+ #include "iterator/iterator.h"
+ #include "iterator/iter_fwd.h"
+ #include "validator/validator.h"
+@@ -296,6 +297,7 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env*
+ {
+ if(fptr == &iter_init) return 1;
+ else if(fptr == &val_init) return 1;
++ else if(fptr == &dns64_init) return 1;
+ #ifdef WITH_PYTHONMODULE
+ else if(fptr == &pythonmod_init) return 1;
+ #endif
+@@ -307,6 +309,7 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_e
+ {
+ if(fptr == &iter_deinit) return 1;
+ else if(fptr == &val_deinit) return 1;
++ else if(fptr == &dns64_deinit) return 1;
+ #ifdef WITH_PYTHONMODULE
+ else if(fptr == &pythonmod_deinit) return 1;
+ #endif
+@@ -319,6 +322,7 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_
+ {
+ if(fptr == &iter_operate) return 1;
+ else if(fptr == &val_operate) return 1;
++ else if(fptr == &dns64_operate) return 1;
+ #ifdef WITH_PYTHONMODULE
+ else if(fptr == &pythonmod_operate) return 1;
+ #endif
+@@ -331,6 +335,7 @@ fptr_whitelist_mod_inform_super(void (*fptr)(
+ {
+ if(fptr == &iter_inform_super) return 1;
+ else if(fptr == &val_inform_super) return 1;
++ else if(fptr == &dns64_inform_super) return 1;
+ #ifdef WITH_PYTHONMODULE
+ else if(fptr == &pythonmod_inform_super) return 1;
+ #endif
+@@ -343,6 +348,7 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qs
+ {
+ if(fptr == &iter_clear) return 1;
+ else if(fptr == &val_clear) return 1;
++ else if(fptr == &dns64_clear) return 1;
+ #ifdef WITH_PYTHONMODULE
+ else if(fptr == &pythonmod_clear) return 1;
+ #endif
+@@ -354,6 +360,7 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct modul
+ {
+ if(fptr == &iter_get_mem) return 1;
+ else if(fptr == &val_get_mem) return 1;
++ else if(fptr == &dns64_get_mem) return 1;
+ #ifdef WITH_PYTHONMODULE
+ else if(fptr == &pythonmod_get_mem) return 1;
+ #endif

Reply | Threaded
Open this post in threaded view
|

Re: dns64 patch for unbound

Stuart Henderson
On 2011-05-13, Ryan McBride <[hidden email]> wrote:
> This is the patch from http://ecdysis.viagenie.ca/, updated for
> unbound-1.4.9. Needed for nat64 in pf being tested now, but also useful
> if you're running nat64 on another box.

I'd prefer to download the patchset rather than include it in filesdir:

Index: Makefile
===================================================================
RCS file: /cvs/ports/net/unbound/Makefile,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile
--- Makefile 24 Mar 2011 20:30:42 -0000 1.28
+++ Makefile 14 May 2011 07:30:49 -0000
@@ -3,9 +3,11 @@
 COMMENT= validating DNS resolver
 
 DISTNAME= unbound-1.4.9
+REVISION= 0
 CATEGORIES= net
 
 MASTER_SITES= http://www.unbound.net/downloads/
+MASTER_SITES0= http://spacehopper.org/mirrors/
 HOMEPAGE= http://www.unbound.net/
 
 MAINTAINER=     Jakob Schlyter <[hidden email]>
@@ -36,7 +38,17 @@ CONFIGURE_ARGS+= --with-ssl=/usr \
  --with-pidfile=/var/unbound/var/run/unbound.pid \
  --with-conf-file=/var/unbound/etc/unbound.conf \
  --with-username=_unbound
+
+FLAVORS= dns64
+FLAVOR?=
+
 USE_GROFF = Yes
+
+.if ${FLAVOR:L:Mdns64}
+PATCHFILES= ecdysis-unbound.patch:0
+.else
+SUPDISTFILES= ecdysis-unbound.patch:0
+.endif
 
 post-install:
  ${INSTALL_DATA_DIR} ${PREFIX}/share/examples/unbound
Index: distinfo
===================================================================
RCS file: /cvs/ports/net/unbound/distinfo,v
retrieving revision 1.19
diff -u -p -r1.19 distinfo
--- distinfo 24 Mar 2011 20:30:42 -0000 1.19
+++ distinfo 14 May 2011 07:30:49 -0000
@@ -1,5 +1,10 @@
+MD5 (ecdysis-unbound.patch) = o8UHbvy/JnkVFJlj6ob+0Q==
 MD5 (unbound-1.4.9.tar.gz) = cHnnUhDGVnYdOASp8qx7nw==
+RMD160 (ecdysis-unbound.patch) = HQLVt7HQe0XKCmYqWkzk1ROs/kk=
 RMD160 (unbound-1.4.9.tar.gz) = nDTFX3dvRQavt3XI9E34SmSFQHM=
+SHA1 (ecdysis-unbound.patch) = dukezXPLc00fwgyG/fMzP48jYz4=
 SHA1 (unbound-1.4.9.tar.gz) = 8qx7TvHRszDi3V4u7etv0ruthHg=
+SHA256 (ecdysis-unbound.patch) = kCVFYZXldjEwvha0jLp3xKHYfYUcATeR2LEP7N/6zUg=
 SHA256 (unbound-1.4.9.tar.gz) = 2guYn+jPEOQ0gTQ4c+rt9gvvY75HPIbXPQJUt5xZFrc=
+SIZE (ecdysis-unbound.patch) = 38863
 SIZE (unbound-1.4.9.tar.gz) = 4470329

Reply | Threaded
Open this post in threaded view
|

Re: dns64 patch for unbound

Stuart Henderson
actually... just noticed a few problems with the modified sample
config, I'll send another one with a modified patchset soon.


Reply | Threaded
Open this post in threaded view
|

Re: dns64 patch for unbound

Stuart Henderson
In reply to this post by Stuart Henderson
In gmane.os.openbsd.ports, you wrote:
> On 2011-05-13, Ryan McBride <[hidden email]> wrote:
>> This is the patch from http://ecdysis.viagenie.ca/, updated for
>> unbound-1.4.9. Needed for nat64 in pf being tested now, but also useful
>> if you're running nat64 on another box.
>
> I'd prefer to download the patchset rather than include it in filesdir:

This one's better. Don't change the default config settings (just
add the commented-out examples), and add the missing config parser
patches so you can specify dns64-prefix without an error.

$ grep dns64 /var/unbound/etc/unbound.conf                                          
        module-config: "dns64 validator iterator"
        dns64-prefix: 64:ff9b::0/96

$ dig +short @::1 www.openbsd.org aaaa      
64:ff9b::8ef4:c2a

OK?

If anyone is reading this from outside OpenBSD and not interested in
the ports bits but just wanting an updated dns64 patch for unbound 1.4.9,
it's at http://spacehopper.org/mirrors/unbound-1.4.9-dns64.patch.gz

Index: Makefile
===================================================================
RCS file: /cvs/ports/net/unbound/Makefile,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile
--- Makefile 24 Mar 2011 20:30:42 -0000 1.28
+++ Makefile 14 May 2011 10:47:41 -0000
@@ -3,9 +3,11 @@
 COMMENT= validating DNS resolver
 
 DISTNAME= unbound-1.4.9
+REVISION= 0
 CATEGORIES= net
 
 MASTER_SITES= http://www.unbound.net/downloads/
+MASTER_SITES0= http://spacehopper.org/mirrors/
 HOMEPAGE= http://www.unbound.net/
 
 MAINTAINER=     Jakob Schlyter <[hidden email]>
@@ -37,6 +39,16 @@ CONFIGURE_ARGS+= --with-ssl=/usr \
  --with-conf-file=/var/unbound/etc/unbound.conf \
  --with-username=_unbound
 USE_GROFF = Yes
+
+FLAVORS= dns64
+FLAVOR?=
+
+.if ${FLAVOR:L:Mdns64}
+PATCHFILES= unbound-1.4.9-dns64.patch.gz:0
+PATCH_DIST_STRIP= -p1
+.else
+SUPDISTFILES= unbound-1.4.9-dns64.patch.gz:0
+.endif
 
 post-install:
  ${INSTALL_DATA_DIR} ${PREFIX}/share/examples/unbound
Index: distinfo
===================================================================
RCS file: /cvs/ports/net/unbound/distinfo,v
retrieving revision 1.19
diff -u -p -r1.19 distinfo
--- distinfo 24 Mar 2011 20:30:42 -0000 1.19
+++ distinfo 14 May 2011 10:47:41 -0000
@@ -1,5 +1,10 @@
+MD5 (unbound-1.4.9-dns64.patch.gz) = 0AOiMRttQ4YSINu9iHL3sQ==
 MD5 (unbound-1.4.9.tar.gz) = cHnnUhDGVnYdOASp8qx7nw==
+RMD160 (unbound-1.4.9-dns64.patch.gz) = Ee2Qax67R7JDbjBDTpRLhoRDx3U=
 RMD160 (unbound-1.4.9.tar.gz) = nDTFX3dvRQavt3XI9E34SmSFQHM=
+SHA1 (unbound-1.4.9-dns64.patch.gz) = k7ls65yzXBqUvefwV8UVluj/ZE0=
 SHA1 (unbound-1.4.9.tar.gz) = 8qx7TvHRszDi3V4u7etv0ruthHg=
+SHA256 (unbound-1.4.9-dns64.patch.gz) = PnBRP13Gg0rY0VT01vMlzXHnB9eBFzdi+zOOGkvH9NI=
 SHA256 (unbound-1.4.9.tar.gz) = 2guYn+jPEOQ0gTQ4c+rt9gvvY75HPIbXPQJUt5xZFrc=
+SIZE (unbound-1.4.9-dns64.patch.gz) = 94073
 SIZE (unbound-1.4.9.tar.gz) = 4470329
Index: pkg/DESCR
===================================================================
RCS file: /cvs/ports/net/unbound/pkg/DESCR,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 DESCR
--- pkg/DESCR 23 May 2008 06:52:21 -0000 1.1.1.1
+++ pkg/DESCR 14 May 2011 10:47:41 -0000
@@ -1,2 +1,5 @@
 Unbound is an implementation of a recursive DNS resolver, that does caching
 and DNSSEC validation.
+
+Flavors:
+ dns64 Support for synthesized AAAA records for NAT64

Reply | Threaded
Open this post in threaded view
|

Re: dns64 patch for unbound

Todd T. Fries-2
Penned by Stuart Henderson on 20110514  5:48.47, we have:
| In gmane.os.openbsd.ports, you wrote:
| > On 2011-05-13, Ryan McBride <[hidden email]> wrote:
| >> This is the patch from http://ecdysis.viagenie.ca/, updated for
| >> unbound-1.4.9. Needed for nat64 in pf being tested now, but also useful
| >> if you're running nat64 on another box.
| >
| > I'd prefer to download the patchset rather than include it in filesdir:
|
| This one's better. Don't change the default config settings (just
| add the commented-out examples), and add the missing config parser
| patches so you can specify dns64-prefix without an error.
|
| $ grep dns64 /var/unbound/etc/unbound.conf                                          
|         module-config: "dns64 validator iterator"
|         dns64-prefix: 64:ff9b::0/96
|
| $ dig +short @::1 www.openbsd.org aaaa      
| 64:ff9b::8ef4:c2a
|
| OK?
|
| If anyone is reading this from outside OpenBSD and not interested in
| the ports bits but just wanting an updated dns64 patch for unbound 1.4.9,
| it's at http://spacehopper.org/mirrors/unbound-1.4.9-dns64.patch.gz

I like this a lot.  Though I question, if the module-config must be adjusted
to use dns64, why make it a flavor at all?

Thanks,
 
| Index: Makefile
| ===================================================================
| RCS file: /cvs/ports/net/unbound/Makefile,v
| retrieving revision 1.28
| diff -u -p -r1.28 Makefile
| --- Makefile 24 Mar 2011 20:30:42 -0000 1.28
| +++ Makefile 14 May 2011 10:47:41 -0000
| @@ -3,9 +3,11 @@
|  COMMENT= validating DNS resolver
|  
|  DISTNAME= unbound-1.4.9
| +REVISION= 0
|  CATEGORIES= net
|  
|  MASTER_SITES= http://www.unbound.net/downloads/
| +MASTER_SITES0= http://spacehopper.org/mirrors/
|  HOMEPAGE= http://www.unbound.net/
|  
|  MAINTAINER=     Jakob Schlyter <[hidden email]>
| @@ -37,6 +39,16 @@ CONFIGURE_ARGS+= --with-ssl=/usr \
|   --with-conf-file=/var/unbound/etc/unbound.conf \
|   --with-username=_unbound
|  USE_GROFF = Yes
| +
| +FLAVORS= dns64
| +FLAVOR?=
| +
| +.if ${FLAVOR:L:Mdns64}
| +PATCHFILES= unbound-1.4.9-dns64.patch.gz:0
| +PATCH_DIST_STRIP= -p1
| +.else
| +SUPDISTFILES= unbound-1.4.9-dns64.patch.gz:0
| +.endif
|  
|  post-install:
|   ${INSTALL_DATA_DIR} ${PREFIX}/share/examples/unbound
| Index: distinfo
| ===================================================================
| RCS file: /cvs/ports/net/unbound/distinfo,v
| retrieving revision 1.19
| diff -u -p -r1.19 distinfo
| --- distinfo 24 Mar 2011 20:30:42 -0000 1.19
| +++ distinfo 14 May 2011 10:47:41 -0000
| @@ -1,5 +1,10 @@
| +MD5 (unbound-1.4.9-dns64.patch.gz) = 0AOiMRttQ4YSINu9iHL3sQ==
|  MD5 (unbound-1.4.9.tar.gz) = cHnnUhDGVnYdOASp8qx7nw==
| +RMD160 (unbound-1.4.9-dns64.patch.gz) = Ee2Qax67R7JDbjBDTpRLhoRDx3U=
|  RMD160 (unbound-1.4.9.tar.gz) = nDTFX3dvRQavt3XI9E34SmSFQHM=
| +SHA1 (unbound-1.4.9-dns64.patch.gz) = k7ls65yzXBqUvefwV8UVluj/ZE0=
|  SHA1 (unbound-1.4.9.tar.gz) = 8qx7TvHRszDi3V4u7etv0ruthHg=
| +SHA256 (unbound-1.4.9-dns64.patch.gz) = PnBRP13Gg0rY0VT01vMlzXHnB9eBFzdi+zOOGkvH9NI=
|  SHA256 (unbound-1.4.9.tar.gz) = 2guYn+jPEOQ0gTQ4c+rt9gvvY75HPIbXPQJUt5xZFrc=
| +SIZE (unbound-1.4.9-dns64.patch.gz) = 94073
|  SIZE (unbound-1.4.9.tar.gz) = 4470329
| Index: pkg/DESCR
| ===================================================================
| RCS file: /cvs/ports/net/unbound/pkg/DESCR,v
| retrieving revision 1.1.1.1
| diff -u -p -r1.1.1.1 DESCR
| --- pkg/DESCR 23 May 2008 06:52:21 -0000 1.1.1.1
| +++ pkg/DESCR 14 May 2011 10:47:41 -0000
| @@ -1,2 +1,5 @@
|  Unbound is an implementation of a recursive DNS resolver, that does caching
|  and DNSSEC validation.
| +
| +Flavors:
| + dns64 Support for synthesized AAAA records for NAT64

--
Todd Fries .. [hidden email]

 _____________________________________________
|                                             \  1.636.410.0632 (voice)
| Free Daemon Consulting, LLC                 \  1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com             \  1.866.792.3418 (FAX)
| 2525 NW Expy #525, Oklahoma City, OK 73112  \  sip:[hidden email]
| "..in support of free software solutions."  \  sip:[hidden email]
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                                                 
              37E7 D3EB 74D0 8D66 A68D  B866 0326 204E 3F42 004A
                        http://todd.fries.net/pgp.txt

Reply | Threaded
Open this post in threaded view
|

Re: dns64 patch for unbound

Stuart Henderson
On 2011/05/18 17:13, Todd T. Fries wrote:

> Penned by Stuart Henderson on 20110514  5:48.47, we have:
> | In gmane.os.openbsd.ports, you wrote:
> | > On 2011-05-13, Ryan McBride <[hidden email]> wrote:
> | >> This is the patch from http://ecdysis.viagenie.ca/, updated for
> | >> unbound-1.4.9. Needed for nat64 in pf being tested now, but also useful
> | >> if you're running nat64 on another box.
> | >
> | > I'd prefer to download the patchset rather than include it in filesdir:
> |
> | This one's better. Don't change the default config settings (just
> | add the commented-out examples), and add the missing config parser
> | patches so you can specify dns64-prefix without an error.
> |
> | $ grep dns64 /var/unbound/etc/unbound.conf                                          
> |         module-config: "dns64 validator iterator"
> |         dns64-prefix: 64:ff9b::0/96
> |
> | $ dig +short @::1 www.openbsd.org aaaa      
> | 64:ff9b::8ef4:c2a
> |
> | OK?
> |
> | If anyone is reading this from outside OpenBSD and not interested in
> | the ports bits but just wanting an updated dns64 patch for unbound 1.4.9,
> | it's at http://spacehopper.org/mirrors/unbound-1.4.9-dns64.patch.gz
>
> I like this a lot.  Though I question, if the module-config must be adjusted
> to use dns64, why make it a flavor at all?

I think a flavour makes sense for now as it's a large patch
and upstream haven't decided whether to include it yet, so I'd
rather have it be reasonably clear that it's something that
has been added.

http://permalink.gmane.org/gmane.network.dns.unbound.user/1644