]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
implement xfrin via XoT
authorOndřej Surý <ondrej@sury.org>
Thu, 14 Jan 2021 11:51:25 +0000 (12:51 +0100)
committerOndřej Surý <ondrej@sury.org>
Fri, 29 Jan 2021 11:07:38 +0000 (12:07 +0100)
Add support for a "tls" key/value pair for zone primaries, referencing
either a "tls" configuration statement or "ephemeral". If set to use
TLS, zones will send SOA and AXFR/IXFR queries over a TLS channel.

50 files changed:
bin/named/Makefile.am
bin/named/config.c
bin/named/include/named/transportconf.h [new file with mode: 0644]
bin/named/named.conf.rst
bin/named/server.c
bin/named/transportconf.c [new file with mode: 0644]
bin/named/win32/named.vcxproj.filters.in
bin/named/win32/named.vcxproj.in
bin/named/zoneconf.c
bin/tests/system/Makefile.am
bin/tests/system/xot/clean.sh [new file with mode: 0644]
bin/tests/system/xot/dig1.good [new file with mode: 0644]
bin/tests/system/xot/ns1/named.conf.in [new file with mode: 0644]
bin/tests/system/xot/ns2/named.conf.in [new file with mode: 0644]
bin/tests/system/xot/setup.sh [new file with mode: 0644]
bin/tests/system/xot/tests.sh [new file with mode: 0755]
doc/arm/reference.rst
doc/man/named.conf.5in
doc/misc/Makefile.am
doc/misc/master.zoneopt
doc/misc/master.zoneopt.rst
doc/misc/mirror.zoneopt
doc/misc/mirror.zoneopt.rst
doc/misc/options
doc/misc/options.active
doc/misc/options.grammar.rst
doc/misc/primaries.grammar.rst
doc/misc/redirect.zoneopt
doc/misc/redirect.zoneopt.rst
doc/misc/slave.zoneopt
doc/misc/slave.zoneopt.rst
doc/misc/stub.zoneopt
doc/misc/stub.zoneopt.rst
doc/misc/tls.grammar.rst [new file with mode: 0644]
lib/dns/Makefile.am
lib/dns/include/dns/ipkeylist.h
lib/dns/include/dns/transport.h [new file with mode: 0644]
lib/dns/include/dns/view.h
lib/dns/include/dns/xfrin.h
lib/dns/include/dns/zone.h
lib/dns/ipkeylist.c
lib/dns/transport.c [new file with mode: 0644]
lib/dns/view.c
lib/dns/win32/libdns.def.in
lib/dns/win32/libdns.vcxproj.filters.in
lib/dns/win32/libdns.vcxproj.in
lib/dns/xfrin.c
lib/dns/zone.c
lib/isccfg/namedconf.c
util/copyrights

index 1c9483a0c55edc7879160b1a0f0e3e9df11bb589..548229a807cb3950ec9ef38b1e39a6d9bbe66627 100644 (file)
@@ -59,6 +59,7 @@ named_SOURCES =                               \
        server.c                        \
        statschannel.c                  \
        tkeyconf.c                      \
+       transportconf.c                 \
        tsigconf.c                      \
        zoneconf.c                      \
        unix/dlz_dlopen_driver.c        \
@@ -77,6 +78,7 @@ named_SOURCES =                               \
        include/named/smf_globals.h     \
        include/named/statschannel.h    \
        include/named/tkeyconf.h        \
+       include/named/transportconf.h   \
        include/named/tsigconf.h        \
        include/named/types.h           \
        include/named/zoneconf.h        \
index 2850ff996087deeae7aa6d85d7a9a89721b65722..72094f8302ee854b140fc16cc15c725fda02583e 100644 (file)
@@ -608,10 +608,76 @@ named_config_getprimariesdef(const cfg_obj_t *cctx, const char *name,
        return (result);
 }
 
+static isc_result_t
+named_config_getname(isc_mem_t *mctx, const cfg_obj_t *obj,
+                    dns_name_t **namep) {
+       REQUIRE(namep != NULL && *namep == NULL);
+
+       const char *objstr;
+       isc_result_t result;
+       isc_buffer_t b;
+       dns_fixedname_t fname;
+
+       if (!cfg_obj_isstring(obj)) {
+               *namep = NULL;
+               return (ISC_R_SUCCESS);
+       }
+
+       *namep = isc_mem_get(mctx, sizeof(**namep));
+       dns_name_init(*namep, NULL);
+
+       objstr = cfg_obj_asstring(obj);
+       isc_buffer_constinit(&b, objstr, strlen(objstr));
+       isc_buffer_add(&b, strlen(objstr));
+       dns_fixedname_init(&fname);
+       result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname,
+                                  0, NULL);
+       if (result != ISC_R_SUCCESS) {
+               isc_mem_put(mctx, *namep, sizeof(*namep));
+               *namep = NULL;
+               return (result);
+       }
+       dns_name_dup(dns_fixedname_name(&fname), mctx, *namep);
+
+       return (ISC_R_SUCCESS);
+}
+
+#define grow_array(mctx, array, newlen, oldlen)                    \
+       if (newlen >= oldlen) {                                    \
+               size_t newsize = (newlen + 16) * sizeof(array[0]); \
+               size_t oldsize = oldlen * sizeof(array[0]);        \
+               void *tmp = isc_mem_get(mctx, newsize);            \
+               memset(tmp, 0, newsize);                           \
+               if (oldlen != 0) {                                 \
+                       memmove(tmp, array, oldsize);              \
+                       isc_mem_put(mctx, array, oldsize);         \
+               }                                                  \
+               array = tmp;                                       \
+               oldlen = newlen + 16;                              \
+       }
+
+#define shrink_array(mctx, array, newlen, oldlen)           \
+       if (newlen < oldlen) {                              \
+               void *tmp = NULL;                           \
+               size_t newsize = newlen * sizeof(array[0]); \
+               size_t oldsize = oldlen * sizeof(array[0]); \
+               if (newlen != 0) {                          \
+                       tmp = isc_mem_get(mctx, newsize);   \
+                       memset(tmp, 0, newsize);            \
+                       memmove(tmp, array, newsize);       \
+               } else {                                    \
+                       tmp = NULL;                         \
+               }                                           \
+               isc_mem_put(mctx, array, oldsize);          \
+               array = tmp;                                \
+               oldlen = newlen;                            \
+       }
+
 isc_result_t
 named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
                             isc_mem_t *mctx, dns_ipkeylist_t *ipkl) {
-       uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
+       uint32_t addrcount = 0, dscpcount = 0, keycount = 0, tlscount = 0,
+                i = 0;
        uint32_t listcount = 0, l = 0, j;
        uint32_t stackcount = 0, pushed = 0;
        isc_result_t result;
@@ -619,12 +685,14 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
        const cfg_obj_t *addrlist;
        const cfg_obj_t *portobj;
        const cfg_obj_t *dscpobj;
-       in_port_t port;
+       in_port_t port = (in_port_t)0;
+       in_port_t def_port;
+       in_port_t def_tlsport;
        isc_dscp_t dscp = -1;
-       dns_fixedname_t fname;
        isc_sockaddr_t *addrs = NULL;
        isc_dscp_t *dscps = NULL;
        dns_name_t **keys = NULL;
+       dns_name_t **tlss = NULL;
        struct {
                const char *name;
        } *lists = NULL;
@@ -638,6 +706,7 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
        REQUIRE(ipkl->count == 0);
        REQUIRE(ipkl->addrs == NULL);
        REQUIRE(ipkl->keys == NULL);
+       REQUIRE(ipkl->tlss == NULL);
        REQUIRE(ipkl->dscps == NULL);
        REQUIRE(ipkl->labels == NULL);
        REQUIRE(ipkl->allocated == 0);
@@ -645,7 +714,12 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
        /*
         * Get system defaults.
         */
-       result = named_config_getport(config, "port", &port);
+       result = named_config_getport(config, "port", &def_port);
+       if (result != ISC_R_SUCCESS) {
+               goto cleanup;
+       }
+
+       result = named_config_getport(config, "tls-port", &def_tlsport);
        if (result != ISC_R_SUCCESS) {
                goto cleanup;
        }
@@ -689,33 +763,20 @@ resume:
        for (; element != NULL; element = cfg_list_next(element)) {
                const cfg_obj_t *addr;
                const cfg_obj_t *key;
-               const char *keystr;
-               isc_buffer_t b;
+               const cfg_obj_t *tls;
 
                addr = cfg_tuple_get(cfg_listelt_value(element),
                                     "primarieselement");
                key = cfg_tuple_get(cfg_listelt_value(element), "key");
+               tls = cfg_tuple_get(cfg_listelt_value(element), "tls");
 
                if (!cfg_obj_issockaddr(addr)) {
                        const char *listname = cfg_obj_asstring(addr);
                        isc_result_t tresult;
 
                        /* Grow lists? */
-                       if (listcount == l) {
-                               void *tmp;
-                               uint32_t newlen = listcount + 16;
-                               size_t newsize, oldsize;
-
-                               newsize = newlen * sizeof(*lists);
-                               oldsize = listcount * sizeof(*lists);
-                               tmp = isc_mem_get(mctx, newsize);
-                               if (listcount != 0) {
-                                       memmove(tmp, lists, oldsize);
-                                       isc_mem_put(mctx, lists, oldsize);
-                               }
-                               lists = tmp;
-                               listcount = newlen;
-                       }
+                       grow_array(mctx, lists, l, listcount);
+
                        /* Seen? */
                        for (j = 0; j < l; j++) {
                                if (strcasecmp(lists[j].name, listname) == 0) {
@@ -741,21 +802,7 @@ resume:
                        }
                        lists[l++].name = listname;
                        /* Grow stack? */
-                       if (stackcount == pushed) {
-                               void *tmp;
-                               uint32_t newlen = stackcount + 16;
-                               size_t newsize, oldsize;
-
-                               newsize = newlen * sizeof(*stack);
-                               oldsize = stackcount * sizeof(*stack);
-                               tmp = isc_mem_get(mctx, newsize);
-                               if (stackcount != 0) {
-                                       memmove(tmp, stack, oldsize);
-                                       isc_mem_put(mctx, stack, oldsize);
-                               }
-                               stack = tmp;
-                               stackcount = newlen;
-                       }
+                       grow_array(mctx, stack, pushed, stackcount);
                        /*
                         * We want to resume processing this list on the
                         * next element.
@@ -767,68 +814,44 @@ resume:
                        goto newlist;
                }
 
-               if (i == addrcount) {
-                       void *tmp;
-                       uint32_t newlen = addrcount + 16;
-                       size_t newsize, oldsize;
-
-                       newsize = newlen * sizeof(isc_sockaddr_t);
-                       oldsize = addrcount * sizeof(isc_sockaddr_t);
-                       tmp = isc_mem_get(mctx, newsize);
-                       if (addrcount != 0) {
-                               memmove(tmp, addrs, oldsize);
-                               isc_mem_put(mctx, addrs, oldsize);
-                       }
-                       addrs = tmp;
-                       addrcount = newlen;
-
-                       newsize = newlen * sizeof(isc_dscp_t);
-                       oldsize = dscpcount * sizeof(isc_dscp_t);
-                       tmp = isc_mem_get(mctx, newsize);
-                       if (dscpcount != 0) {
-                               memmove(tmp, dscps, oldsize);
-                               isc_mem_put(mctx, dscps, oldsize);
-                       }
-                       dscps = tmp;
-                       dscpcount = newlen;
-
-                       newsize = newlen * sizeof(dns_name_t *);
-                       oldsize = keycount * sizeof(dns_name_t *);
-                       tmp = isc_mem_get(mctx, newsize);
-                       if (keycount != 0) {
-                               memmove(tmp, keys, oldsize);
-                               isc_mem_put(mctx, keys, oldsize);
-                       }
-                       keys = tmp;
-                       keycount = newlen;
-               }
+               grow_array(mctx, addrs, i, addrcount);
+               grow_array(mctx, dscps, i, dscpcount);
+               grow_array(mctx, keys, i, keycount);
+               grow_array(mctx, tlss, i, tlscount);
 
                addrs[i] = *cfg_obj_assockaddr(addr);
-               if (isc_sockaddr_getport(&addrs[i]) == 0) {
-                       isc_sockaddr_setport(&addrs[i], port);
-               }
                dscps[i] = cfg_obj_getdscp(addr);
                if (dscps[i] == -1) {
                        dscps[i] = dscp;
                }
-               keys[i] = NULL;
-               i++; /* Increment here so that cleanup on error works. */
-               if (!cfg_obj_isstring(key)) {
-                       continue;
+
+               result = named_config_getname(mctx, key, &keys[i]);
+               if (result != ISC_R_SUCCESS) {
+                       i++; /* Increment here so that cleanup on error works.
+                             */
+                       goto cleanup;
                }
-               keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t));
-               dns_name_init(keys[i - 1], NULL);
-
-               keystr = cfg_obj_asstring(key);
-               isc_buffer_constinit(&b, keystr, strlen(keystr));
-               isc_buffer_add(&b, strlen(keystr));
-               dns_fixedname_init(&fname);
-               result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
-                                          dns_rootname, 0, NULL);
+
+               result = named_config_getname(mctx, tls, &tlss[i]);
                if (result != ISC_R_SUCCESS) {
+                       i++; /* Increment here so that cleanup on error works.
+                             */
                        goto cleanup;
                }
-               dns_name_dup(dns_fixedname_name(&fname), mctx, keys[i - 1]);
+
+               /* Set the default port or tls-port */
+               if (port == 0) {
+                       if (tlss[i] != NULL) {
+                               port = def_tlsport;
+                       } else {
+                               port = def_port;
+                       }
+               }
+
+               if (isc_sockaddr_getport(&addrs[i]) == 0) {
+                       isc_sockaddr_setport(&addrs[i], port);
+               }
+               i++;
        }
        if (pushed != 0) {
                pushed--;
@@ -837,61 +860,28 @@ resume:
                dscp = stack[pushed].dscp;
                goto resume;
        }
-       if (i < addrcount) {
-               void *tmp;
-               size_t newsize, oldsize;
-
-               newsize = i * sizeof(isc_sockaddr_t);
-               oldsize = addrcount * sizeof(isc_sockaddr_t);
-               if (i != 0) {
-                       tmp = isc_mem_get(mctx, newsize);
-                       memmove(tmp, addrs, newsize);
-               } else {
-                       tmp = NULL;
-               }
-               isc_mem_put(mctx, addrs, oldsize);
-               addrs = tmp;
-               addrcount = i;
-
-               newsize = i * sizeof(isc_dscp_t);
-               oldsize = dscpcount * sizeof(isc_dscp_t);
-               if (i != 0) {
-                       tmp = isc_mem_get(mctx, newsize);
-                       memmove(tmp, dscps, newsize);
-               } else {
-                       tmp = NULL;
-               }
-               isc_mem_put(mctx, dscps, oldsize);
-               dscps = tmp;
-               dscpcount = i;
-
-               newsize = i * sizeof(dns_name_t *);
-               oldsize = keycount * sizeof(dns_name_t *);
-               if (i != 0) {
-                       tmp = isc_mem_get(mctx, newsize);
-                       memmove(tmp, keys, newsize);
-               } else {
-                       tmp = NULL;
-               }
-               isc_mem_put(mctx, keys, oldsize);
-               keys = tmp;
-               keycount = i;
-       }
+
+       shrink_array(mctx, addrs, i, addrcount);
+       shrink_array(mctx, dscps, i, dscpcount);
+       shrink_array(mctx, keys, i, keycount);
+       shrink_array(mctx, tlss, i, tlscount);
 
        if (lists != NULL) {
-               isc_mem_put(mctx, lists, listcount * sizeof(*lists));
+               isc_mem_put(mctx, lists, listcount * sizeof(lists[0]));
        }
        if (stack != NULL) {
-               isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
+               isc_mem_put(mctx, stack, stackcount * sizeof(stack[0]));
        }
 
        INSIST(dscpcount == addrcount);
        INSIST(keycount == addrcount);
+       INSIST(tlscount == addrcount);
        INSIST(keycount == dscpcount);
 
        ipkl->addrs = addrs;
        ipkl->dscps = dscps;
        ipkl->keys = keys;
+       ipkl->tlss = tlss;
        ipkl->count = addrcount;
        ipkl->allocated = addrcount;
 
@@ -899,10 +889,10 @@ resume:
 
 cleanup:
        if (addrs != NULL) {
-               isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t));
+               isc_mem_put(mctx, addrs, addrcount * sizeof(addrs[0]));
        }
        if (dscps != NULL) {
-               isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t));
+               isc_mem_put(mctx, dscps, dscpcount * sizeof(dscps[0]));
        }
        if (keys != NULL) {
                for (j = 0; j < i; j++) {
@@ -912,15 +902,27 @@ cleanup:
                        if (dns_name_dynamic(keys[j])) {
                                dns_name_free(keys[j], mctx);
                        }
-                       isc_mem_put(mctx, keys[j], sizeof(dns_name_t));
+                       isc_mem_put(mctx, keys[j], sizeof(*keys[j]));
+               }
+               isc_mem_put(mctx, keys, keycount * sizeof(keys[0]));
+       }
+       if (tlss != NULL) {
+               for (j = 0; j < i; j++) {
+                       if (tlss[j] == NULL) {
+                               continue;
+                       }
+                       if (dns_name_dynamic(tlss[j])) {
+                               dns_name_free(tlss[j], mctx);
+                       }
+                       isc_mem_put(mctx, tlss[j], sizeof(*tlss[j]));
                }
-               isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *));
+               isc_mem_put(mctx, tlss, tlscount * sizeof(tlss[0]));
        }
        if (lists != NULL) {
-               isc_mem_put(mctx, lists, listcount * sizeof(*lists));
+               isc_mem_put(mctx, lists, listcount * sizeof(lists[0]));
        }
        if (stack != NULL) {
-               isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
+               isc_mem_put(mctx, stack, stackcount * sizeof(stack[0]));
        }
        return (result);
 }
diff --git a/bin/named/include/named/transportconf.h b/bin/named/include/named/transportconf.h
new file mode 100644 (file)
index 0000000..0314267
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#include <dns/transport.h>
+
+#include <isccfg/cfg.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+named_transports_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
+                           isc_mem_t *mctx, dns_transport_list_t **listp);
+/*%<
+ * Create a list of transport objects (DoT or DoH) and configure them
+ * according to 'key-file', 'cert-file', 'ca-file' or 'hostname'
+ * statements.
+ *
+ *     Requires:
+ *     \li     'config' is not NULL.
+ *     \li     'vconfig' is not NULL.
+ *     \li     'mctx' is not NULL
+ *     \li     'listp' is not NULL, and '*listp' is NULL
+ *
+ */
+
+ISC_LANG_ENDDECLS
index 40163878a54519e8532dedf533073831dfad0394..722c514dbce29e2f269568cc9a8ddc28e9158427 100644 (file)
@@ -137,7 +137,8 @@ MASTERS
   masters string [ port integer ] [ dscp
       integer ] { ( primaries | ipv4_address
       [ port integer ] | ipv6_address [ port
-      integer ] ) [ key string ]; ... };
+      integer ] ) [ key string ] [ tls
+      string ]; ... };
 
 OPTIONS
 ^^^^^^^
