diff --git a/bin/named/server.c b/bin/named/server.c index cb03db4d62..2d67b7adc3 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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); diff --git a/bin/plugins/synthrecord.c b/bin/plugins/synthrecord.c index 895f2f7df2..fc2f79450b 100644 --- a/bin/plugins/synthrecord.c +++ b/bin/plugins/synthrecord.c @@ -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 diff --git a/bin/tests/system/hooks/driver/test-syncplugin.c b/bin/tests/system/hooks/driver/test-syncplugin.c index c125f335d6..3ac08a2dc9 100644 --- a/bin/tests/system/hooks/driver/test-syncplugin.c +++ b/bin/tests/system/hooks/driver/test-syncplugin.c @@ -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) { diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index 975385409e..6d1ef1e503 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -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. */ diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index c6ecbf041b..90fc49a74e 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -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); } } } diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 8b9a99c8e4..e7980be9cd 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -68,6 +68,14 @@ #include #include +/* + * 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); } } diff --git a/tests/isccfg/parser_test.c b/tests/isccfg/parser_test.c index d817d3eeaf..90a5a3d940 100644 --- a/tests/isccfg/parser_test.c +++ b/tests/isccfg/parser_test.c @@ -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);