diff options
Diffstat (limited to 'services')
| -rw-r--r-- | services/authzone.c | 2 | ||||
| -rw-r--r-- | services/cache/dns.c | 3 | ||||
| -rw-r--r-- | services/cache/infra.c | 2 | ||||
| -rw-r--r-- | services/listen_dnsport.c | 7 | ||||
| -rw-r--r-- | services/localzone.c | 111 | ||||
| -rw-r--r-- | services/localzone.h | 7 | ||||
| -rw-r--r-- | services/outside_network.c | 11 |
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) { |