@@ -158,7 +159,7 @@ OPTIONS
        allow-update-forwarding { address_match_element; ... };
        also-notify [ port integer ] [ dscp integer ] { ( primaries |
            ipv4_address [ port integer ] | ipv6_address [ port
-           integer ] ) [ key string ]; ... };
+           integer ] ) [ key string ] [ tls string ]; ... };
        alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
            ] [ dscp integer ];
        alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
@@ -176,8 +177,9 @@ OPTIONS
        catalog-zones { zone string [ default-masters [ port integer ]
            [ dscp integer ] { ( primaries | ipv4_address [ port
            integer ] | ipv6_address [ port integer ] ) [ key
-           string ]; ... } ] [ zone-directory quoted_string ] [
-           in-memory boolean ] [ min-update-interval duration ]; ... };
+           string ] [ tls string ]; ... } ] [ zone-directory
+           quoted_string ] [ in-memory boolean ] [ min-update-interval
+           duration ]; ... };
        check-dup-records ( fail | warn | ignore );
        check-integrity boolean;
        check-mx ( fail | warn | ignore );
@@ -461,7 +463,8 @@ PRIMARIES
   primaries string [ port integer ] [ dscp
       integer ] { ( primaries | ipv4_address
       [ port integer ] | ipv6_address [ port
-      integer ] ) [ key string ]; ... };
+      integer ] ) [ key string ] [ tls
+      string ]; ... };
 
 SERVER
 ^^^^^^
@@ -519,9 +522,11 @@ TLS
 ::
 
   tls string {
+       ca-file quoted_string;
        cert-file quoted_string;
        ciphers string; // experimental
        dh-param quoted_string; // experimental
+       hostname quoted_string;
        key-file quoted_string;
        protocols sslprotos; // experimental
   };
@@ -566,7 +571,7 @@ VIEW
        allow-update-forwarding { address_match_element; ... };
        also-notify [ port integer ] [ dscp integer ] { ( primaries |
            ipv4_address [ port integer ] | ipv6_address [ port
-           integer ] ) [ key string ]; ... };
+           integer ] ) [ key string ] [ tls string ]; ... };
        alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
            ] [ dscp integer ];
        alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
@@ -578,8 +583,9 @@ VIEW
        catalog-zones { zone string [ default-masters [ port integer ]
            [ dscp integer ] { ( primaries | ipv4_address [ port
            integer ] | ipv6_address [ port integer ] ) [ key
-           string ]; ... } ] [ zone-directory quoted_string ] [
-           in-memory boolean ] [ min-update-interval duration ]; ... };
+           string ] [ tls string ]; ... } ] [ zone-directory
+           quoted_string ] [ in-memory boolean ] [ min-update-interval
+           duration ]; ... };
        check-dup-records ( fail | warn | ignore );
        check-integrity boolean;
        check-mx ( fail | warn | ignore );
@@ -843,8 +849,8 @@ VIEW
                allow-update-forwarding { address_match_element; ... };
                also-notify [ port integer ] [ dscp integer ] { (
                    primaries | ipv4_address [ port integer ] |
-                   ipv6_address [ port integer ] ) [ key string ];
-                   ... };
+                   ipv6_address [ port integer ] ) [ key string ] [
+                   tls string ]; ... };
                alt-transfer-source ( ipv4_address | * ) [ port (
                    integer | * ) ] [ dscp integer ];
                alt-transfer-source-v6 ( ipv6_address | * ) [ port (
@@ -884,8 +890,8 @@ VIEW
                masterfile-style ( full | relative );
                masters [ port integer ] [ dscp integer ] { (
                    primaries | ipv4_address [ port integer ] |
-                   ipv6_address [ port integer ] ) [ key string ];
-                   ... };
+                   ipv6_address [ port integer ] ) [ key string ] [
+                   tls string ]; ... };
                max-ixfr-ratio ( unlimited | percentage );
                max-journal-size ( default | unlimited | sizeval );
                max-records integer;
@@ -908,8 +914,8 @@ VIEW
                notify-to-soa boolean;
                primaries [ port integer ] [ dscp integer ] { (
                    primaries | ipv4_address [ port integer ] |
-                   ipv6_address [ port integer ] ) [ key string ];
-                   ... };
+                   ipv6_address [ port integer ] ) [ key string ] [
+                   tls string ]; ... };
                request-expire boolean;
                request-ixfr boolean;
                serial-update-method ( date | increment | unixtime );
@@ -954,7 +960,7 @@ ZONE
        allow-update-forwarding { address_match_element; ... };
        also-notify [ port integer ] [ dscp integer ] { ( primaries |
            ipv4_address [ port integer ] | ipv6_address [ port
-           integer ] ) [ key string ]; ... };
+           integer ] ) [ key string ] [ tls string ]; ... };
        alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
            ] [ dscp integer ];
        alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
@@ -992,7 +998,7 @@ ZONE
        masterfile-style ( full | relative );
        masters [ port integer ] [ dscp integer ] { ( primaries |
            ipv4_address [ port integer ] | ipv6_address [ port
-           integer ] ) [ key string ]; ... };
+           integer ] ) [ key string ] [ tls string ]; ... };
        max-ixfr-ratio ( unlimited | percentage );
        max-journal-size ( default | unlimited | sizeval );
        max-records integer;
@@ -1015,7 +1021,7 @@ ZONE
        notify-to-soa boolean;
        primaries [ port integer ] [ dscp integer ] { ( primaries |
            ipv4_address [ port integer ] | ipv6_address [ port
-           integer ] ) [ key string ]; ... };
+           integer ] ) [ key string ] [ tls string ]; ... };
        request-expire boolean;
        request-ixfr boolean;
        serial-update-method ( date | increment | unixtime );
index 2354a55ca2c8ee52e24af074e82cd175ed99197f..3d39d8f65764226cab653194c26f7d6e3c6c8821 100644 (file)
 #include <named/server.h>
 #include <named/statschannel.h>
 #include <named/tkeyconf.h>
+#include <named/transportconf.h>
 #include <named/tsigconf.h>
 #include <named/zoneconf.h>
 #ifdef HAVE_LIBSCF
@@ -3988,6 +3989,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        uint32_t max_stale_ttl = 0;
        uint32_t stale_refresh_time = 0;
        dns_tsig_keyring_t *ring = NULL;
+       dns_transport_list_t *transports = NULL;
        dns_view_t *pview = NULL; /* Production view */
        isc_mem_t *cmctx = NULL, *hmctx = NULL;
        dns_dispatch_t *dispatch4 = NULL;
@@ -4973,6 +4975,14 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                }
        }
 
+       /*
+        * Configure the view's transports (DoT/DoH)
+        */
+       CHECK(named_transports_fromconfig(config, vconfig, view->mctx,
+                                         &transports));
+       dns_view_settransports(view, transports);
+       dns_transport_list_detach(&transports);
+
        /*
         * Configure the view's TSIG keys.
         */
diff --git a/bin/named/transportconf.c b/bin/named/transportconf.c
new file mode 100644 (file)
index 0000000..3a1bfb4
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <inttypes.h>
+
+#include <isc/buffer.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/name.h>
+#include <dns/transport.h>
+
+#include <isccfg/cfg.h>
+
+#include <named/log.h>
+#include <named/transportconf.h>
+
+#define create_name(id, name)                                      \
+       isc_buffer_t namesrc, namebuf;                             \
+       char namedata[DNS_NAME_FORMATSIZE + 1];                    \
+       dns_name_init(name, NULL);                                 \
+       isc_buffer_constinit(&namesrc, id, strlen(id));            \
+       isc_buffer_add(&namesrc, strlen(id));                      \
+       isc_buffer_init(&namebuf, namedata, sizeof(namedata));     \
+       result = (dns_name_fromtext(name, &namesrc, dns_rootname,  \
+                                   DNS_NAME_DOWNCASE, &namebuf)); \
+       if (result != ISC_R_SUCCESS) {                             \
+               goto failure;                                      \
+       }
+
+#define parse_transport_option(map, transport, name, setter)      \
+       {                                                         \
+               const cfg_obj_t *obj = NULL;                      \
+               cfg_map_get(map, name, &obj);                     \
+               if (obj != NULL) {                                \
+                       setter(transport, cfg_obj_asstring(obj)); \
+               }                                                 \
+       }
+
+static isc_result_t
+add_doh_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
+       const cfg_obj_t *doh = NULL;
+       const char *dohid = NULL;
+       isc_result_t result;
+
+       for (const cfg_listelt_t *element = cfg_list_first(transportlist);
+            element != NULL; element = cfg_list_next(element))
+       {
+               dns_name_t dohname;
+               dns_transport_t *transport;
+
+               doh = cfg_listelt_value(element);
+               dohid = cfg_obj_asstring(cfg_map_getname(doh));
+
+               create_name(dohid, &dohname);
+
+               transport = dns_transport_new(&dohname, DNS_TRANSPORT_DOH,
+                                             list);
+
+               parse_transport_option(doh, transport, "key-file",
+                                      dns_transport_set_keyfile);
+               parse_transport_option(doh, transport, "cert-file",
+                                      dns_transport_set_certfile);
+               parse_transport_option(doh, transport, "ca-file",
+                                      dns_transport_set_cafile);
+               parse_transport_option(doh, transport, "hostname",
+                                      dns_transport_set_hostname);
+       }
+
+       return (ISC_R_SUCCESS);
+failure:
+       cfg_obj_log(doh, named_g_lctx, ISC_LOG_ERROR,
+                   "configuring DoH '%s': %s", dohid,
+                   isc_result_totext(result));
+
+       return (result);
+}
+
+static isc_result_t
+add_tls_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
+       const cfg_obj_t *tls = NULL;
+       const char *tlsid = NULL;
+       isc_result_t result;
+
+       for (const cfg_listelt_t *element = cfg_list_first(transportlist);
+            element != NULL; element = cfg_list_next(element))
+       {
+               dns_name_t tlsname;
+               dns_transport_t *transport;
+
+               tls = cfg_listelt_value(element);
+               tlsid = cfg_obj_asstring(cfg_map_getname(tls));
+
+               if (!strcmp(tlsid, "ephemeral")) {
+                       result = ISC_R_UNEXPECTEDTOKEN;
+                       goto failure;
+               }
+
+               create_name(tlsid, &tlsname);
+
+               transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS,
+                                             list);
+
+               parse_transport_option(tls, transport, "key-file",
+                                      dns_transport_set_keyfile);
+               parse_transport_option(tls, transport, "cert-file",
+                                      dns_transport_set_certfile);
+               parse_transport_option(tls, transport, "ca-file",
+                                      dns_transport_set_cafile);
+               parse_transport_option(tls, transport, "hostname",
+                                      dns_transport_set_hostname);
+       }
+
+       return (ISC_R_SUCCESS);
+failure:
+       cfg_obj_log(tls, named_g_lctx, ISC_LOG_ERROR,
+                   "configuring tls '%s': %s", tlsid,
+                   isc_result_totext(result));
+
+       return (result);
+}
+
+#define CHECK(f)                             \
+       if ((result = f) != ISC_R_SUCCESS) { \
+               goto failure;                \
+       }
+
+static isc_result_t
+transport_list_fromconfig(const cfg_obj_t *config, dns_transport_list_t *list) {
+       const cfg_obj_t *obj = NULL;
+       isc_result_t result = ISC_R_SUCCESS;
+
+       if (result == ISC_R_SUCCESS &&
+           cfg_map_get(config, "tls", &obj) == ISC_R_SUCCESS)
+       {
+               result = add_tls_transports(obj, list);
+               obj = NULL;
+       }
+
+       if (result == ISC_R_SUCCESS &&
+           cfg_map_get(config, "doh", &obj) == ISC_R_SUCCESS)
+       {
+               result = add_doh_transports(obj, list);
+               obj = NULL;
+       }
+
+       return (result);
+}
+
+static void
+transport_list_add_ephemeral(dns_transport_list_t *list) {
+       isc_result_t result;
+       dns_name_t tlsname;
+
+       create_name("ephemeral", &tlsname);
+
+       (void)dns_transport_new(&tlsname, DNS_TRANSPORT_TLS, list);
+
+       return;
+failure:
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+}
+
+isc_result_t
+named_transports_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
+                           isc_mem_t *mctx, dns_transport_list_t **listp) {
+       isc_result_t result;
+       dns_transport_list_t *list = dns_transport_list_new(mctx);
+
+       REQUIRE(listp != NULL && *listp == NULL);
+
+       transport_list_add_ephemeral(list);
+
+       if (config != NULL) {
+               result = transport_list_fromconfig(config, list);
+               if (result != ISC_R_SUCCESS) {
+                       goto failure;
+               }
+       }
+
+       if (vconfig != NULL) {
+               config = cfg_tuple_get(vconfig, "options");
+               transport_list_fromconfig(config, list);
+       }
+
+       *listp = list;
+       return (ISC_R_SUCCESS);
+failure:
+       dns_transport_list_detach(&list);
+       return (result);
+}
index 6677ef31a4b06b347780b2c8394d9be78f99a98a..76e358f060c36c2695c27d7f71446e9a4164a87c 100644 (file)
@@ -59,6 +59,9 @@
     <ClCompile Include="..\tkeyconf.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\transportconf.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\tsigconf.c">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClInclude Include="..\include\named\tkeyconf.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\named\transportconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\include\named\tsigconf.h">
       <Filter>Header Files</Filter>
     </ClInclude>
index 73f091ea9cf60c3e366ba3297a477986da91229e..9c59a339c7ccd7d18ea500d5f4e642628d0faa1e 100644 (file)
@@ -138,6 +138,7 @@ perl -e "print \";\";" &gt;&gt; xsl.c
     <ClCompile Include="..\server.c" />
     <ClCompile Include="..\statschannel.c" />
     <ClCompile Include="..\tkeyconf.c" />
+    <ClCompile Include="..\transportconf.c" />
     <ClCompile Include="..\tsigconf.c" />
     <ClCompile Include="..\xsl.c" />
     <ClCompile Include="..\zoneconf.c" />
@@ -159,6 +160,7 @@ perl -e "print \";\";" &gt;&gt; xsl.c
     <ClInclude Include="..\include\named\server.h" />
     <ClInclude Include="..\include\named\statschannel.h" />
     <ClInclude Include="..\include\named\tkeyconf.h" />
+    <ClInclude Include="..\include\named\transportconf.h" />
     <ClInclude Include="..\include\named\tsigconf.h" />
     <ClInclude Include="..\include\named\types.h" />
     <ClInclude Include="..\xsl_p.h" />
index 9ad830b3164c623ed72a57bb00bb34934f2e7c7a..e0b17e65f539542a64c32db1a28442bd7c47ca59 100644 (file)
@@ -1302,13 +1302,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
 
                        RETERR(named_config_getipandkeylist(config, obj, mctx,
                                                            &ipkl));
-                       result = dns_zone_setalsonotifydscpkeys(
-                               zone, ipkl.addrs, ipkl.dscps, ipkl.keys,
-                               ipkl.count);
+                       result = dns_zone_setalsonotify(zone, ipkl.addrs,
+                                                       ipkl.dscps, ipkl.keys,
+                                                       ipkl.tlss, ipkl.count);
                        dns_ipkeylist_clear(mctx, &ipkl);
                        RETERR(result);
                } else {
-                       RETERR(dns_zone_setalsonotify(zone, NULL, 0));
+                       RETERR(dns_zone_setalsonotify(zone, NULL, NULL, NULL,
+                                                     NULL, 0));
                }
 
                obj = NULL;
@@ -1910,13 +1911,15 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
 
                        RETERR(named_config_getipandkeylist(config, obj, mctx,
                                                            &ipkl));
-                       result = dns_zone_setprimarieswithkeys(
-                               mayberaw, ipkl.addrs, ipkl.keys, ipkl.count);
+                       result = dns_zone_setprimaries(mayberaw, ipkl.addrs,
+                                                      ipkl.keys, ipkl.tlss,
+                                                      ipkl.count);
                        count = ipkl.count;
                        dns_ipkeylist_clear(mctx, &ipkl);
                        RETERR(result);
                } else {
-                       result = dns_zone_setprimaries(mayberaw, NULL, 0);
+                       result = dns_zone_setprimaries(mayberaw, NULL, NULL,
+                                                      NULL, 0);
                }
                RETERR(result);
 
index a90f0b62783fabee8725e4dd02ba251f13c7bc13..36fc21b532a788f38990620047a1a86d101e0308 100644 (file)
@@ -151,6 +151,7 @@ TESTS +=                    \
        views                   \
        wildcard                \
        xferquota               \
+       xot                     \
        zonechecks
 
 # eddsa test is broken
