diff options
Diffstat (limited to 'util/config_file.c')
| -rw-r--r-- | util/config_file.c | 210 |
1 files changed, 194 insertions, 16 deletions
diff --git a/util/config_file.c b/util/config_file.c index f9b1531c23dc..3e72bcad06b1 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -163,6 +163,7 @@ config_create(void) cfg->so_sndbuf = 0; cfg->so_reuseport = 0; cfg->ip_transparent = 0; + cfg->ip_freebind = 0; cfg->num_ifs = 0; cfg->ifs = NULL; cfg->num_out_ifs = 0; @@ -237,6 +238,7 @@ config_create(void) if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH))) goto error_exit; #endif + cfg->disable_dnssec_lame_check = 0; cfg->ratelimit = 0; cfg->ratelimit_slabs = 4; cfg->ratelimit_size = 4*1024*1024; @@ -393,6 +395,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_MEMSIZE("so-sndbuf:", so_sndbuf) else S_YNO("so-reuseport:", so_reuseport) else S_YNO("ip-transparent:", ip_transparent) + else S_YNO("ip-freebind:", ip_freebind) else S_MEMSIZE("rrset-cache-size:", rrset_cache_size) else S_POW2("rrset-cache-slabs:", rrset_cache_slabs) else S_YNO("prefetch:", prefetch) @@ -473,6 +476,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_STR("control-cert-file:", control_cert_file) else S_STR("module-config:", module_conf) else S_STR("python-script:", python_script) + else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check) else if(strcmp(opt, "ratelimit:") == 0) { IS_NUMBER_OR_ZERO; cfg->ratelimit = atoi(val); infra_dp_ratelimit=cfg->ratelimit; @@ -481,9 +485,11 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_POW2("ratelimit-slabs:", ratelimit_slabs) else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor) else S_YNO("qname-minimisation:", qname_minimisation) + else if(strcmp(opt, "define-tag:") ==0) { + return config_add_tag(cfg, val); /* val_sig_skew_min and max are copied into val_env during init, * so this does not update val_env with set_option */ - else if(strcmp(opt, "val-sig-skew-min:") == 0) + } else if(strcmp(opt, "val-sig-skew-min:") == 0) { IS_NUMBER_OR_ZERO; cfg->val_sig_skew_min = (int32_t)atoi(val); } else if(strcmp(opt, "val-sig-skew-max:") == 0) { IS_NUMBER_OR_ZERO; cfg->val_sig_skew_max = (int32_t)atoi(val); } @@ -504,7 +510,8 @@ int config_set_option(struct config_file* cfg, const char* opt, * stub-zone, name, stub-addr, stub-host, stub-prime * forward-first, stub-first, * forward-zone, name, forward-addr, forward-host, - * ratelimit-for-domain, ratelimit-below-domain */ + * ratelimit-for-domain, ratelimit-below-domain, + * local-zone-tag */ return 0; } return 1; @@ -628,9 +635,23 @@ config_collate_cat(struct config_strlist* list) /** compare and print list option */ #define O_LS2(opt, name, lst) if(strcmp(opt, name)==0) { \ struct config_str2list* p = cfg->lst; \ - for(p = cfg->lst; p; p = p->next) \ - snprintf(buf, len, "%s %s\n", p->str, p->str2); \ + for(p = cfg->lst; p; p = p->next) { \ + snprintf(buf, len, "%s %s", p->str, p->str2); \ func(buf, arg); \ + } \ + } +/** compare and print taglist option */ +#define O_LTG(opt, name, lst) if(strcmp(opt, name)==0) { \ + char* tmpstr = NULL; \ + struct config_strbytelist *p = cfg->lst; \ + for(p = cfg->lst; p; p = p->next) {\ + tmpstr = config_taglist2str(cfg, p->str2, p->str2len); \ + if(tmpstr) {\ + snprintf(buf, len, "%s %s", p->str, tmpstr); \ + func(buf, arg); \ + free(tmpstr); \ + } \ + } \ } int @@ -664,6 +685,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_MEM(opt, "so-sndbuf", so_sndbuf) else O_YNO(opt, "so-reuseport", so_reuseport) else O_YNO(opt, "ip-transparent", ip_transparent) + else O_YNO(opt, "ip-freebind", ip_freebind) else O_MEM(opt, "rrset-cache-size", rrset_cache_size) else O_DEC(opt, "rrset-cache-slabs", rrset_cache_slabs) else O_YNO(opt, "prefetch-key", prefetch_key) @@ -750,6 +772,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones) else O_DEC(opt, "max-udp-size", max_udp_size) else O_STR(opt, "python-script", python_script) + else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check) else O_DEC(opt, "ratelimit", ratelimit) else O_MEM(opt, "ratelimit-size", ratelimit_size) else O_DEC(opt, "ratelimit-slabs", ratelimit_slabs) @@ -759,6 +782,8 @@ config_get_option(struct config_file* cfg, const char* opt, else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min) else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max) else O_YNO(opt, "qname-minimisation", qname_minimisation) + else O_IFC(opt, "define-tag", num_tags, tagname) + else O_LTG(opt, "local-zone-tag", local_zone_tags) /* not here: * outgoing-permit, outgoing-avoid - have list of ports * local-zone - zones and nodefault variables @@ -931,6 +956,33 @@ config_delstubs(struct config_stub* p) } } +/** delete string array */ +static void +config_del_strarray(char** array, int num) +{ + int i; + if(!array) + return; + for(i=0; i<num; i++) { + free(array[i]); + } + free(array); +} + +/** delete stringbytelist */ +static void +config_del_strbytelist(struct config_strbytelist* p) +{ + struct config_strbytelist* np; + while(p) { + np = p->next; + free(p->str); + free(p->str2); + free(p); + p = np; + } +} + void config_delete(struct config_file* cfg) { @@ -943,18 +995,8 @@ config_delete(struct config_file* cfg) free(cfg->target_fetch_policy); free(cfg->ssl_service_key); free(cfg->ssl_service_pem); - if(cfg->ifs) { - int i; - for(i=0; i<cfg->num_ifs; i++) - free(cfg->ifs[i]); - free(cfg->ifs); - } - if(cfg->out_ifs) { - int i; - for(i=0; i<cfg->num_out_ifs; i++) - free(cfg->out_ifs[i]); - free(cfg->out_ifs); - } + config_del_strarray(cfg->ifs, cfg->num_ifs); + config_del_strarray(cfg->out_ifs, cfg->num_out_ifs); config_delstubs(cfg->stubs); config_delstubs(cfg->forwards); config_delstrlist(cfg->donotqueryaddrs); @@ -978,6 +1020,8 @@ config_delete(struct config_file* cfg) config_deldblstrlist(cfg->local_zones); config_delstrlist(cfg->local_zones_nodefault); config_delstrlist(cfg->local_data); + config_del_strarray(cfg->tagname, cfg->num_tags); + config_del_strbytelist(cfg->local_zone_tags); config_delstrlist(cfg->control_ifs); free(cfg->server_key_file); free(cfg->server_cert_file); @@ -1166,6 +1210,24 @@ cfg_str2list_insert(struct config_str2list** head, char* item, char* i2) return 1; } +int +cfg_strbytelist_insert(struct config_strbytelist** head, char* item, + uint8_t* i2, size_t i2len) +{ + struct config_strbytelist* s; + if(!item || !i2 || !head) + return 0; + s = (struct config_strbytelist*)calloc(1, sizeof(*s)); + if(!s) + return 0; + s->str = item; + s->str2 = i2; + s->str2len = i2len; + s->next = *head; + *head = s; + return 1; +} + time_t cfg_convert_timeval(const char* str) { @@ -1270,6 +1332,122 @@ cfg_parse_memsize(const char* str, size_t* res) return 1; } +int +find_tag_id(struct config_file* cfg, const char* tag) +{ + int i; + for(i=0; i<cfg->num_tags; i++) { + if(strcmp(cfg->tagname[i], tag) == 0) + return i; + } + return -1; +} + +int +config_add_tag(struct config_file* cfg, const char* tag) +{ + char** newarray; + char* newtag; + if(find_tag_id(cfg, tag) != -1) + return 1; /* nothing to do */ + newarray = (char**)malloc(sizeof(char*)*(cfg->num_tags+1)); + if(!newarray) + return 0; + newtag = strdup(tag); + if(!newtag) { + free(newarray); + return 0; + } + if(cfg->tagname) { + memcpy(newarray, cfg->tagname, sizeof(char*)*cfg->num_tags); + free(cfg->tagname); + } + newarray[cfg->num_tags++] = newtag; + cfg->tagname = newarray; + return 1; +} + +/** set a bit in a bit array */ +static void +cfg_set_bit(uint8_t* bitlist, size_t len, int id) +{ + int pos = id/8; + log_assert((size_t)pos < len); + bitlist[pos] |= 1<<(id%8); +} + +uint8_t* config_parse_taglist(struct config_file* cfg, char* str, + size_t* listlen) +{ + uint8_t* taglist = NULL; + size_t len = 0; + char* p, *s; + + /* allocate */ + if(cfg->num_tags == 0) { + log_err("parse taglist, but no tags defined"); + return 0; + } + len = (size_t)(cfg->num_tags+7)/8; + taglist = calloc(1, len); + if(!taglist) { + log_err("out of memory"); + return 0; + } + + /* parse */ + s = str; + while((p=strsep(&s, " \t\n")) != NULL) { + if(*p) { + int id = find_tag_id(cfg, p); + /* set this bit in the bitlist */ + if(id == -1) { + log_err("unknown tag: %s", p); + free(taglist); + return 0; + } + cfg_set_bit(taglist, len, id); + } + } + + *listlen = len; + return taglist; +} + +char* config_taglist2str(struct config_file* cfg, uint8_t* taglist, + size_t taglen) +{ + char buf[10240]; + size_t i, j, len = 0; + buf[0] = 0; + for(i=0; i<taglen; i++) { + if(taglist[i] == 0) + continue; + for(j=0; j<8; j++) { + if((taglist[i] & (1<<j)) != 0) { + size_t id = i*8 + j; + snprintf(buf+len, sizeof(buf)-len, "%s%s", + (len==0?"":" "), cfg->tagname[id]); + len += strlen(buf+len); + } + } + } + return strdup(buf); +} + +int taglist_intersect(uint8_t* list1, size_t list1len, uint8_t* list2, + size_t list2len) +{ + size_t i; + if(!list1 || !list2) + return 0; + for(i=0; i<list1len && i<list2len; i++) { + if((list1[i] & list2[i]) != 0) + return 1; + } + return 0; +} + void config_apply(struct config_file* config) { |
