infra.c revision 291767
1/*
2 * services/cache/infra.c - infrastructure cache, server rtt and capabilities
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/**
37 * \file
38 *
39 * This file contains the infrastructure cache.
40 */
41#include "config.h"
42#include "sldns/rrdef.h"
43#include "sldns/str2wire.h"
44#include "services/cache/infra.h"
45#include "util/storage/slabhash.h"
46#include "util/storage/lookup3.h"
47#include "util/data/dname.h"
48#include "util/log.h"
49#include "util/net_help.h"
50#include "util/config_file.h"
51#include "iterator/iterator.h"
52
53/** Timeout when only a single probe query per IP is allowed. */
54#define PROBE_MAXRTO 12000 /* in msec */
55
56/** number of timeouts for a type when the domain can be blocked ;
57 * even if another type has completely rtt maxed it, the different type
58 * can do this number of packets (until those all timeout too) */
59#define TIMEOUT_COUNT_MAX 3
60
61/** ratelimit value for delegation point */
62int infra_dp_ratelimit = 0;
63
64size_t
65infra_sizefunc(void* k, void* ATTR_UNUSED(d))
66{
67	struct infra_key* key = (struct infra_key*)k;
68	return sizeof(*key) + sizeof(struct infra_data) + key->namelen
69		+ lock_get_mem(&key->entry.lock);
70}
71
72int
73infra_compfunc(void* key1, void* key2)
74{
75	struct infra_key* k1 = (struct infra_key*)key1;
76	struct infra_key* k2 = (struct infra_key*)key2;
77	int r = sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
78	if(r != 0)
79		return r;
80	if(k1->namelen != k2->namelen) {
81		if(k1->namelen < k2->namelen)
82			return -1;
83		return 1;
84	}
85	return query_dname_compare(k1->zonename, k2->zonename);
86}
87
88void
89infra_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
90{
91	struct infra_key* key = (struct infra_key*)k;
92	if(!key)
93		return;
94	lock_rw_destroy(&key->entry.lock);
95	free(key->zonename);
96	free(key);
97}
98
99void
100infra_deldatafunc(void* d, void* ATTR_UNUSED(arg))
101{
102	struct infra_data* data = (struct infra_data*)d;
103	free(data);
104}
105
106size_t
107rate_sizefunc(void* k, void* ATTR_UNUSED(d))
108{
109	struct rate_key* key = (struct rate_key*)k;
110	return sizeof(*key) + sizeof(struct rate_data) + key->namelen
111		+ lock_get_mem(&key->entry.lock);
112}
113
114int
115rate_compfunc(void* key1, void* key2)
116{
117	struct rate_key* k1 = (struct rate_key*)key1;
118	struct rate_key* k2 = (struct rate_key*)key2;
119	if(k1->namelen != k2->namelen) {
120		if(k1->namelen < k2->namelen)
121			return -1;
122		return 1;
123	}
124	return query_dname_compare(k1->name, k2->name);
125}
126
127void
128rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
129{
130	struct rate_key* key = (struct rate_key*)k;
131	if(!key)
132		return;
133	lock_rw_destroy(&key->entry.lock);
134	free(key->name);
135	free(key);
136}
137
138void
139rate_deldatafunc(void* d, void* ATTR_UNUSED(arg))
140{
141	struct rate_data* data = (struct rate_data*)d;
142	free(data);
143}
144
145/** find or create element in domainlimit tree */
146static struct domain_limit_data* domain_limit_findcreate(
147	struct infra_cache* infra, char* name)
148{
149	uint8_t* nm;
150	int labs;
151	size_t nmlen;
152	struct domain_limit_data* d;
153
154	/* parse name */
155	nm = sldns_str2wire_dname(name, &nmlen);
156	if(!nm) {
157		log_err("could not parse %s", name);
158		return NULL;
159	}
160	labs = dname_count_labels(nm);
161
162	/* can we find it? */
163	d = (struct domain_limit_data*)name_tree_find(&infra->domain_limits,
164		nm, nmlen, labs, LDNS_RR_CLASS_IN);
165	if(d) {
166		free(nm);
167		return d;
168	}
169
170	/* create it */
171	d = (struct domain_limit_data*)calloc(1, sizeof(*d));
172	if(!d) {
173		free(nm);
174		return NULL;
175	}
176	d->node.node.key = &d->node;
177	d->node.name = nm;
178	d->node.len = nmlen;
179	d->node.labs = labs;
180	d->node.dclass = LDNS_RR_CLASS_IN;
181	d->lim = -1;
182	d->below = -1;
183	if(!name_tree_insert(&infra->domain_limits, &d->node, nm, nmlen,
184		labs, LDNS_RR_CLASS_IN)) {
185		log_err("duplicate element in domainlimit tree");
186		free(nm);
187		free(d);
188		return NULL;
189	}
190	return d;
191}
192
193/** insert rate limit configuration into lookup tree */
194static int infra_ratelimit_cfg_insert(struct infra_cache* infra,
195	struct config_file* cfg)
196{
197	struct config_str2list* p;
198	struct domain_limit_data* d;
199	for(p = cfg->ratelimit_for_domain; p; p = p->next) {
200		d = domain_limit_findcreate(infra, p->str);
201		if(!d)
202			return 0;
203		d->lim = atoi(p->str2);
204	}
205	for(p = cfg->ratelimit_below_domain; p; p = p->next) {
206		d = domain_limit_findcreate(infra, p->str);
207		if(!d)
208			return 0;
209		d->below = atoi(p->str2);
210	}
211	return 1;
212}
213
214struct infra_cache*
215infra_create(struct config_file* cfg)
216{
217	struct infra_cache* infra = (struct infra_cache*)calloc(1,
218		sizeof(struct infra_cache));
219	size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
220		sizeof(struct infra_data)+INFRA_BYTES_NAME);
221	infra->hosts = slabhash_create(cfg->infra_cache_slabs,
222		INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc,
223		&infra_delkeyfunc, &infra_deldatafunc, NULL);
224	if(!infra->hosts) {
225		free(infra);
226		return NULL;
227	}
228	infra->host_ttl = cfg->host_ttl;
229	name_tree_init(&infra->domain_limits);
230	infra_dp_ratelimit = cfg->ratelimit;
231	if(cfg->ratelimit != 0) {
232		infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
233			INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
234			&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
235			&rate_deldatafunc, NULL);
236		if(!infra->domain_rates) {
237			infra_delete(infra);
238			return NULL;
239		}
240		/* insert config data into ratelimits */
241		if(!infra_ratelimit_cfg_insert(infra, cfg)) {
242			infra_delete(infra);
243			return NULL;
244		}
245		name_tree_init_parents(&infra->domain_limits);
246	}
247	return infra;
248}
249
250/** delete domain_limit entries */
251static void domain_limit_free(rbnode_t* n, void* ATTR_UNUSED(arg))
252{
253	if(n) {
254		free(((struct domain_limit_data*)n)->node.name);
255		free(n);
256	}
257}
258
259void
260infra_delete(struct infra_cache* infra)
261{
262	if(!infra)
263		return;
264	slabhash_delete(infra->hosts);
265	slabhash_delete(infra->domain_rates);
266	traverse_postorder(&infra->domain_limits, domain_limit_free, NULL);
267	free(infra);
268}
269
270struct infra_cache*
271infra_adjust(struct infra_cache* infra, struct config_file* cfg)
272{
273	size_t maxmem;
274	if(!infra)
275		return infra_create(cfg);
276	infra->host_ttl = cfg->host_ttl;
277	maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
278		sizeof(struct infra_data)+INFRA_BYTES_NAME);
279	if(maxmem != slabhash_get_size(infra->hosts) ||
280		cfg->infra_cache_slabs != infra->hosts->size) {
281		infra_delete(infra);
282		infra = infra_create(cfg);
283	}
284	return infra;
285}
286
287/** calculate the hash value for a host key */
288static hashvalue_t
289hash_addr(struct sockaddr_storage* addr, socklen_t addrlen)
290{
291	hashvalue_t h = 0xab;
292	/* select the pieces to hash, some OS have changing data inside */
293	if(addr_is_ip6(addr, addrlen)) {
294		struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
295		h = hashlittle(&in6->sin6_family, sizeof(in6->sin6_family), h);
296		h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
297		h = hashlittle(&in6->sin6_addr, INET6_SIZE, h);
298	} else {
299		struct sockaddr_in* in = (struct sockaddr_in*)addr;
300		h = hashlittle(&in->sin_family, sizeof(in->sin_family), h);
301		h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
302		h = hashlittle(&in->sin_addr, INET_SIZE, h);
303	}
304	return h;
305}
306
307/** calculate infra hash for a key */
308static hashvalue_t
309hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name)
310{
311	return dname_query_hash(name, hash_addr(addr, addrlen));
312}
313
314/** lookup version that does not check host ttl (you check it) */
315struct lruhash_entry*
316infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr,
317	socklen_t addrlen, uint8_t* name, size_t namelen, int wr)
318{
319	struct infra_key k;
320	k.addrlen = addrlen;
321	memcpy(&k.addr, addr, addrlen);
322	k.namelen = namelen;
323	k.zonename = name;
324	k.entry.hash = hash_infra(addr, addrlen, name);
325	k.entry.key = (void*)&k;
326	k.entry.data = NULL;
327	return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr);
328}
329
330/** init the data elements */
331static void
332data_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
333	time_t timenow)
334{
335	struct infra_data* data = (struct infra_data*)e->data;
336	data->ttl = timenow + infra->host_ttl;
337	rtt_init(&data->rtt);
338	data->edns_version = 0;
339	data->edns_lame_known = 0;
340	data->probedelay = 0;
341	data->isdnsseclame = 0;
342	data->rec_lame = 0;
343	data->lame_type_A = 0;
344	data->lame_other = 0;
345	data->timeout_A = 0;
346	data->timeout_AAAA = 0;
347	data->timeout_other = 0;
348}
349
350/**
351 * Create and init a new entry for a host
352 * @param infra: infra structure with config parameters.
353 * @param addr: host address.
354 * @param addrlen: length of addr.
355 * @param name: name of zone
356 * @param namelen: length of name.
357 * @param tm: time now.
358 * @return: the new entry or NULL on malloc failure.
359 */
360static struct lruhash_entry*
361new_entry(struct infra_cache* infra, struct sockaddr_storage* addr,
362	socklen_t addrlen, uint8_t* name, size_t namelen, time_t tm)
363{
364	struct infra_data* data;
365	struct infra_key* key = (struct infra_key*)malloc(sizeof(*key));
366	if(!key)
367		return NULL;
368	data = (struct infra_data*)malloc(sizeof(struct infra_data));
369	if(!data) {
370		free(key);
371		return NULL;
372	}
373	key->zonename = memdup(name, namelen);
374	if(!key->zonename) {
375		free(key);
376		free(data);
377		return NULL;
378	}
379	key->namelen = namelen;
380	lock_rw_init(&key->entry.lock);
381	key->entry.hash = hash_infra(addr, addrlen, name);
382	key->entry.key = (void*)key;
383	key->entry.data = (void*)data;
384	key->addrlen = addrlen;
385	memcpy(&key->addr, addr, addrlen);
386	data_entry_init(infra, &key->entry, tm);
387	return &key->entry;
388}
389
390int
391infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
392        socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow,
393	int* edns_vs, uint8_t* edns_lame_known, int* to)
394{
395	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
396		nm, nmlen, 0);
397	struct infra_data* data;
398	int wr = 0;
399	if(e && ((struct infra_data*)e->data)->ttl < timenow) {
400		/* it expired, try to reuse existing entry */
401		int old = ((struct infra_data*)e->data)->rtt.rto;
402		uint8_t tA = ((struct infra_data*)e->data)->timeout_A;
403		uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA;
404		uint8_t tother = ((struct infra_data*)e->data)->timeout_other;
405		lock_rw_unlock(&e->lock);
406		e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
407		if(e) {
408			/* if its still there we have a writelock, init */
409			/* re-initialise */
410			/* do not touch lameness, it may be valid still */
411			data_entry_init(infra, e, timenow);
412			wr = 1;
413			/* TOP_TIMEOUT remains on reuse */
414			if(old >= USEFUL_SERVER_TOP_TIMEOUT) {
415				((struct infra_data*)e->data)->rtt.rto
416					= USEFUL_SERVER_TOP_TIMEOUT;
417				((struct infra_data*)e->data)->timeout_A = tA;
418				((struct infra_data*)e->data)->timeout_AAAA = tAAAA;
419				((struct infra_data*)e->data)->timeout_other = tother;
420			}
421		}
422	}
423	if(!e) {
424		/* insert new entry */
425		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
426			return 0;
427		data = (struct infra_data*)e->data;
428		*edns_vs = data->edns_version;
429		*edns_lame_known = data->edns_lame_known;
430		*to = rtt_timeout(&data->rtt);
431		slabhash_insert(infra->hosts, e->hash, e, data, NULL);
432		return 1;
433	}
434	/* use existing entry */
435	data = (struct infra_data*)e->data;
436	*edns_vs = data->edns_version;
437	*edns_lame_known = data->edns_lame_known;
438	*to = rtt_timeout(&data->rtt);
439	if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) {
440		/* delay other queries, this is the probe query */
441		if(!wr) {
442			lock_rw_unlock(&e->lock);
443			e = infra_lookup_nottl(infra, addr,addrlen,nm,nmlen, 1);
444			if(!e) { /* flushed from cache real fast, no use to
445				allocate just for the probedelay */
446				return 1;
447			}
448			data = (struct infra_data*)e->data;
449		}
450		/* add 999 to round up the timeout value from msec to sec,
451		 * then add a whole second so it is certain that this probe
452		 * has timed out before the next is allowed */
453		data->probedelay = timenow + ((*to)+1999)/1000;
454	}
455	lock_rw_unlock(&e->lock);
456	return 1;
457}
458
459int
460infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr,
461	socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow,
462	int dnsseclame, int reclame, uint16_t qtype)
463{
464	struct infra_data* data;
465	struct lruhash_entry* e;
466	int needtoinsert = 0;
467	e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
468	if(!e) {
469		/* insert it */
470		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) {
471			log_err("set_lame: malloc failure");
472			return 0;
473		}
474		needtoinsert = 1;
475	} else if( ((struct infra_data*)e->data)->ttl < timenow) {
476		/* expired, reuse existing entry */
477		data_entry_init(infra, e, timenow);
478	}
479	/* got an entry, now set the zone lame */
480	data = (struct infra_data*)e->data;
481	/* merge data (if any) */
482	if(dnsseclame)
483		data->isdnsseclame = 1;
484	if(reclame)
485		data->rec_lame = 1;
486	if(!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A)
487		data->lame_type_A = 1;
488	if(!dnsseclame  && !reclame && qtype != LDNS_RR_TYPE_A)
489		data->lame_other = 1;
490	/* done */
491	if(needtoinsert)
492		slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
493	else 	{ lock_rw_unlock(&e->lock); }
494	return 1;
495}
496
497void
498infra_update_tcp_works(struct infra_cache* infra,
499        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
500	size_t nmlen)
501{
502	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
503		nm, nmlen, 1);
504	struct infra_data* data;
505	if(!e)
506		return; /* doesn't exist */
507	data = (struct infra_data*)e->data;
508	if(data->rtt.rto >= RTT_MAX_TIMEOUT)
509		/* do not disqualify this server altogether, it is better
510		 * than nothing */
511		data->rtt.rto = RTT_MAX_TIMEOUT-1000;
512	lock_rw_unlock(&e->lock);
513}
514
515int
516infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
517	socklen_t addrlen, uint8_t* nm, size_t nmlen, int qtype,
518	int roundtrip, int orig_rtt, time_t timenow)
519{
520	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
521		nm, nmlen, 1);
522	struct infra_data* data;
523	int needtoinsert = 0;
524	int rto = 1;
525	if(!e) {
526		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
527			return 0;
528		needtoinsert = 1;
529	} else if(((struct infra_data*)e->data)->ttl < timenow) {
530		data_entry_init(infra, e, timenow);
531	}
532	/* have an entry, update the rtt */
533	data = (struct infra_data*)e->data;
534	if(roundtrip == -1) {
535		rtt_lost(&data->rtt, orig_rtt);
536		if(qtype == LDNS_RR_TYPE_A) {
537			if(data->timeout_A < TIMEOUT_COUNT_MAX)
538				data->timeout_A++;
539		} else if(qtype == LDNS_RR_TYPE_AAAA) {
540			if(data->timeout_AAAA < TIMEOUT_COUNT_MAX)
541				data->timeout_AAAA++;
542		} else {
543			if(data->timeout_other < TIMEOUT_COUNT_MAX)
544				data->timeout_other++;
545		}
546	} else {
547		/* if we got a reply, but the old timeout was above server
548		 * selection height, delete the timeout so the server is
549		 * fully available again */
550		if(rtt_unclamped(&data->rtt) >= USEFUL_SERVER_TOP_TIMEOUT)
551			rtt_init(&data->rtt);
552		rtt_update(&data->rtt, roundtrip);
553		data->probedelay = 0;
554		if(qtype == LDNS_RR_TYPE_A)
555			data->timeout_A = 0;
556		else if(qtype == LDNS_RR_TYPE_AAAA)
557			data->timeout_AAAA = 0;
558		else	data->timeout_other = 0;
559	}
560	if(data->rtt.rto > 0)
561		rto = data->rtt.rto;
562
563	if(needtoinsert)
564		slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
565	else 	{ lock_rw_unlock(&e->lock); }
566	return rto;
567}
568
569long long infra_get_host_rto(struct infra_cache* infra,
570        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
571	size_t nmlen, struct rtt_info* rtt, int* delay, time_t timenow,
572	int* tA, int* tAAAA, int* tother)
573{
574	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
575		nm, nmlen, 0);
576	struct infra_data* data;
577	long long ttl = -2;
578	if(!e) return -1;
579	data = (struct infra_data*)e->data;
580	if(data->ttl >= timenow) {
581		ttl = (long long)(data->ttl - timenow);
582		memmove(rtt, &data->rtt, sizeof(*rtt));
583		if(timenow < data->probedelay)
584			*delay = (int)(data->probedelay - timenow);
585		else	*delay = 0;
586	}
587	*tA = (int)data->timeout_A;
588	*tAAAA = (int)data->timeout_AAAA;
589	*tother = (int)data->timeout_other;
590	lock_rw_unlock(&e->lock);
591	return ttl;
592}
593
594int
595infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr,
596	socklen_t addrlen, uint8_t* nm, size_t nmlen, int edns_version,
597	time_t timenow)
598{
599	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
600		nm, nmlen, 1);
601	struct infra_data* data;
602	int needtoinsert = 0;
603	if(!e) {
604		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
605			return 0;
606		needtoinsert = 1;
607	} else if(((struct infra_data*)e->data)->ttl < timenow) {
608		data_entry_init(infra, e, timenow);
609	}
610	/* have an entry, update the rtt, and the ttl */
611	data = (struct infra_data*)e->data;
612	/* do not update if noEDNS and stored is yesEDNS */
613	if(!(edns_version == -1 && (data->edns_version != -1 &&
614		data->edns_lame_known))) {
615		data->edns_version = edns_version;
616		data->edns_lame_known = 1;
617	}
618
619	if(needtoinsert)
620		slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
621	else 	{ lock_rw_unlock(&e->lock); }
622	return 1;
623}
624
625int
626infra_get_lame_rtt(struct infra_cache* infra,
627        struct sockaddr_storage* addr, socklen_t addrlen,
628        uint8_t* name, size_t namelen, uint16_t qtype,
629	int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow)
630{
631	struct infra_data* host;
632	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
633		name, namelen, 0);
634	if(!e)
635		return 0;
636	host = (struct infra_data*)e->data;
637	*rtt = rtt_unclamped(&host->rtt);
638	if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
639		&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
640		/* single probe for this domain, and we are not probing */
641		/* unless the query type allows a probe to happen */
642		if(qtype == LDNS_RR_TYPE_A) {
643			if(host->timeout_A >= TIMEOUT_COUNT_MAX)
644				*rtt = USEFUL_SERVER_TOP_TIMEOUT;
645			else	*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
646		} else if(qtype == LDNS_RR_TYPE_AAAA) {
647			if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
648				*rtt = USEFUL_SERVER_TOP_TIMEOUT;
649			else	*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
650		} else {
651			if(host->timeout_other >= TIMEOUT_COUNT_MAX)
652				*rtt = USEFUL_SERVER_TOP_TIMEOUT;
653			else	*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
654		}
655	}
656	if(timenow > host->ttl) {
657		/* expired entry */
658		/* see if this can be a re-probe of an unresponsive server */
659		/* minus 1000 because that is outside of the RTTBAND, so
660		 * blacklisted servers stay blacklisted if this is chosen */
661		if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
662			lock_rw_unlock(&e->lock);
663			*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
664			*lame = 0;
665			*dnsseclame = 0;
666			*reclame = 0;
667			return 1;
668		}
669		lock_rw_unlock(&e->lock);
670		return 0;
671	}
672	/* check lameness first */
673	if(host->lame_type_A && qtype == LDNS_RR_TYPE_A) {
674		lock_rw_unlock(&e->lock);
675		*lame = 1;
676		*dnsseclame = 0;
677		*reclame = 0;
678		return 1;
679	} else if(host->lame_other && qtype != LDNS_RR_TYPE_A) {
680		lock_rw_unlock(&e->lock);
681		*lame = 1;
682		*dnsseclame = 0;
683		*reclame = 0;
684		return 1;
685	} else if(host->isdnsseclame) {
686		lock_rw_unlock(&e->lock);
687		*lame = 0;
688		*dnsseclame = 1;
689		*reclame = 0;
690		return 1;
691	} else if(host->rec_lame) {
692		lock_rw_unlock(&e->lock);
693		*lame = 0;
694		*dnsseclame = 0;
695		*reclame = 1;
696		return 1;
697	}
698	/* no lameness for this type of query */
699	lock_rw_unlock(&e->lock);
700	*lame = 0;
701	*dnsseclame = 0;
702	*reclame = 0;
703	return 1;
704}
705
706int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
707	size_t namelen)
708{
709	int labs = dname_count_labels(name);
710	struct domain_limit_data* d = (struct domain_limit_data*)
711		name_tree_lookup(&infra->domain_limits, name, namelen, labs,
712		LDNS_RR_CLASS_IN);
713	if(!d) return infra_dp_ratelimit;
714
715	if(d->node.labs == labs && d->lim != -1)
716		return d->lim; /* exact match */
717
718	/* find 'below match' */
719	if(d->node.labs == labs)
720		d = (struct domain_limit_data*)d->node.parent;
721	while(d) {
722		if(d->below != -1)
723			return d->below;
724		d = (struct domain_limit_data*)d->node.parent;
725	}
726	return infra_dp_ratelimit;
727}
728
729/** find data item in array, for write access, caller unlocks */
730static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
731	uint8_t* name, size_t namelen, int wr)
732{
733	struct rate_key key;
734	hashvalue_t h = dname_query_hash(name, 0xab);
735	memset(&key, 0, sizeof(key));
736	key.name = name;
737	key.namelen = namelen;
738	key.entry.hash = h;
739	return slabhash_lookup(infra->domain_rates, h, &key, wr);
740}
741
742/** create rate data item for name, number 1 in now */
743static void infra_create_ratedata(struct infra_cache* infra,
744	uint8_t* name, size_t namelen, time_t timenow)
745{
746	hashvalue_t h = dname_query_hash(name, 0xab);
747	struct rate_key* k = (struct rate_key*)calloc(1, sizeof(*k));
748	struct rate_data* d = (struct rate_data*)calloc(1, sizeof(*d));
749	if(!k || !d) {
750		free(k);
751		free(d);
752		return; /* alloc failure */
753	}
754	k->namelen = namelen;
755	k->name = memdup(name, namelen);
756	if(!k->name) {
757		free(k);
758		free(d);
759		return; /* alloc failure */
760	}
761	lock_rw_init(&k->entry.lock);
762	k->entry.hash = h;
763	k->entry.key = k;
764	k->entry.data = d;
765	d->qps[0] = 1;
766	d->timestamp[0] = timenow;
767	slabhash_insert(infra->domain_rates, h, &k->entry, d, NULL);
768}
769
770/** find the second and return its rate counter, if none, remove oldest */
771static int* infra_rate_find_second(void* data, time_t t)
772{
773	struct rate_data* d = (struct rate_data*)data;
774	int i, oldest;
775	for(i=0; i<RATE_WINDOW; i++) {
776		if(d->timestamp[i] == t)
777			return &(d->qps[i]);
778	}
779	/* remove oldest timestamp, and insert it at t with 0 qps */
780	oldest = 0;
781	for(i=0; i<RATE_WINDOW; i++) {
782		if(d->timestamp[i] < d->timestamp[oldest])
783			oldest = i;
784	}
785	d->timestamp[oldest] = t;
786	d->qps[oldest] = 0;
787	return &(d->qps[oldest]);
788}
789
790int infra_rate_max(void* data, time_t now)
791{
792	struct rate_data* d = (struct rate_data*)data;
793	int i, max = 0;
794	for(i=0; i<RATE_WINDOW; i++) {
795		if(now-d->timestamp[i] <= RATE_WINDOW) {
796			if(d->qps[i] > max)
797				max = d->qps[i];
798		}
799	}
800	return max;
801}
802
803int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
804	size_t namelen, time_t timenow)
805{
806	int lim, max;
807	struct lruhash_entry* entry;
808
809	if(!infra_dp_ratelimit)
810		return 1; /* not enabled */
811
812	/* find ratelimit */
813	lim = infra_find_ratelimit(infra, name, namelen);
814
815	/* find or insert ratedata */
816	entry = infra_find_ratedata(infra, name, namelen, 1);
817	if(entry) {
818		int premax = infra_rate_max(entry->data, timenow);
819		int* cur = infra_rate_find_second(entry->data, timenow);
820		(*cur)++;
821		max = infra_rate_max(entry->data, timenow);
822		lock_rw_unlock(&entry->lock);
823
824		if(premax < lim && max >= lim) {
825			char buf[257];
826			dname_str(name, buf);
827			verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim);
828		}
829		return (max < lim);
830	}
831
832	/* create */
833	infra_create_ratedata(infra, name, namelen, timenow);
834	return (1 < lim);
835}
836
837void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
838	size_t namelen, time_t timenow)
839{
840	struct lruhash_entry* entry;
841	int* cur;
842	if(!infra_dp_ratelimit)
843		return; /* not enabled */
844	entry = infra_find_ratedata(infra, name, namelen, 1);
845	if(!entry) return; /* not cached */
846	cur = infra_rate_find_second(entry->data, timenow);
847	if((*cur) > 0)
848		(*cur)--;
849	lock_rw_unlock(&entry->lock);
850}
851
852int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
853	size_t namelen, time_t timenow)
854{
855	struct lruhash_entry* entry;
856	int lim, max;
857	if(!infra_dp_ratelimit)
858		return 0; /* not enabled */
859
860	/* find ratelimit */
861	lim = infra_find_ratelimit(infra, name, namelen);
862
863	/* find current rate */
864	entry = infra_find_ratedata(infra, name, namelen, 0);
865	if(!entry)
866		return 0; /* not cached */
867	max = infra_rate_max(entry->data, timenow);
868	lock_rw_unlock(&entry->lock);
869
870	return (max >= lim);
871}
872
873size_t
874infra_get_mem(struct infra_cache* infra)
875{
876	size_t s = sizeof(*infra) + slabhash_get_mem(infra->hosts);
877	if(infra->domain_rates) s += slabhash_get_mem(infra->domain_rates);
878	/* ignore domain_limits because walk through tree is big */
879	return s;
880}
881