diff --git a/bin/tests/system/xot/clean.sh b/bin/tests/system/xot/clean.sh
new file mode 100644 (file)
index 0000000..d4711ba
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+#
+# Clean up after zone transfer tests.
+#
+
+rm -f ./*/named.conf
+rm -f ./*/named.memstats
+rm -f ./*/named.run
+rm -f ./*/named.run.prev
+rm -f ./dig.out.*
+rm -f ./*/*.db
diff --git a/bin/tests/system/xot/dig1.good b/bin/tests/system/xot/dig1.good
new file mode 100644 (file)
index 0000000..18c0e63
--- /dev/null
@@ -0,0 +1,171 @@
+example.               86400   IN      SOA     ns2.example. hostmaster.example. 1397051952 5 5 1814400 3600
+example.               3600    IN      NS      ns2.example.
+a01.example.           3600    IN      A       0.0.0.0
+a02.example.           3600    IN      A       255.255.255.255
+a601.example.          3600    IN      A6      0 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+a601.example.          3600    IN      A6      64 ::ffff:ffff:ffff:ffff foo.
+a601.example.          3600    IN      A6      127 ::1 foo.
+a601.example.          3600    IN      A6      128  .
+aaaa01.example.                3600    IN      AAAA    ::1
+aaaa02.example.                3600    IN      AAAA    fd92:7065:b8e:ffff::5
+afsdb01.example.       3600    IN      AFSDB   0 hostname.example.
+afsdb02.example.       3600    IN      AFSDB   65535 .
+amtrelay01.example.    3600    IN      AMTRELAY 0 0 0
+amtrelay02.example.    3600    IN      AMTRELAY 0 1 0
+amtrelay03.example.    3600    IN      AMTRELAY 0 0 1 0.0.0.0
+amtrelay04.example.    3600    IN      AMTRELAY 0 0 2 ::
+amtrelay05.example.    3600    IN      AMTRELAY 0 0 3 example.net.
+amtrelay06.example.    3600    IN      AMTRELAY \# 2 0004
+apl01.example.         3600    IN      APL     !1:10.0.0.1/32 1:10.0.0.0/24
+apl02.example.         3600    IN      APL
+atma01.example.                3600    IN      ATMA    +61200000000
+atma02.example.                3600    IN      ATMA    +61200000000
+atma03.example.                3600    IN      ATMA    1234567890abcdef
+atma04.example.                3600    IN      ATMA    fedcba0987654321
+avc.example.           3600    IN      AVC     "foo:bar"
+caa01.example.         3600    IN      CAA     0 issue "ca.example.net; policy=ev"
+caa02.example.         3600    IN      CAA     128 tbs "Unknown"
+caa03.example.         3600    IN      CAA     128 tbs ""
+cdnskey01.example.     3600    IN      CDNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
+cds01.example.         3600    IN      CDS     30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
+cert01.example.                3600    IN      CERT    65534 65535 PRIVATEOID MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgiWCn/GxHhai6V AuHAoNUz4YoU1tVfSCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY=
+cname01.example.       3600    IN      CNAME   cname-target.
+cname02.example.       3600    IN      CNAME   cname-target.example.
+cname03.example.       3600    IN      CNAME   .
+csync01.example.       3600    IN      CSYNC   0 0 A NS AAAA
+csync02.example.       3600    IN      CSYNC   0 0
+dhcid01.example.       3600    IN      DHCID   AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=
+dhcid02.example.       3600    IN      DHCID   AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQdWL3b/NaiUDlW2No=
+dhcid03.example.       3600    IN      DHCID   AAABxLmlskllE0MVjd57zHcWmEH3pCQ6VytcKD//7es/deY=
+dlv.example.           3600    IN      DLV     30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
+dname01.example.       3600    IN      DNAME   dname-target.
+dname02.example.       3600    IN      DNAME   dname-target.example.
+dname03.example.       3600    IN      DNAME   .
+dnskey01.example.      3600    IN      DNSKEY  512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
+doa01.example.         3600    IN      DOA     1234567890 1234567890 1 "image/gif" R0lGODlhKAAZAOMCAGZmZgBmmf///zOZzMz//5nM/zNmmWbM/5nMzMzMzACZ/////////////////////yH5BAEKAA8ALAAAAAAoABkAAATH8IFJK5U2a4337F5ogRkpnoCJrly7PrCKyh8c3HgAhzT35MDbbtO7/IJIHbGiOiaTxVTpSVWWLqNq1UVyapNS1wd3OAxug0LhnCubcVhsxysQnOt4ATpvvzHlFzl1AwODhWeFAgRpen5/UhheAYMFdUB4SFcpGEGGdQeCAqBBLTuSk30EeXd9pEsAbKGxjHqDSE0Sp6ixN4N1BJmbc7lIhmsBich1awPAjkY1SZR8bJWrz382SGqIBQQFQd4IsUTaX+ceuudPEQA7
+doa02.example.         3600    IN      DOA     0 1 2 "" aHR0cHM6Ly93d3cuaXNjLm9yZy8=
+ds01.example.          3600    IN      DS      12892 5 2 26584835CA80C81C91999F31CFAF2A0E89D4FF1C8FAFD0DDB31A85C7 19277C13
+ds01.example.          3600    IN      NS      ns42.example.
+ds02.example.          3600    IN      DS      12892 5 1 7AA4A3F416C2F2391FB7AB0D434F762CD62D1390
+ds02.example.          3600    IN      NS      ns43.example.
+eid01.example.         3600    IN      EID     1289AB
+eui48.example.         3600    IN      EUI48   01-23-45-67-89-ab
+eui64.example.         3600    IN      EUI64   01-23-45-67-89-ab-cd-ef
+gid01.example.         3600    IN      GID     \# 1 03
+gpos01.example.                3600    IN      GPOS    "-22.6882" "116.8652" "250.0"
+gpos02.example.                3600    IN      GPOS    "" "" ""
+hinfo01.example.       3600    IN      HINFO   "Generic PC clone" "NetBSD-1.4"
+hinfo02.example.       3600    IN      HINFO   "PC" "NetBSD"
+hip1.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
+hip2.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
+ipseckey01.example.    3600    IN      IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
+ipseckey02.example.    3600    IN      IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
+ipseckey03.example.    3600    IN      IPSECKEY 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
+ipseckey04.example.    3600    IN      IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
+ipseckey05.example.    3600    IN      IPSECKEY 10 2 2 2001:db8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
+isdn01.example.                3600    IN      ISDN    "isdn-address"
+isdn02.example.                3600    IN      ISDN    "isdn-address" "subaddress"
+isdn03.example.                3600    IN      ISDN    "isdn-address"
+isdn04.example.                3600    IN      ISDN    "isdn-address" "subaddress"
+keydata.example.       3600    IN      TYPE65533 \# 0
+keydata.example.       3600    IN      TYPE65533 \# 6 010203040506
+keydata.example.       3600    IN      TYPE65533 \# 18 010203040506010203040506010203040506
+kx01.example.          3600    IN      KX      10 kdc.example.
+kx02.example.          3600    IN      KX      10 .
+l32.example.           3600    IN      L32     10 1.2.3.4
+l64.example.           3600    IN      L64     10 14:4fff:ff20:ee64
+loc01.example.         3600    IN      LOC     60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m
+loc02.example.         3600    IN      LOC     60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m
+lp.example.            3600    IN      LP      10 example.net.
+mb01.example.          3600    IN      MG      madname.example.
+mb02.example.          3600    IN      MG      .
+mg01.example.          3600    IN      MG      mgmname.example.
+mg02.example.          3600    IN      MG      .
+minfo01.example.       3600    IN      MINFO   rmailbx.example. emailbx.example.
+minfo02.example.       3600    IN      MINFO   . .
+mr01.example.          3600    IN      MR      mrname.example.
+mr02.example.          3600    IN      MR      .
+mx01.example.          3600    IN      MX      10 mail.example.
+mx02.example.          3600    IN      MX      10 .
+naptr01.example.       3600    IN      NAPTR   0 0 "" "" "" .
+naptr02.example.       3600    IN      NAPTR   65535 65535 "blurgh" "blorf" "blllbb" foo.
+nid.example.           3600    IN      NID     10 14:4fff:ff20:ee64
+nimloc01.example.      3600    IN      NIMLOC  1289AB
+ninfo01.example.       3600    IN      NINFO   "foo"
+ninfo02.example.       3600    IN      NINFO   "foo" "bar"
+ninfo03.example.       3600    IN      NINFO   "foo"
+ninfo04.example.       3600    IN      NINFO   "foo" "bar"
+ninfo05.example.       3600    IN      NINFO   "foo bar"
+ninfo06.example.       3600    IN      NINFO   "foo bar"
+ninfo07.example.       3600    IN      NINFO   "foo bar"
+ninfo08.example.       3600    IN      NINFO   "foo\010bar"
+ninfo09.example.       3600    IN      NINFO   "foo\010bar"
+ninfo10.example.       3600    IN      NINFO   "foo bar"
+ninfo11.example.       3600    IN      NINFO   "\"foo\""
+ninfo12.example.       3600    IN      NINFO   "\"foo\""
+ninfo13.example.       3600    IN      NINFO   "foo;"
+ninfo14.example.       3600    IN      NINFO   "foo;"
+ninfo15.example.       3600    IN      NINFO   "bar\\;"
+ns2.example.           3600    IN      A       10.53.0.2
+nsap-ptr01.example.    3600    IN      NSAP-PTR foo.
+nsap-ptr01.example.    3600    IN      NSAP-PTR .
+nsap01.example.                3600    IN      NSAP    0x47000580005a0000000001e133ffffff00016100
+nsap02.example.                3600    IN      NSAP    0x47000580005a0000000001e133ffffff00016100
+nsec01.example.                3600    IN      NSEC    a.secure.nil. NS SOA MX LOC RRSIG NSEC DNSKEY
+nsec02.example.                3600    IN      NSEC    . NSAP-PTR NSEC
+nsec03.example.                3600    IN      NSEC    . A
+nsec04.example.                3600    IN      NSEC    . TYPE127
+openpgpkey.example.    3600    IN      OPENPGPKEY AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
+ptr01.example.         3600    IN      PTR     example.
+px01.example.          3600    IN      PX      65535 foo. bar.
+px02.example.          3600    IN      PX      65535 . .
+rkey01.example.                3600    IN      RKEY    0 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
+rp01.example.          3600    IN      RP      mbox-dname.example. txt-dname.example.
+rp02.example.          3600    IN      RP      . .
+rrsig01.example.       3600    IN      RRSIG   NSEC 1 3 3600 20000102030405 19961211100908 2143 foo.nil. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgiWCn/GxHhai6V AuHAoNUz4YoU1tVfSCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY=
+rt01.example.          3600    IN      RT      0 intermediate-host.example.
+rt02.example.          3600    IN      RT      65535 .
+sink01.example.                3600    IN      SINK    1 0 0
+sink02.example.                3600    IN      SINK    8 0 2 l4ik
+smimea.example.                3600    IN      SMIMEA  1 1 2 92003BA34942DC74152E2F2C408D29ECA5A520E7F2E06BB944F4DCA3 46BAF63C1B177615D466F6C4B71C216A50292BD58C9EBDD2F74E38FE 51FFD48C43326CBC
+spf01.example.         3600    IN      SPF     "v=spf1 -all"
+spf02.example.         3600    IN      SPF     "v=spf1" " -all"
+srv01.example.         3600    IN      SRV     0 0 0 .
+srv02.example.         3600    IN      SRV     65535 65535 65535 old-slow-box.example.
+sshfp01.example.       3600    IN      SSHFP   4 2 C76D8329954DA2835751E371544E963EFDA099080D6C58DD2BFD9A31 6E162C83
+sshfp02.example.       3600    IN      SSHFP   1 2 BF29468C83AC58CCF8C85AB7B3BEB054ECF1E38512B8353AB36471FA 88961DCC
+ta.example.            3600    IN      TA      30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
+talink0.example.       3600    IN      TALINK  . talink1.example.
+talink1.example.       3600    IN      TALINK  talink0.example. talink2.example.
+talink2.example.       3600    IN      TALINK  talink2.example. .
+tlsa.example.          3600    IN      TLSA    1 1 2 92003BA34942DC74152E2F2C408D29ECA5A520E7F2E06BB944F4DCA3 46BAF63C1B177615D466F6C4B71C216A50292BD58C9EBDD2F74E38FE 51FFD48C43326CBC
+txt01.example.         3600    IN      TXT     "foo"
+txt02.example.         3600    IN      TXT     "foo" "bar"
+txt03.example.         3600    IN      TXT     "foo"
+txt04.example.         3600    IN      TXT     "foo" "bar"
+txt05.example.         3600    IN      TXT     "foo bar"
+txt06.example.         3600    IN      TXT     "foo bar"
+txt07.example.         3600    IN      TXT     "foo bar"
+txt08.example.         3600    IN      TXT     "foo\010bar"
+txt09.example.         3600    IN      TXT     "foo\010bar"
+txt10.example.         3600    IN      TXT     "foo bar"
+txt11.example.         3600    IN      TXT     "\"foo\""
+txt12.example.         3600    IN      TXT     "\"foo\""
+txt13.example.         3600    IN      TXT     "foo;"
+txt14.example.         3600    IN      TXT     "foo;"
+txt15.example.         3600    IN      TXT     "bar\\;"
+uid01.example.         3600    IN      UID     \# 1 02
+uinfo01.example.       3600    IN      UINFO   \# 1 01
+unspec01.example.      3600    IN      UNSPEC  \# 1 04
+uri01.example.         3600    IN      URI     10 20 "https://www.isc.org/"
+uri02.example.         3600    IN      URI     30 40 "https://www.isc.org/HolyCowThisSureIsAVeryLongURIRecordIDontEvenKnowWhatSomeoneWouldEverWantWithSuchAThingButTheSpecificationRequiresThatWesupportItSoHereWeGoTestingItLaLaLaLaLaLaLaSeriouslyThoughWhyWouldYouEvenConsiderUsingAURIThisLongItSeemsLikeASillyIdeaButEnhWhatAreYouGonnaDo/"
+uri03.example.         3600    IN      URI     30 40 ""
+wks01.example.         3600    IN      WKS     10.0.0.1 6 0 1 2 21 23
+wks02.example.         3600    IN      WKS     10.0.0.1 17 0 1 2 53
+wks03.example.         3600    IN      WKS     10.0.0.2 6 65535
+x2501.example.         3600    IN      X25     "123456789"
+zonemd01.example.      3600    IN      ZONEMD  2019020700 1 0 C220B8A6ED5728A971902F7E3D4FD93ADEEA88B0453C2E8E8C863D46 5AB06CF34EB95B266398C98B59124FA239CB7EEB
+8f1tmio9avcom2k0frp92lgcumak0cad.example. 3600 IN NSEC3        1 0 10 D2CF0294C020CE6C 8FPNS2UCT7FBS643THP2B77PEQ77K6IU A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
+kcd3juae64f9c5csl1kif1htaui7un0g.example. 3600 IN NSEC3        1 0 10 D2CF0294C020CE6C KD5MN2M20340DGO0BL7NTSB8JP4BSC7E
+mr5ukvsk1l37btu4q7b1dfevft4hkqdk.example. 3600 IN NSEC3        1 0 10 D2CF0294C020CE6C MT38J6VG7S0SN5G17MCUF6IQIKFUAJ05 A AAAA RRSIG
+example.               86400   IN      SOA     ns2.example. hostmaster.example. 1397051952 5 5 1814400 3600
diff --git a/bin/tests/system/xot/ns1/named.conf.in b/bin/tests/system/xot/ns1/named.conf.in
new file mode 100644 (file)
index 0000000..699e46a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+include "../../common/rndc.key";
+
+controls {
+       inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       port @PORT@;
+       tls-port @TLSPORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.1; };
+       listen-on-v6 { none; };
+       listen-on tls ephemeral { 10.53.0.1; };
+       recursion no;
+       notify explicit;
+       also-notify { 10.53.0.2 port @PORT@; };
+       statistics-file "named.stats";
+       dnssec-validation yes;
+};
+
+zone "." {
+       type hint;
+       file "../../common/root.hint";
+};
+
+zone "example" {
+       type primary;
+       file "example.db";
+       allow-transfer { any; };
+};
diff --git a/bin/tests/system/xot/ns2/named.conf.in b/bin/tests/system/xot/ns2/named.conf.in
new file mode 100644 (file)
index 0000000..aabe987
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+include "../../common/rndc.key";
+
+controls {
+       inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       query-source address 10.53.0.2;
+       notify-source 10.53.0.2;
+       transfer-source 10.53.0.2;
+       port @PORT@;
+       tls-port @TLSPORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.2; };
+       listen-on tls ephemeral { 10.53.0.2; };
+       listen-on-v6 { none; };
+       listen-on tls ephemeral { 10.53.0.2; };
+       recursion no;
+       notify no;
+       ixfr-from-differences yes;
+       check-integrity no;
+       dnssec-validation yes;
+};
+
+zone "." {
+       type hint;
+       file "../../common/root.hint";
+};
+
+zone "example" {
+       type secondary;
+       primaries { 10.53.0.1 tls ephemeral; };
+       file "example.db";
+       allow-transfer { any; };
+};
diff --git a/bin/tests/system/xot/setup.sh b/bin/tests/system/xot/setup.sh
new file mode 100644 (file)
index 0000000..29e49c4
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+. ../conf.sh
+
+$SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns1/example.db
+
+copy_setports ns1/named.conf.in ns1/named.conf
+copy_setports ns2/named.conf.in ns2/named.conf
diff --git a/bin/tests/system/xot/tests.sh b/bin/tests/system/xot/tests.sh
new file mode 100755 (executable)
index 0000000..c8c1ecb
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+. ../conf.sh
+
+dig_with_opts() {
+       "$DIG" +tls +noadd +nosea +nostat +noquest +nocomm +nocmd -p "${TLSPORT}" "$@"
+}
+
+wait_for_xfer() (
+       dig_with_opts -b 10.53.0.3 @10.53.0.2 example. AXFR > "dig.out.ns2.test$n" || return 1
+       grep "^;" "dig.out.ns2.test$n" > /dev/null && return 1
+       return 0
+)
+
+status=0
+n=0
+
+n=$((n+1))
+echo_i "testing XoT server functionality (using dig) ($n)"
+ret=0
+dig_with_opts example. -b 10.53.0.3 @10.53.0.1 axfr > dig.out.ns1.test$n || ret=1
+grep "^;" dig.out.ns1.test$n | cat_i
+digcomp dig1.good dig.out.ns1.test$n || ret=1
+if test $ret != 0 ; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "testing basic incoming XoT functionality (from secondary) ($n)"
+ret=0
+if retry_quiet 10 wait_for_xfer; then
+       grep "^;" "dig.out.ns2.test$n" | cat_i
+       digcomp dig1.good "dig.out.ns2.test$n" || ret=1
+else
+       echo_i "timed out waiting for zone transfer"
+       ret=1
+fi
+if test $ret != 0 ; then echo_i "failed"; fi
+status=$((status+ret))
+
+echo_i "exit status: $status"
+[ $status -eq 0 ] || exit 1
index eb9140b3dc002b6ca8dca1fd1b1a02fc654a8159..f3599be319ffaf00bcd655d6ad874d6270b96989 100644 (file)
@@ -30,7 +30,7 @@ file documentation:
         A list of one or more ``ip_addr``, ``ip_prefix``, ``key_id``, or ``acl_name`` elements; see :ref:`address_match_lists`.
 
     ``primaries_list``
-        A named list of one or more ``ip_addr`` with optional ``key_id`` and/or ``ip_port``. A ``primaries_list`` may include other ``primaries_list``.
+        A named list of one or more ``ip_addr`` with optional ``tls_id``, ``key_id`` and/or ``ip_port``. A ``primaries_list`` may include other ``primaries_list``.
 
     ``domain_name``
         A quoted string which is used as a DNS name; for example. ``my.test.domain``.
@@ -66,6 +66,9 @@ file documentation:
     ``key_list``
         A list of one or more ``key_id``, separated by semicolons and ending with a semicolon.
 
+    ``tls_id``
+        A string representing a TLS configuration object, including a key and certificate.
+
     ``number``
         A non-negative 32-bit integer (i.e., a number between 0 and 4294967295, inclusive). Its acceptable value might be further limited by the context in which it is used.
 
@@ -286,6 +289,9 @@ The following statements are supported:
     ``statistics-channels``
         Declares communication channels to get access to ``named`` statistics.
 
+    ``tls``
+        Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file`` and ``hostname``.
+
     ``trust-anchors``
         Defines DNSSEC trust anchors: if used with the ``initial-key`` or ``initial-ds`` keyword, trust anchors are kept up-to-date using :rfc:`5011` trust anchor maintenance; if used with ``static-key`` or ``static-ds``, keys are permanent.
 
@@ -2446,12 +2452,13 @@ Multiple ``listen-on`` statements are allowed. For example:
 
    listen-on { 5.6.7.8; };
    listen-on port 1234 { !1.2.3.4; 1.2/16; };
-   listen-on port 8853 tls example-tls { 4.3.2.1; };
+   listen-on port 8853 tls ephemeral { 4.3.2.1; };
 
 enables the name server to listen for standard DNS queries on port 53 of the
 IP address 5.6.7.8 and on port 1234 of an address on the machine in net 1.2
 that is not 1.2.3.4, and to listen for DNS-over-TLS connections on port
-8853 of the IP address 4.3.2.1.
+8853 of the IP address 4.3.2.1, using an ephemeral TLS key and certificate
+created for the currently running ``named`` process.
 
 If no ``listen-on`` is specified, the server listens for standard DNS
 on port 53 of all IPv4 interfaces.
@@ -2472,9 +2479,10 @@ Multiple ``listen-on-v6`` options can be used. For example:
 enables the name server to listen for standard DNS queries on port 53 of
 any IPv6 addresses and on port 1234 of IPv6 addresses that are not in the
 prefix 2001:db8::/32, and for DNS-over-TLS connections on port 8853 of
-the address 2001:db8::100.
+the address 2001:db8::100, using a TLS key and certificate specified in
+the a ``tls`` statement with the name ``example-tls``.
 
-To instruct the server not to listen on any IPv6 address, use:
+To instruct the server not to listen on any IPv6 addresses, use:
 
 ::
 
@@ -4579,6 +4587,43 @@ socket statistics), http://127.0.0.1:8888/json/v1/mem (memory manager
 statistics), http://127.0.0.1:8888/json/v1/tasks (task manager
 statistics), and http://127.0.0.1:8888/json/v1/traffic (traffic sizes).
 
+.. _tls:
+
+``tls`` Statement Grammar
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. include:: ../misc/tls.grammar.rst
+
+``tls`` Statement Definition and Usage
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``tls`` statement is used to configure a TLS connection; this
+configuration can then be referenced by a ``listen-on`` or ``listen-on-v6``
+statement to cause ``named`` to listen for incoming requests via TLS,
+or in the ``primaries`` statement for a zone of type ``secondary`` to
+cause zone transfer requests to be sent via TLS.
+
+``tls`` can only be set at the top level of ``named.conf``.
+
+The following options can be specified in a ``tls`` statement:
+
+  ``key-file``
+    Path to a file containing the private TLS key to be used for
+    the connection.
+
+  ``cert-file``
+    Path to a file containing the TLS certificate to be used for
+    the connection.
+
+  ``ca-file``
+    Path to a file containing trusted TLS certificates.
+
+  ``hostname``
+    The hostname associated with the certificate.
+
+The built-in ``ephemeral`` TLS connection object represents a temporary
+key and certificate created for the current ``named`` session only.
+
 .. _trust_anchors:
 
 ``trust-anchors`` Statement Grammar
index 2180bdbd6c73bdab9471551cb5e2e563a4d00b82..7884fd5f28c80b22fa2f99dcc51fc9c9e95e134c 100644 (file)
@@ -196,7 +196,8 @@ managed\-keys { string ( static\-key
 masters string [ port integer ] [ dscp
     integer ] { ( primaries | ipv4_address
     [ port integer ] | ipv6_address [ port
-    integer ] ) [ key string ]; ... };
+    integer ] ) [ key string ] [ tls
+    string ]; ... };
 .ft P
 .fi
 .UNINDENT
@@ -221,7 +222,7 @@ options {
       allow\-update\-forwarding { address_match_element; ... };
       also\-notify [ port integer ] [ dscp integer ] { ( primaries |
           ipv4_address [ port integer ] | ipv6_address [ port
-          integer ] ) [ key string ]; ... };
+          integer ] ) [ key string ] [ tls string ]; ... };
       alt\-transfer\-source ( ipv4_address | * ) [ port ( integer | * )
           ] [ dscp integer ];
       alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
@@ -239,8 +240,9 @@ options {
       catalog\-zones { zone string [ default\-masters [ port integer ]
           [ dscp integer ] { ( primaries | ipv4_address [ port
           integer ] | ipv6_address [ port integer ] ) [ key
-          string ]; ... } ] [ zone\-directory quoted_string ] [
-          in\-memory boolean ] [ min\-update\-interval duration ]; ... };
+          string ] [ tls string ]; ... } ] [ zone\-directory
+          quoted_string ] [ in\-memory boolean ] [ min\-update\-interval
+          duration ]; ... };
       check\-dup\-records ( fail | warn | ignore );
       check\-integrity boolean;
       check\-mx ( fail | warn | ignore );
@@ -532,7 +534,8 @@ plugin ( query ) string [ { unspecified\-text
 primaries string [ port integer ] [ dscp
     integer ] { ( primaries | ipv4_address
     [ port integer ] | ipv6_address [ port
-    integer ] ) [ key string ]; ... };
+    integer ] ) [ key string ] [ tls
+    string ]; ... };
 .ft P
 .fi
 .UNINDENT
@@ -602,9 +605,11 @@ statistics\-channels {
 .nf
 .ft C
 tls string {
+      ca\-file quoted_string;
       cert\-file quoted_string;
       ciphers string; // experimental
       dh\-param quoted_string; // experimental
+      hostname quoted_string;
       key\-file quoted_string;
       protocols sslprotos; // experimental
 };
@@ -661,7 +666,7 @@ view string [ class ] {
       allow\-update\-forwarding { address_match_element; ... };
       also\-notify [ port integer ] [ dscp integer ] { ( primaries |
           ipv4_address [ port integer ] | ipv6_address [ port
-          integer ] ) [ key string ]; ... };
+          integer ] ) [ key string ] [ tls string ]; ... };
       alt\-transfer\-source ( ipv4_address | * ) [ port ( integer | * )
           ] [ dscp integer ];
       alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
@@ -673,8 +678,9 @@ view string [ class ] {
       catalog\-zones { zone string [ default\-masters [ port integer ]
           [ dscp integer ] { ( primaries | ipv4_address [ port
           integer ] | ipv6_address [ port integer ] ) [ key
-          string ]; ... } ] [ zone\-directory quoted_string ] [
-          in\-memory boolean ] [ min\-update\-interval duration ]; ... };
+          string ] [ tls string ]; ... } ] [ zone\-directory
+          quoted_string ] [ in\-memory boolean ] [ min\-update\-interval
+          duration ]; ... };
       check\-dup\-records ( fail | warn | ignore );
       check\-integrity boolean;
       check\-mx ( fail | warn | ignore );
@@ -938,8 +944,8 @@ view string [ class ] {
               allow\-update\-forwarding { address_match_element; ... };
               also\-notify [ port integer ] [ dscp integer ] { (
                   primaries | ipv4_address [ port integer ] |
-                  ipv6_address [ port integer ] ) [ key string ];
-                  ... };
+                  ipv6_address [ port integer ] ) [ key string ] [
+                  tls string ]; ... };
               alt\-transfer\-source ( ipv4_address | * ) [ port (
                   integer | * ) ] [ dscp integer ];
               alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port (
@@ -979,8 +985,8 @@ view string [ class ] {
               masterfile\-style ( full | relative );
               masters [ port integer ] [ dscp integer ] { (
                   primaries | ipv4_address [ port integer ] |
-                  ipv6_address [ port integer ] ) [ key string ];
-                  ... };
+                  ipv6_address [ port integer ] ) [ key string ] [
+                  tls string ]; ... };
               max\-ixfr\-ratio ( unlimited | percentage );
               max\-journal\-size ( default | unlimited | sizeval );
               max\-records integer;
@@ -1003,8 +1009,8 @@ view string [ class ] {
               notify\-to\-soa boolean;
               primaries [ port integer ] [ dscp integer ] { (
                   primaries | ipv4_address [ port integer ] |
-                  ipv6_address [ port integer ] ) [ key string ];
-                  ... };
+                  ipv6_address [ port integer ] ) [ key string ] [
+                  tls string ]; ... };
               request\-expire boolean;
               request\-ixfr boolean;
               serial\-update\-method ( date | increment | unixtime );
@@ -1053,7 +1059,7 @@ zone string [ class ] {
       allow\-update\-forwarding { address_match_element; ... };
       also\-notify [ port integer ] [ dscp integer ] { ( primaries |
           ipv4_address [ port integer ] | ipv6_address [ port
-          integer ] ) [ key string ]; ... };
+          integer ] ) [ key string ] [ tls string ]; ... };
       alt\-transfer\-source ( ipv4_address | * ) [ port ( integer | * )
           ] [ dscp integer ];
       alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
@@ -1091,7 +1097,7 @@ zone string [ class ] {
       masterfile\-style ( full | relative );
       masters [ port integer ] [ dscp integer ] { ( primaries |
           ipv4_address [ port integer ] | ipv6_address [ port
-          integer ] ) [ key string ]; ... };
+          integer ] ) [ key string ] [ tls string ]; ... };
       max\-ixfr\-ratio ( unlimited | percentage );
       max\-journal\-size ( default | unlimited | sizeval );
       max\-records integer;
@@ -1114,7 +1120,7 @@ zone string [ class ] {
       notify\-to\-soa boolean;
       primaries [ port integer ] [ dscp integer ] { ( primaries |
           ipv4_address [ port integer ] | ipv6_address [ port
-          integer ] ) [ key string ]; ... };
+          integer ] ) [ key string ] [ tls string ]; ... };
       request\-expire boolean;
       request\-ixfr boolean;
       serial\-update\-method ( date | increment | unixtime );
index 32549892149bc2bbbbf94d7f65f7005a66cc35c6..d4db7194a6f421fbeab35ef620b4aceab984d0a3 100644 (file)
@@ -34,6 +34,7 @@ OPTIONS_FILES =                               \
        options.grammar.rst             \
        server.grammar.rst              \
        statistics-channels.grammar.rst \
+       tls.grammar.rst                 \
        trust-anchors.grammar.rst       \
        managed-keys.grammar.rst        \
        trusted-keys.grammar.rst
@@ -162,6 +163,9 @@ server.grammar.rst: options.active
 statistics-channels.grammar.rst: options.active
        $(AM_V_RST_GRAMMARS)$(PERL) $(srcdir)/rst-grammars.pl options.active statistics-channels > $@
 
+tls.grammar.rst: options.active
+       $(AM_V_RST_GRAMMARS)$(PERL) $(srcdir)/rst-grammars.pl options.active tls > $@
+
 trust-anchors.grammar.rst: options.active
        $(AM_V_RST_GRAMMARS)$(PERL) $(srcdir)/rst-grammars.pl options.active trust-anchors > $@
 
index f9903b34e818546a4dd020fe571c162036b7b301..ae47d96b85451b8023c1c980fb503e3bbd742f6d 100644 (file)
@@ -4,7 +4,7 @@ zone <string> [ <class> ] {
        allow-query-on { <address_match_element>; ... };
        allow-transfer { <address_match_element>; ... };
        allow-update { <address_match_element>; ... };
-       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        auto-dnssec ( allow | maintain | off );
index 7d97ce8ead95f13bf581b2c0702d0b3814d0daba..9bac436947ad724790ef896d6acf8aad28e92a46 100644 (file)
@@ -6,7 +6,7 @@
        allow-query-on { <address_match_element>; ... };
        allow-transfer { <address_match_element>; ... };
        allow-update { <address_match_element>; ... };
-       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        auto-dnssec ( allow | maintain | off );
index c142586fe21510935ce26a616b11f59cdc938daf..fee1789fe07733e9d19427366473e3c4e68f4006 100644 (file)
@@ -5,7 +5,7 @@ zone <string> [ <class> ] {
        allow-query-on { <address_match_element>; ... };
        allow-transfer { <address_match_element>; ... };
        allow-update-forwarding { <address_match_element>; ... };
-       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        check-names ( fail | warn | ignore );
@@ -15,7 +15,7 @@ zone <string> [ <class> ] {
        journal <quoted_string>;
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-ixfr-ratio ( unlimited | <percentage> );
        max-journal-size ( default | unlimited | <sizeval> );
        max-records <integer>;
@@ -32,7 +32,7 @@ zone <string> [ <class> ] {
        notify-delay <integer>;
        notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        request-expire <boolean>;
        request-ixfr <boolean>;
        transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
index 84792737dcc3117d1cc43cda52f069be2b4b1a9e..ed63137f8e812353b8bd318cbf284db831c29e7f 100644 (file)
@@ -7,7 +7,7 @@
        allow-query-on { <address_match_element>; ... };
        allow-transfer { <address_match_element>; ... };
        allow-update-forwarding { <address_match_element>; ... };
-       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        check-names ( fail | warn | ignore );
@@ -17,7 +17,7 @@
        journal <quoted_string>;
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-ixfr-ratio ( unlimited | <percentage> );
        max-journal-size ( default | unlimited | <sizeval> );
        max-records <integer>;
@@ -34,7 +34,7 @@
        notify-delay <integer>;
        notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        request-expire <boolean>;
        request-ixfr <boolean>;
        transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
index 3444f6eaf86c46bea652acf6ea2c569bb7241388..1e5bedec9c3edffe722301238869dc27ea211175 100644 (file)
@@ -71,7 +71,8 @@ managed-keys { <string> ( static-key
 masters <string> [ port <integer> ] [ dscp
     <integer> ] { ( <primaries> | <ipv4_address>
     [ port <integer> ] | <ipv6_address> [ port
-    <integer> ] ) [ key <string> ]; ... }; // may occur multiple times
+    <integer> ] ) [ key <string> ] [ tls
+    <string> ]; ... }; // may occur multiple times
 
 options {
         allow-new-zones <boolean>;
@@ -87,7 +88,7 @@ options {
         allow-update-forwarding { <address_match_element>; ... };
         also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
             ] [ dscp <integer> ];
         alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -105,8 +106,9 @@ options {
         catalog-zones { zone <string> [ default-masters [ port <integer> ]
             [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
             <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
-            <string> ]; ... } ] [ zone-directory <quoted_string> ] [
-            in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
+            <string> ] [ tls <string> ]; ... } ] [ zone-directory
+            <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
+            <duration> ]; ... };
         check-dup-records ( fail | warn | ignore );
         check-integrity <boolean>;
         check-mx ( fail | warn | ignore );
@@ -382,7 +384,8 @@ plugin ( query ) <string> [ { <unspecified-text>
 primaries <string> [ port <integer> ] [ dscp
     <integer> ] { ( <primaries> | <ipv4_address>
     [ port <integer> ] | <ipv6_address> [ port
-    <integer> ] ) [ key <string> ]; ... }; // may occur multiple times
+    <integer> ] ) [ key <string> ] [ tls
+    <string> ]; ... }; // may occur multiple times
 
 server <netprefix> {
         bogus <boolean>;
@@ -425,9 +428,11 @@ statistics-channels {
 }; // may occur multiple times
 
 tls <string> {
+        ca-file <quoted_string>;
         cert-file <quoted_string>;
         ciphers <string>; // experimental
         dh-param <quoted_string>; // experimental
+        hostname <quoted_string>;
         key-file <quoted_string>;
         protocols <sslprotos>; // experimental
 }; // may occur multiple times
@@ -455,7 +460,7 @@ view <string> [ <class> ] {
         allow-update-forwarding { <address_match_element>; ... };
         also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
             ] [ dscp <integer> ];
         alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -467,8 +472,9 @@ view <string> [ <class> ] {
         catalog-zones { zone <string> [ default-masters [ port <integer> ]
             [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
             <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
-            <string> ]; ... } ] [ zone-directory <quoted_string> ] [
-            in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
+            <string> ] [ tls <string> ]; ... } ] [ zone-directory
+            <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
+            <duration> ]; ... };
         check-dup-records ( fail | warn | ignore );
         check-integrity <boolean>;
         check-mx ( fail | warn | ignore );
@@ -734,8 +740,8 @@ view <string> [ <class> ] {
                 allow-update-forwarding { <address_match_element>; ... };
                 also-notify [ port <integer> ] [ dscp <integer> ] { (
                     <primaries> | <ipv4_address> [ port <integer> ] |
-                    <ipv6_address> [ port <integer> ] ) [ key <string> ];
-                    ... };
+                    <ipv6_address> [ port <integer> ] ) [ key <string> ] [
+                    tls <string> ]; ... };
                 alt-transfer-source ( <ipv4_address> | * ) [ port (
                     <integer> | * ) ] [ dscp <integer> ];
                 alt-transfer-source-v6 ( <ipv6_address> | * ) [ port (
@@ -775,8 +781,8 @@ view <string> [ <class> ] {
                 masterfile-style ( full | relative );
                 masters [ port <integer> ] [ dscp <integer> ] { (
                     <primaries> | <ipv4_address> [ port <integer> ] |
-                    <ipv6_address> [ port <integer> ] ) [ key <string> ];
-                    ... };
+                    <ipv6_address> [ port <integer> ] ) [ key <string> ] [
+                    tls <string> ]; ... };
                 max-ixfr-ratio ( unlimited | <percentage> );
                 max-journal-size ( default | unlimited | <sizeval> );
                 max-records <integer>;
@@ -800,8 +806,8 @@ view <string> [ <class> ] {
                 nsec3-test-zone <boolean>; // test only
                 primaries [ port <integer> ] [ dscp <integer> ] { (
                     <primaries> | <ipv4_address> [ port <integer> ] |
-                    <ipv6_address> [ port <integer> ] ) [ key <string> ];
-                    ... };
+                    <ipv6_address> [ port <integer> ] ) [ key <string> ] [
+                    tls <string> ]; ... };
                 request-expire <boolean>;
                 request-ixfr <boolean>;
                 serial-update-method ( date | increment | unixtime );
@@ -841,7 +847,7 @@ zone <string> [ <class> ] {
         allow-update-forwarding { <address_match_element>; ... };
         also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
             ] [ dscp <integer> ];
         alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -879,7 +885,7 @@ zone <string> [ <class> ] {
         masterfile-style ( full | relative );
         masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         max-ixfr-ratio ( unlimited | <percentage> );
         max-journal-size ( default | unlimited | <sizeval> );
         max-records <integer>;
@@ -903,7 +909,7 @@ zone <string> [ <class> ] {
         nsec3-test-zone <boolean>; // test only
         primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         request-expire <boolean>;
         request-ixfr <boolean>;
         serial-update-method ( date | increment | unixtime );
index deeda6713141c67b05c0391b523ad8df9e137c9f..0e007d68554e19d6e2d86f1792ace16b3375ce05 100644 (file)
@@ -70,7 +70,8 @@ managed-keys { <string> ( static-key
 masters <string> [ port <integer> ] [ dscp
     <integer> ] { ( <primaries> | <ipv4_address>
     [ port <integer> ] | <ipv6_address> [ port
-    <integer> ] ) [ key <string> ]; ... }; // may occur multiple times
+    <integer> ] ) [ key <string> ] [ tls
+    <string> ]; ... }; // may occur multiple times
 
 options {
         allow-new-zones <boolean>;
@@ -86,7 +87,7 @@ options {
         allow-update-forwarding { <address_match_element>; ... };
         also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
             ] [ dscp <integer> ];
         alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -104,8 +105,9 @@ options {
         catalog-zones { zone <string> [ default-masters [ port <integer> ]
             [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
             <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
-            <string> ]; ... } ] [ zone-directory <quoted_string> ] [
-            in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
+            <string> ] [ tls <string> ]; ... } ] [ zone-directory
+            <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
+            <duration> ]; ... };
         check-dup-records ( fail | warn | ignore );
         check-integrity <boolean>;
         check-mx ( fail | warn | ignore );
@@ -379,7 +381,8 @@ plugin ( query ) <string> [ { <unspecified-text>
 primaries <string> [ port <integer> ] [ dscp
     <integer> ] { ( <primaries> | <ipv4_address>
     [ port <integer> ] | <ipv6_address> [ port
-    <integer> ] ) [ key <string> ]; ... }; // may occur multiple times
+    <integer> ] ) [ key <string> ] [ tls
+    <string> ]; ... }; // may occur multiple times
 
 server <netprefix> {
         bogus <boolean>;
@@ -422,9 +425,11 @@ statistics-channels {
 }; // may occur multiple times
 
 tls <string> {
+        ca-file <quoted_string>;
         cert-file <quoted_string>;
         ciphers <string>; // experimental
         dh-param <quoted_string>; // experimental
+        hostname <quoted_string>;
         key-file <quoted_string>;
         protocols <sslprotos>; // experimental
 }; // may occur multiple times
@@ -452,7 +457,7 @@ view <string> [ <class> ] {
         allow-update-forwarding { <address_match_element>; ... };
         also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
             ] [ dscp <integer> ];
         alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -464,8 +469,9 @@ view <string> [ <class> ] {
         catalog-zones { zone <string> [ default-masters [ port <integer> ]
             [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
             <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
-            <string> ]; ... } ] [ zone-directory <quoted_string> ] [
-            in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
+            <string> ] [ tls <string> ]; ... } ] [ zone-directory
+            <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
+            <duration> ]; ... };
         check-dup-records ( fail | warn | ignore );
         check-integrity <boolean>;
         check-mx ( fail | warn | ignore );
@@ -729,8 +735,8 @@ view <string> [ <class> ] {
                 allow-update-forwarding { <address_match_element>; ... };
                 also-notify [ port <integer> ] [ dscp <integer> ] { (
                     <primaries> | <ipv4_address> [ port <integer> ] |
-                    <ipv6_address> [ port <integer> ] ) [ key <string> ];
-                    ... };
+                    <ipv6_address> [ port <integer> ] ) [ key <string> ] [
+                    tls <string> ]; ... };
                 alt-transfer-source ( <ipv4_address> | * ) [ port (
                     <integer> | * ) ] [ dscp <integer> ];
                 alt-transfer-source-v6 ( <ipv6_address> | * ) [ port (
@@ -770,8 +776,8 @@ view <string> [ <class> ] {
                 masterfile-style ( full | relative );
                 masters [ port <integer> ] [ dscp <integer> ] { (
                     <primaries> | <ipv4_address> [ port <integer> ] |
-                    <ipv6_address> [ port <integer> ] ) [ key <string> ];
-                    ... };
+                    <ipv6_address> [ port <integer> ] ) [ key <string> ] [
+                    tls <string> ]; ... };
                 max-ixfr-ratio ( unlimited | <percentage> );
                 max-journal-size ( default | unlimited | <sizeval> );
                 max-records <integer>;
@@ -794,8 +800,8 @@ view <string> [ <class> ] {
                 notify-to-soa <boolean>;
                 primaries [ port <integer> ] [ dscp <integer> ] { (
                     <primaries> | <ipv4_address> [ port <integer> ] |
-                    <ipv6_address> [ port <integer> ] ) [ key <string> ];
-                    ... };
+                    <ipv6_address> [ port <integer> ] ) [ key <string> ] [
+                    tls <string> ]; ... };
                 request-expire <boolean>;
                 request-ixfr <boolean>;
                 serial-update-method ( date | increment | unixtime );
@@ -835,7 +841,7 @@ zone <string> [ <class> ] {
         allow-update-forwarding { <address_match_element>; ... };
         also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
             ] [ dscp <integer> ];
         alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -873,7 +879,7 @@ zone <string> [ <class> ] {
         masterfile-style ( full | relative );
         masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         max-ixfr-ratio ( unlimited | <percentage> );
         max-journal-size ( default | unlimited | <sizeval> );
         max-records <integer>;
@@ -896,7 +902,7 @@ zone <string> [ <class> ] {
         notify-to-soa <boolean>;
         primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
             <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-            <integer> ] ) [ key <string> ]; ... };
+            <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
         request-expire <boolean>;
         request-ixfr <boolean>;
         serial-update-method ( date | increment | unixtime );
index 4fdc098aaef36934d76c1ac86e636bda672200c9..30aee7b7c98a6292dde8d7c6978bd2bf4383aa85 100644 (file)
@@ -14,7 +14,7 @@
        allow-update-forwarding { <address_match_element>; ... };
        also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
            <ipv4_address> [ port <integer> ] | <ipv6_address> [ port
-           <integer> ] ) [ key <string> ]; ... };
+           <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
            ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -32,8 +32,9 @@
        catalog-zones { zone <string> [ default-masters [ port <integer> ]
            [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
            <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
-           <string> ]; ... } ] [ zone-directory <quoted_string> ] [
-           in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
+           <string> ] [ tls <string> ]; ... } ] [ zone-directory
+           <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
+           <duration> ]; ... };
        check-dup-records ( fail | warn | ignore );
        check-integrity <boolean>;
        check-mx ( fail | warn | ignore );
index 2f6ba537d8609fd0d57c13b1d2683ea0c3da92b5..cfc7601724659961b0670406204974dc46dd9772 100644 (file)
@@ -3,4 +3,5 @@
   primaries <string> [ port <integer> ] [ dscp
       <integer> ] { ( <primaries> | <ipv4_address>
       [ port <integer> ] | <ipv6_address> [ port
-      <integer> ] ) [ key <string> ]; ... };
+      <integer> ] ) [ key <string> ] [ tls
+      <string> ]; ... };
index 40df0e5b9c9816108c794f65a9823c3d7520678d..ac53d5499ca1104656fd5b09494cc25e6ff9433e 100644 (file)
@@ -6,9 +6,9 @@ zone <string> [ <class> ] {
        file <quoted_string>;
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-records <integer>;
        max-zone-ttl ( unlimited | <duration> );
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        zone-statistics ( full | terse | none | <boolean> );
 };
index 5a08a22e3c25af14ac252fa3de731485cbb072b9..bf263cd00d8bacfd4246c18e0568c166b17de960 100644 (file)
@@ -8,9 +8,9 @@
        file <quoted_string>;
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-records <integer>;
        max-zone-ttl ( unlimited | <duration> );
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        zone-statistics ( full | terse | none | <boolean> );
   };
index 040f2d5b69a2dd16900826b79c560d55ee0ced04..169ed8481072e15b524860c450aebfd6c68c63db 100644 (file)
@@ -5,7 +5,7 @@ zone <string> [ <class> ] {
        allow-query-on { <address_match_element>; ... };
        allow-transfer { <address_match_element>; ... };
        allow-update-forwarding { <address_match_element>; ... };
-       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        auto-dnssec ( allow | maintain | off );
@@ -27,7 +27,7 @@ zone <string> [ <class> ] {
        key-directory <quoted_string>;
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-ixfr-ratio ( unlimited | <percentage> );
        max-journal-size ( default | unlimited | <sizeval> );
        max-records <integer>;
@@ -45,7 +45,7 @@ zone <string> [ <class> ] {
        notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        notify-to-soa <boolean>;
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        request-expire <boolean>;
        request-ixfr <boolean>;
        sig-signing-nodes <integer>;
index d9617de9d341b55b8d2eec20be44399d55262566..6f2da9559d5a67dd474adad7b7ae951351932af5 100644 (file)
@@ -7,7 +7,7 @@
        allow-query-on { <address_match_element>; ... };
        allow-transfer { <address_match_element>; ... };
        allow-update-forwarding { <address_match_element>; ... };
-       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        auto-dnssec ( allow | maintain | off );
@@ -29,7 +29,7 @@
        key-directory <quoted_string>;
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-ixfr-ratio ( unlimited | <percentage> );
        max-journal-size ( default | unlimited | <sizeval> );
        max-records <integer>;
@@ -47,7 +47,7 @@
        notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        notify-to-soa <boolean>;
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        request-expire <boolean>;
        request-ixfr <boolean>;
        sig-signing-nodes <integer>;
index d7c583bbb1098549fa6a6534bf5cfe3b9e086664..c616cc687f3a33cd3a78102bf0c46e0f3e013c07 100644 (file)
@@ -11,7 +11,7 @@ zone <string> [ <class> ] {
        forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-records <integer>;
        max-refresh-time <integer>;
        max-retry-time <integer>;
@@ -20,7 +20,7 @@ zone <string> [ <class> ] {
        min-refresh-time <integer>;
        min-retry-time <integer>;
        multi-master <boolean>;
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        use-alt-transfer-source <boolean>;
index 02e7cc8d356ab938843bfe4442d4642f0047d3cd..d00a0c17852779c95477074c308df67658c805c1 100644 (file)
@@ -13,7 +13,7 @@
        forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
        masterfile-format ( map | raw | text );
        masterfile-style ( full | relative );
-       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        max-records <integer>;
        max-refresh-time <integer>;
        max-retry-time <integer>;
@@ -22,7 +22,7 @@
        min-refresh-time <integer>;
        min-retry-time <integer>;
        multi-master <boolean>;
-       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
+       primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
        transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
        use-alt-transfer-source <boolean>;
diff --git a/doc/misc/tls.grammar.rst b/doc/misc/tls.grammar.rst
new file mode 100644 (file)
index 0000000..f610a77
--- /dev/null
@@ -0,0 +1,11 @@
+::
+
+  tls <string> {
+       ca-file <quoted_string>;
+       cert-file <quoted_string>;
+       ciphers <string>; // experimental
+       dh-param <quoted_string>; // experimental
+       hostname <quoted_string>;
+       key-file <quoted_string>;
+       protocols <sslprotos>; // experimental
+  };
index d996b5b16da11d1b4cb496bbc178e36704dc74b9..6cb69a307f4007a8e283e19c753f7d24760d9931 100644 (file)
@@ -129,6 +129,7 @@ libdns_la_HEADERS =                 \
        include/dns/tcpmsg.h            \
        include/dns/time.h              \
        include/dns/timer.h             \
+       include/dns/transport.h         \
        include/dns/tkey.h              \
        include/dns/tsec.h              \
        include/dns/tsig.h              \
@@ -232,6 +233,7 @@ libdns_la_SOURCES =                 \
        tcpmsg.c                        \
        time.c                          \
        timer.c                         \
+       transport.c                     \
        tkey.c                          \
        tsec.c                          \
        tsig.c                          \
index 1afce6541841b2a42262fe4686c79490373030f0..2be60c35b6173fcbe241ee829609fb490452f90e 100644 (file)
@@ -26,6 +26,7 @@ struct dns_ipkeylist {
        isc_sockaddr_t *addrs;
        isc_dscp_t *    dscps;
        dns_name_t **   keys;
+       dns_name_t **   tlss;
        dns_name_t **   labels;
        uint32_t        count;
        uint32_t        allocated;
diff --git a/lib/dns/include/dns/transport.h b/lib/dns/include/dns/transport.h
new file mode 100644 (file)
index 0000000..0b03152
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <dns/name.h>
+
+typedef enum {
+       DNS_TRANSPORT_NONE = 0,
+       DNS_TRANSPORT_UDP = 1,
+       DNS_TRANSPORT_TCP = 2,
+       DNS_TRANSPORT_TLS = 3,
+       DNS_TRANSPORT_DOH = 4,
+       DNS_TRANSPORT_COUNT = 5,
+} dns_transport_type_t;
+
+typedef enum {
+       DNS_DOH_GET = 0,
+       DNS_DOH_POST = 1,
+} dns_doh_mode_t;
+
+typedef struct dns_transport     dns_transport_t;
+typedef struct dns_transport_list dns_transport_list_t;
+
+dns_transport_t *
+dns_transport_new(const dns_name_t *name, dns_transport_type_t type,
+                 dns_transport_list_t *list);
+/*%<
+ * Create a new transport object with name 'name' and type 'type',
+ * and append it to 'list'.
+ */
+
+dns_transport_type_t
+dns_transport_get_type(dns_transport_t *transport);
+char *
+dns_transport_get_certfile(dns_transport_t *transport);
+char *
+dns_transport_get_keyfile(dns_transport_t *transport);
+char *
+dns_transport_get_cafile(dns_transport_t *transport);
+char *
+dns_transport_get_hostname(dns_transport_t *transport);
+char *
+dns_transport_get_endpoint(dns_transport_t *transport);
+dns_doh_mode_t
+dns_transport_get_mode(dns_transport_t *transport);
+/*%<
+ * Getter functions: return the type, cert file, key file, CA file,
+ * hostname, DoH endpoint, or DoH mode (GET or POST) for 'transport'.
+ */
+
+void
+dns_transport_set_certfile(dns_transport_t *transport, const char *certfile);
+void
+dns_transport_set_keyfile(dns_transport_t *transport, const char *keyfile);
+void
+dns_transport_set_cafile(dns_transport_t *transport, const char *cafile);
+void
+dns_transport_set_hostname(dns_transport_t *transport, const char *hostname);
+void
+dns_transport_set_endpoint(dns_transport_t *transport, const char *endpoint);
+void
+dns_transport_set_mode(dns_transport_t *transport, dns_doh_mode_t mode);
+/*%<
+ * Setter functions: set the type, cert file, key file, CA file,
+ * hostname, DoH endpoint, or DoH mode (GET or POST) for 'transport'.
+ *
+ * Requires:
+ *\li  'transport' is valid.
+ *\li  'transport' is of type DNS_TRANSPORT_TLS or DNS_TRANSPORT_DOH
+ *     (for certfile, keyfile, cafile, or hostname).
+ *\li  'transport' is of type DNS_TRANSPORT_DOH (for endpoint or mode).
+ */
+
+void
+dns_transport_attach(dns_transport_t *source, dns_transport_t **targetp);
+/*%<
+ * Attach to a transport object.
+ *
+ * Requires:
+ *\li  'source' is a valid transport.
+ *\li  'targetp' is not NULL and '*targetp' is NULL.
+ */
+
+void
+dns_transport_detach(dns_transport_t **transportp);
+/*%<
+ * Detach a transport object; destroy it if there are no remaining
+ * references.
+ *
+ * Requires:
+ *\li  'transportp' is not NULL.
+ *\li  '*transportp' is a valid transport.
+ */
+
+dns_transport_t *
+dns_transport_find(const dns_transport_type_t type, const dns_name_t *name,
+                  dns_transport_list_t *list);
+/*%<
+ * Find a transport matching type 'type' and name `name` in 'list'.
+ *
+ * Requires:
+ *\li  'list' is valid.
+ *\li  'list' contains a table of type 'type' transports.
+ */
+
+dns_transport_list_t *
+dns_transport_list_new(isc_mem_t *mctx);
+/*%<
+ * Create a new transport list.
+ */
+
+void
+dns_transport_list_attach(dns_transport_list_t * source,
+                         dns_transport_list_t **targetp);
+/*%<
+ * Attach to a transport list.
+ *
+ * Requires:
+ *\li  'source' is a valid transport list.
+ *\li  'targetp' is not NULL and '*targetp' is NULL.
+ */
+
+void
+dns_transport_list_detach(dns_transport_list_t **listp);
+/*%<
+ * Detach a transport list; destroy it if there are no remaining
+ * references.
+ *
+ * Requires:
+ *\li  'listp' is not NULL.
+ *\li  '*listp' is a valid transport list.
+ */
index c0a4eb5d53c654468cfb93241495b93c2c870eeb..937c0e55a90817952d899bec926ccd12a37593c9 100644 (file)
@@ -73,6 +73,7 @@
 #include <dns/rdatastruct.h>
 #include <dns/rpz.h>
 #include <dns/rrl.h>
