]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add DoT support to bind
authorWitold Kręcicki <wpk@isc.org>
Thu, 1 Oct 2020 11:18:47 +0000 (13:18 +0200)
committerOndřej Surý <ondrej@sury.org>
Tue, 10 Nov 2020 13:16:55 +0000 (14:16 +0100)
Parse the configuration of tls objects into SSL_CTX* objects.  Listen on
DoT if 'tls' option is setup in listen-on directive.  Use DoT/DoH ports
for DoT/DoH.

15 files changed:
bin/named/config.c
bin/named/include/named/config.h
bin/named/include/named/globals.h
bin/named/main.c
bin/named/named.conf.rst
bin/named/server.c
doc/misc/options
doc/misc/options.active
doc/misc/options.grammar.rst
lib/isc/netmgr/tcpdns.c
lib/isccfg/namedconf.c
lib/ns/Makefile.am
lib/ns/include/ns/listenlist.h
lib/ns/interfacemgr.c
lib/ns/listenlist.c

index 39a67eee123793912d31dfc2cf880155ad21a21d..c19a8897682c2f366b649efea335283e2d441f13 100644 (file)
@@ -93,6 +93,7 @@ options {\n\
        nta-recheck 300;\n\
 #      pid-file \"" NAMED_LOCALSTATEDIR "/run/named/named.pid\"; \n\
        port 53;\n\
+       dot-port 853;\n\
        prefetch 2 9;\n\
        recursing-file \"named.recursing\";\n\
        recursive-clients 1000;\n\
@@ -497,7 +498,7 @@ named_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
        } else if (defport != 0) {
                port = defport;
        } else {
-               result = named_config_getport(config, &port);
+               result = named_config_getport(config, "port", &port);
                if (result != ISC_R_SUCCESS) {
                        return (result);
                }
@@ -644,7 +645,7 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
        /*
         * Get system defaults.
         */
-       result = named_config_getport(config, &port);
+       result = named_config_getport(config, "port", &port);
        if (result != ISC_R_SUCCESS) {
                goto cleanup;
        }
@@ -925,7 +926,8 @@ cleanup:
 }
 
 isc_result_t
