Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5294313284 | ||
|
|
d07faffa93 | ||
|
|
caa7d9ba00 | ||
|
|
13aa796043 | ||
|
|
dbae8fe142 |
+86
-43
@@ -500,6 +500,46 @@ named_config_getzonetype(const cfg_obj_t *zonetypeobj) {
|
|||||||
return (ztype);
|
return (ztype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
named_tuple_getport(const cfg_obj_t *obj, bool optional, in_port_t *portp) {
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
if (obj == NULL || !cfg_obj_isuint32(obj)) {
|
||||||
|
if (optional) {
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val = cfg_obj_asuint32(obj);
|
||||||
|
if (val >= UINT16_MAX) {
|
||||||
|
cfg_obj_log(obj, named_g_lctx, ISC_LOG_ERROR,
|
||||||
|
"port '%u' out of range", val);
|
||||||
|
return (ISC_R_RANGE);
|
||||||
|
}
|
||||||
|
*portp = (in_port_t)val;
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
named_tuple_getdscp(const cfg_obj_t *obj, bool optional, isc_dscp_t *dscpp) {
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
if (obj == NULL || !cfg_obj_isuint32(obj)) {
|
||||||
|
if (optional) {
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val = cfg_obj_asuint32(obj);
|
||||||
|
if (val >= UINT16_MAX) {
|
||||||
|
cfg_obj_log(obj, named_g_lctx, ISC_LOG_ERROR,
|
||||||
|
"dscp '%u' out of range", val);
|
||||||
|
return (ISC_R_RANGE);
|
||||||
|
}
|
||||||
|
*dscpp = (isc_dscp_t)val;
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
named_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
|
named_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
|
||||||
in_port_t defport, isc_mem_t *mctx,
|
in_port_t defport, isc_mem_t *mctx,
|
||||||
@@ -633,19 +673,25 @@ getremotesdef(const cfg_obj_t *cctx, const char *list, const char *name,
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
named_config_getremotesdef(const cfg_obj_t *cctx, const char *list,
|
named_config_getremotesdef(const cfg_obj_t *cctx, const char *list,
|
||||||
const char *name, const cfg_obj_t **ret) {
|
const char *name, const cfg_obj_t **ret,
|
||||||
isc_result_t result;
|
bool *isremote) {
|
||||||
|
isc_result_t result = ISC_R_NOTFOUND;
|
||||||
|
|
||||||
if (strcmp(list, "parental-agents") == 0) {
|
/* Try "remote" first. */
|
||||||
return (getremotesdef(cctx, list, name, ret));
|
result = getremotesdef(cctx, "remote", name, ret);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
*isremote = true;
|
||||||
|
return (result);
|
||||||
|
} else if (strcmp(list, "parental-agents") == 0) {
|
||||||
|
result = getremotesdef(cctx, list, name, ret);
|
||||||
} else if (strcmp(list, "primaries") == 0) {
|
} else if (strcmp(list, "primaries") == 0) {
|
||||||
result = getremotesdef(cctx, list, name, ret);
|
result = getremotesdef(cctx, list, name, ret);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
result = getremotesdef(cctx, "masters", name, ret);
|
result = getremotesdef(cctx, "masters", name, ret);
|
||||||
}
|
}
|
||||||
return (result);
|
|
||||||
}
|
}
|
||||||
return (ISC_R_NOTFOUND);
|
*isremote = false;
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@@ -723,6 +769,7 @@ named_config_getipandkeylist(const cfg_obj_t *config, const char *listtype,
|
|||||||
uint32_t stackcount = 0, pushed = 0;
|
uint32_t stackcount = 0, pushed = 0;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
const cfg_listelt_t *element;
|
const cfg_listelt_t *element;
|
||||||
|
const cfg_obj_t *remoteobj;
|
||||||
const cfg_obj_t *addrlist;
|
const cfg_obj_t *addrlist;
|
||||||
const cfg_obj_t *portobj;
|
const cfg_obj_t *portobj;
|
||||||
const cfg_obj_t *dscpobj;
|
const cfg_obj_t *dscpobj;
|
||||||
@@ -742,6 +789,7 @@ named_config_getipandkeylist(const cfg_obj_t *config, const char *listtype,
|
|||||||
in_port_t port;
|
in_port_t port;
|
||||||
isc_dscp_t dscp;
|
isc_dscp_t dscp;
|
||||||
} *stack = NULL;
|
} *stack = NULL;
|
||||||
|
bool isremote = false;
|
||||||
|
|
||||||
REQUIRE(ipkl != NULL);
|
REQUIRE(ipkl != NULL);
|
||||||
REQUIRE(ipkl->count == 0);
|
REQUIRE(ipkl->count == 0);
|
||||||
@@ -771,30 +819,37 @@ named_config_getipandkeylist(const cfg_obj_t *config, const char *listtype,
|
|||||||
}
|
}
|
||||||
|
|
||||||
newlist:
|
newlist:
|
||||||
addrlist = cfg_tuple_get(list, "addresses");
|
if (isremote) {
|
||||||
portobj = cfg_tuple_get(list, "port");
|
addrlist = NULL;
|
||||||
dscpobj = cfg_tuple_get(list, "dscp");
|
portobj = NULL;
|
||||||
|
dscpobj = NULL;
|
||||||
|
/* TODO: source, source-v6 */
|
||||||
|
remoteobj = cfg_tuple_get(list, "options");
|
||||||
|
(void)cfg_map_get(remoteobj, "addresses", &addrlist);
|
||||||
|
|
||||||
if (cfg_obj_isuint32(portobj)) {
|
result = named_tuple_getport(list, true, &port);
|
||||||
uint32_t val = cfg_obj_asuint32(portobj);
|
if (result != ISC_R_SUCCESS) {
|
||||||
if (val > UINT16_MAX) {
|
|
||||||
cfg_obj_log(portobj, named_g_lctx, ISC_LOG_ERROR,
|
|
||||||
"port '%u' out of range", val);
|
|
||||||
result = ISC_R_RANGE;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
port = (in_port_t)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
|
result = named_tuple_getdscp(list, true, &dscp);
|
||||||
if (cfg_obj_asuint32(dscpobj) > 63) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
cfg_obj_log(dscpobj, named_g_lctx, ISC_LOG_ERROR,
|
goto cleanup;
|
||||||
"dscp value '%u' is out of range",
|
}
|
||||||
cfg_obj_asuint32(dscpobj));
|
} else {
|
||||||
result = ISC_R_RANGE;
|
addrlist = cfg_tuple_get(list, "addresses");
|
||||||
|
portobj = cfg_tuple_get(list, "port");
|
||||||
|
dscpobj = cfg_tuple_get(list, "dscp");
|
||||||
|
|
||||||
|
result = named_tuple_getport(portobj, true, &port);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = named_tuple_getdscp(dscpobj, true, &dscp);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = ISC_R_NOMEMORY;
|
result = ISC_R_NOMEMORY;
|
||||||
@@ -812,8 +867,8 @@ resume:
|
|||||||
tls = cfg_tuple_get(cfg_listelt_value(element), "tls");
|
tls = cfg_tuple_get(cfg_listelt_value(element), "tls");
|
||||||
|
|
||||||
if (!cfg_obj_issockaddr(addr)) {
|
if (!cfg_obj_issockaddr(addr)) {
|
||||||
const char *listname = cfg_obj_asstring(addr);
|
|
||||||
isc_result_t tresult;
|
isc_result_t tresult;
|
||||||
|
const char *listname = cfg_obj_asstring(addr);
|
||||||
|
|
||||||
/* Grow lists? */
|
/* Grow lists? */
|
||||||
grow_array(mctx, lists, l, listcount);
|
grow_array(mctx, lists, l, listcount);
|
||||||
@@ -828,8 +883,8 @@ resume:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list = NULL;
|
list = NULL;
|
||||||
tresult = named_config_getremotesdef(config, listtype,
|
tresult = named_config_getremotesdef(
|
||||||
listname, &list);
|
config, listtype, listname, &list, &isremote);
|
||||||
if (tresult == ISC_R_NOTFOUND) {
|
if (tresult == ISC_R_NOTFOUND) {
|
||||||
cfg_obj_log(addr, named_g_lctx, ISC_LOG_ERROR,
|
cfg_obj_log(addr, named_g_lctx, ISC_LOG_ERROR,
|
||||||
"%s \"%s\" not found", listtype,
|
"%s \"%s\" not found", listtype,
|
||||||
@@ -987,14 +1042,8 @@ named_config_getport(const cfg_obj_t *config, const char *type,
|
|||||||
|
|
||||||
result = named_config_get(maps, type, &portobj);
|
result = named_config_get(maps, type, &portobj);
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
if (cfg_obj_asuint32(portobj) >= UINT16_MAX) {
|
|
||||||
cfg_obj_log(portobj, named_g_lctx, ISC_LOG_ERROR,
|
return (named_tuple_getport(portobj, false, portp));
|
||||||
"port '%u' out of range",
|
|
||||||
cfg_obj_asuint32(portobj));
|
|
||||||
return (ISC_R_RANGE);
|
|
||||||
}
|
|
||||||
*portp = (in_port_t)cfg_obj_asuint32(portobj);
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@@ -1013,14 +1062,8 @@ named_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) {
|
|||||||
*dscpp = -1;
|
*dscpp = -1;
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
if (cfg_obj_asuint32(dscpobj) >= 64) {
|
|
||||||
cfg_obj_log(dscpobj, named_g_lctx, ISC_LOG_ERROR,
|
return (named_tuple_getdscp(dscpobj, false, dscpp));
|
||||||
"dscp '%u' out of range",
|
|
||||||
cfg_obj_asuint32(dscpobj));
|
|
||||||
return (ISC_R_RANGE);
|
|
||||||
}
|
|
||||||
*dscpp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct keyalgorithms {
|
struct keyalgorithms {
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ named_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
named_config_getremotesdef(const cfg_obj_t *cctx, const char *list,
|
named_config_getremotesdef(const cfg_obj_t *cctx, const char *list,
|
||||||
const char *name, const cfg_obj_t **ret);
|
const char *name, const cfg_obj_t **ret,
|
||||||
|
bool *isremote);
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
named_config_getipandkeylist(const cfg_obj_t *config, const char *listtype,
|
named_config_getipandkeylist(const cfg_obj_t *config, const char *listtype,
|
||||||
|
|||||||
@@ -505,6 +505,23 @@ PRIMARIES
|
|||||||
ipv6_address [ port integer ] ) [ key
|
ipv6_address [ port integer ] ) [ key
|
||||||
string ] [ tls string ]; ... };
|
string ] [ tls string ]; ... };
|
||||||
|
|
||||||
|
REMOTE
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
remote string {
|
||||||
|
addresses { ( remote-servers | ipv4_address [ port integer ]
|
||||||
|
| ipv6_address [ port integer ] ) [ key string ] [ tls
|
||||||
|
string ]; ... };
|
||||||
|
dscp integer;
|
||||||
|
port integer;
|
||||||
|
source ( ipv4_address | * ) [ port ( integer | * ) ] [ dscp
|
||||||
|
integer ];
|
||||||
|
source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] [ dscp
|
||||||
|
integer ];
|
||||||
|
};
|
||||||
|
|
||||||
SERVER
|
SERVER
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -1880,9 +1880,12 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||||||
if (obj == NULL && ztype == dns_zone_mirror &&
|
if (obj == NULL && ztype == dns_zone_mirror &&
|
||||||
dns_name_equal(dns_zone_getorigin(zone), dns_rootname))
|
dns_name_equal(dns_zone_getorigin(zone), dns_rootname))
|
||||||
{
|
{
|
||||||
|
bool isremote = false;
|
||||||
result = named_config_getremotesdef(
|
result = named_config_getremotesdef(
|
||||||
named_g_config, "primaries",
|
named_g_config, "primaries",
|
||||||
DEFAULT_IANA_ROOT_ZONE_PRIMARIES, &obj);
|
DEFAULT_IANA_ROOT_ZONE_PRIMARIES, &obj,
|
||||||
|
&isremote);
|
||||||
|
INSIST(!isremote);
|
||||||
RETERR(result);
|
RETERR(result);
|
||||||
}
|
}
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
parental-agents "net" {
|
||||||
|
192.168.1.1;
|
||||||
|
};
|
||||||
|
|
||||||
|
remote "net" {
|
||||||
|
addresses { 192.168.1.2; };
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
parental-agents { "net"; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
primaries "net" {
|
||||||
|
addresses { 192.168.1.1; };
|
||||||
|
};
|
||||||
|
|
||||||
|
parental-agents "net" {
|
||||||
|
addresses { 192.168.1.2; };
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
parental-agents { "net"; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
remote "net" {
|
||||||
|
addresses { 192.168.1.1; };
|
||||||
|
};
|
||||||
|
|
||||||
|
remote "net" {
|
||||||
|
addresses { 192.168.1.2; };
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
parental-agents { "net"; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
options {
|
||||||
|
update-ds { 192.168.1.2; };
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
update-ds { 192.168.1.1; };
|
||||||
|
update-ds { 192.168.1.1; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
update-ds { };
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
zone "." {
|
||||||
|
type mirror;
|
||||||
|
file "root.mirror";
|
||||||
|
update-ds { 192.168.1.1; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
parental-agents "com" {
|
||||||
|
192.168.1.2;
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "example.net" {
|
||||||
|
type primary;
|
||||||
|
file "example.net.db";
|
||||||
|
update-ds { "net"; };
|
||||||
|
};
|
||||||
@@ -183,6 +183,9 @@ view "fourth" {
|
|||||||
1.2.3.4;
|
1.2.3.4;
|
||||||
1.2.3.5;
|
1.2.3.5;
|
||||||
};
|
};
|
||||||
|
update-ds {
|
||||||
|
"parents";
|
||||||
|
};
|
||||||
dnssec-policy "test";
|
dnssec-policy "test";
|
||||||
parental-source 10.10.10.10 port 53 dscp 55;
|
parental-source 10.10.10.10 port 53 dscp 55;
|
||||||
};
|
};
|
||||||
@@ -192,6 +195,10 @@ view "fourth" {
|
|||||||
parental-agents {
|
parental-agents {
|
||||||
"parents";
|
"parents";
|
||||||
};
|
};
|
||||||
|
update-ds {
|
||||||
|
1.2.3.4;
|
||||||
|
1.2.3.5;
|
||||||
|
};
|
||||||
dnssec-policy "default";
|
dnssec-policy "default";
|
||||||
};
|
};
|
||||||
zone "dnssec-inherit" {
|
zone "dnssec-inherit" {
|
||||||
|
|||||||
@@ -34,8 +34,14 @@ controls {
|
|||||||
inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||||
};
|
};
|
||||||
|
|
||||||
parental-agents "ns2" port @PORT@ {
|
remote "ns2" {
|
||||||
10.53.0.2;
|
addresses { 10.53.0.2; };
|
||||||
|
port @PORT@;
|
||||||
|
};
|
||||||
|
|
||||||
|
remote "ns4" {
|
||||||
|
addresses { 10.53.0.4; };
|
||||||
|
port @PORT@;
|
||||||
};
|
};
|
||||||
|
|
||||||
zone "." {
|
zone "." {
|
||||||
@@ -99,10 +105,7 @@ zone "multiple-dspublished.checkds" {
|
|||||||
type primary;
|
type primary;
|
||||||
file "multiple-dspublished.checkds.db";
|
file "multiple-dspublished.checkds.db";
|
||||||
dnssec-policy "default";
|
dnssec-policy "default";
|
||||||
parental-agents {
|
parental-agents { "ns2"; "ns4"; };
|
||||||
10.53.0.2 port @PORT@;
|
|
||||||
10.53.0.4 port @PORT@;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
rm -f dig.out*
|
||||||
|
rm -f ns*/named.conf ns*/named.memstats ns*/named.run*
|
||||||
|
rm -f ns*/*.jnl ns*/*.jbk
|
||||||
|
rm -f ns*/K*.private ns*/K*.key ns*/K*.state
|
||||||
|
rm -f ns*/dsset-*
|
||||||
|
rm -f ns*/*.db ns*/*.jnl ns*/*.jbk ns*/*.db.signed ns*/*.db.infile
|
||||||
|
rm -f ns*/keygen.out.* ns*/settime.out.* ns*/signer.out.*
|
||||||
|
rm -f ns*/managed-keys.bind*
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NS2
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.2;
|
||||||
|
notify-source 10.53.0.2;
|
||||||
|
transfer-source 10.53.0.2;
|
||||||
|
port @PORT@;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.2; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
allow-transfer { any; };
|
||||||
|
recursion no;
|
||||||
|
};
|
||||||
|
|
||||||
|
key rndc_key {
|
||||||
|
secret "1234abcd8765";
|
||||||
|
algorithm hmac-sha256;
|
||||||
|
};
|
||||||
|
|
||||||
|
controls {
|
||||||
|
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "." {
|
||||||
|
type hint;
|
||||||
|
file "../../common/root.hint";
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "updateds" {
|
||||||
|
type primary;
|
||||||
|
file "updateds.db";
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# shellcheck source=conf.sh
|
||||||
|
. ../../conf.sh
|
||||||
|
|
||||||
|
echo_i "ns2/setup.sh"
|
||||||
|
|
||||||
|
for subdomain in dspublish dswithdraw rollover
|
||||||
|
do
|
||||||
|
cp "../ns9/dsset-$subdomain.updateds." .
|
||||||
|
done
|
||||||
|
|
||||||
|
zone="updateds"
|
||||||
|
infile="updateds.db.infile"
|
||||||
|
zonefile="updateds.db"
|
||||||
|
|
||||||
|
CSK=$($KEYGEN -k default $zone 2> keygen.out.$zone)
|
||||||
|
cat template.db.in "${CSK}.key" > "$infile"
|
||||||
|
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||||
|
$SIGNER -S -g -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone 2>&1
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: MPL-2.0
|
||||||
|
;
|
||||||
|
; 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.
|
||||||
|
|
||||||
|
$TTL 300
|
||||||
|
@ IN SOA secondary.example. hostmaster.example. (
|
||||||
|
1 ; serial
|
||||||
|
20 ; refresh (20 seconds)
|
||||||
|
20 ; retry (20 seconds)
|
||||||
|
1814400 ; expire (3 weeks)
|
||||||
|
3600 ; minimum (1 hour)
|
||||||
|
)
|
||||||
|
|
||||||
|
NS ns2
|
||||||
|
ns2 A 10.53.0.2
|
||||||
|
|
||||||
|
dspublish NS ns9.dspublish
|
||||||
|
dswithdraw NS ns9.dswithdraw
|
||||||
|
rollover NS ns9.rollover
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NS9
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.9;
|
||||||
|
notify-source 10.53.0.9;
|
||||||
|
transfer-source 10.53.0.9;
|
||||||
|
port @PORT@;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.9; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
allow-transfer { any; };
|
||||||
|
recursion no;
|
||||||
|
};
|
||||||
|
|
||||||
|
key rndc_key {
|
||||||
|
secret "1234abcd8765";
|
||||||
|
algorithm hmac-sha256;
|
||||||
|
};
|
||||||
|
|
||||||
|
controls {
|
||||||
|
inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||||
|
};
|
||||||
|
|
||||||
|
parental-agents "ns2" port @PORT@ {
|
||||||
|
10.53.0.2;
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "." {
|
||||||
|
type hint;
|
||||||
|
file "../../common/root.hint";
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zone with parental agent configured, time to submit the DS.
|
||||||
|
*/
|
||||||
|
zone "dspublish.updateds" {
|
||||||
|
type primary;
|
||||||
|
file "dspublish.updateds.db";
|
||||||
|
dnssec-policy "default";
|
||||||
|
parental-agents { "ns2"; };
|
||||||
|
update-ds { "ns2"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zone with parental agent configured, time to withdraw the DS.
|
||||||
|
*/
|
||||||
|
zone "dswithdraw.updateds" {
|
||||||
|
type primary;
|
||||||
|
file "dswithdraw.updateds.db";
|
||||||
|
dnssec-policy "insecure";
|
||||||
|
parental-agents { "ns2"; };
|
||||||
|
update-ds { "ns2" };
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zone with parental agent configured, time to update the DS (rollover).
|
||||||
|
*/
|
||||||
|
zone "rollover.updateds" {
|
||||||
|
type primary;
|
||||||
|
file "rollover.updateds.db";
|
||||||
|
dnssec-policy "default";
|
||||||
|
parental-agents { "ns2"; };
|
||||||
|
update-ds { "ns2" };
|
||||||
|
};
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# shellcheck source=conf.sh
|
||||||
|
. ../../conf.sh
|
||||||
|
|
||||||
|
echo_i "ns9/setup.sh"
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
zone="$1"
|
||||||
|
echo_i "setting up zone: $zone"
|
||||||
|
zonefile="${zone}.db"
|
||||||
|
infile="${zone}.db.infile"
|
||||||
|
echo "$zone" >> zones
|
||||||
|
}
|
||||||
|
|
||||||
|
# Short environment variable names for key states and times.
|
||||||
|
H="HIDDEN"
|
||||||
|
R="RUMOURED"
|
||||||
|
O="OMNIPRESENT"
|
||||||
|
U="UNRETENTIVE"
|
||||||
|
T="now-30d"
|
||||||
|
Y="now-1y"
|
||||||
|
|
||||||
|
setup "dspublish.updateds"
|
||||||
|
cp template.db.in "$zonefile"
|
||||||
|
keytimes="-P $T -P sync $T -A $T"
|
||||||
|
CSK=$($KEYGEN -k default $keytimes $zone 2> keygen.out.$zone)
|
||||||
|
$SETTIME -s -g $O -k $O $T -r $O $T -z $O $T -d $H $T "$CSK" > settime.out.$zone 2>&1
|
||||||
|
cat template.db.in "${CSK}.key" > "$infile"
|
||||||
|
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||||
|
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||||
|
|
||||||
|
setup "dswithdraw.updateds"
|
||||||
|
cp template.db.in "$zonefile"
|
||||||
|
keytimes="-P $Y -P sync $Y -A $Y"
|
||||||
|
CSK=$($KEYGEN -k default $keytimes $zone 2> keygen.out.$zone)
|
||||||
|
$SETTIME -s -g $H -k $O $T -r $O $T -z $O $T -d $O $T "$CSK" > settime.out.$zone 2>&1
|
||||||
|
cat template.db.in "${CSK}.key" > "$infile"
|
||||||
|
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||||
|
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
setup "rollover.updateds"
|
||||||
|
cp template.db.in "$zonefile"
|
||||||
|
keytimes="-P $Y -P sync $Y -A $Y"
|
||||||
|
CSK=$($KEYGEN -k default $keytimes $zone 2> keygen.out.$zone)
|
||||||
|
$SETTIME -s -g $H -k $O $T -r $O $T -z $O $T -d $U $T "$CSK" > settime.out.$zone 2>&1
|
||||||
|
cat template.db.in "${CSK}.key" > "$infile"
|
||||||
|
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||||
|
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: MPL-2.0
|
||||||
|
;
|
||||||
|
; 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.
|
||||||
|
|
||||||
|
$TTL 300
|
||||||
|
@ IN SOA mname1. . (
|
||||||
|
1 ; serial
|
||||||
|
20 ; refresh (20 seconds)
|
||||||
|
20 ; retry (20 seconds)
|
||||||
|
1814400 ; expire (3 weeks)
|
||||||
|
3600 ; minimum (1 hour)
|
||||||
|
)
|
||||||
|
|
||||||
|
NS ns9
|
||||||
|
ns9 A 10.53.0.9
|
||||||
|
|
||||||
|
a A 10.0.0.1
|
||||||
|
b A 10.0.0.2
|
||||||
|
c A 10.0.0.3
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# shellcheck source=conf.sh
|
||||||
|
. ../conf.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
$SHELL clean.sh
|
||||||
|
|
||||||
|
copy_setports ns2/named.conf.in ns2/named.conf
|
||||||
|
copy_setports ns9/named.conf.in ns9/named.conf
|
||||||
|
|
||||||
|
# Setup zones
|
||||||
|
(
|
||||||
|
cd ns9
|
||||||
|
$SHELL setup.sh
|
||||||
|
)
|
||||||
|
(
|
||||||
|
cd ns2
|
||||||
|
$SHELL setup.sh
|
||||||
|
)
|
||||||
Executable
+277
@@ -0,0 +1,277 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import mmap
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
pytest.importorskip("dns", minversion="2.0.0")
|
||||||
|
import dns.exception
|
||||||
|
import dns.message
|
||||||
|
import dns.name
|
||||||
|
import dns.query
|
||||||
|
import dns.rcode
|
||||||
|
import dns.rdataclass
|
||||||
|
import dns.rdatatype
|
||||||
|
import dns.resolver
|
||||||
|
|
||||||
|
|
||||||
|
def has_signed_apex_nsec(zone, response):
|
||||||
|
has_nsec = False
|
||||||
|
has_rrsig = False
|
||||||
|
|
||||||
|
ttl = 300
|
||||||
|
nextname = "a."
|
||||||
|
types = "NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY"
|
||||||
|
match = "{0} {1} IN NSEC {2}{0} {3}".format(zone, ttl, nextname, types)
|
||||||
|
sig = "{0} {1} IN RRSIG NSEC 13 2 300".format(zone, ttl)
|
||||||
|
|
||||||
|
for rr in response.answer:
|
||||||
|
if match in rr.to_text():
|
||||||
|
has_nsec = True
|
||||||
|
if sig in rr.to_text():
|
||||||
|
has_rrsig = True
|
||||||
|
|
||||||
|
if not has_nsec:
|
||||||
|
print("error: missing apex NSEC record in response")
|
||||||
|
if not has_rrsig:
|
||||||
|
print("error: missing NSEC signature in response")
|
||||||
|
|
||||||
|
return has_nsec and has_rrsig
|
||||||
|
|
||||||
|
|
||||||
|
def do_query(server, qname, qtype, tcp=False):
|
||||||
|
query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True)
|
||||||
|
try:
|
||||||
|
if tcp:
|
||||||
|
response = dns.query.tcp(
|
||||||
|
query, server.nameservers[0], timeout=3, port=server.port
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
response = dns.query.udp(
|
||||||
|
query, server.nameservers[0], timeout=3, port=server.port
|
||||||
|
)
|
||||||
|
except dns.exception.Timeout:
|
||||||
|
print(
|
||||||
|
"error: query timeout for query {} {} to {}".format(
|
||||||
|
qname, qtype, server.nameservers[0]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def verify_zone(zone, transfer):
|
||||||
|
verify = os.getenv("VERIFY")
|
||||||
|
assert verify is not None
|
||||||
|
|
||||||
|
filename = "{}out".format(zone)
|
||||||
|
with open(filename, "w", encoding="utf-8") as file:
|
||||||
|
for rr in transfer.answer:
|
||||||
|
file.write(rr.to_text())
|
||||||
|
file.write("\n")
|
||||||
|
|
||||||
|
# dnssec-verify command with default arguments.
|
||||||
|
verify_cmd = [verify, "-z", "-o", zone, filename]
|
||||||
|
|
||||||
|
verifier = subprocess.run(verify_cmd, capture_output=True, check=True)
|
||||||
|
|
||||||
|
if verifier.returncode != 0:
|
||||||
|
print("error: dnssec-verify {} failed".format(zone))
|
||||||
|
sys.stderr.buffer.write(verifier.stderr)
|
||||||
|
|
||||||
|
return verifier.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def read_statefile(server, zone):
|
||||||
|
addr = server.nameservers[0]
|
||||||
|
count = 0
|
||||||
|
keyid = 0
|
||||||
|
state = {}
|
||||||
|
|
||||||
|
response = do_query(server, zone, "DS", tcp=True)
|
||||||
|
if not isinstance(response, dns.message.Message):
|
||||||
|
print("error: no response for {} DS from {}".format(zone, addr))
|
||||||
|
return {}
|
||||||
|
|
||||||
|
if response.rcode() == dns.rcode.NOERROR:
|
||||||
|
# fetch key id from response.
|
||||||
|
for rr in response.answer:
|
||||||
|
if rr.match(
|
||||||
|
dns.name.from_text(zone),
|
||||||
|
dns.rdataclass.IN,
|
||||||
|
dns.rdatatype.DS,
|
||||||
|
dns.rdatatype.NONE,
|
||||||
|
):
|
||||||
|
if count == 0:
|
||||||
|
keyid = list(dict(rr.items).items())[0][0].key_tag
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
if count != 1:
|
||||||
|
print(
|
||||||
|
"error: expected a single DS in response for {} from {},"
|
||||||
|
"got {}".format(zone, addr, count)
|
||||||
|
)
|
||||||
|
return {}
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
"error: {} response for {} DNSKEY from {}".format(
|
||||||
|
dns.rcode.to_text(response.rcode()), zone, addr
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return {}
|
||||||
|
|
||||||
|
filename = "ns9/K{}+013+{:05d}.state".format(zone, keyid)
|
||||||
|
print("read state file {}".format(filename))
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filename, "r", encoding="utf-8") as file:
|
||||||
|
for line in file:
|
||||||
|
if line.startswith(";"):
|
||||||
|
continue
|
||||||
|
key, val = line.strip().split(":", 1)
|
||||||
|
state[key.strip()] = val.strip()
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
# file may not be written just yet.
|
||||||
|
return {}
|
||||||
|
|
||||||
|
return state
|
||||||
|
|
||||||
|
|
||||||
|
def zone_check(server, zone):
|
||||||
|
addr = server.nameservers[0]
|
||||||
|
|
||||||
|
# wait until zone is fully signed.
|
||||||
|
signed = False
|
||||||
|
for _ in range(10):
|
||||||
|
response = do_query(server, zone, "NSEC")
|
||||||
|
if not isinstance(response, dns.message.Message):
|
||||||
|
print("error: no response for {} NSEC from {}".format(zone, addr))
|
||||||
|
elif response.rcode() == dns.rcode.NOERROR:
|
||||||
|
signed = has_signed_apex_nsec(zone, response)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
"error: {} response for {} NSEC from {}".format(
|
||||||
|
dns.rcode.to_text(response.rcode()), zone, addr
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if signed:
|
||||||
|
break
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
assert signed
|
||||||
|
|
||||||
|
# check if zone if DNSSEC valid.
|
||||||
|
verified = False
|
||||||
|
transfer = do_query(server, zone, "AXFR", tcp=True)
|
||||||
|
if not isinstance(transfer, dns.message.Message):
|
||||||
|
print("error: no response for {} AXFR from {}".format(zone, addr))
|
||||||
|
elif transfer.rcode() == dns.rcode.NOERROR:
|
||||||
|
verified = verify_zone(zone, transfer)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
"error: {} response for {} AXFR from {}".format(
|
||||||
|
dns.rcode.to_text(transfer.rcode()), zone, addr
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert verified
|
||||||
|
|
||||||
|
|
||||||
|
def keystate_check(server, zone, key):
|
||||||
|
val = 0
|
||||||
|
deny = False
|
||||||
|
|
||||||
|
search = key
|
||||||
|
if key.startswith("!"):
|
||||||
|
deny = True
|
||||||
|
search = key[1:]
|
||||||
|
|
||||||
|
for _ in range(10):
|
||||||
|
state = read_statefile(server, zone)
|
||||||
|
try:
|
||||||
|
val = state[search]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not deny and val != 0:
|
||||||
|
break
|
||||||
|
if deny and val == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
if deny:
|
||||||
|
assert val == 0
|
||||||
|
else:
|
||||||
|
assert val != 0
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_log(filename, log):
|
||||||
|
found = False
|
||||||
|
|
||||||
|
for _ in range(10):
|
||||||
|
print("read log file {}".format(filename))
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filename, "r", encoding="utf-8") as file:
|
||||||
|
s = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
|
||||||
|
if s.find(bytes(log, "ascii")) != -1:
|
||||||
|
found = True
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("file not found {}".format(filename))
|
||||||
|
|
||||||
|
if found:
|
||||||
|
break
|
||||||
|
|
||||||
|
print("sleep")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
assert found
|
||||||
|
|
||||||
|
|
||||||
|
def test_updateds_publishds(named_port):
|
||||||
|
# Create resolver instances that will be used to send queries.
|
||||||
|
server = dns.resolver.Resolver()
|
||||||
|
server.nameservers = ["10.53.0.9"]
|
||||||
|
server.port = named_port
|
||||||
|
|
||||||
|
parent = dns.resolver.Resolver()
|
||||||
|
parent.nameservers = ["10.53.0.2"]
|
||||||
|
parent.port = named_port
|
||||||
|
|
||||||
|
# DS published in parent.
|
||||||
|
parent_check(parent, "publishds.updateds.")
|
||||||
|
|
||||||
|
def test_updateds_withdrawds(named_port):
|
||||||
|
# We create resolver instances that will be used to send queries.
|
||||||
|
server = dns.resolver.Resolver()
|
||||||
|
server.nameservers = ["10.53.0.9"]
|
||||||
|
server.port = named_port
|
||||||
|
|
||||||
|
parent = dns.resolver.Resolver()
|
||||||
|
parent.nameservers = ["10.53.0.2"]
|
||||||
|
parent.port = named_port
|
||||||
|
|
||||||
|
# DS removed from parent.
|
||||||
|
parent_check(parent, "withdrawds.updateds.")
|
||||||
|
|
||||||
|
# TBD: Key event does not change DS at the parent.
|
||||||
@@ -382,7 +382,7 @@ The following blocks are supported:
|
|||||||
Controls global server configuration options and sets defaults for other statements.
|
Controls global server configuration options and sets defaults for other statements.
|
||||||
|
|
||||||
``parental-agents``
|
``parental-agents``
|
||||||
Defines a named list of servers for inclusion in primary and secondary zones' ``parental-agents`` lists.
|
Defines a named list of servers for inclusion in primary and secondary zones' ``parental-agents`` or ``update-ds`` lists.
|
||||||
|
|
||||||
.. _primaries:
|
.. _primaries:
|
||||||
|
|
||||||
@@ -6648,6 +6648,12 @@ Zone Options
|
|||||||
``dnssec-secure-to-insecure``
|
``dnssec-secure-to-insecure``
|
||||||
See the description of ``dnssec-secure-to-insecure`` in :ref:`boolean_options`.
|
See the description of ``dnssec-secure-to-insecure`` in :ref:`boolean_options`.
|
||||||
|
|
||||||
|
``update-ds``
|
||||||
|
Defines a named list of servers that will be used to send dynamic
|
||||||
|
updates to. When the zone is configured with a ``dnssec-policy``,
|
||||||
|
BIND will try to update the DS RRset at these servers during a key
|
||||||
|
rollover.
|
||||||
|
|
||||||
.. _dynamic_update_policies:
|
.. _dynamic_update_policies:
|
||||||
|
|
||||||
Dynamic Update Policies
|
Dynamic Update Policies
|
||||||
|
|||||||
@@ -1042,6 +1042,7 @@ zone <string> [ <class> ] {
|
|||||||
sig\-signing\-type <integer>;
|
sig\-signing\-type <integer>;
|
||||||
sig\-validity\-interval <integer> [ <integer> ];
|
sig\-validity\-interval <integer> [ <integer> ];
|
||||||
update\-check\-ksk <boolean>;
|
update\-check\-ksk <boolean>;
|
||||||
|
update\-ds [ port <integer> ] [ dscp <integer> ] { ( <remote\-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
update\-policy ( local | { ( deny | grant ) <string> ( 6to4\-self | external | krb5\-self | krb5\-selfsub | krb5\-subdomain | krb5\-subdomain\-self\-rhs | ms\-self | ms\-selfsub | ms\-subdomain | ms\-subdomain\-self\-rhs | name | self | selfsub | selfwild | subdomain | tcp\-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
update\-policy ( local | { ( deny | grant ) <string> ( 6to4\-self | external | krb5\-self | krb5\-selfsub | krb5\-subdomain | krb5\-subdomain\-self\-rhs | ms\-self | ms\-selfsub | ms\-subdomain | ms\-subdomain\-self\-rhs | name | self | selfsub | selfwild | subdomain | tcp\-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
||||||
zero\-no\-soa\-ttl <boolean>;
|
zero\-no\-soa\-ttl <boolean>;
|
||||||
zone\-statistics ( full | terse | none | <boolean> );
|
zone\-statistics ( full | terse | none | <boolean> );
|
||||||
@@ -1115,6 +1116,7 @@ zone <string> [ <class> ] {
|
|||||||
transfer\-source\-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
transfer\-source\-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
||||||
try\-tcp\-refresh <boolean>;
|
try\-tcp\-refresh <boolean>;
|
||||||
update\-check\-ksk <boolean>;
|
update\-check\-ksk <boolean>;
|
||||||
|
update\-ds [ port <integer> ] [ dscp <integer> ] { ( <remote\-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
use\-alt\-transfer\-source <boolean>;
|
use\-alt\-transfer\-source <boolean>;
|
||||||
zero\-no\-soa\-ttl <boolean>;
|
zero\-no\-soa\-ttl <boolean>;
|
||||||
zone\-statistics ( full | terse | none | <boolean> );
|
zone\-statistics ( full | terse | none | <boolean> );
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ zone <string> [ <class> ] {
|
|||||||
sig-signing-type <integer>;
|
sig-signing-type <integer>;
|
||||||
sig-validity-interval <integer> [ <integer> ];
|
sig-validity-interval <integer> [ <integer> ];
|
||||||
update-check-ksk <boolean>;
|
update-check-ksk <boolean>;
|
||||||
|
update-ds [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
||||||
zero-no-soa-ttl <boolean>;
|
zero-no-soa-ttl <boolean>;
|
||||||
zone-statistics ( full | terse | none | <boolean> );
|
zone-statistics ( full | terse | none | <boolean> );
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
sig-signing-type <integer>;
|
sig-signing-type <integer>;
|
||||||
sig-validity-interval <integer> [ <integer> ];
|
sig-validity-interval <integer> [ <integer> ];
|
||||||
update-check-ksk <boolean>;
|
update-check-ksk <boolean>;
|
||||||
|
update-ds [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
||||||
zero-no-soa-ttl <boolean>;
|
zero-no-soa-ttl <boolean>;
|
||||||
zone-statistics ( full | terse | none | <boolean> );
|
zone-statistics ( full | terse | none | <boolean> );
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ zone <string> [ <class> ] {
|
|||||||
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
||||||
try-tcp-refresh <boolean>;
|
try-tcp-refresh <boolean>;
|
||||||
update-check-ksk <boolean>;
|
update-check-ksk <boolean>;
|
||||||
|
update-ds [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
use-alt-transfer-source <boolean>;
|
use-alt-transfer-source <boolean>;
|
||||||
zero-no-soa-ttl <boolean>;
|
zero-no-soa-ttl <boolean>;
|
||||||
zone-statistics ( full | terse | none | <boolean> );
|
zone-statistics ( full | terse | none | <boolean> );
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
||||||
try-tcp-refresh <boolean>;
|
try-tcp-refresh <boolean>;
|
||||||
update-check-ksk <boolean>;
|
update-check-ksk <boolean>;
|
||||||
|
update-ds [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
use-alt-transfer-source <boolean>;
|
use-alt-transfer-source <boolean>;
|
||||||
zero-no-soa-ttl <boolean>;
|
zero-no-soa-ttl <boolean>;
|
||||||
zone-statistics ( full | terse | none | <boolean> );
|
zone-statistics ( full | terse | none | <boolean> );
|
||||||
|
|||||||
+48
-36
@@ -2029,11 +2029,11 @@ bind9_check_remoteserverlist(const cfg_obj_t *cctx, const char *list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check primaries lists for duplicates.
|
* Check remote server lists for duplicates.
|
||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
bind9_check_primarylists(const cfg_obj_t *cctx, isc_log_t *logctx,
|
bind9_check_remoteserverlists(const cfg_obj_t *cctx, isc_log_t *logctx,
|
||||||
isc_mem_t *mctx) {
|
isc_mem_t *mctx) {
|
||||||
isc_result_t result, tresult;
|
isc_result_t result, tresult;
|
||||||
isc_symtab_t *symtab = NULL;
|
isc_symtab_t *symtab = NULL;
|
||||||
|
|
||||||
@@ -2041,6 +2041,16 @@ bind9_check_primarylists(const cfg_obj_t *cctx, isc_log_t *logctx,
|
|||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
tresult = bind9_check_remoteserverlist(cctx, "remote", logctx, symtab,
|
||||||
|
mctx);
|
||||||
|
if (tresult != ISC_R_SUCCESS) {
|
||||||
|
result = tresult;
|
||||||
|
}
|
||||||
|
tresult = bind9_check_remoteserverlist(cctx, "parental-agents", logctx,
|
||||||
|
symtab, mctx);
|
||||||
|
if (tresult != ISC_R_SUCCESS) {
|
||||||
|
result = tresult;
|
||||||
|
}
|
||||||
tresult = bind9_check_remoteserverlist(cctx, "primaries", logctx,
|
tresult = bind9_check_remoteserverlist(cctx, "primaries", logctx,
|
||||||
symtab, mctx);
|
symtab, mctx);
|
||||||
if (tresult != ISC_R_SUCCESS) {
|
if (tresult != ISC_R_SUCCESS) {
|
||||||
@@ -2055,28 +2065,6 @@ bind9_check_primarylists(const cfg_obj_t *cctx, isc_log_t *logctx,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check parental-agents lists for duplicates.
|
|
||||||
*/
|
|
||||||
static isc_result_t
|
|
||||||
bind9_check_parentalagentlists(const cfg_obj_t *cctx, isc_log_t *logctx,
|
|
||||||
isc_mem_t *mctx) {
|
|
||||||
isc_result_t result, tresult;
|
|
||||||
isc_symtab_t *symtab = NULL;
|
|
||||||
|
|
||||||
result = isc_symtab_create(mctx, 100, freekey, mctx, false, &symtab);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
tresult = bind9_check_remoteserverlist(cctx, "parental-agents", logctx,
|
|
||||||
symtab, mctx);
|
|
||||||
if (tresult != ISC_R_SUCCESS) {
|
|
||||||
result = tresult;
|
|
||||||
}
|
|
||||||
isc_symtab_destroy(&symtab);
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_LIBNGHTTP2
|
#if HAVE_LIBNGHTTP2
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
bind9_check_httpserver(const cfg_obj_t *http, isc_log_t *logctx,
|
bind9_check_httpserver(const cfg_obj_t *http, isc_log_t *logctx,
|
||||||
@@ -2362,10 +2350,15 @@ get_remotes(const cfg_obj_t *cctx, const char *list, const char *name,
|
|||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
get_remoteservers_def(const char *list, const char *name, const cfg_obj_t *cctx,
|
get_remoteservers_def(const char *list, const char *name, const cfg_obj_t *cctx,
|
||||||
const cfg_obj_t **ret) {
|
const cfg_obj_t **ret, bool *isremote) {
|
||||||
isc_result_t result = ISC_R_NOTFOUND;
|
isc_result_t result = ISC_R_NOTFOUND;
|
||||||
|
|
||||||
if (strcmp(list, "primaries") == 0) {
|
/* Try "remote" first. */
|
||||||
|
result = get_remotes(cctx, "remote", name, ret);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
*isremote = true;
|
||||||
|
return (result);
|
||||||
|
} else if (strcmp(list, "primaries") == 0) {
|
||||||
result = get_remotes(cctx, "primaries", name, ret);
|
result = get_remotes(cctx, "primaries", name, ret);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
result = get_remotes(cctx, "masters", name, ret);
|
result = get_remotes(cctx, "masters", name, ret);
|
||||||
@@ -2373,6 +2366,8 @@ get_remoteservers_def(const char *list, const char *name, const cfg_obj_t *cctx,
|
|||||||
} else if (strcmp(list, "parental-agents") == 0) {
|
} else if (strcmp(list, "parental-agents") == 0) {
|
||||||
result = get_remotes(cctx, "parental-agents", name, ret);
|
result = get_remotes(cctx, "parental-agents", name, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*isremote = false;
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2389,6 +2384,8 @@ validate_remotes(const char *list, const cfg_obj_t *obj,
|
|||||||
const cfg_listelt_t **stack = NULL;
|
const cfg_listelt_t **stack = NULL;
|
||||||
uint32_t stackcount = 0, pushed = 0;
|
uint32_t stackcount = 0, pushed = 0;
|
||||||
const cfg_obj_t *listobj;
|
const cfg_obj_t *listobj;
|
||||||
|
const cfg_obj_t *remoteobj;
|
||||||
|
bool isremote = false;
|
||||||
|
|
||||||
REQUIRE(countp != NULL);
|
REQUIRE(countp != NULL);
|
||||||
result = isc_symtab_create(mctx, 100, NULL, NULL, false, &symtab);
|
result = isc_symtab_create(mctx, 100, NULL, NULL, false, &symtab);
|
||||||
@@ -2398,7 +2395,13 @@ validate_remotes(const char *list, const cfg_obj_t *obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
newlist:
|
newlist:
|
||||||
listobj = cfg_tuple_get(obj, "addresses");
|
if (isremote) {
|
||||||
|
listobj = NULL;
|
||||||
|
remoteobj = cfg_tuple_get(obj, "options");
|
||||||
|
(void)cfg_map_get(remoteobj, "addresses", &listobj);
|
||||||
|
} else {
|
||||||
|
listobj = cfg_tuple_get(obj, "addresses");
|
||||||
|
}
|
||||||
element = cfg_list_first(listobj);
|
element = cfg_list_first(listobj);
|
||||||
resume:
|
resume:
|
||||||
for (; element != NULL; element = cfg_list_next(element)) {
|
for (; element != NULL; element = cfg_list_next(element)) {
|
||||||
@@ -2483,7 +2486,8 @@ resume:
|
|||||||
if (tresult == ISC_R_EXISTS) {
|
if (tresult == ISC_R_EXISTS) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tresult = get_remoteservers_def(list, listname, config, &obj);
|
tresult = get_remoteservers_def(list, listname, config, &obj,
|
||||||
|
&isremote);
|
||||||
if (tresult != ISC_R_SUCCESS) {
|
if (tresult != ISC_R_SUCCESS) {
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
result = tresult;
|
result = tresult;
|
||||||
@@ -3316,12 +3320,17 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Primary and secondary zones that have a "parental-agents" field,
|
* Primary and secondary zones that have a "parental-agents" or
|
||||||
* must have a corresponding "parental-agents" clause.
|
* "update-ds" field, must have a corresponding "parental-agents"
|
||||||
|
* clause.
|
||||||
*/
|
*/
|
||||||
if (ztype == CFG_ZONE_PRIMARY || ztype == CFG_ZONE_SECONDARY) {
|
if (ztype == CFG_ZONE_PRIMARY || ztype == CFG_ZONE_SECONDARY) {
|
||||||
|
bool updateds = false;
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
(void)cfg_map_get(zoptions, "parental-agents", &obj);
|
(void)cfg_map_get(zoptions, "parental-agents", &obj);
|
||||||
|
|
||||||
|
check_parentalagents:
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
tresult = validate_remotes("parental-agents", obj,
|
tresult = validate_remotes("parental-agents", obj,
|
||||||
@@ -3339,6 +3348,13 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||||||
result = ISC_R_FAILURE;
|
result = ISC_R_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!updateds) {
|
||||||
|
obj = NULL;
|
||||||
|
(void)cfg_map_get(zoptions, "update-ds", &obj);
|
||||||
|
updateds = true;
|
||||||
|
goto check_parentalagents;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5781,11 +5797,7 @@ bind9_check_namedconf(const cfg_obj_t *config, bool check_plugins,
|
|||||||
result = ISC_R_FAILURE;
|
result = ISC_R_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind9_check_primarylists(config, logctx, mctx) != ISC_R_SUCCESS) {
|
if (bind9_check_remoteserverlists(config, logctx, mctx) !=
|
||||||
result = ISC_R_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind9_check_parentalagentlists(config, logctx, mctx) !=
|
|
||||||
ISC_R_SUCCESS) {
|
ISC_R_SUCCESS) {
|
||||||
result = ISC_R_FAILURE;
|
result = ISC_R_FAILURE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ libdns_la_HEADERS = \
|
|||||||
include/dns/rdatasetiter.h \
|
include/dns/rdatasetiter.h \
|
||||||
include/dns/rdataslab.h \
|
include/dns/rdataslab.h \
|
||||||
include/dns/rdatatype.h \
|
include/dns/rdatatype.h \
|
||||||
|
include/dns/remote.h \
|
||||||
include/dns/request.h \
|
include/dns/request.h \
|
||||||
include/dns/resolver.h \
|
include/dns/resolver.h \
|
||||||
include/dns/result.h \
|
include/dns/result.h \
|
||||||
@@ -212,6 +213,7 @@ libdns_la_SOURCES = \
|
|||||||
rdataset.c \
|
rdataset.c \
|
||||||
rdatasetiter.c \
|
rdatasetiter.c \
|
||||||
rdataslab.c \
|
rdataslab.c \
|
||||||
|
remote.c \
|
||||||
request.c \
|
request.c \
|
||||||
resolver.c \
|
resolver.c \
|
||||||
result.c \
|
result.c \
|
||||||
|
|||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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 dns/remote.h */
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <isc/lang.h>
|
||||||
|
#include <isc/mem.h>
|
||||||
|
|
||||||
|
#include <dns/types.h>
|
||||||
|
|
||||||
|
ISC_LANG_BEGINDECLS
|
||||||
|
|
||||||
|
struct dns_remote {
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
isc_sockaddr_t *addresses;
|
||||||
|
isc_dscp_t *dscps;
|
||||||
|
dns_name_t **keynames;
|
||||||
|
dns_name_t **tlsnames;
|
||||||
|
bool *ok;
|
||||||
|
unsigned int addrcnt;
|
||||||
|
unsigned int curraddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
isc_sockaddr_t *
|
||||||
|
dns_remote_addresses(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the addresses of the remote server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_remote_count(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the number of addresses of the remote server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_name_t **
|
||||||
|
dns_remote_keynames(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the keynames of the remote server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_name_t **
|
||||||
|
dns_remote_tlsnames(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the tlsnames of the remote server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_init(dns_remote_t *remote, unsigned int count,
|
||||||
|
const isc_sockaddr_t *addrs, const isc_dscp_t *dscp,
|
||||||
|
dns_name_t **keynames, dns_name_t **tlsnames, bool mark,
|
||||||
|
isc_mem_t *mctx);
|
||||||
|
|
||||||
|
/*%<
|
||||||
|
* Initialize a remote server. Set the provided addresses (addrs),
|
||||||
|
* dscp's (dscp), key names (keynames) and tls names (tlsnames). Use the
|
||||||
|
* provided memory context (mctx) for allocations. If 'mark' is 'true',
|
||||||
|
* set up a list of boolean values to mark the server bad or good.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
* 'mctx' is not NULL.
|
||||||
|
* 'addrs' is not NULL or 'count' equals zero.
|
||||||
|
* if 'count' is not zero, 'keynames' and 'tlsnames' are
|
||||||
|
*not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_clear(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Clear remote server 'remote', free memory.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_equal(dns_remote_t *a, dns_remote_t *b);
|
||||||
|
/*%<
|
||||||
|
* Compare two remote servers 'a' and 'b'. Check if the address
|
||||||
|
* count, the addresses, the dscps, the key names and the tls names are
|
||||||
|
* the same. Return 'true' if so, 'false' otherwise.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'a' is not NULL and 'b' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_reset(dns_remote_t *remote, bool clear_ok);
|
||||||
|
/*%<
|
||||||
|
* Reset the remote server, set the current address back to the
|
||||||
|
*first. If 'clear_ok' is 'true', clear any servers marked ok.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_next(dns_remote_t *remote, bool skip_good);
|
||||||
|
/*%<
|
||||||
|
* Skipt to the next address. If 'skip_good' is 'true', skip over
|
||||||
|
* already addresses already considered good, whatever good means in the
|
||||||
|
* context of this remote server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_sockaddr_t
|
||||||
|
dns_remote_curraddr(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the currently used address for this remote server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
'remote->addresses' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_sockaddr_t
|
||||||
|
dns_remote_addr(dns_remote_t *remote, unsigned int i);
|
||||||
|
/*%<
|
||||||
|
* Return the address at index 'i'. Returns NULL if we i is equal
|
||||||
|
* or larger than the address count.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
'remote->addresses' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_dscp_t
|
||||||
|
dns_remote_dscp(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the current dscp. Returns -1 if we have iterated over all
|
||||||
|
* addresses already, or if dscps are not used.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_name_t *
|
||||||
|
dns_remote_keyname(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the current key name. Returns NULL if we have iterated
|
||||||
|
* over all addresses already, or if keynames are not used.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_name_t *
|
||||||
|
dns_remote_tlsname(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return the current tls name. Returns NULL if we have iterated
|
||||||
|
* over all addresses already, or if tlsnames are not used.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_allgood(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return 'true' if all the addresses are considered good.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_mark(dns_remote_t *remote, bool good);
|
||||||
|
/*%<
|
||||||
|
* Mark the current address 'good' (or not good if 'good' is
|
||||||
|
* 'false').
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
* The current address index is lower than the address count.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_addrok(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return 'true' if the current address is marked good, 'false'
|
||||||
|
* otherwise. Also return 'true' if marking servers is not used.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
* The current address index is lower than the address count.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_done(dns_remote_t *remote);
|
||||||
|
/*%<
|
||||||
|
* Return 'true' if we iterated over all addresses, 'false' otherwise.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* 'remote' is not NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ISC_LANG_ENDDECLS
|
||||||
@@ -127,6 +127,7 @@ typedef struct dns_rdataset dns_rdataset_t;
|
|||||||
typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t;
|
typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t;
|
||||||
typedef struct dns_rdatasetiter dns_rdatasetiter_t;
|
typedef struct dns_rdatasetiter dns_rdatasetiter_t;
|
||||||
typedef uint16_t dns_rdatatype_t;
|
typedef uint16_t dns_rdatatype_t;
|
||||||
|
typedef struct dns_remote dns_remote_t;
|
||||||
typedef struct dns_request dns_request_t;
|
typedef struct dns_request dns_request_t;
|
||||||
typedef struct dns_requestmgr dns_requestmgr_t;
|
typedef struct dns_requestmgr dns_requestmgr_t;
|
||||||
typedef struct dns_resolver dns_resolver_t;
|
typedef struct dns_resolver dns_resolver_t;
|
||||||
|
|||||||
@@ -642,7 +642,7 @@ dns_zone_maintenance(dns_zone_t *zone);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
|
dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses,
|
||||||
dns_name_t **keynames, dns_name_t **tlsnames,
|
dns_name_t **keynames, dns_name_t **tlsnames,
|
||||||
uint32_t count);
|
uint32_t count);
|
||||||
/*%<
|
/*%<
|
||||||
@@ -650,8 +650,8 @@ dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
|
|||||||
*
|
*
|
||||||
* Require:
|
* Require:
|
||||||
*\li 'zone' to be a valid zone.
|
*\li 'zone' to be a valid zone.
|
||||||
*\li 'primaries' array of isc_sockaddr_t with port set or NULL.
|
*\li 'addresses' array of isc_sockaddr_t with port set or NULL.
|
||||||
*\li 'count' the number of primaries.
|
*\li 'count' the number of addresses.
|
||||||
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
|
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
|
||||||
*
|
*
|
||||||
*\li If 'primaries' is NULL then 'count' must be zero.
|
*\li If 'primaries' is NULL then 'count' must be zero.
|
||||||
@@ -663,7 +663,7 @@ dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses,
|
||||||
dns_name_t **keynames, dns_name_t **tlsnames,
|
dns_name_t **keynames, dns_name_t **tlsnames,
|
||||||
uint32_t count);
|
uint32_t count);
|
||||||
/*%<
|
/*%<
|
||||||
@@ -684,29 +684,8 @@ dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses,
|
||||||
dns_name_t **keynames, dns_name_t **tlsnames,
|
isc_dscp_t *dscps, dns_name_t **keynames,
|
||||||
uint32_t count);
|
|
||||||
/*%<
|
|
||||||
* Set the list of parental agents for the zone.
|
|
||||||
*
|
|
||||||
* Require:
|
|
||||||
*\li 'zone' to be a valid zone.
|
|
||||||
*\li 'parentals' array of isc_sockaddr_t with port set or NULL.
|
|
||||||
*\li 'count' the number of parentals.
|
|
||||||
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
|
|
||||||
*
|
|
||||||
*\li If 'parentals' is NULL then 'count' must be zero.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
*\li #ISC_R_SUCCESS
|
|
||||||
*\li #ISC_R_NOMEMORY
|
|
||||||
*\li Any result dns_name_dup() can return, if keynames!=NULL
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
|
|
||||||
const isc_dscp_t *dscps, dns_name_t **keynames,
|
|
||||||
dns_name_t **tlsnames, uint32_t count);
|
dns_name_t **tlsnames, uint32_t count);
|
||||||
/*%<
|
/*%<
|
||||||
* Set the list of additional servers to be notified when
|
* Set the list of additional servers to be notified when
|
||||||
@@ -717,8 +696,8 @@ dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
|
|||||||
*
|
*
|
||||||
* Require:
|
* Require:
|
||||||
*\li 'zone' to be a valid zone.
|
*\li 'zone' to be a valid zone.
|
||||||
*\li 'notify' to be non-NULL if count != 0.
|
*\li 'addresses' to be non-NULL if count != 0.
|
||||||
*\li 'count' to be the number of notifiees.
|
*\li 'count' to be the number of addresses.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
*\li #ISC_R_SUCCESS
|
*\li #ISC_R_SUCCESS
|
||||||
|
|||||||
@@ -0,0 +1,416 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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 <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <isc/result.h>
|
||||||
|
#include <isc/sockaddr.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include <dns/name.h>
|
||||||
|
#include <dns/remote.h>
|
||||||
|
#include <dns/types.h>
|
||||||
|
|
||||||
|
isc_sockaddr_t *
|
||||||
|
dns_remote_addresses(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
return (remote->addresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_remote_count(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
return (remote->addrcnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_name_t **
|
||||||
|
dns_remote_keynames(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
return (remote->keynames);
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_name_t **
|
||||||
|
dns_remote_tlsnames(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
return (remote->tlsnames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_init(dns_remote_t *remote, unsigned int count,
|
||||||
|
const isc_sockaddr_t *addrs, const isc_dscp_t *dscp,
|
||||||
|
dns_name_t **keynames, dns_name_t **tlsnames, bool mark,
|
||||||
|
isc_mem_t *mctx) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
REQUIRE(count == 0 || addrs != NULL);
|
||||||
|
if (keynames != NULL || tlsnames != NULL) {
|
||||||
|
REQUIRE(count != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
remote->mctx = mctx;
|
||||||
|
|
||||||
|
if (addrs != NULL) {
|
||||||
|
remote->addresses = isc_mem_get(mctx,
|
||||||
|
count * sizeof(isc_sockaddr_t));
|
||||||
|
memmove(remote->addresses, addrs,
|
||||||
|
count * sizeof(isc_sockaddr_t));
|
||||||
|
} else {
|
||||||
|
remote->addresses = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dscp != NULL) {
|
||||||
|
remote->dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
|
||||||
|
memmove(remote->dscps, dscp, count * sizeof(isc_dscp_t));
|
||||||
|
} else {
|
||||||
|
remote->dscps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keynames != NULL) {
|
||||||
|
remote->keynames = isc_mem_get(mctx, count * sizeof(keynames));
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
remote->keynames[i] = NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (keynames[i] != NULL) {
|
||||||
|
remote->keynames[i] =
|
||||||
|
isc_mem_get(mctx, sizeof(dns_name_t));
|
||||||
|
dns_name_init(remote->keynames[i], NULL);
|
||||||
|
dns_name_dup(keynames[i], mctx,
|
||||||
|
remote->keynames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
remote->keynames = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tlsnames != NULL) {
|
||||||
|
remote->tlsnames = isc_mem_get(mctx, count * sizeof(tlsnames));
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
remote->tlsnames[i] = NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (tlsnames[i] != NULL) {
|
||||||
|
remote->tlsnames[i] =
|
||||||
|
isc_mem_get(mctx, sizeof(dns_name_t));
|
||||||
|
dns_name_init(remote->tlsnames[i], NULL);
|
||||||
|
dns_name_dup(tlsnames[i], mctx,
|
||||||
|
remote->tlsnames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
remote->tlsnames = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mark) {
|
||||||
|
remote->ok = isc_mem_get(mctx, count * sizeof(bool));
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
remote->ok[i] = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
remote->ok = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
remote->addrcnt = count;
|
||||||
|
remote->curraddr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
|
||||||
|
uint32_t count) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (oldlist == NULL && newlist == NULL) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
if (oldlist == NULL || newlist == NULL) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist,
|
||||||
|
uint32_t count) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (oldlist == NULL && newlist == NULL) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
if (oldlist == NULL || newlist == NULL) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (oldlist[i] == NULL && newlist[i] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (oldlist[i] == NULL || newlist[i] == NULL ||
|
||||||
|
!dns_name_equal(oldlist[i], newlist[i]))
|
||||||
|
{
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
same_dscp(isc_dscp_t *oldlist, isc_dscp_t *newlist, uint32_t count) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (oldlist == NULL && newlist == NULL) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
if (oldlist == NULL || newlist == NULL) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (oldlist[i] != newlist[i]) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_clear(dns_remote_t *remote) {
|
||||||
|
unsigned int count;
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
count = remote->addrcnt;
|
||||||
|
mctx = remote->mctx;
|
||||||
|
|
||||||
|
if (mctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote->ok != NULL) {
|
||||||
|
isc_mem_put(mctx, remote->ok, count * sizeof(bool));
|
||||||
|
remote->ok = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote->addresses != NULL) {
|
||||||
|
isc_mem_put(mctx, remote->addresses,
|
||||||
|
count * sizeof(isc_sockaddr_t));
|
||||||
|
remote->addresses = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote->dscps != NULL) {
|
||||||
|
isc_mem_put(mctx, remote->dscps, count * sizeof(isc_dscp_t));
|
||||||
|
remote->dscps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote->keynames != NULL) {
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (remote->keynames[i] != NULL) {
|
||||||
|
dns_name_free(remote->keynames[i], mctx);
|
||||||
|
isc_mem_put(mctx, remote->keynames[i],
|
||||||
|
sizeof(dns_name_t));
|
||||||
|
remote->keynames[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isc_mem_put(mctx, remote->keynames,
|
||||||
|
count * sizeof(dns_name_t *));
|
||||||
|
remote->keynames = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote->tlsnames != NULL) {
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (remote->tlsnames[i] != NULL) {
|
||||||
|
dns_name_free(remote->tlsnames[i], mctx);
|
||||||
|
isc_mem_put(mctx, remote->tlsnames[i],
|
||||||
|
sizeof(dns_name_t));
|
||||||
|
remote->tlsnames[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isc_mem_put(mctx, remote->tlsnames,
|
||||||
|
count * sizeof(dns_name_t *));
|
||||||
|
remote->tlsnames = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
remote->mctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_equal(dns_remote_t *a, dns_remote_t *b) {
|
||||||
|
REQUIRE(a != NULL);
|
||||||
|
REQUIRE(b != NULL);
|
||||||
|
|
||||||
|
if (a->addrcnt != b->addrcnt) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!same_addrs(a->addresses, b->addresses, a->addrcnt)) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (!same_dscp(a->dscps, b->dscps, a->addrcnt)) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!same_names(a->keynames, b->keynames, a->addrcnt)) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (!same_names(a->tlsnames, b->tlsnames, a->addrcnt)) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_reset(dns_remote_t *remote, bool clear_ok) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
remote->curraddr = 0;
|
||||||
|
|
||||||
|
if (clear_ok && remote->ok != NULL) {
|
||||||
|
for (unsigned int i = 0; i < remote->addrcnt; i++) {
|
||||||
|
remote->ok[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_sockaddr_t
|
||||||
|
dns_remote_curraddr(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
REQUIRE(remote->addresses != NULL);
|
||||||
|
REQUIRE(remote->curraddr < remote->addrcnt);
|
||||||
|
|
||||||
|
return (remote->addresses[remote->curraddr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_sockaddr_t
|
||||||
|
dns_remote_addr(dns_remote_t *remote, unsigned int i) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
REQUIRE(remote->addresses != NULL);
|
||||||
|
REQUIRE(i < remote->addrcnt);
|
||||||
|
|
||||||
|
return (remote->addresses[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_dscp_t
|
||||||
|
dns_remote_dscp(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
if (remote->dscps == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (remote->curraddr >= remote->addrcnt) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (remote->dscps[remote->curraddr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_name_t *
|
||||||
|
dns_remote_keyname(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
if (remote->keynames == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (remote->curraddr >= remote->addrcnt) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (remote->keynames[remote->curraddr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_name_t *
|
||||||
|
dns_remote_tlsname(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
if (remote->tlsnames == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (remote->curraddr >= remote->addrcnt) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (remote->tlsnames[remote->curraddr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_next(dns_remote_t *remote, bool skip_good) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
skip_to_next:
|
||||||
|
remote->curraddr++;
|
||||||
|
|
||||||
|
if (remote->curraddr >= remote->addrcnt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip_good && remote->ok != NULL && remote->ok[remote->curraddr]) {
|
||||||
|
goto skip_to_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_done(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
return (remote->curraddr >= remote->addrcnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_allgood(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
|
||||||
|
if (remote->ok == NULL) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < remote->addrcnt; i++) {
|
||||||
|
if (!remote->ok[i]) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_remote_addrok(dns_remote_t *remote) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
REQUIRE(remote->curraddr < remote->addrcnt);
|
||||||
|
|
||||||
|
if (remote->ok == NULL) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (remote->ok[remote->curraddr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_remote_mark(dns_remote_t *remote, bool good) {
|
||||||
|
REQUIRE(remote != NULL);
|
||||||
|
REQUIRE(remote->curraddr < remote->addrcnt);
|
||||||
|
|
||||||
|
remote->ok[remote->curraddr] = good;
|
||||||
|
}
|
||||||
+226
-467
File diff suppressed because it is too large
Load Diff
@@ -242,6 +242,33 @@ static cfg_type_t cfg_type_remoteservers = { "remote-servers", cfg_parse_tuple,
|
|||||||
cfg_print_tuple, cfg_doc_tuple,
|
cfg_print_tuple, cfg_doc_tuple,
|
||||||
&cfg_rep_tuple, remotes_fields };
|
&cfg_rep_tuple, remotes_fields };
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Statement to configure communication with remote servers.
|
||||||
|
*/
|
||||||
|
static cfg_clausedef_t remote_clauses[] = {
|
||||||
|
{ "port", &cfg_type_uint32, 0 },
|
||||||
|
{ "dscp", &cfg_type_uint32, 0 },
|
||||||
|
{ "source", &cfg_type_sockaddr4wild, 0 },
|
||||||
|
{ "source-v6", &cfg_type_sockaddr6wild, 0 },
|
||||||
|
{ "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
|
||||||
|
{ NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static cfg_clausedef_t *remote_clausesets[] = { remote_clauses, NULL };
|
||||||
|
|
||||||
|
cfg_type_t cfg_type_remoteopts = { "remoteopts", cfg_parse_map,
|
||||||
|
cfg_print_map, cfg_doc_map,
|
||||||
|
&cfg_rep_map, remote_clausesets };
|
||||||
|
|
||||||
|
static cfg_tuplefielddef_t remote_fields[] = { { "name", &cfg_type_astring, 0 },
|
||||||
|
{ "options",
|
||||||
|
&cfg_type_remoteopts, 0 },
|
||||||
|
{ NULL, NULL, 0 } };
|
||||||
|
|
||||||
|
static cfg_type_t cfg_type_remote = { "remote", cfg_parse_tuple,
|
||||||
|
cfg_print_tuple, cfg_doc_tuple,
|
||||||
|
&cfg_rep_tuple, remote_fields };
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* "sockaddrkeylist", a list of socket addresses with optional keys
|
* "sockaddrkeylist", a list of socket addresses with optional keys
|
||||||
* and an optional default port, as used in the remote-servers option.
|
* and an optional default port, as used in the remote-servers option.
|
||||||
@@ -1162,6 +1189,7 @@ static cfg_clausedef_t namedconf_clauses[] = {
|
|||||||
{ "options", &cfg_type_options, 0 },
|
{ "options", &cfg_type_options, 0 },
|
||||||
{ "parental-agents", &cfg_type_remoteservers, CFG_CLAUSEFLAG_MULTI },
|
{ "parental-agents", &cfg_type_remoteservers, CFG_CLAUSEFLAG_MULTI },
|
||||||
{ "primaries", &cfg_type_remoteservers, CFG_CLAUSEFLAG_MULTI },
|
{ "primaries", &cfg_type_remoteservers, CFG_CLAUSEFLAG_MULTI },
|
||||||
|
{ "remote", &cfg_type_remote, CFG_CLAUSEFLAG_MULTI },
|
||||||
{ "statistics-channels", &cfg_type_statschannels,
|
{ "statistics-channels", &cfg_type_statschannels,
|
||||||
CFG_CLAUSEFLAG_MULTI },
|
CFG_CLAUSEFLAG_MULTI },
|
||||||
{ "tls", &cfg_type_tlsconf, CFG_CLAUSEFLAG_MULTI },
|
{ "tls", &cfg_type_tlsconf, CFG_CLAUSEFLAG_MULTI },
|
||||||
@@ -2405,6 +2433,8 @@ static cfg_clausedef_t zone_only_clauses[] = {
|
|||||||
{ "server-addresses", &cfg_type_bracketed_netaddrlist,
|
{ "server-addresses", &cfg_type_bracketed_netaddrlist,
|
||||||
CFG_ZONE_STATICSTUB },
|
CFG_ZONE_STATICSTUB },
|
||||||
{ "server-names", &cfg_type_namelist, CFG_ZONE_STATICSTUB },
|
{ "server-names", &cfg_type_namelist, CFG_ZONE_STATICSTUB },
|
||||||
|
{ "update-ds", &cfg_type_namesockaddrkeylist,
|
||||||
|
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
||||||
{ "update-policy", &cfg_type_updatepolicy, CFG_ZONE_PRIMARY },
|
{ "update-policy", &cfg_type_updatepolicy, CFG_ZONE_PRIMARY },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user