+#include <dns/transport.h>
 #include <dns/types.h>
 #include <dns/zt.h>
 
@@ -111,6 +112,7 @@ struct dns_view {
        bool         cacheshared;
 
        /* Configurable data. */
+       dns_transport_list_t *transports;
        dns_tsig_keyring_t *  statickeys;
        dns_tsig_keyring_t *  dynamickeys;
        dns_peerlist_t *      peers;
@@ -454,6 +456,9 @@ dns_view_sethints(dns_view_t *view, dns_db_t *hints);
  * \li         The hints database of 'view' is 'hints'.
  */
 
+void
+dns_view_settransports(dns_view_t *view, dns_transport_list_t *list);
+
 void
 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring);
 void
@@ -817,6 +822,10 @@ dns_view_asyncload(dns_view_t *view, bool newonly, dns_zt_allloaded_t callback,
  *\li  'view' is valid.
  */
 
+isc_result_t
+dns_view_gettransport(dns_view_t *view, const dns_transport_type_t type,
+                     const dns_name_t *name, dns_transport_t **transportp);
+
 isc_result_t
 dns_view_gettsig(dns_view_t *view, const dns_name_t *keyname,
                 dns_tsigkey_t **keyp);
index 253f90e6843d22edf19a8658df7d7676c40d8c68..cb7364768dbf8b31ce3deb662418904ab31634d0 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <isc/lang.h>
 
+#include <dns/transport.h>
 #include <dns/types.h>
 
 /***
@@ -48,8 +49,9 @@ isc_result_t
 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
                 const isc_sockaddr_t *masteraddr,
                 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
-                dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_nm_t *netmgr,
-                dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp);
+                dns_tsigkey_t *tsigkey, dns_transport_t *transport,
+                isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
+                dns_xfrin_ctx_t **xfrp);
 /*%<
  * Attempt to start an incoming zone transfer of 'zone'
  * from 'masteraddr', creating a dns_xfrin_ctx_t object to
index ec9991a78f1ccaa32ff38db9fe7f42880a1ffa74..822989ab82ac4c8dab20445d3b32e98de0b8e818 100644 (file)
@@ -625,10 +625,8 @@ dns_zone_maintenance(dns_zone_t *zone);
 
 isc_result_t
 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
+                     dns_name_t **keynames, dns_name_t **tlsnames,
                      uint32_t count);
-isc_result_t
-dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *primaries,
-                             dns_name_t **keynames, uint32_t count);
 /*%<
  *     Set the list of master servers for the zone.
  *
@@ -651,14 +649,8 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *primaries,
 
 isc_result_t
 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
-                      uint32_t count);
-isc_result_t
-dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
-                              dns_name_t **keynames, uint32_t count);
-isc_result_t
-dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
-                              const isc_dscp_t *dscps, dns_name_t **keynames,
-                              uint32_t count);
+                      const isc_dscp_t *dscps, dns_name_t **keynames,
+                      dns_name_t **tlsnames, uint32_t count);
 /*%<
  *     Set the list of additional servers to be notified when
  *     a zone changes.  To clear the list use 'count = 0'.
index 8eca1820d4bcc35a2d3d2804924bf37b0ee4d9c4..76788d8831735804f22ec6169d7bafda417af042 100644 (file)
@@ -26,6 +26,7 @@ dns_ipkeylist_init(dns_ipkeylist_t *ipkl) {
        ipkl->addrs = NULL;
        ipkl->dscps = NULL;
        ipkl->keys = NULL;
+       ipkl->tlss = NULL;
        ipkl->labels = NULL;
 }
 
@@ -63,6 +64,20 @@ dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) {
                            ipkl->allocated * sizeof(dns_name_t *));
        }
 
+       if (ipkl->tlss != NULL) {
+               for (i = 0; i < ipkl->allocated; i++) {
+                       if (ipkl->tlss[i] == NULL) {
+                               continue;
+                       }
+                       if (dns_name_dynamic(ipkl->tlss[i])) {
+                               dns_name_free(ipkl->tlss[i], mctx);
+                       }
+                       isc_mem_put(mctx, ipkl->tlss[i], sizeof(dns_name_t));
+               }
+               isc_mem_put(mctx, ipkl->tlss,
+                           ipkl->allocated * sizeof(dns_name_t *));
+       }
+
        if (ipkl->labels != NULL) {
                for (i = 0; i < ipkl->allocated; i++) {
                        if (ipkl->labels[i] == NULL) {
@@ -119,6 +134,19 @@ dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src,
                }
        }
 
+       if (src->tlss != NULL) {
+               for (i = 0; i < src->count; i++) {
+                       if (src->tlss[i] != NULL) {
+                               dst->tlss[i] = isc_mem_get(mctx,
+                                                          sizeof(dns_name_t));
+                               dns_name_init(dst->tlss[i], NULL);
+                               dns_name_dup(src->tlss[i], mctx, dst->tlss[i]);
+                       } else {
+                               dst->tlss[i] = NULL;
+                       }
+               }
+       }
+
        if (src->labels != NULL) {
                for (i = 0; i < src->count; i++) {
                        if (src->labels[i] != NULL) {
@@ -141,6 +169,7 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
        isc_sockaddr_t *addrs = NULL;
        isc_dscp_t *dscps = NULL;
        dns_name_t **keys = NULL;
+       dns_name_t **tlss = NULL;
        dns_name_t **labels = NULL;
 
        REQUIRE(ipkl != NULL);
@@ -153,6 +182,7 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
        addrs = isc_mem_get(mctx, n * sizeof(isc_sockaddr_t));
        dscps = isc_mem_get(mctx, n * sizeof(isc_dscp_t));
        keys = isc_mem_get(mctx, n * sizeof(dns_name_t *));
+       tlss = isc_mem_get(mctx, n * sizeof(dns_name_t *));
        labels = isc_mem_get(mctx, n * sizeof(dns_name_t *));
 
        if (ipkl->addrs != NULL) {
@@ -185,6 +215,16 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
        memset(&ipkl->keys[ipkl->allocated], 0,
               (n - ipkl->allocated) * sizeof(dns_name_t *));
 
+       if (ipkl->tlss) {
+               memmove(tlss, ipkl->tlss,
+                       ipkl->allocated * sizeof(dns_name_t *));
+               isc_mem_put(mctx, ipkl->tlss,
+                           ipkl->allocated * sizeof(dns_name_t *));
+       }
+       ipkl->tlss = tlss;
+       memset(&ipkl->tlss[ipkl->allocated], 0,
+              (n - ipkl->allocated) * sizeof(dns_name_t *));
+
        if (ipkl->labels != NULL) {
                memmove(labels, ipkl->labels,
                        ipkl->allocated * sizeof(dns_name_t *));
@@ -200,6 +240,7 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
 
        isc_mem_put(mctx, addrs, n * sizeof(isc_sockaddr_t));
        isc_mem_put(mctx, dscps, n * sizeof(isc_dscp_t));
+       isc_mem_put(mctx, tlss, n * sizeof(dns_name_t *));
        isc_mem_put(mctx, keys, n * sizeof(dns_name_t *));
        isc_mem_put(mctx, labels, n * sizeof(dns_name_t *));
 
diff --git a/lib/dns/transport.c b/lib/dns/transport.c
new file mode 100644 (file)
index 0000000..2dcc8a9
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <inttypes.h>
+
+#include <isc/list.h>
+#include <isc/mem.h>
+#include <isc/refcount.h>
+#include <isc/result.h>
+#include <isc/rwlock.h>
+#include <isc/util.h>
+
+#include <dns/name.h>
+#include <dns/rbt.h>
+#include <dns/result.h>
+#include <dns/transport.h>
+
+#define TRANSPORT_MAGIC             ISC_MAGIC('T', 'r', 'n', 's')
+#define VALID_TRANSPORT(ptr) ISC_MAGIC_VALID(ptr, TRANSPORT_MAGIC)
+
+#define TRANSPORT_LIST_MAGIC     ISC_MAGIC('T', 'r', 'L', 's')
+#define VALID_TRANSPORT_LIST(ptr) ISC_MAGIC_VALID(ptr, TRANSPORT_LIST_MAGIC)
+
+struct dns_transport_list {
+       unsigned int magic;
+       isc_refcount_t references;
+       isc_mem_t *mctx;
+       isc_rwlock_t lock;
+       dns_rbt_t *transports[DNS_TRANSPORT_COUNT];
+};
+
+struct dns_transport {
+       unsigned int magic;
+       isc_refcount_t references;
+       isc_mem_t *mctx;
+       dns_transport_type_t type;
+       struct {
+               char *certfile;
+               char *keyfile;
+               char *cafile;
+               char *hostname;
+       } tls;
+       struct {
+               char *endpoint;
+               dns_doh_mode_t mode;
+       } doh;
+};
+
+static void
+free_dns_transport(void *node, void *arg) {
+       dns_transport_t *transport = node;
+
+       REQUIRE(node != NULL);
+
+       UNUSED(arg);
+
+       dns_transport_detach(&transport);
+}
+
+static isc_result_t
+list_add(dns_transport_list_t *list, const dns_name_t *name,
+        const dns_transport_type_t type, dns_transport_t *transport) {
+       isc_result_t result;
+       dns_rbt_t *rbt = NULL;
+
+       RWLOCK(&list->lock, isc_rwlocktype_write);
+       rbt = list->transports[type];
+       INSIST(rbt != NULL);
+
+       result = dns_rbt_addname(rbt, name, transport);
+
+       RWUNLOCK(&list->lock, isc_rwlocktype_write);
+
+       return (result);
+}
+
+dns_transport_type_t
+dns_transport_get_type(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->type);
+}
+
+char *
+dns_transport_get_certfile(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->tls.certfile);
+}
+
+char *
+dns_transport_get_keyfile(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->tls.keyfile);
+}
+
+char *
+dns_transport_get_cafile(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->tls.cafile);
+}
+
+char *
+dns_transport_get_hostname(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->tls.hostname);
+}
+
+char *
+dns_transport_get_endpoint(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->doh.endpoint);
+}
+
+dns_doh_mode_t
+dns_transport_get_mode(dns_transport_t *transport) {
+       REQUIRE(VALID_TRANSPORT(transport));
+
+       return (transport->doh.mode);
+}
+
+dns_transport_t *
+dns_transport_new(const dns_name_t *name, dns_transport_type_t type,
+                 dns_transport_list_t *list) {
+       dns_transport_t *transport = isc_mem_get(list->mctx,
+                                                sizeof(*transport));
+       *transport = (dns_transport_t){ .type = type };
+       isc_refcount_init(&transport->references, 1);
+       isc_mem_attach(list->mctx, &transport->mctx);
+       transport->magic = TRANSPORT_MAGIC;
+
+       list_add(list, name, type, transport);
+
+       return (transport);
+}
+
+void
+dns_transport_set_certfile(dns_transport_t *transport, const char *certfile) {
+       REQUIRE(VALID_TRANSPORT(transport));
+       REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
+               transport->type == DNS_TRANSPORT_DOH);
+
+       if (certfile != NULL) {
+               transport->tls.certfile = isc_mem_strdup(transport->mctx,
+                                                        certfile);
+       }
+}
+
+void
+dns_transport_set_keyfile(dns_transport_t *transport, const char *keyfile) {
+       REQUIRE(VALID_TRANSPORT(transport));
+       REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
+               transport->type == DNS_TRANSPORT_DOH);
+
+       if (keyfile != NULL) {
+               transport->tls.keyfile = isc_mem_strdup(transport->mctx,
+                                                       keyfile);
+       }
+}
+
+void
+dns_transport_set_cafile(dns_transport_t *transport, const char *cafile) {
+       REQUIRE(VALID_TRANSPORT(transport));
+       REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
+               transport->type == DNS_TRANSPORT_DOH);
+
+       if (cafile != NULL) {
+               transport->tls.cafile = isc_mem_strdup(transport->mctx, cafile);
+       }
+}
+
+void
+dns_transport_set_hostname(dns_transport_t *transport, const char *hostname) {
+       REQUIRE(VALID_TRANSPORT(transport));
+       REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
+               transport->type == DNS_TRANSPORT_DOH);
+
+       if (hostname != NULL) {
+               transport->tls.hostname = isc_mem_strdup(transport->mctx,
+                                                        hostname);
+       }
+}
+
+void
+dns_transport_set_endpoint(dns_transport_t *transport, const char *endpoint) {
+       REQUIRE(VALID_TRANSPORT(transport));
+       REQUIRE(transport->type == DNS_TRANSPORT_DOH);
+
+       if (endpoint != NULL) {
+               transport->doh.endpoint = isc_mem_strdup(transport->mctx,
+                                                        endpoint);
+       }
+}
+
+void
+dns_transport_set_mode(dns_transport_t *transport, dns_doh_mode_t mode) {
+       REQUIRE(VALID_TRANSPORT(transport));
+       REQUIRE(transport->type == DNS_TRANSPORT_DOH);
+
+       transport->doh.mode = mode;
+}
+
+static void
+transport_destroy(dns_transport_t *transport) {
+       isc_refcount_destroy(&transport->references);
+       transport->magic = 0;
+
+       if (transport->doh.endpoint != NULL) {
+               isc_mem_free(transport->mctx, transport->doh.endpoint);
+       }
+       if (transport->tls.hostname != NULL) {
+               isc_mem_free(transport->mctx, transport->tls.hostname);
+       }
+       if (transport->tls.cafile != NULL) {
+               isc_mem_free(transport->mctx, transport->tls.cafile);
+       }
+       if (transport->tls.keyfile != NULL) {
+               isc_mem_free(transport->mctx, transport->tls.keyfile);
+       }
+       if (transport->tls.certfile != NULL) {
+               isc_mem_free(transport->mctx, transport->tls.certfile);
+       }
+
+       isc_mem_putanddetach(&transport->mctx, transport, sizeof(*transport));
+}
+
+void
+dns_transport_attach(dns_transport_t *source, dns_transport_t **targetp) {
+       REQUIRE(source != NULL);
+       REQUIRE(targetp != NULL && *targetp == NULL);
+
+       isc_refcount_increment(&source->references);
+
+       *targetp = source;
+}
+
+void
+dns_transport_detach(dns_transport_t **transportp) {
+       dns_transport_t *transport = NULL;
+
+       REQUIRE(transportp != NULL);
+       REQUIRE(VALID_TRANSPORT(*transportp));
+
+       transport = *transportp;
+       *transportp = NULL;
+
+       if (isc_refcount_decrement(&transport->references) == 1) {
+               transport_destroy(transport);
+       }
+}
+
+dns_transport_t *
+dns_transport_find(const dns_transport_type_t type, const dns_name_t *name,
+                  dns_transport_list_t *list) {
+       isc_result_t result;
+       dns_transport_t *transport = NULL;
+       dns_rbt_t *rbt = NULL;
+
+       REQUIRE(VALID_TRANSPORT_LIST(list));
+       REQUIRE(list->transports[type] != NULL);
+
+       rbt = list->transports[type];
+
+       RWLOCK(&list->lock, isc_rwlocktype_read);
+       result = dns_rbt_findname(rbt, name, 0, NULL, (void *)&transport);
+       if (result == ISC_R_SUCCESS) {
+               isc_refcount_increment(&transport->references);
+       }
+       RWUNLOCK(&list->lock, isc_rwlocktype_read);
+
+       return (transport);
+}
+
+dns_transport_list_t *
+dns_transport_list_new(isc_mem_t *mctx) {
+       dns_transport_list_t *list = isc_mem_get(mctx, sizeof(*list));
+
+       *list = (dns_transport_list_t){ 0 };
+
+       isc_rwlock_init(&list->lock, 0, 0);
+
+       isc_mem_attach(mctx, &list->mctx);
+       isc_refcount_init(&list->references, 1);
+
+       list->magic = TRANSPORT_LIST_MAGIC;
+
+       for (size_t type = 0; type < DNS_TRANSPORT_COUNT; type++) {
+               isc_result_t result;
+               result = dns_rbt_create(list->mctx, free_dns_transport, NULL,
+                                       &list->transports[type]);
+               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+       }
+
+       return (list);
+}
+
+void
+dns_transport_list_attach(dns_transport_list_t *source,
+                         dns_transport_list_t **targetp) {
+       REQUIRE(VALID_TRANSPORT_LIST(source));
+       REQUIRE(targetp != NULL && *targetp == NULL);
+
+       isc_refcount_increment(&source->references);
+
+       *targetp = source;
+}
+
+static void
+transport_list_destroy(dns_transport_list_t *list) {
+       isc_refcount_destroy(&list->references);
+       list->magic = 0;
+
+       for (size_t type = 0; type < DNS_TRANSPORT_COUNT; type++) {
+               if (list->transports[type] != NULL) {
+                       dns_rbt_destroy(&list->transports[type]);
+               }
+       }
+       isc_rwlock_destroy(&list->lock);
+       isc_mem_putanddetach(&list->mctx, list, sizeof(*list));
+}
+
+void
+dns_transport_list_detach(dns_transport_list_t **listp) {
+       dns_transport_list_t *list = NULL;
+
+       REQUIRE(listp != NULL);
+       REQUIRE(VALID_TRANSPORT_LIST(*listp));
+
+       list = *listp;
+       *listp = NULL;
+
+       if (isc_refcount_decrement(&list->references) == 1) {
+               transport_list_destroy(list);
+       }
+}
index 3572cec04a7412eacf460af117da2fd9f285f501..87aaec269a9de499c2157331cde6e6f0bed2f157 100644 (file)
@@ -56,6 +56,7 @@
 #include <dns/rrl.h>
 #include <dns/stats.h>
 #include <dns/time.h>
+#include <dns/transport.h>
 #include <dns/tsig.h>
 #include <dns/zone.h>
 #include <dns/zt.h>
@@ -152,6 +153,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
        atomic_init(&view->attributes,
                    (DNS_VIEWATTR_RESSHUTDOWN | DNS_VIEWATTR_ADBSHUTDOWN |
                     DNS_VIEWATTR_REQSHUTDOWN));
+       view->transports = NULL;
        view->statickeys = NULL;
        view->dynamickeys = NULL;
        view->matchclients = NULL;
@@ -397,6 +399,9 @@ destroy(dns_view_t *view) {
                        }
                }
        }
+       if (view->transports != NULL) {
+               dns_transport_list_detach(&view->transports);
+       }
        if (view->statickeys != NULL) {
                dns_tsigkeyring_detach(&view->statickeys);
        }
@@ -884,6 +889,16 @@ dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
        dns_db_attach(hints, &view->hints);
 }
 
+void
+dns_view_settransports(dns_view_t *view, dns_transport_list_t *list) {
+       REQUIRE(DNS_VIEW_VALID(view));
+       REQUIRE(list != NULL);
+       if (view->transports != NULL) {
+               dns_transport_list_detach(&view->transports);
+       }
+       dns_transport_list_attach(list, &view->transports);
+}
+
 void
 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
        REQUIRE(DNS_VIEW_VALID(view));
@@ -1589,6 +1604,22 @@ dns_view_gettsig(dns_view_t *view, const dns_name_t *keyname,
        return (result);
 }
 
+isc_result_t
+dns_view_gettransport(dns_view_t *view, const dns_transport_type_t type,
+                     const dns_name_t *name, dns_transport_t **transportp) {
+       REQUIRE(DNS_VIEW_VALID(view));
+       REQUIRE(transportp != NULL && *transportp == NULL);
+
+       dns_transport_t *transport = dns_transport_find(type, name,
+                                                       view->transports);
+       if (transport == NULL) {
+               return (ISC_R_NOTFOUND);
+       }
+
+       *transportp = transport;
+       return (ISC_R_SUCCESS);
+}
+
 isc_result_t
 dns_view_getpeertsig(dns_view_t *view, const isc_netaddr_t *peeraddr,
                     dns_tsigkey_t **keyp) {
index ce495393c2e1d4c5dfe304c2ce8571aab4be4646..2dce5121e87455da350a47ff0a52a4670a31d9d5 100644 (file)
@@ -1059,6 +1059,26 @@ dns_tkey_processgssresponse
 dns_tkey_processquery
 dns_tkeyctx_create
 dns_tkeyctx_destroy
+dns_transport_attach
+dns_transport_detach
+dns_transport_find
+dns_transport_get_cafile
+dns_transport_get_certfile
+dns_transport_get_endpoint
+dns_transport_get_hostname
+dns_transport_get_keyfile
+dns_transport_get_mode
+dns_transport_get_type
+dns_transport_list_attach
+dns_transport_list_detach
+dns_transport_list_new
+dns_transport_new
+dns_transport_set_cafile
+dns_transport_set_certfile
+dns_transport_set_endpoint
+dns_transport_set_hostname
+dns_transport_set_keyfile
+dns_transport_set_mode
 dns_trust_totext
 dns_tsec_create
 dns_tsec_destroy
@@ -1120,6 +1140,7 @@ dns_view_getresquerystats
 dns_view_getresstats
 dns_view_getrootdelonly
 dns_view_getsecroots
+dns_view_gettransport
 dns_view_gettsig
 dns_view_initntatable
 dns_view_initsecroots
@@ -1144,6 +1165,7 @@ dns_view_setnewzones
 dns_view_setresquerystats
 dns_view_setresstats
 dns_view_setrootdelonly
+dns_view_settransports
 dns_view_setviewcommit
 dns_view_setviewrevert
 dns_view_simplefind
@@ -1283,8 +1305,6 @@ dns_zone_secure_to_insecure
 dns_zone_set_parentcatz
 dns_zone_setadded
 dns_zone_setalsonotify
-dns_zone_setalsonotifydscpkeys
-dns_zone_setalsonotifywithkeys
 dns_zone_setaltxfrsource4
 dns_zone_setaltxfrsource4dscp
 dns_zone_setaltxfrsource6
@@ -1332,7 +1352,6 @@ dns_zone_setnsec3param
 dns_zone_setoption
 dns_zone_setorigin
 dns_zone_setprimaries
-dns_zone_setprimarieswithkeys
 dns_zone_setprivatetype
 dns_zone_setqueryacl
 dns_zone_setqueryonacl
index a7de95a273bc4c62c6d66528a8796eac1b7858ea..503464efee6b246ffbb114e79d71362c20d7e978 100644 (file)
     <ClCompile Include="..\tkey.c">
       <Filter>Library Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\transport.c">
+      <Filter>Library Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\tsec.c">
       <Filter>Library Source Files</Filter>
     </ClCompile>
     <ClInclude Include="..\include\dns\tkey.h">
       <Filter>Library Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\dns\transport.h">
+      <Filter>Library Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\include\dns\tsec.h">
       <Filter>Library Header Files</Filter>
     </ClInclude>
index e08156afee6baac9d748203ff0ce47202dde11e0..a5f31f1752a643e21009d876953cb22403467ba1 100644 (file)
     <ClCompile Include="..\time.c" />
     <ClCompile Include="..\timer.c" />
     <ClCompile Include="..\tkey.c" />
+    <ClCompile Include="..\transport.c" />
     <ClCompile Include="..\tsec.c" />
     <ClCompile Include="..\tsig.c" />
     <ClCompile Include="..\ttl.c" />
     <ClInclude Include="..\include\dns\time.h" />
     <ClInclude Include="..\include\dns\timer.h" />
     <ClInclude Include="..\include\dns\tkey.h" />
+    <ClInclude Include="..\include\dns\transport.h" />
     <ClInclude Include="..\include\dns\tsec.h" />
     <ClInclude Include="..\include\dns\tsig.h" />
     <ClInclude Include="..\include\dns\ttl.h" />
index 2adfac46a6d6913db4e7a890e5e9552cb955b2e8..c0e06cf71a12ec19699d7daef66a23ed993ac4b2 100644 (file)
@@ -35,6 +35,7 @@
 #include <dns/result.h>
 #include <dns/soa.h>
 #include <dns/tcpmsg.h>
+#include <dns/transport.h>
 #include <dns/tsig.h>
 #include <dns/view.h>
 #include <dns/xfrin.h>
@@ -160,6 +161,10 @@ struct dns_xfrin_ctx {
        isc_buffer_t *lasttsig; /*%< The last TSIG */
        dst_context_t *tsigctx; /*%< TSIG verification context */
        unsigned int sincetsig; /*%< recvd since the last TSIG */
+
+       dns_transport_t *transport;
+       isc_tlsctx_t *tlsctx;
+
        dns_xfrindone_t done;
 
        /*%
@@ -190,7 +195,8 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
             dns_name_t *zonename, dns_rdataclass_t rdclass,
             dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
             const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
-            dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp);
+            dns_tsigkey_t *tsigkey, dns_transport_t *transport,
+            dns_xfrin_ctx_t **xfrp);
 
 static isc_result_t
 axfr_init(dns_xfrin_ctx_t *xfr);
@@ -652,8 +658,9 @@ isc_result_t
 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
                 const isc_sockaddr_t *masteraddr,
                 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
-                dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_nm_t *netmgr,
-                dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) {
+                dns_tsigkey_t *tsigkey, dns_transport_t *transport,
+                isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
+                dns_xfrin_ctx_t **xfrp) {
        dns_name_t *zonename = dns_zone_getorigin(zone);
        dns_xfrin_ctx_t *xfr = NULL;
        isc_result_t result;
@@ -661,6 +668,7 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
 
        REQUIRE(xfrp != NULL && *xfrp == NULL);
        REQUIRE(done != NULL);
+       REQUIRE(isc_sockaddr_getport(masteraddr) != 0);
 
        (void)dns_zone_getdb(zone, &db);
 
@@ -669,7 +677,8 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
        }
 
        xfrin_create(mctx, zone, db, netmgr, zonename, dns_zone_getclass(zone),
-                    xfrtype, masteraddr, sourceaddr, dscp, tsigkey, &xfr);
+                    xfrtype, masteraddr, sourceaddr, dscp, tsigkey, transport,
+                    &xfr);
 
        if (db != NULL) {
                xfr->zone_had_db = true;
@@ -809,7 +818,8 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
             dns_name_t *zonename, dns_rdataclass_t rdclass,
             dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
             const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
-            dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp) {
+            dns_tsigkey_t *tsigkey, dns_transport_t *transport,
+            dns_xfrin_ctx_t **xfrp) {
        dns_xfrin_ctx_t *xfr = NULL;
 
        xfr = isc_mem_get(mctx, sizeof(*xfr));
@@ -845,6 +855,10 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
                dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
        }
 
+       if (transport != NULL) {
+               dns_transport_attach(transport, &xfr->transport);
+       }
+
        dns_name_dup(zonename, mctx, &xfr->name);
 
        INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
@@ -865,20 +879,45 @@ static isc_result_t
 xfrin_start(dns_xfrin_ctx_t *xfr) {
        isc_result_t result;
        dns_xfrin_ctx_t *connect_xfr = NULL;
+       dns_transport_type_t transport_type = DNS_TRANSPORT_TCP;
+
+       (void)isc_refcount_increment0(&xfr->connects);
+       dns_xfrin_attach(xfr, &connect_xfr);
+
+       if (xfr->transport != NULL) {
+               transport_type = dns_transport_get_type(xfr->transport);
+       }
+
        /*
-        * XXX: timeout hard-coded to 30 seconds; this needs to be
+        * XXX: timeouts are hard-coded to 30 seconds; this needs to be
         * configurable.
         */
-       (void)isc_refcount_increment0(&xfr->connects);
-       dns_xfrin_attach(xfr, &connect_xfr);
-       CHECK(isc_nm_tcpdnsconnect(xfr->netmgr,
-                                  (isc_nmiface_t *)&xfr->sourceaddr,
-                                  (isc_nmiface_t *)&xfr->masteraddr,
-                                  xfrin_connect_done, connect_xfr, 30000, 0));
+       switch (transport_type) {
+       case DNS_TRANSPORT_TCP:
+               CHECK(isc_nm_tcpdnsconnect(
+                       xfr->netmgr, (isc_nmiface_t *)&xfr->sourceaddr,
+                       (isc_nmiface_t *)&xfr->masteraddr, xfrin_connect_done,
+                       connect_xfr, 30000, 0));
+               break;
+       case DNS_TRANSPORT_TLS:
+               CHECK(isc_tlsctx_createclient(&xfr->tlsctx));
+               CHECK(isc_nm_tlsdnsconnect(
+                       xfr->netmgr, (isc_nmiface_t *)&xfr->sourceaddr,
+                       (isc_nmiface_t *)&xfr->masteraddr, xfrin_connect_done,
+                       connect_xfr, 30000, 0, xfr->tlsctx));
+               break;
+       default:
+               INSIST(0);
+               ISC_UNREACHABLE();
+       }
+
        /* TODO isc_socket_dscp(xfr->socket, xfr->dscp); */
        return (ISC_R_SUCCESS);
 
 failure:
+       if (xfr->tlsctx != NULL) {
+               isc_tlsctx_free(&xfr->tlsctx);
+       }
        isc_refcount_decrement0(&xfr->connects);
        dns_xfrin_detach(&connect_xfr);
        return (result);
@@ -925,6 +964,10 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
 
        isc_refcount_decrement0(&xfr->connects);
 
+       if (xfr->tlsctx != NULL) {
+               isc_tlsctx_free(&xfr->tlsctx);
+       }
+
        if (xfr->shuttingdown) {
                result = ISC_R_SHUTTINGDOWN;
        }
@@ -1499,6 +1542,10 @@ xfrin_destroy(dns_xfrin_ctx_t *xfr) {
                isc_nmhandle_detach(&xfr->sendhandle);
        }
 
+       if (xfr->transport != NULL) {
+               dns_transport_detach(&xfr->transport);
+       }
+
        if (xfr->tsigkey != NULL) {
                dns_tsigkey_detach(&xfr->tsigkey);
        }
index 1406a0e116caf3ab8f9cde85b33678a95fac198a..4197a7efd9ccfe227891adfc93a9f7c607149a9a 100644 (file)
@@ -259,6 +259,7 @@ struct dns_zone {
        isc_sockaddr_t *masters;
        isc_dscp_t *masterdscps;
        dns_name_t **masterkeynames;
+       dns_name_t **mastertlsnames;
        bool *mastersok;
        unsigned int masterscnt;
        unsigned int curmaster;
@@ -266,6 +267,7 @@ struct dns_zone {
        dns_notifytype_t notifytype;
        isc_sockaddr_t *notify;
        dns_name_t **notifykeynames;
+       dns_name_t **notifytlsnames;
        isc_dscp_t *notifydscp;
        unsigned int notifycnt;
        isc_sockaddr_t notifyfrom;
@@ -284,8 +286,9 @@ struct dns_zone {
        isc_dscp_t xfrsource6dscp;
        isc_dscp_t altxfrsource4dscp;
        isc_dscp_t altxfrsource6dscp;
-       dns_xfrin_ctx_t *xfr;   /* task locked */
-       dns_tsigkey_t *tsigkey; /* key used for xfr */
+       dns_xfrin_ctx_t *xfr;       /* task locked */
+       dns_tsigkey_t *tsigkey;     /* key used for xfr */
+       dns_transport_t *transport; /* transport used for xfr */
        /* Access Control Lists */
        dns_acl_t *update_acl;
        dns_acl_t *forward_acl;
@@ -595,6 +598,7 @@ struct dns_notify {
        dns_name_t ns;
        isc_sockaddr_t dst;
        dns_tsigkey_t *key;
+       dns_transport_t *transport;
        isc_dscp_t dscp;
        ISC_LINK(dns_notify_t) link;
        isc_event_t *event;
@@ -1047,12 +1051,14 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        zone->masters = NULL;
        zone->masterdscps = NULL;
        zone->masterkeynames = NULL;
+       zone->mastertlsnames = NULL;
        zone->mastersok = NULL;
        zone->masterscnt = 0;
        zone->curmaster = 0;
        zone->maxttl = 0;
        zone->notify = NULL;
        zone->notifykeynames = NULL;
+       zone->notifytlsnames = NULL;
        zone->notifydscp = NULL;
        zone->notifytype = dns_notifytype_yes;
        zone->notifycnt = 0;
@@ -1091,6 +1097,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        zone->altxfrsource6dscp = -1;
        zone->xfr = NULL;
        zone->tsigkey = NULL;
+       zone->transport = NULL;
        zone->maxxfrin = MAX_XFER_TIME;
        zone->maxxfrout = MAX_XFER_TIME;
        zone->ssutable = NULL;
@@ -1301,9 +1308,10 @@ zone_free(dns_zone_t *zone) {
                dns_catz_catzs_detach(&zone->catzs);
        }
        zone_freedbargs(zone);
-       RUNTIME_CHECK(dns_zone_setprimarieswithkeys(zone, NULL, NULL, 0) ==
+       RUNTIME_CHECK(dns_zone_setprimaries(zone, NULL, NULL, NULL, 0) ==
+                     ISC_R_SUCCESS);
+       RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0) ==
                      ISC_R_SUCCESS);
-       RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
        zone->check_names = dns_severity_ignore;
        if (zone->update_acl != NULL) {
                dns_acl_detach(&zone->update_acl);
@@ -6148,8 +6156,8 @@ same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
 }
 
 static bool
-same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
-             uint32_t count) {
+same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist,
+          uint32_t count) {
        unsigned int i;
 
        if (oldlist == NULL && newlist == NULL) {
@@ -6173,16 +6181,20 @@ same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
 }
 
 static void
-clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
-                    dns_name_t ***keynamesp, unsigned int *countp,
-                    isc_mem_t *mctx) {
+clear_primarieslist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
+                   dns_name_t ***keynamesp, dns_name_t ***tlsnamesp,
+                   unsigned int *countp, isc_mem_t *mctx) {
        unsigned int count;
        isc_sockaddr_t *addrs;
        isc_dscp_t *dscps;
        dns_name_t **keynames;
+       dns_name_t **tlsnames;
 
-       REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
-               keynamesp != NULL);
+       REQUIRE(countp != NULL);
+       REQUIRE(addrsp != NULL);
+       REQUIRE(dscpsp != NULL);
+       REQUIRE(keynamesp != NULL);
+       REQUIRE(tlsnamesp != NULL);
 
        count = *countp;
        *countp = 0;
@@ -6192,6 +6204,8 @@ clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
        *dscpsp = NULL;
        keynames = *keynamesp;
        *keynamesp = NULL;
+       tlsnames = *tlsnamesp;
+       *tlsnamesp = NULL;
 
        if (addrs != NULL) {
                isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
@@ -6213,21 +6227,37 @@ clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
                }
                isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
        }
+
+       if (tlsnames != NULL) {
+               unsigned int i;
+               for (i = 0; i < count; i++) {
+                       if (tlsnames[i] != NULL) {
+                               dns_name_free(tlsnames[i], mctx);
+                               isc_mem_put(mctx, tlsnames[i],
+                                           sizeof(dns_name_t));
+                               tlsnames[i] = NULL;
+                       }
+               }
+               isc_mem_put(mctx, tlsnames, count * sizeof(dns_name_t *));
+       }
 }
 
 static isc_result_t
-set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs,
-               isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
-               isc_dscp_t **newdscpp, dns_name_t **names,
-               dns_name_t ***newnamesp, isc_mem_t *mctx) {
+set_primarieslist(unsigned int count, const isc_sockaddr_t *addrs,
+                 isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
+                 isc_dscp_t **newdscpp, dns_name_t **keynames,
+                 dns_name_t ***newkeynamesp, dns_name_t **tlsnames,
+                 dns_name_t ***newtlsnamesp, isc_mem_t *mctx) {
        isc_sockaddr_t *newaddrs = NULL;
        isc_dscp_t *newdscp = NULL;
-       dns_name_t **newnames = NULL;
+       dns_name_t **newkeynames = NULL;
+       dns_name_t **newtlsnames = NULL;
        unsigned int i;
 
        REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
        REQUIRE(newdscpp != NULL && *newdscpp == NULL);
-       REQUIRE(newnamesp != NULL && *newnamesp == NULL);
+       REQUIRE(newkeynamesp != NULL && *newkeynamesp == NULL);
+       REQUIRE(newtlsnamesp != NULL && *newtlsnamesp == NULL);
 
        newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
        memmove(newaddrs, addrs, count * sizeof(*newaddrs));
@@ -6239,26 +6269,40 @@ set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs,
                newdscp = NULL;
        }
 
-       if (names != NULL) {
-               newnames = isc_mem_get(mctx, count * sizeof(*newnames));
+       if (keynames != NULL) {
+               newkeynames = isc_mem_get(mctx, count * sizeof(*newkeynames));
                for (i = 0; i < count; i++) {
-                       newnames[i] = NULL;
+                       newkeynames[i] = NULL;
                }
                for (i = 0; i < count; i++) {
-                       if (names[i] != NULL) {
-                               newnames[i] = isc_mem_get(mctx,
-                                                         sizeof(dns_name_t));
-                               dns_name_init(newnames[i], NULL);
-                               dns_name_dup(names[i], mctx, newnames[i]);
+                       if (keynames[i] != NULL) {
+                               newkeynames[i] =
+                                       isc_mem_get(mctx, sizeof(dns_name_t));
+                               dns_name_init(newkeynames[i], NULL);
+                               dns_name_dup(keynames[i], mctx, newkeynames[i]);
+                       }
+               }
+       }
+
+       if (tlsnames != NULL) {
+               newtlsnames = isc_mem_get(mctx, count * sizeof(*newtlsnames));
+               for (i = 0; i < count; i++) {
+                       newtlsnames[i] = NULL;
+               }
+               for (i = 0; i < count; i++) {
+                       if (tlsnames[i] != NULL) {
+                               newtlsnames[i] =
+                                       isc_mem_get(mctx, sizeof(dns_name_t));
+                               dns_name_init(newtlsnames[i], NULL);
+                               dns_name_dup(tlsnames[i], mctx, newtlsnames[i]);
                        }
                }
-       } else {
-               newnames = NULL;
        }
 
        *newdscpp = newdscp;
        *newaddrsp = newaddrs;
-       *newnamesp = newnames;
+       *newkeynamesp = newkeynames;
+       *newtlsnamesp = newtlsnames;
        return (ISC_R_SUCCESS);
 }
 
@@ -6281,26 +6325,13 @@ dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
 
 isc_result_t
 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
-                      uint32_t count) {
-       return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
-                                              count));
-}
-
-isc_result_t
-dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
-                              dns_name_t **keynames, uint32_t count) {
-       return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
-                                              count));
-}
-
-isc_result_t
-dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
-                              const isc_dscp_t *dscps, dns_name_t **keynames,
-                              uint32_t count) {
+                      const isc_dscp_t *dscps, dns_name_t **keynames,
+                      dns_name_t **tlsnames, uint32_t count) {
        isc_result_t result;
        isc_sockaddr_t *newaddrs = NULL;
        isc_dscp_t *newdscps = NULL;
-       dns_name_t **newnames = NULL;
+       dns_name_t **newkeynames = NULL;
+       dns_name_t **newtlsnames = NULL;
 
        REQUIRE(DNS_ZONE_VALID(zone));
        REQUIRE(count == 0 || notify != NULL);
@@ -6312,14 +6343,15 @@ dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
 
        if (count == zone->notifycnt &&
            same_addrs(zone->notify, notify, count) &&
-           same_keynames(zone->notifykeynames, keynames, count))
+           same_names(zone->notifykeynames, keynames, count) &&
+           same_names(zone->notifytlsnames, tlsnames, count))
        {
                goto unlock;
        }
 