-named_config_getport(const cfg_obj_t *config, in_port_t *portp) {
+named_config_getport(const cfg_obj_t *config, const char *type,
+                    in_port_t *portp) {
        const cfg_obj_t *maps[3];
        const cfg_obj_t *options = NULL;
        const cfg_obj_t *portobj = NULL;
@@ -940,7 +942,7 @@ named_config_getport(const cfg_obj_t *config, in_port_t *portp) {
        maps[i++] = named_g_defaults;
        maps[i] = NULL;
 
-       result = named_config_get(maps, "port", &portobj);
+       result = named_config_get(maps, type, &portobj);
        INSIST(result == ISC_R_SUCCESS);
        if (cfg_obj_asuint32(portobj) >= UINT16_MAX) {
                cfg_obj_log(portobj, named_g_lctx, ISC_LOG_ERROR,
@@ -980,13 +982,15 @@ named_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) {
 
 struct keyalgorithms {
        const char *str;
-       enum { hmacnone,
-              hmacmd5,
-              hmacsha1,
-              hmacsha224,
-              hmacsha256,
-              hmacsha384,
-              hmacsha512 } hmac;
+       enum {
+               hmacnone,
+               hmacmd5,
+               hmacsha1,
+               hmacsha224,
+               hmacsha256,
+               hmacsha384,
+               hmacsha512
+       } hmac;
        unsigned int type;
        uint16_t size;
 } algorithms[] = { { "hmac-md5", hmacmd5, DST_ALG_HMACMD5, 128 },
index 06a414164acd6d2b45d9aa9bc766725c6d16033d..7e005a29a1fac9a336e1cb8a9e1badae09264523 100644 (file)
@@ -67,7 +67,8 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
                             isc_mem_t *mctx, dns_ipkeylist_t *ipkl);
 
 isc_result_t
-named_config_getport(const cfg_obj_t *config, in_port_t *portp);
+named_config_getport(const cfg_obj_t *config, const char *type,
+                    in_port_t *portp);
 
 isc_result_t
 named_config_getkeyalgorithm(const char *str, const dns_name_t **name,
index 78e30dbc0f7620fb4c63b6ab727f5bbb625a70cd..4c0569dfdf705937330ccf063e7ab1611655242d 100644 (file)
@@ -72,6 +72,7 @@ EXTERN const char *named_g_srcid       INIT(PACKAGE_SRCID);
 EXTERN const char *named_g_configargs  INIT(PACKAGE_CONFIGARGS);
 EXTERN const char *named_g_builder     INIT(PACKAGE_BUILDER);
 EXTERN in_port_t named_g_port         INIT(0);
+EXTERN in_port_t named_g_dot_port      INIT(0);
 EXTERN isc_dscp_t named_g_dscp        INIT(-1);
 
 EXTERN named_server_t *named_g_server INIT(NULL);
@@ -128,7 +129,7 @@ EXTERN bool named_g_forcelock                  INIT(false);
 #if NAMED_RUN_PID_DIR
 EXTERN const char *named_g_defaultpidfile INIT(NAMED_LOCALSTATEDIR "/run/named/"
                                                                   "named.pid");
-#else  /* if NAMED_RUN_PID_DIR */
+#else /* if NAMED_RUN_PID_DIR */
 EXTERN const char *named_g_defaultpidfile INIT(NAMED_LOCALSTATEDIR "/run/"
                                                                   "named.pid");
 #endif /* if NAMED_RUN_PID_DIR */
index 443263d7f495b39dd9c24db793641ec50d9235c5..13fbba992745c88d18da56571d9f839fd841376b 100644 (file)
@@ -232,7 +232,7 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
                                              NAMED_LOGMODULE_MAIN,
                                              ISC_LOG_CRITICAL, "%s", strs[i]);
                        }
-#else  /* HAVE_BACKTRACE_SYMBOLS */
+#else /* HAVE_BACKTRACE_SYMBOLS */
                        for (int i = 0; i < nframes; i++) {
                                isc_log_write(
                                        named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
@@ -521,8 +521,8 @@ printversion(bool verbose) {
        printf("linked to OpenSSL version: %s\n",
               OpenSSL_version(OPENSSL_VERSION));
 
-#else  /* if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
-       * 0x10100000L */
+#else /* if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
+       * 0x10100000L */
        printf("linked to OpenSSL version: %s\n",
               SSLeay_version(SSLEAY_VERSION));
 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
@@ -789,11 +789,13 @@ parse_command_line(int argc, char *argv[]) {
                        break;
                case 'p':
                        port = parse_int(isc_commandline_argument, "port");
-                       if (port < 1 || port > 65535) {
+                       if (port < 1 || port > 64735) {
                                named_main_earlyfatal("port '%s' out of range",
                                                      isc_commandline_argument);
                        }
                        named_g_port = port;
+                       /* XXXWPK have a separate option for that. */
+                       named_g_dot_port = port + 800;
                        break;
                case 's':
                        /* XXXRTH temporary syntax */
@@ -887,7 +889,7 @@ create_managers(void) {
                named_g_cpus, named_g_cpus == 1 ? "" : "s");
 #ifdef WIN32
        named_g_udpdisp = 1;
-#else  /* ifdef WIN32 */
+#else /* ifdef WIN32 */
        if (named_g_udpdisp == 0) {
                named_g_udpdisp = named_g_cpus_detected;
        }
@@ -1107,8 +1109,8 @@ setup(void) {
                      NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE,
                      "linked to OpenSSL version: %s",
                      OpenSSL_version(OPENSSL_VERSION));
-#else  /* if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
-       * 0x10100000L */
+#else /* if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
+       * 0x10100000L */
        isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                      NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE,
                      "linked to OpenSSL version: %s",
index 68d1d8eee1ff3c26b553f86fcfaf0b56dd64bccd..34caff2e3592b27d543e466fb7d25f534a0920b0 100644 (file)
@@ -231,6 +231,7 @@ OPTIONS
            size ) ] [ versions ( unlimited | integer ) ] [ suffix (
            increment | timestamp ) ];
        dnstap-version ( quoted_string | none );
+       dot-port integer;
        dscp integer;
        dual-stack-servers [ port integer ] { ( quoted_string [ port
            integer ] [ dscp integer ] | ipv4_address [ port
index af3ea264420b43588b634ff022331b175c4cd16c..dbdb6332c143e6f49995d087b66c10eb686574d1 100644 (file)
@@ -465,7 +465,7 @@ nzd_close(MDB_txn **txnp, bool commit);
 
 static isc_result_t
 nzd_count(dns_view_t *view, int *countp);
-#else  /* ifdef HAVE_LMDB */
+#else /* ifdef HAVE_LMDB */
 static isc_result_t
 nzf_append(dns_view_t *view, const cfg_obj_t *zconfig);
 #endif /* ifdef HAVE_LMDB */
@@ -674,11 +674,13 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, const char **namestrp,
        dns_name_t *name = NULL;
        isc_buffer_t namebuf;
        const char *atstr = NULL;
-       enum { INIT_DNSKEY,
-              STATIC_DNSKEY,
-              INIT_DS,
-              STATIC_DS,
-              TRUSTED } anchortype;
+       enum {
+               INIT_DNSKEY,
+               STATIC_DNSKEY,
+               INIT_DS,
+               STATIC_DS,
+               TRUSTED
+       } anchortype;
 
        REQUIRE(namestrp != NULL && *namestrp == NULL);
        REQUIRE(ds != NULL);
@@ -1388,7 +1390,7 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
        if (!strcasecmp(str, "fixed")) {
 #if DNS_RDATASET_FIXED
                mode = DNS_RDATASETATTR_FIXEDORDER;
-#else  /* if DNS_RDATASET_FIXED */
+#else /* if DNS_RDATASET_FIXED */
                mode = DNS_RDATASETATTR_CYCLIC;
 #endif /* DNS_RDATASET_FIXED */
        } else if (!strcasecmp(str, "random")) {
@@ -2475,7 +2477,7 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
                            " without `./configure --enable-dnsrps`");
                return (ISC_R_FAILURE);
        }
-#else  /* ifndef USE_DNSRPS */
+#else /* ifndef USE_DNSRPS */
        if (dnsrps_enabled) {
                if (librpz == NULL) {
                        cfg_obj_log(rpz_obj, named_g_lctx, DNS_RPZ_ERROR_LEVEL,
@@ -3962,7 +3964,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        /*
         * Set the view's port number for outgoing queries.
         */
-       CHECKM(named_config_getport(config, &port), "port");
+       CHECKM(named_config_getport(config, "port", &port), "port");
        dns_view_setdstport(view, port);
 
        /*
@@ -5762,7 +5764,7 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
        /*
         * Determine which port to send requests to.
         */
-       CHECKM(named_config_getport(config, &port), "port");
+       CHECKM(named_config_getport(config, "port", &port), "port");
 
        if (alternates != NULL) {
                portobj = cfg_tuple_get(alternates, "port");
@@ -5850,7 +5852,7 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
        /*
         * Determine which port to send forwarded requests to.
         */
-       CHECKM(named_config_getport(config, &port), "port");
+       CHECKM(named_config_getport(config, "port", &port), "port");
 
        if (forwarders != NULL) {
                portobj = cfg_tuple_get(forwarders, "port");
@@ -6735,7 +6737,8 @@ add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
                }
 
                result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr),
-                                            dscp, src_acl, &lelt);
+                                            dscp, src_acl, false, NULL, NULL,
+                                            &lelt);
                if (result != ISC_R_SUCCESS) {
                        goto clean;
                }
@@ -6822,8 +6825,7 @@ adjust_interfaces(named_server_t *server, isc_mem_t *mctx) {
                for (view = ISC_LIST_HEAD(server->viewlist);
                     view != NULL && view != zoneview;
                     view = ISC_LIST_NEXT(view, link))
-               {
-               }
+               {}
                if (view == NULL) {
                        continue;
                }
@@ -7752,7 +7754,7 @@ setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
                        return (ISC_R_FAILURE);
                }
        }
-#else  /* ifdef HAVE_LMDB */
+#else /* ifdef HAVE_LMDB */
        UNUSED(obj);
 #endif /* HAVE_LMDB */
 
@@ -8799,7 +8801,8 @@ load_configuration(const char *filename, named_server_t *server,
        if (named_g_port != 0) {
                listen_port = named_g_port;
        } else {
-               CHECKM(named_config_getport(config, &listen_port), "port");
+               CHECKM(named_config_getport(config, "port", &listen_port),
+                      "port");
        }
 
        /*
@@ -9774,7 +9777,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
 
 #if defined(HAVE_GEOIP2)
        geoip = named_g_geoip;
-#else  /* if defined(HAVE_GEOIP2) */
+#else /* if defined(HAVE_GEOIP2) */
        geoip = NULL;
 #endif /* if defined(HAVE_GEOIP2) */
 
@@ -10860,20 +10863,67 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                        cfg_aclconfctx_t *actx, isc_mem_t *mctx,
                        uint16_t family, ns_listenelt_t **target) {
        isc_result_t result;
-       const cfg_obj_t *portobj, *dscpobj;
+       const cfg_obj_t *tlsobj, *portobj, *dscpobj;
        in_port_t port;
        isc_dscp_t dscp = -1;
+       const char *key = NULL, *cert = NULL;
+       bool tls = false;
        ns_listenelt_t *delt = NULL;
        REQUIRE(target != NULL && *target == NULL);
 
+       /* XXXWPK TODO be more verbose on failures. */
+       tlsobj = cfg_tuple_get(listener, "tls");
+       if (tlsobj != NULL && cfg_obj_isstring(tlsobj)) {
+               const cfg_obj_t *tlsconfigs = NULL;
+               const cfg_listelt_t *element;
+               (void)cfg_map_get(config, "tls", &tlsconfigs);
+               for (element = cfg_list_first(tlsconfigs); element != NULL;
+                    element = cfg_list_next(element))
+               {
+                       cfg_obj_t *tconfig = cfg_listelt_value(element);
+                       const cfg_obj_t *name = cfg_map_getname(tconfig);
+                       if (!strcmp(cfg_obj_asstring(name),
+                                   cfg_obj_asstring(tlsobj))) {
+                               tls = true;
+                               const cfg_obj_t *keyo = NULL, *certo = NULL;
+                               (void)cfg_map_get(tconfig, "key-file", &keyo);
+                               if (keyo == NULL) {
+                                       return (ISC_R_FAILURE);
+                               }
+                               (void)cfg_map_get(tconfig, "cert-file", &certo);
+                               if (certo == NULL) {
+                                       return (ISC_R_FAILURE);
+                               }
+                               key = cfg_obj_asstring(keyo);
+                               cert = cfg_obj_asstring(certo);
+                               break;
+                       }
+               }
+               if (!tls) {
+                       return (ISC_R_FAILURE);
+               }
+       }
        portobj = cfg_tuple_get(listener, "port");
        if (!cfg_obj_isuint32(portobj)) {
-               if (named_g_port != 0) {
-                       port = named_g_port;
+               if (tls) {
+                       if (named_g_dot_port != 0) {
+                               port = named_g_dot_port;
+                       } else {
+                               result = named_config_getport(
+                                       config, "dot-port", &port);
+                               if (result != ISC_R_SUCCESS) {
+                                       return (result);
+                               }
+                       }
                } else {
-                       result = named_config_getport(config, &port);
-                       if (result != ISC_R_SUCCESS) {
-                               return (result);
+                       if (named_g_port != 0) {
+                               port = named_g_port;
+                       } else {
+                               result = named_config_getport(config, "port",
+                                                             &port);
+                               if (result != ISC_R_SUCCESS) {
+                                       return (result);
+                               }
                        }
                }
        } else {
@@ -10899,7 +10949,8 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
        }
 
-       result = ns_listenelt_create(mctx, port, dscp, NULL, &delt);
+       result = ns_listenelt_create(mctx, port, dscp, NULL, tls, key, cert,
+                                    &delt);
        if (result != ISC_R_SUCCESS) {
                return (result);
        }
@@ -13330,7 +13381,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
 #ifndef HAVE_LMDB
        FILE *fp = NULL;
        bool cleanup_config = false;
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        MDB_txn *txn = NULL;
        MDB_dbi dbi;
 
@@ -13371,7 +13422,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
 
        (void)isc_stdio_close(fp);
        fp = NULL;
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        /* Make sure we can open the NZD database */
        result = nzd_writable(view);
        if (result != ISC_R_SUCCESS) {
@@ -13469,7 +13520,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
        /* Save the new zone configuration into the NZD */
        CHECK(nzd_open(view, 0, &txn, &dbi));
        CHECK(nzd_save(&txn, dbi, zone, zoneobj));
-#else  /* ifdef HAVE_LMDB */
+#else /* ifdef HAVE_LMDB */
        /* Append the zone configuration to the NZF */
        result = nzf_append(view, zoneobj);
 #endif /* HAVE_LMDB */
@@ -13485,7 +13536,7 @@ cleanup:
                                          cfg->nzf_config, name, NULL);
                RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
        }
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        if (txn != NULL) {
                (void)nzd_close(&txn, false);
        }
@@ -13510,7 +13561,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
 #ifndef HAVE_LMDB
        FILE *fp = NULL;
        cfg_obj_t *z;
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        MDB_txn *txn = NULL;
        MDB_dbi dbi;
        LOCK(&view->new_zone_lock);
@@ -13558,7 +13609,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
        }
        (void)isc_stdio_close(fp);
        fp = NULL;
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        /* Make sure we can open the NZD database */
        result = nzd_writable(view);
        if (result != ISC_R_SUCCESS) {
@@ -13679,7 +13730,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
 #ifdef HAVE_LMDB
                CHECK(nzd_open(view, 0, &txn, &dbi));
                CHECK(nzd_save(&txn, dbi, zone, zoneobj));
-#else  /* ifdef HAVE_LMDB */
+#else /* ifdef HAVE_LMDB */
                result = nzf_append(view, zoneobj);
                if (result != ISC_R_SUCCESS) {
                        TCHECK(putstr(text, "\nNew zone config not saved: "));
@@ -13707,7 +13758,7 @@ cleanup:
        if (fp != NULL) {
                (void)isc_stdio_close(fp);
        }
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        if (txn != NULL) {
                (void)nzd_close(&txn, false);
        }
@@ -13752,7 +13803,7 @@ named_server_changezone(named_server_t *server, char *command,
        /* Are we accepting new zones in this view? */
 #ifdef HAVE_LMDB
        if (view->new_zone_db == NULL)
-#else  /* ifdef HAVE_LMDB */
+#else /* ifdef HAVE_LMDB */
        if (view->new_zone_file == NULL)
 #endif /* HAVE_LMDB */
        {
@@ -13898,7 +13949,7 @@ rmzone(isc_task_t *task, isc_event_t *event) {
                        (void)nzd_close(&txn, false);
                }
                UNLOCK(&view->new_zone_lock);
-#else  /* ifdef HAVE_LMDB */
+#else /* ifdef HAVE_LMDB */
                result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config,
                                         dns_zone_getorigin(zone),
                                         nzf_writeconf);
@@ -14267,7 +14318,7 @@ named_server_showzone(named_server_t *server, isc_lex_t *lex,
                zconfig = find_name_in_list_from_map(cfg->nzf_config, "zone",
                                                     zonename, redirect);
        }
-#else  /* HAVE_LMDB */
+#else /* HAVE_LMDB */
        if (zconfig == NULL) {
                const cfg_obj_t *zlist = NULL;
                CHECK(get_newzone_config(view, zonename, &nzconfig));
@@ -15935,7 +15986,7 @@ named_server_dnstap(named_server_t *server, isc_lex_t *lex,
 
        result = dns_dt_reopen(server->dtenv, backups);
        return (result);
-#else  /* ifdef HAVE_DNSTAP */
+#else /* ifdef HAVE_DNSTAP */
        UNUSED(server);
        UNUSED(lex);
        UNUSED(text);
index 1f3daa904a16d3f55707520c88135d9b7025c0ee..6d92b380deccec4d7edc082e24e6bce60e08e9fc 100644 (file)
@@ -173,6 +173,7 @@ options {
             <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
             increment | timestamp ) ];
         dnstap-version ( <quoted_string> | none );
+        dot-port <integer>;
         dscp <integer>;
         dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
             <integer> ] [ dscp <integer> ] | <ipv4_address> [ port
index 6da3e4ee7a9408047877207cc7742a7ce5ba5dfd..76f4c546b84ee20a5f313929117d034c01b4d90f 100644 (file)
@@ -159,6 +159,7 @@ options {
             <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
             increment | timestamp ) ];
         dnstap-version ( <quoted_string> | none );
+        dot-port <integer>;
         dscp <integer>;
         dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
             <integer> ] [ dscp <integer> ] | <ipv4_address> [ port
index 9fef7669d37fd7f020b9f8a0b1bc8f1e305919af..2360354c3e96582cfccd5fc2087eb4f13abe9458 100644 (file)
@@ -89,6 +89,7 @@
            <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
            increment | timestamp ) ];
        dnstap-version ( <quoted_string> | none );
+       dot-port <integer>;
        dscp <integer>;
        dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
            <integer> ] [ dscp <integer> ] | <ipv4_address> [ port
index 8004124a850a0edfbc1ec3056b73c126a1d9a475..422e26d2b5bfb53513e77cd31ebc83721f5a3ae9 100644 (file)
@@ -471,6 +471,7 @@ isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) {
                        break;
                default:
                        INSIST(0);
+                       ISC_UNREACHABLE();
                }
                isc__nmsocket_detach(&sock->outer);
        }
index b4eed89a1114246b0d67fa45b291f542c04287df..ebd0d1952023873a2d503c19eeb7262579200ca5 100644 (file)
@@ -1201,6 +1201,7 @@ static cfg_clausedef_t options_clauses[] = {
        { "notify-rate", &cfg_type_uint32, 0 },
        { "pid-file", &cfg_type_qstringornone, 0 },
        { "port", &cfg_type_uint32, 0 },
+       { "dot-port", &cfg_type_uint32, 0 },
        { "querylog", &cfg_type_boolean, 0 },
        { "random-device", &cfg_type_qstringornone, 0 },
        { "recursing-file", &cfg_type_qstring, 0 },
index 5c93b2e85b7026e5ba70b9872ebe4939d64ddf9b..d430493aef169fd04f8b29d274fc41b4aadbb945 100644 (file)
@@ -44,12 +44,14 @@ libns_la_CPPFLAGS =                         \
        $(LIBDNS_CFLAGS)                        \
        $(LIBISC_CFLAGS)                        \
        $(LIBNS_CFLAGS)                         \
-       $(LIBUV_CFLAGS)
+       $(LIBUV_CFLAGS)                         \
+       $(OPENSSL_CFLAGS)
 
 libns_la_LIBADD =      \
        $(LIBDNS_LIBS)  \
        $(LIBISC_LIBS)  \
-       $(LIBUV_LIBS)
+       $(LIBUV_LIBS)   \
+       $(OPENSSL_LIBS)
 
 libns_la_LDFLAGS =             \
        $(AM_LDFLAGS)           \
index 22a6af0d5be40d745544008c340b842d7a045e51..d3ced20034523a447af13d3bb72c492c6dbe0e16 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <dns/types.h>
 
+#include <openssl/ssl.h>
+
 /***
  *** Types
  ***/
@@ -43,6 +45,7 @@ struct ns_listenelt {
        in_port_t  port;
        isc_dscp_t dscp; /* -1 = not set, 0..63 */
        dns_acl_t *acl;
+       SSL_CTX *  sslctx;
        ISC_LINK(ns_listenelt_t) link;
 };
 
@@ -58,7 +61,8 @@ struct ns_listenlist {
 
 isc_result_t
 ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
-                   dns_acl_t *acl, ns_listenelt_t **target);
+                   dns_acl_t *acl, bool tls, const char *key, const char *cert,
+                   ns_listenelt_t **target);
 /*%<
  * Create a listen-on list element.
  */
index 193e7e62cb7dc8a85e8932f25573ed30fdaf9e8b..ae8c1c2406b9bbe477fb62a763fe94d1f4fac0bc 100644 (file)
@@ -502,10 +502,48 @@ ns_interface_listentcp(ns_interface_t *ifp) {
        return (result);
 }
 
+/*
+ * XXXWPK we should probably pass a complete object with key, cert, and other
+ * TLS related options.
+ */
+static isc_result_t
+ns_interface_listentls(ns_interface_t *ifp, SSL_CTX *sslctx) {
+       isc_result_t result;
+       SSL_CTX *ctx = NULL;
+
+       result = isc_nm_listentlsdns(
+               ifp->mgr->nm, (isc_nmiface_t *)&ifp->addr, ns__client_request,
+               ifp, ns__client_tcpconn, ifp, sizeof(ns_client_t),
+               ifp->mgr->backlog, &ifp->mgr->sctx->tcpquota, sslctx,
+               &ifp->tcplistensocket);
+
+       if (result != ISC_R_SUCCESS) {
+               isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
+                             "creating TLS socket: %s",
+                             isc_result_totext(result));
+               SSL_CTX_free(ctx);
+               return (result);
+       }
+
+       /*
+        * We call this now to update the tcp-highwater statistic:
+        * this is necessary because we are adding to the TCP quota just
+        * by listening.
+        */
+       result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp);
+       if (result != ISC_R_SUCCESS) {
+               isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
+                             "updating TCP stats: %s",
+                             isc_result_totext(result));
+       }
+
+       return (result);
+}
+
 static isc_result_t
 ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
                   const char *name, ns_interface_t **ifpret, bool accept_tcp,
-                  isc_dscp_t dscp, bool *addr_in_use) {
+                  ns_listenelt_t *elt, bool *addr_in_use) {
        isc_result_t result;
        ns_interface_t *ifp = NULL;
        REQUIRE(ifpret != NULL && *ifpret == NULL);
@@ -516,7 +554,16 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
                return (result);
        }
 
-       ifp->dscp = dscp;
+       ifp->dscp = elt->dscp;
+
+       if (elt->sslctx != NULL) {
+               result = ns_interface_listentls(ifp, elt->sslctx);
+               if (result != ISC_R_SUCCESS) {
+                       goto cleanup_interface;
+               }
+               *ifpret = ifp;
+               return (result);
+       }
 
        result = ns_interface_listenudp(ifp);
        if (result != ISC_R_SUCCESS) {
@@ -865,7 +912,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) {
                                              le->port);
                                result = ns_interface_setup(mgr, &listen_addr,
                                                            "<any>", &ifp, true,
-                                                           le->dscp, NULL);
+                                                           le, NULL);
                                if (result == ISC_R_SUCCESS) {
                                        ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
                                } else {
@@ -1087,8 +1134,8 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) {
 
                                result = ns_interface_setup(
                                        mgr, &listen_sockaddr, interface.name,
-                                       &ifp, (adjusting) ? false : true,
-                                       le->dscp, &addr_in_use);
+                                       &ifp, (adjusting) ? false : true, le,
+                                       &addr_in_use);
 
                                tried_listening = true;
                                if (!addr_in_use) {
index cf23b3f6173a27f4184659d432d840fec12b4b71..50e71023d6886efb6b94cd3d45e8451c037246d0 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdbool.h>
 
 #include <isc/mem.h>
+#include <isc/netmgr.h>
 #include <isc/util.h>
 
 #include <dns/acl.h>
@@ -25,8 +26,10 @@ destroy(ns_listenlist_t *list);
 
 isc_result_t
 ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
-                   dns_acl_t *acl, ns_listenelt_t **target) {
+                   dns_acl_t *acl, bool tls, const char *key, const char *cert,
+                   ns_listenelt_t **target) {
        ns_listenelt_t *elt = NULL;
+       isc_result_t result = ISC_R_SUCCESS;
        REQUIRE(target != NULL && *target == NULL);
        elt = isc_mem_get(mctx, sizeof(*elt));
        elt->mctx = mctx;
@@ -34,6 +37,13 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
        elt->port = port;
        elt->dscp = dscp;
        elt->acl = acl;
+       elt->sslctx = NULL;
+       if (tls) {
+               result = isc_nm_tls_create_server_ctx(key, cert, &elt->sslctx);
+               if (result != ISC_R_SUCCESS) {
+                       return (result);
+               }
+       }
        *target = elt;
        return (ISC_R_SUCCESS);
 }
@@ -43,6 +53,10 @@ ns_listenelt_destroy(ns_listenelt_t *elt) {
        if (elt->acl != NULL) {
                dns_acl_detach(&elt->acl);
        }
+       if (elt->sslctx != NULL) {
+               SSL_CTX_free(elt->sslctx);
+               elt->sslctx = NULL;
+       }
        isc_mem_put(elt->mctx, elt, sizeof(*elt));
 }
 
@@ -104,7 +118,8 @@ ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
                goto cleanup;
        }
 
-       result = ns_listenelt_create(mctx, port, dscp, acl, &elt);
+       result = ns_listenelt_create(mctx, port, dscp, acl, false, NULL, NULL,
+                                    &elt);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_acl;
        }