summaryrefslogtreecommitdiffstats
path: root/contrib/unbound/util
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/util')
-rw-r--r--contrib/unbound/util/alloc.c19
-rw-r--r--contrib/unbound/util/alloc.h4
-rw-r--r--contrib/unbound/util/config_file.c62
-rw-r--r--contrib/unbound/util/config_file.h25
-rw-r--r--contrib/unbound/util/configlexer.lex15
-rw-r--r--contrib/unbound/util/configparser.y126
-rw-r--r--contrib/unbound/util/data/dname.c2
-rw-r--r--contrib/unbound/util/data/msgencode.c4
-rw-r--r--contrib/unbound/util/data/msgparse.c8
-rw-r--r--contrib/unbound/util/data/msgparse.h6
-rw-r--r--contrib/unbound/util/data/msgreply.c46
-rw-r--r--contrib/unbound/util/data/msgreply.h3
-rw-r--r--contrib/unbound/util/data/packed_rrset.c6
-rw-r--r--contrib/unbound/util/data/packed_rrset.h6
-rw-r--r--contrib/unbound/util/fptr_wlist.c4
-rw-r--r--contrib/unbound/util/iana_ports.inc17
-rw-r--r--contrib/unbound/util/log.c10
-rw-r--r--contrib/unbound/util/log.h9
-rw-r--r--contrib/unbound/util/net_help.c33
-rw-r--r--contrib/unbound/util/netevent.c22
-rw-r--r--contrib/unbound/util/netevent.h2
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;
OpenPOWER on IntegriCloud