-       clear_addresskeylist(&zone->notify, &zone->notifydscp,
-                            &zone->notifykeynames, &zone->notifycnt,
-                            zone->mctx);
+       clear_primarieslist(&zone->notify, &zone->notifydscp,
+                           &zone->notifykeynames, &zone->notifytlsnames,
+                           &zone->notifycnt, zone->mctx);
 
        if (count == 0) {
                goto unlock;
@@ -6328,8 +6360,9 @@ dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
        /*
         * Set up the notify and notifykey lists
         */
-       result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
-                                keynames, &newnames, zone->mctx);
+       result = set_primarieslist(count, notify, &newaddrs, dscps, &newdscps,
+                                  keynames, &newkeynames, tlsnames,
+                                  &newtlsnames, zone->mctx);
        if (result != ISC_R_SUCCESS) {
                goto unlock;
        }
@@ -6339,7 +6372,8 @@ dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
         */
        zone->notify = newaddrs;
        zone->notifydscp = newdscps;
-       zone->notifykeynames = newnames;
+       zone->notifykeynames = newkeynames;
+       zone->notifytlsnames = newtlsnames;
        zone->notifycnt = count;
 unlock:
        UNLOCK_ZONE(zone);
@@ -6348,26 +6382,19 @@ unlock:
 
 isc_result_t
 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *masters,
