configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_aclconfctx_t *actx);
+static const cfg_obj_t *
+find_maplist(const cfg_obj_t *config, const char *listname, const char *name);
+
static isc_result_t
add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
return (result);
}
+static isc_result_t
+validate_tls(const cfg_obj_t *config, dns_view_t *view, const cfg_obj_t *obj,
+ isc_log_t *logctx, const char *str, dns_name_t **name) {
+ dns_fixedname_t fname;
+ dns_name_t *nm = dns_fixedname_initname(&fname);
+ isc_result_t result = dns_name_fromstring(nm, str, 0, NULL);
+
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "'%s' is not a valid name", str);
+ return (result);
+ }
+
+ if (strcasecmp(str, "ephemeral") != 0) {
+ const cfg_obj_t *tlsmap = find_maplist(config, "tls", str);
+
+ if (tlsmap == NULL) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "tls '%s' is not defined", str);
+ return (ISC_R_FAILURE);
+ }
+ }
+
+ if (name != NULL && *name == NULL) {
+ *name = isc_mem_get(view->mctx, sizeof(dns_name_t));
+ dns_name_init(*name, NULL);
+ dns_name_dup(nm, view->mctx, *name);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
static isc_result_t
configure_forward(const cfg_obj_t *config, dns_view_t *view,
const dns_name_t *origin, const cfg_obj_t *forwarders,
const cfg_obj_t *forwardtype) {
const cfg_obj_t *portobj = NULL;
+ const cfg_obj_t *tlspobj = NULL;
const cfg_obj_t *faddresses = NULL;
const cfg_listelt_t *element = NULL;
dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
dns_forwarder_t *fwd = NULL;
isc_result_t result;
in_port_t port;
+ in_port_t tls_port;
+ const char *tls = NULL;
ISC_LIST_INIT(fwdlist);
* Determine which port to send forwarded requests to.
*/
CHECKM(named_config_getport(config, "port", &port), "port");
+ CHECKM(named_config_getport(config, "tls-port", &tls_port), "tls-port");
if (forwarders != NULL) {
portobj = cfg_tuple_get(forwarders, "port");
"port '%u' out of range", val);
return (ISC_R_RANGE);
}
- port = (in_port_t)val;
+ port = tls_port = (in_port_t)val;
+ }
+ }
+
+ /*
+ * TLS value for forwarded requests.
+ */
+ if (forwarders != NULL) {
+ tlspobj = cfg_tuple_get(forwarders, "tls");
+ if (cfg_obj_isstring(tlspobj)) {
+ tls = cfg_obj_asstring(tlspobj);
+ if (tls != NULL) {
+ result = validate_tls(config, view, tlspobj,
+ named_g_lctx, tls, NULL);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+ }
}
}
element = cfg_list_next(element))
{
const cfg_obj_t *forwarder = cfg_listelt_value(element);
+ const char *cur_tls = NULL;
+
fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t));
+ fwd->tlsname = NULL;
+ cur_tls = cfg_obj_getsockaddrtls(forwarder);
+ if (cur_tls == NULL) {
+ cur_tls = tls;
+ }
+ if (cur_tls != NULL) {
+ result = validate_tls(config, view, faddresses,
+ named_g_lctx, cur_tls,
+ &fwd->tlsname);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(view->mctx, fwd,
+ sizeof(dns_forwarder_t));
+ goto cleanup;
+ }
+ }
fwd->addr = *cfg_obj_assockaddr(forwarder);
if (isc_sockaddr_getport(&fwd->addr) == 0) {
- isc_sockaddr_setport(&fwd->addr, port);
+ isc_sockaddr_setport(&fwd->addr,
+ cur_tls != NULL ? tls_port : port);
}
ISC_LINK_INIT(fwd, link);
ISC_LIST_APPEND(fwdlist, fwd, link);
while (!ISC_LIST_EMPTY(fwdlist)) {
fwd = ISC_LIST_HEAD(fwdlist);
ISC_LIST_UNLINK(fwdlist, fwd, link);
+ if (fwd->tlsname != NULL) {
+ dns_name_free(fwd->tlsname, view->mctx);
+ isc_mem_put(view->mctx, fwd->tlsname,
+ sizeof(dns_name_t));
+ }
isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t));
}
#include <isc/util.h>
#include <dns/forward.h>
+#include <dns/name.h>
#include <dns/rbt.h>
#include <dns/types.h>
{
nfwd = isc_mem_get(fwdtable->mctx, sizeof(*nfwd));
*nfwd = *fwd;
+
+ if (fwd->tlsname != NULL) {
+ nfwd->tlsname = isc_mem_get(fwdtable->mctx,
+ sizeof(*nfwd->tlsname));
+ dns_name_init(nfwd->tlsname, NULL);
+ dns_name_dup(fwd->tlsname, fwdtable->mctx,
+ nfwd->tlsname);
+ }
+
ISC_LINK_INIT(nfwd, link);
ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
}
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+ if (fwd->tlsname != NULL) {
+ dns_name_free(fwd->tlsname, fwdtable->mctx);
+ isc_mem_put(fwdtable->mctx, fwd->tlsname,
+ sizeof(*fwd->tlsname));
+ }
isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));
sa = ISC_LIST_NEXT(sa, link))
{
fwd = isc_mem_get(fwdtable->mctx, sizeof(*fwd));
- fwd->addr = *sa;
- ISC_LINK_INIT(fwd, link);
+ *fwd = (dns_forwarder_t){ .addr = *sa,
+ .link = ISC_LINK_INITIALIZER };
ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+ if (fwd->tlsname != NULL) {
+ dns_name_free(fwd->tlsname, fwdtable->mctx);
+ isc_mem_put(fwdtable->mctx, fwd->tlsname,
+ sizeof(*fwd->tlsname));
+ }
isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));