aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/util
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2019-12-31 15:50:41 +0000
committerCy Schubert <cy@FreeBSD.org>2019-12-31 15:50:41 +0000
commit0eefd3079a04edf4cf315403beb0344724567f42 (patch)
treeac77aee886bf3d3af45942d2573720d128c5688e /contrib/unbound/util
parent493c98c6d2b52d2066a913203e4cbcee5a6080c2 (diff)
parente2fe726866d062155f6b1aae749375475ef19191 (diff)
downloadsrc-0eefd3079a04edf4cf315403beb0344724567f42.tar.gz
src-0eefd3079a04edf4cf315403beb0344724567f42.zip
Notes
Diffstat (limited to 'contrib/unbound/util')
-rw-r--r--contrib/unbound/util/config_file.c60
-rw-r--r--contrib/unbound/util/config_file.h25
-rw-r--r--contrib/unbound/util/configlexer.lex8
-rw-r--r--contrib/unbound/util/configparser.y67
-rw-r--r--contrib/unbound/util/data/dname.c12
-rw-r--r--contrib/unbound/util/data/msgencode.c72
-rw-r--r--contrib/unbound/util/data/msgencode.h4
-rw-r--r--contrib/unbound/util/data/msgparse.c4
-rw-r--r--contrib/unbound/util/data/msgreply.c4
-rw-r--r--contrib/unbound/util/fptr_wlist.c26
-rw-r--r--contrib/unbound/util/iana_ports.inc3
-rw-r--r--contrib/unbound/util/log.c36
-rw-r--r--contrib/unbound/util/mini_event.c2
-rw-r--r--contrib/unbound/util/net_help.c40
-rw-r--r--contrib/unbound/util/net_help.h7
-rw-r--r--contrib/unbound/util/netevent.c44
-rw-r--r--contrib/unbound/util/random.c45
-rw-r--r--contrib/unbound/util/random.h13
-rw-r--r--contrib/unbound/util/regional.c13
-rw-r--r--contrib/unbound/util/shm_side/shm_main.c8
-rw-r--r--contrib/unbound/util/ub_event.c2
-rw-r--r--contrib/unbound/util/ub_event_pluggable.c4
-rw-r--r--contrib/unbound/util/winsock_event.c2
23 files changed, 375 insertions, 126 deletions
diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c
index bdb55cbb0c02..fb6c33eacac9 100644
--- a/contrib/unbound/util/config_file.c
+++ b/contrib/unbound/util/config_file.c
@@ -255,6 +255,9 @@ config_create(void)
cfg->neg_cache_size = 1 * 1024 * 1024;
cfg->local_zones = NULL;
cfg->local_zones_nodefault = NULL;
+#ifdef USE_IPSET
+ cfg->local_zones_ipset = NULL;
+#endif
cfg->local_zones_disable_default = 0;
cfg->local_data = NULL;
cfg->local_zone_overrides = NULL;
@@ -327,9 +330,13 @@ config_create(void)
cfg->cachedb_backend = NULL;
cfg->cachedb_secret = NULL;
#endif
+#ifdef USE_IPSET
+ cfg->ipset_name_v4 = NULL;
+ cfg->ipset_name_v6 = NULL;
+#endif
return cfg;
error_exit:
- config_delete(cfg);
+ config_delete(cfg);
return NULL;
}
@@ -602,7 +609,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STR("control-key-file:", control_key_file)
else S_STR("control-cert-file:", control_cert_file)
else S_STR("module-config:", module_conf)
- else S_STR("python-script:", python_script)
+ else S_STRLIST("python-script:", python_script)
else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check)
#ifdef CLIENT_SUBNET
/* Can't set max subnet prefix here, since that value is used when
@@ -1054,7 +1061,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones)
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
else O_DEC(opt, "max-udp-size", max_udp_size)
- else O_STR(opt, "python-script", python_script)
+ else O_LST(opt, "python-script", python_script)
else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
else O_DEC(opt, "ratelimit", ratelimit)
@@ -1092,6 +1099,10 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "backend", cachedb_backend)
else O_STR(opt, "secret-seed", cachedb_secret)
#endif
+#ifdef USE_IPSET
+ else O_STR(opt, "name-v4", ipset_name_v4)
+ else O_STR(opt, "name-v6", ipset_name_v6)
+#endif
/* not here:
* outgoing-permit, outgoing-avoid - have list of ports
* local-zone - zones and nodefault variables
@@ -1310,6 +1321,9 @@ config_delview(struct config_view* p)
free(p->name);
config_deldblstrlist(p->local_zones);
config_delstrlist(p->local_zones_nodefault);
+#ifdef USE_IPSET
+ config_delstrlist(p->local_zones_ipset);
+#endif
config_delstrlist(p->local_data);
free(p);
}
@@ -1384,7 +1398,6 @@ config_delete(struct config_file* cfg)
free(cfg->version);
free(cfg->module_conf);
free(cfg->outgoing_avail_ports);
- free(cfg->python_script);
config_delstrlist(cfg->caps_whitelist);
config_delstrlist(cfg->private_address);
config_delstrlist(cfg->private_domain);
@@ -1400,6 +1413,9 @@ config_delete(struct config_file* cfg)
free(cfg->val_nsec3_key_iterations);
config_deldblstrlist(cfg->local_zones);
config_delstrlist(cfg->local_zones_nodefault);
+#ifdef USE_IPSET
+ config_delstrlist(cfg->local_zones_ipset);
+#endif
config_delstrlist(cfg->local_data);
config_deltrplstrlist(cfg->local_zone_overrides);
config_del_strarray(cfg->tagname, cfg->num_tags);
@@ -1420,6 +1436,7 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_version);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
+ config_delstrlist(cfg->python_script);
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);
@@ -1428,6 +1445,10 @@ config_delete(struct config_file* cfg)
free(cfg->cachedb_backend);
free(cfg->cachedb_secret);
#endif
+#ifdef USE_IPSET
+ free(cfg->ipset_name_v4);
+ free(cfg->ipset_name_v6);
+#endif
free(cfg);
}
@@ -1630,6 +1651,31 @@ cfg_strlist_insert(struct config_strlist** head, char* item)
return 1;
}
+int
+cfg_strlist_append_ex(struct config_strlist** head, char* item)
+{
+ struct config_strlist *s;
+ if(!item || !head)
+ return 0;
+ s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist));
+ if(!s)
+ return 0;
+ s->str = item;
+ s->next = NULL;
+
+ if (*head==NULL) {
+ *head = s;
+ } else {
+ struct config_strlist *last = *head;
+ while (last->next!=NULL) {
+ last = last->next;
+ }
+ last->next = s;
+ }
+
+ return 1;
+}
+
int
cfg_str2list_insert(struct config_str2list** head, char* item, char* i2)
{
@@ -2107,6 +2153,11 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val)
if(strcmp(type, "nodefault")==0) {
return cfg_strlist_insert(&cfg->local_zones_nodefault,
strdup(name));
+#ifdef USE_IPSET
+ } else if(strcmp(type, "ipset")==0) {
+ return cfg_strlist_insert(&cfg->local_zones_ipset,
+ strdup(name));
+#endif
} else {
return cfg_str2list_insert(&cfg->local_zones, strdup(buf),
strdup(type));
@@ -2381,3 +2432,4 @@ int options_remote_is_address(struct config_file* cfg)
if(cfg->control_ifs.first->str[0] == 0) return 1;
return (cfg->control_ifs.first->str[0] != '/');
}
+
diff --git a/contrib/unbound/util/config_file.h b/contrib/unbound/util/config_file.h
index 3cffdbff9386..b3ef930a0f16 100644
--- a/contrib/unbound/util/config_file.h
+++ b/contrib/unbound/util/config_file.h
@@ -384,6 +384,10 @@ struct config_file {
struct config_str2list* local_zones;
/** local zones nodefault list */
struct config_strlist* local_zones_nodefault;
+#ifdef USE_IPSET
+ /** local zones ipset list */
+ struct config_strlist* local_zones_ipset;
+#endif
/** do not add any default local zone */
int local_zones_disable_default;
/** local data RRs configured */
@@ -433,7 +437,7 @@ struct config_file {
char* control_cert_file;
/** Python script file */
- char* python_script;
+ struct config_strlist* python_script;
/** Use systemd socket activation. */
int use_systemd;
@@ -575,6 +579,12 @@ struct config_file {
int redis_timeout;
#endif
#endif
+
+ /* ipset module */
+#ifdef USE_IPSET
+ char* ipset_name_v4;
+ char* ipset_name_v6;
+#endif
};
/** from cfg username, after daemonize setup performed */
@@ -647,6 +657,10 @@ struct config_view {
struct config_strlist* local_data;
/** local zones nodefault list */
struct config_strlist* local_zones_nodefault;
+#ifdef USE_IPSET
+ /** local zones ipset list */
+ struct config_strlist* local_zones_ipset;
+#endif
/** Fallback to global local_zones when there is no match in the view
* view specific tree. 1 for yes, 0 for no */
int isfirst;
@@ -821,6 +835,14 @@ char* config_collate_cat(struct config_strlist* list);
int cfg_strlist_append(struct config_strlist_head* list, char* item);
/**
+ * Searches the end of a string list and appends the given text.
+ * @param head: pointer to strlist head variable.
+ * @param item: new item. malloced by caller. if NULL the insertion fails.
+ * @return true on success.
+ */
+int cfg_strlist_append_ex(struct config_strlist** head, char* item);
+
+/**
* Find string in strlist.
* @param head: pointer to strlist head variable.
* @param item: the item to search for.
@@ -1181,3 +1203,4 @@ void w_config_adjust_directory(struct config_file* cfg);
extern int fake_dsa, fake_sha1;
#endif /* UTIL_CONFIG_FILE_H */
+
diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex
index 99311a6311a4..0afcb3ccefaa 100644
--- a/contrib/unbound/util/configlexer.lex
+++ b/contrib/unbound/util/configlexer.lex
@@ -113,8 +113,7 @@ static void config_start_include_glob(const char* filename)
/* check for wildcards */
#ifdef HAVE_GLOB
glob_t g;
- size_t i;
- int r, flags;
+ int i, r, flags;
if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') &&
!strchr(filename, '{') && !strchr(filename, '~'))) {
flags = 0
@@ -145,7 +144,7 @@ static void config_start_include_glob(const char* filename)
return;
}
/* process files found, if any */
- for(i=0; i<(size_t)g.gl_pathc; i++) {
+ for(i=(int)g.gl_pathc-1; i>=0; i--) {
config_start_include(g.gl_pathv[i]);
}
globfree(&g);
@@ -484,6 +483,9 @@ secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) }
redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) }
redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
+ipset{COLON} { YDVAR(0, VAR_IPSET) }
+name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
+name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y
index c7b916966e24..10227a2ff7ff 100644
--- a/contrib/unbound/util/configparser.y
+++ b/contrib/unbound/util/configparser.y
@@ -167,6 +167,7 @@ extern struct config_parser_state* cfg_parser;
%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
+%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -174,7 +175,7 @@ toplevelvar: serverstart contents_server | stubstart contents_stub |
forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb |
- authstart contents_auth
+ ipsetstart contents_ipset | authstart contents_auth
;
/* server: declaration */
@@ -1784,13 +1785,14 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
&& strcmp($3, "always_nxdomain")!=0
&& strcmp($3, "noview")!=0
&& strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
- && strcmp($3, "inform_redirect") != 0) {
+ && strcmp($3, "inform_redirect") != 0
+ && strcmp($3, "ipset") != 0) {
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
"inform_redirect, always_transparent, "
"always_refuse, always_nxdomain, noview "
- "or nodefault");
+ ", nodefault or ipset");
free($2);
free($3);
} else if(strcmp($3, "nodefault")==0) {
@@ -1798,6 +1800,13 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
local_zones_nodefault, $2))
fatal_exit("out of memory adding local-zone");
free($3);
+#ifdef USE_IPSET
+ } else if(strcmp($3, "ipset")==0) {
+ if(!cfg_strlist_insert(&cfg_parser->cfg->
+ local_zones_ipset, $2))
+ fatal_exit("out of memory adding local-zone");
+ free($3);
+#endif
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones,
$2, $3))
@@ -2455,6 +2464,13 @@ view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
local_zones_nodefault, $2))
fatal_exit("out of memory adding local-zone");
free($3);
+#ifdef USE_IPSET
+ } else if(strcmp($3, "ipset")==0) {
+ if(!cfg_strlist_insert(&cfg_parser->cfg->views->
+ local_zones_ipset, $2))
+ fatal_exit("out of memory adding local-zone");
+ free($3);
+#endif
} else {
if(!cfg_str2list_insert(
&cfg_parser->cfg->views->local_zones,
@@ -2722,8 +2738,8 @@ content_py: py_script
py_script: VAR_PYTHON_SCRIPT STRING_ARG
{
OUTYY(("P(python-script:%s)\n", $2));
- free(cfg_parser->cfg->python_script);
- cfg_parser->cfg->python_script = $2;
+ if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2))
+ yyerror("out of memory");
}
server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
{
@@ -2959,6 +2975,45 @@ server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG
}
}
;
+ ipsetstart: VAR_IPSET
+ {
+ OUTYY(("\nP(ipset:)\n"));
+ }
+ ;
+ contents_ipset: contents_ipset content_ipset
+ | ;
+ content_ipset: ipset_name_v4 | ipset_name_v6
+ ;
+ ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG
+ {
+ #ifdef USE_IPSET
+ OUTYY(("P(name-v4:%s)\n", $2));
+ if(cfg_parser->cfg->ipset_name_v4)
+ yyerror("ipset name v4 override, there must be one "
+ "name for ip v4");
+ free(cfg_parser->cfg->ipset_name_v4);
+ cfg_parser->cfg->ipset_name_v4 = $2;
+ #else
+ OUTYY(("P(Compiled without ipset, ignoring)\n"));
+ free($2);
+ #endif
+ }
+ ;
+ ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG
+ {
+ #ifdef USE_IPSET
+ OUTYY(("P(name-v6:%s)\n", $2));
+ if(cfg_parser->cfg->ipset_name_v6)
+ yyerror("ipset name v6 override, there must be one "
+ "name for ip v6");
+ free(cfg_parser->cfg->ipset_name_v6);
+ cfg_parser->cfg->ipset_name_v6 = $2;
+ #else
+ OUTYY(("P(Compiled without ipset, ignoring)\n"));
+ free($2);
+ #endif
+ }
+ ;
%%
/* parse helper routines could be here */
@@ -2978,3 +3033,5 @@ validate_respip_action(const char* action)
"always_refuse or always_nxdomain");
}
}
+
+
diff --git a/contrib/unbound/util/data/dname.c b/contrib/unbound/util/data/dname.c
index c7360f75f32a..9f25e1efe204 100644
--- a/contrib/unbound/util/data/dname.c
+++ b/contrib/unbound/util/data/dname.c
@@ -75,6 +75,8 @@ dname_valid(uint8_t* dname, size_t maxlen)
{
size_t len = 0;
size_t labellen;
+ if(maxlen == 0)
+ return 0; /* too short, shortest is '0' root label */
labellen = *dname++;
while(labellen) {
if(labellen&0xc0)
@@ -327,16 +329,26 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h)
void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname)
{
/* copy over the dname and decompress it at the same time */
+ size_t comprcount = 0;
size_t len = 0;
uint8_t lablen;
lablen = *dname++;
while(lablen) {
if(LABEL_IS_PTR(lablen)) {
+ if(comprcount++ > MAX_COMPRESS_PTRS) {
+ /* too many compression pointers */
+ *to = 0; /* end the result prematurely */
+ return;
+ }
/* follow pointer */
dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
lablen = *dname++;
continue;
}
+ if(lablen > LDNS_MAX_LABELLEN) {
+ *to = 0; /* end the result prematurely */
+ return;
+ }
log_assert(lablen <= LDNS_MAX_LABELLEN);
len += (size_t)lablen+1;
if(len >= LDNS_MAX_DOMAINLEN) {
diff --git a/contrib/unbound/util/data/msgencode.c b/contrib/unbound/util/data/msgencode.c
index 4c0a5550be13..a51a4b9b85d8 100644
--- a/contrib/unbound/util/data/msgencode.c
+++ b/contrib/unbound/util/data/msgencode.c
@@ -639,15 +639,37 @@ positive_answer(struct reply_info* rep, uint16_t qtype) {
return 0;
}
-int
-reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
- uint16_t id, uint16_t flags, sldns_buffer* buffer, time_t timenow,
- struct regional* region, uint16_t udpsize, int dnssec)
+static int
+negative_answer(struct reply_info* rep) {
+ size_t i;
+ int ns_seen = 0;
+ if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN)
+ return 1;
+ if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR &&
+ rep->an_numrrsets != 0)
+ return 0; /* positive */
+ if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR &&
+ FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN)
+ return 0;
+ for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++){
+ if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_SOA)
+ return 1;
+ if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS)
+ ns_seen = 1;
+ }
+ if(ns_seen) return 0; /* could be referral, NS, but no SOA */
+ return 1;
+}
+
+int
+reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
+ uint16_t id, uint16_t flags, sldns_buffer* buffer, time_t timenow,
+ struct regional* region, uint16_t udpsize, int dnssec, int minimise)
{
uint16_t ancount=0, nscount=0, arcount=0;
struct compress_tree_node* tree = 0;
int r;
- size_t rr_offset;
+ size_t rr_offset;
sldns_buffer_clear(buffer);
if(udpsize < sldns_buffer_limit(buffer))
@@ -663,7 +685,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
/* insert query section */
if(rep->qdcount) {
- if((r=insert_query(qinfo, &tree, buffer, region)) !=
+ if((r=insert_query(qinfo, &tree, buffer, region)) !=
RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* create truncated message */
@@ -707,8 +729,8 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
}
/* insert answer section */
- if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
- 0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
+ if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
+ 0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
dnssec, rr_offset)) != RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* create truncated message */
@@ -722,9 +744,9 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
sldns_buffer_write_u16_at(buffer, 6, ancount);
/* if response is positive answer, auth/add sections are not required */
- if( ! (MINIMAL_RESPONSES && positive_answer(rep, qinfo->qtype)) ) {
+ if( ! (minimise && positive_answer(rep, qinfo->qtype)) ) {
/* insert auth section */
- if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
+ if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
rep->an_numrrsets, timenow, region, &tree,
LDNS_SECTION_AUTHORITY, qinfo->qtype,
dnssec, rr_offset)) != RETVAL_OK) {
@@ -739,20 +761,22 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
}
sldns_buffer_write_u16_at(buffer, 8, nscount);
- /* insert add section */
- if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
- rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
- &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
- dnssec, rr_offset)) != RETVAL_OK) {
- if(r == RETVAL_TRUNC) {
- /* no need to set TC bit, this is the additional */
- sldns_buffer_write_u16_at(buffer, 10, arcount);
- sldns_buffer_flip(buffer);
- return 1;
+ if(! (minimise && negative_answer(rep))) {
+ /* insert add section */
+ if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
+ rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
+ &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
+ dnssec, rr_offset)) != RETVAL_OK) {
+ if(r == RETVAL_TRUNC) {
+ /* no need to set TC bit, this is the additional */
+ sldns_buffer_write_u16_at(buffer, 10, arcount);
+ sldns_buffer_flip(buffer);
+ return 1;
+ }
+ return 0;
}
- return 0;
+ sldns_buffer_write_u16_at(buffer, 10, arcount);
}
- sldns_buffer_write_u16_at(buffer, 10, arcount);
}
sldns_buffer_flip(buffer);
return 1;
@@ -763,7 +787,7 @@ calc_edns_field_size(struct edns_data* edns)
{
size_t rdatalen = 0;
struct edns_option* opt;
- if(!edns || !edns->edns_present)
+ if(!edns || !edns->edns_present)
return 0;
for(opt = edns->opt_list; opt; opt = opt->next) {
rdatalen += 4 + opt->opt_len;
@@ -850,7 +874,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
}
if(!reply_info_encode(qinf, rep, id, flags, pkt, timenow, region,
- udpsize, dnssec)) {
+ udpsize, dnssec, MINIMAL_RESPONSES)) {
log_err("reply encode: out of memory");
return 0;
}
diff --git a/contrib/unbound/util/data/msgencode.h b/contrib/unbound/util/data/msgencode.h
index eea129d98d59..30dc515cbe59 100644
--- a/contrib/unbound/util/data/msgencode.h
+++ b/contrib/unbound/util/data/msgencode.h
@@ -85,12 +85,14 @@ int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
* @param region: to store temporary data in.
* @param udpsize: size of the answer, 512, from EDNS, or 64k for TCP.
* @param dnssec: if 0 DNSSEC records are omitted from the answer.
+ * @param minimise: if true, the answer is a minimal response, with
+ * authority and additional removed if possible.
* @return: nonzero is success, or
* 0 on error: malloc failure (no log_err has been done).
*/
int reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
uint16_t id, uint16_t flags, struct sldns_buffer* buffer, time_t timenow,
- struct regional* region, uint16_t udpsize, int dnssec);
+ struct regional* region, uint16_t udpsize, int dnssec, int minimise);
/**
* Encode query packet. Assumes the buffer is large enough.
diff --git a/contrib/unbound/util/data/msgparse.c b/contrib/unbound/util/data/msgparse.c
index 13cad8a26630..fb312370366d 100644
--- a/contrib/unbound/util/data/msgparse.c
+++ b/contrib/unbound/util/data/msgparse.c
@@ -1061,18 +1061,18 @@ parse_edns_from_pkt(sldns_buffer* pkt, struct edns_data* edns,
size_t rdata_len;
uint8_t* rdata_ptr;
log_assert(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) == 1);
+ memset(edns, 0, sizeof(*edns));
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 ||
LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
if(!skip_pkt_rrs(pkt, ((int)LDNS_ANCOUNT(sldns_buffer_begin(pkt)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(pkt)))))
- return 0;
+ return LDNS_RCODE_FORMERR;
}
/* check edns section is present */
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
return LDNS_RCODE_FORMERR;
}
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) {
- memset(edns, 0, sizeof(*edns));
edns->udp_size = 512;
return 0;
}
diff --git a/contrib/unbound/util/data/msgreply.c b/contrib/unbound/util/data/msgreply.c
index 32aec4bf4c95..4320f312d6f3 100644
--- a/contrib/unbound/util/data/msgreply.c
+++ b/contrib/unbound/util/data/msgreply.c
@@ -243,10 +243,10 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
break;
}
if(len) {
+ log_assert(len <= pkt_len);
memmove(to, sldns_buffer_current(pkt), len);
to += len;
sldns_buffer_skip(pkt, (ssize_t)len);
- log_assert(len <= pkt_len);
pkt_len -= len;
}
rdf++;
@@ -819,7 +819,7 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
sldns_buffer* buf = sldns_buffer_new(65535);
struct regional* region = regional_create();
if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0,
- region, 65535, 1)) {
+ region, 65535, 1, 0)) {
log_info("%s: log_dns_msg: out of memory", str);
} else {
char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
diff --git a/contrib/unbound/util/fptr_wlist.c b/contrib/unbound/util/fptr_wlist.c
index 94d23fa3a32a..f5da501de19b 100644
--- a/contrib/unbound/util/fptr_wlist.c
+++ b/contrib/unbound/util/fptr_wlist.c
@@ -90,6 +90,9 @@
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#endif
+#ifdef USE_IPSET
+#include "ipset/ipset.h"
+#endif
int
fptr_whitelist_comm_point(comm_point_callback_type *fptr)
@@ -358,8 +361,8 @@ fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq))
}
int
-fptr_whitelist_modenv_detect_cycle(int (*fptr)(
- struct module_qstate* qstate, struct query_info* qinfo,
+fptr_whitelist_modenv_detect_cycle(int (*fptr)(
+ struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime, int valrec))
{
if(fptr == &mesh_detect_cycle) return 1;
@@ -385,6 +388,9 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_init) return 1;
#endif
+#ifdef USE_IPSET
+ else if(fptr == &ipset_init) return 1;
+#endif
return 0;
}
@@ -407,6 +413,9 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_deinit) return 1;
#endif
+#ifdef USE_IPSET
+ else if(fptr == &ipset_deinit) return 1;
+#endif
return 0;
}
@@ -430,6 +439,9 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_operate) return 1;
#endif
+#ifdef USE_IPSET
+ else if(fptr == &ipset_operate) return 1;
+#endif
return 0;
}
@@ -453,6 +465,9 @@ fptr_whitelist_mod_inform_super(void (*fptr)(
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_inform_super) return 1;
#endif
+#ifdef USE_IPSET
+ else if(fptr == &ipset_inform_super) return 1;
+#endif
return 0;
}
@@ -476,6 +491,9 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_clear) return 1;
#endif
+#ifdef USE_IPSET
+ else if(fptr == &ipset_clear) return 1;
+#endif
return 0;
}
@@ -498,6 +516,9 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_get_mem) return 1;
#endif
+#ifdef USE_IPSET
+ else if(fptr == &ipset_get_mem) return 1;
+#endif
return 0;
}
@@ -597,3 +618,4 @@ int fptr_whitelist_inplace_cb_query_response(
#endif
return 0;
}
+
diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc
index aa972a67bd5d..3e6f3e6be617 100644
--- a/contrib/unbound/util/iana_ports.inc
+++ b/contrib/unbound/util/iana_ports.inc
@@ -960,8 +960,6 @@
1298,
1299,
1300,
-1301,
-1302,
1303,
1304,
1305,
@@ -1848,7 +1846,6 @@
2197,
2198,
2199,
-2200,
2201,
2202,
2203,
diff --git a/contrib/unbound/util/log.c b/contrib/unbound/util/log.c
index 318ff1d79107..8499d8c0a8a7 100644
--- a/contrib/unbound/util/log.c
+++ b/contrib/unbound/util/log.c
@@ -61,7 +61,7 @@
#endif
/* default verbosity */
-enum verbosity_value verbosity = 0;
+enum verbosity_value verbosity = NO_VERBOSE;
/** the file logged to. */
static FILE* logfile = 0;
/** if key has been created */
@@ -70,7 +70,7 @@ static int key_created = 0;
static ub_thread_key_type logkey;
#ifndef THREADS_DISABLED
/** pthread mutex to protect FILE* */
-static lock_quick_type log_lock;
+static lock_basic_type log_lock;
#endif
/** the identity of this executable/process */
static const char* ident="unbound";
@@ -88,18 +88,18 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
if(!key_created) {
key_created = 1;
ub_thread_key_create(&logkey, NULL);
- lock_quick_init(&log_lock);
+ lock_basic_init(&log_lock);
}
- lock_quick_lock(&log_lock);
+ lock_basic_lock(&log_lock);
if(logfile
#if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS)
|| logging_to_syslog
#endif
) {
- lock_quick_unlock(&log_lock); /* verbose() needs the lock */
+ lock_basic_unlock(&log_lock); /* verbose() needs the lock */
verbose(VERB_QUERY, "switching log to %s",
use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"));
- lock_quick_lock(&log_lock);
+ lock_basic_lock(&log_lock);
}
if(logfile && logfile != stderr) {
FILE* cl = logfile;
@@ -115,9 +115,11 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
if(use_syslog) {
/* do not delay opening until first write, because we may
* chroot and no longer be able to access dev/log and so on */
- openlog(ident, LOG_NDELAY, LOG_DAEMON);
+ /* the facility is LOG_DAEMON by default, but
+ * --with-syslog-facility=LOCAL[0-7] can override it */
+ openlog(ident, LOG_NDELAY, UB_SYSLOG_FACILITY);
logging_to_syslog = 1;
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
return;
}
#elif defined(UB_ON_WINDOWS)
@@ -126,13 +128,13 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
}
if(use_syslog) {
logging_to_syslog = 1;
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
return;
}
#endif /* HAVE_SYSLOG_H */
if(!filename || !filename[0]) {
logfile = stderr;
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
return;
}
/* open the file for logging */
@@ -141,7 +143,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
filename += strlen(chrootdir);
f = fopen(filename, "a");
if(!f) {
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
log_err("Could not open logfile %s: %s", filename,
strerror(errno));
return;
@@ -151,14 +153,14 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
setvbuf(f, NULL, (int)_IOLBF, 0);
#endif
logfile = f;
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
}
void log_file(FILE *f)
{
- lock_quick_lock(&log_lock);
+ lock_basic_lock(&log_lock);
logfile = f;
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
}
void log_thread_set(int* num)
@@ -243,9 +245,9 @@ log_vmsg(int pri, const char* type,
return;
}
#endif /* HAVE_SYSLOG_H */
- lock_quick_lock(&log_lock);
+ lock_basic_lock(&log_lock);
if(!logfile) {
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
return;
}
now = (time_t)time(NULL);
@@ -270,7 +272,7 @@ log_vmsg(int pri, const char* type,
/* line buffering does not work on windows */
fflush(logfile);
#endif
- lock_quick_unlock(&log_lock);
+ lock_basic_unlock(&log_lock);
}
/**
diff --git a/contrib/unbound/util/mini_event.c b/contrib/unbound/util/mini_event.c
index faadf1a23c8d..661d88d2e6f6 100644
--- a/contrib/unbound/util/mini_event.c
+++ b/contrib/unbound/util/mini_event.c
@@ -313,7 +313,7 @@ int event_add(struct event* ev, struct timeval* tv)
struct timeval *now = ev->ev_base->time_tv;
ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec;
ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec;
- while(ev->ev_timeout.tv_usec > 1000000) {
+ while(ev->ev_timeout.tv_usec >= 1000000) {
ev->ev_timeout.tv_usec -= 1000000;
ev->ev_timeout.tv_sec++;
}
diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c
index 13bcdf8085bf..9747b5d55a78 100644
--- a/contrib/unbound/util/net_help.c
+++ b/contrib/unbound/util/net_help.c
@@ -698,10 +698,19 @@ void
log_crypto_err(const char* str)
{
#ifdef HAVE_SSL
+ log_crypto_err_code(str, ERR_get_error());
+#else
+ (void)str;
+#endif /* HAVE_SSL */
+}
+
+void log_crypto_err_code(const char* str, unsigned long err)
+{
+#ifdef HAVE_SSL
/* error:[error code]:[library name]:[function name]:[reason string] */
char buf[128];
unsigned long e;
- ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
+ ERR_error_string_n(err, buf, sizeof(buf));
log_err("%s crypto %s", str, buf);
while( (e=ERR_get_error()) ) {
ERR_error_string_n(e, buf, sizeof(buf));
@@ -709,6 +718,7 @@ log_crypto_err(const char* str)
}
#else
(void)str;
+ (void)err;
#endif /* HAVE_SSL */
}
@@ -744,6 +754,14 @@ listen_sslctx_setup(void* ctxt)
return 0;
}
#endif
+#if defined(SSL_OP_NO_RENEGOTIATION)
+ /* disable client renegotiation */
+ if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
+ SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) {
+ log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION");
+ return 0;
+ }
+#endif
#if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA)
/* if we have sha256, set the cipher list to have no known vulns */
if(!SSL_CTX_set_cipher_list(ctx, "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"))
@@ -962,6 +980,14 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert)
SSL_CTX_free(ctx);
return NULL;
}
+#if defined(SSL_OP_NO_RENEGOTIATION)
+ /* disable client renegotiation */
+ if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
+ SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) {
+ log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION");
+ return 0;
+ }
+#endif
if(key && key[0]) {
if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) {
log_err("error in client certificate %s", pem);
@@ -1019,7 +1045,7 @@ void* incoming_ssl_fd(void* sslctx, int fd)
return NULL;
}
SSL_set_accept_state(ssl);
- (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+ (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
if(!SSL_set_fd(ssl, fd)) {
log_crypto_err("could not SSL_set_fd");
SSL_free(ssl);
@@ -1041,7 +1067,7 @@ void* outgoing_ssl_fd(void* sslctx, int fd)
return NULL;
}
SSL_set_connect_state(ssl);
- (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+ (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
if(!SSL_set_fd(ssl, fd)) {
log_crypto_err("could not SSL_set_fd");
SSL_free(ssl);
@@ -1197,10 +1223,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name
verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed");
return -1;
}
+#ifndef HMAC_INIT_EX_RETURNS_VOID
if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) {
verbose(VERB_CLIENT, "HMAC_Init_ex failed");
return -1;
}
+#else
+ HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL);
+#endif
return 1;
} else if (enc == 0) {
/* decrypt */
@@ -1217,10 +1247,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name
return 0;
}
+#ifndef HMAC_INIT_EX_RETURNS_VOID
if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) {
verbose(VERB_CLIENT, "HMAC_Init_ex failed");
return -1;
}
+#else
+ HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL);
+#endif
if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) {
log_err("EVP_DecryptInit_ex failed");
return -1;
diff --git a/contrib/unbound/util/net_help.h b/contrib/unbound/util/net_help.h
index 0b197fbdd6e7..79e2a834931a 100644
--- a/contrib/unbound/util/net_help.h
+++ b/contrib/unbound/util/net_help.h
@@ -379,6 +379,13 @@ void sock_list_merge(struct sock_list** list, struct regional* region,
void log_crypto_err(const char* str);
/**
+ * Log libcrypto error from errcode with descriptive string, calls log_err.
+ * @param str: what failed.
+ * @param err: error code from ERR_get_error.
+ */
+void log_crypto_err_code(const char* str, unsigned long err);
+
+/**
* Set SSL_OP_NOxxx options on SSL context to disable bad crypto
* @param ctxt: SSL_CTX*
* @return false on failure.
diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c
index 9e2ba92b5fdf..980bb8bea972 100644
--- a/contrib/unbound/util/netevent.c
+++ b/contrib/unbound/util/netevent.c
@@ -1001,7 +1001,7 @@ tcp_callback_writer(struct comm_point* c)
tcp_req_info_handle_writedone(c->tcp_req_info);
} else {
comm_point_stop_listening(c);
- comm_point_start_listening(c, -1, -1);
+ comm_point_start_listening(c, -1, c->tcp_timeout_msec);
}
}
@@ -1052,6 +1052,35 @@ log_cert(unsigned level, const char* str, X509* cert)
}
#endif /* HAVE_SSL */
+#ifdef HAVE_SSL
+/** true if the ssl handshake error has to be squelched from the logs */
+static int
+squelch_err_ssl_handshake(unsigned long err)
+{
+ if(verbosity >= VERB_QUERY)
+ return 0; /* only squelch on low verbosity */
+ /* this is very specific, we could filter on ERR_GET_REASON()
+ * (the third element in ERR_PACK) */
+ if(err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTPS_PROXY_REQUEST) ||
+ err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTP_REQUEST) ||
+ err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER) ||
+ err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_READ_BYTES, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE)
+#ifdef SSL_F_TLS_POST_PROCESS_CLIENT_HELLO
+ || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER)
+#endif
+#ifdef SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO
+ || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL)
+ || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL)
+# ifdef SSL_R_VERSION_TOO_LOW
+ || err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_VERSION_TOO_LOW)
+# endif
+#endif
+ )
+ return 1;
+ return 0;
+}
+#endif /* HAVE_SSL */
+
/** continue ssl handshake */
#ifdef HAVE_SSL
static int
@@ -1096,9 +1125,12 @@ ssl_handshake(struct comm_point* c)
strerror(errno));
return 0;
} else {
- log_crypto_err("ssl handshake failed");
- log_addr(1, "ssl handshake failed", &c->repinfo.addr,
- c->repinfo.addrlen);
+ unsigned long err = ERR_get_error();
+ if(!squelch_err_ssl_handshake(err)) {
+ log_crypto_err_code("ssl handshake failed", err);
+ log_addr(VERB_OPS, "ssl handshake failed", &c->repinfo.addr,
+ c->repinfo.addrlen);
+ }
return 0;
}
}
@@ -1277,7 +1309,7 @@ ssl_handle_write(struct comm_point* c)
return 1;
}
/* ignore return, if fails we may simply block */
- (void)SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ (void)SSL_set_mode(c->ssl, (long)SSL_MODE_ENABLE_PARTIAL_WRITE);
if(c->tcp_byte_count < sizeof(uint16_t)) {
uint16_t len = htons(sldns_buffer_limit(c->buffer));
ERR_clear_error();
@@ -3159,7 +3191,7 @@ comm_point_drop_reply(struct comm_reply* repinfo)
{
if(!repinfo)
return;
- log_assert(repinfo && repinfo->c);
+ log_assert(repinfo->c);
log_assert(repinfo->c->type != comm_tcp_accept);
if(repinfo->c->type == comm_udp)
return;
diff --git a/contrib/unbound/util/random.c b/contrib/unbound/util/random.c
index 8332960b4d0c..bb564f2f99aa 100644
--- a/contrib/unbound/util/random.c
+++ b/contrib/unbound/util/random.c
@@ -79,15 +79,8 @@
#define MAX_VALUE 0x7fffffff
#if defined(HAVE_SSL)
-void
-ub_systemseed(unsigned int ATTR_UNUSED(seed))
-{
- /* arc4random_uniform does not need seeds, it gets kernel entropy */
-}
-
struct ub_randstate*
-ub_initstate(unsigned int ATTR_UNUSED(seed),
- struct ub_randstate* ATTR_UNUSED(from))
+ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
{
struct ub_randstate* s = (struct ub_randstate*)malloc(1);
if(!s) {
@@ -119,12 +112,7 @@ struct ub_randstate {
int ready;
};
-void ub_systemseed(unsigned int ATTR_UNUSED(seed))
-{
-}
-
-struct ub_randstate* ub_initstate(unsigned int ATTR_UNUSED(seed),
- struct ub_randstate* ATTR_UNUSED(from))
+struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
{
struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
if(!s) {
@@ -140,7 +128,9 @@ long int ub_random(struct ub_randstate* ATTR_UNUSED(state))
/* random 31 bit value. */
SECStatus s = PK11_GenerateRandom((unsigned char*)&x, (int)sizeof(x));
if(s != SECSuccess) {
- log_err("PK11_GenerateRandom error: %s",
+ /* unbound needs secure randomness for randomized
+ * ID bits and port numbers in packets to upstream servers */
+ fatal_exit("PK11_GenerateRandom error: %s",
PORT_ErrorToString(PORT_GetError()));
}
return x & MAX_VALUE;
@@ -157,17 +147,7 @@ struct ub_randstate {
int seeded;
};
-void ub_systemseed(unsigned int ATTR_UNUSED(seed))
-{
-/**
- * We seed on init and not here, as we need the ctx to re-seed.
- * This also means that re-seeding is not supported.
- */
- log_err("Re-seeding not supported, generator untouched");
-}
-
-struct ub_randstate* ub_initstate(unsigned int seed,
- struct ub_randstate* ATTR_UNUSED(from))
+struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
{
struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
uint8_t buf[YARROW256_SEED_FILE_SIZE];
@@ -183,15 +163,10 @@ struct ub_randstate* ub_initstate(unsigned int seed,
yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf);
s->seeded = yarrow256_is_seeded(&s->ctx);
} else {
- /* Stretch the uint32 input seed and feed it to Yarrow */
- uint32_t v = seed;
- size_t i;
- for(i=0; i < (YARROW256_SEED_FILE_SIZE/sizeof(seed)); i++) {
- memmove(buf+i*sizeof(seed), &v, sizeof(seed));
- v = v*seed + (uint32_t)i;
- }
- yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf);
- s->seeded = yarrow256_is_seeded(&s->ctx);
+ log_err("nettle random(yarrow) cannot initialize, "
+ "getentropy failed: %s", strerror(errno));
+ free(s);
+ return NULL;
}
return s;
diff --git a/contrib/unbound/util/random.h b/contrib/unbound/util/random.h
index a05a994a3d52..b257793a4449 100644
--- a/contrib/unbound/util/random.h
+++ b/contrib/unbound/util/random.h
@@ -48,24 +48,13 @@
struct ub_randstate;
/**
- * Initialize the system randomness. Obtains entropy from the system
- * before a chroot or privilege makes it unavailable.
- * You do not have to call this, otherwise ub_initstate does so.
- * @param seed: seed value to create state (if no good entropy is found).
- */
-void ub_systemseed(unsigned int seed);
-
-/**
* Initialize a random generator state for use
- * @param seed: seed value to create state contents.
- * (ignored for arc4random).
* @param from: if not NULL, the seed is taken from this random structure.
* can be used to seed random states via a parent-random-state that
* is itself seeded with entropy.
* @return new state or NULL alloc failure.
*/
-struct ub_randstate* ub_initstate(unsigned int seed,
- struct ub_randstate* from);
+struct ub_randstate* ub_initstate(struct ub_randstate* from);
/**
* Generate next random number from the state passed along.
diff --git a/contrib/unbound/util/regional.c b/contrib/unbound/util/regional.c
index 899a54edbddd..ff36d0e21241 100644
--- a/contrib/unbound/util/regional.c
+++ b/contrib/unbound/util/regional.c
@@ -84,6 +84,7 @@ struct regional*
regional_create_custom(size_t size)
{
struct regional* r = (struct regional*)malloc(size);
+ size = ALIGN_UP(size, ALIGNMENT);
log_assert(sizeof(struct regional) <= size);
if(!r) return NULL;
r->first_size = size;
@@ -120,8 +121,18 @@ regional_destroy(struct regional *r)
void *
regional_alloc(struct regional *r, size_t size)
{
- size_t a = ALIGN_UP(size, ALIGNMENT);
+ size_t a;
void *s;
+ if(
+#if SIZEOF_SIZE_T == 8
+ (unsigned long long)size >= 0xffffffffffffff00ULL
+#else
+ (unsigned)size >= (unsigned)0xffffff00UL
+#endif
+ )
+ return NULL; /* protect against integer overflow in
+ malloc and ALIGN_UP */
+ a = ALIGN_UP(size, ALIGNMENT);
/* large objects */
if(a > REGIONAL_LARGE_OBJECT_SIZE) {
s = malloc(ALIGNMENT + size);
diff --git a/contrib/unbound/util/shm_side/shm_main.c b/contrib/unbound/util/shm_side/shm_main.c
index a783c099b5a4..46a71510fea3 100644
--- a/contrib/unbound/util/shm_side/shm_main.c
+++ b/contrib/unbound/util/shm_side/shm_main.c
@@ -121,7 +121,7 @@ int shm_main_init(struct daemon* daemon)
shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL);
/* SHM: Create the segment */
- daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0666);
+ daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0644);
if (daemon->shm_info->id_ctl < 0)
{
@@ -134,7 +134,7 @@ int shm_main_init(struct daemon* daemon)
return 0;
}
- daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0666);
+ daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0644);
if (daemon->shm_info->id_arr < 0)
{
@@ -223,8 +223,10 @@ void shm_main_run(struct worker *worker)
struct ub_stats_info *stat_info;
int offset;
+#ifndef S_SPLINT_S
verbose(VERB_DETAIL, "SHM run - worker [%d] - daemon [%p] - timenow(%u) - timeboot(%u)",
worker->thread_num, worker->daemon, (unsigned)worker->env.now_tv->tv_sec, (unsigned)worker->daemon->time_boot.tv_sec);
+#endif
offset = worker->thread_num + 1;
stat_total = worker->daemon->shm_info->ptr_arr;
@@ -240,9 +242,11 @@ void shm_main_run(struct worker *worker)
memset(stat_total, 0, sizeof(struct ub_stats_info));
/* Point to data into SHM */
+#ifndef S_SPLINT_S
shm_stat = worker->daemon->shm_info->ptr_ctl;
shm_stat->time.now_sec = (long long)worker->env.now_tv->tv_sec;
shm_stat->time.now_usec = (long long)worker->env.now_tv->tv_usec;
+#endif
stat_timeval_subtract(&shm_stat->time.up_sec, &shm_stat->time.up_usec, worker->env.now_tv, &worker->daemon->time_boot);
stat_timeval_subtract(&shm_stat->time.elapsed_sec, &shm_stat->time.elapsed_usec, worker->env.now_tv, &worker->daemon->time_last_stat);
diff --git a/contrib/unbound/util/ub_event.c b/contrib/unbound/util/ub_event.c
index e097fbc40158..9af476ad4084 100644
--- a/contrib/unbound/util/ub_event.c
+++ b/contrib/unbound/util/ub_event.c
@@ -458,7 +458,9 @@ void ub_comm_base_now(struct comm_base* cb)
if(gettimeofday(tv, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
}
+#ifndef S_SPLINT_S
*tt = tv->tv_sec;
+#endif
#endif /* USE_MINI_EVENT */
}
diff --git a/contrib/unbound/util/ub_event_pluggable.c b/contrib/unbound/util/ub_event_pluggable.c
index 4a9451263b7c..235bba6ba797 100644
--- a/contrib/unbound/util/ub_event_pluggable.c
+++ b/contrib/unbound/util/ub_event_pluggable.c
@@ -453,7 +453,7 @@ ub_get_event_sys(struct ub_event_base* ub_base, const char** n, const char** s,
* ub_base is guaranteed to exist and to be the default
* event base.
*/
- assert(b);
+ assert(b != NULL);
*n = "pluggable-event";
*s = event_get_version();
# if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
@@ -687,6 +687,8 @@ void ub_comm_base_now(struct comm_base* cb)
if(gettimeofday(tv, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
}
+#ifndef S_SPLINT_S
*tt = tv->tv_sec;
+#endif
}
diff --git a/contrib/unbound/util/winsock_event.c b/contrib/unbound/util/winsock_event.c
index 63d98796d19f..de6c28ecb08e 100644
--- a/contrib/unbound/util/winsock_event.c
+++ b/contrib/unbound/util/winsock_event.c
@@ -558,7 +558,7 @@ int event_add(struct event *ev, struct timeval *tv)
struct timeval *now = ev->ev_base->time_tv;
ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec;
ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec;
- while(ev->ev_timeout.tv_usec > 1000000) {
+ while(ev->ev_timeout.tv_usec >= 1000000) {
ev->ev_timeout.tv_usec -= 1000000;
ev->ev_timeout.tv_sec++;
}