aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/util
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2019-07-04 08:40:10 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2019-07-04 08:40:10 +0000
commite86b9096262054dbb4228fb94def3728edcc8a37 (patch)
tree38011feac90fc25a7214578f3afe100de515941f /contrib/unbound/util
parent9f011bca829751ed3552ac94fe7c865d75fabfc4 (diff)
parent366b94c4a9552acfb560d3234aea0955ebc1eb8e (diff)
downloadsrc-e86b9096262054dbb4228fb94def3728edcc8a37.tar.gz
src-e86b9096262054dbb4228fb94def3728edcc8a37.zip
Notes
Diffstat (limited to 'contrib/unbound/util')
-rw-r--r--contrib/unbound/util/alloc.c8
-rw-r--r--contrib/unbound/util/config_file.c53
-rw-r--r--contrib/unbound/util/config_file.h32
-rw-r--r--contrib/unbound/util/configlexer.lex22
-rw-r--r--contrib/unbound/util/configparser.y219
-rw-r--r--contrib/unbound/util/data/msgencode.c7
-rw-r--r--contrib/unbound/util/data/msgreply.c12
-rw-r--r--contrib/unbound/util/data/msgreply.h2
-rw-r--r--contrib/unbound/util/edns.c2
-rw-r--r--contrib/unbound/util/fptr_wlist.c11
-rw-r--r--contrib/unbound/util/iana_ports.inc4
-rw-r--r--contrib/unbound/util/log.c29
-rw-r--r--contrib/unbound/util/log.h21
-rw-r--r--contrib/unbound/util/mini_event.c2
-rw-r--r--contrib/unbound/util/net_help.c200
-rw-r--r--contrib/unbound/util/net_help.h36
-rw-r--r--contrib/unbound/util/netevent.c205
-rw-r--r--contrib/unbound/util/netevent.h8
-rw-r--r--contrib/unbound/util/storage/lookup3.c8
-rw-r--r--contrib/unbound/util/ub_event.c14
20 files changed, 777 insertions, 118 deletions
diff --git a/contrib/unbound/util/alloc.c b/contrib/unbound/util/alloc.c
index 908b1f42361f..7e9618931ca6 100644
--- a/contrib/unbound/util/alloc.c
+++ b/contrib/unbound/util/alloc.c
@@ -376,6 +376,7 @@ void *unbound_stat_malloc(size_t size)
{
void* res;
if(size == 0) size = 1;
+ log_assert(size <= SIZE_MAX-16);
res = malloc(size+16);
if(!res) return NULL;
unbound_mem_alloc += size;
@@ -398,6 +399,7 @@ void *unbound_stat_calloc(size_t nmemb, size_t size)
if(nmemb != 0 && INT_MAX/nmemb < size)
return NULL; /* integer overflow check */
s = (nmemb*size==0)?(size_t)1:nmemb*size;
+ log_assert(s <= SIZE_MAX-16);
res = calloc(1, s+16);
if(!res) return NULL;
log_info("stat %p=calloc(%u, %u)", res+16, (unsigned)nmemb, (unsigned)size);
@@ -447,6 +449,7 @@ void *unbound_stat_realloc(void *ptr, size_t size)
/* nothing changes */
return ptr;
}
+ log_assert(size <= SIZE_MAX-16);
res = malloc(size+16);
if(!res) return NULL;
unbound_mem_alloc += size;
@@ -521,7 +524,9 @@ void *unbound_stat_malloc_lite(size_t size, const char* file, int line,
const char* func)
{
/* [prefix .. len .. actual data .. suffix] */
- void* res = malloc(size+lite_pad*2+sizeof(size_t));
+ void* res;
+ log_assert(size <= SIZE_MAX-(lite_pad*2+sizeof(size_t)));
+ res = malloc(size+lite_pad*2+sizeof(size_t));
if(!res) return NULL;
memmove(res, lite_pre, lite_pad);
memmove(res+lite_pad, &size, sizeof(size_t));
@@ -538,6 +543,7 @@ void *unbound_stat_calloc_lite(size_t nmemb, size_t size, const char* file,
if(nmemb != 0 && INT_MAX/nmemb < size)
return NULL; /* integer overflow check */
req = nmemb * size;
+ log_assert(req <= SIZE_MAX-(lite_pad*2+sizeof(size_t)));
res = malloc(req+lite_pad*2+sizeof(size_t));
if(!res) return NULL;
memmove(res, lite_pre, lite_pad);
diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c
index 1a24ed5019c6..bdb55cbb0c02 100644
--- a/contrib/unbound/util/config_file.c
+++ b/contrib/unbound/util/config_file.c
@@ -59,6 +59,7 @@
#include "services/cache/infra.h"
#include "sldns/wire2str.h"
#include "sldns/parseutil.h"
+#include "iterator/iterator.h"
#ifdef HAVE_GLOB_H
# include <glob.h>
#endif
@@ -75,6 +76,8 @@ uid_t cfg_uid = (uid_t)-1;
gid_t cfg_gid = (gid_t)-1;
/** for debug allow small timeout values for fast rollovers */
int autr_permit_small_holddown = 0;
+/** size (in bytes) of stream wait buffers max */
+size_t stream_wait_max = 4 * 1024 * 1024;
/** global config during parsing */
struct config_parser_state* cfg_parser = 0;
@@ -118,6 +121,7 @@ config_create(void)
cfg->log_time_ascii = 0;
cfg->log_queries = 0;
cfg->log_replies = 0;
+ cfg->log_tag_queryreply = 0;
cfg->log_local_actions = 0;
cfg->log_servfail = 0;
#ifndef USE_WINSOCK
@@ -138,6 +142,7 @@ config_create(void)
cfg->outgoing_num_tcp = 2; /* leaves 64-52=12 for: 4if,1stop,thread4 */
cfg->incoming_num_tcp = 2;
#endif
+ cfg->stream_wait_size = 4 * 1024 * 1024;
cfg->edns_buffer_size = 4096; /* 4k from rfc recommendation */
cfg->msg_buffer_size = 65552; /* 64 k + a small margin */
cfg->msg_cache_size = 4 * 1024 * 1024;
@@ -152,6 +157,7 @@ config_create(void)
cfg->max_negative_ttl = 3600;
cfg->prefetch = 0;
cfg->prefetch_key = 0;
+ cfg->deny_any = 0;
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 10000;
cfg->infra_cache_min_rtt = 50;
@@ -167,8 +173,8 @@ config_create(void)
if(!(cfg->logfile = strdup(""))) goto error_exit;
if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit;
if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
- cfg->low_rtt_permil = 0;
- cfg->low_rtt = 45;
+ cfg->fast_server_permil = 0;
+ cfg->fast_server_num = 3;
cfg->donotqueryaddrs = NULL;
cfg->donotquery_localhost = 1;
cfg->root_hints = NULL;
@@ -194,6 +200,10 @@ config_create(void)
cfg->client_subnet_always_forward = 0;
cfg->max_client_subnet_ipv4 = 24;
cfg->max_client_subnet_ipv6 = 56;
+ cfg->min_client_subnet_ipv4 = 0;
+ cfg->min_client_subnet_ipv6 = 0;
+ cfg->max_ecs_tree_size_ipv4 = 100;
+ cfg->max_ecs_tree_size_ipv6 = 100;
#endif
cfg->views = NULL;
cfg->acls = NULL;
@@ -258,6 +268,7 @@ config_create(void)
cfg->control_use_cert = 1;
cfg->minimal_responses = 1;
cfg->rrset_roundrobin = 0;
+ cfg->unknown_server_time_limit = 376;
cfg->max_udp_size = 4096;
if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key")))
goto error_exit;
@@ -476,6 +487,9 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STRLIST("additional-tls-port:", tls_additional_port)
else S_STRLIST("tls-additional-ports:", tls_additional_port)
else S_STRLIST("tls-additional-port:", tls_additional_port)
+ else S_STRLIST_APPEND("tls-session-ticket-keys:", tls_session_ticket_keys)
+ else S_STR("tls-ciphers:", tls_ciphers)
+ else S_STR("tls-ciphersuites:", tls_ciphersuites)
else S_YNO("interface-automatic:", if_automatic)
else S_YNO("use-systemd:", use_systemd)
else S_YNO("do-daemonize:", do_daemonize)
@@ -483,6 +497,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_NUMBER_NONZERO("outgoing-range:", outgoing_num_ports)
else S_SIZET_OR_ZERO("outgoing-num-tcp:", outgoing_num_tcp)
else S_SIZET_OR_ZERO("incoming-num-tcp:", incoming_num_tcp)
+ else S_MEMSIZE("stream-wait-size:", stream_wait_size)
else S_SIZET_NONZERO("edns-buffer-size:", edns_buffer_size)
else S_SIZET_NONZERO("msg-buffer-size:", msg_buffer_size)
else S_MEMSIZE("msg-cache-size:", msg_cache_size)
@@ -498,6 +513,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_POW2("rrset-cache-slabs:", rrset_cache_slabs)
else S_YNO("prefetch:", prefetch)
else S_YNO("prefetch-key:", prefetch_key)
+ else S_YNO("deny-any:", deny_any)
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)
@@ -552,6 +568,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("val-log-squelch:", val_log_squelch)
else S_YNO("log-queries:", log_queries)
else S_YNO("log-replies:", log_replies)
+ else S_YNO("log-tag-queryreply:", log_tag_queryreply)
else S_YNO("log-local-actions:", log_local_actions)
else S_YNO("log-servfail:", log_servfail)
else S_YNO("val-permissive-mode:", val_permissive_mode)
@@ -573,6 +590,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_MEMSIZE("neg-cache-size:", neg_cache_size)
else S_YNO("minimal-responses:", minimal_responses)
else S_YNO("rrset-roundrobin:", rrset_roundrobin)
+ else S_NUMBER_OR_ZERO("unknown-server-time-limit:", unknown_server_time_limit)
else S_STRLIST("local-data:", local_data)
else S_YNO("unblock-lan-zones:", unblock_lan_zones)
else S_YNO("insecure-lan-zones:", insecure_lan_zones)
@@ -642,9 +660,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_POW2("ratelimit-slabs:", ratelimit_slabs)
else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
- else S_NUMBER_OR_ZERO("low-rtt:", low_rtt)
- else S_NUMBER_OR_ZERO("low-rtt-pct:", low_rtt_permil)
- else S_NUMBER_OR_ZERO("low-rtt-permil:", low_rtt_permil)
+ else S_SIZET_NONZERO("fast-server-num:", fast_server_num)
+ else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
else S_YNO("qname-minimisation:", qname_minimisation)
else S_YNO("qname-minimisation-strict:", qname_minimisation_strict)
#ifdef USE_IPSECMOD
@@ -683,7 +700,9 @@ int config_set_option(struct config_file* cfg, const char* opt,
* ratelimit-for-domain, ratelimit-below-domain,
* local-zone-tag, access-control-view,
* send-client-subnet, client-subnet-always-forward,
- * max-client-subnet-ipv4, max-client-subnet-ipv6, ipsecmod_hook,
+ * max-client-subnet-ipv4, max-client-subnet-ipv6,
+ * min-client-subnet-ipv4, min-client-subnet-ipv6,
+ * max-ecs-tree-size-ipv4, max-ecs-tree-size-ipv6, ipsecmod_hook,
* ipsecmod_whitelist. */
return 0;
}
@@ -865,6 +884,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_DEC(opt, "outgoing-range", outgoing_num_ports)
else O_DEC(opt, "outgoing-num-tcp", outgoing_num_tcp)
else O_DEC(opt, "incoming-num-tcp", incoming_num_tcp)
+ else O_MEM(opt, "stream-wait-size", stream_wait_size)
else O_DEC(opt, "edns-buffer-size", edns_buffer_size)
else O_DEC(opt, "msg-buffer-size", msg_buffer_size)
else O_MEM(opt, "msg-cache-size", msg_cache_size)
@@ -880,6 +900,7 @@ config_get_option(struct config_file* cfg, const char* opt,
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_YNO(opt, "deny-any", deny_any)
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)
@@ -906,6 +927,9 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
else O_YNO(opt, "tls-win-cert", tls_win_cert)
else O_LST(opt, "tls-additional-port", tls_additional_port)
+ else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first)
+ else O_STR(opt, "tls-ciphers", tls_ciphers)
+ else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
else O_YNO(opt, "use-systemd", use_systemd)
else O_YNO(opt, "do-daemonize", do_daemonize)
else O_STR(opt, "chroot", chrootdir)
@@ -914,6 +938,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "logfile", logfile)
else O_YNO(opt, "log-queries", log_queries)
else O_YNO(opt, "log-replies", log_replies)
+ else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply)
else O_YNO(opt, "log-local-actions", log_local_actions)
else O_YNO(opt, "log-servfail", log_servfail)
else O_STR(opt, "pidfile", pidfile)
@@ -977,11 +1002,16 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_UNS(opt, "val-override-date", val_date_override)
else O_YNO(opt, "minimal-responses", minimal_responses)
else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
+ else O_DEC(opt, "unknown-server-time-limit", unknown_server_time_limit)
#ifdef CLIENT_SUBNET
else O_LST(opt, "send-client-subnet", client_subnet)
else O_LST(opt, "client-subnet-zone", client_subnet_zone)
else O_DEC(opt, "max-client-subnet-ipv4", max_client_subnet_ipv4)
else O_DEC(opt, "max-client-subnet-ipv6", max_client_subnet_ipv6)
+ else O_DEC(opt, "min-client-subnet-ipv4", min_client_subnet_ipv4)
+ else O_DEC(opt, "min-client-subnet-ipv6", min_client_subnet_ipv6)
+ else O_DEC(opt, "max-ecs-tree-size-ipv4", max_ecs_tree_size_ipv4)
+ else O_DEC(opt, "max-ecs-tree-size-ipv6", max_ecs_tree_size_ipv6)
else O_YNO(opt, "client-subnet-always-forward:",
client_subnet_always_forward)
#endif
@@ -1036,9 +1066,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
- else O_DEC(opt, "low-rtt", low_rtt)
- else O_DEC(opt, "low-rtt-pct", low_rtt_permil)
- else O_DEC(opt, "low-rtt-permil", low_rtt_permil)
+ else O_DEC(opt, "fast-server-num", fast_server_num)
+ else O_DEC(opt, "fast-server-permil", fast_server_permil)
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
else O_YNO(opt, "qname-minimisation", qname_minimisation)
@@ -1335,6 +1364,9 @@ config_delete(struct config_file* cfg)
free(cfg->ssl_service_pem);
free(cfg->tls_cert_bundle);
config_delstrlist(cfg->tls_additional_port);
+ config_delstrlist(cfg->tls_session_ticket_keys.first);
+ free(cfg->tls_ciphers);
+ free(cfg->tls_ciphersuites);
free(cfg->log_identity);
config_del_strarray(cfg->ifs, cfg->num_ifs);
config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
@@ -1888,8 +1920,11 @@ config_apply(struct config_file* config)
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
MINIMAL_RESPONSES = config->minimal_responses;
RRSET_ROUNDROBIN = config->rrset_roundrobin;
+ LOG_TAG_QUERYREPLY = config->log_tag_queryreply;
+ UNKNOWN_SERVER_NICENESS = config->unknown_server_time_limit;
log_set_time_asc(config->log_time_ascii);
autr_permit_small_holddown = config->permit_small_holddown;
+ stream_wait_max = config->stream_wait_size;
}
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 8c630b8a109c..3cffdbff9386 100644
--- a/contrib/unbound/util/config_file.h
+++ b/contrib/unbound/util/config_file.h
@@ -120,6 +120,12 @@ struct config_file {
int tls_win_cert;
/** additional tls ports */
struct config_strlist* tls_additional_port;
+ /** secret key used to encrypt and decrypt TLS session ticket */
+ struct config_strlist_head tls_session_ticket_keys;
+ /** TLS ciphers */
+ char* tls_ciphers;
+ /** TLS chiphersuites (TLSv1.3) */
+ char* tls_ciphersuites;
/** outgoing port range number of ports (per thread) */
int outgoing_num_ports;
@@ -132,6 +138,8 @@ struct config_file {
/** EDNS buffer size to use */
size_t edns_buffer_size;
+ /** size of the stream wait buffers, max */
+ size_t stream_wait_size;
/** number of bytes buffer size for DNS messages */
size_t msg_buffer_size;
/** size of the message cache */
@@ -159,10 +167,11 @@ struct config_file {
/** the target fetch policy for the iterator */
char* target_fetch_policy;
- /** percent*10, how many times in 1000 to pick low rtt destinations */
- int low_rtt_permil;
- /** what time in msec is a low rtt destination */
- int low_rtt;
+ /** percent*10, how many times in 1000 to pick from the fastest
+ * destinations */
+ int fast_server_permil;
+ /** number of fastest server to select from */
+ size_t fast_server_num;
/** automatic interface for incoming messages. Uses ipv6 remapping,
* and recvmsg/sendmsg ancillary data to detect interfaces, boolean */
@@ -214,6 +223,12 @@ struct config_file {
/** Subnet length we are willing to give up privacy for */
uint8_t max_client_subnet_ipv4;
uint8_t max_client_subnet_ipv6;
+ /** Minimum subnet length we are willing to answer */
+ uint8_t min_client_subnet_ipv4;
+ uint8_t min_client_subnet_ipv6;
+ /** Max number of nodes in the ECS radix tree */
+ uint32_t max_ecs_tree_size_ipv4;
+ uint32_t max_ecs_tree_size_ipv6;
#endif
/** list of access control entries, linked list */
struct config_str2list* acls;
@@ -257,6 +272,8 @@ struct config_file {
int prefetch;
/** if prefetching of DNSKEYs should be performed. */
int prefetch_key;
+ /** deny queries of type ANY with an empty answer */
+ int deny_any;
/** chrootdir, if not "" or chroot will be done */
char* chrootdir;
@@ -277,6 +294,8 @@ struct config_file {
int log_queries;
/** log replies with one line per reply */
int log_replies;
+ /** tag log_queries and log_replies for filtering */
+ int log_tag_queryreply;
/** log every local-zone hit **/
int log_local_actions;
/** log servfails with a reason */
@@ -428,6 +447,9 @@ struct config_file {
/* RRSet roundrobin */
int rrset_roundrobin;
+ /* wait time for unknown server in msec */
+ int unknown_server_time_limit;
+
/* maximum UDP response size */
size_t max_udp_size;
@@ -561,6 +583,8 @@ extern uid_t cfg_uid;
extern gid_t cfg_gid;
/** debug and enable small timeouts */
extern int autr_permit_small_holddown;
+/** size (in bytes) of stream wait buffers max */
+extern size_t stream_wait_max;
/**
* Stub config options
diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex
index 84920586675e..99311a6311a4 100644
--- a/contrib/unbound/util/configlexer.lex
+++ b/contrib/unbound/util/configlexer.lex
@@ -121,9 +121,8 @@ static void config_start_include_glob(const char* filename)
#ifdef GLOB_ERR
| GLOB_ERR
#endif
-#ifdef GLOB_NOSORT
- | GLOB_NOSORT
-#endif
+ /* do not set GLOB_NOSORT so the results are sorted
+ and in a predictable order. */
#ifdef GLOB_BRACE
| GLOB_BRACE
#endif
@@ -247,6 +246,9 @@ additional-ssl-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
additional-tls-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
tls-additional-ports{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
tls-additional-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
+tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
+tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) }
+tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) }
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
@@ -264,6 +266,7 @@ directory{COLON} { YDVAR(1, VAR_DIRECTORY) }
logfile{COLON} { YDVAR(1, VAR_LOGFILE) }
pidfile{COLON} { YDVAR(1, VAR_PIDFILE) }
root-hints{COLON} { YDVAR(1, VAR_ROOT_HINTS) }
+stream-wait-size{COLON} { YDVAR(1, VAR_STREAM_WAIT_SIZE) }
edns-buffer-size{COLON} { YDVAR(1, VAR_EDNS_BUFFER_SIZE) }
msg-buffer-size{COLON} { YDVAR(1, VAR_MSG_BUFFER_SIZE) }
msg-cache-size{COLON} { YDVAR(1, VAR_MSG_CACHE_SIZE) }
@@ -297,6 +300,7 @@ private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
prefetch{COLON} { YDVAR(1, VAR_PREFETCH) }
+deny-any{COLON} { YDVAR(1, VAR_DENY_ANY) }
stub-zone{COLON} { YDVAR(0, VAR_STUB_ZONE) }
name{COLON} { YDVAR(1, VAR_NAME) }
stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) }
@@ -332,6 +336,10 @@ client-subnet-always-forward{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_ALWAYS_FORWARD)
client-subnet-opcode{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_OPCODE) }
max-client-subnet-ipv4{COLON} { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV4) }
max-client-subnet-ipv6{COLON} { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV6) }
+min-client-subnet-ipv4{COLON} { YDVAR(1, VAR_MIN_CLIENT_SUBNET_IPV4) }
+min-client-subnet-ipv6{COLON} { YDVAR(1, VAR_MIN_CLIENT_SUBNET_IPV6) }
+max-ecs-tree-size-ipv4{COLON} { YDVAR(1, VAR_MAX_ECS_TREE_SIZE_IPV4) }
+max-ecs-tree-size-ipv6{COLON} { YDVAR(1, VAR_MAX_ECS_TREE_SIZE_IPV6) }
hide-identity{COLON} { YDVAR(1, VAR_HIDE_IDENTITY) }
hide-version{COLON} { YDVAR(1, VAR_HIDE_VERSION) }
hide-trustanchor{COLON} { YDVAR(1, VAR_HIDE_TRUSTANCHOR) }
@@ -374,6 +382,7 @@ log-identity{COLON} { YDVAR(1, VAR_LOG_IDENTITY) }
log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) }
log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) }
log-replies{COLON} { YDVAR(1, VAR_LOG_REPLIES) }
+log-tag-queryreply{COLON} { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) }
log-local-actions{COLON} { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) }
log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) }
local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) }
@@ -400,6 +409,7 @@ python{COLON} { YDVAR(0, VAR_PYTHON) }
domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) }
minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) }
rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) }
+unknown-server-time-limit{COLON} { YDVAR(1, VAR_UNKNOWN_SERVER_TIME_LIMIT) }
max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) }
dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
@@ -442,8 +452,10 @@ ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
-low-rtt-pct{COLON} { YDVAR(1, VAR_LOW_RTT_PERMIL) }
-low-rtt-permil{COLON} { YDVAR(1, VAR_LOW_RTT_PERMIL) }
+fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) }
+low-rtt-pct{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
+low-rtt-permil{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
+fast-server-permil{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }
diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y
index 24c5b2d1e95d..c7b916966e24 100644
--- a/contrib/unbound/util/configparser.y
+++ b/contrib/unbound/util/configparser.y
@@ -135,6 +135,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE
%token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE
%token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
+%token VAR_MIN_CLIENT_SUBNET_IPV4 VAR_MIN_CLIENT_SUBNET_IPV6
+%token VAR_MAX_ECS_TREE_SIZE_IPV4 VAR_MAX_ECS_TREE_SIZE_IPV6
%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
%token VAR_QNAME_MINIMISATION VAR_QNAME_MINIMISATION_STRICT VAR_IP_FREEBIND
%token VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG VAR_ACCESS_CONTROL_TAG
@@ -159,8 +161,12 @@ extern struct config_parser_state* cfg_parser;
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
+%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
-%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL
+%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
+%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
+%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
+%token VAR_TLS_SESSION_TICKET_KEYS
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -237,6 +243,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_client_subnet_zone | server_client_subnet_always_forward |
server_client_subnet_opcode |
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
+ server_min_client_subnet_ipv4 | server_min_client_subnet_ipv6 |
+ server_max_ecs_tree_size_ipv4 | server_max_ecs_tree_size_ipv6 |
server_caps_whitelist | server_cache_max_negative_ttl |
server_permit_small_holddown | server_qname_minimisation |
server_ip_freebind | server_define_tag | server_local_zone_tag |
@@ -255,8 +263,11 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ipsecmod_whitelist | server_ipsecmod_strict |
server_udp_upstream_without_downstream | server_aggressive_nsec |
server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
- server_low_rtt_permil | server_tls_win_cert |
- server_tcp_connection_limit | server_log_servfail
+ server_fast_server_permil | server_fast_server_num | server_tls_win_cert |
+ server_tcp_connection_limit | server_log_servfail | server_deny_any |
+ server_unknown_server_time_limit | server_log_tag_queryreply |
+ server_stream_wait_size | server_tls_ciphers |
+ server_tls_ciphersuites | server_tls_session_ticket_keys
;
stubstart: VAR_STUB_ZONE
{
@@ -493,6 +504,70 @@ server_max_client_subnet_ipv6: VAR_MAX_CLIENT_SUBNET_IPV6 STRING_ARG
free($2);
}
;
+server_min_client_subnet_ipv4: VAR_MIN_CLIENT_SUBNET_IPV4 STRING_ARG
+ {
+ #ifdef CLIENT_SUBNET
+ OUTYY(("P(min_client_subnet_ipv4:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("IPv4 subnet length expected");
+ else if (atoi($2) > 32)
+ cfg_parser->cfg->min_client_subnet_ipv4 = 32;
+ else if (atoi($2) < 0)
+ cfg_parser->cfg->min_client_subnet_ipv4 = 0;
+ else cfg_parser->cfg->min_client_subnet_ipv4 = (uint8_t)atoi($2);
+ #else
+ OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+ #endif
+ free($2);
+ }
+ ;
+server_min_client_subnet_ipv6: VAR_MIN_CLIENT_SUBNET_IPV6 STRING_ARG
+ {
+ #ifdef CLIENT_SUBNET
+ OUTYY(("P(min_client_subnet_ipv6:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("Ipv6 subnet length expected");
+ else if (atoi($2) > 128)
+ cfg_parser->cfg->min_client_subnet_ipv6 = 128;
+ else if (atoi($2) < 0)
+ cfg_parser->cfg->min_client_subnet_ipv6 = 0;
+ else cfg_parser->cfg->min_client_subnet_ipv6 = (uint8_t)atoi($2);
+ #else
+ OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+ #endif
+ free($2);
+ }
+ ;
+server_max_ecs_tree_size_ipv4: VAR_MAX_ECS_TREE_SIZE_IPV4 STRING_ARG
+ {
+ #ifdef CLIENT_SUBNET
+ OUTYY(("P(max_ecs_tree_size_ipv4:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("IPv4 ECS tree size expected");
+ else if (atoi($2) < 0)
+ cfg_parser->cfg->max_ecs_tree_size_ipv4 = 0;
+ else cfg_parser->cfg->max_ecs_tree_size_ipv4 = (uint32_t)atoi($2);
+ #else
+ OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+ #endif
+ free($2);
+ }
+ ;
+server_max_ecs_tree_size_ipv6: VAR_MAX_ECS_TREE_SIZE_IPV6 STRING_ARG
+ {
+ #ifdef CLIENT_SUBNET
+ OUTYY(("P(max_ecs_tree_size_ipv6:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("IPv6 ECS tree size expected");
+ else if (atoi($2) < 0)
+ cfg_parser->cfg->max_ecs_tree_size_ipv6 = 0;
+ else cfg_parser->cfg->max_ecs_tree_size_ipv6 = (uint32_t)atoi($2);
+ #else
+ OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+ #endif
+ free($2);
+ }
+ ;
server_interface: VAR_INTERFACE STRING_ARG
{
OUTYY(("P(server_interface:%s)\n", $2));
@@ -747,6 +822,28 @@ server_tls_additional_port: VAR_TLS_ADDITIONAL_PORT STRING_ARG
yyerror("out of memory");
}
;
+server_tls_ciphers: VAR_TLS_CIPHERS STRING_ARG
+ {
+ OUTYY(("P(server_tls_ciphers:%s)\n", $2));
+ free(cfg_parser->cfg->tls_ciphers);
+ cfg_parser->cfg->tls_ciphers = $2;
+ }
+ ;
+server_tls_ciphersuites: VAR_TLS_CIPHERSUITES STRING_ARG
+ {
+ OUTYY(("P(server_tls_ciphersuites:%s)\n", $2));
+ free(cfg_parser->cfg->tls_ciphersuites);
+ cfg_parser->cfg->tls_ciphersuites = $2;
+ }
+ ;
+server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG
+ {
+ OUTYY(("P(server_tls_session_ticket_keys:%s)\n", $2));
+ if(!cfg_strlist_append(&cfg_parser->cfg->tls_session_ticket_keys,
+ $2))
+ yyerror("out of memory");
+ }
+ ;
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
{
OUTYY(("P(server_use_systemd:%s)\n", $2));
@@ -806,6 +903,15 @@ server_log_replies: VAR_LOG_REPLIES STRING_ARG
free($2);
}
;
+server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG
+ {
+ OUTYY(("P(server_log_tag_queryreply:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG
{
OUTYY(("P(server_log_servfail:%s)\n", $2));
@@ -1047,6 +1153,14 @@ server_ip_freebind: VAR_IP_FREEBIND STRING_ARG
free($2);
}
;
+server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG
+ {
+ OUTYY(("P(server_stream_wait_size:%s)\n", $2));
+ if(!cfg_parse_memsize($2, &cfg_parser->cfg->stream_wait_size))
+ yyerror("memory size expected");
+ free($2);
+ }
+ ;
server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
{
OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
@@ -1342,6 +1456,15 @@ server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG
free($2);
}
;
+server_deny_any: VAR_DENY_ANY STRING_ARG
+ {
+ OUTYY(("P(server_deny_any:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->deny_any = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
{
OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
@@ -1380,6 +1503,8 @@ server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG
yyerror("expected deny, refuse, deny_non_local, "
"refuse_non_local, allow, allow_setrd or "
"allow_snoop in access control action");
+ free($2);
+ free($3);
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
fatal_exit("out of memory adding acl");
@@ -1658,13 +1783,17 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
&& strcmp($3, "always_refuse")!=0
&& strcmp($3, "always_nxdomain")!=0
&& strcmp($3, "noview")!=0
- && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
+ && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
+ && strcmp($3, "inform_redirect") != 0) {
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
- "always_transparent, always_refuse, "
- "always_nxdomain, noview or nodefault");
- else if(strcmp($3, "nodefault")==0) {
+ "inform_redirect, always_transparent, "
+ "always_refuse, always_nxdomain, noview "
+ "or nodefault");
+ free($2);
+ free($3);
+ } else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->
local_zones_nodefault, $2))
fatal_exit("out of memory adding local-zone");
@@ -1718,6 +1847,13 @@ server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG
free($2);
}
;
+server_unknown_server_time_limit: VAR_UNKNOWN_SERVER_TIME_LIMIT STRING_ARG
+ {
+ OUTYY(("P(server_unknown_server_time_limit:%s)\n", $2));
+ cfg_parser->cfg->unknown_server_time_limit = atoi($2);
+ free($2);
+ }
+ ;
server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
{
OUTYY(("P(server_max_udp_size:%s)\n", $2));
@@ -1770,8 +1906,10 @@ server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG
&len);
free($3);
OUTYY(("P(server_local_zone_tag:%s)\n", $2));
- if(!bitlist)
+ if(!bitlist) {
yyerror("could not parse tags, (define-tag them first)");
+ free($2);
+ }
if(bitlist) {
if(!cfg_strbytelist_insert(
&cfg_parser->cfg->local_zone_tags,
@@ -1789,8 +1927,10 @@ server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
&len);
free($3);
OUTYY(("P(server_access_control_tag:%s)\n", $2));
- if(!bitlist)
+ if(!bitlist) {
yyerror("could not parse tags, (define-tag them first)");
+ free($2);
+ }
if(bitlist) {
if(!cfg_strbytelist_insert(
&cfg_parser->cfg->acl_tags,
@@ -1843,8 +1983,6 @@ server_access_control_view: VAR_ACCESS_CONTROL_VIEW STRING_ARG STRING_ARG
if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view,
$2, $3)) {
yyerror("out of memory");
- free($2);
- free($3);
}
}
;
@@ -1855,8 +1993,10 @@ server_response_ip_tag: VAR_RESPONSE_IP_TAG STRING_ARG STRING_ARG
&len);
free($3);
OUTYY(("P(response_ip_tag:%s)\n", $2));
- if(!bitlist)
+ if(!bitlist) {
yyerror("could not parse tags, (define-tag them first)");
+ free($2);
+ }
if(bitlist) {
if(!cfg_strbytelist_insert(
&cfg_parser->cfg->respip_tags,
@@ -1933,6 +2073,8 @@ 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");
+ free($2);
+ free($3);
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->
ratelimit_for_domain, $2, $3))
@@ -1946,6 +2088,8 @@ 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");
+ free($2);
+ free($3);
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->
ratelimit_below_domain, $2, $3))
@@ -1974,19 +2118,25 @@ server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG
;
server_low_rtt: VAR_LOW_RTT STRING_ARG
{
- OUTYY(("P(server_low_rtt:%s)\n", $2));
- if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));
+ free($2);
+ }
+ ;
+server_fast_server_num: VAR_FAST_SERVER_NUM STRING_ARG
+ {
+ OUTYY(("P(server_fast_server_num:%s)\n", $2));
+ if(atoi($2) <= 0)
yyerror("number expected");
- else cfg_parser->cfg->low_rtt = atoi($2);
+ else cfg_parser->cfg->fast_server_num = atoi($2);
free($2);
}
;
-server_low_rtt_permil: VAR_LOW_RTT_PERMIL STRING_ARG
+server_fast_server_permil: VAR_FAST_SERVER_PERMIL STRING_ARG
{
- OUTYY(("P(server_low_rtt_permil:%s)\n", $2));
+ OUTYY(("P(server_fast_server_permil:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
- else cfg_parser->cfg->low_rtt_permil = atoi($2);
+ else cfg_parser->cfg->fast_server_permil = atoi($2);
free($2);
}
;
@@ -2017,10 +2167,10 @@ server_ipsecmod_enabled: VAR_IPSECMOD_ENABLED STRING_ARG
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ipsecmod_enabled = (strcmp($2, "yes")==0);
- free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
+ free($2);
}
;
server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG
@@ -2030,10 +2180,10 @@ server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ipsecmod_ignore_bogus = (strcmp($2, "yes")==0);
- free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
+ free($2);
}
;
server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG
@@ -2044,6 +2194,7 @@ server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG
cfg_parser->cfg->ipsecmod_hook = $2;
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
#endif
}
;
@@ -2057,6 +2208,7 @@ server_ipsecmod_max_ttl: VAR_IPSECMOD_MAX_TTL STRING_ARG
free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
#endif
}
;
@@ -2068,6 +2220,7 @@ server_ipsecmod_whitelist: VAR_IPSECMOD_WHITELIST STRING_ARG
yyerror("out of memory");
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
#endif
}
;
@@ -2081,6 +2234,7 @@ server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG
free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
#endif
}
;
@@ -2288,13 +2442,15 @@ view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
&& strcmp($3, "always_refuse")!=0
&& strcmp($3, "always_nxdomain")!=0
&& strcmp($3, "noview")!=0
- && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
+ && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) {
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
"always_transparent, always_refuse, "
"always_nxdomain, noview or nodefault");
- else if(strcmp($3, "nodefault")==0) {
+ free($2);
+ free($3);
+ } else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->views->
local_zones_nodefault, $2))
fatal_exit("out of memory adding local-zone");
@@ -2330,7 +2486,6 @@ view_local_data: VAR_LOCAL_DATA STRING_ARG
OUTYY(("P(view_local_data:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, $2)) {
fatal_exit("out of memory adding local-data");
- free($2);
}
}
;
@@ -2453,6 +2608,7 @@ dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG
@@ -2468,6 +2624,7 @@ dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG
@@ -2476,6 +2633,7 @@ dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG
@@ -2499,6 +2657,7 @@ dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES ST
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_log_resolver_query_messages =
(strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG
@@ -2508,6 +2667,7 @@ dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSA
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_log_resolver_response_messages =
(strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG
@@ -2517,6 +2677,7 @@ dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_log_client_query_messages =
(strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG
@@ -2526,6 +2687,7 @@ dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_log_client_response_messages =
(strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG
@@ -2535,6 +2697,7 @@ dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_log_forwarder_query_messages =
(strcmp($2, "yes")==0);
+ free($2);
}
;
dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG
@@ -2544,6 +2707,7 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
yyerror("expected yes or no.");
else cfg_parser->cfg->dnstap_log_forwarder_response_messages =
(strcmp($2, "yes")==0);
+ free($2);
}
;
pythonstart: VAR_PYTHON
@@ -2590,15 +2754,14 @@ server_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG
server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
{
OUTYY(("P(server_response_ip_data:%s)\n", $2));
- if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
- $2, $3))
- fatal_exit("out of memory adding response-ip-data");
+ if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
+ $2, $3))
+ fatal_exit("out of memory adding response-ip-data");
}
;
dnscstart: VAR_DNSCRYPT
{
OUTYY(("\nP(dnscrypt:)\n"));
- OUTYY(("\nP(dnscrypt:)\n"));
}
;
contents_dnsc: contents_dnsc content_dnsc
@@ -2625,7 +2788,6 @@ dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG
dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG
{
OUTYY(("P(dnsc_dnscrypt_port:%s)\n", $2));
-
if(atoi($2) == 0)
yyerror("port number expected");
else cfg_parser->cfg->dnscrypt_port = atoi($2);
@@ -2727,6 +2889,7 @@ cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
cfg_parser->cfg->cachedb_backend = $2;
#else
OUTYY(("P(Compiled without cachedb, ignoring)\n"));
+ free($2);
#endif
}
;
diff --git a/contrib/unbound/util/data/msgencode.c b/contrib/unbound/util/data/msgencode.c
index 6bc3216ff9e9..4c0a5550be13 100644
--- a/contrib/unbound/util/data/msgencode.c
+++ b/contrib/unbound/util/data/msgencode.c
@@ -50,6 +50,11 @@
#include "sldns/sbuffer.h"
#include "services/localzone.h"
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#include <sys/time.h>
+
/** return code that means the function ran out of memory. negative so it does
* not conflict with DNS rcodes. */
#define RETVAL_OUTMEM -2
@@ -672,7 +677,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
}
/* roundrobin offset. using query id for random number. With ntohs
* for different roundrobins for sequential id client senders. */
- rr_offset = RRSET_ROUNDROBIN?ntohs(id):0;
+ rr_offset = RRSET_ROUNDROBIN?ntohs(id)+(timenow?timenow:time(NULL)):0;
/* "prepend" any local alias records in the answer section if this
* response is supposed to be authoritative. Currently it should
diff --git a/contrib/unbound/util/data/msgreply.c b/contrib/unbound/util/data/msgreply.c
index 45d42a87f458..32aec4bf4c95 100644
--- a/contrib/unbound/util/data/msgreply.c
+++ b/contrib/unbound/util/data/msgreply.c
@@ -195,6 +195,8 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
}
if(*rr_ttl < MIN_TTL)
*rr_ttl = MIN_TTL;
+ if(*rr_ttl > MAX_TTL)
+ *rr_ttl = MAX_TTL;
if(*rr_ttl < data->ttl)
data->ttl = *rr_ttl;
@@ -853,7 +855,9 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf,
addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));
if(rcode == LDNS_RCODE_FORMERR)
{
- log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
+ if(LOG_TAG_QUERYREPLY)
+ log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);
+ else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
} else {
if(qinf->qname)
dname_str(qinf->qname, qname_buf);
@@ -861,7 +865,11 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf,
pktlen = sldns_buffer_limit(rmsg);
sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));
sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));
- log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+ if(LOG_TAG_QUERYREPLY)
+ log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+ clientip_buf, qname_buf, type_buf, class_buf,
+ rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
+ else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
clientip_buf, qname_buf, type_buf, class_buf,
rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
}
diff --git a/contrib/unbound/util/data/msgreply.h b/contrib/unbound/util/data/msgreply.h
index a455c4d2b374..8d75f9b12f3a 100644
--- a/contrib/unbound/util/data/msgreply.h
+++ b/contrib/unbound/util/data/msgreply.h
@@ -157,7 +157,7 @@ struct reply_info {
time_t prefetch_ttl;
/**
- * Reply TTL extended with serve exipred TTL, to limit time to serve
+ * Reply TTL extended with serve expired TTL, to limit time to serve
* expired message.
*/
time_t serve_expired_ttl;
diff --git a/contrib/unbound/util/edns.c b/contrib/unbound/util/edns.c
index 5aa085549361..9c540913efdc 100644
--- a/contrib/unbound/util/edns.c
+++ b/contrib/unbound/util/edns.c
@@ -40,7 +40,7 @@
*/
#include "config.h"
-
+#include "util/edns.h"
#include "util/config_file.h"
#include "util/netevent.h"
#include "util/regional.h"
diff --git a/contrib/unbound/util/fptr_wlist.c b/contrib/unbound/util/fptr_wlist.c
index 302b6f7843ea..94d23fa3a32a 100644
--- a/contrib/unbound/util/fptr_wlist.c
+++ b/contrib/unbound/util/fptr_wlist.c
@@ -127,6 +127,7 @@ fptr_whitelist_comm_timer(void (*fptr)(void*))
#endif
else if(fptr == &auth_xfer_timer) return 1;
else if(fptr == &auth_xfer_probe_timer_callback) return 1;
+ else if(fptr == &auth_xfer_transfer_timer_callback) return 1;
return 0;
}
@@ -303,6 +304,9 @@ fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr)
{
if(fptr == NULL) return 1;
else if(fptr == &rrset_markdel) return 1;
+#ifdef CLIENT_SUBNET
+ else if(fptr == &subnet_markdel) return 1;
+#endif
return 0;
}
@@ -561,9 +565,12 @@ int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr)
#ifdef CLIENT_SUBNET
if(fptr == &ecs_whitelist_check)
return 1;
-#else
- (void)fptr;
#endif
+#ifdef WITH_PYTHONMODULE
+ if(fptr == &python_inplace_cb_query_generic)
+ return 1;
+#endif
+ (void)fptr;
return 0;
}
diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc
index e24322931326..aa972a67bd5d 100644
--- a/contrib/unbound/util/iana_ports.inc
+++ b/contrib/unbound/util/iana_ports.inc
@@ -4768,6 +4768,7 @@
8088,
8097,
8100,
+8111,
8115,
8116,
8118,
@@ -4796,10 +4797,12 @@
8206,
8207,
8208,
+8211,
8230,
8231,
8232,
8243,
+8266,
8276,
8280,
8282,
@@ -4862,6 +4865,7 @@
8805,
8807,
8808,
+8809,
8873,
8880,
8883,
diff --git a/contrib/unbound/util/log.c b/contrib/unbound/util/log.c
index 75a58f9de3db..318ff1d79107 100644
--- a/contrib/unbound/util/log.c
+++ b/contrib/unbound/util/log.c
@@ -78,8 +78,6 @@ static const char* ident="unbound";
/** are we using syslog(3) to log to */
static int logging_to_syslog = 0;
#endif /* HAVE_SYSLOG_H */
-/** time to print in log, if NULL, use time(2) */
-static time_t* log_now = NULL;
/** print time in UTC or in secondsfrom1970 */
static int log_time_asc = 0;
@@ -181,11 +179,6 @@ void log_ident_set(const char* id)
ident = id;
}
-void log_set_time(time_t* t)
-{
- log_now = t;
-}
-
void log_set_time_asc(int use_asc)
{
log_time_asc = use_asc;
@@ -255,9 +248,7 @@ log_vmsg(int pri, const char* type,
lock_quick_unlock(&log_lock);
return;
}
- if(log_now)
- now = (time_t)*log_now;
- else now = (time_t)time(NULL);
+ now = (time_t)time(NULL);
#if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R)
if(log_time_asc && strftime(tmbuf, sizeof(tmbuf), "%b %d %H:%M:%S",
localtime_r(&now, &tm))%(sizeof(tmbuf)) != 0) {
@@ -391,6 +382,24 @@ log_hex(const char* msg, void* data, size_t length)
log_hex_f(verbosity, msg, data, length);
}
+void
+log_query(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ log_vmsg(LOG_INFO, "query", format, args);
+ va_end(args);
+}
+
+void
+log_reply(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ log_vmsg(LOG_INFO, "reply", format, args);
+ va_end(args);
+}
+
void log_buf(enum verbosity_value level, const char* msg, sldns_buffer* buf)
{
if(verbosity < level)
diff --git a/contrib/unbound/util/log.h b/contrib/unbound/util/log.h
index f73c0754d657..81d9d837d72b 100644
--- a/contrib/unbound/util/log.h
+++ b/contrib/unbound/util/log.h
@@ -113,13 +113,6 @@ int log_thread_get(void);
void log_ident_set(const char* id);
/**
- * Set the time value to print in log entries.
- * @param t: the point is copied and used to find the time.
- * if NULL, time(2) is used.
- */
-void log_set_time(time_t* t);
-
-/**
* Set if the time value is printed ascii or decimal in log entries.
* @param use_asc: if true, ascii is printed, otherwise decimal.
* If the conversion fails or you have no time functions,
@@ -161,6 +154,20 @@ void log_warn(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
void log_hex(const char* msg, void* data, size_t length);
/**
+ * Log query.
+ * Pass printf formatted arguments. No trailing newline is needed.
+ * @param format: printf-style format string. Arguments follow.
+ */
+void log_query(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+
+/**
+ * Log reply.
+ * Pass printf formatted arguments. No trailing newline is needed.
+ * @param format: printf-style format string. Arguments follow.
+ */
+void log_reply(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+
+/**
* Easy alternative for log_hex, takes a sldns_buffer.
* @param level: verbosity level for this message, compared to global
* verbosity setting.
diff --git a/contrib/unbound/util/mini_event.c b/contrib/unbound/util/mini_event.c
index 14e9efe4790d..faadf1a23c8d 100644
--- a/contrib/unbound/util/mini_event.c
+++ b/contrib/unbound/util/mini_event.c
@@ -41,6 +41,7 @@
*/
#include "config.h"
+#include "util/mini_event.h"
#ifdef HAVE_TIME_H
#include <time.h>
#endif
@@ -48,7 +49,6 @@
#if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK)
#include <signal.h>
-#include "util/mini_event.h"
#include "util/fptr_wlist.h"
/** compare events in tree, based on timevalue, ptr for uniqueness */
diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c
index 91368c847597..13bcdf8085bf 100644
--- a/contrib/unbound/util/net_help.c
+++ b/contrib/unbound/util/net_help.c
@@ -43,11 +43,14 @@
#include "util/data/dname.h"
#include "util/module.h"
#include "util/regional.h"
+#include "util/config_file.h"
#include "sldns/parseutil.h"
#include "sldns/wire2str.h"
#include <fcntl.h>
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
#endif
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
@@ -67,6 +70,15 @@ int MINIMAL_RESPONSES = 0;
/** rrset order roundrobin: default is no */
int RRSET_ROUNDROBIN = 0;
+/** log tag queries with name instead of 'info' for filtering */
+int LOG_TAG_QUERYREPLY = 0;
+
+static struct tls_session_ticket_key {
+ unsigned char *key_name;
+ unsigned char *aes_key;
+ unsigned char *hmac_key;
+} *ticket_keys;
+
/* returns true is string addr is an ip6 specced address */
int
str_is_ip6(const char* str)
@@ -361,6 +373,37 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
log_info("%s %s %s %s", str, buf, ts, cs);
}
+void
+log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass)
+{
+ char buf[LDNS_MAX_DOMAINLEN+1];
+ char t[12], c[12];
+ const char *ts, *cs;
+ dname_str(name, buf);
+ if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";
+ else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";
+ else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";
+ else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";
+ else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";
+ else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";
+ else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name)
+ ts = sldns_rr_descript(type)->_name;
+ else {
+ snprintf(t, sizeof(t), "TYPE%d", (int)type);
+ ts = t;
+ }
+ if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) &&
+ sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name)
+ cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name;
+ else {
+ snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
+ cs = c;
+ }
+ if(LOG_TAG_QUERYREPLY)
+ log_query("%s %s %s %s", str, buf, ts, cs);
+ else log_info("%s %s %s %s", str, buf, ts, cs);
+}
+
void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
struct sockaddr_storage* addr, socklen_t addrlen)
{
@@ -759,6 +802,16 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem)
log_crypto_err("could not SSL_CTX_new");
return NULL;
}
+ if(!key || key[0] == 0) {
+ log_err("error: no tls-service-key file specified");
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ if(!pem || pem[0] == 0) {
+ log_err("error: no tls-service-pem file specified");
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
if(!listen_sslctx_setup(ctx)) {
SSL_CTX_free(ctx);
return NULL;
@@ -1006,11 +1059,19 @@ void* outgoing_ssl_fd(void* sslctx, int fd)
static lock_basic_type *ub_openssl_locks = NULL;
/** callback that gets thread id for openssl */
+#ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK
+static void
+ub_crypto_id_cb(CRYPTO_THREADID *id)
+{
+ CRYPTO_THREADID_set_numeric(id, (unsigned long)log_thread_get());
+}
+#else
static unsigned long
ub_crypto_id_cb(void)
{
return (unsigned long)log_thread_get();
}
+#endif
static void
ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
@@ -1035,7 +1096,11 @@ int ub_openssl_lock_init(void)
for(i=0; i<CRYPTO_num_locks(); i++) {
lock_basic_init(&ub_openssl_locks[i]);
}
+# ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK
+ CRYPTO_THREADID_set_callback(&ub_crypto_id_cb);
+# else
CRYPTO_set_id_callback(&ub_crypto_id_cb);
+# endif
CRYPTO_set_locking_callback(&ub_crypto_lock_cb);
#endif /* OPENSSL_THREADS */
return 1;
@@ -1047,7 +1112,11 @@ void ub_openssl_lock_delete(void)
int i;
if(!ub_openssl_locks)
return;
+# ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK
+ CRYPTO_THREADID_set_callback(NULL);
+# else
CRYPTO_set_id_callback(NULL);
+# endif
CRYPTO_set_locking_callback(NULL);
for(i=0; i<CRYPTO_num_locks(); i++) {
lock_basic_destroy(&ub_openssl_locks[i]);
@@ -1056,3 +1125,134 @@ void ub_openssl_lock_delete(void)
#endif /* OPENSSL_THREADS */
}
+int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys) {
+#ifdef HAVE_SSL
+ size_t s = 1;
+ struct config_strlist* p;
+ struct tls_session_ticket_key *keys;
+ for(p = tls_session_ticket_keys; p; p = p->next) {
+ s++;
+ }
+ keys = calloc(s, sizeof(struct tls_session_ticket_key));
+ memset(keys, 0, s*sizeof(*keys));
+ ticket_keys = keys;
+
+ for(p = tls_session_ticket_keys; p; p = p->next) {
+ size_t n;
+ unsigned char *data = (unsigned char *)malloc(80);
+ FILE *f = fopen(p->str, "r");
+ if(!f) {
+ log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno));
+ free(data);
+ return 0;
+ }
+ n = fread(data, 1, 80, f);
+ fclose(f);
+
+ if(n != 80) {
+ log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", p->str, (int)n);
+ free(data);
+ return 0;
+ }
+ verbose(VERB_OPS, "read tls-session-ticket-key: %s", p->str);
+
+ keys->key_name = data;
+ keys->aes_key = data + 16;
+ keys->hmac_key = data + 48;
+ keys++;
+ }
+ /* terminate array with NULL key name entry */
+ keys->key_name = NULL;
+ if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) {
+ log_err("no support for TLS session ticket");
+ return 0;
+ }
+ return 1;
+#else
+ (void)sslctx;
+ (void)tls_session_ticket_keys;
+ return 0;
+#endif
+
+}
+
+int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name, unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc)
+{
+#ifdef HAVE_SSL
+ const EVP_MD *digest;
+ const EVP_CIPHER *cipher;
+ int evp_cipher_length;
+ digest = EVP_sha256();
+ cipher = EVP_aes_256_cbc();
+ evp_cipher_length = EVP_CIPHER_iv_length(cipher);
+ if( enc == 1 ) {
+ /* encrypt */
+ verbose(VERB_CLIENT, "start session encrypt");
+ memcpy(key_name, ticket_keys->key_name, 16);
+ if (RAND_bytes(iv, evp_cipher_length) != 1) {
+ verbose(VERB_CLIENT, "RAND_bytes failed");
+ return -1;
+ }
+ if (EVP_EncryptInit_ex(evp_sctx, cipher, NULL, ticket_keys->aes_key, iv) != 1) {
+ verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed");
+ return -1;
+ }
+ if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) {
+ verbose(VERB_CLIENT, "HMAC_Init_ex failed");
+ return -1;
+ }
+ return 1;
+ } else if (enc == 0) {
+ /* decrypt */
+ struct tls_session_ticket_key *key;
+ verbose(VERB_CLIENT, "start session decrypt");
+ for(key = ticket_keys; key->key_name != NULL; key++) {
+ if (!memcmp(key_name, key->key_name, 16)) {
+ verbose(VERB_CLIENT, "Found session_key");
+ break;
+ }
+ }
+ if(key->key_name == NULL) {
+ verbose(VERB_CLIENT, "Not found session_key");
+ return 0;
+ }
+
+ if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) {
+ verbose(VERB_CLIENT, "HMAC_Init_ex failed");
+ return -1;
+ }
+ if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) {
+ log_err("EVP_DecryptInit_ex failed");
+ return -1;
+ }
+
+ return (key == ticket_keys) ? 1 : 2;
+ }
+ return -1;
+#else
+ (void)key_name;
+ (void)iv;
+ (void)evp_sctx;
+ (void)hmac_ctx;
+ (void)enc;
+ return 0;
+#endif
+}
+
+void
+listen_sslctx_delete_ticket_keys(void)
+{
+ struct tls_session_ticket_key *key;
+ if(!ticket_keys) return;
+ for(key = ticket_keys; key->key_name != NULL; key++) {
+ /* wipe key data from memory*/
+#ifdef HAVE_EXPLICIT_BZERO
+ explicit_bzero(key->key_name, 80);
+#else
+ memset(key->key_name, 0xdd, 80);
+#endif
+ free(key->key_name);
+ }
+ free(ticket_keys);
+ ticket_keys = NULL;
+}
diff --git a/contrib/unbound/util/net_help.h b/contrib/unbound/util/net_help.h
index de2e1accfd40..0b197fbdd6e7 100644
--- a/contrib/unbound/util/net_help.h
+++ b/contrib/unbound/util/net_help.h
@@ -44,6 +44,7 @@
#include "util/log.h"
struct sock_list;
struct regional;
+struct config_strlist;
/** DNS constants for uint16_t style flag manipulation. host byteorder.
* 1 1 1 1 1 1
@@ -99,6 +100,9 @@ extern int MINIMAL_RESPONSES;
/** rrset order roundrobin */
extern int RRSET_ROUNDROBIN;
+/** log tag queries with name instead of 'info' for filtering */
+extern int LOG_TAG_QUERYREPLY;
+
/**
* See if string is ip4 or ip6.
* @param str: IP specification.
@@ -236,6 +240,12 @@ void log_nametypeclass(enum verbosity_value v, const char* str,
uint8_t* name, uint16_t type, uint16_t dclass);
/**
+ * Like log_nametypeclass, but logs with log_query for query logging
+ */
+void log_query_in(const char* str, uint8_t* name, uint16_t type,
+ uint16_t dclass);
+
+/**
* Compare two sockaddrs. Imposes an ordering on the addresses.
* Compares address and port.
* @param addr1: address 1.
@@ -428,4 +438,30 @@ int ub_openssl_lock_init(void);
*/
void ub_openssl_lock_delete(void);
+/**
+ * setup TLS session ticket
+ * @param sslctx: the SSL_CTX to use (from connect_sslctx_create())
+ * @param tls_session_ticket_keys: TLS ticket secret filenames
+ * @return false on failure (alloc failure).
+ */
+int listen_sslctx_setup_ticket_keys(void* sslctx,
+ struct config_strlist* tls_session_ticket_keys);
+
+/**
+ * callback TLS session ticket encrypt and decrypt
+ * For use with SSL_CTX_set_tlsext_ticket_key_cb
+ * @param s: the SSL_CTX to use (from connect_sslctx_create())
+ * @param key_name: secret name, 16 bytes
+ * @param iv: up to EVP_MAX_IV_LENGTH.
+ * @param evp_ctx: the evp cipher context, function sets this.
+ * @param hmac_ctx: the hmax context, function sets this.
+ * @param enc: 1 is encrypt, 0 is decrypt
+ * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket
+ * (the ticket is decrypt only). and <0 for failures.
+ */
+int tls_session_ticket_key_cb(void *s, unsigned char* key_name,unsigned char* iv, void *evp_ctx, void *hmac_ctx, int enc);
+
+/** Free memory used for TLS session ticket keys */
+void listen_sslctx_delete_ticket_keys(void);
+
#endif /* NET_HELP_H */
diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c
index 373538041420..9e2ba92b5fdf 100644
--- a/contrib/unbound/util/netevent.c
+++ b/contrib/unbound/util/netevent.c
@@ -50,6 +50,7 @@
#include "sldns/str2wire.h"
#include "dnstap/dnstap.h"
#include "dnscrypt/dnscrypt.h"
+#include "services/listen_dnsport.h"
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
@@ -150,7 +151,8 @@ struct internal_signal {
/** create a tcp handler with a parent */
static struct comm_point* comm_point_create_tcp_handler(
struct comm_base *base, struct comm_point* parent, size_t bufsize,
- comm_point_callback_type* callback, void* callback_arg);
+ struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+ void* callback_arg);
/* -------- End of local definitions -------- */
@@ -176,7 +178,7 @@ comm_base_create(int sigs)
}
ub_comm_base_now(b);
ub_get_event_sys(b->eb->base, &evnm, &evsys, &evmethod);
- verbose(VERB_ALGO, "%s %s user %s method.", evnm, evsys, evmethod);
+ verbose(VERB_ALGO, "%s %s uses %s method.", evnm, evsys, evmethod);
return b;
}
@@ -924,6 +926,14 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
}
/* accept incoming connection. */
c_hdl = c->tcp_free;
+ /* clear leftover flags from previous use, and then set the
+ * correct event base for the event structure for libevent */
+ ub_event_free(c_hdl->ev->ev);
+ c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1, UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT, comm_point_tcp_handle_callback, c_hdl);
+ if(!c_hdl->ev->ev) {
+ log_warn("could not ub_event_new, dropped tcp");
+ return;
+ }
log_assert(fd != -1);
(void)fd;
new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr,
@@ -987,8 +997,12 @@ tcp_callback_writer(struct comm_point* c)
c->tcp_is_reading = 1;
c->tcp_byte_count = 0;
/* switch from listening(write) to listening(read) */
- comm_point_stop_listening(c);
- comm_point_start_listening(c, -1, -1);
+ if(c->tcp_req_info) {
+ tcp_req_info_handle_writedone(c->tcp_req_info);
+ } else {
+ comm_point_stop_listening(c);
+ comm_point_start_listening(c, -1, -1);
+ }
}
/** do the callback when reading is done */
@@ -1000,11 +1014,15 @@ tcp_callback_reader(struct comm_point* c)
if(c->tcp_do_toggle_rw)
c->tcp_is_reading = 0;
c->tcp_byte_count = 0;
- if(c->type == comm_tcp)
- comm_point_stop_listening(c);
- fptr_ok(fptr_whitelist_comm_point(c->callback));
- if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
- comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+ if(c->tcp_req_info) {
+ tcp_req_info_handle_readdone(c->tcp_req_info);
+ } else {
+ if(c->type == comm_tcp)
+ comm_point_stop_listening(c);
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
+ comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+ }
}
}
@@ -1163,6 +1181,8 @@ ssl_handle_read(struct comm_point* c)
c->tcp_byte_count))) <= 0) {
int want = SSL_get_error(c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
return 0; /* shutdown, closed */
} else if(want == SSL_ERROR_WANT_READ) {
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
@@ -1172,6 +1192,10 @@ ssl_handle_read(struct comm_point* c)
comm_point_listen_for_rw(c, 0, 1);
return 1;
} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef ECONNRESET
+ if(errno == ECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
+#endif
if(errno != 0)
log_err("SSL_read syscall: %s",
strerror(errno));
@@ -1205,6 +1229,8 @@ ssl_handle_read(struct comm_point* c)
if(r <= 0) {
int want = SSL_get_error(c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
return 0; /* shutdown, closed */
} else if(want == SSL_ERROR_WANT_READ) {
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
@@ -1214,6 +1240,10 @@ ssl_handle_read(struct comm_point* c)
comm_point_listen_for_rw(c, 0, 1);
return 1;
} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef ECONNRESET
+ if(errno == ECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
+#endif
if(errno != 0)
log_err("SSL_read syscall: %s",
strerror(errno));
@@ -1274,13 +1304,17 @@ ssl_handle_write(struct comm_point* c)
if(want == SSL_ERROR_ZERO_RETURN) {
return 0; /* closed */
} else if(want == SSL_ERROR_WANT_READ) {
- c->ssl_shake_state = comm_ssl_shake_read;
+ c->ssl_shake_state = comm_ssl_shake_hs_read;
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef EPIPE
+ if(errno == EPIPE && verbosity < 2)
+ return 0; /* silence 'broken pipe' */
+#endif
if(errno != 0)
log_err("SSL_write syscall: %s",
strerror(errno));
@@ -1308,13 +1342,17 @@ ssl_handle_write(struct comm_point* c)
if(want == SSL_ERROR_ZERO_RETURN) {
return 0; /* closed */
} else if(want == SSL_ERROR_WANT_READ) {
- c->ssl_shake_state = comm_ssl_shake_read;
+ c->ssl_shake_state = comm_ssl_shake_hs_read;
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef EPIPE
+ if(errno == EPIPE && verbosity < 2)
+ return 0; /* silence 'broken pipe' */
+#endif
if(errno != 0)
log_err("SSL_write syscall: %s",
strerror(errno));
@@ -1365,9 +1403,11 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
/* read length bytes */
r = recv(fd,(void*)sldns_buffer_at(c->buffer,c->tcp_byte_count),
sizeof(uint16_t)-c->tcp_byte_count, 0);
- if(r == 0)
+ if(r == 0) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
return 0;
- else if(r == -1) {
+ } else if(r == -1) {
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1;
@@ -1416,6 +1456,8 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
r = recv(fd, (void*)sldns_buffer_current(c->buffer),
sldns_buffer_remaining(c->buffer), 0);
if(r == 0) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
return 0;
} else if(r == -1) {
#ifndef USE_WINSOCK
@@ -1525,7 +1567,6 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
iov[1].iov_base = sldns_buffer_begin(buffer);
iov[1].iov_len = sldns_buffer_limit(buffer);
log_assert(iov[0].iov_len > 0);
- log_assert(iov[1].iov_len > 0);
msg.msg_name = &c->repinfo.addr;
msg.msg_namelen = c->repinfo.addrlen;
msg.msg_iov = iov;
@@ -1592,7 +1633,6 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
iov[1].iov_base = sldns_buffer_begin(buffer);
iov[1].iov_len = sldns_buffer_limit(buffer);
log_assert(iov[0].iov_len > 0);
- log_assert(iov[1].iov_len > 0);
r = writev(fd, iov, 2);
#else /* HAVE_WRITEV */
r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count),
@@ -1606,6 +1646,10 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
#endif
if(errno == EINTR || errno == EAGAIN)
return 1;
+#ifdef ECONNRESET
+ if(errno == ECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
+#endif
# ifdef HAVE_WRITEV
log_err_addr("tcp writev", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
@@ -1623,6 +1667,8 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
UB_EV_WRITE);
return 1;
}
+ if(WSAGetLastError() == WSAECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
log_err_addr("tcp send s",
wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
@@ -1646,6 +1692,10 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1;
+#ifdef ECONNRESET
+ if(errno == ECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
+#endif
log_err_addr("tcp send r", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
#else
@@ -1655,6 +1705,8 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1;
}
+ if(WSAGetLastError() == WSAECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
#endif
@@ -1669,6 +1721,29 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
return 1;
}
+/** read again to drain buffers when there could be more to read */
+static void
+tcp_req_info_read_again(int fd, struct comm_point* c)
+{
+ while(c->tcp_req_info->read_again) {
+ int r;
+ c->tcp_req_info->read_again = 0;
+ if(c->tcp_is_reading)
+ r = comm_point_tcp_handle_read(fd, c, 0);
+ else r = comm_point_tcp_handle_write(fd, c);
+ if(!r) {
+ reclaim_tcp_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(
+ c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_CLOSED, NULL);
+ }
+ return;
+ }
+ }
+}
+
void
comm_point_tcp_handle_callback(int fd, short event, void* arg)
{
@@ -1697,7 +1772,18 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
#endif
+ if(event&UB_EV_TIMEOUT) {
+ verbose(VERB_QUERY, "tcp took too long, dropped");
+ reclaim_tcp_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_TIMEOUT, NULL);
+ }
+ return;
+ }
if(event&UB_EV_READ) {
+ int has_tcpq = (c->tcp_req_info != NULL);
if(!comm_point_tcp_handle_read(fd, c, 0)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@@ -1707,9 +1793,12 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
NETEVENT_CLOSED, NULL);
}
}
+ if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
+ tcp_req_info_read_again(fd, c);
return;
}
if(event&UB_EV_WRITE) {
+ int has_tcpq = (c->tcp_req_info != NULL);
if(!comm_point_tcp_handle_write(fd, c)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@@ -1719,16 +1808,8 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
NETEVENT_CLOSED, NULL);
}
}
- return;
- }
- if(event&UB_EV_TIMEOUT) {
- verbose(VERB_QUERY, "tcp took too long, dropped");
- reclaim_tcp_handler(c);
- if(!c->tcp_do_close) {
- fptr_ok(fptr_whitelist_comm_point(c->callback));
- (void)(*c->callback)(c, c->cb_arg,
- NETEVENT_TIMEOUT, NULL);
- }
+ if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
+ tcp_req_info_read_again(fd, c);
return;
}
log_err("Ignored event %d for tcphdl.", event);
@@ -1779,6 +1860,10 @@ ssl_http_read_more(struct comm_point* c)
comm_point_listen_for_rw(c, 0, 1);
return 1;
} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef ECONNRESET
+ if(errno == ECONNRESET && verbosity < 2)
+ return 0; /* silence reset by peer */
+#endif
if(errno != 0)
log_err("SSL_read syscall: %s",
strerror(errno));
@@ -2221,12 +2306,16 @@ ssl_http_write_more(struct comm_point* c)
if(want == SSL_ERROR_ZERO_RETURN) {
return 0; /* closed */
} else if(want == SSL_ERROR_WANT_READ) {
- c->ssl_shake_state = comm_ssl_shake_read;
+ c->ssl_shake_state = comm_ssl_shake_hs_read;
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef EPIPE
+ if(errno == EPIPE && verbosity < 2)
+ return 0; /* silence 'broken pipe' */
+#endif
if(errno != 0)
log_err("SSL_write syscall: %s",
strerror(errno));
@@ -2335,6 +2424,16 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_http);
ub_comm_base_now(c->ev->base);
+ if(event&UB_EV_TIMEOUT) {
+ verbose(VERB_QUERY, "http took too long, dropped");
+ reclaim_http_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_TIMEOUT, NULL);
+ }
+ return;
+ }
if(event&UB_EV_READ) {
if(!comm_point_http_handle_read(fd, c)) {
reclaim_http_handler(c);
@@ -2359,16 +2458,6 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
}
return;
}
- if(event&UB_EV_TIMEOUT) {
- verbose(VERB_QUERY, "http took too long, dropped");
- reclaim_http_handler(c);
- if(!c->tcp_do_close) {
- fptr_ok(fptr_whitelist_comm_point(c->callback));
- (void)(*c->callback)(c, c->cb_arg,
- NETEVENT_TIMEOUT, NULL);
- }
- return;
- }
log_err("Ignored event %d for httphdl.", event);
}
@@ -2523,7 +2612,8 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
static struct comm_point*
comm_point_create_tcp_handler(struct comm_base *base,
struct comm_point* parent, size_t bufsize,
- comm_point_callback_type* callback, void* callback_arg)
+ struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+ void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -2579,6 +2669,20 @@ comm_point_create_tcp_handler(struct comm_base *base,
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
+ if(spoolbuf) {
+ c->tcp_req_info = tcp_req_info_create(spoolbuf);
+ if(!c->tcp_req_info) {
+ log_err("could not create tcp commpoint");
+ sldns_buffer_free(c->buffer);
+ free(c->timeout);
+ free(c->ev);
+ free(c);
+ return NULL;
+ }
+ c->tcp_req_info->cp = c;
+ c->tcp_do_close = 1;
+ c->tcp_do_toggle_rw = 0;
+ }
/* add to parent free list */
c->tcp_free = parent->tcp_free;
parent->tcp_free = c;
@@ -2590,6 +2694,9 @@ comm_point_create_tcp_handler(struct comm_base *base,
{
log_err("could not basetset tcphdl event");
parent->tcp_free = c->tcp_free;
+ tcp_req_info_delete(c->tcp_req_info);
+ sldns_buffer_free(c->buffer);
+ free(c->timeout);
free(c->ev);
free(c);
return NULL;
@@ -2600,7 +2707,8 @@ comm_point_create_tcp_handler(struct comm_base *base,
struct comm_point*
comm_point_create_tcp(struct comm_base *base, int fd, int num,
int idle_timeout, struct tcl_list* tcp_conn_limit, size_t bufsize,
- comm_point_callback_type* callback, void* callback_arg)
+ struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+ void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -2667,7 +2775,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
/* now prealloc the tcp handlers */
for(i=0; i<num; i++) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
- c, bufsize, callback, callback_arg);
+ c, bufsize, spoolbuf, callback, callback_arg);
if(!c->tcp_handlers[i]) {
comm_point_delete(c);
return NULL;
@@ -2949,6 +3057,8 @@ comm_point_close(struct comm_point* c)
}
}
tcl_close_connection(c->tcl_addr);
+ if(c->tcp_req_info)
+ tcp_req_info_clear(c->tcp_req_info);
/* close fd after removing from event lists, or epoll.. is messed up */
if(c->fd != -1 && !c->do_not_close) {
if(c->type == comm_tcp || c->type == comm_http) {
@@ -2992,6 +3102,9 @@ comm_point_delete(struct comm_point* c)
sldns_buffer_free(c->dnscrypt_buffer);
}
#endif
+ if(c->tcp_req_info) {
+ tcp_req_info_delete(c->tcp_req_info);
+ }
}
ub_event_free(c->ev->ev);
free(c->ev);
@@ -3032,8 +3145,12 @@ comm_point_send_reply(struct comm_reply *repinfo)
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
#endif
- comm_point_start_listening(repinfo->c, -1,
- repinfo->c->tcp_timeout_msec);
+ if(repinfo->c->tcp_req_info) {
+ tcp_req_info_send_reply(repinfo->c->tcp_req_info);
+ } else {
+ comm_point_start_listening(repinfo->c, -1,
+ repinfo->c->tcp_timeout_msec);
+ }
}
}
@@ -3046,6 +3163,8 @@ comm_point_drop_reply(struct comm_reply* repinfo)
log_assert(repinfo->c->type != comm_tcp_accept);
if(repinfo->c->type == comm_udp)
return;
+ if(repinfo->c->tcp_req_info)
+ repinfo->c->tcp_req_info->is_drop = 1;
reclaim_tcp_handler(repinfo->c);
}
@@ -3061,8 +3180,8 @@ comm_point_stop_listening(struct comm_point* c)
void
comm_point_start_listening(struct comm_point* c, int newfd, int msec)
{
- verbose(VERB_ALGO, "comm point start listening %d",
- c->fd==-1?newfd:c->fd);
+ verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
+ c->fd==-1?newfd:c->fd, msec);
if(c->type == comm_tcp_accept && !c->tcp_free) {
/* no use to start listening no free slots. */
return;
diff --git a/contrib/unbound/util/netevent.h b/contrib/unbound/util/netevent.h
index f6b6af688b94..d80c72b33431 100644
--- a/contrib/unbound/util/netevent.h
+++ b/contrib/unbound/util/netevent.h
@@ -268,6 +268,9 @@ struct comm_point {
/** the entry for the connection. */
struct tcl_addr* tcl_addr;
+ /** the structure to keep track of open requests on this channel */
+ struct tcp_req_info* tcp_req_info;
+
#ifdef USE_MSG_FASTOPEN
/** used to track if the sendto() call should be done when using TFO. */
int tcp_do_fastopen;
@@ -455,6 +458,8 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
* @param idle_timeout: TCP idle timeout in ms.
* @param tcp_conn_limit: TCP connection limit info.
* @param bufsize: size of buffer to create for handlers.
+ * @param spoolbuf: shared spool buffer for tcp_req_info structures.
+ * or NULL to not create those structures in the tcp handlers.
* @param callback: callback function pointer for TCP handlers.
* @param callback_arg: will be passed to your callback function.
* @return: returns the TCP listener commpoint. You can find the
@@ -464,7 +469,8 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
*/
struct comm_point* comm_point_create_tcp(struct comm_base* base,
int fd, int num, int idle_timeout, struct tcl_list* tcp_conn_limit,
- size_t bufsize, comm_point_callback_type* callback, void* callback_arg);
+ size_t bufsize, struct sldns_buffer* spoolbuf,
+ comm_point_callback_type* callback, void* callback_arg);
/**
* Create an outgoing TCP commpoint. No file descriptor is opened, left at -1.
diff --git a/contrib/unbound/util/storage/lookup3.c b/contrib/unbound/util/storage/lookup3.c
index cc110748156f..bb25eb433c94 100644
--- a/contrib/unbound/util/storage/lookup3.c
+++ b/contrib/unbound/util/storage/lookup3.c
@@ -1,4 +1,7 @@
/*
+ May 2019(Wouter) patch to enable the valgrind clean implementation all the
+ time. This enables better security audit and checks, which is better
+ than the speedup. Git issue #30. Renamed the define ARRAY_CLEAN_ACCESS.
February 2013(Wouter) patch defines for BSD endianness, from Brad Smith.
January 2012(Wouter) added randomised initial value, fallout from 28c3.
March 2007(Wouter) adapted from lookup3.c original, add config.h include.
@@ -44,6 +47,7 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
-------------------------------------------------------------------------------
*/
/*#define SELF_TEST 1*/
+#define ARRAY_CLEAN_ACCESS 1
#include "config.h"
#include "util/storage/lookup3.h"
@@ -336,7 +340,7 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
-#ifdef VALGRIND
+#ifdef ARRAY_CLEAN_ACCESS
const uint8_t *k8;
#endif
@@ -361,7 +365,7 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
* still catch it and complain. The masking trick does make the hash
* noticeably faster for short strings (like English words).
*/
-#ifndef VALGRIND
+#ifndef ARRAY_CLEAN_ACCESS
switch(length)
{
diff --git a/contrib/unbound/util/ub_event.c b/contrib/unbound/util/ub_event.c
index 78481a982055..e097fbc40158 100644
--- a/contrib/unbound/util/ub_event.c
+++ b/contrib/unbound/util/ub_event.c
@@ -295,11 +295,18 @@ ub_event_new(struct ub_event_base* base, int fd, short bits,
if (!ev)
return NULL;
+#ifndef HAVE_EVENT_ASSIGN
event_set(ev, fd, NATIVE_BITS(bits), NATIVE_BITS_CB(cb), arg);
if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
free(ev);
return NULL;
}
+#else
+ if (event_assign(ev, AS_EVENT_BASE(base), fd, bits, cb, arg) != 0) {
+ free(ev);
+ return NULL;
+ }
+#endif
return AS_UB_EVENT(ev);
}
@@ -312,11 +319,18 @@ ub_signal_new(struct ub_event_base* base, int fd,
if (!ev)
return NULL;
+#if !HAVE_DECL_EVSIGNAL_ASSIGN
signal_set(ev, fd, NATIVE_BITS_CB(cb), arg);
if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
free(ev);
return NULL;
}
+#else
+ if (evsignal_assign(ev, AS_EVENT_BASE(base), fd, cb, arg) != 0) {
+ free(ev);
+ return NULL;
+ }
+#endif
return AS_UB_EVENT(ev);
}