shrunk cfgobj down to 48bytes

Make all non-scalar properties of `cfg_obj_t` allocated values, which
ensures the union size is the width of one pointer. Also reorder the
fields inside `cfg_obj_t` to avoid alignment padding that would increase
the size. As a result, a `cfg_obj_t` instance is now 48 bytes on a
64-bit platform.

Add a static assertion to avoid increasing the size of the struct by
mistake.

The function `parse_sockaddrsub` was taking advantage of the fact that
both sockaddr and sockaddrtls were in the same position, and used to
initialize the sockaddr field independently if this was a -tls one or
not. This doesn't work anymore now that all fields are allocated,
so it has been slightly rewritten to take both cases into account
separately.
This commit is contained in:
Colin Vidal
2025-11-07 14:58:36 +01:00
parent b97991463e
commit 77e0104cf4
7 changed files with 185 additions and 168 deletions

View File

@@ -12088,7 +12088,7 @@ nzf_writeconf(const cfg_obj_t *config, dns_view_t *view) {
CLEANUP(ISC_R_FAILURE);
}
list = UNCONST(&zl->value.list);
list = UNCONST(zl->value.list);
CHECK(add_comment(fp, view->name)); /* force a comment */
@@ -12750,7 +12750,7 @@ delete_zoneconf(dns_view_t *view, const cfg_obj_t *config,
CLEANUP(ISC_R_FAILURE);
}
cfg_list_t *list = UNCONST(&zl->value.list);
cfg_list_t *list = UNCONST(zl->value.list);
ISC_LIST_FOREACH(*list, elt, link) {
dns_fixedname_t myfixed;
dns_name_t *myname = dns_fixedname_initname(&myfixed);

View File

@@ -408,7 +408,6 @@ static cfg_type_t synthrecord_cfgparams = {
static isc_result_t
synthrecord_initprefix(synthrecord_t *inst, const cfg_obj_t *synthrecordcfg) {
isc_result_t result;
size_t len;
const char *base = NULL;
const cfg_obj_t *obj = NULL;
@@ -419,9 +418,7 @@ synthrecord_initprefix(synthrecord_t *inst, const cfg_obj_t *synthrecordcfg) {
return result;
}
len = obj->value.string.length;
base = obj->value.string.base;
base = obj->value.string;
if (strstr(base, ".") != NULL) {
isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS,
ISC_LOG_ERROR,
@@ -430,10 +427,9 @@ synthrecord_initprefix(synthrecord_t *inst, const cfg_obj_t *synthrecordcfg) {
return ISC_R_UNEXPECTEDTOKEN;
}
inst->prefix = (isc_region_t){
.base = isc_mem_allocate(inst->mctx, len), .length = len
};
memmove(inst->prefix.base, base, len);
inst->prefix = (isc_region_t){ .base = (unsigned char *)isc_mem_strdup(
inst->mctx, base),
.length = strlen(base) };
/*
* Avoid dynamically lower-casing the prefix when parsing the

View File

@@ -80,7 +80,7 @@ syncplugin__parse_rcode(const cfg_obj_t *syncplugincfg, uint8_t *rcode) {
RETERR(cfg_map_get(syncplugincfg, "rcode", &obj));
rcodestr = obj->value.string.base;
rcodestr = obj->value.string;
if (strcmp("servfail", rcodestr) == 0) {
*rcode = dns_rcode_servfail;
@@ -141,7 +141,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfgfile,
obj = NULL;
CHECK(cfg_map_get(syncplugincfg, "source", &obj));
sourcestr = obj->value.string.base;
sourcestr = obj->value.string;
if (strcmp(sourcestr, "zone") == 0) {
if (ctx->source != NS_HOOKSOURCE_ZONE) {

View File

@@ -196,37 +196,43 @@ struct cfg_rep {
* A configuration object. This is the main building block
* of the configuration parse tree.
*/
typedef struct {
isc_sockaddr_t sockaddr;
char *tls;
} cfg_sockaddrtls_t;
struct cfg_obj {
unsigned int magic;
isc_refcount_t references;
/*
* These two 4 byte fields are contiguous to avoid an extra
* padding of 4 bytes each, avoiding an extra 8 bytes in the
* struct.
*/
unsigned int magic;
unsigned int line;
isc_refcount_t references;
cfg_obj_t *file; /*%< separate string with its own refcount */
const cfg_type_t *type;
union {
uint32_t uint32;
uint64_t uint64;
char *string; /*%< null terminated */
bool boolean;
cfg_map_t *map;
cfg_list_t *list;
cfg_obj_t **tuple;
isc_sockaddr_t *sockaddr;
cfg_sockaddrtls_t *sockaddrtls;
cfg_netprefix_t *netprefix;
isccfg_duration_t *duration;
} value;
/*%
* Indicates that an object was cloned from the defaults
* or otherwise generated during the configuration merge
* process:
* process.
*/
bool cloned;
const cfg_type_t *type;
union {
uint32_t uint32;
uint64_t uint64;
isc_textregion_t string; /*%< null terminated, too */
bool boolean;
cfg_map_t map;
cfg_list_t list;
cfg_obj_t **tuple;
isc_sockaddr_t *sockaddr;
struct {
isc_sockaddr_t *sockaddr;
isc_textregion_t tls;
} sockaddrtls;
cfg_netprefix_t *netprefix;
isccfg_duration_t *duration;
} value;
cfg_obj_t *file; /*%< separate string with its own refcount */
unsigned int line;
};
/*% A list element. */

View File

@@ -2297,8 +2297,8 @@ checknames_merge(const cfg_obj_t *config ISC_ATTR_UNUSED,
const cfg_obj_t *etype = cfg_tuple_get(echeckname,
"type");
if (strcasecmp(type->value.string.base,
etype->value.string.base) == 0)
if (strcasecmp(type->value.string,
etype->value.string) == 0)
{
found = true;
break;
@@ -2311,7 +2311,7 @@ checknames_merge(const cfg_obj_t *config ISC_ATTR_UNUSED,
cfg_listelt_create(&eelt);
*eelt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER };
cfg_obj_clone(checkname, &eelt->obj);
ISC_LIST_APPEND(effectiveobj->value.list, eelt, link);
ISC_LIST_APPEND(*effectiveobj->value.list, eelt, link);
}
}
}

View File

@@ -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);
}
}

View File

@@ -233,6 +233,9 @@ options {\n\
answer-cookie yes;\n\
cookie-algorithm siphash24;\n\
dump-file \"named_dump.db\";\n\
listen-on port 53 tls \"foobar\" {\n\
127.0.0.1/32;\n\
};\n\
notify-rate 20;\n\
allow-recursion {\n\
\"localhost\";\n\
@@ -250,6 +253,9 @@ view \"_bind\" chaos {\n\
zone \"version.bind\" chaos {\n\
type primary;\n\
database \"_builtin version\";\n\
update-policy {\n\
grant \"int\" zonesub \"any\";\n\
};\n\
};\n\
max-cache-size 2097152;\n\
rate-limit {\n\
@@ -257,6 +263,7 @@ view \"_bind\" chaos {\n\
slip 0;\n\
};\n\
};\n";
isc_buffer_init(&buf, conf, sizeof(conf));
isc_buffer_add(&buf, sizeof(conf) - 1);