+                     dns_name_t **keynames, dns_name_t **tlsnames,
                      uint32_t count) {
-       isc_result_t result;
-
-       result = dns_zone_setprimarieswithkeys(zone, masters, NULL, count);
-       return (result);
-}
-
-isc_result_t
-dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
-                             dns_name_t **keynames, uint32_t count) {
        isc_result_t result = ISC_R_SUCCESS;
        isc_sockaddr_t *newaddrs = NULL;
        isc_dscp_t *newdscps = NULL;
-       dns_name_t **newnames = NULL;
+       dns_name_t **newkeynames = NULL;
+       dns_name_t **newtlsnames = NULL;
        bool *newok;
        unsigned int i;
 
        REQUIRE(DNS_ZONE_VALID(zone));
        REQUIRE(count == 0 || masters != NULL);
-       if (keynames != NULL) {
+       if (keynames != NULL || tlsnames != NULL) {
                REQUIRE(count != 0);
        }
 
@@ -6380,7 +6407,8 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
         */
        if (count != zone->masterscnt ||
            !same_addrs(zone->masters, masters, count) ||
-           !same_keynames(zone->masterkeynames, keynames, count))
+           !same_names(zone->masterkeynames, keynames, count) ||
+           !same_names(zone->mastertlsnames, tlsnames, count))
        {
                if (zone->request != NULL) {
                        dns_request_cancel(zone->request);
@@ -6398,9 +6426,9 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
                            zone->masterscnt * sizeof(bool));
                zone->mastersok = NULL;
        }
-       clear_addresskeylist(&zone->masters, &zone->masterdscps,
-                            &zone->masterkeynames, &zone->masterscnt,
-                            zone->mctx);
+       clear_primarieslist(&zone->masters, &zone->masterdscps,
+                           &zone->masterkeynames, &zone->mastertlsnames,
+                           &zone->masterscnt, zone->mctx);
        /*
         * If count == 0, don't allocate any space for masters, mastersok or
         * keynames so internally, those pointers are NULL if count == 0
@@ -6420,8 +6448,9 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
        /*
         * Now set up the primaries and primary key lists
         */
-       result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
-                                keynames, &newnames, zone->mctx);
+       result = set_primarieslist(count, masters, &newaddrs, NULL, &newdscps,
+                                  keynames, &newkeynames, tlsnames,
+                                  &newtlsnames, zone->mctx);
        INSIST(newdscps == NULL);
        if (result != ISC_R_SUCCESS) {
                isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
@@ -6435,7 +6464,8 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
        zone->mastersok = newok;
        zone->masters = newaddrs;
        zone->masterdscps = newdscps;
-       zone->masterkeynames = newnames;
+       zone->masterkeynames = newkeynames;
+       zone->mastertlsnames = newtlsnames;
        zone->masterscnt = count;
        DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
 
@@ -11897,7 +11927,8 @@ dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
 
 static bool
 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
-               isc_sockaddr_t *addr, dns_tsigkey_t *key) {
+               isc_sockaddr_t *addr, dns_tsigkey_t *key,
+               dns_transport_t *transport) {
        dns_notify_t *notify;
        dns_zonemgr_t *zmgr;
        isc_result_t result;
@@ -11914,7 +11945,7 @@ notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
                        goto requeue;
                }
                if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
