diff options
author | des <des@FreeBSD.org> | 2014-07-29 20:57:38 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2014-07-29 20:57:38 +0000 |
commit | fe6d9379787eb938c503444ce243caa89cc7b08c (patch) | |
tree | 5cc01e837e3c2f3dfb21ef0136ca69be1f957059 /contrib/unbound/daemon | |
parent | 1f52ac9340be3979c9bf100fe65c551bcd870cc6 (diff) | |
download | FreeBSD-src-fe6d9379787eb938c503444ce243caa89cc7b08c.zip FreeBSD-src-fe6d9379787eb938c503444ce243caa89cc7b08c.tar.gz |
MFH (r266114, r266138): upgrade to latest ldns and unbound
MFH (r266139-r266143, r266145, r266149, r266150): fix props
MFH (r266179, r266180, r266193, r266238, r266777): misc cleanup
MFH (r266863): create and use /var/unbound/conf.d
MFH (r268839): import unblock-lan-zones patch from upstream
MFH (r268840): fix reverse lookups on private networks
MFH (r268883): avoid spamming source tree during build
PR: 190739 (for r268883)
Diffstat (limited to 'contrib/unbound/daemon')
-rw-r--r-- | contrib/unbound/daemon/acl_list.c | 24 | ||||
-rw-r--r-- | contrib/unbound/daemon/acl_list.h | 24 | ||||
-rw-r--r-- | contrib/unbound/daemon/cachedump.c | 298 | ||||
-rw-r--r-- | contrib/unbound/daemon/cachedump.h | 20 | ||||
-rw-r--r-- | contrib/unbound/daemon/daemon.c | 100 | ||||
-rw-r--r-- | contrib/unbound/daemon/daemon.h | 27 | ||||
-rw-r--r-- | contrib/unbound/daemon/remote.c | 209 | ||||
-rw-r--r-- | contrib/unbound/daemon/remote.h | 20 | ||||
-rw-r--r-- | contrib/unbound/daemon/stats.c | 39 | ||||
-rw-r--r-- | contrib/unbound/daemon/stats.h | 24 | ||||
-rw-r--r-- | contrib/unbound/daemon/unbound.c | 32 | ||||
-rw-r--r-- | contrib/unbound/daemon/worker.c | 302 | ||||
-rw-r--r-- | contrib/unbound/daemon/worker.h | 20 |
13 files changed, 621 insertions, 518 deletions
diff --git a/contrib/unbound/daemon/acl_list.c b/contrib/unbound/daemon/acl_list.c index 48c8e0f..84d099c 100644 --- a/contrib/unbound/daemon/acl_list.c +++ b/contrib/unbound/daemon/acl_list.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -103,6 +103,10 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2, control = acl_deny; else if(strcmp(s2, "refuse") == 0) control = acl_refuse; + else if(strcmp(s2, "deny_non_local") == 0) + control = acl_deny_non_local; + else if(strcmp(s2, "refuse_non_local") == 0) + control = acl_refuse_non_local; else if(strcmp(s2, "allow_snoop") == 0) control = acl_allow_snoop; else { diff --git a/contrib/unbound/daemon/acl_list.h b/contrib/unbound/daemon/acl_list.h index 03ac301..2323697 100644 --- a/contrib/unbound/daemon/acl_list.h +++ b/contrib/unbound/daemon/acl_list.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -55,6 +55,10 @@ enum acl_access { acl_deny = 0, /** disallow access, send a polite 'REFUSED' reply */ acl_refuse, + /** disallow any access to zones that aren't local, drop it */ + acl_deny_non_local, + /** disallow access to zones that aren't local, 'REFUSED' reply */ + acl_refuse_non_local, /** allow full access for recursion (+RD) queries */ acl_allow, /** allow full access for all queries, recursion and cache snooping */ diff --git a/contrib/unbound/daemon/cachedump.c b/contrib/unbound/daemon/cachedump.c index 9d941d7..cf5b1a1 100644 --- a/contrib/unbound/daemon/cachedump.c +++ b/contrib/unbound/daemon/cachedump.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,7 +40,7 @@ * to text format. */ #include "config.h" -#include <ldns/ldns.h> +#include <openssl/ssl.h> #include "daemon/cachedump.h" #include "daemon/remote.h" #include "daemon/worker.h" @@ -56,70 +56,25 @@ #include "iterator/iter_utils.h" #include "iterator/iter_fwd.h" #include "iterator/iter_hints.h" - -/** convert to ldns rr */ -static ldns_rr* -to_rr(struct ub_packed_rrset_key* k, struct packed_rrset_data* d, - uint32_t now, size_t i, uint16_t type) -{ - ldns_rr* rr = ldns_rr_new(); - ldns_rdf* rdf; - ldns_status status; - size_t pos; - log_assert(i < d->count + d->rrsig_count); - if(!rr) { - return NULL; - } - ldns_rr_set_type(rr, type); - ldns_rr_set_class(rr, ntohs(k->rk.rrset_class)); - if(d->rr_ttl[i] < now) - ldns_rr_set_ttl(rr, 0); - else ldns_rr_set_ttl(rr, d->rr_ttl[i] - now); - pos = 0; - status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos); - if(status != LDNS_STATUS_OK) { - /* we drop detailed error in status */ - ldns_rr_free(rr); - return NULL; - } - ldns_rr_set_owner(rr, rdf); - pos = 0; - status = ldns_wire2rdf(rr, d->rr_data[i], d->rr_len[i], &pos); - if(status != LDNS_STATUS_OK) { - /* we drop detailed error in status */ - ldns_rr_free(rr); - return NULL; - } - return rr; -} +#include "ldns/sbuffer.h" +#include "ldns/wire2str.h" +#include "ldns/str2wire.h" /** dump one rrset zonefile line */ static int -dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, - struct packed_rrset_data* d, uint32_t now, size_t i, uint16_t type) +dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) { - char* s; - ldns_rr* rr = to_rr(k, d, now, i, type); - if(!rr) { - return ssl_printf(ssl, "BADRR\n"); - } - s = ldns_rr2str(rr); - ldns_rr_free(rr); - if(!s) { + char s[65535]; + if(!packed_rr_to_string(k, i, now, s, sizeof(s))) { return ssl_printf(ssl, "BADRR\n"); } - if(!ssl_printf(ssl, "%s", s)) { - free(s); - return 0; - } - free(s); - return 1; + return ssl_printf(ssl, "%s", s); } /** dump rrset key and data info */ static int dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, - struct packed_rrset_data* d, uint32_t now) + struct packed_rrset_data* d, time_t now) { size_t i; /* rd lock held by caller */ @@ -127,29 +82,23 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, if(d->ttl < now) return 1; /* expired */ /* meta line */ - if(!ssl_printf(ssl, ";rrset%s %u %u %u %d %d\n", + if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n", (k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"", - (unsigned)(d->ttl - now), + (long long)(d->ttl - now), (unsigned)d->count, (unsigned)d->rrsig_count, (int)d->trust, (int)d->security )) return 0; - for(i=0; i<d->count; i++) { - if(!dump_rrset_line(ssl, k, d, now, i, ntohs(k->rk.type))) + for(i=0; i<d->count + d->rrsig_count; i++) { + if(!dump_rrset_line(ssl, k, now, i)) return 0; } - for(i=0; i<d->rrsig_count; i++) { - if(!dump_rrset_line(ssl, k, d, now, i+d->count, - LDNS_RR_TYPE_RRSIG)) - return 0; - } - return 1; } /** dump lruhash rrset cache */ static int -dump_rrset_lruhash(SSL* ssl, struct lruhash* h, uint32_t now) +dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now) { struct lruhash_entry* e; /* lruhash already locked by caller */ @@ -189,20 +138,10 @@ dump_rrset_cache(SSL* ssl, struct worker* worker) static int dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) { - ldns_rdf* rdf; - ldns_status status; - size_t pos; char* nm, *tp, *cl; - - pos = 0; - status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos); - if(status != LDNS_STATUS_OK) { - return ssl_printf(ssl, "BADREF\n"); - } - nm = ldns_rdf2str(rdf); - ldns_rdf_deep_free(rdf); - tp = ldns_rr_type2str(ntohs(k->rk.type)); - cl = ldns_rr_class2str(ntohs(k->rk.rrset_class)); + nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len); + tp = sldns_wire2str_type(ntohs(k->rk.type)); + cl = sldns_wire2str_class(ntohs(k->rk.rrset_class)); if(!nm || !cl || !tp) { free(nm); free(tp); @@ -225,25 +164,16 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) /** dump message entry */ static int dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, - uint32_t now) + time_t now) { size_t i; char* nm, *tp, *cl; - ldns_rdf* rdf; - ldns_status status; - size_t pos; if(!k || !d) return 1; if(d->ttl < now) return 1; /* expired */ - pos = 0; - status = ldns_wire2dname(&rdf, k->qname, k->qname_len, &pos); - if(status != LDNS_STATUS_OK) { - return 1; /* skip this entry */ - } - nm = ldns_rdf2str(rdf); - ldns_rdf_deep_free(rdf); - tp = ldns_rr_type2str(k->qtype); - cl = ldns_rr_class2str(k->qclass); + nm = sldns_wire2str_dname(k->qname, k->qname_len); + tp = sldns_wire2str_type(k->qtype); + cl = sldns_wire2str_class(k->qclass); if(!nm || !tp || !cl) { free(nm); free(tp); @@ -259,10 +189,10 @@ dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, } /* meta line */ - if(!ssl_printf(ssl, "msg %s %s %s %d %d %u %d %u %u %u\n", + if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u\n", nm, cl, tp, (int)d->flags, (int)d->qdcount, - (unsigned)(d->ttl-now), (int)d->security, + (long long)(d->ttl-now), (int)d->security, (unsigned)d->an_numrrsets, (unsigned)d->ns_numrrsets, (unsigned)d->ar_numrrsets)) { @@ -369,96 +299,74 @@ dump_cache(SSL* ssl, struct worker* worker) /** read a line from ssl into buffer */ static int -ssl_read_buf(SSL* ssl, ldns_buffer* buf) +ssl_read_buf(SSL* ssl, sldns_buffer* buf) { - return ssl_read_line(ssl, (char*)ldns_buffer_begin(buf), - ldns_buffer_capacity(buf)); + return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf), + sldns_buffer_capacity(buf)); } /** check fixed text on line */ static int -read_fixed(SSL* ssl, ldns_buffer* buf, const char* str) +read_fixed(SSL* ssl, sldns_buffer* buf, const char* str) { if(!ssl_read_buf(ssl, buf)) return 0; - return (strcmp((char*)ldns_buffer_begin(buf), str) == 0); + return (strcmp((char*)sldns_buffer_begin(buf), str) == 0); } /** load an RR into rrset */ static int -load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region, +load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region, struct ub_packed_rrset_key* rk, struct packed_rrset_data* d, - unsigned int i, int is_rrsig, int* go_on, uint32_t now) + unsigned int i, int is_rrsig, int* go_on, time_t now) { - ldns_rr* rr; - ldns_status status; + uint8_t rr[LDNS_RR_BUF_SIZE]; + size_t rr_len = sizeof(rr), dname_len = 0; + int status; /* read the line */ if(!ssl_read_buf(ssl, buf)) return 0; - if(strncmp((char*)ldns_buffer_begin(buf), "BADRR\n", 6) == 0) { + if(strncmp((char*)sldns_buffer_begin(buf), "BADRR\n", 6) == 0) { *go_on = 0; return 1; } - status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf), - LDNS_DEFAULT_TTL, NULL, NULL); - if(status != LDNS_STATUS_OK) { + status = sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr, + &rr_len, &dname_len, 3600, NULL, 0, NULL, 0); + if(status != 0) { log_warn("error cannot parse rr: %s: %s", - ldns_get_errorstr_by_id(status), - (char*)ldns_buffer_begin(buf)); + sldns_get_errorstr_parse(status), + (char*)sldns_buffer_begin(buf)); return 0; } - if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) { + if(is_rrsig && sldns_wirerr_get_type(rr, rr_len, dname_len) + != LDNS_RR_TYPE_RRSIG) { log_warn("error expected rrsig but got %s", - (char*)ldns_buffer_begin(buf)); + (char*)sldns_buffer_begin(buf)); return 0; } /* convert ldns rr into packed_rr */ - d->rr_ttl[i] = ldns_rr_ttl(rr) + now; - ldns_buffer_clear(buf); - ldns_buffer_skip(buf, 2); - status = ldns_rr_rdata2buffer_wire(buf, rr); - if(status != LDNS_STATUS_OK) { - log_warn("error cannot rr2wire: %s", - ldns_get_errorstr_by_id(status)); - ldns_rr_free(rr); - return 0; - } - ldns_buffer_flip(buf); - ldns_buffer_write_u16_at(buf, 0, ldns_buffer_limit(buf) - 2); - - d->rr_len[i] = ldns_buffer_limit(buf); + d->rr_ttl[i] = (time_t)sldns_wirerr_get_ttl(rr, rr_len, dname_len) + now; + sldns_buffer_clear(buf); + d->rr_len[i] = sldns_wirerr_get_rdatalen(rr, rr_len, dname_len)+2; d->rr_data[i] = (uint8_t*)regional_alloc_init(region, - ldns_buffer_begin(buf), ldns_buffer_limit(buf)); + sldns_wirerr_get_rdatawl(rr, rr_len, dname_len), d->rr_len[i]); if(!d->rr_data[i]) { - ldns_rr_free(rr); log_warn("error out of memory"); return 0; } /* if first entry, fill the key structure */ if(i==0) { - rk->rk.type = htons(ldns_rr_get_type(rr)); - rk->rk.rrset_class = htons(ldns_rr_get_class(rr)); - ldns_buffer_clear(buf); - status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr)); - if(status != LDNS_STATUS_OK) { - log_warn("error cannot dname2buffer: %s", - ldns_get_errorstr_by_id(status)); - ldns_rr_free(rr); - return 0; - } - ldns_buffer_flip(buf); - rk->rk.dname_len = ldns_buffer_limit(buf); - rk->rk.dname = regional_alloc_init(region, - ldns_buffer_begin(buf), ldns_buffer_limit(buf)); + rk->rk.type = htons(sldns_wirerr_get_type(rr, rr_len, dname_len)); + rk->rk.rrset_class = htons(sldns_wirerr_get_class(rr, rr_len, dname_len)); + rk->rk.dname_len = dname_len; + rk->rk.dname = regional_alloc_init(region, rr, dname_len); if(!rk->rk.dname) { log_warn("error out of memory"); - ldns_rr_free(rr); return 0; } } - ldns_rr_free(rr); return 1; } @@ -489,7 +397,7 @@ move_into_cache(struct ub_packed_rrset_key* k, return 0; } s = sizeof(*ad) + (sizeof(size_t) + sizeof(uint8_t*) + - sizeof(uint32_t))* num; + sizeof(time_t))* num; for(i=0; i<num; i++) s += d->rr_len[i]; ad = (struct packed_rrset_data*)malloc(s); @@ -505,8 +413,8 @@ move_into_cache(struct ub_packed_rrset_key* k, p += sizeof(size_t)*num; memmove(p, &d->rr_data[0], sizeof(uint8_t*)*num); p += sizeof(uint8_t*)*num; - memmove(p, &d->rr_ttl[0], sizeof(uint32_t)*num); - p += sizeof(uint32_t)*num; + memmove(p, &d->rr_ttl[0], sizeof(time_t)*num); + p += sizeof(time_t)*num; for(i=0; i<num; i++) { memmove(p, d->rr_data[i], d->rr_len[i]); p += d->rr_len[i]; @@ -524,13 +432,14 @@ move_into_cache(struct ub_packed_rrset_key* k, /** load an rrset entry */ static int -load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker) +load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker) { - char* s = (char*)ldns_buffer_begin(buf); + char* s = (char*)sldns_buffer_begin(buf); struct regional* region = worker->scratchpad; struct ub_packed_rrset_key* rk; struct packed_rrset_data* d; - unsigned int ttl, rr_count, rrsig_count, trust, security; + unsigned int rr_count, rrsig_count, trust, security; + long long ttl; unsigned int i; int go_on = 1; regional_free_all(region); @@ -552,7 +461,7 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker) s += 10; rk->rk.flags |= PACKED_RRSET_NSEC_AT_APEX; } - if(sscanf(s, " %u %u %u %u %u", &ttl, &rr_count, &rrsig_count, + if(sscanf(s, " " ARG_LL "d %u %u %u %u", &ttl, &rr_count, &rrsig_count, &trust, &security) != 5) { log_warn("error bad rrset spec %s", s); return 0; @@ -565,12 +474,12 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker) d->rrsig_count = (size_t)rrsig_count; d->security = (enum sec_status)security; d->trust = (enum rrset_trust)trust; - d->ttl = (uint32_t)ttl + *worker->env.now; + d->ttl = (time_t)ttl + *worker->env.now; d->rr_len = regional_alloc_zero(region, sizeof(size_t)*(d->count+d->rrsig_count)); d->rr_ttl = regional_alloc_zero(region, - sizeof(uint32_t)*(d->count+d->rrsig_count)); + sizeof(time_t)*(d->count+d->rrsig_count)); d->rr_data = regional_alloc_zero(region, sizeof(uint8_t*)*(d->count+d->rrsig_count)); if(!d->rr_len || !d->rr_ttl || !d->rr_data) { @@ -605,10 +514,10 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker) static int load_rrset_cache(SSL* ssl, struct worker* worker) { - ldns_buffer* buf = worker->env.scratch_buffer; + sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0; while(ssl_read_buf(ssl, buf) && - strcmp((char*)ldns_buffer_begin(buf), "END_RRSET_CACHE")!=0) { + strcmp((char*)sldns_buffer_begin(buf), "END_RRSET_CACHE")!=0) { if(!load_rrset(ssl, buf, worker)) return 0; } @@ -617,13 +526,13 @@ load_rrset_cache(SSL* ssl, struct worker* worker) /** read qinfo from next three words */ static char* -load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf, - struct regional* region) +load_qinfo(char* str, struct query_info* qinfo, struct regional* region) { /* s is part of the buf */ char* s = str; - ldns_rr* rr; - ldns_status status; + uint8_t rr[LDNS_RR_BUF_SIZE]; + size_t rr_len = sizeof(rr), dname_len = 0; + int status; /* skip three words */ s = strchr(str, ' '); @@ -637,26 +546,17 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf, s++; /* parse them */ - status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL); - if(status != LDNS_STATUS_OK) { + status = sldns_str2wire_rr_question_buf(str, rr, &rr_len, &dname_len, + NULL, 0, NULL, 0); + if(status != 0) { log_warn("error cannot parse: %s %s", - ldns_get_errorstr_by_id(status), str); - return NULL; - } - qinfo->qtype = ldns_rr_get_type(rr); - qinfo->qclass = ldns_rr_get_class(rr); - ldns_buffer_clear(buf); - status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr)); - ldns_rr_free(rr); - if(status != LDNS_STATUS_OK) { - log_warn("error cannot dname2wire: %s", - ldns_get_errorstr_by_id(status)); + sldns_get_errorstr_parse(status), str); return NULL; } - ldns_buffer_flip(buf); - qinfo->qname_len = ldns_buffer_limit(buf); - qinfo->qname = (uint8_t*)regional_alloc_init(region, - ldns_buffer_begin(buf), ldns_buffer_limit(buf)); + qinfo->qtype = sldns_wirerr_get_type(rr, rr_len, dname_len); + qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len); + qinfo->qname_len = dname_len; + qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len); if(!qinfo->qname) { log_warn("error out of memory"); return NULL; @@ -667,11 +567,11 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf, /** load a msg rrset reference */ static int -load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker, +load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, struct regional *region, struct ub_packed_rrset_key** rrset, int* go_on) { - char* s = (char*)ldns_buffer_begin(buf); + char* s = (char*)sldns_buffer_begin(buf); struct query_info qinfo; unsigned int flags; struct ub_packed_rrset_key* k; @@ -684,7 +584,7 @@ load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker, return 1; } - s = load_qinfo(s, &qinfo, buf, region); + s = load_qinfo(s, &qinfo, region); if(!s) { return 0; } @@ -712,13 +612,14 @@ load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker, /** load a msg entry */ static int -load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker) +load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) { struct regional* region = worker->scratchpad; struct query_info qinf; struct reply_info rep; - char* s = (char*)ldns_buffer_begin(buf); - unsigned int flags, qdcount, ttl, security, an, ns, ar; + char* s = (char*)sldns_buffer_begin(buf); + unsigned int flags, qdcount, security, an, ns, ar; + long long ttl; size_t i; int go_on = 1; @@ -729,20 +630,20 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker) return 0; } s += 4; - s = load_qinfo(s, &qinf, buf, region); + s = load_qinfo(s, &qinf, region); if(!s) { return 0; } /* read remainder of line */ - if(sscanf(s, " %u %u %u %u %u %u %u", &flags, &qdcount, &ttl, + if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u", &flags, &qdcount, &ttl, &security, &an, &ns, &ar) != 7) { log_warn("error cannot parse numbers: %s", s); return 0; } rep.flags = (uint16_t)flags; rep.qdcount = (uint16_t)qdcount; - rep.ttl = (uint32_t)ttl; + rep.ttl = (time_t)ttl; rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl); rep.security = (enum sec_status)security; rep.an_numrrsets = (size_t)an; @@ -774,10 +675,10 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker) static int load_msg_cache(SSL* ssl, struct worker* worker) { - ldns_buffer* buf = worker->env.scratch_buffer; + sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0; while(ssl_read_buf(ssl, buf) && - strcmp((char*)ldns_buffer_begin(buf), "END_MSG_CACHE")!=0) { + strcmp((char*)sldns_buffer_begin(buf), "END_MSG_CACHE")!=0) { if(!load_msg(ssl, buf, worker)) return 0; } @@ -800,8 +701,9 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) { char buf[257]; struct delegpt_addr* a; - int lame, dlame, rlame, rto, edns_vs, to, delay, entry_ttl, + int lame, dlame, rlame, rto, edns_vs, to, delay, tA = 0, tAAAA = 0, tother = 0; + long long entry_ttl; struct rtt_info ri; uint8_t edns_lame_known; for(a = dp->target_list; a; a = a->next_target) { @@ -840,8 +742,8 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) return; continue; /* skip stuff not in infra cache */ } - if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl %d, ping %d " - "var %d rtt %d, tA %d, tAAAA %d, tother %d", + if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl " ARG_LL "d, " + "ping %d var %d rtt %d, tA %d, tAAAA %d, tother %d", lame?"LAME ":"", dlame?"NoDNSSEC ":"", a->lame?"AddrWasParentSide ":"", rlame?"NoAuthButRecursive ":"", rto, entry_ttl, diff --git a/contrib/unbound/daemon/cachedump.h b/contrib/unbound/daemon/cachedump.h index da9804f..0f2feab 100644 --- a/contrib/unbound/daemon/cachedump.h +++ b/contrib/unbound/daemon/cachedump.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/contrib/unbound/daemon/daemon.c b/contrib/unbound/daemon/daemon.c index b91683f..aed22c2 100644 --- a/contrib/unbound/daemon/daemon.c +++ b/contrib/unbound/daemon/daemon.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -56,12 +56,16 @@ #include <openssl/engine.h> #endif +#ifdef HAVE_TIME_H +#include <time.h> +#endif +#include <sys/time.h> + #ifdef HAVE_NSS /* nss3 */ #include "nss.h" #endif -#include <ldns/ldns.h> #include "daemon/daemon.h" #include "daemon/worker.h" #include "daemon/remote.h" @@ -80,6 +84,7 @@ #include "util/random.h" #include "util/tube.h" #include "util/net_help.h" +#include "ldns/keyraw.h" #include <signal.h> /** How many quit requests happened. */ @@ -203,7 +208,7 @@ daemon_init(void) OPENSSL_config("unbound"); # endif # ifdef USE_GOST - (void)ldns_key_EVP_load_gost_id(); + (void)sldns_key_EVP_load_gost_id(); # endif OpenSSL_add_all_algorithms(); # if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS @@ -250,9 +255,55 @@ daemon_open_shared_ports(struct daemon* daemon) { log_assert(daemon); if(daemon->cfg->port != daemon->listening_port) { - listening_ports_free(daemon->ports); - if(!(daemon->ports=listening_ports_open(daemon->cfg))) + size_t i; + int reuseport = 0; + struct listen_port* p0; + /* free and close old ports */ + if(daemon->ports != NULL) { + for(i=0; i<daemon->num_ports; i++) + listening_ports_free(daemon->ports[i]); + free(daemon->ports); + daemon->ports = NULL; + } + /* see if we want to reuseport */ +#if defined(__linux__) && defined(SO_REUSEPORT) + if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0) + reuseport = 1; +#endif + /* try to use reuseport */ + p0 = listening_ports_open(daemon->cfg, &reuseport); + if(!p0) { + listening_ports_free(p0); return 0; + } + if(reuseport) { + /* reuseport was successful, allocate for it */ + daemon->num_ports = (size_t)daemon->cfg->num_threads; + } else { + /* do the normal, singleportslist thing, + * reuseport not enabled or did not work */ + daemon->num_ports = 1; + } + if(!(daemon->ports = (struct listen_port**)calloc( + daemon->num_ports, sizeof(*daemon->ports)))) { + listening_ports_free(p0); + return 0; + } + daemon->ports[0] = p0; + if(reuseport) { + /* continue to use reuseport */ + for(i=1; i<daemon->num_ports; i++) { + if(!(daemon->ports[i]= + listening_ports_open(daemon->cfg, + &reuseport)) || !reuseport ) { + for(i=0; i<daemon->num_ports; i++) + listening_ports_free(daemon->ports[i]); + free(daemon->ports); + daemon->ports = NULL; + return 0; + } + } + } daemon->listening_port = daemon->cfg->port; } if(!daemon->cfg->remote_control_enable && daemon->rc_port) { @@ -389,6 +440,7 @@ static void* thread_start(void* arg) { struct worker* worker = (struct worker*)arg; + int port_num = 0; log_thread_set(&worker->thread_num); ub_thread_blocksigs(); #ifdef THREADS_DISABLED @@ -396,7 +448,14 @@ thread_start(void* arg) tube_close_write(worker->cmd); close_other_pipes(worker->daemon, worker->thread_num); #endif - if(!worker_init(worker, worker->daemon->cfg, worker->daemon->ports, 0)) +#if defined(__linux__) && defined(SO_REUSEPORT) + if(worker->daemon->cfg->so_reuseport) + port_num = worker->thread_num; + else + port_num = 0; +#endif + if(!worker_init(worker, worker->daemon->cfg, + worker->daemon->ports[port_num], 0)) fatal_exit("Could not initialize thread"); worker_work(worker); @@ -469,7 +528,7 @@ daemon_fork(struct daemon* daemon) #if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) /* in libev the first inited base gets signals */ - if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1)) + if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1)) fatal_exit("Could not initialize main thread"); #endif @@ -483,7 +542,7 @@ daemon_fork(struct daemon* daemon) */ #if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) /* libevent has the last inited base get signals (or any base) */ - if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1)) + if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1)) fatal_exit("Could not initialize main thread"); #endif signal_handling_playback(daemon->workers[0]); @@ -529,11 +588,14 @@ daemon_cleanup(struct daemon* daemon) void daemon_delete(struct daemon* daemon) { + size_t i; if(!daemon) return; modstack_desetup(&daemon->mods, daemon->env); daemon_remote_delete(daemon->rc); - listening_ports_free(daemon->ports); + for(i = 0; i < daemon->num_ports; i++) + listening_ports_free(daemon->ports[i]); + free(daemon->ports); listening_ports_free(daemon->rc_ports); if(daemon->env) { slabhash_delete(daemon->env->msg_cache); @@ -558,7 +620,7 @@ daemon_delete(struct daemon* daemon) /* libcrypto cleanup */ #ifdef HAVE_SSL # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) - ldns_key_EVP_unload_gost(); + sldns_key_EVP_unload_gost(); # endif # if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE # ifndef S_SPLINT_S diff --git a/contrib/unbound/daemon/daemon.h b/contrib/unbound/daemon/daemon.h index 8e47ea0..855b0d3 100644 --- a/contrib/unbound/daemon/daemon.h +++ b/contrib/unbound/daemon/daemon.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -72,8 +72,11 @@ struct daemon { char* pidfile; /** port number that has ports opened. */ int listening_port; - /** listening ports, opened, to be shared by threads */ - struct listen_port* ports; + /** array of listening ports, opened. Listening ports per worker, + * or just one element[0] shared by the worker threads. */ + struct listen_port** ports; + /** size of ports array */ + size_t num_ports; /** port number for remote that has ports opened. */ int rc_port; /** listening ports for remote control */ diff --git a/contrib/unbound/daemon/remote.c b/contrib/unbound/daemon/remote.c index ba02d7d..6882e16 100644 --- a/contrib/unbound/daemon/remote.c +++ b/contrib/unbound/daemon/remote.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -47,7 +47,6 @@ #include <openssl/err.h> #endif #include <ctype.h> -#include <ldns/ldns.h> #include "daemon/remote.h" #include "daemon/worker.h" #include "daemon/daemon.h" @@ -75,6 +74,10 @@ #include "iterator/iter_delegpt.h" #include "services/outbound_list.h" #include "services/outside_network.h" +#include "ldns/str2wire.h" +#include "ldns/parseutil.h" +#include "ldns/wire2str.h" +#include "ldns/sbuffer.h" #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> @@ -268,7 +271,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err) } /* open fd */ - fd = create_tcp_accept_sock(res, 1, &noproto); + fd = create_tcp_accept_sock(res, 1, &noproto, 0); freeaddrinfo(res); if(fd == -1 && noproto) { if(!noproto_is_err) @@ -629,8 +632,8 @@ print_stats(SSL* ssl, const char* nm, struct stats_info* s) if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%u\n", nm, (unsigned)s->mesh_num_reply_states)) return 0; timeval_divide(&avg, &s->mesh_replies_sum_wait, s->mesh_replies_sent); - if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ"%d.%6.6d\n", nm, - (int)avg.tv_sec, (int)avg.tv_usec)) return 0; + if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ ARG_LL "d.%6.6d\n", nm, + (long long)avg.tv_sec, (int)avg.tv_usec)) return 0; if(!ssl_printf(ssl, "%s.recursion.time.median"SQ"%g\n", nm, s->mesh_time_median)) return 0; return 1; @@ -713,12 +716,12 @@ print_uptime(SSL* ssl, struct worker* worker, int reset) timeval_subtract(&dt, &now, &worker->daemon->time_last_stat); if(reset) worker->daemon->time_last_stat = now; - if(!ssl_printf(ssl, "time.now"SQ"%d.%6.6d\n", - (unsigned)now.tv_sec, (unsigned)now.tv_usec)) return 0; - if(!ssl_printf(ssl, "time.up"SQ"%d.%6.6d\n", - (unsigned)up.tv_sec, (unsigned)up.tv_usec)) return 0; - if(!ssl_printf(ssl, "time.elapsed"SQ"%d.%6.6d\n", - (unsigned)dt.tv_sec, (unsigned)dt.tv_usec)) return 0; + if(!ssl_printf(ssl, "time.now"SQ ARG_LL "d.%6.6d\n", + (long long)now.tv_sec, (unsigned)now.tv_usec)) return 0; + if(!ssl_printf(ssl, "time.up"SQ ARG_LL "d.%6.6d\n", + (long long)up.tv_sec, (unsigned)up.tv_usec)) return 0; + if(!ssl_printf(ssl, "time.elapsed"SQ ARG_LL "d.%6.6d\n", + (long long)dt.tv_sec, (unsigned)dt.tv_usec)) return 0; return 1; } @@ -756,13 +759,13 @@ print_ext(SSL* ssl, struct stats_info* s) { int i; char nm[16]; - const ldns_rr_descriptor* desc; - const ldns_lookup_table* lt; + const sldns_rr_descriptor* desc; + const sldns_lookup_table* lt; /* TYPE */ for(i=0; i<STATS_QTYPE_NUM; i++) { if(inhibit_zero && s->svr.qtype[i] == 0) continue; - desc = ldns_rr_descript((uint16_t)i); + desc = sldns_rr_descript((uint16_t)i); if(desc && desc->_name) { snprintf(nm, sizeof(nm), "%s", desc->_name); } else if (i == LDNS_RR_TYPE_IXFR) { @@ -789,7 +792,7 @@ print_ext(SSL* ssl, struct stats_info* s) for(i=0; i<STATS_QCLASS_NUM; i++) { if(inhibit_zero && s->svr.qclass[i] == 0) continue; - lt = ldns_lookup_by_id(ldns_rr_classes, i); + lt = sldns_lookup_by_id(sldns_rr_classes, i); if(lt && lt->name) { snprintf(nm, sizeof(nm), "%s", lt->name); } else { @@ -806,7 +809,7 @@ print_ext(SSL* ssl, struct stats_info* s) for(i=0; i<STATS_OPCODE_NUM; i++) { if(inhibit_zero && s->svr.qopcode[i] == 0) continue; - lt = ldns_lookup_by_id(ldns_opcodes, i); + lt = sldns_lookup_by_id(sldns_opcodes, i); if(lt && lt->name) { snprintf(nm, sizeof(nm), "%s", lt->name); } else { @@ -846,7 +849,7 @@ print_ext(SSL* ssl, struct stats_info* s) for(i=0; i<STATS_RCODE_NUM; i++) { if(inhibit_zero && s->svr.ans_rcode[i] == 0) continue; - lt = ldns_lookup_by_id(ldns_rcodes, i); + lt = sldns_lookup_by_id(sldns_rcodes, i); if(lt && lt->name) { snprintf(nm, sizeof(nm), "%s", lt->name); } else { @@ -912,17 +915,20 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset) static int parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) { - ldns_rdf* rdf; + uint8_t nm[LDNS_MAX_DOMAINLEN+1]; + size_t nmlen = sizeof(nm); + int status; *res = NULL; *len = 0; *labs = 0; - rdf = ldns_dname_new_frm_str(str); - if(!rdf) { - ssl_printf(ssl, "error cannot parse name %s\n", str); + status = sldns_str2wire_dname_buf(str, nm, &nmlen); + if(status != 0) { + ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", str, + LDNS_WIREPARSE_OFFSET(status), + sldns_get_errorstr_parse(status)); return 0; } - *res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf)); - ldns_rdf_deep_free(rdf); + *res = memdup(nm, nmlen); if(!*res) { ssl_printf(ssl, "error out of memory\n"); return 0; @@ -975,7 +981,7 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg) free(nm); return; } - lock_quick_lock(&worker->daemon->local_zones->lock); + lock_rw_wrlock(&worker->daemon->local_zones->lock); if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* already present in tree */ @@ -983,17 +989,17 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg) z->type = t; /* update type anyway */ lock_rw_unlock(&z->lock); free(nm); - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); send_ok(ssl); return; } if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, t)) { - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); ssl_printf(ssl, "error out of memory\n"); return; } - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); send_ok(ssl); } @@ -1007,13 +1013,13 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg) struct local_zone* z; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) return; - lock_quick_lock(&worker->daemon->local_zones->lock); + lock_rw_wrlock(&worker->daemon->local_zones->lock); if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* present in tree */ local_zones_del_zone(worker->daemon->local_zones, z); } - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); free(nm); send_ok(ssl); } @@ -1022,8 +1028,7 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg) static void do_data_add(SSL* ssl, struct worker* worker, char* arg) { - if(!local_zones_add_RR(worker->daemon->local_zones, arg, - worker->env.scratch_buffer)) { + if(!local_zones_add_RR(worker->daemon->local_zones, arg)) { ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg); return; } @@ -1090,7 +1095,7 @@ do_flush_type(SSL* ssl, struct worker* worker, char* arg) return; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) return; - t = ldns_get_rr_type_by_name(arg2); + t = sldns_get_rr_type_by_name(arg2); do_cache_remove(worker, nm, nmlen, t, LDNS_RR_CLASS_IN); free(nm); @@ -1118,9 +1123,9 @@ struct del_info { /** labels */ int labs; /** now */ - uint32_t now; + time_t now; /** time to invalidate to */ - uint32_t expired; + time_t expired; /** number of rrsets removed */ size_t num_rrsets; /** number of msgs removed */ @@ -1388,9 +1393,9 @@ ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt_addr* a; int f = 0; if(str) { /* print header for forward, stub */ - char* c = ldns_rr_class2str(dclass); + char* c = sldns_wire2str_class(dclass); dname_str(nm, buf); - if(!ssl_printf(ssl, "%s %s %s: ", buf, c, str)) { + if(!ssl_printf(ssl, "%s %s %s: ", buf, (c?c:"CLASS??"), str)) { free(c); return 0; } @@ -1571,7 +1576,7 @@ do_forward_add(SSL* ssl, struct worker* worker, char* args) struct delegpt* dp = NULL; if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, NULL)) return; - if(insecure) { + if(insecure && worker->env.anchors) { if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm)) { (void)ssl_printf(ssl, "error out of memory\n"); @@ -1598,7 +1603,7 @@ do_forward_remove(SSL* ssl, struct worker* worker, char* args) uint8_t* nm = NULL; if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) return; - if(insecure) + if(insecure && worker->env.anchors) anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm); forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, nm); @@ -1616,7 +1621,7 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) struct delegpt* dp = NULL; if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, &prime)) return; - if(insecure) { + if(insecure && worker->env.anchors) { if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm)) { (void)ssl_printf(ssl, "error out of memory\n"); @@ -1626,8 +1631,9 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) } } if(!forwards_add_stub_hole(fwd, LDNS_RR_CLASS_IN, nm)) { - if(insecure) anchors_delete_insecure(worker->env.anchors, - LDNS_RR_CLASS_IN, nm); + if(insecure && worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm); (void)ssl_printf(ssl, "error out of memory\n"); delegpt_free_mlc(dp); free(nm); @@ -1636,8 +1642,9 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) if(!hints_add_stub(worker->env.hints, LDNS_RR_CLASS_IN, dp, !prime)) { (void)ssl_printf(ssl, "error out of memory\n"); forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm); - if(insecure) anchors_delete_insecure(worker->env.anchors, - LDNS_RR_CLASS_IN, nm); + if(insecure && worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm); free(nm); return; } @@ -1654,7 +1661,7 @@ do_stub_remove(SSL* ssl, struct worker* worker, char* args) uint8_t* nm = NULL; if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) return; - if(insecure) + if(insecure && worker->env.anchors) anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm); forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm); @@ -1663,6 +1670,43 @@ do_stub_remove(SSL* ssl, struct worker* worker, char* args) send_ok(ssl); } +/** do the insecure_add command */ +static void +do_insecure_add(SSL* ssl, struct worker* worker, char* arg) +{ + size_t nmlen; + int nmlabs; + uint8_t* nm = NULL; + if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if(worker->env.anchors) { + if(!anchors_add_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm)) { + (void)ssl_printf(ssl, "error out of memory\n"); + free(nm); + return; + } + } + free(nm); + send_ok(ssl); +} + +/** do the insecure_remove command */ +static void +do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) +{ + size_t nmlen; + int nmlabs; + uint8_t* nm = NULL; + if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if(worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm); + free(nm); + send_ok(ssl); +} + /** do the status command */ static void do_status(SSL* ssl, struct worker* worker) @@ -1684,7 +1728,7 @@ do_status(SSL* ssl, struct worker* worker) if(!ssl_printf(ssl, " ]\n")) return; uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec; - if(!ssl_printf(ssl, "uptime: %u seconds\n", (unsigned)uptime)) + if(!ssl_printf(ssl, "uptime: " ARG_LL "d seconds\n", (long long)uptime)) return; if(!ssl_printf(ssl, "unbound (pid %d) is running...\n", (int)getpid())) @@ -1703,7 +1747,8 @@ get_mesh_age(struct mesh_state* m, char* buf, size_t len, while(r && r->next) r = r->next; timeval_subtract(&d, env->now_tv, &r->start_time); - snprintf(buf, len, "%d.%6.6d", (int)d.tv_sec, (int)d.tv_usec); + snprintf(buf, len, ARG_LL "d.%6.6d", + (long long)d.tv_sec, (int)d.tv_usec); } else { snprintf(buf, len, "-"); } @@ -1748,10 +1793,11 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m, if(m->sub_set.count == 0) snprintf(buf, len, " (empty_list)"); RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) { - char* t = ldns_rr_type2str(sub->s->s.qinfo.qtype); - char* c = ldns_rr_class2str(sub->s->s.qinfo.qclass); + char* t = sldns_wire2str_type(sub->s->s.qinfo.qtype); + char* c = sldns_wire2str_class(sub->s->s.qinfo.qclass); dname_str(sub->s->s.qinfo.qname, nm); - snprintf(buf, len, " %s %s %s", t, c, nm); + snprintf(buf, len, " %s %s %s", (t?t:"TYPE??"), + (c?c:"CLASS??"), nm); l = strlen(buf); buf += l; len -= l; free(t); @@ -1780,13 +1826,14 @@ do_dump_requestlist(SSL* ssl, struct worker* worker) mesh = worker->env.mesh; if(!mesh) return; RBTREE_FOR(m, struct mesh_state*, &mesh->all) { - char* t = ldns_rr_type2str(m->s.qinfo.qtype); - char* c = ldns_rr_class2str(m->s.qinfo.qclass); + char* t = sldns_wire2str_type(m->s.qinfo.qtype); + char* c = sldns_wire2str_class(m->s.qinfo.qclass); dname_str(m->s.qinfo.qname, buf); get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env); get_mesh_status(mesh, m, statbuf, sizeof(statbuf)); if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n", - num, t, c, buf, timebuf, statbuf)) { + num, (t?t:"TYPE??"), (c?c:"CLASS??"), buf, timebuf, + statbuf)) { free(t); free(c); return; @@ -1804,7 +1851,7 @@ struct infra_arg { /** the SSL connection */ SSL* ssl; /** the time now */ - uint32_t now; + time_t now; }; /** callback for every host element in the infra cache */ @@ -1927,7 +1974,7 @@ do_list_local_zones(SSL* ssl, struct worker* worker) struct local_zones* zones = worker->daemon->local_zones; struct local_zone* z; char buf[257]; - lock_quick_lock(&zones->lock); + lock_rw_rdlock(&zones->lock); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); dname_str(z->name, buf); @@ -1935,7 +1982,7 @@ do_list_local_zones(SSL* ssl, struct worker* worker) local_zone_type2str(z->type)); lock_rw_unlock(&z->lock); } - lock_quick_unlock(&zones->lock); + lock_rw_unlock(&zones->lock); } /** do the list_local_data command */ @@ -1946,22 +1993,30 @@ do_list_local_data(SSL* ssl, struct worker* worker) struct local_zone* z; struct local_data* d; struct local_rrset* p; - lock_quick_lock(&zones->lock); + char* s = (char*)sldns_buffer_begin(worker->env.scratch_buffer); + size_t slen = sldns_buffer_capacity(worker->env.scratch_buffer); + lock_rw_rdlock(&zones->lock); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); RBTREE_FOR(d, struct local_data*, &z->data) { for(p = d->rrsets; p; p = p->next) { - ldns_rr_list* rr = packed_rrset_to_rr_list( - p->rrset, worker->env.scratch_buffer); - char* str = ldns_rr_list2str(rr); - (void)ssl_printf(ssl, "%s", str); - free(str); - ldns_rr_list_free(rr); + struct packed_rrset_data* d = + (struct packed_rrset_data*)p->rrset->entry.data; + size_t i; + for(i=0; i<d->count + d->rrsig_count; i++) { + if(!packed_rr_to_string(p->rrset, i, + 0, s, slen)) { + if(!ssl_printf(ssl, "BADRR\n")) + return; + } + if(!ssl_printf(ssl, "%s\n", s)) + return; + } } } lock_rw_unlock(&z->lock); } - lock_quick_unlock(&zones->lock); + lock_rw_unlock(&zones->lock); } /** tell other processes to execute the command */ @@ -2050,6 +2105,16 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, if(rc) distribute_cmd(rc, ssl, cmd); do_forward_remove(ssl, worker, skipwhite(p+14)); return; + } else if(cmdcmp(p, "insecure_add", 12)) { + /* must always distribute this cmd */ + if(rc) distribute_cmd(rc, ssl, cmd); + do_insecure_add(ssl, worker, skipwhite(p+12)); + return; + } else if(cmdcmp(p, "insecure_remove", 15)) { + /* must always distribute this cmd */ + if(rc) distribute_cmd(rc, ssl, cmd); + do_insecure_remove(ssl, worker, skipwhite(p+15)); + return; } else if(cmdcmp(p, "forward", 7)) { /* must always distribute this cmd */ if(rc) distribute_cmd(rc, ssl, cmd); diff --git a/contrib/unbound/daemon/remote.h b/contrib/unbound/daemon/remote.h index 7d922bd..cc670b7 100644 --- a/contrib/unbound/daemon/remote.h +++ b/contrib/unbound/daemon/remote.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/contrib/unbound/daemon/stats.c b/contrib/unbound/daemon/stats.c index 9a1a7d2..57ad1ef 100644 --- a/contrib/unbound/daemon/stats.c +++ b/contrib/unbound/daemon/stats.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,7 +40,11 @@ * numbers. These 'statistics' may be of interest to the operator. */ #include "config.h" -#include <ldns/wire2host.h> +#ifdef HAVE_TIME_H +#include <time.h> +#endif +#include <sys/time.h> +#include <sys/types.h> #include "daemon/stats.h" #include "daemon/worker.h" #include "daemon/daemon.h" @@ -51,6 +55,7 @@ #include "util/timehist.h" #include "util/net_help.h" #include "validator/validator.h" +#include "ldns/sbuffer.h" /** add timers and the values do not overflow or become negative */ static void @@ -257,14 +262,14 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c, uint16_t qtype, uint16_t qclass, struct edns_data* edns, struct comm_reply* repinfo) { - uint16_t flags = ldns_buffer_read_u16_at(c->buffer, 2); + uint16_t flags = sldns_buffer_read_u16_at(c->buffer, 2); if(qtype < STATS_QTYPE_NUM) stats->qtype[qtype]++; else stats->qtype_big++; if(qclass < STATS_QCLASS_NUM) stats->qclass[qclass]++; else stats->qclass_big++; - stats->qopcode[ LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) ]++; + stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++; if(c->type != comm_udp) stats->qtcp++; if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen)) @@ -292,12 +297,12 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c, } } -void server_stats_insrcode(struct server_stats* stats, ldns_buffer* buf) +void server_stats_insrcode(struct server_stats* stats, sldns_buffer* buf) { - if(stats->extended && ldns_buffer_limit(buf) != 0) { - int r = (int)LDNS_RCODE_WIRE( ldns_buffer_begin(buf) ); + if(stats->extended && sldns_buffer_limit(buf) != 0) { + int r = (int)LDNS_RCODE_WIRE( sldns_buffer_begin(buf) ); stats->ans_rcode[r] ++; - if(r == 0 && LDNS_ANCOUNT( ldns_buffer_begin(buf) ) == 0) + if(r == 0 && LDNS_ANCOUNT( sldns_buffer_begin(buf) ) == 0) stats->ans_rcode_nodata ++; } } diff --git a/contrib/unbound/daemon/stats.h b/contrib/unbound/daemon/stats.h index c0fc1cc..7c31551 100644 --- a/contrib/unbound/daemon/stats.h +++ b/contrib/unbound/daemon/stats.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -43,12 +43,12 @@ #ifndef DAEMON_STATS_H #define DAEMON_STATS_H #include "util/timehist.h" -#include <ldns/buffer.h> struct worker; struct config_file; struct comm_point; struct comm_reply; struct edns_data; +struct sldns_buffer; /** number of qtype that is stored for in array */ #define STATS_QTYPE_NUM 256 @@ -230,6 +230,6 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c, * @param stats: the stats * @param buf: buffer with rcode. If buffer is length0: not counted. */ -void server_stats_insrcode(struct server_stats* stats, ldns_buffer* buf); +void server_stats_insrcode(struct server_stats* stats, struct sldns_buffer* buf); #endif /* DAEMON_STATS_H */ diff --git a/contrib/unbound/daemon/unbound.c b/contrib/unbound/daemon/unbound.c index 6539b9e..716fbce 100644 --- a/contrib/unbound/daemon/unbound.c +++ b/contrib/unbound/daemon/unbound.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -67,9 +67,12 @@ #include <grp.h> #endif +#ifndef S_SPLINT_S +/* splint chokes on this system header file */ #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif +#endif /* S_SPLINT_S */ #ifdef HAVE_LOGIN_CAP_H #include <login_cap.h> #endif @@ -165,8 +168,8 @@ static void usage() #endif printf("Version %s\n", PACKAGE_VERSION); get_event_sys(&evnm, &evsys, &evmethod); - printf("linked libs: %s %s (it uses %s), ldns %s, %s\n", - evnm, evsys, evmethod, ldns_version(), + printf("linked libs: %s %s (it uses %s), %s\n", + evnm, evsys, evmethod, #ifdef HAVE_SSL SSLeay_version(SSLEAY_VERSION) #elif defined(HAVE_NSS) @@ -193,6 +196,7 @@ int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) static void checkrlimits(struct config_file* cfg) { +#ifndef S_SPLINT_S #ifdef HAVE_GETRLIMIT /* list has number of ports to listen to, ifs number addresses */ int list = ((cfg->do_udp?1:0) + (cfg->do_tcp?1 + @@ -283,6 +287,7 @@ checkrlimits(struct config_file* cfg) #else (void)cfg; #endif /* HAVE_GETRLIMIT */ +#endif /* S_SPLINT_S */ } /** set verbosity, check rlimits, cache settings */ @@ -522,7 +527,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, /* setusercontext does initgroups, setuid, setgid, and * also resource limits from login config, but we * still call setresuid, setresgid to be sure to set all uid*/ - if(setusercontext(NULL, pwd, uid, + if(setusercontext(NULL, pwd, uid, (unsigned) LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0) log_warn("unable to setusercontext %s: %s", cfg->username, strerror(errno)); @@ -715,6 +720,7 @@ main(int argc, char* argv[]) #endif log_init(NULL, 0, NULL); + log_ident_set(strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]); /* parse the options */ while( (c=getopt(argc, argv, "c:dhvw:")) != -1) { switch(c) { diff --git a/contrib/unbound/daemon/worker.c b/contrib/unbound/daemon/worker.c index 0e5b14d..ccc45f6 100644 --- a/contrib/unbound/daemon/worker.c +++ b/contrib/unbound/daemon/worker.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,7 +40,6 @@ * pending requests. */ #include "config.h" -#include <ldns/wire2host.h> #include "util/log.h" #include "util/net_help.h" #include "util/random.h" @@ -72,6 +71,7 @@ #include "validator/val_anchor.h" #include "libunbound/context.h" #include "libunbound/libworker.h" +#include "ldns/sbuffer.h" #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> @@ -181,7 +181,7 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker), + sizeof(worker->rndstate) + regional_get_mem(worker->scratchpad) + sizeof(*worker->env.scratch_buffer) - + ldns_buffer_capacity(worker->env.scratch_buffer) + + sldns_buffer_capacity(worker->env.scratch_buffer) + forwards_get_mem(worker->env.fwds) + hints_get_mem(worker->env.hints); if(worker->thread_num == 0) @@ -243,10 +243,10 @@ worker_handle_reply(struct comm_point* c, void* arg, int error, return 0; } /* sanity check. */ - if(!LDNS_QR_WIRE(ldns_buffer_begin(c->buffer)) - || LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) != + if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer)) + || LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) != LDNS_PACKET_QUERY - || LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1) { + || LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) { /* error becomes timeout for the module as if this reply * never arrived. */ mesh_report_reply(worker->env.mesh, &e, reply_info, @@ -274,10 +274,10 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error, return 0; } /* sanity check. */ - if(!LDNS_QR_WIRE(ldns_buffer_begin(c->buffer)) - || LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) != + if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer)) + || LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) != LDNS_PACKET_QUERY - || LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1) { + || LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) { /* error becomes timeout for the module as if this reply * never arrived. */ verbose(VERB_ALGO, "worker: bad reply handled as timeout"); @@ -297,49 +297,49 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error, * @return error code, 0 OK, or -1 discard. */ static int -worker_check_request(ldns_buffer* pkt, struct worker* worker) +worker_check_request(sldns_buffer* pkt, struct worker* worker) { - if(ldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) { + if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) { verbose(VERB_QUERY, "request too short, discarded"); return -1; } - if(ldns_buffer_limit(pkt) > NORMAL_UDP_SIZE && + if(sldns_buffer_limit(pkt) > NORMAL_UDP_SIZE && worker->daemon->cfg->harden_large_queries) { verbose(VERB_QUERY, "request too large, discarded"); return -1; } - if(LDNS_QR_WIRE(ldns_buffer_begin(pkt))) { + if(LDNS_QR_WIRE(sldns_buffer_begin(pkt))) { verbose(VERB_QUERY, "request has QR bit on, discarded"); return -1; } - if(LDNS_TC_WIRE(ldns_buffer_begin(pkt))) { - LDNS_TC_CLR(ldns_buffer_begin(pkt)); + if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) { + LDNS_TC_CLR(sldns_buffer_begin(pkt)); verbose(VERB_QUERY, "request bad, has TC bit on"); return LDNS_RCODE_FORMERR; } - if(LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) { + if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) { verbose(VERB_QUERY, "request unknown opcode %d", - LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt))); + LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt))); return LDNS_RCODE_NOTIMPL; } - if(LDNS_QDCOUNT(ldns_buffer_begin(pkt)) != 1) { + if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) { verbose(VERB_QUERY, "request wrong nr qd=%d", - LDNS_QDCOUNT(ldns_buffer_begin(pkt))); + LDNS_QDCOUNT(sldns_buffer_begin(pkt))); return LDNS_RCODE_FORMERR; } - if(LDNS_ANCOUNT(ldns_buffer_begin(pkt)) != 0) { + if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) { verbose(VERB_QUERY, "request wrong nr an=%d", - LDNS_ANCOUNT(ldns_buffer_begin(pkt))); + LDNS_ANCOUNT(sldns_buffer_begin(pkt))); return LDNS_RCODE_FORMERR; } - if(LDNS_NSCOUNT(ldns_buffer_begin(pkt)) != 0) { + if(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) { verbose(VERB_QUERY, "request wrong nr ns=%d", - LDNS_NSCOUNT(ldns_buffer_begin(pkt))); + LDNS_NSCOUNT(sldns_buffer_begin(pkt))); return LDNS_RCODE_FORMERR; } - if(LDNS_ARCOUNT(ldns_buffer_begin(pkt)) > 1) { + if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) { verbose(VERB_QUERY, "request wrong nr ar=%d", - LDNS_ARCOUNT(ldns_buffer_begin(pkt))); + LDNS_ARCOUNT(sldns_buffer_begin(pkt))); return LDNS_RCODE_FORMERR; } return 0; @@ -361,7 +361,7 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg, if(len != sizeof(uint32_t)) { fatal_exit("bad control msg length %d", (int)len); } - cmd = ldns_read_uint32(msg); + cmd = sldns_read_uint32(msg); free(msg); switch(cmd) { case worker_cmd_quit: @@ -451,7 +451,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo, */ uint16_t udpsize = edns->udp_size; int secure = 0; - uint32_t timenow = *worker->env.now; + time_t timenow = *worker->env.now; int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd) && worker->env.need_to_validate; struct dns_msg *msg = NULL; @@ -526,7 +526,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, struct reply_info* rep, uint16_t id, uint16_t flags, struct comm_reply* repinfo, struct edns_data* edns) { - uint32_t timenow = *worker->env.now; + time_t timenow = *worker->env.now; uint16_t udpsize = edns->udp_size; int secure; int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd) @@ -616,7 +616,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, /** Reply to client and perform prefetch to keep cache up to date */ static void reply_and_prefetch(struct worker* worker, struct query_info* qinfo, - uint16_t flags, struct comm_reply* repinfo, uint32_t leeway) + uint16_t flags, struct comm_reply* repinfo, time_t leeway) { /* first send answer to client to keep its latency * as small as a cachereply */ @@ -638,32 +638,32 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo, * @param edns: edns reply information. */ static void -chaos_replystr(ldns_buffer* pkt, const char* str, struct edns_data* edns) +chaos_replystr(sldns_buffer* pkt, const char* str, struct edns_data* edns) { size_t len = strlen(str); - unsigned int rd = LDNS_RD_WIRE(ldns_buffer_begin(pkt)); - unsigned int cd = LDNS_CD_WIRE(ldns_buffer_begin(pkt)); + unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt)); + unsigned int cd = LDNS_CD_WIRE(sldns_buffer_begin(pkt)); if(len>255) len=255; /* cap size of TXT record */ - ldns_buffer_clear(pkt); - ldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */ - ldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA)); - if(rd) LDNS_RD_SET(ldns_buffer_begin(pkt)); - if(cd) LDNS_CD_SET(ldns_buffer_begin(pkt)); - ldns_buffer_write_u16(pkt, 1); /* qdcount */ - ldns_buffer_write_u16(pkt, 1); /* ancount */ - ldns_buffer_write_u16(pkt, 0); /* nscount */ - ldns_buffer_write_u16(pkt, 0); /* arcount */ + sldns_buffer_clear(pkt); + sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */ + sldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA)); + if(rd) LDNS_RD_SET(sldns_buffer_begin(pkt)); + if(cd) LDNS_CD_SET(sldns_buffer_begin(pkt)); + sldns_buffer_write_u16(pkt, 1); /* qdcount */ + sldns_buffer_write_u16(pkt, 1); /* ancount */ + sldns_buffer_write_u16(pkt, 0); /* nscount */ + sldns_buffer_write_u16(pkt, 0); /* arcount */ (void)query_dname_len(pkt); /* skip qname */ - ldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */ - ldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */ - ldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */ - ldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT); - ldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH); - ldns_buffer_write_u32(pkt, 0); /* TTL */ - ldns_buffer_write_u16(pkt, sizeof(uint8_t) + len); - ldns_buffer_write_u8(pkt, len); - ldns_buffer_write(pkt, str, len); - ldns_buffer_flip(pkt); + sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */ + sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */ + sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */ + sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT); + sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH); + sldns_buffer_write_u32(pkt, 0); /* TTL */ + sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len); + sldns_buffer_write_u8(pkt, len); + sldns_buffer_write(pkt, str, len); + sldns_buffer_flip(pkt); edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->bits &= EDNS_DO; @@ -680,7 +680,7 @@ chaos_replystr(ldns_buffer* pkt, const char* str, struct edns_data* edns) */ static int answer_chaos(struct worker* w, struct query_info* qinfo, - struct edns_data* edns, ldns_buffer* pkt) + struct edns_data* edns, sldns_buffer* pkt) { struct config_file* cfg = w->env.cfg; if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT) @@ -720,6 +720,52 @@ answer_chaos(struct worker* w, struct query_info* qinfo, return 0; } +static int +deny_refuse(struct comm_point* c, enum acl_access acl, + enum acl_access deny, enum acl_access refuse, + struct worker* worker, struct comm_reply* repinfo) +{ + if(acl == deny) { + comm_point_drop_reply(repinfo); + if(worker->stats.extended) + worker->stats.unwanted_queries++; + return 0; + } else if(acl == refuse) { + log_addr(VERB_ALGO, "refused query from", + &repinfo->addr, repinfo->addrlen); + log_buf(VERB_ALGO, "refuse", c->buffer); + if(worker->stats.extended) + worker->stats.unwanted_queries++; + if(worker_check_request(c->buffer, worker) == -1) { + comm_point_drop_reply(repinfo); + return 0; /* discard this */ + } + sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE); + sldns_buffer_write_at(c->buffer, 4, + (uint8_t*)"\0\0\0\0\0\0\0\0", 8); + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), + LDNS_RCODE_REFUSED); + return 1; + } + + return -1; +} + +static int +deny_refuse_all(struct comm_point* c, enum acl_access acl, + struct worker* worker, struct comm_reply* repinfo) +{ + return deny_refuse(c, acl, acl_deny, acl_refuse, worker, repinfo); +} + +static int +deny_refuse_non_local(struct comm_point* c, enum acl_access acl, + struct worker* worker, struct comm_reply* repinfo) +{ + return deny_refuse(c, acl, acl_deny_non_local, acl_refuse_non_local, worker, repinfo); +} + int worker_handle_request(struct comm_point* c, void* arg, int error, struct comm_reply* repinfo) @@ -739,35 +785,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error, } acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr, repinfo->addrlen); - if(acl == acl_deny) { - comm_point_drop_reply(repinfo); - if(worker->stats.extended) - worker->stats.unwanted_queries++; - return 0; - } else if(acl == acl_refuse) { - log_addr(VERB_ALGO, "refused query from", - &repinfo->addr, repinfo->addrlen); - log_buf(VERB_ALGO, "refuse", c->buffer); - if(worker->stats.extended) - worker->stats.unwanted_queries++; - if(worker_check_request(c->buffer, worker) == -1) { - comm_point_drop_reply(repinfo); - return 0; /* discard this */ - } - ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE); - ldns_buffer_write_at(c->buffer, 4, - (uint8_t*)"\0\0\0\0\0\0\0\0", 8); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), - LDNS_RCODE_REFUSED); - return 1; + if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1) + { + return ret; } if((ret=worker_check_request(c->buffer, worker)) != 0) { verbose(VERB_ALGO, "worker check request: bad query."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); if(ret != -1) { - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret); + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret); return 1; } comm_point_drop_reply(repinfo); @@ -778,9 +805,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if(!query_info_parse(&qinfo, c->buffer)) { verbose(VERB_ALGO, "worker parse request: formerror."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); - ldns_buffer_rewind(c->buffer); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), + sldns_buffer_rewind(c->buffer); + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), LDNS_RCODE_FORMERR); server_stats_insrcode(&worker->stats, c->buffer); return 1; @@ -794,9 +821,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error, qinfo.qtype == LDNS_RR_TYPE_IXFR) { verbose(VERB_ALGO, "worker request: refused zone transfer."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); - ldns_buffer_rewind(c->buffer); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), + sldns_buffer_rewind(c->buffer); + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), LDNS_RCODE_REFUSED); if(worker->stats.extended) { worker->stats.qtype[qinfo.qtype]++; @@ -807,9 +834,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if((ret=parse_edns_from_pkt(c->buffer, &edns)) != 0) { verbose(VERB_ALGO, "worker parse edns: formerror."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); - ldns_buffer_rewind(c->buffer); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret); + sldns_buffer_rewind(c->buffer); + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret); server_stats_insrcode(&worker->stats, c->buffer); return 1; } @@ -821,8 +848,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error, verbose(VERB_ALGO, "query with bad edns version."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo, - *(uint16_t*)(void *)ldns_buffer_begin(c->buffer), - ldns_buffer_read_u16_at(c->buffer, 2), NULL); + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), NULL); attach_edns_record(c->buffer, &edns); return 1; } @@ -833,17 +860,25 @@ worker_handle_request(struct comm_point* c, void* arg, int error, log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); edns.udp_size = NORMAL_UDP_SIZE; } - if(edns.edns_present && edns.udp_size < LDNS_HEADER_SIZE) { + if(edns.udp_size > worker->daemon->cfg->max_udp_size && + c->type == comm_udp) { + verbose(VERB_QUERY, + "worker request: max UDP reply size modified" + " (%d to max-udp-size)", (int)edns.udp_size); + log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + edns.udp_size = worker->daemon->cfg->max_udp_size; + } + if(edns.udp_size < LDNS_HEADER_SIZE) { verbose(VERB_ALGO, "worker request: edns is too small."); log_addr(VERB_CLIENT, "from", &repinfo->addr, repinfo->addrlen); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_TC_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_TC_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), LDNS_RCODE_SERVFAIL); - ldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE); - ldns_buffer_write_at(c->buffer, 4, + sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE); + sldns_buffer_write_at(c->buffer, 4, (uint8_t*)"\0\0\0\0\0\0\0\0", 8); - ldns_buffer_flip(c->buffer); + sldns_buffer_flip(c->buffer); return 1; } if(worker->stats.extended) @@ -859,22 +894,32 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns, c->buffer, worker->scratchpad)) { regional_free_all(worker->scratchpad); - if(ldns_buffer_limit(c->buffer) == 0) { + if(sldns_buffer_limit(c->buffer) == 0) { comm_point_drop_reply(repinfo); return 0; } server_stats_insrcode(&worker->stats, c->buffer); return 1; } - if(!(LDNS_RD_WIRE(ldns_buffer_begin(c->buffer))) && + + /* We've looked in our local zones. If the answer isn't there, we + * might need to bail out based on ACLs now. */ + if((ret=deny_refuse_non_local(c, acl, worker, repinfo)) != -1) + { + return ret; + } + + /* If this request does not have the recursion bit set, verify + * ACLs allow the snooping. */ + if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) && acl != acl_allow_snoop ) { - ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE); - ldns_buffer_write_at(c->buffer, 4, + sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE); + sldns_buffer_write_at(c->buffer, 4, (uint8_t*)"\0\0\0\0\0\0\0\0", 8); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), LDNS_RCODE_REFUSED); - ldns_buffer_flip(c->buffer); + sldns_buffer_flip(c->buffer); server_stats_insrcode(&worker->stats, c->buffer); log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from", &repinfo->addr, repinfo->addrlen); @@ -885,17 +930,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error, /* answer from cache - we have acquired a readlock on it */ if(answer_from_cache(worker, &qinfo, (struct reply_info*)e->data, - *(uint16_t*)(void *)ldns_buffer_begin(c->buffer), - ldns_buffer_read_u16_at(c->buffer, 2), repinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, &edns)) { /* prefetch it if the prefetch TTL expired */ if(worker->env.cfg->prefetch && *worker->env.now >= ((struct reply_info*)e->data)->prefetch_ttl) { - uint32_t leeway = ((struct reply_info*)e-> + time_t leeway = ((struct reply_info*)e-> data)->ttl - *worker->env.now; lock_rw_unlock(&e->lock); reply_and_prefetch(worker, &qinfo, - ldns_buffer_read_u16_at(c->buffer, 2), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, leeway); return 0; } @@ -905,17 +950,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error, verbose(VERB_ALGO, "answer from the cache failed"); lock_rw_unlock(&e->lock); } - if(!LDNS_RD_WIRE(ldns_buffer_begin(c->buffer))) { + if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) { if(answer_norec_from_cache(worker, &qinfo, - *(uint16_t*)(void *)ldns_buffer_begin(c->buffer), - ldns_buffer_read_u16_at(c->buffer, 2), repinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, &edns)) { return 1; } verbose(VERB_ALGO, "answer norec from cache -- " "need to validate or not primed"); } - ldns_buffer_rewind(c->buffer); + sldns_buffer_rewind(c->buffer); server_stats_querymiss(&worker->stats, worker); if(verbosity >= VERB_CLIENT) { @@ -928,8 +973,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error, /* grab a work request structure for this new request */ mesh_new_client(worker->env.mesh, &qinfo, - ldns_buffer_read_u16_at(c->buffer, 2), &edns, repinfo, - *(uint16_t*)(void *)ldns_buffer_begin(c->buffer)); + sldns_buffer_read_u16_at(c->buffer, 2), + &edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer)); worker_mem_report(worker, NULL); return 0; } @@ -1113,7 +1158,7 @@ worker_init(struct worker* worker, struct config_file *cfg, worker->daemon->env->infra_cache, worker->rndstate, cfg->use_caps_bits_for_id, worker->ports, worker->numports, cfg->unwanted_threshold, &worker_alloc_cleanup, worker, - cfg->do_udp, worker->daemon->connect_sslctx); + cfg->do_udp, worker->daemon->connect_sslctx, cfg->delay_close); if(!worker->back) { log_err("could not create outgoing sockets"); worker_delete(worker); @@ -1159,7 +1204,7 @@ worker_init(struct worker* worker, struct config_file *cfg, worker->env.attach_sub = &mesh_attach_sub; worker->env.kill_sub = &mesh_state_delete; worker->env.detect_cycle = &mesh_detect_cycle; - worker->env.scratch_buffer = ldns_buffer_new(cfg->msg_buffer_size); + worker->env.scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size); if(!(worker->env.fwds = forwards_create()) || !forwards_apply_cfg(worker->env.fwds, cfg)) { log_err("Could not set forward zones"); @@ -1222,7 +1267,7 @@ worker_delete(struct worker* worker) } outside_network_quit_prepare(worker->back); mesh_delete(worker->env.mesh); - ldns_buffer_free(worker->env.scratch_buffer); + sldns_buffer_free(worker->env.scratch_buffer); forwards_delete(worker->env.fwds); hints_delete(worker->env.hints); listen_delete(worker->front); @@ -1336,14 +1381,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), } void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), char* ATTR_UNUSED(why_bogus)) { log_assert(0); } void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus)) +{ + log_assert(0); +} + +void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), char* ATTR_UNUSED(why_bogus)) { log_assert(0); diff --git a/contrib/unbound/daemon/worker.h b/contrib/unbound/daemon/worker.h index f0e8cf0..83503ae 100644 --- a/contrib/unbound/daemon/worker.h +++ b/contrib/unbound/daemon/worker.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** |