aboutsummaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2019-06-30 14:56:56 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2019-06-30 14:56:56 +0000
commit4713c21a1ac91081e50e474d11fcec002b43a562 (patch)
tree3dee8846d50565e925146b25f6b761ceb1ea7b07 /services
parent9c9d011eed674ddd7e4a0a148691887afb9e75cd (diff)
downloadsrc-4713c21a1ac91081e50e474d11fcec002b43a562.tar.gz
src-4713c21a1ac91081e50e474d11fcec002b43a562.zip
Vendor import of Unbound 1.9.1.vendor/unbound/1.9.1
Notes
Notes: svn path=/vendor/unbound/dist/; revision=349557 svn path=/vendor/unbound/1.9.1/; revision=349558; tag=vendor/unbound/1.9.1
Diffstat (limited to 'services')
-rw-r--r--services/cache/infra.c44
-rw-r--r--services/cache/infra.h9
-rw-r--r--services/listen_dnsport.c10
-rw-r--r--services/localzone.c26
-rw-r--r--services/localzone.h4
-rw-r--r--services/modstack.c10
-rw-r--r--services/outside_network.c31
7 files changed, 96 insertions, 38 deletions
diff --git a/services/cache/infra.c b/services/cache/infra.c
index 07c41928d67e..c2484a9f1aa8 100644
--- a/services/cache/infra.c
+++ b/services/cache/infra.c
@@ -41,6 +41,8 @@
#include "config.h"
#include "sldns/rrdef.h"
#include "sldns/str2wire.h"
+#include "sldns/sbuffer.h"
+#include "sldns/wire2str.h"
#include "services/cache/infra.h"
#include "util/storage/slabhash.h"
#include "util/storage/lookup3.h"
@@ -907,7 +909,8 @@ int infra_rate_max(void* data, time_t now)
}
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
- size_t namelen, time_t timenow)
+ size_t namelen, time_t timenow, struct query_info* qinfo,
+ struct comm_reply* replylist)
{
int lim, max;
struct lruhash_entry* entry;
@@ -930,9 +933,19 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
lock_rw_unlock(&entry->lock);
if(premax < lim && max >= lim) {
- char buf[257];
+ char buf[257], qnm[257], ts[12], cs[12], ip[128];
dname_str(name, buf);
- verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim);
+ dname_str(qinfo->qname, qnm);
+ sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
+ sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
+ ip[0]=0;
+ if(replylist) {
+ addr_to_str((struct sockaddr_storage *)&replylist->addr,
+ replylist->addrlen, ip, sizeof(ip));
+ verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
+ } else {
+ verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
+ }
}
return (max < lim);
}
@@ -991,7 +1004,7 @@ infra_get_mem(struct infra_cache* infra)
}
int infra_ip_ratelimit_inc(struct infra_cache* infra,
- struct comm_reply* repinfo, time_t timenow)
+ struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer)
{
int max;
struct lruhash_entry* entry;
@@ -1010,11 +1023,28 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
lock_rw_unlock(&entry->lock);
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
- char client_ip[128];
+ char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
repinfo->addrlen, client_ip, sizeof(client_ip));
- verbose(VERB_OPS, "ip_ratelimit exceeded %s %d",
- client_ip, infra_ip_ratelimit);
+ qnm[0]=0;
+ if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
+ LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
+ (void)sldns_wire2str_rrquestion_buf(
+ sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
+ sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
+ qnm, sizeof(qnm));
+ if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
+ qnm[strlen(qnm)-1] = 0; /*remove newline*/
+ if(strchr(qnm, '\t'))
+ *strchr(qnm, '\t') = ' ';
+ if(strchr(qnm, '\t'))
+ *strchr(qnm, '\t') = ' ';
+ verbose(VERB_OPS, "ip_ratelimit exceeded %s %d %s",
+ client_ip, infra_ip_ratelimit, qnm);
+ } else {
+ verbose(VERB_OPS, "ip_ratelimit exceeded %s %d (no query name)",
+ client_ip, infra_ip_ratelimit);
+ }
}
return (max <= infra_ip_ratelimit);
}
diff --git a/services/cache/infra.h b/services/cache/infra.h
index 10db796bfcdd..e33f2a6c04ee 100644
--- a/services/cache/infra.h
+++ b/services/cache/infra.h
@@ -366,12 +366,15 @@ long long infra_get_host_rto(struct infra_cache* infra,
* @param name: zone name
* @param namelen: zone name length
* @param timenow: what time it is now.
+ * @param qinfo: for logging, query name.
+ * @param replylist: for logging, querier's address (if any).
* @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit or if in the previous second the ratelimit was exceeded.
* Failures like alloc failures are not returned (probably as 1).
*/
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
- size_t namelen, time_t timenow);
+ size_t namelen, time_t timenow, struct query_info* qinfo,
+ struct comm_reply* replylist);
/**
* Decrement the query rate counter for a delegation point.
@@ -410,10 +413,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
* @param infra: infra cache
* @param repinfo: information about client
* @param timenow: what time it is now.
+ * @param buffer: with query for logging.
* @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit and the query should be dropped. */
int infra_ip_ratelimit_inc(struct infra_cache* infra,
- struct comm_reply* repinfo, time_t timenow);
+ struct comm_reply* repinfo, time_t timenow,
+ struct sldns_buffer* buffer);
/**
* Get memory used by the infra cache.
diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c
index f86a83d96736..e74d1abcffc5 100644
--- a/services/listen_dnsport.c
+++ b/services/listen_dnsport.c
@@ -1636,10 +1636,12 @@ tcp_req_info_setup_listen(struct tcp_req_info* req)
if(wr) {
req->cp->tcp_is_reading = 0;
+ comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
} else if(rd) {
req->cp->tcp_is_reading = 1;
+ comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
/* and also read it (from SSL stack buffers), so
@@ -1647,6 +1649,7 @@ tcp_req_info_setup_listen(struct tcp_req_info* req)
* the TLS frame is sitting in the buffers. */
req->read_again = 1;
} else {
+ comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
comm_point_listen_for_rw(req->cp, 0, 0);
@@ -1759,6 +1762,7 @@ tcp_req_info_handle_readdone(struct tcp_req_info* req)
* clear to write to */
send_it:
c->tcp_is_reading = 0;
+ comm_point_stop_listening(c);
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
return;
}
@@ -1779,6 +1783,12 @@ tcp_req_info_handle_readdone(struct tcp_req_info* req)
/* If mesh failed(mallocfail) and called commpoint_send_reply with
* something like servfail then we pick up that reply below. */
if(req->is_reply) {
+ /* reply from mesh is in the spool_buffer */
+ sldns_buffer_clear(c->buffer);
+ sldns_buffer_write(c->buffer,
+ sldns_buffer_begin(req->spool_buffer),
+ sldns_buffer_limit(req->spool_buffer));
+ sldns_buffer_flip(c->buffer);
goto send_it;
}
diff --git a/services/localzone.c b/services/localzone.c
index 902a29f21d48..6295b17e2fc5 100644
--- a/services/localzone.c
+++ b/services/localzone.c
@@ -464,7 +464,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
return 0;
}
log_assert(z->dclass == rrclass);
- if(z->type == local_zone_redirect &&
+ if((z->type == local_zone_redirect ||
+ z->type == local_zone_inform_redirect) &&
query_dname_compare(z->name, nm) != 0) {
log_err("local-data in redirect zone must reside at top of zone"
", not at %s", rrstr);
@@ -481,7 +482,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
/* Reject it if we would end up having CNAME and other data (including
* another CNAME) for a redirect zone. */
- if(z->type == local_zone_redirect && node->rrsets) {
+ if((z->type == local_zone_redirect ||
+ z->type == local_zone_inform_redirect) && node->rrsets) {
const char* othertype = NULL;
if (rrtype == LDNS_RR_TYPE_CNAME)
othertype = "other";
@@ -1323,7 +1325,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
key.name = qinfo->qname;
key.namelen = qinfo->qname_len;
key.namelabs = labs;
- if(lz_type == local_zone_redirect) {
+ if(lz_type == local_zone_redirect ||
+ lz_type == local_zone_inform_redirect) {
key.name = z->name;
key.namelen = z->namelen;
key.namelabs = z->namelabs;
@@ -1355,7 +1358,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
return 0;
/* Special case for alias matching. See local_data_answer(). */
- if(lz_type == local_zone_redirect &&
+ if((lz_type == local_zone_redirect ||
+ lz_type == local_zone_inform_redirect) &&
qinfo->qtype != LDNS_RR_TYPE_CNAME &&
lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
qinfo->local_alias =
@@ -1370,7 +1374,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
return 1;
}
- if(lz_type == local_zone_redirect) {
+ if(lz_type == local_zone_redirect ||
+ lz_type == local_zone_inform_redirect) {
/* convert rrset name to query name; like a wildcard */
struct ub_packed_rrset_key r = *lr->rrset;
r.rk.dname = qinfo->qname;
@@ -1442,6 +1447,7 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
return 1;
} else if(lz_type == local_zone_static ||
lz_type == local_zone_redirect ||
+ lz_type == local_zone_inform_redirect ||
lz_type == local_zone_always_nxdomain) {
/* for static, reply nodata or nxdomain
* for redirect, reply nodata */
@@ -1450,7 +1456,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
* or using closest match for NSEC.
* or using closest match for returning delegation downwards
*/
- int rcode = (ld || lz_type == local_zone_redirect)?
+ int rcode = (ld || lz_type == local_zone_redirect ||
+ lz_type == local_zone_inform_redirect)?
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
if(z->soa)
return local_encode(qinfo, env, edns, repinfo, buf, temp,
@@ -1624,7 +1631,9 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
}
}
if((env->cfg->log_local_actions ||
- lzt == local_zone_inform || lzt == local_zone_inform_deny)
+ lzt == local_zone_inform ||
+ lzt == local_zone_inform_deny ||
+ lzt == local_zone_inform_redirect)
&& repinfo)
lz_inform_print(z, qinfo, repinfo);
@@ -1656,6 +1665,7 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_nodefault: return "nodefault";
case local_zone_inform: return "inform";
case local_zone_inform_deny: return "inform_deny";
+ case local_zone_inform_redirect: return "inform_redirect";
case local_zone_always_transparent: return "always_transparent";
case local_zone_always_refuse: return "always_refuse";
case local_zone_always_nxdomain: return "always_nxdomain";
@@ -1682,6 +1692,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_inform;
else if(strcmp(type, "inform_deny") == 0)
*t = local_zone_inform_deny;
+ else if(strcmp(type, "inform_redirect") == 0)
+ *t = local_zone_inform_redirect;
else if(strcmp(type, "always_transparent") == 0)
*t = local_zone_always_transparent;
else if(strcmp(type, "always_refuse") == 0)
diff --git a/services/localzone.h b/services/localzone.h
index dd7aa584c461..1d6caeff2c74 100644
--- a/services/localzone.h
+++ b/services/localzone.h
@@ -83,6 +83,8 @@ enum localzone_type {
local_zone_inform,
/** log client address, and block (drop) */
local_zone_inform_deny,
+ /** log client address, and direct */
+ local_zone_inform_redirect,
/** resolve normally, even when there is local data */
local_zone_always_transparent,
/** answer with error, even when there is local data */
@@ -491,6 +493,8 @@ enum respip_action {
respip_inform = local_zone_inform,
/** log query source and don't answer query */
respip_inform_deny = local_zone_inform_deny,
+ /** log query source and redirect */
+ respip_inform_redirect = local_zone_inform_redirect,
/** resolve normally, even when there is response-ip data */
respip_always_transparent = local_zone_always_transparent,
/** answer with 'refused' response */
diff --git a/services/modstack.c b/services/modstack.c
index 136245a96838..05b949d1e330 100644
--- a/services/modstack.c
+++ b/services/modstack.c
@@ -113,8 +113,14 @@ modstack_config(struct module_stack* stack, const char* module_conf)
for(i=0; i<stack->num; i++) {
stack->mod[i] = module_factory(&module_conf);
if(!stack->mod[i]) {
- log_err("Unknown value for next module: '%s'",
- module_conf);
+ char md[256];
+ snprintf(md, sizeof(md), "%s", module_conf);
+ if(strchr(md, ' ')) *(strchr(md, ' ')) = 0;
+ if(strchr(md, '\t')) *(strchr(md, '\t')) = 0;
+ log_err("Unknown value in module-config, module: '%s'."
+ " This module is not present (not compiled in),"
+ " See the list of linked modules with unbound -h",
+ md);
return 0;
}
}
diff --git a/services/outside_network.c b/services/outside_network.c
index 8ed5de375852..16d63df4395a 100644
--- a/services/outside_network.c
+++ b/services/outside_network.c
@@ -1964,7 +1964,6 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet;
struct timeval now = *sq->outnet->now_tv;
- int fallback_tcp = 0;
sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) {
@@ -1996,14 +1995,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
return 0;
}
- if(rto >= RTT_MAX_TIMEOUT) {
- /* fallback_tcp = 1; */
- /* UDP does not work, fallback to TCP below */
- } else {
- serviced_callbacks(sq, NETEVENT_TIMEOUT, c, rep);
- return 0;
- }
- } else if(error != NETEVENT_NOERROR) {
+ }
+ if(error != NETEVENT_NOERROR) {
/* udp returns error (due to no ID or interface available) */
serviced_callbacks(sq, error, c, rep);
return 0;
@@ -2016,9 +2009,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
#endif
- if(!fallback_tcp) {
- if( (sq->status == serviced_query_UDP_EDNS
- ||sq->status == serviced_query_UDP_EDNS_FRAG)
+ if( (sq->status == serviced_query_UDP_EDNS
+ ||sq->status == serviced_query_UDP_EDNS_FRAG)
&& (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL
@@ -2032,7 +2024,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
}
return 0;
- } else if(sq->status == serviced_query_UDP_EDNS &&
+ } else if(sq->status == serviced_query_UDP_EDNS &&
!sq->edns_lame_known) {
/* now we know that edns queries received answers store that */
log_addr(VERB_ALGO, "serviced query: EDNS works for",
@@ -2042,7 +2034,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
log_err("Out of memory caching edns works");
}
sq->edns_lame_known = 1;
- } else if(sq->status == serviced_query_UDP_EDNS_fallback &&
+ } else if(sq->status == serviced_query_UDP_EDNS_fallback &&
!sq->edns_lame_known && (LDNS_RCODE_WIRE(
sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR ||
LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
@@ -2060,12 +2052,12 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
} else {
log_addr(VERB_ALGO, "serviced query: EDNS fails, but "
- "not stored because need DNSSEC for", &sq->addr,
+ "not stored because need DNSSEC for", &sq->addr,
sq->addrlen);
}
sq->status = serviced_query_UDP;
- }
- if(now.tv_sec > sq->last_sent_time.tv_sec ||
+ }
+ if(now.tv_sec > sq->last_sent_time.tv_sec ||
(now.tv_sec == sq->last_sent_time.tv_sec &&
now.tv_usec > sq->last_sent_time.tv_usec)) {
/* convert from microseconds to milliseconds */
@@ -2081,11 +2073,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
sq->last_rtt, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
}
- }
- } /* end of if_!fallback_tcp */
+ }
/* perform TC flag check and TCP fallback after updating our
* cache entries for EDNS status and RTT times */
- if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) {
+ if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer))) {
/* fallback to TCP */
/* this discards partial UDP contents */
if(sq->status == serviced_query_UDP_EDNS ||