-                   notify->key == key)
+                   notify->key == key && notify->transport == transport)
                {
                        goto requeue;
                }
@@ -12032,6 +12063,9 @@ notify_destroy(dns_notify_t *notify, bool locked) {
        if (notify->key != NULL) {
                dns_tsigkey_detach(&notify->key);
        }
+       if (notify->transport != NULL) {
+               dns_transport_detach(&notify->transport);
+       }
        mctx = notify->mctx;
        isc_mem_put(notify->mctx, notify, sizeof(*notify));
        isc_mem_detach(&mctx);
@@ -12044,15 +12078,11 @@ notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
        REQUIRE(notifyp != NULL && *notifyp == NULL);
 
        notify = isc_mem_get(mctx, sizeof(*notify));
+       *notify = (dns_notify_t){
+               .flags = flags,
+       };
 
-       notify->mctx = NULL;
        isc_mem_attach(mctx, &notify->mctx);
-       notify->flags = flags;
-       notify->zone = NULL;
-       notify->find = NULL;
-       notify->request = NULL;
-       notify->key = NULL;
-       notify->event = NULL;
        isc_sockaddr_any(&notify->dst);
        dns_name_init(&notify->ns, NULL);
        ISC_LINK_INIT(notify, link);
@@ -12332,7 +12362,7 @@ notify_send(dns_notify_t *notify) {
        {
                dst = ai->sockaddr;
                if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
-                                   NULL)) {
+                                   NULL, NULL)) {
                        continue;
                }
                if (notify_isself(notify->zone, &dst)) {
@@ -12485,20 +12515,37 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
        LOCK_ZONE(zone);
        for (i = 0; i < zone->notifycnt; i++) {
                dns_tsigkey_t *key = NULL;
+               dns_transport_t *transport = NULL;
                dns_notify_t *notify = NULL;
+               dns_view_t *view = dns_zone_getview(zone);
 
                if ((zone->notifykeynames != NULL) &&
                    (zone->notifykeynames[i] != NULL)) {
-                       dns_view_t *view = dns_zone_getview(zone);
                        dns_name_t *keyname = zone->notifykeynames[i];
                        (void)dns_view_gettsig(view, keyname, &key);
                }
 
+               if ((zone->notifytlsnames != NULL) &&
+                   (zone->notifytlsnames[i] != NULL)) {
+                       dns_name_t *tlsname = zone->notifytlsnames[i];
+                       (void)dns_view_gettransport(view, DNS_TRANSPORT_TLS,
+                                                   tlsname, &transport);
+
+                       dns_zone_logc(
+                               zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
+                               "got TLS configuration for zone transfer");
+               }
+
+               /* TODO: glue the transport to the notify */
+
                dst = zone->notify[i];
-               if (notify_isqueued(zone, flags, NULL, &dst, key)) {
+               if (notify_isqueued(zone, flags, NULL, &dst, key, transport)) {
                        if (key != NULL) {
                                dns_tsigkey_detach(&key);
                        }
+                       if (transport != NULL) {
+                               dns_transport_detach(&transport);
+                       }
                        continue;
                }
 
@@ -12507,6 +12554,9 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
                        if (key != NULL) {
                                dns_tsigkey_detach(&key);
                        }
+                       if (transport != NULL) {
+                               dns_transport_detach(&transport);
+                       }
                        continue;
                }
 
@@ -12520,6 +12570,12 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
                        key = NULL;
                }
 
+               INSIST(notify->transport == NULL);
+               if (transport != NULL) {
+                       notify->transport = transport;
+                       transport = NULL;
+               }
+
                ISC_LIST_APPEND(zone->notifies, notify, link);
                result = notify_send_queue(notify, startup);
                if (result != ISC_R_SUCCESS) {
@@ -12574,7 +12630,8 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
                }
 
                LOCK_ZONE(zone);
-               isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
+               isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL,
+                                          NULL);
                UNLOCK_ZONE(zone);
                if (isqueued) {
                        result = dns_rdataset_next(&nsrdset);
@@ -13973,12 +14030,14 @@ soa_query(isc_task_t *task, isc_event_t *event) {
        dns_zone_t *dummy = NULL;
        isc_netaddr_t masterip;
        dns_tsigkey_t *key = NULL;
+       dns_transport_t *transport = NULL;
        uint32_t options;
        bool cancel = true;
        int timeout;
        bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
        uint16_t udpsize = SEND_BUFFER_SIZE;
        isc_dscp_t dscp = -1;
+       bool do_queue_xfrin = false;
 
        REQUIRE(DNS_ZONE_VALID(zone));
 
@@ -13998,11 +14057,6 @@ soa_query(isc_task_t *task, isc_event_t *event) {
        }
 
 again:
-       result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup;
-       }
-
        INSIST(zone->masterscnt > 0);
        INSIST(zone->curmaster < zone->masterscnt);
 
@@ -14038,6 +14092,23 @@ again:
                }
        }
 
