chg: dev: Shrunk cfgobj down from 72 bytes to 48 bytes

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.

Merge branch 'colin/cfgobj-48bytes' into 'main'

See merge request isc-projects/bind9!11239
This commit is contained in:
Colin Vidal 2025-12-05 09:35:58 +01:00
commit 38ce29066b
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);