diff options
Diffstat (limited to 'contrib/unbound/util')
-rw-r--r-- | contrib/unbound/util/alloc.c | 19 | ||||
-rw-r--r-- | contrib/unbound/util/alloc.h | 4 | ||||
-rw-r--r-- | contrib/unbound/util/config_file.c | 62 | ||||
-rw-r--r-- | contrib/unbound/util/config_file.h | 25 | ||||
-rw-r--r-- | contrib/unbound/util/configlexer.lex | 15 | ||||
-rw-r--r-- | contrib/unbound/util/configparser.y | 126 | ||||
-rw-r--r-- | contrib/unbound/util/data/dname.c | 2 | ||||
-rw-r--r-- | contrib/unbound/util/data/msgencode.c | 4 | ||||
-rw-r--r-- | contrib/unbound/util/data/msgparse.c | 8 | ||||
-rw-r--r-- | contrib/unbound/util/data/msgparse.h | 6 | ||||
-rw-r--r-- | contrib/unbound/util/data/msgreply.c | 46 | ||||
-rw-r--r-- | contrib/unbound/util/data/msgreply.h | 3 | ||||
-rw-r--r-- | contrib/unbound/util/data/packed_rrset.c | 6 | ||||
-rw-r--r-- | contrib/unbound/util/data/packed_rrset.h | 6 | ||||
-rw-r--r-- | contrib/unbound/util/fptr_wlist.c | 4 | ||||
-rw-r--r-- | contrib/unbound/util/iana_ports.inc | 17 | ||||
-rw-r--r-- | contrib/unbound/util/log.c | 10 | ||||
-rw-r--r-- | contrib/unbound/util/log.h | 9 | ||||
-rw-r--r-- | contrib/unbound/util/net_help.c | 33 | ||||
-rw-r--r-- | contrib/unbound/util/netevent.c | 22 | ||||
-rw-r--r-- | contrib/unbound/util/netevent.h | 2 |
21 files changed, 377 insertions, 52 deletions
diff --git a/contrib/unbound/util/alloc.c b/contrib/unbound/util/alloc.c index 4b81beb..05d2fa3 100644 --- a/contrib/unbound/util/alloc.c +++ b/contrib/unbound/util/alloc.c @@ -364,11 +364,18 @@ void *unbound_stat_malloc(size_t size) #ifdef calloc #undef calloc #endif +#ifndef INT_MAX +#define INT_MAX (((int)-1)>>1) +#endif /** calloc with stats */ void *unbound_stat_calloc(size_t nmemb, size_t size) { - size_t s = (nmemb*size==0)?(size_t)1:nmemb*size; - void* res = calloc(1, s+16); + size_t s; + void* res; + if(nmemb != 0 && INT_MAX/nmemb < size) + return NULL; /* integer overflow check */ + s = (nmemb*size==0)?(size_t)1:nmemb*size; + res = calloc(1, s+16); if(!res) return NULL; log_info("stat %p=calloc(%u, %u)", res+16, (unsigned)nmemb, (unsigned)size); unbound_mem_alloc += s; @@ -503,8 +510,12 @@ void *unbound_stat_malloc_lite(size_t size, const char* file, int line, void *unbound_stat_calloc_lite(size_t nmemb, size_t size, const char* file, int line, const char* func) { - size_t req = nmemb * size; - void* res = malloc(req+lite_pad*2+sizeof(size_t)); + size_t req; + void* res; + if(nmemb != 0 && INT_MAX/nmemb < size) + return NULL; /* integer overflow check */ + req = nmemb * size; + res = malloc(req+lite_pad*2+sizeof(size_t)); if(!res) return NULL; memmove(res, lite_pre, lite_pad); memmove(res+lite_pad, &req, sizeof(size_t)); diff --git a/contrib/unbound/util/alloc.h b/contrib/unbound/util/alloc.h index ffd605c..43fc30f 100644 --- a/contrib/unbound/util/alloc.h +++ b/contrib/unbound/util/alloc.h @@ -177,8 +177,8 @@ void alloc_set_id_cleanup(struct alloc_cache* alloc, void (*cleanup)(void*), void* arg); #ifdef UNBOUND_ALLOC_LITE -# include <ldns/ldns.h> -# include <ldns/packet.h> +# include <sldns/ldns.h> +# include <sldns/packet.h> # ifdef HAVE_OPENSSL_SSL_H # include <openssl/ssl.h> # endif diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c index cdb2b33..062d12d 100644 --- a/contrib/unbound/util/config_file.c +++ b/contrib/unbound/util/config_file.c @@ -56,8 +56,9 @@ #include "util/fptr_wlist.h" #include "util/data/dname.h" #include "util/rtt.h" -#include "ldns/wire2str.h" -#include "ldns/parseutil.h" +#include "services/cache/infra.h" +#include "sldns/wire2str.h" +#include "sldns/parseutil.h" #ifdef HAVE_GLOB_H # include <glob.h> #endif @@ -69,6 +70,8 @@ uid_t cfg_uid = (uid_t)-1; /** from cfg username, after daemonise setup performed */ gid_t cfg_gid = (gid_t)-1; +/** for debug allow small timeout values for fast rollovers */ +int autr_permit_small_holddown = 0; /** global config during parsing */ struct config_parser_state* cfg_parser = 0; @@ -131,6 +134,7 @@ config_create(void) cfg->bogus_ttl = 60; cfg->min_ttl = 0; cfg->max_ttl = 3600 * 24; + cfg->max_negative_ttl = 3600; cfg->prefetch = 0; cfg->prefetch_key = 0; cfg->infra_cache_slabs = 4; @@ -156,6 +160,7 @@ config_create(void) cfg->so_rcvbuf = 0; cfg->so_sndbuf = 0; cfg->so_reuseport = 0; + cfg->ip_transparent = 0; cfg->num_ifs = 0; cfg->ifs = NULL; cfg->num_out_ifs = 0; @@ -169,7 +174,9 @@ config_create(void) cfg->harden_dnssec_stripped = 1; cfg->harden_below_nxdomain = 0; cfg->harden_referral_path = 0; + cfg->harden_algo_downgrade = 0; cfg->use_caps_bits_for_id = 0; + cfg->caps_whitelist = NULL; cfg->private_address = NULL; cfg->private_domain = NULL; cfg->unwanted_threshold = 0; @@ -195,6 +202,7 @@ config_create(void) cfg->add_holddown = 30*24*3600; cfg->del_holddown = 30*24*3600; cfg->keep_missing = 366*24*3600; /* one year plus a little leeway */ + cfg->permit_small_holddown = 0; cfg->key_cache_size = 4 * 1024 * 1024; cfg->key_cache_slabs = 4; cfg->neg_cache_size = 1 * 1024 * 1024; @@ -226,6 +234,12 @@ config_create(void) if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH))) goto error_exit; #endif + cfg->ratelimit = 0; + cfg->ratelimit_slabs = 4; + cfg->ratelimit_size = 4*1024*1024; + cfg->ratelimit_for_domain = NULL; + cfg->ratelimit_below_domain = NULL; + cfg->ratelimit_factor = 10; return cfg; error_exit: config_delete(cfg); @@ -372,12 +386,15 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_MEMSIZE("so-rcvbuf:", so_rcvbuf) else S_MEMSIZE("so-sndbuf:", so_sndbuf) else S_YNO("so-reuseport:", so_reuseport) + else S_YNO("ip-transparent:", ip_transparent) else S_MEMSIZE("rrset-cache-size:", rrset_cache_size) else S_POW2("rrset-cache-slabs:", rrset_cache_slabs) else S_YNO("prefetch:", prefetch) else S_YNO("prefetch-key:", prefetch_key) else if(strcmp(opt, "cache-max-ttl:") == 0) { IS_NUMBER_OR_ZERO; cfg->max_ttl = atoi(val); MAX_TTL=(time_t)cfg->max_ttl;} + else if(strcmp(opt, "cache-max-negative-ttl:") == 0) + { IS_NUMBER_OR_ZERO; cfg->max_negative_ttl = atoi(val); MAX_NEG_TTL=(time_t)cfg->max_negative_ttl;} else if(strcmp(opt, "cache-min-ttl:") == 0) { IS_NUMBER_OR_ZERO; cfg->min_ttl = atoi(val); MIN_TTL=(time_t)cfg->min_ttl;} else if(strcmp(opt, "infra-cache-min-rtt:") == 0) { @@ -404,7 +421,9 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_YNO("harden-dnssec-stripped:", harden_dnssec_stripped) else S_YNO("harden-below-nxdomain:", harden_below_nxdomain) else S_YNO("harden-referral-path:", harden_referral_path) + else S_YNO("harden-algo-downgrade:", harden_algo_downgrade) else S_YNO("use-caps-for-id", use_caps_bits_for_id) + else S_STRLIST("caps-whitelist:", caps_whitelist) else S_SIZET_OR_ZERO("unwanted-reply-threshold:", unwanted_threshold) else S_STRLIST("private-address:", private_address) else S_STRLIST("private-domain:", private_domain) @@ -428,6 +447,9 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_UNSIGNED_OR_ZERO("add-holddown:", add_holddown) else S_UNSIGNED_OR_ZERO("del-holddown:", del_holddown) else S_UNSIGNED_OR_ZERO("keep-missing:", keep_missing) + else if(strcmp(opt, "permit-small-holddown:") == 0) + { IS_YES_OR_NO; cfg->permit_small_holddown = (strcmp(val, "yes") == 0); + autr_permit_small_holddown = cfg->permit_small_holddown; } else S_MEMSIZE("key-cache-size:", key_cache_size) else S_POW2("key-cache-slabs:", key_cache_slabs) else S_MEMSIZE("neg-cache-size:", neg_cache_size) @@ -444,6 +466,13 @@ 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 if(strcmp(opt, "ratelimit:") == 0) { + IS_NUMBER_OR_ZERO; cfg->ratelimit = atoi(val); + infra_dp_ratelimit=cfg->ratelimit; + } + else S_MEMSIZE("ratelimit-size:", ratelimit_size) + else S_POW2("ratelimit-slabs:", ratelimit_slabs) + else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor) /* 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) @@ -452,7 +481,8 @@ int config_set_option(struct config_file* cfg, const char* opt, { IS_NUMBER_OR_ZERO; cfg->val_sig_skew_max = (int32_t)atoi(val); } else if (strcmp(opt, "outgoing-interface:") == 0) { char* d = strdup(val); - char** oi = (char**)malloc((cfg->num_out_ifs+1)*sizeof(char*)); + char** oi = + (char**)reallocarray(NULL, (size_t)cfg->num_out_ifs+1, sizeof(char*)); if(!d || !oi) { free(d); free(oi); return -1; } if(cfg->out_ifs && cfg->num_out_ifs) { memmove(oi, cfg->out_ifs, cfg->num_out_ifs*sizeof(char*)); @@ -465,7 +495,8 @@ int config_set_option(struct config_file* cfg, const char* opt, * interface, outgoing-interface, access-control, * stub-zone, name, stub-addr, stub-host, stub-prime * forward-first, stub-first, - * forward-zone, name, forward-addr, forward-host */ + * forward-zone, name, forward-addr, forward-host, + * ratelimit-for-domain, ratelimit-below-domain */ return 0; } return 1; @@ -577,8 +608,8 @@ config_collate_cat(struct config_strlist* list) #define O_MEM(opt, str, var) if(strcmp(opt, str)==0) { \ if(cfg->var > 1024*1024*1024) { \ size_t f=cfg->var/(size_t)1000000, b=cfg->var%(size_t)1000000; \ - snprintf(buf, len, "%u%6.6u\n", (unsigned)f, (unsigned)b); \ - } else snprintf(buf, len, "%u\n", (unsigned)cfg->var); \ + snprintf(buf, len, "%u%6.6u", (unsigned)f, (unsigned)b); \ + } else snprintf(buf, len, "%u", (unsigned)cfg->var); \ func(buf, arg);} /** compare and print list option */ #define O_LST(opt, name, lst) if(strcmp(opt, name)==0) { \ @@ -624,11 +655,13 @@ config_get_option(struct config_file* cfg, const char* opt, else O_MEM(opt, "so-rcvbuf", so_rcvbuf) 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_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) else O_YNO(opt, "prefetch", prefetch) else O_DEC(opt, "cache-max-ttl", max_ttl) + else O_DEC(opt, "cache-max-negative-ttl", max_negative_ttl) else O_DEC(opt, "cache-min-ttl", min_ttl) else O_DEC(opt, "infra-host-ttl", host_ttl) else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs) @@ -662,7 +695,9 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "harden-dnssec-stripped", harden_dnssec_stripped) else O_YNO(opt, "harden-below-nxdomain", harden_below_nxdomain) else O_YNO(opt, "harden-referral-path", harden_referral_path) + else O_YNO(opt, "harden-algo-downgrade", harden_algo_downgrade) else O_YNO(opt, "use-caps-for-id", use_caps_bits_for_id) + else O_LST(opt, "caps-whitelist", caps_whitelist) else O_DEC(opt, "unwanted-reply-threshold", unwanted_threshold) else O_YNO(opt, "do-not-query-localhost", donotquery_localhost) else O_STR(opt, "module-config", module_conf) @@ -676,6 +711,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_UNS(opt, "add-holddown", add_holddown) else O_UNS(opt, "del-holddown", del_holddown) else O_UNS(opt, "keep-missing", keep_missing) + else O_YNO(opt, "permit-small-holddown", permit_small_holddown) else O_MEM(opt, "key-cache-size", key_cache_size) else O_DEC(opt, "key-cache-slabs", key_cache_slabs) else O_MEM(opt, "neg-cache-size", neg_cache_size) @@ -703,6 +739,12 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones) else O_DEC(opt, "max-udp-size", max_udp_size) else O_STR(opt, "python-script", python_script) + else O_DEC(opt, "ratelimit", ratelimit) + else O_MEM(opt, "ratelimit-size", ratelimit_size) + else O_DEC(opt, "ratelimit-slabs", ratelimit_slabs) + else O_LS2(opt, "ratelimit-for-domain", ratelimit_for_domain) + else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain) + else O_DEC(opt, "ratelimit-factor", ratelimit_factor) else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min) else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max) /* not here: @@ -890,6 +932,7 @@ config_delete(struct config_file* cfg) free(cfg->version); free(cfg->module_conf); free(cfg->outgoing_avail_ports); + config_delstrlist(cfg->caps_whitelist); config_delstrlist(cfg->private_address); config_delstrlist(cfg->private_domain); config_delstrlist(cfg->auto_trust_anchor_file_list); @@ -909,9 +952,12 @@ config_delete(struct config_file* cfg) free(cfg->server_cert_file); free(cfg->control_key_file); free(cfg->control_cert_file); + free(cfg->dns64_prefix); free(cfg->dnstap_socket_path); free(cfg->dnstap_identity); free(cfg->dnstap_version); + config_deldblstrlist(cfg->ratelimit_for_domain); + config_deldblstrlist(cfg->ratelimit_below_domain); free(cfg); } @@ -998,7 +1044,7 @@ int cfg_condense_ports(struct config_file* cfg, int** avail) *avail = NULL; if(num == 0) return 0; - *avail = (int*)malloc(sizeof(int)*num); + *avail = (int*)reallocarray(NULL, (size_t)num, sizeof(int)); if(!*avail) return 0; for(i=0; i<65536; i++) { @@ -1198,11 +1244,13 @@ config_apply(struct config_file* config) { MAX_TTL = (time_t)config->max_ttl; MIN_TTL = (time_t)config->min_ttl; + MAX_NEG_TTL = (time_t)config->max_negative_ttl; RTT_MIN_TIMEOUT = config->infra_cache_min_rtt; EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size; MINIMAL_RESPONSES = config->minimal_responses; RRSET_ROUNDROBIN = config->rrset_roundrobin; log_set_time_asc(config->log_time_ascii); + autr_permit_small_holddown = config->permit_small_holddown; } void config_lookup_uid(struct config_file* cfg) diff --git a/contrib/unbound/util/config_file.h b/contrib/unbound/util/config_file.h index ca512d7..99b15e0 100644 --- a/contrib/unbound/util/config_file.h +++ b/contrib/unbound/util/config_file.h @@ -136,6 +136,8 @@ struct config_file { size_t so_sndbuf; /** SO_REUSEPORT requested on port 53 sockets */ int so_reuseport; + /** IP_TRANSPARENT socket option requested on port 53 sockets */ + int ip_transparent; /** number of interfaces to open. If 0 default all interfaces. */ int num_ifs; @@ -173,8 +175,12 @@ struct config_file { int harden_below_nxdomain; /** harden the referral path, query for NS,A,AAAA and validate */ int harden_referral_path; + /** harden against algorithm downgrade */ + int harden_algo_downgrade; /** use 0x20 bits in query as random ID bits */ int use_caps_bits_for_id; + /** 0x20 whitelist, domains that do not use capsforid */ + struct config_strlist* caps_whitelist; /** strip away these private addrs from answers, no DNS Rebinding */ struct config_strlist* private_address; /** allow domain (and subdomains) to use private address space */ @@ -185,6 +191,8 @@ struct config_file { int max_ttl; /** the number of seconds minimum TTL used for RRsets and messages */ int min_ttl; + /** the number of seconds maximal negative TTL for SOA in auth */ + int max_negative_ttl; /** if prefetching of messages should be performed. */ int prefetch; /** if prefetching of DNSKEYs should be performed. */ @@ -261,6 +269,8 @@ struct config_file { unsigned int del_holddown; /** autotrust keep_missing time, in seconds. 0 is forever. */ unsigned int keep_missing; + /** permit small holddown values, allowing 5011 rollover very fast */ + int permit_small_holddown; /** size of the key cache */ size_t key_cache_size; @@ -341,12 +351,27 @@ struct config_file { int dnstap_log_forwarder_query_messages; /** true to log dnstap FORWARDER_RESPONSE message events */ int dnstap_log_forwarder_response_messages; + + /** ratelimit 0 is off, otherwise qps (unless overridden) */ + int ratelimit; + /** number of slabs for ratelimit cache */ + size_t ratelimit_slabs; + /** memory size in bytes for ratelimit cache */ + size_t ratelimit_size; + /** ratelimits for domain (exact match) */ + struct config_str2list* ratelimit_for_domain; + /** ratelimits below domain */ + struct config_str2list* ratelimit_below_domain; + /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */ + int ratelimit_factor; }; /** from cfg username, after daemonise setup performed */ extern uid_t cfg_uid; /** from cfg username, after daemonise setup performed */ extern gid_t cfg_gid; +/** debug and enable small timeouts */ +extern int autr_permit_small_holddown; /** * Stub config options diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex index 0e22946..1aea22e 100644 --- a/contrib/unbound/util/configlexer.lex +++ b/contrib/unbound/util/configlexer.lex @@ -128,6 +128,10 @@ static void config_start_include_glob(const char* filename) #endif ; memset(&g, 0, sizeof(g)); + if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot, + strlen(cfg_parser->chroot)) == 0) { + filename += strlen(cfg_parser->chroot); + } r = glob(filename, flags, NULL, &g); if(r) { /* some error */ @@ -228,6 +232,7 @@ interface-automatic{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC) } so-rcvbuf{COLON} { YDVAR(1, VAR_SO_RCVBUF) } so-sndbuf{COLON} { YDVAR(1, VAR_SO_SNDBUF) } so-reuseport{COLON} { YDVAR(1, VAR_SO_REUSEPORT) } +ip-transparent{COLON} { YDVAR(1, VAR_IP_TRANSPARENT) } chroot{COLON} { YDVAR(1, VAR_CHROOT) } username{COLON} { YDVAR(1, VAR_USERNAME) } directory{COLON} { YDVAR(1, VAR_DIRECTORY) } @@ -241,6 +246,7 @@ msg-cache-slabs{COLON} { YDVAR(1, VAR_MSG_CACHE_SLABS) } rrset-cache-size{COLON} { YDVAR(1, VAR_RRSET_CACHE_SIZE) } rrset-cache-slabs{COLON} { YDVAR(1, VAR_RRSET_CACHE_SLABS) } cache-max-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_TTL) } +cache-max-negative-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_NEGATIVE_TTL) } cache-min-ttl{COLON} { YDVAR(1, VAR_CACHE_MIN_TTL) } infra-host-ttl{COLON} { YDVAR(1, VAR_INFRA_HOST_TTL) } infra-lame-ttl{COLON} { YDVAR(1, VAR_INFRA_LAME_TTL) } @@ -258,7 +264,9 @@ harden-glue{COLON} { YDVAR(1, VAR_HARDEN_GLUE) } harden-dnssec-stripped{COLON} { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) } harden-below-nxdomain{COLON} { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) } harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } +harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) } use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) } +caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) } unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } @@ -304,6 +312,7 @@ val-nsec3-keysize-iterations{COLON} { add-holddown{COLON} { YDVAR(1, VAR_ADD_HOLDDOWN) } del-holddown{COLON} { YDVAR(1, VAR_DEL_HOLDDOWN) } keep-missing{COLON} { YDVAR(1, VAR_KEEP_MISSING) } +permit-small-holddown{COLON} { YDVAR(1, VAR_PERMIT_SMALL_HOLDDOWN) } use-syslog{COLON} { YDVAR(1, VAR_USE_SYSLOG) } log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) } log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) } @@ -350,6 +359,12 @@ dnstap-log-forwarder-query-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } dnstap-log-forwarder-response-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } +ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) } +ratelimit-slabs{COLON} { YDVAR(1, VAR_RATELIMIT_SLABS) } +ratelimit-size{COLON} { YDVAR(1, VAR_RATELIMIT_SIZE) } +ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } +ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } +ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) } <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } /* Quoted strings. Strip leading and ending quotes */ diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y index 396ea3c..d6db3c8 100644 --- a/contrib/unbound/util/configparser.y +++ b/contrib/unbound/util/configparser.y @@ -118,6 +118,10 @@ extern struct config_parser_state* cfg_parser; %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES +%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT +%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE +%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR +%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -177,7 +181,12 @@ content_server: server_num_threads | server_verbosity | server_port | server_minimal_responses | server_rrset_roundrobin | server_max_udp_size | server_so_reuseport | server_delay_close | server_unblock_lan_zones | server_dns64_prefix | server_dns64_synthall | - server_infra_cache_min_rtt + server_infra_cache_min_rtt | server_harden_algo_downgrade | + server_ip_transparent | server_ratelimit | server_ratelimit_slabs | + server_ratelimit_size | server_ratelimit_for_domain | + server_ratelimit_below_domain | server_ratelimit_factor | + server_caps_whitelist | server_cache_max_negative_ttl | + server_permit_small_holddown ; stubstart: VAR_STUB_ZONE { @@ -620,6 +629,16 @@ server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG free($2); } ; +server_ip_transparent: VAR_IP_TRANSPARENT STRING_ARG + { + OUTYY(("P(server_ip_transparent:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->ip_transparent = + (strcmp($2, "yes")==0); + free($2); + } + ; server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG { OUTYY(("P(server_edns_buffer_size:%s)\n", $2)); @@ -846,6 +865,16 @@ server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG free($2); } ; +server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG + { + OUTYY(("P(server_harden_algo_downgrade:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->harden_algo_downgrade = + (strcmp($2, "yes")==0); + free($2); + } + ; server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG { OUTYY(("P(server_use_caps_for_id:%s)\n", $2)); @@ -856,6 +885,13 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG free($2); } ; +server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG + { + OUTYY(("P(server_caps_whitelist:%s)\n", $2)); + if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2)) + yyerror("out of memory"); + } + ; server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG { OUTYY(("P(server_private_address:%s)\n", $2)); @@ -991,6 +1027,15 @@ server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG free($2); } ; +server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG + { + OUTYY(("P(server_cache_max_negative_ttl:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->max_negative_ttl = atoi($2); + free($2); + } + ; server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG { OUTYY(("P(server_cache_min_ttl:%s)\n", $2)); @@ -1081,6 +1126,15 @@ server_keep_missing: VAR_KEEP_MISSING STRING_ARG free($2); } ; +server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG + { + OUTYY(("P(server_permit_small_holddown:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->permit_small_holddown = + (strcmp($2, "yes")==0); + free($2); + } server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG { OUTYY(("P(server_key_cache_size:%s)\n", $2)); @@ -1117,10 +1171,11 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 && strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0 && strcmp($3, "typetransparent")!=0 && - strcmp($3, "inform")!=0) + strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " - "typetransparent, inform or nodefault"); + "typetransparent, inform, inform_deny " + "or nodefault"); else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, $2)) @@ -1198,6 +1253,71 @@ server_dns64_synthall: VAR_DNS64_SYNTHALL STRING_ARG free($2); } ; +server_ratelimit: VAR_RATELIMIT STRING_ARG + { + OUTYY(("P(server_ratelimit:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->ratelimit = atoi($2); + free($2); + } + ; +server_ratelimit_size: VAR_RATELIMIT_SIZE STRING_ARG + { + OUTYY(("P(server_ratelimit_size:%s)\n", $2)); + if(!cfg_parse_memsize($2, &cfg_parser->cfg->ratelimit_size)) + yyerror("memory size expected"); + free($2); + } + ; +server_ratelimit_slabs: VAR_RATELIMIT_SLABS STRING_ARG + { + OUTYY(("P(server_ratelimit_slabs:%s)\n", $2)); + if(atoi($2) == 0) + yyerror("number expected"); + else { + cfg_parser->cfg->ratelimit_slabs = atoi($2); + if(!is_pow2(cfg_parser->cfg->ratelimit_slabs)) + yyerror("must be a power of 2"); + } + free($2); + } + ; +server_ratelimit_for_domain: VAR_RATELIMIT_FOR_DOMAIN STRING_ARG STRING_ARG + { + OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", $2, $3)); + if(atoi($3) == 0 && strcmp($3, "0") != 0) { + yyerror("number expected"); + } else { + if(!cfg_str2list_insert(&cfg_parser->cfg-> + ratelimit_for_domain, $2, $3)) + fatal_exit("out of memory adding " + "ratelimit-for-domain"); + } + } + ; +server_ratelimit_below_domain: VAR_RATELIMIT_BELOW_DOMAIN STRING_ARG STRING_ARG + { + OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", $2, $3)); + if(atoi($3) == 0 && strcmp($3, "0") != 0) { + yyerror("number expected"); + } else { + if(!cfg_str2list_insert(&cfg_parser->cfg-> + ratelimit_below_domain, $2, $3)) + fatal_exit("out of memory adding " + "ratelimit-below-domain"); + } + } + ; +server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG + { + OUTYY(("P(server_ratelimit_factor:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->ratelimit_factor = atoi($2); + free($2); + } + ; stub_name: VAR_NAME STRING_ARG { OUTYY(("P(name:%s)\n", $2)); diff --git a/contrib/unbound/util/data/dname.c b/contrib/unbound/util/data/dname.c index d43bbf6..79bf52a 100644 --- a/contrib/unbound/util/data/dname.c +++ b/contrib/unbound/util/data/dname.c @@ -45,7 +45,7 @@ #include "util/data/msgparse.h" #include "util/log.h" #include "util/storage/lookup3.h" -#include "ldns/sbuffer.h" +#include "sldns/sbuffer.h" /* determine length of a dname in buffer, no compression pointers allowed */ size_t diff --git a/contrib/unbound/util/data/msgencode.c b/contrib/unbound/util/data/msgencode.c index 26b5dea..43464e9 100644 --- a/contrib/unbound/util/data/msgencode.c +++ b/contrib/unbound/util/data/msgencode.c @@ -47,7 +47,7 @@ #include "util/log.h" #include "util/regional.h" #include "util/net_help.h" -#include "ldns/sbuffer.h" +#include "sldns/sbuffer.h" /** return code that means the function ran out of memory. negative so it does * not conflict with DNS rcodes. */ @@ -283,7 +283,7 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, size_t owner_pos, uint16_t* owner_ptr, int owner_labs) { struct compress_tree_node* p; - struct compress_tree_node** insertpt; + struct compress_tree_node** insertpt = NULL; if(!*owner_ptr) { /* compress first time dname */ if((p = compress_tree_lookup(tree, key->rk.dname, diff --git a/contrib/unbound/util/data/msgparse.c b/contrib/unbound/util/data/msgparse.c index abe778a..108c9da 100644 --- a/contrib/unbound/util/data/msgparse.c +++ b/contrib/unbound/util/data/msgparse.c @@ -42,10 +42,10 @@ #include "util/data/packed_rrset.h" #include "util/storage/lookup3.h" #include "util/regional.h" -#include "ldns/rrdef.h" -#include "ldns/sbuffer.h" -#include "ldns/parseutil.h" -#include "ldns/wire2str.h" +#include "sldns/rrdef.h" +#include "sldns/sbuffer.h" +#include "sldns/parseutil.h" +#include "sldns/wire2str.h" /** smart comparison of (compressed, valid) dnames from packet */ static int diff --git a/contrib/unbound/util/data/msgparse.h b/contrib/unbound/util/data/msgparse.h index 221a45a..44497c8 100644 --- a/contrib/unbound/util/data/msgparse.h +++ b/contrib/unbound/util/data/msgparse.h @@ -63,8 +63,8 @@ #ifndef UTIL_DATA_MSGPARSE_H #define UTIL_DATA_MSGPARSE_H #include "util/storage/lruhash.h" -#include "ldns/pkthdr.h" -#include "ldns/rrdef.h" +#include "sldns/pkthdr.h" +#include "sldns/rrdef.h" struct sldns_buffer; struct rrset_parse; struct rr_parse; @@ -76,6 +76,8 @@ struct regional; extern time_t MAX_TTL; /** Minimum TTL that is allowed. */ extern time_t MIN_TTL; +/** Maximum Negative TTL that is allowed */ +extern time_t MAX_NEG_TTL; /** Negative cache time (for entries without any RRs.) */ #define NORR_TTL 5 /* seconds */ diff --git a/contrib/unbound/util/data/msgreply.c b/contrib/unbound/util/data/msgreply.c index 68bcfd0..06593ff 100644 --- a/contrib/unbound/util/data/msgreply.c +++ b/contrib/unbound/util/data/msgreply.c @@ -50,13 +50,15 @@ #include "util/regional.h" #include "util/data/msgparse.h" #include "util/data/msgencode.h" -#include "ldns/sbuffer.h" -#include "ldns/wire2str.h" +#include "sldns/sbuffer.h" +#include "sldns/wire2str.h" /** MAX TTL default for messages and rrsets */ time_t MAX_TTL = 3600 * 24 * 10; /* ten days */ /** MIN TTL default for messages and rrsets */ time_t MIN_TTL = 0; +/** MAX Negative TTL, for SOA records in authority section */ +time_t MAX_NEG_TTL = 3600; /* one hour */ /** allocate qinfo, return 0 on error */ static int @@ -87,6 +89,7 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd, /* rrset_count-1 because the first ref is part of the struct. */ size_t s = sizeof(struct reply_info) - sizeof(struct rrset_ref) + sizeof(struct ub_packed_rrset_key*) * total; + if(total >= RR_COUNT_MAX) return NULL; /* sanity check on numRRS*/ if(region) rep = (struct reply_info*)regional_alloc(region, s); else rep = (struct reply_info*)malloc(s + @@ -152,10 +155,23 @@ repinfo_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc, return 1; } +/** find the minimumttl in the rdata of SOA record */ +static time_t +soa_find_minttl(struct rr_parse* rr) +{ + uint16_t rlen = sldns_read_uint16(rr->ttl_data+4); + if(rlen < 20) + return 0; /* rdata too small for SOA (dname, dname, 5*32bit) */ + /* minimum TTL is the last 32bit value in the rdata of the record */ + /* at position ttl_data + 4(ttl) + 2(rdatalen) + rdatalen - 4(timeval)*/ + return (time_t)sldns_read_uint32(rr->ttl_data+6+rlen-4); +} + /** do the rdata copy */ static int rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, - struct rr_parse* rr, time_t* rr_ttl, uint16_t type) + struct rr_parse* rr, time_t* rr_ttl, uint16_t type, + sldns_pkt_section section) { uint16_t pkt_len; const sldns_rr_descriptor* desc; @@ -164,6 +180,14 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, /* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */ if(*rr_ttl & 0x80000000U) *rr_ttl = 0; + if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) { + /* negative response. see if TTL of SOA record larger than the + * minimum-ttl in the rdata of the SOA record */ + if(*rr_ttl > soa_find_minttl(rr)) + *rr_ttl = soa_find_minttl(rr); + if(*rr_ttl > MAX_NEG_TTL) + *rr_ttl = MAX_NEG_TTL; + } if(*rr_ttl < MIN_TTL) *rr_ttl = MIN_TTL; if(*rr_ttl < data->ttl) @@ -253,7 +277,7 @@ parse_rr_copy(sldns_buffer* pkt, struct rrset_parse* pset, data->rr_data[i] = nextrdata; nextrdata += rr->size; if(!rdata_copy(pkt, data, data->rr_data[i], rr, - &data->rr_ttl[i], pset->type)) + &data->rr_ttl[i], pset->type, pset->section)) return 0; rr = rr->next; } @@ -264,7 +288,7 @@ parse_rr_copy(sldns_buffer* pkt, struct rrset_parse* pset, data->rr_data[i] = nextrdata; nextrdata += rr->size; if(!rdata_copy(pkt, data, data->rr_data[i], rr, - &data->rr_ttl[i], LDNS_RR_TYPE_RRSIG)) + &data->rr_ttl[i], LDNS_RR_TYPE_RRSIG, pset->section)) return 0; rr = rr->next; } @@ -277,7 +301,11 @@ parse_create_rrset(sldns_buffer* pkt, struct rrset_parse* pset, struct packed_rrset_data** data, struct regional* region) { /* allocate */ - size_t s = sizeof(struct packed_rrset_data) + + size_t s; + if(pset->rr_count > RR_COUNT_MAX || pset->rrsig_count > RR_COUNT_MAX || + pset->size > RR_COUNT_MAX) + return 0; /* protect against integer overflow */ + s = sizeof(struct packed_rrset_data) + (pset->rr_count + pset->rrsig_count) * (sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t)) + pset->size; @@ -794,13 +822,13 @@ log_query_info(enum verbosity_value v, const char* str, } int -reply_check_cname_chain(struct reply_info* rep) +reply_check_cname_chain(struct query_info* qinfo, struct reply_info* rep) { /* check only answer section rrs for matching cname chain. * the cache may return changed rdata, but owner names are untouched.*/ size_t i; - uint8_t* sname = rep->rrsets[0]->rk.dname; - size_t snamelen = rep->rrsets[0]->rk.dname_len; + uint8_t* sname = qinfo->qname; + size_t snamelen = qinfo->qname_len; for(i=0; i<rep->an_numrrsets; i++) { uint16_t t = ntohs(rep->rrsets[i]->rk.type); if(t == LDNS_RR_TYPE_DNAME) diff --git a/contrib/unbound/util/data/msgreply.h b/contrib/unbound/util/data/msgreply.h index e8d6d76..7088979 100644 --- a/contrib/unbound/util/data/msgreply.h +++ b/contrib/unbound/util/data/msgreply.h @@ -359,10 +359,11 @@ uint8_t* reply_find_final_cname_target(struct query_info* qinfo, /** * Check if cname chain in cached reply is still valid. + * @param qinfo: query info with query name. * @param rep: reply to check. * @return: true if valid, false if invalid. */ -int reply_check_cname_chain(struct reply_info* rep); +int reply_check_cname_chain(struct query_info* qinfo, struct reply_info* rep); /** * Check security status of all RRs in the message. diff --git a/contrib/unbound/util/data/packed_rrset.c b/contrib/unbound/util/data/packed_rrset.c index 8074685..0a5c9d3 100644 --- a/contrib/unbound/util/data/packed_rrset.c +++ b/contrib/unbound/util/data/packed_rrset.c @@ -47,9 +47,9 @@ #include "util/alloc.h" #include "util/regional.h" #include "util/net_help.h" -#include "ldns/rrdef.h" -#include "ldns/sbuffer.h" -#include "ldns/wire2str.h" +#include "sldns/rrdef.h" +#include "sldns/sbuffer.h" +#include "sldns/wire2str.h" void ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey, diff --git a/contrib/unbound/util/data/packed_rrset.h b/contrib/unbound/util/data/packed_rrset.h index 5d7990a..6039aef 100644 --- a/contrib/unbound/util/data/packed_rrset.h +++ b/contrib/unbound/util/data/packed_rrset.h @@ -58,6 +58,12 @@ typedef uint64_t rrset_id_t; * from the SOA in the answer section from a direct SOA query or ANY query. */ #define PACKED_RRSET_SOA_NEG 0x4 +/** number of rrs and rrsets for integer overflow protection. More than + * this is not really possible (64K packet has much less RRs and RRsets) in + * a message. And this is small enough that also multiplied there is no + * integer overflow. */ +#define RR_COUNT_MAX 0xffffff + /** * The identifying information for an RRset. */ diff --git a/contrib/unbound/util/fptr_wlist.c b/contrib/unbound/util/fptr_wlist.c index 5a77432..1397e9c 100644 --- a/contrib/unbound/util/fptr_wlist.c +++ b/contrib/unbound/util/fptr_wlist.c @@ -210,6 +210,7 @@ fptr_whitelist_hash_sizefunc(lruhash_sizefunc_t fptr) else if(fptr == &ub_rrset_sizefunc) return 1; else if(fptr == &infra_sizefunc) return 1; else if(fptr == &key_entry_sizefunc) return 1; + else if(fptr == &rate_sizefunc) return 1; else if(fptr == &test_slabhash_sizefunc) return 1; return 0; } @@ -221,6 +222,7 @@ fptr_whitelist_hash_compfunc(lruhash_compfunc_t fptr) else if(fptr == &ub_rrset_compare) return 1; else if(fptr == &infra_compfunc) return 1; else if(fptr == &key_entry_compfunc) return 1; + else if(fptr == &rate_compfunc) return 1; else if(fptr == &test_slabhash_compfunc) return 1; return 0; } @@ -232,6 +234,7 @@ fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_t fptr) else if(fptr == &ub_rrset_key_delete) return 1; else if(fptr == &infra_delkeyfunc) return 1; else if(fptr == &key_entry_delkeyfunc) return 1; + else if(fptr == &rate_delkeyfunc) return 1; else if(fptr == &test_slabhash_delkey) return 1; return 0; } @@ -243,6 +246,7 @@ fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_t fptr) else if(fptr == &rrset_data_delete) return 1; else if(fptr == &infra_deldatafunc) return 1; else if(fptr == &key_entry_deldatafunc) return 1; + else if(fptr == &rate_deldatafunc) return 1; else if(fptr == &test_slabhash_deldata) return 1; return 0; } diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc index ce939d5..64edf0b 100644 --- a/contrib/unbound/util/iana_ports.inc +++ b/contrib/unbound/util/iana_ports.inc @@ -1066,7 +1066,6 @@ 1404, 1405, 1406, -1407, 1408, 1409, 1410, @@ -3791,7 +3790,6 @@ 4321, 4322, 4323, -4324, 4325, 4326, 4327, @@ -3842,6 +3840,8 @@ 4404, 4405, 4406, +4412, +4413, 4425, 4426, 4430, @@ -4015,6 +4015,7 @@ 4952, 4969, 4970, +4980, 4986, 4987, 4988, @@ -4359,6 +4360,7 @@ 6072, 6073, 6074, +6080, 6081, 6082, 6083, @@ -4433,6 +4435,7 @@ 6389, 6390, 6417, +6419, 6420, 6421, 6443, @@ -4665,6 +4668,7 @@ 7725, 7726, 7727, +7728, 7734, 7738, 7741, @@ -4779,6 +4783,7 @@ 8301, 8320, 8321, +8322, 8351, 8376, 8377, @@ -4786,6 +4791,7 @@ 8379, 8380, 8383, +8384, 8400, 8401, 8402, @@ -4802,6 +4808,7 @@ 8474, 8500, 8501, +8503, 8554, 8555, 8567, @@ -4853,6 +4860,7 @@ 9000, 9001, 9002, +9006, 9007, 9009, 9020, @@ -5031,6 +5039,7 @@ 10200, 10201, 10252, +10253, 10260, 10288, 10439, @@ -5165,6 +5174,8 @@ 17220, 17221, 17222, +17224, +17225, 17234, 17235, 17500, @@ -5237,6 +5248,7 @@ 22005, 22273, 22305, +22335, 22343, 22347, 22350, @@ -5376,6 +5388,7 @@ 40843, 40853, 41111, +41230, 41794, 41795, 42508, diff --git a/contrib/unbound/util/log.c b/contrib/unbound/util/log.c index f90efa7..3ebd120 100644 --- a/contrib/unbound/util/log.c +++ b/contrib/unbound/util/log.c @@ -40,7 +40,7 @@ #include "config.h" #include "util/log.h" #include "util/locks.h" -#include "ldns/sbuffer.h" +#include "sldns/sbuffer.h" #include <stdarg.h> #ifdef HAVE_TIME_H #include <time.h> @@ -164,6 +164,14 @@ void log_thread_set(int* num) ub_thread_key_set(logkey, num); } +int log_thread_get(void) +{ + unsigned int* tid; + if(!key_created) return 0; + tid = (unsigned int*)ub_thread_key_get(logkey); + return (int)(tid?*tid:0); +} + void log_ident_set(const char* id) { ident = id; diff --git a/contrib/unbound/util/log.h b/contrib/unbound/util/log.h index ea283da..8e85ee6 100644 --- a/contrib/unbound/util/log.h +++ b/contrib/unbound/util/log.h @@ -98,6 +98,15 @@ void log_file(FILE *f); void log_thread_set(int* num); /** + * Get the thread id from logging system. Set after log_init is + * initialised, or log_thread_set for newly created threads. + * This initialisation happens in unbound as a daemon, in daemon + * startup code, when that spawns threads. + * @return thread number, from 0 and up. Before initialised, returns 0. + */ +int log_thread_get(void); + +/** * Set identity to print, default is 'unbound'. * @param id: string to print. Name of executable. */ diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c index e2b7c38..07605b1 100644 --- a/contrib/unbound/util/net_help.c +++ b/contrib/unbound/util/net_help.c @@ -43,8 +43,8 @@ #include "util/data/dname.h" #include "util/module.h" #include "util/regional.h" -#include "ldns/parseutil.h" -#include "ldns/wire2str.h" +#include "sldns/parseutil.h" +#include "sldns/wire2str.h" #include <fcntl.h> #ifdef HAVE_OPENSSL_SSL_H #include <openssl/ssl.h> @@ -629,9 +629,9 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) SSL_CTX_free(ctx); return NULL; } - if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { + if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { log_err("error for cert file: %s", pem); - log_crypto_err("error in SSL_CTX use_certificate_file"); + log_crypto_err("error in SSL_CTX use_certificate_chain_file"); SSL_CTX_free(ctx); return NULL; } @@ -647,6 +647,23 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) SSL_CTX_free(ctx); return NULL; } +#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO + if(!SSL_CTX_set_ecdh_auto(ctx,1)) { + log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); + } +#elif defined(USE_ECDSA) + if(1) { + EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); + if (!ecdh) { + log_crypto_err("could not find p256, not enabling ECDHE"); + } else { + if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) { + log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE"); + } + EC_KEY_free (ecdh); + } + } +#endif if(verifypem && verifypem[0]) { if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { @@ -684,7 +701,7 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem) return NULL; } if(key && key[0]) { - if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { + if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { log_err("error in client certificate %s", pem); log_crypto_err("error in certificate file"); SSL_CTX_free(ctx); @@ -770,7 +787,7 @@ static lock_basic_t *ub_openssl_locks = NULL; static unsigned long ub_crypto_id_cb(void) { - return (unsigned long)ub_thread_self(); + return (unsigned long)log_thread_get(); } static void @@ -789,8 +806,8 @@ int ub_openssl_lock_init(void) { #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) int i; - ub_openssl_locks = (lock_basic_t*)malloc( - sizeof(lock_basic_t)*CRYPTO_num_locks()); + ub_openssl_locks = (lock_basic_t*)reallocarray( + NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t)); if(!ub_openssl_locks) return 0; for(i=0; i<CRYPTO_num_locks(); i++) { diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c index c7ed30e..3bb8948 100644 --- a/contrib/unbound/util/netevent.c +++ b/contrib/unbound/util/netevent.c @@ -43,8 +43,8 @@ #include "util/log.h" #include "util/net_help.h" #include "util/fptr_wlist.h" -#include "ldns/pkthdr.h" -#include "ldns/sbuffer.h" +#include "sldns/pkthdr.h" +#include "sldns/sbuffer.h" #include "dnstap/dnstap.h" #ifdef HAVE_OPENSSL_SSL_H #include <openssl/ssl.h> @@ -498,12 +498,16 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, cmsg = CMSG_FIRSTHDR(&msg); if(r->srctype == 4) { #ifdef IP_PKTINFO + void* cmsg_data; msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); log_assert(msg.msg_controllen <= sizeof(control)); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info, sizeof(struct in_pktinfo)); + /* unset the ifindex to not bypass the routing tables */ + cmsg_data = CMSG_DATA(cmsg); + ((struct in_pktinfo *) cmsg_data)->ipi_ifindex = 0; cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); #elif defined(IP_SENDSRCADDR) msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); @@ -518,12 +522,16 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, msg.msg_control = NULL; #endif /* IP_PKTINFO or IP_SENDSRCADDR */ } else if(r->srctype == 6) { + void* cmsg_data; msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); log_assert(msg.msg_controllen <= sizeof(control)); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v6info, sizeof(struct in6_pktinfo)); + /* unset the ifindex to not bypass the routing tables */ + cmsg_data = CMSG_DATA(cmsg); + ((struct in6_pktinfo *) cmsg_data)->ipi6_ifindex = 0; cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); } else { /* try to pass all 0 to use default route */ @@ -879,12 +887,12 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) } /* grab the tcp handler buffers */ + c->cur_tcp_count++; c->tcp_free = c_hdl->tcp_free; if(!c->tcp_free) { /* stop accepting incoming queries for now. */ comm_point_stop_listening(c); } - /* addr is dropped. Not needed for tcp reply. */ setup_tcp_handler(c_hdl, new_fd); } @@ -902,6 +910,7 @@ reclaim_tcp_handler(struct comm_point* c) } comm_point_close(c); if(c->tcp_parent) { + c->tcp_parent->cur_tcp_count--; c->tcp_free = c->tcp_parent->tcp_free; c->tcp_parent->tcp_free = c; if(!c->tcp_free) { @@ -1528,6 +1537,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer, c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; + c->cur_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_udp; @@ -1578,6 +1588,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd, c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; + c->cur_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_udp; @@ -1639,6 +1650,7 @@ comm_point_create_tcp_handler(struct comm_base *base, c->tcp_byte_count = 0; c->tcp_parent = parent; c->max_tcp_count = 0; + c->cur_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_tcp; @@ -1691,6 +1703,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize, c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = num; + c->cur_tcp_count = 0; c->tcp_handlers = (struct comm_point**)calloc((size_t)num, sizeof(struct comm_point*)); if(!c->tcp_handlers) { @@ -1758,6 +1771,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize, c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; + c->cur_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_tcp; @@ -1810,6 +1824,7 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize, c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; + c->cur_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_local; @@ -1857,6 +1872,7 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing, c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; + c->cur_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_raw; diff --git a/contrib/unbound/util/netevent.h b/contrib/unbound/util/netevent.h index 37322ab..4b87cdb 100644 --- a/contrib/unbound/util/netevent.h +++ b/contrib/unbound/util/netevent.h @@ -164,6 +164,8 @@ struct comm_point { /* -------- TCP Accept -------- */ /** the number of TCP handlers for this tcp-accept socket */ int max_tcp_count; + /** current number of tcp handler in-use for this accept socket */ + int cur_tcp_count; /** malloced array of tcp handlers for a tcp-accept, of size max_tcp_count. */ struct comm_point** tcp_handlers; |