+       if ((zone->mastertlsnames != NULL) &&
+           (zone->mastertlsnames[zone->curmaster] != NULL))
+       {
+               dns_view_t *view = dns_zone_getview(zone);
+               dns_name_t *tlsname = zone->mastertlsnames[zone->curmaster];
+               result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname,
+                                              &transport);
+               if (result != ISC_R_SUCCESS) {
+                       char namebuf[DNS_NAME_FORMATSIZE];
+                       dns_name_format(tlsname, namebuf, sizeof(namebuf));
+                       dns_zone_log(zone, ISC_LOG_ERROR,
+                                    "unable to find TLS configuration: %s",
+                                    namebuf);
+                       goto skip_master;
+               }
+       }
+
        options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP
                                                         : 0;
        have_xfrsource = have_xfrdscp = false;
@@ -14116,6 +14187,24 @@ again:
                goto cleanup;
        }
 
+       /*
+        * FIXME(OS): This is a bit hackish, but it enforces the SOA query to go
+        * through the XFR channel instead of doing dns_request that doesn't
+        * have DoT support yet.
+        */
+       if (transport != NULL) {
+               DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
+               do_queue_xfrin = true;
+               cancel = false;
+               result = ISC_R_SUCCESS;
+               goto cleanup;
+       }
+
+       result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
+       if (result != ISC_R_SUCCESS) {
+               goto cleanup;
+       }
+
        if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
                result = add_opt(message, udpsize, reqnsid, reqexpire);
                if (result != ISC_R_SUCCESS) {
@@ -14148,8 +14237,10 @@ again:
                }
        }
        cancel = false;
-
 cleanup:
+       if (transport != NULL) {
+               dns_transport_detach(&transport);
+       }
        if (key != NULL) {
                dns_tsigkey_detach(&key);
        }
@@ -14164,6 +14255,9 @@ cleanup:
        }
        isc_event_free(&event);
        UNLOCK_ZONE(zone);
+       if (do_queue_xfrin) {
+               queue_xfrin(zone);
+       }
        dns_zone_idetach(&zone);
        return;
 
@@ -14171,7 +14265,9 @@ skip_master:
        if (key != NULL) {
                dns_tsigkey_detach(&key);
        }
-       dns_message_detach(&message);
+       if (message != NULL) {
+               dns_message_detach(&message);
+       }
        /*
         * Skip to next failed / untried master.
         */
@@ -14316,6 +14412,8 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
                (void)dns_view_getpeertsig(zone->view, &masterip, &key);
        }
 
+       /* FIXME(OS): Do we need the transport here too? Most probably yes */
+
        reqnsid = zone->view->requestnsid;
        if (zone->view->peers != NULL) {
                dns_peer_t *peer = NULL;
@@ -17230,6 +17328,10 @@ again:
                dns_tsigkey_detach(&zone->tsigkey);
        }
 
+       if (zone->transport != NULL) {
+               dns_transport_detach(&zone->transport);
+       }
+
        /*
         * Handle any deferred journal compaction.
         */
@@ -17587,6 +17689,26 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
                              isc_result_totext(result));
        }
 
+       if ((zone->mastertlsnames != NULL) &&
+           (zone->mastertlsnames[zone->curmaster] != NULL))
+       {
+               dns_view_t *view = dns_zone_getview(zone);
+               dns_name_t *tlsname = zone->mastertlsnames[zone->curmaster];
+               result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname,
+                                              &zone->transport);
+
+               dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
+                             "got TLS configuration for zone transfer: %s",
+                             isc_result_totext(result));
+       }
+
+       if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
+               dns_zone_logc(
+                       zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
+                       "could not get TLS configuration for zone transfer: %s",
+                       isc_result_totext(result));
+       }
+
        if (zone->masterdscps != NULL) {
                dscp = zone->masterdscps[zone->curmaster];
        }
@@ -17617,8 +17739,8 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
        }
 
        CHECK(dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr, dscp,
-                              zone->tsigkey, zone->mctx, zone->zmgr->netmgr,
-                              zone_xfrdone, &zone->xfr));
+                              zone->tsigkey, zone->transport, zone->mctx,
+                              zone->zmgr->netmgr, zone_xfrdone, &zone->xfr));
        LOCK_ZONE(zone);
        if (xfrtype == dns_rdatatype_axfr) {
                if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
index 1ca22dd8d2076ca3d1addbd52e115082e7fa0cf7..c18196ea5b333fc06d28bc2c4684000f301f39b5 100644 (file)
@@ -193,6 +193,7 @@ static cfg_type_t cfg_type_primaries = { "primaries",         cfg_parse_tuple,
 static cfg_tuplefielddef_t namesockaddrkey_fields[] = {
        { "primarieselement", &cfg_type_primarieselement, 0 },
        { "key", &cfg_type_optional_keyref, 0 },
+       { "tls", &cfg_type_optional_tls, 0 },
        { NULL, NULL, 0 },
 };
 
@@ -3832,6 +3833,10 @@ static cfg_type_t cfg_type_sslprotos = {
 static cfg_clausedef_t tls_clauses[] = {
        { "key-file", &cfg_type_qstring, 0 },
        { "cert-file", &cfg_type_qstring, 0 },
+       { "ca-file", &cfg_type_qstring, 0 },
+       { "hostname", &cfg_type_qstring, 0 },
+       /* { "trusted-cert-file", &cfg_type_qstring, *
+          CFG_CLAUSEFLAG_EXPERIMENTAL}, */
        { "dh-param", &cfg_type_qstring, CFG_CLAUSEFLAG_EXPERIMENTAL },
        { "protocols", &cfg_type_sslprotos, CFG_CLAUSEFLAG_EXPERIMENTAL },
        { "ciphers", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
index 7270dccc78043b593add2d4485631b35d6c0cfd5..639c1bb3b41dba96902e2f839b1dbecd3bc697bc 100644 (file)
 ./bin/named/include/named/smf_globals.h                C       2017,2018,2019,2020,2021
 ./bin/named/include/named/statschannel.h       C       2008,2016,2017,2018,2019,2020,2021
 ./bin/named/include/named/tkeyconf.h           C       1999,2000,2001,2004,2005,2006,2007,2016,2017,2018,2019,2020,2021
+./bin/named/include/named/transportconf.h      C       2021
 ./bin/named/include/named/tsigconf.h           C       1999,2000,2001,2004,2005,2006,2007,2009,2016,2017,2018,2019,2020,2021
 ./bin/named/include/named/types.h              C       1999,2000,2001,2004,2005,2006,2007,2008,2009,2015,2016,2017,2018,2019,2020,2021
 ./bin/named/include/named/zoneconf.h           C       1999,2000,2001,2002,2004,2005,2006,2007,2010,2011,2015,2016,2017,2018,2019,2020,2021
 ./bin/named/server.c                           C       1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
 ./bin/named/statschannel.c                     C       2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
 ./bin/named/tkeyconf.c                         C       1999,2000,2001,2004,2005,2006,2007,2009,2010,2012,2014,2016,2017,2018,2019,2020,2021
+./bin/named/transportconf.c                    C       2021
 ./bin/named/tsigconf.c                         C       1999,2000,2001,2004,2005,2006,2007,2009,2011,2012,2016,2017,2018,2019,2020,2021
 ./bin/named/unix/dlz_dlopen_driver.c           C       2011,2012,2013,2014,2016,2017,2018,2019,2020,2021
 ./bin/named/unix/include/named/os.h            C       1999,2000,2001,2002,2004,2005,2007,2008,2009,2014,2016,2017,2018,2019,2020,2021
 ./bin/tests/system/xferquota/setup.pl          PERL    2000,2001,2004,2007,2011,2012,2016,2018,2019,2020,2021
 ./bin/tests/system/xferquota/setup.sh          SH      2000,2001,2004,2007,2012,2016,2018,2019,2020,2021
 ./bin/tests/system/xferquota/tests.sh          SH      2000,2001,2004,2007,2012,2016,2018,2019,2020,2021
+./bin/tests/system/xot/clean.sh                        SH      2021
+./bin/tests/system/xot/dig1.good               X       2021
+./bin/tests/system/xot/setup.sh                        SH      2021
+./bin/tests/system/xot/tests.sh                        SH      2021
 ./bin/tests/system/zero/ans5/ans.pl            PERL    2016,2018,2019,2020,2021
 ./bin/tests/system/zero/clean.sh               SH      2013,2014,2015,2016,2018,2019,2020,2021
 ./bin/tests/system/zero/setup.sh               SH      2013,2014,2016,2018,2019,2020,2021
 ./lib/dns/include/dns/time.h                   C       1999,2000,2001,2004,2005,2006,2007,2012,2016,2018,2019,2020,2021
 ./lib/dns/include/dns/timer.h                  C       2000,2001,2004,2005,2006,2007,2016,2018,2019,2020,2021
 ./lib/dns/include/dns/tkey.h                   C       1999,2000,2001,2004,2005,2006,2007,2009,2010,2011,2016,2018,2019,2020,2021
+./lib/dns/include/dns/transport.h              C       2021
 ./lib/dns/include/dns/tsec.h                   C       2009,2010,2012,2016,2018,2019,2020,2021
 ./lib/dns/include/dns/tsig.h                   C       1999,2000,2001,2002,2004,2005,2006,2007,2009,2010,2011,2016,2018,2019,2020,2021
 ./lib/dns/include/dns/ttl.h                    C       1999,2000,2001,2004,2005,2006,2007,2014,2016,2018,2019,2020,2021
 ./lib/dns/time.c                               C       1998,1999,2000,2001,2002,2003,2004,2005,2007,2009,2010,2011,2012,2014,2016,2017,2018,2019,2020,2021
 ./lib/dns/timer.c                              C       2000,2001,2004,2005,2007,2016,2018,2019,2020,2021
 ./lib/dns/tkey.c                               C       1999,2000,2001,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2018,2019,2020,2021
+./lib/dns/transport.c                          C       2021
 ./lib/dns/tsec.c                               C       2009,2010,2016,2017,2018,2019,2020,2021
 ./lib/dns/tsig.c                               C       1999,2000,2001,2002,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
 ./lib/dns/tsig_p.h                             C       2017,2018,2019,2020,2021