summaryrefslogtreecommitdiff
path: root/contrib/unbound/util
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2016-09-29 18:24:29 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2016-09-29 18:24:29 +0000
commitb5663de9eb877cb7ebb54c4ae4eb81007bb17df4 (patch)
treec71a63b65af86d3bb13a920be50d4e4c00d96647 /contrib/unbound/util
parent863ef2ca62df17d196f6b9c642b607910b28864f (diff)
parent27c2fff0f2fef695b0599fc3931cacfc16376e88 (diff)
downloadsrc-test2-b5663de9eb877cb7ebb54c4ae4eb81007bb17df4.tar.gz
src-test2-b5663de9eb877cb7ebb54c4ae4eb81007bb17df4.zip
Notes
Diffstat (limited to 'contrib/unbound/util')
-rw-r--r--contrib/unbound/util/alloc.c4
-rw-r--r--contrib/unbound/util/config_file.c70
-rw-r--r--contrib/unbound/util/config_file.h53
-rw-r--r--contrib/unbound/util/configlexer.lex8
-rw-r--r--contrib/unbound/util/configparser.y104
-rw-r--r--contrib/unbound/util/iana_ports.inc3
-rw-r--r--contrib/unbound/util/net_help.c6
-rw-r--r--contrib/unbound/util/netevent.c110
-rw-r--r--contrib/unbound/util/netevent.h13
-rw-r--r--contrib/unbound/util/storage/dnstree.c13
-rw-r--r--contrib/unbound/util/storage/dnstree.h11
-rw-r--r--contrib/unbound/util/storage/lookup3.c10
-rw-r--r--contrib/unbound/util/ub_event.c16
-rw-r--r--contrib/unbound/util/ub_event_pluggable.c16
-rw-r--r--contrib/unbound/util/winsock_event.c5
15 files changed, 385 insertions, 57 deletions
diff --git a/contrib/unbound/util/alloc.c b/contrib/unbound/util/alloc.c
index 05d2fa36207b..a1152a7cf9fa 100644
--- a/contrib/unbound/util/alloc.c
+++ b/contrib/unbound/util/alloc.c
@@ -64,7 +64,7 @@ alloc_setup_special(alloc_special_t* t)
* @param alloc: the structure to fill up.
*/
static void
-prealloc(struct alloc_cache* alloc)
+prealloc_setup(struct alloc_cache* alloc)
{
alloc_special_t* p;
int i;
@@ -216,7 +216,7 @@ alloc_special_obtain(struct alloc_cache* alloc)
}
}
/* allocate new */
- prealloc(alloc);
+ prealloc_setup(alloc);
if(!(p = (alloc_special_t*)malloc(sizeof(alloc_special_t)))) {
log_err("alloc_special_obtain: out of memory");
return NULL;
diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c
index 2b79bd9a859a..688211c2bf84 100644
--- a/contrib/unbound/util/config_file.c
+++ b/contrib/unbound/util/config_file.c
@@ -212,6 +212,7 @@ config_create(void)
cfg->local_zones = NULL;
cfg->local_zones_nodefault = NULL;
cfg->local_data = NULL;
+ cfg->local_zone_overrides = NULL;
cfg->unblock_lan_zones = 0;
cfg->insecure_lan_zones = 0;
cfg->python_script = NULL;
@@ -640,6 +641,14 @@ config_collate_cat(struct config_strlist* list)
func(buf, arg); \
} \
}
+/** compare and print list option */
+#define O_LS3(opt, name, lst) if(strcmp(opt, name)==0) { \
+ struct config_str3list* p = cfg->lst; \
+ for(p = cfg->lst; p; p = p->next) { \
+ snprintf(buf, len, "%s %s %s", p->str, p->str2, p->str3); \
+ func(buf, arg); \
+ } \
+ }
/** compare and print taglist option */
#define O_LTG(opt, name, lst) if(strcmp(opt, name)==0) { \
char* tmpstr = NULL; \
@@ -784,6 +793,10 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "qname-minimisation", qname_minimisation)
else O_IFC(opt, "define-tag", num_tags, tagname)
else O_LTG(opt, "local-zone-tag", local_zone_tags)
+ else O_LTG(opt, "access-control-tag", acl_tags)
+ else O_LS3(opt, "local-zone-override", local_zone_overrides)
+ else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
+ else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
/* not here:
* outgoing-permit, outgoing-avoid - have list of ports
* local-zone - zones and nodefault variables
@@ -936,6 +949,20 @@ config_deldblstrlist(struct config_str2list* p)
}
void
+config_deltrplstrlist(struct config_str3list* p)
+{
+ struct config_str3list *np;
+ while(p) {
+ np = p->next;
+ free(p->str);
+ free(p->str2);
+ free(p->str3);
+ free(p);
+ p = np;
+ }
+}
+
+void
config_delstub(struct config_stub* p)
{
if(!p) return;
@@ -969,8 +996,7 @@ config_del_strarray(char** array, int num)
free(array);
}
-/** delete stringbytelist */
-static void
+void
config_del_strbytelist(struct config_strbytelist* p)
{
struct config_strbytelist* np;
@@ -1020,8 +1046,12 @@ config_delete(struct config_file* cfg)
config_deldblstrlist(cfg->local_zones);
config_delstrlist(cfg->local_zones_nodefault);
config_delstrlist(cfg->local_data);
+ config_deltrplstrlist(cfg->local_zone_overrides);
config_del_strarray(cfg->tagname, cfg->num_tags);
config_del_strbytelist(cfg->local_zone_tags);
+ config_del_strbytelist(cfg->acl_tags);
+ config_deltrplstrlist(cfg->acl_tag_actions);
+ config_deltrplstrlist(cfg->acl_tag_datas);
config_delstrlist(cfg->control_ifs);
free(cfg->server_key_file);
free(cfg->server_cert_file);
@@ -1180,6 +1210,23 @@ int cfg_strlist_append(struct config_strlist_head* list, char* item)
}
int
+cfg_region_strlist_insert(struct regional* region,
+ struct config_strlist** head, char* item)
+{
+ struct config_strlist *s;
+ if(!item || !head)
+ return 0;
+ s = (struct config_strlist*)regional_alloc_zero(region,
+ sizeof(struct config_strlist));
+ if(!s)
+ return 0;
+ s->str = item;
+ s->next = *head;
+ *head = s;
+ return 1;
+}
+
+int
cfg_strlist_insert(struct config_strlist** head, char* item)
{
struct config_strlist *s;
@@ -1210,6 +1257,24 @@ cfg_str2list_insert(struct config_str2list** head, char* item, char* i2)
return 1;
}
+int
+cfg_str3list_insert(struct config_str3list** head, char* item, char* i2,
+ char* i3)
+{
+ struct config_str3list *s;
+ if(!item || !i2 || !i3 || !head)
+ return 0;
+ s = (struct config_str3list*)calloc(1, sizeof(struct config_str3list));
+ if(!s)
+ return 0;
+ s->str = item;
+ s->str2 = i2;
+ s->str3 = i3;
+ s->next = *head;
+ *head = s;
+ return 1;
+}
+
int
cfg_strbytelist_insert(struct config_strbytelist** head, char* item,
uint8_t* i2, size_t i2len)
@@ -1373,6 +1438,7 @@ cfg_set_bit(uint8_t* bitlist, size_t len, int id)
{
int pos = id/8;
log_assert((size_t)pos < len);
+ (void)len;
bitlist[pos] |= 1<<(id%8);
}
diff --git a/contrib/unbound/util/config_file.h b/contrib/unbound/util/config_file.h
index a51cdb464c0c..07edff7b4cf4 100644
--- a/contrib/unbound/util/config_file.h
+++ b/contrib/unbound/util/config_file.h
@@ -44,10 +44,12 @@
struct config_stub;
struct config_strlist;
struct config_str2list;
+struct config_str3list;
struct config_strbytelist;
struct module_qstate;
struct sock_list;
struct ub_packed_rrset_key;
+struct regional;
/**
* The configuration options.
@@ -73,6 +75,8 @@ struct config_file {
int do_ip4;
/** do ip6 query support. */
int do_ip6;
+ /** prefer ip6 upstream queries. */
+ int prefer_ip6;
/** do udp query support. */
int do_udp;
/** do tcp query support. */
@@ -292,12 +296,20 @@ struct config_file {
struct config_strlist* local_zones_nodefault;
/** local data RRs configured */
struct config_strlist* local_data;
+ /** local zone override types per netblock */
+ struct config_str3list* local_zone_overrides;
/** unblock lan zones (reverse lookups for AS112 zones) */
int unblock_lan_zones;
/** insecure lan zones (don't validate AS112 zones) */
int insecure_lan_zones;
/** list of zonename, tagbitlist */
struct config_strbytelist* local_zone_tags;
+ /** list of aclname, tagbitlist */
+ struct config_strbytelist* acl_tags;
+ /** list of aclname, tagname, localzonetype */
+ struct config_str3list* acl_tag_actions;
+ /** list of aclname, tagname, redirectdata */
+ struct config_str3list* acl_tag_datas;
/** tag list, array with tagname[i] is malloced string */
char** tagname;
/** number of items in the taglist */
@@ -434,6 +446,21 @@ struct config_str2list {
};
/**
+ * List of three strings for config options
+ */
+struct config_str3list {
+ /** next item in list */
+ struct config_str3list* next;
+ /** first string */
+ char* str;
+ /** second string */
+ char* str2;
+ /** third string */
+ char* str3;
+};
+
+
+/**
* List of string, bytestring for config options
*/
struct config_strbytelist {
@@ -575,6 +602,10 @@ int cfg_strlist_append(struct config_strlist_head* list, char* item);
*/
int cfg_strlist_insert(struct config_strlist** head, char* item);
+/** insert with region for allocation. */
+int cfg_region_strlist_insert(struct regional* region,
+ struct config_strlist** head, char* item);
+
/**
* Insert string into str2list.
* @param head: pointer to str2list head variable.
@@ -585,8 +616,19 @@ int cfg_strlist_insert(struct config_strlist** head, char* item);
int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2);
/**
+ * Insert string into str3list.
+ * @param head: pointer to str3list head variable.
+ * @param item: new item. malloced by caller. If NULL the insertion fails.
+ * @param i2: 2nd string, malloced by caller. If NULL the insertion fails.
+ * @param i3: 3rd string, malloced by caller. If NULL the insertion fails.
+ * @return: true on success.
+ */
+int cfg_str3list_insert(struct config_str3list** head, char* item, char* i2,
+ char* i3);
+
+/**
* Insert string into strbytelist.
- * @param head: pointer to str2list head variable.
+ * @param head: pointer to strbytelist head variable.
* @param item: new item. malloced by caller. If NULL the insertion fails.
* @param i2: 2nd string, malloced by caller. If NULL the insertion fails.
* @param i2len: length of the i2 bytestring.
@@ -619,6 +661,15 @@ void config_delstrlist(struct config_strlist* list);
void config_deldblstrlist(struct config_str2list* list);
/**
+ * Delete items in config triple string list.
+ * @param list: list.
+ */
+void config_deltrplstrlist(struct config_str3list* list);
+
+/** delete stringbytelist */
+void config_del_strbytelist(struct config_strbytelist* list);
+
+/**
* Delete a stub item
* @param p: stub item
*/
diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex
index 852733b559be..a8d4a96638c3 100644
--- a/contrib/unbound/util/configlexer.lex
+++ b/contrib/unbound/util/configlexer.lex
@@ -9,6 +9,9 @@
*/
#include "config.h"
+/* because flex keeps having sign-unsigned compare problems that are unfixed*/
+#pragma GCC diagnostic ignored "-Wsign-compare"
+
#include <ctype.h>
#include <string.h>
#include <strings.h>
@@ -218,6 +221,7 @@ outgoing-num-tcp{COLON} { YDVAR(1, VAR_OUTGOING_NUM_TCP) }
incoming-num-tcp{COLON} { YDVAR(1, VAR_INCOMING_NUM_TCP) }
do-ip4{COLON} { YDVAR(1, VAR_DO_IP4) }
do-ip6{COLON} { YDVAR(1, VAR_DO_IP6) }
+prefer-ip6{COLON} { YDVAR(1, VAR_PREFER_IP6) }
do-udp{COLON} { YDVAR(1, VAR_DO_UDP) }
do-tcp{COLON} { YDVAR(1, VAR_DO_TCP) }
tcp-upstream{COLON} { YDVAR(1, VAR_TCP_UPSTREAM) }
@@ -347,6 +351,10 @@ dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
define-tag{COLON} { YDVAR(1, VAR_DEFINE_TAG) }
local-zone-tag{COLON} { YDVAR(2, VAR_LOCAL_ZONE_TAG) }
+access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
+access-control-tag-action{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) }
+access-control-tag-data{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) }
+local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) }
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) }
diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y
index 4ff18f0ce5c7..7240ee4bdd00 100644
--- a/contrib/unbound/util/configparser.y
+++ b/contrib/unbound/util/configparser.y
@@ -69,7 +69,7 @@ extern struct config_parser_state* cfg_parser;
%token <str> STRING_ARG
%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
%token VAR_OUTGOING_RANGE VAR_INTERFACE
-%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
+%token VAR_DO_IP4 VAR_DO_IP6 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS
%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
@@ -126,6 +126,8 @@ extern struct config_parser_state* cfg_parser;
%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
%token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG
+%token VAR_ACCESS_CONTROL_TAG VAR_LOCAL_ZONE_OVERRIDE
+%token VAR_ACCESS_CONTROL_TAG_ACTION VAR_ACCESS_CONTROL_TAG_DATA
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -144,7 +146,8 @@ contents_server: contents_server content_server
| ;
content_server: server_num_threads | server_verbosity | server_port |
server_outgoing_range | server_do_ip4 |
- server_do_ip6 | server_do_udp | server_do_tcp |
+ server_do_ip6 | server_prefer_ip6 |
+ server_do_udp | server_do_tcp |
server_tcp_mss | server_outgoing_tcp_mss |
server_interface | server_chroot | server_username |
server_directory | server_logfile | server_pidfile |
@@ -194,7 +197,9 @@ content_server: server_num_threads | server_verbosity | server_port |
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 |
- server_disable_dnssec_lame_check
+ server_disable_dnssec_lame_check | server_access_control_tag |
+ server_local_zone_override | server_access_control_tag_action |
+ server_access_control_tag_data
;
stubstart: VAR_STUB_ZONE
{
@@ -402,6 +407,15 @@ server_do_tcp: VAR_DO_TCP STRING_ARG
free($2);
}
;
+server_prefer_ip6: VAR_PREFER_IP6 STRING_ARG
+ {
+ OUTYY(("P(server_prefer_ip6:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->prefer_ip6 = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_tcp_mss: VAR_TCP_MSS STRING_ARG
{
OUTYY(("P(server_tcp_mss:%s)\n", $2));
@@ -521,6 +535,23 @@ server_directory: VAR_DIRECTORY STRING_ARG
OUTYY(("P(server_directory:%s)\n", $2));
free(cfg_parser->cfg->directory);
cfg_parser->cfg->directory = $2;
+ /* change there right away for includes relative to this */
+ if($2[0]) {
+ char* d;
+#ifdef UB_ON_WINDOWS
+ w_config_adjust_directory(cfg_parser->cfg);
+#endif
+ d = cfg_parser->cfg->directory;
+ /* adjust directory if we have already chroot,
+ * like, we reread after sighup */
+ if(cfg_parser->chroot && cfg_parser->chroot[0] &&
+ strncmp(d, cfg_parser->chroot, strlen(
+ cfg_parser->chroot)) == 0)
+ d += strlen(cfg_parser->chroot);
+ if(chdir(d))
+ log_err("cannot chdir to directory: %s (%s)",
+ d, strerror(errno));
+ }
}
;
server_logfile: VAR_LOGFILE STRING_ARG
@@ -1216,12 +1247,16 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
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_deny")!=0)
+ && strcmp($3, "typetransparent")!=0
+ && strcmp($3, "always_transparent")!=0
+ && strcmp($3, "always_refuse")!=0
+ && strcmp($3, "always_nxdomain")!=0
+ && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
- "typetransparent, inform, inform_deny "
- "or nodefault");
+ "typetransparent, inform, inform_deny, "
+ "always_transparent, always_refuse, "
+ "always_nxdomain or nodefault");
else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->
local_zones_nodefault, $2))
@@ -1332,6 +1367,61 @@ server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG
}
}
;
+server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
+ {
+ size_t len = 0;
+ uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
+ &len);
+ free($3);
+ OUTYY(("P(server_access_control_tag:%s)\n", $2));
+ if(!bitlist)
+ yyerror("could not parse tags, (define-tag them first)");
+ if(bitlist) {
+ if(!cfg_strbytelist_insert(
+ &cfg_parser->cfg->acl_tags,
+ $2, bitlist, len)) {
+ yyerror("out of memory");
+ free($2);
+ }
+ }
+ }
+ ;
+server_access_control_tag_action: VAR_ACCESS_CONTROL_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG
+ {
+ OUTYY(("P(server_access_control_tag_action:%s %s %s)\n", $2, $3, $4));
+ if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_actions,
+ $2, $3, $4)) {
+ yyerror("out of memory");
+ free($2);
+ free($3);
+ free($4);
+ }
+ }
+ ;
+server_access_control_tag_data: VAR_ACCESS_CONTROL_TAG_DATA STRING_ARG STRING_ARG STRING_ARG
+ {
+ OUTYY(("P(server_access_control_tag_data:%s %s %s)\n", $2, $3, $4));
+ if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_datas,
+ $2, $3, $4)) {
+ yyerror("out of memory");
+ free($2);
+ free($3);
+ free($4);
+ }
+ }
+ ;
+server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING_ARG
+ {
+ OUTYY(("P(server_local_zone_override:%s %s %s)\n", $2, $3, $4));
+ if(!cfg_str3list_insert(&cfg_parser->cfg->local_zone_overrides,
+ $2, $3, $4)) {
+ yyerror("out of memory");
+ free($2);
+ free($3);
+ free($4);
+ }
+ }
+ ;
server_ratelimit: VAR_RATELIMIT STRING_ARG
{
OUTYY(("P(server_ratelimit:%s)\n", $2));
diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc
index 3856488ba347..0ac3efb68954 100644
--- a/contrib/unbound/util/iana_ports.inc
+++ b/contrib/unbound/util/iana_ports.inc
@@ -1186,6 +1186,7 @@
1525,
1526,
1527,
+1528,
1529,
1530,
1531,
@@ -4526,7 +4527,6 @@
6786,
6787,
6788,
-6789,
6790,
6791,
6801,
@@ -5425,6 +5425,7 @@
44900,
45000,
45054,
+45514,
45678,
45825,
45966,
diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c
index 5d6c033d6597..248598918b8e 100644
--- a/contrib/unbound/util/net_help.c
+++ b/contrib/unbound/util/net_help.c
@@ -783,7 +783,7 @@ void* outgoing_ssl_fd(void* sslctx, int fd)
#endif
}
-#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
+#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
/** global lock list for openssl locks */
static lock_basic_t *ub_openssl_locks = NULL;
@@ -808,7 +808,7 @@ ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
int ub_openssl_lock_init(void)
{
-#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
+#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
int i;
ub_openssl_locks = (lock_basic_t*)reallocarray(
NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t));
@@ -825,7 +825,7 @@ int ub_openssl_lock_init(void)
void ub_openssl_lock_delete(void)
{
-#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
+#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
int i;
if(!ub_openssl_locks)
return;
diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c
index bdb35739327b..8960b362c78d 100644
--- a/contrib/unbound/util/netevent.c
+++ b/contrib/unbound/util/netevent.c
@@ -80,8 +80,10 @@
# endif
#endif
-/** The TCP reading or writing query timeout in seconds */
-#define TCP_QUERY_TIMEOUT 120
+/** The TCP reading or writing query timeout in milliseconds */
+#define TCP_QUERY_TIMEOUT 120000
+/** The TCP timeout in msec for fast queries, above half are used */
+#define TCP_QUERY_TIMEOUT_FAST 200
#ifndef NONBLOCKING_IS_BROKEN
/** number of UDP reads to perform per read indication from select */
@@ -710,14 +712,20 @@ comm_point_udp_callback(int fd, short event, void* arg)
/** Use a new tcp handler for new query fd, set to read query */
static void
-setup_tcp_handler(struct comm_point* c, int fd)
+setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
{
log_assert(c->type == comm_tcp);
log_assert(c->fd == -1);
sldns_buffer_clear(c->buffer);
c->tcp_is_reading = 1;
c->tcp_byte_count = 0;
- comm_point_start_listening(c, fd, TCP_QUERY_TIMEOUT);
+ c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
+ /* if more than half the tcp handlers are in use, use a shorter
+ * timeout for this TCP connection, we need to make space for
+ * other connections to be able to get attention */
+ if(cur > max/2)
+ c->tcp_timeout_msec = TCP_QUERY_TIMEOUT_FAST;
+ comm_point_start_listening(c, fd, c->tcp_timeout_msec);
}
void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
@@ -769,7 +777,7 @@ int comm_point_perform_accept(struct comm_point* c,
(*b->stop_accept)(b->cb_arg);
/* set timeout, no mallocs */
tv.tv_sec = NETEVENT_SLOW_ACCEPT_TIME/1000;
- tv.tv_usec = NETEVENT_SLOW_ACCEPT_TIME%1000;
+ tv.tv_usec = (NETEVENT_SLOW_ACCEPT_TIME%1000)*1000;
b->eb->slow_accept = ub_event_new(b->eb->base,
-1, UB_EV_TIMEOUT,
comm_base_handle_slow_accept, b);
@@ -862,6 +870,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
/* accept incoming connection. */
c_hdl = c->tcp_free;
log_assert(fd != -1);
+ (void)fd;
new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr,
&c_hdl->repinfo.addrlen);
if(new_fd == -1)
@@ -886,7 +895,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
/* stop accepting incoming queries for now. */
comm_point_stop_listening(c);
}
- setup_tcp_handler(c_hdl, new_fd);
+ setup_tcp_handler(c_hdl, new_fd, c->cur_tcp_count, c->max_tcp_count);
}
/** Make tcp handler free for next assignment */
@@ -940,7 +949,7 @@ tcp_callback_reader(struct comm_point* c)
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, TCP_QUERY_TIMEOUT);
+ comm_point_start_listening(c, -1, c->tcp_timeout_msec);
}
}
@@ -1348,6 +1357,59 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(c->ssl)
return ssl_handle_it(c);
+#ifdef USE_MSG_FASTOPEN
+ /* Only try this on first use of a connection that uses tfo,
+ otherwise fall through to normal write */
+ /* Also, TFO support on WINDOWS not implemented at the moment */
+ if(c->tcp_do_fastopen == 1) {
+ /* this form of sendmsg() does both a connect() and send() so need to
+ look for various flavours of error*/
+ uint16_t len = htons(sldns_buffer_limit(c->buffer));
+ struct msghdr msg;
+ struct iovec iov[2];
+ c->tcp_do_fastopen = 0;
+ memset(&msg, 0, sizeof(msg));
+ iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
+ iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
+ iov[1].iov_base = sldns_buffer_begin(c->buffer);
+ iov[1].iov_len = sldns_buffer_limit(c->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;
+ msg.msg_iovlen = 2;
+ r = sendmsg(fd, &msg, MSG_FASTOPEN);
+ if (r == -1) {
+#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
+ /* Handshake is underway, maybe because no TFO cookie available.
+ Come back to write the messsage*/
+ if(errno == EINPROGRESS || errno == EWOULDBLOCK)
+ return 1;
+#endif
+ if(errno == EINTR || errno == EAGAIN)
+ return 1;
+ /* Not handling EISCONN here as shouldn't ever hit that case.*/
+ if(errno != 0 && verbosity < 2)
+ return 0; /* silence lots of chatter in the logs */
+ else if(errno != 0)
+ log_err_addr("tcp sendmsg", strerror(errno),
+ &c->repinfo.addr, c->repinfo.addrlen);
+ return 0;
+ } else {
+ c->tcp_byte_count += r;
+ if(c->tcp_byte_count < sizeof(uint16_t))
+ return 1;
+ sldns_buffer_set_position(c->buffer, c->tcp_byte_count -
+ sizeof(uint16_t));
+ if(sldns_buffer_remaining(c->buffer) == 0) {
+ tcp_callback_writer(c);
+ return 1;
+ }
+ }
+ }
+#endif /* USE_MSG_FASTOPEN */
+
if(c->tcp_byte_count < sizeof(uint16_t)) {
uint16_t len = htons(sldns_buffer_limit(c->buffer));
#ifdef HAVE_WRITEV
@@ -1540,6 +1602,9 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->inuse = 0;
c->callback = callback;
c->cb_arg = callback_arg;
@@ -1593,6 +1658,9 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
c->inuse = 0;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->callback = callback;
c->cb_arg = callback_arg;
evbits = UB_EV_READ | UB_EV_PERSIST;
@@ -1655,6 +1723,9 @@ comm_point_create_tcp_handler(struct comm_base *base,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
@@ -1715,6 +1786,9 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->callback = NULL;
c->cb_arg = NULL;
evbits = UB_EV_READ | UB_EV_PERSIST;
@@ -1780,6 +1854,9 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1;
c->tcp_check_nb_connect = 1;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 1;
+#endif
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
@@ -1834,6 +1911,9 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
c->do_not_close = 1;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->callback = callback;
c->cb_arg = callback_arg;
/* ub_event stuff */
@@ -1887,6 +1967,9 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
c->do_not_close = 1;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->callback = callback;
c->cb_arg = callback_arg;
/* ub_event stuff */
@@ -1983,7 +2066,8 @@ 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, TCP_QUERY_TIMEOUT);
+ comm_point_start_listening(repinfo->c, -1,
+ repinfo->c->tcp_timeout_msec);
}
}
@@ -2009,7 +2093,7 @@ comm_point_stop_listening(struct comm_point* c)
}
void
-comm_point_start_listening(struct comm_point* c, int newfd, int sec)
+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);
@@ -2017,7 +2101,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
/* no use to start listening no free slots. */
return;
}
- if(sec != -1 && sec != 0) {
+ if(msec != -1 && msec != 0) {
if(!c->timeout) {
c->timeout = (struct timeval*)malloc(sizeof(
struct timeval));
@@ -2028,8 +2112,8 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
}
ub_event_add_bits(c->ev->ev, UB_EV_TIMEOUT);
#ifndef S_SPLINT_S /* splint fails on struct timeval. */
- c->timeout->tv_sec = sec;
- c->timeout->tv_usec = 0;
+ c->timeout->tv_sec = msec/1000;
+ c->timeout->tv_usec = (msec%1000)*1000;
#endif /* S_SPLINT_S */
}
if(c->type == comm_tcp) {
@@ -2049,7 +2133,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
c->fd = newfd;
ub_event_set_fd(c->ev->ev, c->fd);
}
- if(ub_event_add(c->ev->ev, sec==0?NULL:c->timeout) != 0) {
+ if(ub_event_add(c->ev->ev, msec==0?NULL:c->timeout) != 0) {
log_err("event_add failed. in cpsl.");
}
}
diff --git a/contrib/unbound/util/netevent.h b/contrib/unbound/util/netevent.h
index bdcddd848bd0..1d7ac0bc118b 100644
--- a/contrib/unbound/util/netevent.h
+++ b/contrib/unbound/util/netevent.h
@@ -225,9 +225,17 @@ struct comm_point {
So that when that is done the callback is called. */
int tcp_do_toggle_rw;
+ /** timeout in msec for TCP wait times for this connection */
+ int tcp_timeout_msec;
+
/** if set, checks for pending error from nonblocking connect() call.*/
int tcp_check_nb_connect;
+#ifdef USE_MSG_FASTOPEN
+ /** used to track if the sendto() call should be done when using TFO. */
+ int tcp_do_fastopen;
+#endif
+
/** number of queries outstanding on this socket, used by
* outside network for udp ports */
int inuse;
@@ -496,9 +504,10 @@ void comm_point_stop_listening(struct comm_point* c);
* Start listening again for input on the comm point.
* @param c: commpoint to enable again.
* @param newfd: new fd, or -1 to leave fd be.
- * @param sec: timeout in seconds, or -1 for no (change to the) timeout.
+ * @param msec: timeout in milliseconds, or -1 for no (change to the) timeout.
+ * So seconds*1000.
*/
-void comm_point_start_listening(struct comm_point* c, int newfd, int sec);
+void comm_point_start_listening(struct comm_point* c, int newfd, int msec);
/**
* Stop listening and start listening again for reading or writing.
diff --git a/contrib/unbound/util/storage/dnstree.c b/contrib/unbound/util/storage/dnstree.c
index 0df490ee5566..7664c479d47a 100644
--- a/contrib/unbound/util/storage/dnstree.c
+++ b/contrib/unbound/util/storage/dnstree.c
@@ -231,6 +231,19 @@ struct addr_tree_node* addr_tree_lookup(rbtree_t* tree,
return result;
}
+struct addr_tree_node* addr_tree_find(rbtree_t* tree,
+ struct sockaddr_storage* addr, socklen_t addrlen, int net)
+{
+ rbnode_t* res = NULL;
+ struct addr_tree_node key;
+ key.node.key = &key;
+ memcpy(&key.addr, addr, addrlen);
+ key.addrlen = addrlen;
+ key.net = net;
+ res = rbtree_search(tree, &key);
+ return (struct addr_tree_node*)res;
+}
+
int
name_tree_next_root(rbtree_t* tree, uint16_t* dclass)
{
diff --git a/contrib/unbound/util/storage/dnstree.h b/contrib/unbound/util/storage/dnstree.h
index ec8189100f9e..b4595e19ee0f 100644
--- a/contrib/unbound/util/storage/dnstree.h
+++ b/contrib/unbound/util/storage/dnstree.h
@@ -183,6 +183,17 @@ void addr_tree_init_parents(rbtree_t* tree);
struct addr_tree_node* addr_tree_lookup(rbtree_t* tree,
struct sockaddr_storage* addr, socklen_t addrlen);
+/**
+ * Find element in addr tree. (search a netblock, not a match for an address)
+ * @param tree: addr tree
+ * @param addr: netblock to lookup.
+ * @param addrlen: length of addr
+ * @param net: size of subnet
+ * @return addr tree element, or NULL if not found.
+ */
+struct addr_tree_node* addr_tree_find(rbtree_t* tree,
+ struct sockaddr_storage* addr, socklen_t addrlen, int net);
+
/** compare name tree nodes */
int name_tree_compare(const void* k1, const void* k2);
diff --git a/contrib/unbound/util/storage/lookup3.c b/contrib/unbound/util/storage/lookup3.c
index ddcb56e7470f..e9b05af37e31 100644
--- a/contrib/unbound/util/storage/lookup3.c
+++ b/contrib/unbound/util/storage/lookup3.c
@@ -820,7 +820,7 @@ uint32_t hashbig( const void *key, size_t length, uint32_t initval)
#ifdef SELF_TEST
/* used for timings */
-void driver1()
+void driver1(void)
{
uint8_t buf[256];
uint32_t i;
@@ -842,7 +842,7 @@ void driver1()
#define HASHLEN 1
#define MAXPAIR 60
#define MAXLEN 70
-void driver2()
+void driver2(void)
{
uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z;
@@ -912,7 +912,7 @@ void driver2()
}
/* Check for reading beyond the end of the buffer and alignment problems */
-void driver3()
+void driver3(void)
{
uint8_t buf[MAXLEN+20], *b;
uint32_t len;
@@ -1003,7 +1003,7 @@ void driver3()
}
/* check for problems with nulls */
- void driver4()
+ void driver4(void)
{
uint8_t buf[1];
uint32_t h,i,state[HASHSTATE];
@@ -1020,7 +1020,7 @@ void driver3()
}
-int main()
+int main(void)
{
driver1(); /* test that the key is hashed: used for timings */
driver2(); /* test that whole key is hashed thoroughly */
diff --git a/contrib/unbound/util/ub_event.c b/contrib/unbound/util/ub_event.c
index af2a18ea0fc8..3b92be1a3025 100644
--- a/contrib/unbound/util/ub_event.c
+++ b/contrib/unbound/util/ub_event.c
@@ -132,16 +132,12 @@ static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*)
#define EVFLAG_AUTO 0
#endif
-#define AS_EVENT_BASE(x) \
- (((union {struct ub_event_base* a; struct event_base* b;})x).b)
-#define AS_UB_EVENT_BASE(x) \
- (((union {struct event_base* a; struct ub_event_base* b;})x).b)
-#define AS_EVENT(x) \
- (((union {struct ub_event* a; struct event* b;})x).b)
-#define AS_UB_EVENT(x) \
- (((union {struct event* a; struct ub_event* b;})x).b)
-
-const char* ub_event_get_version()
+#define AS_EVENT_BASE(x) ((struct event_base*)x)
+#define AS_UB_EVENT_BASE(x) ((struct ub_event_base*)x)
+#define AS_EVENT(x) ((struct event*)x)
+#define AS_UB_EVENT(x) ((struct ub_event*)x)
+
+const char* ub_event_get_version(void)
{
return event_get_version();
}
diff --git a/contrib/unbound/util/ub_event_pluggable.c b/contrib/unbound/util/ub_event_pluggable.c
index 5c517555e71b..4a9451263b7c 100644
--- a/contrib/unbound/util/ub_event_pluggable.c
+++ b/contrib/unbound/util/ub_event_pluggable.c
@@ -144,12 +144,10 @@ struct my_event {
struct event ev;
};
-#define AS_MY_EVENT_BASE(x) \
- (((union {struct ub_event_base* a; struct my_event_base* b;})x).b)
-#define AS_MY_EVENT(x) \
- (((union {struct ub_event* a; struct my_event* b;})x).b)
+#define AS_MY_EVENT_BASE(x) ((struct my_event_base*)x)
+#define AS_MY_EVENT(x) ((struct my_event*)x)
-const char* ub_event_get_version()
+const char* ub_event_get_version(void)
{
return "pluggable-event"PACKAGE_VERSION;
}
@@ -597,7 +595,7 @@ ub_event_add(struct ub_event* ev, struct timeval* tv)
int
ub_event_del(struct ub_event* ev)
{
- if (ev->magic == UB_EVENT_MAGIC) {
+ if (ev && ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del == my_event_del);
return (*ev->vmt->del)(ev);
@@ -620,7 +618,7 @@ ub_timer_add(struct ub_event* ev, struct ub_event_base* base,
int
ub_timer_del(struct ub_event* ev)
{
- if (ev->magic == UB_EVENT_MAGIC) {
+ if (ev && ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del_timer == my_timer_del);
return (*ev->vmt->del_timer)(ev);
@@ -642,7 +640,7 @@ ub_signal_add(struct ub_event* ev, struct timeval* tv)
int
ub_signal_del(struct ub_event* ev)
{
- if (ev->magic == UB_EVENT_MAGIC) {
+ if (ev && ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del_signal == my_signal_del);
return (*ev->vmt->del_signal)(ev);
@@ -653,7 +651,7 @@ ub_signal_del(struct ub_event* ev)
void
ub_winsock_unregister_wsaevent(struct ub_event* ev)
{
- if (ev->magic == UB_EVENT_MAGIC) {
+ if (ev && ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->winsock_unregister_wsaevent ==
my_winsock_unregister_wsaevent);
diff --git a/contrib/unbound/util/winsock_event.c b/contrib/unbound/util/winsock_event.c
index 40b79821a478..9aad27edc0bc 100644
--- a/contrib/unbound/util/winsock_event.c
+++ b/contrib/unbound/util/winsock_event.c
@@ -262,8 +262,9 @@ static int handle_select(struct event_base* base, struct timeval* wait)
break; /* sanity check */
}
log_assert(numwait <= WSA_MAXIMUM_WAIT_EVENTS);
- verbose(VERB_CLIENT, "winsock_event bmax=%d numwait=%d wait=%x "
- "timeout=%d", base->max, numwait, (int)wait, (int)timeout);
+ verbose(VERB_CLIENT, "winsock_event bmax=%d numwait=%d wait=%s "
+ "timeout=%d", base->max, numwait, (wait?"<wait>":"<null>"),
+ (int)timeout);
/* do the wait */
if(numwait == 0) {