|
|
|
|
@@ -68,6 +68,14 @@
|
|
|
|
|
#include <isccfg/cfg.h>
|
|
|
|
|
#include <isccfg/grammar.h>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* cfg_obj_t is used _a lot_ when building the configuration tree, which
|
|
|
|
|
* can take a significant amount of memory. This assert ensures that we
|
|
|
|
|
* won't increase its size by mistake without getting a warning.
|
|
|
|
|
*/
|
|
|
|
|
static_assert(sizeof(struct cfg_obj) <= 48,
|
|
|
|
|
"sizeof(cfg_obj_t) must be 48 bytes");
|
|
|
|
|
|
|
|
|
|
/* Shorthand */
|
|
|
|
|
#define CAT CFG_LOGCATEGORY_CONFIG
|
|
|
|
|
#define MOD CFG_LOGMODULE_PARSER
|
|
|
|
|
@@ -77,7 +85,6 @@
|
|
|
|
|
#define SYMTAB_DUMMY_TYPE 1
|
|
|
|
|
|
|
|
|
|
#define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base)
|
|
|
|
|
#define TOKEN_REGION(pctx) (pctx->token.value.as_textregion)
|
|
|
|
|
|
|
|
|
|
/* cfg_obj_t magic number */
|
|
|
|
|
#define CFGOBJ_MAGIC ISC_MAGIC('c', 'f', 'g', 'o')
|
|
|
|
|
@@ -188,19 +195,12 @@ copy_sockaddr(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
copy_sockaddrtls(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
to->value.sockaddrtls.sockaddr = isc_mem_get(isc_g_mctx,
|
|
|
|
|
sizeof(isc_sockaddr_t));
|
|
|
|
|
memmove(to->value.sockaddrtls.sockaddr,
|
|
|
|
|
from->value.sockaddrtls.sockaddr, sizeof(isc_sockaddr_t));
|
|
|
|
|
|
|
|
|
|
if (from->value.sockaddrtls.tls.base != NULL) {
|
|
|
|
|
size_t len = from->value.sockaddrtls.tls.length;
|
|
|
|
|
|
|
|
|
|
to->value.sockaddrtls.tls.base = isc_mem_get(isc_g_mctx,
|
|
|
|
|
len + 1);
|
|
|
|
|
to->value.sockaddrtls.tls.length = len;
|
|
|
|
|
memmove(to->value.sockaddrtls.tls.base,
|
|
|
|
|
from->value.sockaddrtls.tls.base, len + 1);
|
|
|
|
|
to->value.sockaddrtls = isc_mem_cget(isc_g_mctx, 1,
|
|
|
|
|
sizeof(*to->value.sockaddrtls));
|
|
|
|
|
to->value.sockaddrtls->sockaddr = from->value.sockaddrtls->sockaddr;
|
|
|
|
|
if (from->value.sockaddrtls->tls != NULL) {
|
|
|
|
|
to->value.sockaddrtls->tls = isc_mem_strdup(
|
|
|
|
|
isc_g_mctx, from->value.sockaddrtls->tls);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -230,11 +230,7 @@ copy_duration(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
copy_string(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
to->value.string.length = from->value.string.length;
|
|
|
|
|
to->value.string.base = isc_mem_get(isc_g_mctx,
|
|
|
|
|
to->value.string.length + 1);
|
|
|
|
|
memmove(to->value.string.base, from->value.string.base,
|
|
|
|
|
to->value.string.length + 1);
|
|
|
|
|
to->value.string = isc_mem_strdup(isc_g_mctx, from->value.string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
@@ -261,7 +257,7 @@ copy_map_add(char *key, unsigned int type, isc_symvalue_t value, void *arg) {
|
|
|
|
|
cfg_obj_clone(value.as_pointer, &toelt);
|
|
|
|
|
value.as_pointer = toelt;
|
|
|
|
|
|
|
|
|
|
INSIST(isc_symtab_define(to->value.map.symtab, key, type, value,
|
|
|
|
|
INSIST(isc_symtab_define(to->value.map->symtab, key, type, value,
|
|
|
|
|
isc_symexists_reject) == ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -272,24 +268,28 @@ copy_map_add(char *key, unsigned int type, isc_symvalue_t value, void *arg) {
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
copy_map(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
if (from->value.map.id != NULL) {
|
|
|
|
|
cfg_obj_clone(from->value.map.id, &to->value.map.id);
|
|
|
|
|
to->value.map = isc_mem_cget(isc_g_mctx, 1, sizeof(*to->value.map));
|
|
|
|
|
|
|
|
|
|
if (from->value.map->id != NULL) {
|
|
|
|
|
cfg_obj_clone(from->value.map->id, &to->value.map->id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isc_symtab_create(isc_g_mctx, copy_map_destroy, NULL, false,
|
|
|
|
|
&to->value.map.symtab);
|
|
|
|
|
isc_symtab_foreach(from->value.map.symtab, copy_map_add, to);
|
|
|
|
|
&to->value.map->symtab);
|
|
|
|
|
isc_symtab_foreach(from->value.map->symtab, copy_map_add, to);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* clausesets are statically defined
|
|
|
|
|
*/
|
|
|
|
|
to->value.map.clausesets = from->value.map.clausesets;
|
|
|
|
|
to->value.map->clausesets = from->value.map->clausesets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
copy_list(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
const cfg_listelt_t *fromelt = cfg_list_first(from);
|
|
|
|
|
|
|
|
|
|
ISC_LIST_INIT(to->value.list);
|
|
|
|
|
to->value.list = isc_mem_get(isc_g_mctx, sizeof(*to->value.list));
|
|
|
|
|
ISC_LIST_INIT(*to->value.list);
|
|
|
|
|
|
|
|
|
|
while (fromelt != NULL) {
|
|
|
|
|
cfg_listelt_t *toelt = isc_mem_get(isc_g_mctx, sizeof(*toelt));
|
|
|
|
|
@@ -297,7 +297,7 @@ copy_list(cfg_obj_t *to, const cfg_obj_t *from) {
|
|
|
|
|
*toelt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER };
|
|
|
|
|
cfg_obj_clone(fromelt->obj, &toelt->obj);
|
|
|
|
|
|
|
|
|
|
ISC_LIST_APPEND(to->value.list, toelt, link);
|
|
|
|
|
ISC_LIST_APPEND(*to->value.list, toelt, link);
|
|
|
|
|
|
|
|
|
|
fromelt = cfg_list_next(fromelt);
|
|
|
|
|
}
|
|
|
|
|
@@ -418,7 +418,7 @@ cfg_parser_currentfile(cfg_parser_t *pctx) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elt = ISC_LIST_TAIL(pctx->open_files->value.list);
|
|
|
|
|
elt = ISC_LIST_TAIL(*pctx->open_files->value.list);
|
|
|
|
|
if (elt == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
@@ -755,7 +755,7 @@ parser_openfile(cfg_parser_t *pctx, const char *filename) {
|
|
|
|
|
cfg_string_create(pctx, filename, &cfg_type_qstring, &stringobj);
|
|
|
|
|
cfg_listelt_create(&elt);
|
|
|
|
|
elt->obj = stringobj;
|
|
|
|
|
ISC_LIST_APPEND(pctx->open_files->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*pctx->open_files->value.list, elt, link);
|
|
|
|
|
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
cleanup:
|
|
|
|
|
@@ -823,10 +823,10 @@ cfg_parse_file(const char *filename, const cfg_type_t *type, unsigned int flags,
|
|
|
|
|
result = parse2(pctx, type, ret);
|
|
|
|
|
|
|
|
|
|
/* Clean up the opened file */
|
|
|
|
|
elt = ISC_LIST_TAIL(pctx->open_files->value.list);
|
|
|
|
|
elt = ISC_LIST_TAIL(*pctx->open_files->value.list);
|
|
|
|
|
INSIST(elt != NULL);
|
|
|
|
|
ISC_LIST_UNLINK(pctx->open_files->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(pctx->closed_files->value.list, elt, link);
|
|
|
|
|
ISC_LIST_UNLINK(*pctx->open_files->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*pctx->closed_files->value.list, elt, link);
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
parser_destroy(&pctx);
|
|
|
|
|
@@ -1397,15 +1397,9 @@ void
|
|
|
|
|
cfg_string_create(cfg_parser_t *pctx, const char *contents,
|
|
|
|
|
const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
cfg_obj_t *obj = NULL;
|
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj);
|
|
|
|
|
len = strlen(contents);
|
|
|
|
|
obj->value.string.length = len;
|
|
|
|
|
obj->value.string.base = isc_mem_get(isc_g_mctx, len + 1);
|
|
|
|
|
memmove(obj->value.string.base, contents, len);
|
|
|
|
|
obj->value.string.base[len] = '\0';
|
|
|
|
|
|
|
|
|
|
obj->value.string = isc_mem_strdup(isc_g_mctx, contents);
|
|
|
|
|
*ret = obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1508,7 +1502,7 @@ print_btext(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
*/
|
|
|
|
|
pctx->indent++;
|
|
|
|
|
cfg_print_cstr(pctx, "{");
|
|
|
|
|
cfg_print_chars(pctx, obj->value.string.base, obj->value.string.length);
|
|
|
|
|
cfg_print_chars(pctx, obj->value.string, strlen(obj->value.string));
|
|
|
|
|
print_close(pctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1538,7 +1532,7 @@ check_enum(cfg_parser_t *pctx, cfg_obj_t *obj, const char *const *enums) {
|
|
|
|
|
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
s = obj->value.string.base;
|
|
|
|
|
s = obj->value.string;
|
|
|
|
|
if (cfg_is_enum(s, enums)) {
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
@@ -1636,17 +1630,17 @@ cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(pctx != NULL);
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
cfg_print_chars(pctx, obj->value.string.base, obj->value.string.length);
|
|
|
|
|
cfg_print_chars(pctx, obj->value.string, strlen(obj->value.string));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
print_rawqstring(cfg_printer_t *pctx, const isc_textregion_t string) {
|
|
|
|
|
print_rawqstring(cfg_printer_t *pctx, const char *string) {
|
|
|
|
|
cfg_print_cstr(pctx, "\"");
|
|
|
|
|
for (size_t i = 0; i < string.length; i++) {
|
|
|
|
|
if (string.base[i] == '"') {
|
|
|
|
|
for (size_t i = 0; i < strlen(string); i++) {
|
|
|
|
|
if (string[i] == '"') {
|
|
|
|
|
cfg_print_cstr(pctx, "\\");
|
|
|
|
|
}
|
|
|
|
|
cfg_print_chars(pctx, (const char *)&string.base[i], 1);
|
|
|
|
|
cfg_print_chars(pctx, (const char *)&string[i], 1);
|
|
|
|
|
}
|
|
|
|
|
cfg_print_cstr(pctx, "\"");
|
|
|
|
|
}
|
|
|
|
|
@@ -1662,7 +1656,7 @@ print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
cfg_print_cstr(pctx, "\"");
|
|
|
|
|
if ((pctx->flags & CFG_PRINTER_XKEY) != 0) {
|
|
|
|
|
unsigned int len = obj->value.string.length;
|
|
|
|
|
size_t len = strlen(obj->value.string);
|
|
|
|
|
while (len-- > 0) {
|
|
|
|
|
cfg_print_cstr(pctx, "?");
|
|
|
|
|
}
|
|
|
|
|
@@ -1674,8 +1668,7 @@ print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_string(cfg_obj_t *obj) {
|
|
|
|
|
isc_mem_put(isc_g_mctx, obj->value.string.base,
|
|
|
|
|
obj->value.string.length + 1);
|
|
|
|
|
isc_mem_free(isc_g_mctx, obj->value.string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
@@ -1685,13 +1678,11 @@ free_sockaddr(cfg_obj_t *obj) {
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_sockaddrtls(cfg_obj_t *obj) {
|
|
|
|
|
isc_mem_put(isc_g_mctx, obj->value.sockaddrtls.sockaddr,
|
|
|
|
|
sizeof(isc_sockaddr_t));
|
|
|
|
|
if (obj->value.sockaddrtls.tls.base != NULL) {
|
|
|
|
|
INSIST(obj->value.sockaddrtls.tls.length != 0);
|
|
|
|
|
isc_mem_put(isc_g_mctx, obj->value.sockaddrtls.tls.base,
|
|
|
|
|
obj->value.sockaddrtls.tls.length + 1);
|
|
|
|
|
if (obj->value.sockaddrtls->tls != NULL) {
|
|
|
|
|
isc_mem_free(isc_g_mctx, obj->value.sockaddrtls->tls);
|
|
|
|
|
}
|
|
|
|
|
isc_mem_put(isc_g_mctx, obj->value.sockaddrtls,
|
|
|
|
|
sizeof(*obj->value.sockaddrtls));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
@@ -1704,7 +1695,7 @@ const char *
|
|
|
|
|
cfg_obj_asstring(const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
REQUIRE(obj->type->rep == &cfg_rep_string);
|
|
|
|
|
return obj->value.string.base;
|
|
|
|
|
return obj->value.string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Quoted string only */
|
|
|
|
|
@@ -1949,7 +1940,7 @@ print_optional_btext(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
|
|
|
|
|
pctx->indent++;
|
|
|
|
|
cfg_print_cstr(pctx, "{");
|
|
|
|
|
cfg_print_chars(pctx, obj->value.string.base, obj->value.string.length);
|
|
|
|
|
cfg_print_chars(pctx, obj->value.string, strlen(obj->value.string));
|
|
|
|
|
print_close(pctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2050,7 +2041,9 @@ create_list(cfg_obj_t *file, size_t line, const cfg_type_t *type,
|
|
|
|
|
REQUIRE(obj != NULL && *obj == NULL);
|
|
|
|
|
|
|
|
|
|
cfg_obj_create(file, line, type, obj);
|
|
|
|
|
ISC_LIST_INIT((*obj)->value.list);
|
|
|
|
|
(*obj)->value.list = isc_mem_get(isc_g_mctx,
|
|
|
|
|
sizeof(*(*obj)->value.list));
|
|
|
|
|
ISC_LIST_INIT(*(*obj)->value.list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
@@ -2076,9 +2069,10 @@ free_listelt(cfg_listelt_t **eltp) {
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_list(cfg_obj_t *obj) {
|
|
|
|
|
ISC_LIST_FOREACH(obj->value.list, elt, link) {
|
|
|
|
|
ISC_LIST_FOREACH(*obj->value.list, elt, link) {
|
|
|
|
|
free_listelt(&elt);
|
|
|
|
|
}
|
|
|
|
|
isc_mem_put(isc_g_mctx, obj->value.list, sizeof(*obj->value.list));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
|
@@ -2124,7 +2118,7 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) {
|
|
|
|
|
}
|
|
|
|
|
CHECK(cfg_parse_listelt(pctx, listobj, listof, &elt));
|
|
|
|
|
CHECK(parse_semicolon(pctx));
|
|
|
|
|
ISC_LIST_APPEND(listobj->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*listobj->value.list, elt, link);
|
|
|
|
|
elt = NULL;
|
|
|
|
|
}
|
|
|
|
|
*ret = listobj;
|
|
|
|
|
@@ -2144,7 +2138,7 @@ print_list(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
list = UNCONST(&obj->value.list);
|
|
|
|
|
list = UNCONST(obj->value.list);
|
|
|
|
|
ISC_LIST_FOREACH(*list, elt, link) {
|
|
|
|
|
if ((pctx->flags & CFG_PRINTER_ONELINE) != 0) {
|
|
|
|
|
cfg_print_obj(pctx, elt->obj);
|
|
|
|
|
@@ -2224,7 +2218,7 @@ cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype,
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
CHECK(cfg_parse_listelt(pctx, listobj, listof, &elt));
|
|
|
|
|
ISC_LIST_APPEND(listobj->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*listobj->value.list, elt, link);
|
|
|
|
|
}
|
|
|
|
|
*ret = listobj;
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
@@ -2241,7 +2235,7 @@ cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(pctx != NULL);
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
list = UNCONST(&obj->value.list);
|
|
|
|
|
list = UNCONST(obj->value.list);
|
|
|
|
|
|
|
|
|
|
ISC_LIST_FOREACH(*list, elt, link) {
|
|
|
|
|
cfg_print_obj(pctx, elt->obj);
|
|
|
|
|
@@ -2264,7 +2258,7 @@ cfg_list_first(const cfg_obj_t *obj) {
|
|
|
|
|
if (obj == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return ISC_LIST_HEAD(obj->value.list);
|
|
|
|
|
return ISC_LIST_HEAD(*obj->value.list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cfg_listelt_t *
|
|
|
|
|
@@ -2276,7 +2270,7 @@ cfg_list_next(const cfg_listelt_t *elt) {
|
|
|
|
|
void
|
|
|
|
|
cfg_list_unlink(cfg_obj_t *list, cfg_listelt_t *elt) {
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(list));
|
|
|
|
|
ISC_LIST_UNLINK(list->value.list, elt, link);
|
|
|
|
|
ISC_LIST_UNLINK(*list->value.list, elt, link);
|
|
|
|
|
free_listelt(&elt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2342,7 +2336,7 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
|
|
|
|
|
create_map(pctx, type, &obj);
|
|
|
|
|
|
|
|
|
|
obj->value.map.clausesets = clausesets;
|
|
|
|
|
obj->value.map->clausesets = clausesets;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
/*
|
|
|
|
|
@@ -2372,7 +2366,7 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
&includename));
|
|
|
|
|
CHECK(parse_semicolon(pctx));
|
|
|
|
|
|
|
|
|
|
if (includename->value.string.length == 0) {
|
|
|
|
|
if (includename->value.string[0] == 0) {
|
|
|
|
|
CLEANUP(ISC_R_FILENOTFOUND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2498,7 +2492,7 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
&cfg_type_implicitlist, &listobj);
|
|
|
|
|
symval.as_pointer = listobj;
|
|
|
|
|
result = isc_symtab_define_and_return(
|
|
|
|
|
obj->value.map.symtab, clause->name,
|
|
|
|
|
obj->value.map->symtab, clause->name,
|
|
|
|
|
SYMTAB_DUMMY_TYPE, symval, isc_symexists_reject,
|
|
|
|
|
&symval);
|
|
|
|
|
if (result == ISC_R_EXISTS) {
|
|
|
|
|
@@ -2508,12 +2502,12 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
|
|
|
|
|
CHECK(cfg_parse_listelt(pctx, listobj, clause->type,
|
|
|
|
|
&elt));
|
|
|
|
|
ISC_LIST_APPEND(listobj->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*listobj->value.list, elt, link);
|
|
|
|
|
CHECK(parse_semicolon(pctx));
|
|
|
|
|
} else {
|
|
|
|
|
/* Single-valued clause */
|
|
|
|
|
result = parse_symtab_elt(pctx, clause,
|
|
|
|
|
obj->value.map.symtab);
|
|
|
|
|
obj->value.map->symtab);
|
|
|
|
|
if (result == ISC_R_EXISTS) {
|
|
|
|
|
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
|
|
|
|
"'%s' redefined",
|
|
|
|
|
@@ -2628,7 +2622,7 @@ parse_any_named_map(cfg_parser_t *pctx, cfg_type_t *nametype,
|
|
|
|
|
|
|
|
|
|
CHECK(cfg_parse_obj(pctx, nametype, &idobj));
|
|
|
|
|
CHECK(cfg_parse_map(pctx, type, &mapobj));
|
|
|
|
|
mapobj->value.map.id = idobj;
|
|
|
|
|
mapobj->value.map->id = idobj;
|
|
|
|
|
*ret = mapobj;
|
|
|
|
|
return result;
|
|
|
|
|
cleanup:
|
|
|
|
|
@@ -2691,7 +2685,7 @@ cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(pctx != NULL);
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
for (clauseset = obj->value.map.clausesets; *clauseset != NULL;
|
|
|
|
|
for (clauseset = obj->value.map->clausesets; *clauseset != NULL;
|
|
|
|
|
clauseset++)
|
|
|
|
|
{
|
|
|
|
|
isc_symvalue_t symval;
|
|
|
|
|
@@ -2704,14 +2698,14 @@ cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = isc_symtab_lookup(obj->value.map.symtab,
|
|
|
|
|
result = isc_symtab_lookup(obj->value.map->symtab,
|
|
|
|
|
clause->name,
|
|
|
|
|
SYMTAB_DUMMY_TYPE, &symval);
|
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
|
cfg_obj_t *symobj = symval.as_pointer;
|
|
|
|
|
if (symobj->type == &cfg_type_implicitlist) {
|
|
|
|
|
/* Multivalued. */
|
|
|
|
|
cfg_list_t *list = &symobj->value.list;
|
|
|
|
|
cfg_list_t *list = symobj->value.list;
|
|
|
|
|
ISC_LIST_FOREACH(*list, elt, link) {
|
|
|
|
|
print_symval(pctx, clause->name,
|
|
|
|
|
elt->obj);
|
|
|
|
|
@@ -2798,8 +2792,8 @@ cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(pctx != NULL);
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
if (obj->value.map.id != NULL) {
|
|
|
|
|
cfg_print_obj(pctx, obj->value.map.id);
|
|
|
|
|
if (obj->value.map->id != NULL) {
|
|
|
|
|
cfg_print_obj(pctx, obj->value.map->id);
|
|
|
|
|
cfg_print_cstr(pctx, " ");
|
|
|
|
|
}
|
|
|
|
|
print_open(pctx);
|
|
|
|
|
@@ -2870,7 +2864,7 @@ cfg_map_get(const cfg_obj_t *mapobj, const char *name, const cfg_obj_t **obj) {
|
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
|
REQUIRE(obj != NULL && *obj == NULL);
|
|
|
|
|
|
|
|
|
|
map = &mapobj->value.map;
|
|
|
|
|
map = mapobj->value.map;
|
|
|
|
|
|
|
|
|
|
RETERR(isc_symtab_lookup(map->symtab, name, SYMTAB_DUMMY_TYPE, &val));
|
|
|
|
|
*obj = val.as_pointer;
|
|
|
|
|
@@ -2881,7 +2875,7 @@ const cfg_obj_t *
|
|
|
|
|
cfg_map_getname(const cfg_obj_t *mapobj) {
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(mapobj));
|
|
|
|
|
REQUIRE(mapobj->type->rep == &cfg_rep_map);
|
|
|
|
|
return mapobj->value.map.id;
|
|
|
|
|
return mapobj->value.map->id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
|
@@ -2891,7 +2885,7 @@ cfg_map_count(const cfg_obj_t *mapobj) {
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(mapobj));
|
|
|
|
|
REQUIRE(mapobj->type->rep == &cfg_rep_map);
|
|
|
|
|
|
|
|
|
|
map = &mapobj->value.map;
|
|
|
|
|
map = mapobj->value.map;
|
|
|
|
|
return isc_symtab_count(map->symtab);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2961,6 +2955,17 @@ cfg_map_findclause(const cfg_type_t *map, const char *name) {
|
|
|
|
|
return ((cfg_clausedef_t *)clauses) + idx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
region_to_string(isc_region_t region) {
|
|
|
|
|
size_t len = region.length + 1;
|
|
|
|
|
char *str = isc_mem_allocate(isc_g_mctx, len);
|
|
|
|
|
|
|
|
|
|
memmove(str, region.base, region.length);
|
|
|
|
|
str[region.length] = 0;
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Parse an arbitrary token, storing its raw text representation. */
|
|
|
|
|
static isc_result_t
|
|
|
|
|
parse_token(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED,
|
|
|
|
|
@@ -2978,11 +2983,8 @@ parse_token(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isc_lex_getlasttokentext(pctx->lexer, &pctx->token, &r);
|
|
|
|
|
obj->value.string = region_to_string(r);
|
|
|
|
|
|
|
|
|
|
obj->value.string.base = isc_mem_get(isc_g_mctx, r.length + 1);
|
|
|
|
|
obj->value.string.length = r.length;
|
|
|
|
|
memmove(obj->value.string.base, r.base, r.length);
|
|
|
|
|
obj->value.string.base[r.length] = '\0';
|
|
|
|
|
*ret = obj;
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
@@ -3032,7 +3034,7 @@ parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECK(cfg_parse_listelt(pctx, listobj, &cfg_type_token, &elt));
|
|
|
|
|
ISC_LIST_APPEND(listobj->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*listobj->value.list, elt, link);
|
|
|
|
|
}
|
|
|
|
|
INSIST(braces == 0);
|
|
|
|
|
*ret = listobj;
|
|
|
|
|
@@ -3404,16 +3406,6 @@ cfg_type_t cfg_type_netprefix = { "netprefix", cfg_parse_netprefix,
|
|
|
|
|
print_netprefix, cfg_doc_terminal,
|
|
|
|
|
&cfg_rep_netprefix, NULL };
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
copy_textregion(isc_mem_t *mctx, isc_textregion_t *dest, isc_textregion_t src) {
|
|
|
|
|
size_t dest_mem_length = (dest->base != NULL) ? dest->length + 1 : 0;
|
|
|
|
|
dest->base = isc_mem_creget(mctx, dest->base, dest_mem_length,
|
|
|
|
|
src.length + 1, sizeof(char));
|
|
|
|
|
dest->length = src.length;
|
|
|
|
|
memmove(dest->base, src.base, src.length);
|
|
|
|
|
dest->base[dest->length] = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
|
parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
|
|
|
|
cfg_obj_t **ret) {
|
|
|
|
|
@@ -3423,12 +3415,10 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
|
|
|
|
cfg_obj_t *obj = NULL;
|
|
|
|
|
int have_address = 0;
|
|
|
|
|
int have_port = 0;
|
|
|
|
|
int have_tls = 0;
|
|
|
|
|
int is_port_ok = (flags & CFG_ADDR_PORTOK) != 0;
|
|
|
|
|
int is_tls_ok = (flags & CFG_ADDR_TLSOK) != 0;
|
|
|
|
|
int is_address_ok = (flags & CFG_ADDR_TRAILINGOK) != 0;
|
|
|
|
|
|
|
|
|
|
isc_textregion_t tls = { .base = NULL, .length = 0 };
|
|
|
|
|
char *tls = NULL;
|
|
|
|
|
|
|
|
|
|
CHECK(cfg_peektoken(pctx, 0));
|
|
|
|
|
if (cfg_lookingat_netaddr(pctx, flags)) {
|
|
|
|
|
@@ -3457,10 +3447,15 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
|
|
|
|
CHECK(cfg_gettoken(pctx, 0)); /* read "tls" */
|
|
|
|
|
CHECK(cfg_getstringtoken(pctx));
|
|
|
|
|
|
|
|
|
|
isc_textregion_t tok = TOKEN_REGION(pctx);
|
|
|
|
|
copy_textregion(isc_g_mctx, &tls, tok);
|
|
|
|
|
if (tls != NULL) {
|
|
|
|
|
cfg_parser_error(
|
|
|
|
|
pctx, 0,
|
|
|
|
|
"expected at most one tls");
|
|
|
|
|
CLEANUP(ISC_R_UNEXPECTEDTOKEN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++have_tls;
|
|
|
|
|
tls = region_to_string(
|
|
|
|
|
pctx->token.value.as_region);
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -3483,25 +3478,27 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
|
|
|
|
CLEANUP(ISC_R_UNEXPECTEDTOKEN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (have_tls > 1) {
|
|
|
|
|
cfg_parser_error(pctx, 0, "expected at most one tls");
|
|
|
|
|
CLEANUP(ISC_R_UNEXPECTEDTOKEN);
|
|
|
|
|
cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj);
|
|
|
|
|
|
|
|
|
|
if (is_tls_ok != 0) {
|
|
|
|
|
obj->value.sockaddrtls = isc_mem_cget(
|
|
|
|
|
isc_g_mctx, 1, sizeof(*obj->value.sockaddrtls));
|
|
|
|
|
isc_sockaddr_fromnetaddr(&obj->value.sockaddrtls->sockaddr,
|
|
|
|
|
&netaddr, port);
|
|
|
|
|
obj->value.sockaddrtls->tls = tls;
|
|
|
|
|
tls = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
obj->value.sockaddr = isc_mem_get(isc_g_mctx,
|
|
|
|
|
sizeof(*obj->value.sockaddr));
|
|
|
|
|
isc_sockaddr_fromnetaddr(obj->value.sockaddr, &netaddr, port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj);
|
|
|
|
|
if (have_tls == 1) {
|
|
|
|
|
obj->value.sockaddrtls.tls = tls;
|
|
|
|
|
}
|
|
|
|
|
obj->value.sockaddrtls.sockaddr = isc_mem_get(isc_g_mctx,
|
|
|
|
|
sizeof(isc_sockaddr_t));
|
|
|
|
|
isc_sockaddr_fromnetaddr(obj->value.sockaddrtls.sockaddr, &netaddr,
|
|
|
|
|
port);
|
|
|
|
|
*ret = obj;
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
if (tls.base != NULL) {
|
|
|
|
|
isc_mem_put(isc_g_mctx, tls.base, tls.length + 1);
|
|
|
|
|
if (tls != NULL) {
|
|
|
|
|
isc_mem_free(isc_g_mctx, tls);
|
|
|
|
|
}
|
|
|
|
|
CLEANUP_OBJ(obj);
|
|
|
|
|
return result;
|
|
|
|
|
@@ -3552,21 +3549,30 @@ cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
|
|
|
|
isc_netaddr_t netaddr;
|
|
|
|
|
in_port_t port;
|
|
|
|
|
char buf[ISC_NETADDR_FORMATSIZE];
|
|
|
|
|
isc_sockaddr_t *sockaddr;
|
|
|
|
|
bool tls = false;
|
|
|
|
|
|
|
|
|
|
REQUIRE(pctx != NULL);
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
|
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, obj->value.sockaddr);
|
|
|
|
|
if (obj->type == &cfg_type_sockaddrtls) {
|
|
|
|
|
sockaddr = &obj->value.sockaddrtls->sockaddr;
|
|
|
|
|
tls = true;
|
|
|
|
|
} else {
|
|
|
|
|
sockaddr = obj->value.sockaddr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, sockaddr);
|
|
|
|
|
isc_netaddr_format(&netaddr, buf, sizeof(buf));
|
|
|
|
|
cfg_print_cstr(pctx, buf);
|
|
|
|
|
port = isc_sockaddr_getport(obj->value.sockaddr);
|
|
|
|
|
port = isc_sockaddr_getport(sockaddr);
|
|
|
|
|
if (port != 0) {
|
|
|
|
|
cfg_print_cstr(pctx, " port ");
|
|
|
|
|
cfg_print_rawuint(pctx, port);
|
|
|
|
|
}
|
|
|
|
|
if (obj->value.sockaddrtls.tls.base != NULL) {
|
|
|
|
|
if (tls && obj->value.sockaddrtls->tls != NULL) {
|
|
|
|
|
cfg_print_cstr(pctx, " tls ");
|
|
|
|
|
print_rawqstring(pctx, obj->value.sockaddrtls.tls);
|
|
|
|
|
print_rawqstring(pctx, obj->value.sockaddrtls->tls);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3637,7 +3643,7 @@ const char *
|
|
|
|
|
cfg_obj_getsockaddrtls(const cfg_obj_t *obj) {
|
|
|
|
|
REQUIRE(VALID_CFGOBJ(obj));
|
|
|
|
|
REQUIRE(obj->type->rep == &cfg_rep_sockaddrtls);
|
|
|
|
|
return obj->value.sockaddrtls.tls.base;
|
|
|
|
|
return obj->value.sockaddrtls->tls;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
|
@@ -3671,11 +3677,11 @@ redo:
|
|
|
|
|
*/
|
|
|
|
|
cfg_listelt_t *elt;
|
|
|
|
|
elt = ISC_LIST_TAIL(
|
|
|
|
|
pctx->open_files->value.list);
|
|
|
|
|
*pctx->open_files->value.list);
|
|
|
|
|
INSIST(elt != NULL);
|
|
|
|
|
ISC_LIST_UNLINK(pctx->open_files->value.list,
|
|
|
|
|
ISC_LIST_UNLINK(*pctx->open_files->value.list,
|
|
|
|
|
elt, link);
|
|
|
|
|
ISC_LIST_APPEND(pctx->closed_files->value.list,
|
|
|
|
|
ISC_LIST_APPEND(*pctx->closed_files->value.list,
|
|
|
|
|
elt, link);
|
|
|
|
|
goto redo;
|
|
|
|
|
}
|
|
|
|
|
@@ -3917,16 +3923,18 @@ create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|
|
|
|
cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj);
|
|
|
|
|
isc_symtab_create(isc_g_mctx, map_symtabitem_destroy, pctx, false,
|
|
|
|
|
&symtab);
|
|
|
|
|
obj->value.map.symtab = symtab;
|
|
|
|
|
obj->value.map.id = NULL;
|
|
|
|
|
|
|
|
|
|
obj->value.map = isc_mem_cget(isc_g_mctx, 1, sizeof(*obj->value.map));
|
|
|
|
|
obj->value.map->symtab = symtab;
|
|
|
|
|
|
|
|
|
|
*ret = obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_map(cfg_obj_t *obj) {
|
|
|
|
|
CLEANUP_OBJ(obj->value.map.id);
|
|
|
|
|
isc_symtab_destroy(&obj->value.map.symtab);
|
|
|
|
|
CLEANUP_OBJ(obj->value.map->id);
|
|
|
|
|
isc_symtab_destroy(&obj->value.map->symtab);
|
|
|
|
|
isc_mem_put(isc_g_mctx, obj->value.map, sizeof(*obj->value.map));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
@@ -3994,7 +4002,7 @@ map_define(cfg_obj_t *mapobj, cfg_obj_t *obj, const cfg_clausedef_t *clause) {
|
|
|
|
|
const cfg_map_t *map;
|
|
|
|
|
isc_symvalue_t symval;
|
|
|
|
|
|
|
|
|
|
map = &mapobj->value.map;
|
|
|
|
|
map = mapobj->value.map;
|
|
|
|
|
result = isc_symtab_lookup(map->symtab, clause->name, SYMTAB_DUMMY_TYPE,
|
|
|
|
|
&symval);
|
|
|
|
|
if (result == ISC_R_NOTFOUND) {
|
|
|
|
|
@@ -4006,7 +4014,7 @@ map_define(cfg_obj_t *mapobj, cfg_obj_t *obj, const cfg_clausedef_t *clause) {
|
|
|
|
|
&cfg_type_implicitlist, &destobj);
|
|
|
|
|
cfg_listelt_create(&elt);
|
|
|
|
|
cfg_obj_attach(obj, &elt->obj);
|
|
|
|
|
ISC_LIST_APPEND(destobj->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*destobj->value.list, elt, link);
|
|
|
|
|
symval.as_pointer = destobj;
|
|
|
|
|
} else {
|
|
|
|
|
symval.as_pointer = obj;
|
|
|
|
|
@@ -4025,7 +4033,7 @@ map_define(cfg_obj_t *mapobj, cfg_obj_t *obj, const cfg_clausedef_t *clause) {
|
|
|
|
|
if (destobj->type == &cfg_type_implicitlist) {
|
|
|
|
|
cfg_listelt_create(&elt);
|
|
|
|
|
cfg_obj_attach(obj, &elt->obj);
|
|
|
|
|
ISC_LIST_APPEND(destobj->value.list, elt, link);
|
|
|
|
|
ISC_LIST_APPEND(*destobj->value.list, elt, link);
|
|
|
|
|
} else {
|
|
|
|
|
result = ISC_R_EXISTS;
|
|
|
|
|
}
|
|
|
|
|
@@ -4114,12 +4122,12 @@ cfg_list_addclone(cfg_obj_t *dst, const cfg_obj_t *src, bool prepend) {
|
|
|
|
|
if (prepend) {
|
|
|
|
|
ISC_LIST_APPEND(list, dstelt, link);
|
|
|
|
|
} else {
|
|
|
|
|
ISC_LIST_APPEND(dst->value.list, dstelt, link);
|
|
|
|
|
ISC_LIST_APPEND(*dst->value.list, dstelt, link);
|
|
|
|
|
}
|
|
|
|
|
srcelt = cfg_list_next(srcelt);
|
|
|
|
|
}
|
|
|
|
|
if (prepend) {
|
|
|
|
|
ISC_LIST_PREPENDLIST(dst->value.list, list, link);
|
|
|
|
|
ISC_LIST_PREPENDLIST(*dst->value.list, list, link);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|