mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Change of timeout code. No more lost and backoff in blockage.
At 12sec timeout (and at least 2x lost before) one probe per IP is allowed only. At 120sec, the IP is blocked. After 15min, a 120sec entry has a single retry packet. git-svn-id: file:///svn/unbound/trunk@2311 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
a032ac2f61
commit
498cc8ab88
5 changed files with 57 additions and 7 deletions
|
|
@ -802,8 +802,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||||
{
|
{
|
||||||
char buf[257];
|
char buf[257];
|
||||||
struct delegpt_addr* a;
|
struct delegpt_addr* a;
|
||||||
int lame, dlame, rlame, rto, edns_vs, to;
|
int lame, dlame, rlame, rto, edns_vs, to, delay, entry_ttl;
|
||||||
int entry_ttl;
|
|
||||||
struct rtt_info ri;
|
struct rtt_info ri;
|
||||||
uint8_t edns_lame_known;
|
uint8_t edns_lame_known;
|
||||||
for(a = dp->target_list; a; a = a->next_target) {
|
for(a = dp->target_list; a; a = a->next_target) {
|
||||||
|
|
@ -816,7 +815,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||||
}
|
}
|
||||||
/* lookup in infra cache */
|
/* lookup in infra cache */
|
||||||
entry_ttl = infra_get_host_rto(worker->env.infra_cache,
|
entry_ttl = infra_get_host_rto(worker->env.infra_cache,
|
||||||
&a->addr, a->addrlen, &ri, *worker->env.now);
|
&a->addr, a->addrlen, &ri, &delay, *worker->env.now);
|
||||||
if(entry_ttl == -1) {
|
if(entry_ttl == -1) {
|
||||||
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
||||||
return;
|
return;
|
||||||
|
|
@ -840,6 +839,9 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||||
rlame?"NoAuthButRecursive ":"", rto, entry_ttl,
|
rlame?"NoAuthButRecursive ":"", rto, entry_ttl,
|
||||||
ri.srtt, ri.rttvar, rtt_notimeout(&ri)))
|
ri.srtt, ri.rttvar, rtt_notimeout(&ri)))
|
||||||
return;
|
return;
|
||||||
|
if(delay)
|
||||||
|
if(!ssl_printf(ssl, ", probedelay %d", delay))
|
||||||
|
return;
|
||||||
if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
|
if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
|
||||||
*worker->env.now, &edns_vs, &edns_lame_known, &to)) {
|
*worker->env.now, &edns_vs, &edns_lame_known, &to)) {
|
||||||
if(edns_vs == -1) {
|
if(edns_vs == -1) {
|
||||||
|
|
|
||||||
|
|
@ -1572,10 +1572,11 @@ dump_infra_host(struct lruhash_entry* e, void* arg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!ssl_printf(a->ssl, "%s ttl %d ping %d var %d rtt %d rto %d "
|
if(!ssl_printf(a->ssl, "%s ttl %d ping %d var %d rtt %d rto %d "
|
||||||
"ednsknown %d edns %d\n",
|
"ednsknown %d edns %d delay %d\n",
|
||||||
ip_str, (int)(d->ttl - a->now),
|
ip_str, (int)(d->ttl - a->now),
|
||||||
d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto,
|
d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto,
|
||||||
(int)d->edns_lame_known, (int)d->edns_version))
|
(int)d->edns_lame_known, (int)d->edns_version,
|
||||||
|
(int)(a->now<d->probedelay?d->probedelay-a->now:0)))
|
||||||
return;
|
return;
|
||||||
if(d->lameness)
|
if(d->lameness)
|
||||||
lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
|
lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
26 October 2010: Wouter
|
26 October 2010: Wouter
|
||||||
- dump_infra and flush_infra commands for unbound-control.
|
- dump_infra and flush_infra commands for unbound-control.
|
||||||
- no timeout backoff if meanwhile a query succeeded.
|
- no timeout backoff if meanwhile a query succeeded.
|
||||||
|
- Change of timeout code. No more lost and backoff in blockage.
|
||||||
|
At 12sec timeout (and at least 2x lost before) one probe per IP
|
||||||
|
is allowed only. At 120sec, the IP is blocked. After 15min, a
|
||||||
|
120sec entry has a single retry packet.
|
||||||
|
|
||||||
25 October 2010: Wouter
|
25 October 2010: Wouter
|
||||||
- Configure errors if ldns is not found.
|
- Configure errors if ldns is not found.
|
||||||
|
|
|
||||||
39
services/cache/infra.c
vendored
39
services/cache/infra.c
vendored
|
|
@ -49,6 +49,9 @@
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "iterator/iterator.h"
|
#include "iterator/iterator.h"
|
||||||
|
|
||||||
|
/** Timeout when only a single probe query per IP is allowed. */
|
||||||
|
#define PROBE_MAXRTO 12000 /* in msec */
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
infra_host_sizefunc(void* k, void* ATTR_UNUSED(d))
|
infra_host_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||||
{
|
{
|
||||||
|
|
@ -213,6 +216,7 @@ host_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
|
||||||
rtt_init(&data->rtt);
|
rtt_init(&data->rtt);
|
||||||
data->edns_version = 0;
|
data->edns_version = 0;
|
||||||
data->edns_lame_known = 0;
|
data->edns_lame_known = 0;
|
||||||
|
data->probedelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -257,6 +261,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||||
addrlen, 0);
|
addrlen, 0);
|
||||||
struct infra_host_data* data;
|
struct infra_host_data* data;
|
||||||
|
int wr = 0;
|
||||||
if(e && ((struct infra_host_data*)e->data)->ttl < timenow) {
|
if(e && ((struct infra_host_data*)e->data)->ttl < timenow) {
|
||||||
/* it expired, try to reuse existing entry */
|
/* it expired, try to reuse existing entry */
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
|
|
@ -266,6 +271,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||||
/* re-initialise */
|
/* re-initialise */
|
||||||
/* do not touch lameness, it may be valid still */
|
/* do not touch lameness, it may be valid still */
|
||||||
host_entry_init(infra, e, timenow);
|
host_entry_init(infra, e, timenow);
|
||||||
|
wr = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!e) {
|
if(!e) {
|
||||||
|
|
@ -284,6 +290,22 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||||
*to = rtt_timeout(&data->rtt);
|
*to = rtt_timeout(&data->rtt);
|
||||||
*edns_vs = data->edns_version;
|
*edns_vs = data->edns_version;
|
||||||
*edns_lame_known = data->edns_lame_known;
|
*edns_lame_known = data->edns_lame_known;
|
||||||
|
if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) {
|
||||||
|
/* delay other queries, this is the probe query */
|
||||||
|
if(!wr) {
|
||||||
|
lock_rw_unlock(&e->lock);
|
||||||
|
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||||
|
if(!e) { /* flushed from cache real fast, no use to
|
||||||
|
allocate just for the probedelay */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
data = (struct infra_host_data*)e->data;
|
||||||
|
}
|
||||||
|
/* add 999 to round up the timeout value from msec to sec,
|
||||||
|
* then add a whole second so it is certain that this probe
|
||||||
|
* has timed out before the next is allowed */
|
||||||
|
data->probedelay = timenow + ((*to)+1999)/1000;
|
||||||
|
}
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -498,6 +520,7 @@ infra_rtt_update(struct infra_cache* infra,
|
||||||
rtt_lost(&data->rtt, orig_rtt);
|
rtt_lost(&data->rtt, orig_rtt);
|
||||||
} else {
|
} else {
|
||||||
rtt_update(&data->rtt, roundtrip);
|
rtt_update(&data->rtt, roundtrip);
|
||||||
|
data->probedelay = 0;
|
||||||
}
|
}
|
||||||
if(data->rtt.rto > 0)
|
if(data->rtt.rto > 0)
|
||||||
rto = data->rtt.rto;
|
rto = data->rtt.rto;
|
||||||
|
|
@ -510,7 +533,7 @@ infra_rtt_update(struct infra_cache* infra,
|
||||||
|
|
||||||
int infra_get_host_rto(struct infra_cache* infra,
|
int infra_get_host_rto(struct infra_cache* infra,
|
||||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
struct rtt_info* rtt, uint32_t timenow)
|
struct rtt_info* rtt, int* delay, uint32_t timenow)
|
||||||
{
|
{
|
||||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||||
addrlen, 0);
|
addrlen, 0);
|
||||||
|
|
@ -521,6 +544,9 @@ int infra_get_host_rto(struct infra_cache* infra,
|
||||||
if(data->ttl >= timenow) {
|
if(data->ttl >= timenow) {
|
||||||
ttl = (int)(data->ttl - timenow);
|
ttl = (int)(data->ttl - timenow);
|
||||||
memmove(rtt, &data->rtt, sizeof(*rtt));
|
memmove(rtt, &data->rtt, sizeof(*rtt));
|
||||||
|
if(timenow < data->probedelay)
|
||||||
|
*delay = (int)(data->probedelay - timenow);
|
||||||
|
else *delay = 0;
|
||||||
}
|
}
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
return ttl;
|
return ttl;
|
||||||
|
|
@ -570,6 +596,10 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||||
return 0;
|
return 0;
|
||||||
host = (struct infra_host_data*)e->data;
|
host = (struct infra_host_data*)e->data;
|
||||||
*rtt = rtt_unclamped(&host->rtt);
|
*rtt = rtt_unclamped(&host->rtt);
|
||||||
|
if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
|
||||||
|
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto)
|
||||||
|
/* single probe for this domain, and we are not probing */
|
||||||
|
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||||
/* check lameness first, if so, ttl on host does not matter anymore */
|
/* check lameness first, if so, ttl on host does not matter anymore */
|
||||||
if(infra_lookup_lame(host, name, namelen, timenow,
|
if(infra_lookup_lame(host, name, namelen, timenow,
|
||||||
&dlm, &rlm, &alm, &olm)) {
|
&dlm, &rlm, &alm, &olm)) {
|
||||||
|
|
@ -604,6 +634,13 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||||
*dnsseclame = 0;
|
*dnsseclame = 0;
|
||||||
*reclame = 0;
|
*reclame = 0;
|
||||||
if(timenow > host->ttl) {
|
if(timenow > host->ttl) {
|
||||||
|
/* expired entry */
|
||||||
|
/* see if this can be a re-probe of an unresponsive server */
|
||||||
|
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||||
|
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1;
|
||||||
|
lock_rw_unlock(&e->lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
services/cache/infra.h
vendored
8
services/cache/infra.h
vendored
|
|
@ -64,6 +64,8 @@ struct infra_host_key {
|
||||||
struct infra_host_data {
|
struct infra_host_data {
|
||||||
/** TTL value for this entry. absolute time. */
|
/** TTL value for this entry. absolute time. */
|
||||||
uint32_t ttl;
|
uint32_t ttl;
|
||||||
|
/** time in seconds (absolute) when probing re-commences, 0 disabled */
|
||||||
|
uint32_t probedelay;
|
||||||
/** round trip times for timeout calculation */
|
/** round trip times for timeout calculation */
|
||||||
struct rtt_info rtt;
|
struct rtt_info rtt;
|
||||||
/** Names of the zones that are lame. NULL=no lame zones. */
|
/** Names of the zones that are lame. NULL=no lame zones. */
|
||||||
|
|
@ -173,6 +175,8 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
|
||||||
* Find host information to send a packet. Creates new entry if not found.
|
* Find host information to send a packet. Creates new entry if not found.
|
||||||
* Lameness is empty. EDNS is 0 (try with first), and rtt is returned for
|
* Lameness is empty. EDNS is 0 (try with first), and rtt is returned for
|
||||||
* the first message to it.
|
* the first message to it.
|
||||||
|
* Use this to send a packet only, because it also locks out others when
|
||||||
|
* probing is restricted.
|
||||||
* @param infra: infrastructure cache.
|
* @param infra: infrastructure cache.
|
||||||
* @param addr: host address.
|
* @param addr: host address.
|
||||||
* @param addrlen: length of addr.
|
* @param addrlen: length of addr.
|
||||||
|
|
@ -265,6 +269,7 @@ int infra_edns_update(struct infra_cache* infra,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Lameness information and average RTT if host is in the cache.
|
* Get Lameness information and average RTT if host is in the cache.
|
||||||
|
* This information is to be used for server selection.
|
||||||
* @param infra: infrastructure cache.
|
* @param infra: infrastructure cache.
|
||||||
* @param addr: host address.
|
* @param addr: host address.
|
||||||
* @param addrlen: length of addr.
|
* @param addrlen: length of addr.
|
||||||
|
|
@ -291,12 +296,13 @@ int infra_get_lame_rtt(struct infra_cache* infra,
|
||||||
* @param addr: host address.
|
* @param addr: host address.
|
||||||
* @param addrlen: length of addr.
|
* @param addrlen: length of addr.
|
||||||
* @param rtt: the rtt_info is copied into here (caller alloced return struct).
|
* @param rtt: the rtt_info is copied into here (caller alloced return struct).
|
||||||
|
* @param delay: probe delay (if any).
|
||||||
* @param timenow: what time it is now.
|
* @param timenow: what time it is now.
|
||||||
* @return TTL the infra host element is valid for. If -1: not found in cache.
|
* @return TTL the infra host element is valid for. If -1: not found in cache.
|
||||||
*/
|
*/
|
||||||
int infra_get_host_rto(struct infra_cache* infra,
|
int infra_get_host_rto(struct infra_cache* infra,
|
||||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
struct rtt_info* rtt, uint32_t timenow);
|
struct rtt_info* rtt, int* delay, uint32_t timenow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get memory used by the infra cache.
|
* Get memory used by the infra cache.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue