summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/authzone.c2
-rw-r--r--services/cache/dns.c3
-rw-r--r--services/cache/infra.c2
-rw-r--r--services/listen_dnsport.c7
-rw-r--r--services/localzone.c111
-rw-r--r--services/localzone.h7
-rw-r--r--services/outside_network.c11
7 files changed, 102 insertions, 41 deletions
diff --git a/services/authzone.c b/services/authzone.c
index 75dd4fc607363..88beddbf9229e 100644
--- a/services/authzone.c
+++ b/services/authzone.c
@@ -628,7 +628,7 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
d->rr_len[d->count-1] = rdatalen;
else d->rr_len[total-1] = rdatalen;
packed_rrset_ptr_fixup(d);
- if(rr_ttl < d->ttl)
+ if((time_t)rr_ttl < d->ttl)
d->ttl = rr_ttl;
/* copy old values into new array */
diff --git a/services/cache/dns.c b/services/cache/dns.c
index 764205e53cbec..da43c504dfa31 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -99,6 +99,9 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
}
}
/* no break: also copy key item */
+ /* the line below is matched by gcc regex and silences
+ * the fallthrough warning */
+ /* fallthrough */
case 1: /* ref updated, item inserted */
rep->rrsets[i] = rep->ref[i].key;
}
diff --git a/services/cache/infra.c b/services/cache/infra.c
index ca1102ef5f7fb..734b7969e7a2e 100644
--- a/services/cache/infra.c
+++ b/services/cache/infra.c
@@ -249,7 +249,7 @@ infra_create(struct config_file* cfg)
name_tree_init_parents(&infra->domain_limits);
}
infra_ip_ratelimit = cfg->ip_ratelimit;
- infra->client_ip_rates = slabhash_create(cfg->ratelimit_slabs,
+ infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
if(!infra->client_ip_rates) {
diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c
index 0341f30674899..3b53676d0e06e 100644
--- a/services/listen_dnsport.c
+++ b/services/listen_dnsport.c
@@ -792,7 +792,12 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
#endif
if ((setsockopt(s, IPPROTO_TCP, TCP_FASTOPEN, &qlen,
sizeof(qlen))) == -1 ) {
- log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
+#ifdef ENOPROTOOPT
+ /* squelch ENOPROTOOPT: freebsd server mode with kernel support
+ disabled, except when verbosity enabled for debugging */
+ if(errno != ENOPROTOOPT || verbosity >= 3)
+#endif
+ log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
}
#endif
return s;
diff --git a/services/localzone.c b/services/localzone.c
index a19b5252643f3..6bde432e8d097 100644
--- a/services/localzone.c
+++ b/services/localzone.c
@@ -260,7 +260,8 @@ rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
/** return name and class of rr; parses string */
static int
-get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
+get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass,
+ uint16_t* dtype)
{
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t len = sizeof(rr), dname_len = 0;
@@ -274,6 +275,7 @@ get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
}
*nm = memdup(rr, dname_len);
*dclass = sldns_wirerr_get_class(rr, len, dname_len);
+ *dtype = sldns_wirerr_get_type(rr, len, dname_len);
if(!*nm) {
log_err("out of memory");
return 0;
@@ -522,18 +524,18 @@ static int
lz_enter_rr_str(struct local_zones* zones, const char* rr)
{
uint8_t* rr_name;
- uint16_t rr_class;
+ uint16_t rr_class, rr_type;
size_t len;
int labs;
struct local_zone* z;
int r;
- if(!get_rr_nameclass(rr, &rr_name, &rr_class)) {
+ if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) {
log_err("bad rr %s", rr);
return 0;
}
labs = dname_count_size_labels(rr_name, &len);
lock_rw_rdlock(&zones->lock);
- z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
+ z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
if(!z) {
lock_rw_unlock(&zones->lock);
fatal_exit("internal error: no zone for rr %s", rr);
@@ -719,9 +721,9 @@ lz_nodefault(struct config_file* cfg, const char* name)
return 0;
}
-/** enter AS112 default zone */
+/** enter (AS112) empty default zone */
static int
-add_as112_default(struct local_zones* zones, struct config_file* cfg,
+add_empty_default(struct local_zones* zones, struct config_file* cfg,
const char* name)
{
struct local_zone* z;
@@ -762,7 +764,7 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg
/* localhost. zone */
if(!lz_exists(zones, "localhost.") &&
!lz_nodefault(cfg, "localhost.")) {
- if(!(z=lz_enter_zone(zones, "localhost.", "static",
+ if(!(z=lz_enter_zone(zones, "localhost.", "redirect",
LDNS_RR_CLASS_IN)) ||
!lz_enter_rr_into_zone(z,
"localhost. 10800 IN NS localhost.") ||
@@ -816,26 +818,24 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg
lock_rw_unlock(&z->lock);
}
/* onion. zone (RFC 7686) */
- if(!lz_exists(zones, "onion.") &&
- !lz_nodefault(cfg, "onion.")) {
- if(!(z=lz_enter_zone(zones, "onion.", "static",
- LDNS_RR_CLASS_IN)) ||
- !lz_enter_rr_into_zone(z,
- "onion. 10800 IN NS localhost.") ||
- !lz_enter_rr_into_zone(z,
- "onion. 10800 IN SOA localhost. nobody.invalid. "
- "1 3600 1200 604800 10800")) {
- log_err("out of memory adding default zone");
- if(z) { lock_rw_unlock(&z->lock); }
- return 0;
- }
- lock_rw_unlock(&z->lock);
+ if(!add_empty_default(zones, cfg, "onion.")) {
+ log_err("out of memory adding default zone");
+ return 0;
+ }
+ /* test. zone (RFC 7686) */
+ if(!add_empty_default(zones, cfg, "test.")) {
+ log_err("out of memory adding default zone");
+ return 0;
+ }
+ /* invalid. zone (RFC 7686) */
+ if(!add_empty_default(zones, cfg, "invalid.")) {
+ log_err("out of memory adding default zone");
+ return 0;
}
-
/* block AS112 zones, unless asked not to */
if(!cfg->unblock_lan_zones) {
for(zstr = as112_zones; *zstr; zstr++) {
- if(!add_as112_default(zones, cfg, *zstr)) {
+ if(!add_empty_default(zones, cfg, *zstr)) {
log_err("out of memory adding default zone");
return 0;
}
@@ -913,16 +913,17 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
init_parents(zones); /* to enable local_zones_lookup() */
for(p = cfg->local_data; p; p = p->next) {
uint8_t* rr_name;
- uint16_t rr_class;
+ uint16_t rr_class, rr_type;
size_t len;
int labs;
- if(!get_rr_nameclass(p->str, &rr_name, &rr_class)) {
+ if(!get_rr_nameclass(p->str, &rr_name, &rr_class, &rr_type)) {
log_err("Bad local-data RR %s", p->str);
return 0;
}
labs = dname_count_size_labels(rr_name, &len);
lock_rw_rdlock(&zones->lock);
- if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) {
+ if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
+ rr_type)) {
if(!have_name) {
dclass = rr_class;
nm = rr_name;
@@ -1053,21 +1054,26 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
struct local_zone*
local_zones_lookup(struct local_zones* zones,
- uint8_t* name, size_t len, int labs, uint16_t dclass)
+ uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype)
{
return local_zones_tags_lookup(zones, name, len, labs,
- dclass, NULL, 0, 1);
+ dclass, dtype, NULL, 0, 1);
}
struct local_zone*
local_zones_tags_lookup(struct local_zones* zones,
- uint8_t* name, size_t len, int labs, uint16_t dclass,
+ uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
uint8_t* taglist, size_t taglen, int ignoretags)
{
rbnode_type* res = NULL;
struct local_zone *result;
struct local_zone key;
int m;
+ /* for type DS use a zone higher when on a zonecut */
+ if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) {
+ dname_remove_label(&name, &len);
+ labs--;
+ }
key.node.key = &key;
key.dclass = dclass;
key.name = name;
@@ -1583,7 +1589,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
if(view->local_zones &&
(z = local_zones_lookup(view->local_zones,
qinfo->qname, qinfo->qname_len, labs,
- qinfo->qclass))) {
+ qinfo->qclass, qinfo->qtype))) {
verbose(VERB_ALGO,
"using localzone from view: %s",
view->name);
@@ -1600,8 +1606,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
/* try global local_zones tree */
lock_rw_rdlock(&zones->lock);
if(!(z = local_zones_tags_lookup(zones, qinfo->qname,
- qinfo->qname_len, labs, qinfo->qclass, taglist,
- taglen, 0))) {
+ qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype,
+ taglist, taglen, 0))) {
lock_rw_unlock(&zones->lock);
return 0;
}
@@ -1756,19 +1762,19 @@ int
local_zones_add_RR(struct local_zones* zones, const char* rr)
{
uint8_t* rr_name;
- uint16_t rr_class;
+ uint16_t rr_class, rr_type;
size_t len;
int labs;
struct local_zone* z;
int r;
- if(!get_rr_nameclass(rr, &rr_name, &rr_class)) {
+ if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) {
return 0;
}
labs = dname_count_size_labels(rr_name, &len);
/* could first try readlock then get writelock if zone does not exist,
* but we do not add enough RRs (from multiple threads) to optimize */
lock_rw_wrlock(&zones->lock);
- z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
+ z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
if(!z) {
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
local_zone_transparent);
@@ -1820,14 +1826,47 @@ del_empty_term(struct local_zone* z, struct local_data* d,
}
}
+/** find and remove type from list in domain struct */
+static void
+del_local_rrset(struct local_data* d, uint16_t dtype)
+{
+ struct local_rrset* prev=NULL, *p=d->rrsets;
+ while(p && ntohs(p->rrset->rk.type) != dtype) {
+ prev = p;
+ p = p->next;
+ }
+ if(!p)
+ return; /* rrset type not found */
+ /* unlink it */
+ if(prev) prev->next = p->next;
+ else d->rrsets = p->next;
+ /* no memory recycling for zone deletions ... */
+}
+
void local_zones_del_data(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass)
{
/* find zone */
struct local_zone* z;
struct local_data* d;
+
+ /* remove DS */
+ lock_rw_rdlock(&zones->lock);
+ z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
+ if(z) {
+ lock_rw_wrlock(&z->lock);
+ d = lz_find_node(z, name, len, labs);
+ if(d) {
+ del_local_rrset(d, LDNS_RR_TYPE_DS);
+ del_empty_term(z, d, name, len, labs);
+ }
+ lock_rw_unlock(&z->lock);
+ }
+ lock_rw_unlock(&zones->lock);
+
+ /* remove other types */
lock_rw_rdlock(&zones->lock);
- z = local_zones_lookup(zones, name, len, labs, dclass);
+ z = local_zones_lookup(zones, name, len, labs, dclass, 0);
if(!z) {
/* no such zone, we're done */
lock_rw_unlock(&zones->lock);
diff --git a/services/localzone.h b/services/localzone.h
index fcdad41666d2c..0a8759268bb29 100644
--- a/services/localzone.h
+++ b/services/localzone.h
@@ -235,6 +235,7 @@ void local_zone_delete(struct local_zone* z);
* @param len: length of name.
* @param labs: labelcount of name.
* @param dclass: class to lookup.
+ * @param dtype: type to lookup, if type DS a zone higher is used for zonecuts.
* @param taglist: taglist to lookup.
* @param taglen: lenth of taglist.
* @param ignoretags: lookup zone by name and class, regardless the
@@ -242,7 +243,7 @@ void local_zone_delete(struct local_zone* z);
* @return closest local_zone or NULL if no covering zone is found.
*/
struct local_zone* local_zones_tags_lookup(struct local_zones* zones,
- uint8_t* name, size_t len, int labs, uint16_t dclass,
+ uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
uint8_t* taglist, size_t taglen, int ignoretags);
/**
@@ -253,10 +254,12 @@ struct local_zone* local_zones_tags_lookup(struct local_zones* zones,
* @param len: length of name.
* @param labs: labelcount of name.
* @param dclass: class to lookup.
+ * @param dtype: type of the record, if type DS then a zone higher up is found
+ * pass 0 to just plain find a zone for a name.
* @return closest local_zone or NULL if no covering zone is found.
*/
struct local_zone* local_zones_lookup(struct local_zones* zones,
- uint8_t* name, size_t len, int labs, uint16_t dclass);
+ uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype);
/**
* Debug helper. Print all zones
diff --git a/services/outside_network.c b/services/outside_network.c
index 9b1490e643f84..fe2b55b1ac177 100644
--- a/services/outside_network.c
+++ b/services/outside_network.c
@@ -268,6 +268,13 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
if (connectx(s, &endpoints, SAE_ASSOCID_ANY,
CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE,
NULL, 0, NULL, NULL) == -1) {
+ /* if fails, failover to connect for OSX 10.10 */
+#ifdef EINPROGRESS
+ if(errno != EINPROGRESS) {
+#else
+ if(1) {
+#endif
+ if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) {
#else /* USE_OSX_MSG_FASTOPEN*/
#ifdef USE_MSG_FASTOPEN
pend->c->tcp_do_fastopen = 1;
@@ -302,6 +309,10 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
#ifdef USE_MSG_FASTOPEN
}
#endif /* USE_MSG_FASTOPEN */
+#ifdef USE_OSX_MSG_FASTOPEN
+ }
+ }
+#endif /* USE_OSX_MSG_FASTOPEN */
if(w->outnet->sslctx && w->ssl_upstream) {
pend->c->ssl = outgoing_ssl_fd(w->outnet->sslctx, s);
if(!pend->c->ssl) {