xref: /freebsd/contrib/unbound/services/cache/infra.c (revision 335c7cda)
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 "sldns/sbuffer.h"
45 #include "sldns/wire2str.h"
46 #include "services/cache/infra.h"
47 #include "util/storage/slabhash.h"
48 #include "util/storage/lookup3.h"
49 #include "util/data/dname.h"
50 #include "util/log.h"
51 #include "util/net_help.h"
52 #include "util/config_file.h"
53 #include "iterator/iterator.h"
54 
55 /** Timeout when only a single probe query per IP is allowed. */
56 #define PROBE_MAXRTO 12000 /* in msec */
57 
58 /** number of timeouts for a type when the domain can be blocked ;
59  * even if another type has completely rtt maxed it, the different type
60  * can do this number of packets (until those all timeout too) */
61 #define TIMEOUT_COUNT_MAX 3
62 
63 /** ratelimit value for delegation point */
64 int infra_dp_ratelimit = 0;
65 
66 /** ratelimit value for client ip addresses,
67  *  in queries per second. */
68 int infra_ip_ratelimit = 0;
69 
70 /** ratelimit value for client ip addresses,
71  *  in queries per second.
72  *  For clients with a valid DNS Cookie. */
73 int infra_ip_ratelimit_cookie = 0;
74 
75 size_t
infra_sizefunc(void * k,void * ATTR_UNUSED (d))76 infra_sizefunc(void* k, void* ATTR_UNUSED(d))
77 {
78 	struct infra_key* key = (struct infra_key*)k;
79 	return sizeof(*key) + sizeof(struct infra_data) + key->namelen
80 		+ lock_get_mem(&key->entry.lock);
81 }
82 
83 int
infra_compfunc(void * key1,void * key2)84 infra_compfunc(void* key1, void* key2)
85 {
86 	struct infra_key* k1 = (struct infra_key*)key1;
87 	struct infra_key* k2 = (struct infra_key*)key2;
88 	int r = sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
89 	if(r != 0)
90 		return r;
91 	if(k1->namelen != k2->namelen) {
92 		if(k1->namelen < k2->namelen)
93 			return -1;
94 		return 1;
95 	}
96 	return query_dname_compare(k1->zonename, k2->zonename);
97 }
98 
99 void
infra_delkeyfunc(void * k,void * ATTR_UNUSED (arg))100 infra_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
101 {
102 	struct infra_key* key = (struct infra_key*)k;
103 	if(!key)
104 		return;
105 	lock_rw_destroy(&key->entry.lock);
106 	free(key->zonename);
107 	free(key);
108 }
109 
110 void
infra_deldatafunc(void * d,void * ATTR_UNUSED (arg))111 infra_deldatafunc(void* d, void* ATTR_UNUSED(arg))
112 {
113 	struct infra_data* data = (struct infra_data*)d;
114 	free(data);
115 }
116 
117 size_t
rate_sizefunc(void * k,void * ATTR_UNUSED (d))118 rate_sizefunc(void* k, void* ATTR_UNUSED(d))
119 {
120 	struct rate_key* key = (struct rate_key*)k;
121 	return sizeof(*key) + sizeof(struct rate_data) + key->namelen
122 		+ lock_get_mem(&key->entry.lock);
123 }
124 
125 int
rate_compfunc(void * key1,void * key2)126 rate_compfunc(void* key1, void* key2)
127 {
128 	struct rate_key* k1 = (struct rate_key*)key1;
129 	struct rate_key* k2 = (struct rate_key*)key2;
130 	if(k1->namelen != k2->namelen) {
131 		if(k1->namelen < k2->namelen)
132 			return -1;
133 		return 1;
134 	}
135 	return query_dname_compare(k1->name, k2->name);
136 }
137 
138 void
rate_delkeyfunc(void * k,void * ATTR_UNUSED (arg))139 rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
140 {
141 	struct rate_key* key = (struct rate_key*)k;
142 	if(!key)
143 		return;
144 	lock_rw_destroy(&key->entry.lock);
145 	free(key->name);
146 	free(key);
147 }
148 
149 void
rate_deldatafunc(void * d,void * ATTR_UNUSED (arg))150 rate_deldatafunc(void* d, void* ATTR_UNUSED(arg))
151 {
152 	struct rate_data* data = (struct rate_data*)d;
153 	free(data);
154 }
155 
156 /** find or create element in domainlimit tree */
domain_limit_findcreate(struct infra_cache * infra,char * name)157 static struct domain_limit_data* domain_limit_findcreate(
158 	struct infra_cache* infra, char* name)
159 {
160 	uint8_t* nm;
161 	int labs;
162 	size_t nmlen;
163 	struct domain_limit_data* d;
164 
165 	/* parse name */
166 	nm = sldns_str2wire_dname(name, &nmlen);
167 	if(!nm) {
168 		log_err("could not parse %s", name);
169 		return NULL;
170 	}
171 	labs = dname_count_labels(nm);
172 
173 	/* can we find it? */
174 	d = (struct domain_limit_data*)name_tree_find(&infra->domain_limits,
175 		nm, nmlen, labs, LDNS_RR_CLASS_IN);
176 	if(d) {
177 		free(nm);
178 		return d;
179 	}
180 
181 	/* create it */
182 	d = (struct domain_limit_data*)calloc(1, sizeof(*d));
183 	if(!d) {
184 		free(nm);
185 		return NULL;
186 	}
187 	d->node.node.key = &d->node;
188 	d->node.name = nm;
189 	d->node.len = nmlen;
190 	d->node.labs = labs;
191 	d->node.dclass = LDNS_RR_CLASS_IN;
192 	d->lim = -1;
193 	d->below = -1;
194 	if(!name_tree_insert(&infra->domain_limits, &d->node, nm, nmlen,
195 		labs, LDNS_RR_CLASS_IN)) {
196 		log_err("duplicate element in domainlimit tree");
197 		free(nm);
198 		free(d);
199 		return NULL;
200 	}
201 	return d;
202 }
203 
204 /** insert rate limit configuration into lookup tree */
infra_ratelimit_cfg_insert(struct infra_cache * infra,struct config_file * cfg)205 static int infra_ratelimit_cfg_insert(struct infra_cache* infra,
206 	struct config_file* cfg)
207 {
208 	struct config_str2list* p;
209 	struct domain_limit_data* d;
210 	for(p = cfg->ratelimit_for_domain; p; p = p->next) {
211 		d = domain_limit_findcreate(infra, p->str);
212 		if(!d)
213 			return 0;
214 		d->lim = atoi(p->str2);
215 	}
216 	for(p = cfg->ratelimit_below_domain; p; p = p->next) {
217 		d = domain_limit_findcreate(infra, p->str);
218 		if(!d)
219 			return 0;
220 		d->below = atoi(p->str2);
221 	}
222 	return 1;
223 }
224 
225 /** setup domain limits tree (0 on failure) */
226 static int
setup_domain_limits(struct infra_cache * infra,struct config_file * cfg)227 setup_domain_limits(struct infra_cache* infra, struct config_file* cfg)
228 {
229 	name_tree_init(&infra->domain_limits);
230 	if(!infra_ratelimit_cfg_insert(infra, cfg)) {
231 		return 0;
232 	}
233 	name_tree_init_parents(&infra->domain_limits);
234 	return 1;
235 }
236 
237 /** find or create element in wait limit netblock tree */
238 static struct wait_limit_netblock_info*
wait_limit_netblock_findcreate(struct infra_cache * infra,char * str,int cookie)239 wait_limit_netblock_findcreate(struct infra_cache* infra, char* str,
240 	int cookie)
241 {
242 	rbtree_type* tree;
243 	struct sockaddr_storage addr;
244 	int net;
245 	socklen_t addrlen;
246 	struct wait_limit_netblock_info* d;
247 
248 	if(!netblockstrtoaddr(str, 0, &addr, &addrlen, &net)) {
249 		log_err("cannot parse wait limit netblock '%s'", str);
250 		return 0;
251 	}
252 
253 	/* can we find it? */
254 	if(cookie)
255 		tree = &infra->wait_limits_cookie_netblock;
256 	else
257 		tree = &infra->wait_limits_netblock;
258 	d = (struct wait_limit_netblock_info*)addr_tree_find(tree, &addr,
259 		addrlen, net);
260 	if(d)
261 		return d;
262 
263 	/* create it */
264 	d = (struct wait_limit_netblock_info*)calloc(1, sizeof(*d));
265 	if(!d)
266 		return NULL;
267 	d->limit = -1;
268 	if(!addr_tree_insert(tree, &d->node, &addr, addrlen, net)) {
269 		log_err("duplicate element in domainlimit tree");
270 		free(d);
271 		return NULL;
272 	}
273 	return d;
274 }
275 
276 
277 /** insert wait limit information into lookup tree */
278 static int
infra_wait_limit_netblock_insert(struct infra_cache * infra,struct config_file * cfg)279 infra_wait_limit_netblock_insert(struct infra_cache* infra,
280 	struct config_file* cfg)
281 {
282 	struct config_str2list* p;
283 	struct wait_limit_netblock_info* d;
284 	for(p = cfg->wait_limit_netblock; p; p = p->next) {
285 		d = wait_limit_netblock_findcreate(infra, p->str, 0);
286 		if(!d)
287 			return 0;
288 		d->limit = atoi(p->str2);
289 	}
290 	for(p = cfg->wait_limit_cookie_netblock; p; p = p->next) {
291 		d = wait_limit_netblock_findcreate(infra, p->str, 1);
292 		if(!d)
293 			return 0;
294 		d->limit = atoi(p->str2);
295 	}
296 	return 1;
297 }
298 
299 /** setup wait limits tree (0 on failure) */
300 static int
setup_wait_limits(struct infra_cache * infra,struct config_file * cfg)301 setup_wait_limits(struct infra_cache* infra, struct config_file* cfg)
302 {
303 	addr_tree_init(&infra->wait_limits_netblock);
304 	addr_tree_init(&infra->wait_limits_cookie_netblock);
305 	if(!infra_wait_limit_netblock_insert(infra, cfg))
306 		return 0;
307 	addr_tree_init_parents(&infra->wait_limits_netblock);
308 	addr_tree_init_parents(&infra->wait_limits_cookie_netblock);
309 	return 1;
310 }
311 
312 struct infra_cache*
infra_create(struct config_file * cfg)313 infra_create(struct config_file* cfg)
314 {
315 	struct infra_cache* infra = (struct infra_cache*)calloc(1,
316 		sizeof(struct infra_cache));
317 	size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
318 		sizeof(struct infra_data)+INFRA_BYTES_NAME);
319 	if(!infra) {
320 		return NULL;
321 	}
322 	infra->hosts = slabhash_create(cfg->infra_cache_slabs,
323 		INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc,
324 		&infra_delkeyfunc, &infra_deldatafunc, NULL);
325 	if(!infra->hosts) {
326 		free(infra);
327 		return NULL;
328 	}
329 	infra->host_ttl = cfg->host_ttl;
330 	infra->infra_keep_probing = cfg->infra_keep_probing;
331 	infra_dp_ratelimit = cfg->ratelimit;
332 	infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
333 		INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
334 		&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
335 		&rate_deldatafunc, NULL);
336 	if(!infra->domain_rates) {
337 		infra_delete(infra);
338 		return NULL;
339 	}
340 	/* insert config data into ratelimits */
341 	if(!setup_domain_limits(infra, cfg)) {
342 		infra_delete(infra);
343 		return NULL;
344 	}
345 	if(!setup_wait_limits(infra, cfg)) {
346 		infra_delete(infra);
347 		return NULL;
348 	}
349 	infra_ip_ratelimit = cfg->ip_ratelimit;
350 	infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
351 	    INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
352 	    &ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
353 	if(!infra->client_ip_rates) {
354 		infra_delete(infra);
355 		return NULL;
356 	}
357 	return infra;
358 }
359 
360 /** delete domain_limit entries */
domain_limit_free(rbnode_type * n,void * ATTR_UNUSED (arg))361 static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg))
362 {
363 	if(n) {
364 		free(((struct domain_limit_data*)n)->node.name);
365 		free(n);
366 	}
367 }
368 
369 /** delete wait_limit_netblock_info entries */
wait_limit_netblock_del(rbnode_type * n,void * ATTR_UNUSED (arg))370 static void wait_limit_netblock_del(rbnode_type* n, void* ATTR_UNUSED(arg))
371 {
372 	free(n);
373 }
374 
375 void
infra_delete(struct infra_cache * infra)376 infra_delete(struct infra_cache* infra)
377 {
378 	if(!infra)
379 		return;
380 	slabhash_delete(infra->hosts);
381 	slabhash_delete(infra->domain_rates);
382 	traverse_postorder(&infra->domain_limits, domain_limit_free, NULL);
383 	slabhash_delete(infra->client_ip_rates);
384 	traverse_postorder(&infra->wait_limits_netblock,
385 		wait_limit_netblock_del, NULL);
386 	traverse_postorder(&infra->wait_limits_cookie_netblock,
387 		wait_limit_netblock_del, NULL);
388 	free(infra);
389 }
390 
391 struct infra_cache*
infra_adjust(struct infra_cache * infra,struct config_file * cfg)392 infra_adjust(struct infra_cache* infra, struct config_file* cfg)
393 {
394 	size_t maxmem;
395 	if(!infra)
396 		return infra_create(cfg);
397 	infra->host_ttl = cfg->host_ttl;
398 	infra->infra_keep_probing = cfg->infra_keep_probing;
399 	infra_dp_ratelimit = cfg->ratelimit;
400 	infra_ip_ratelimit = cfg->ip_ratelimit;
401 	maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
402 		sizeof(struct infra_data)+INFRA_BYTES_NAME);
403 	/* divide cachesize by slabs and multiply by slabs, because if the
404 	 * cachesize is not an even multiple of slabs, that is the resulting
405 	 * size of the slabhash */
406 	if(!slabhash_is_size(infra->hosts, maxmem, cfg->infra_cache_slabs) ||
407 	   !slabhash_is_size(infra->domain_rates, cfg->ratelimit_size,
408 	   	cfg->ratelimit_slabs) ||
409 	   !slabhash_is_size(infra->client_ip_rates, cfg->ip_ratelimit_size,
410 	   	cfg->ip_ratelimit_slabs)) {
411 		infra_delete(infra);
412 		infra = infra_create(cfg);
413 	} else {
414 		/* reapply domain limits */
415 		traverse_postorder(&infra->domain_limits, domain_limit_free,
416 			NULL);
417 		if(!setup_domain_limits(infra, cfg)) {
418 			infra_delete(infra);
419 			return NULL;
420 		}
421 	}
422 	return infra;
423 }
424 
425 /** calculate the hash value for a host key
426  *  set use_port to a non-0 number to use the port in
427  *  the hash calculation; 0 to ignore the port.*/
428 static hashvalue_type
hash_addr(struct sockaddr_storage * addr,socklen_t addrlen,int use_port)429 hash_addr(struct sockaddr_storage* addr, socklen_t addrlen,
430   int use_port)
431 {
432 	hashvalue_type h = 0xab;
433 	/* select the pieces to hash, some OS have changing data inside */
434 	if(addr_is_ip6(addr, addrlen)) {
435 		struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
436 		h = hashlittle(&in6->sin6_family, sizeof(in6->sin6_family), h);
437 		if(use_port){
438 			h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
439 		}
440 		h = hashlittle(&in6->sin6_addr, INET6_SIZE, h);
441 	} else {
442 		struct sockaddr_in* in = (struct sockaddr_in*)addr;
443 		h = hashlittle(&in->sin_family, sizeof(in->sin_family), h);
444 		if(use_port){
445 			h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
446 		}
447 		h = hashlittle(&in->sin_addr, INET_SIZE, h);
448 	}
449 	return h;
450 }
451 
452 /** calculate infra hash for a key */
453 static hashvalue_type
hash_infra(struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name)454 hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name)
455 {
456 	return dname_query_hash(name, hash_addr(addr, addrlen, 1));
457 }
458 
459 /** lookup version that does not check host ttl (you check it) */
460 struct lruhash_entry*
infra_lookup_nottl(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name,size_t namelen,int wr)461 infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr,
462 	socklen_t addrlen, uint8_t* name, size_t namelen, int wr)
463 {
464 	struct infra_key k;
465 	k.addrlen = addrlen;
466 	memcpy(&k.addr, addr, addrlen);
467 	k.namelen = namelen;
468 	k.zonename = name;
469 	k.entry.hash = hash_infra(addr, addrlen, name);
470 	k.entry.key = (void*)&k;
471 	k.entry.data = NULL;
472 	return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr);
473 }
474 
475 /** init the data elements */
476 static void
data_entry_init(struct infra_cache * infra,struct lruhash_entry * e,time_t timenow)477 data_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
478 	time_t timenow)
479 {
480 	struct infra_data* data = (struct infra_data*)e->data;
481 	data->ttl = timenow + infra->host_ttl;
482 	rtt_init(&data->rtt);
483 	data->edns_version = 0;
484 	data->edns_lame_known = 0;
485 	data->probedelay = 0;
486 	data->isdnsseclame = 0;
487 	data->rec_lame = 0;
488 	data->lame_type_A = 0;
489 	data->lame_other = 0;
490 	data->timeout_A = 0;
491 	data->timeout_AAAA = 0;
492 	data->timeout_other = 0;
493 }
494 
495 /**
496  * Create and init a new entry for a host
497  * @param infra: infra structure with config parameters.
498  * @param addr: host address.
499  * @param addrlen: length of addr.
500  * @param name: name of zone
501  * @param namelen: length of name.
502  * @param tm: time now.
503  * @return: the new entry or NULL on malloc failure.
504  */
505 static struct lruhash_entry*
new_entry(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name,size_t namelen,time_t tm)506 new_entry(struct infra_cache* infra, struct sockaddr_storage* addr,
507 	socklen_t addrlen, uint8_t* name, size_t namelen, time_t tm)
508 {
509 	struct infra_data* data;
510 	struct infra_key* key = (struct infra_key*)malloc(sizeof(*key));
511 	if(!key)
512 		return NULL;
513 	data = (struct infra_data*)malloc(sizeof(struct infra_data));
514 	if(!data) {
515 		free(key);
516 		return NULL;
517 	}
518 	key->zonename = memdup(name, namelen);
519 	if(!key->zonename) {
520 		free(key);
521 		free(data);
522 		return NULL;
523 	}
524 	key->namelen = namelen;
525 	lock_rw_init(&key->entry.lock);
526 	key->entry.hash = hash_infra(addr, addrlen, name);
527 	key->entry.key = (void*)key;
528 	key->entry.data = (void*)data;
529 	key->addrlen = addrlen;
530 	memcpy(&key->addr, addr, addrlen);
531 	data_entry_init(infra, &key->entry, tm);
532 	return &key->entry;
533 }
534 
535 int
infra_host(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen,time_t timenow,int * edns_vs,uint8_t * edns_lame_known,int * to)536 infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
537         socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow,
538 	int* edns_vs, uint8_t* edns_lame_known, int* to)
539 {
540 	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
541 		nm, nmlen, 0);
542 	struct infra_data* data;
543 	int wr = 0;
544 	if(e && ((struct infra_data*)e->data)->ttl < timenow) {
545 		/* it expired, try to reuse existing entry */
546 		int old = ((struct infra_data*)e->data)->rtt.rto;
547 		time_t tprobe = ((struct infra_data*)e->data)->probedelay;
548 		uint8_t tA = ((struct infra_data*)e->data)->timeout_A;
549 		uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA;
550 		uint8_t tother = ((struct infra_data*)e->data)->timeout_other;
551 		lock_rw_unlock(&e->lock);
552 		e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
553 		if(e) {
554 			/* if its still there we have a writelock, init */
555 			/* re-initialise */
556 			/* do not touch lameness, it may be valid still */
557 			data_entry_init(infra, e, timenow);
558 			wr = 1;
559 			/* TOP_TIMEOUT remains on reuse */
560 			if(old >= USEFUL_SERVER_TOP_TIMEOUT) {
561 				((struct infra_data*)e->data)->rtt.rto
562 					= USEFUL_SERVER_TOP_TIMEOUT;
563 				((struct infra_data*)e->data)->probedelay = tprobe;
564 				((struct infra_data*)e->data)->timeout_A = tA;
565 				((struct infra_data*)e->data)->timeout_AAAA = tAAAA;
566 				((struct infra_data*)e->data)->timeout_other = tother;
567 			}
568 		}
569 	}
570 	if(!e) {
571 		/* insert new entry */
572 		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
573 			return 0;
574 		data = (struct infra_data*)e->data;
575 		*edns_vs = data->edns_version;
576 		*edns_lame_known = data->edns_lame_known;
577 		*to = rtt_timeout(&data->rtt);
578 		slabhash_insert(infra->hosts, e->hash, e, data, NULL);
579 		return 1;
580 	}
581 	/* use existing entry */
582 	data = (struct infra_data*)e->data;
583 	*edns_vs = data->edns_version;
584 	*edns_lame_known = data->edns_lame_known;
585 	*to = rtt_timeout(&data->rtt);
586 	if(*to >= PROBE_MAXRTO && (infra->infra_keep_probing ||
587 		rtt_notimeout(&data->rtt)*4 <= *to)) {
588 		/* delay other queries, this is the probe query */
589 		if(!wr) {
590 			lock_rw_unlock(&e->lock);
591 			e = infra_lookup_nottl(infra, addr,addrlen,nm,nmlen, 1);
592 			if(!e) { /* flushed from cache real fast, no use to
593 				allocate just for the probedelay */
594 				return 1;
595 			}
596 			data = (struct infra_data*)e->data;
597 		}
598 		/* add 999 to round up the timeout value from msec to sec,
599 		 * then add a whole second so it is certain that this probe
600 		 * has timed out before the next is allowed */
601 		data->probedelay = timenow + ((*to)+1999)/1000;
602 	}
603 	lock_rw_unlock(&e->lock);
604 	return 1;
605 }
606 
607 int
infra_set_lame(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen,time_t timenow,int dnsseclame,int reclame,uint16_t qtype)608 infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr,
609 	socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow,
610 	int dnsseclame, int reclame, uint16_t qtype)
611 {
612 	struct infra_data* data;
613 	struct lruhash_entry* e;
614 	int needtoinsert = 0;
615 	e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
616 	if(!e) {
617 		/* insert it */
618 		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) {
619 			log_err("set_lame: malloc failure");
620 			return 0;
621 		}
622 		needtoinsert = 1;
623 	} else if( ((struct infra_data*)e->data)->ttl < timenow) {
624 		/* expired, reuse existing entry */
625 		data_entry_init(infra, e, timenow);
626 	}
627 	/* got an entry, now set the zone lame */
628 	data = (struct infra_data*)e->data;
629 	/* merge data (if any) */
630 	if(dnsseclame)
631 		data->isdnsseclame = 1;
632 	if(reclame)
633 		data->rec_lame = 1;
634 	if(!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A)
635 		data->lame_type_A = 1;
636 	if(!dnsseclame  && !reclame && qtype != LDNS_RR_TYPE_A)
637 		data->lame_other = 1;
638 	/* done */
639 	if(needtoinsert)
640 		slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
641 	else 	{ lock_rw_unlock(&e->lock); }
642 	return 1;
643 }
644 
645 void
infra_update_tcp_works(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen)646 infra_update_tcp_works(struct infra_cache* infra,
647         struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
648 	size_t nmlen)
649 {
650 	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
651 		nm, nmlen, 1);
652 	struct infra_data* data;
653 	if(!e)
654 		return; /* doesn't exist */
655 	data = (struct infra_data*)e->data;
656 	if(data->rtt.rto >= RTT_MAX_TIMEOUT)
657 		/* do not disqualify this server altogether, it is better
658 		 * than nothing */
659 		data->rtt.rto = RTT_MAX_TIMEOUT-1000;
660 	lock_rw_unlock(&e->lock);
661 }
662 
663 int
infra_rtt_update(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen,int qtype,int roundtrip,int orig_rtt,time_t timenow)664 infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
665 	socklen_t addrlen, uint8_t* nm, size_t nmlen, int qtype,
666 	int roundtrip, int orig_rtt, time_t timenow)
667 {
668 	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
669 		nm, nmlen, 1);
670 	struct infra_data* data;
671 	int needtoinsert = 0, expired = 0;
672 	int rto = 1;
673 	time_t oldprobedelay = 0;
674 	if(!e) {
675 		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
676 			return 0;
677 		needtoinsert = 1;
678 	} else if(((struct infra_data*)e->data)->ttl < timenow) {
679 		oldprobedelay = ((struct infra_data*)e->data)->probedelay;
680 		data_entry_init(infra, e, timenow);
681 		expired = 1;
682 	}
683 	/* have an entry, update the rtt */
684 	data = (struct infra_data*)e->data;
685 	if(roundtrip == -1) {
686 		if(needtoinsert || expired) {
687 			/* timeout on entry that has expired before the timer
688 			 * keep old timeout from the function caller */
689 			data->rtt.rto = orig_rtt;
690 			data->probedelay = oldprobedelay;
691 		}
692 		rtt_lost(&data->rtt, orig_rtt);
693 		if(qtype == LDNS_RR_TYPE_A) {
694 			if(data->timeout_A < TIMEOUT_COUNT_MAX)
695 				data->timeout_A++;
696 		} else if(qtype == LDNS_RR_TYPE_AAAA) {
697 			if(data->timeout_AAAA < TIMEOUT_COUNT_MAX)
698 				data->timeout_AAAA++;
699 		} else {
700 			if(data->timeout_other < TIMEOUT_COUNT_MAX)
701 				data->timeout_other++;
702 		}
703 	} else {
704 		/* if we got a reply, but the old timeout was above server
705 		 * selection height, delete the timeout so the server is
706 		 * fully available again */
707 		if(rtt_unclamped(&data->rtt) >= USEFUL_SERVER_TOP_TIMEOUT)
708 			rtt_init(&data->rtt);
709 		rtt_update(&data->rtt, roundtrip);
710 		data->probedelay = 0;
711 		if(qtype == LDNS_RR_TYPE_A)
712 			data->timeout_A = 0;
713 		else if(qtype == LDNS_RR_TYPE_AAAA)
714 			data->timeout_AAAA = 0;
715 		else	data->timeout_other = 0;
716 	}
717 	if(data->rtt.rto > 0)
718 		rto = data->rtt.rto;
719 
720 	if(needtoinsert)
721 		slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
722 	else 	{ lock_rw_unlock(&e->lock); }
723 	return rto;
724 }
725 
infra_get_host_rto(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen,struct rtt_info * rtt,int * delay,time_t timenow,int * tA,int * tAAAA,int * tother)726 long long infra_get_host_rto(struct infra_cache* infra,
727         struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
728 	size_t nmlen, struct rtt_info* rtt, int* delay, time_t timenow,
729 	int* tA, int* tAAAA, int* tother)
730 {
731 	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
732 		nm, nmlen, 0);
733 	struct infra_data* data;
734 	long long ttl = -2;
735 	if(!e) return -1;
736 	data = (struct infra_data*)e->data;
737 	if(data->ttl >= timenow) {
738 		ttl = (long long)(data->ttl - timenow);
739 		memmove(rtt, &data->rtt, sizeof(*rtt));
740 		if(timenow < data->probedelay)
741 			*delay = (int)(data->probedelay - timenow);
742 		else	*delay = 0;
743 	}
744 	*tA = (int)data->timeout_A;
745 	*tAAAA = (int)data->timeout_AAAA;
746 	*tother = (int)data->timeout_other;
747 	lock_rw_unlock(&e->lock);
748 	return ttl;
749 }
750 
751 int
infra_edns_update(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen,int edns_version,time_t timenow)752 infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr,
753 	socklen_t addrlen, uint8_t* nm, size_t nmlen, int edns_version,
754 	time_t timenow)
755 {
756 	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
757 		nm, nmlen, 1);
758 	struct infra_data* data;
759 	int needtoinsert = 0;
760 	if(!e) {
761 		if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
762 			return 0;
763 		needtoinsert = 1;
764 	} else if(((struct infra_data*)e->data)->ttl < timenow) {
765 		data_entry_init(infra, e, timenow);
766 	}
767 	/* have an entry, update the rtt, and the ttl */
768 	data = (struct infra_data*)e->data;
769 	/* do not update if noEDNS and stored is yesEDNS */
770 	if(!(edns_version == -1 && (data->edns_version != -1 &&
771 		data->edns_lame_known))) {
772 		data->edns_version = edns_version;
773 		data->edns_lame_known = 1;
774 	}
775 
776 	if(needtoinsert)
777 		slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
778 	else 	{ lock_rw_unlock(&e->lock); }
779 	return 1;
780 }
781 
782 int
infra_get_lame_rtt(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name,size_t namelen,uint16_t qtype,int * lame,int * dnsseclame,int * reclame,int * rtt,time_t timenow)783 infra_get_lame_rtt(struct infra_cache* infra,
784         struct sockaddr_storage* addr, socklen_t addrlen,
785         uint8_t* name, size_t namelen, uint16_t qtype,
786 	int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow)
787 {
788 	struct infra_data* host;
789 	struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
790 		name, namelen, 0);
791 	if(!e)
792 		return 0;
793 	host = (struct infra_data*)e->data;
794 	*rtt = rtt_unclamped(&host->rtt);
795 	if(host->rtt.rto >= PROBE_MAXRTO && timenow >= host->probedelay
796 		&& infra->infra_keep_probing) {
797 		/* single probe, keep probing */
798 		if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
799 			*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
800 	} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
801 		&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
802 		/* single probe for this domain, and we are not probing */
803 		/* unless the query type allows a probe to happen */
804 		if(qtype == LDNS_RR_TYPE_A) {
805 			if(host->timeout_A >= TIMEOUT_COUNT_MAX)
806 				*rtt = USEFUL_SERVER_TOP_TIMEOUT;
807 			else	*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
808 		} else if(qtype == LDNS_RR_TYPE_AAAA) {
809 			if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
810 				*rtt = USEFUL_SERVER_TOP_TIMEOUT;
811 			else	*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
812 		} else {
813 			if(host->timeout_other >= TIMEOUT_COUNT_MAX)
814 				*rtt = USEFUL_SERVER_TOP_TIMEOUT;
815 			else	*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
816 		}
817 	}
818 	/* expired entry */
819 	if(timenow > host->ttl) {
820 
821 		/* see if this can be a re-probe of an unresponsive server */
822 		/* minus 1000 because that is outside of the RTTBAND, so
823 		 * blacklisted servers stay blacklisted if this is chosen */
824 		if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
825 			lock_rw_unlock(&e->lock);
826 			*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
827 			*lame = 0;
828 			*dnsseclame = 0;
829 			*reclame = 0;
830 			return 1;
831 		}
832 		lock_rw_unlock(&e->lock);
833 		return 0;
834 	}
835 	/* check lameness first */
836 	if(host->lame_type_A && qtype == LDNS_RR_TYPE_A) {
837 		lock_rw_unlock(&e->lock);
838 		*lame = 1;
839 		*dnsseclame = 0;
840 		*reclame = 0;
841 		return 1;
842 	} else if(host->lame_other && qtype != LDNS_RR_TYPE_A) {
843 		lock_rw_unlock(&e->lock);
844 		*lame = 1;
845 		*dnsseclame = 0;
846 		*reclame = 0;
847 		return 1;
848 	} else if(host->isdnsseclame) {
849 		lock_rw_unlock(&e->lock);
850 		*lame = 0;
851 		*dnsseclame = 1;
852 		*reclame = 0;
853 		return 1;
854 	} else if(host->rec_lame) {
855 		lock_rw_unlock(&e->lock);
856 		*lame = 0;
857 		*dnsseclame = 0;
858 		*reclame = 1;
859 		return 1;
860 	}
861 	/* no lameness for this type of query */
862 	lock_rw_unlock(&e->lock);
863 	*lame = 0;
864 	*dnsseclame = 0;
865 	*reclame = 0;
866 	return 1;
867 }
868 
infra_find_ratelimit(struct infra_cache * infra,uint8_t * name,size_t namelen)869 int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
870 	size_t namelen)
871 {
872 	int labs = dname_count_labels(name);
873 	struct domain_limit_data* d = (struct domain_limit_data*)
874 		name_tree_lookup(&infra->domain_limits, name, namelen, labs,
875 		LDNS_RR_CLASS_IN);
876 	if(!d) return infra_dp_ratelimit;
877 
878 	if(d->node.labs == labs && d->lim != -1)
879 		return d->lim; /* exact match */
880 
881 	/* find 'below match' */
882 	if(d->node.labs == labs)
883 		d = (struct domain_limit_data*)d->node.parent;
884 	while(d) {
885 		if(d->below != -1)
886 			return d->below;
887 		d = (struct domain_limit_data*)d->node.parent;
888 	}
889 	return infra_dp_ratelimit;
890 }
891 
ip_rate_sizefunc(void * k,void * ATTR_UNUSED (d))892 size_t ip_rate_sizefunc(void* k, void* ATTR_UNUSED(d))
893 {
894 	struct ip_rate_key* key = (struct ip_rate_key*)k;
895 	return sizeof(*key) + sizeof(struct ip_rate_data)
896 		+ lock_get_mem(&key->entry.lock);
897 }
898 
ip_rate_compfunc(void * key1,void * key2)899 int ip_rate_compfunc(void* key1, void* key2)
900 {
901 	struct ip_rate_key* k1 = (struct ip_rate_key*)key1;
902 	struct ip_rate_key* k2 = (struct ip_rate_key*)key2;
903 	return sockaddr_cmp_addr(&k1->addr, k1->addrlen,
904 		&k2->addr, k2->addrlen);
905 }
906 
ip_rate_delkeyfunc(void * k,void * ATTR_UNUSED (arg))907 void ip_rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
908 {
909 	struct ip_rate_key* key = (struct ip_rate_key*)k;
910 	if(!key)
911 		return;
912 	lock_rw_destroy(&key->entry.lock);
913 	free(key);
914 }
915 
916 /** find data item in array, for write access, caller unlocks */
infra_find_ratedata(struct infra_cache * infra,uint8_t * name,size_t namelen,int wr)917 static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
918 	uint8_t* name, size_t namelen, int wr)
919 {
920 	struct rate_key key;
921 	hashvalue_type h = dname_query_hash(name, 0xab);
922 	memset(&key, 0, sizeof(key));
923 	key.name = name;
924 	key.namelen = namelen;
925 	key.entry.hash = h;
926 	return slabhash_lookup(infra->domain_rates, h, &key, wr);
927 }
928 
929 /** find data item in array for ip addresses */
infra_find_ip_ratedata(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,int wr)930 static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
931 	struct sockaddr_storage* addr, socklen_t addrlen, int wr)
932 {
933 	struct ip_rate_key key;
934 	hashvalue_type h = hash_addr(addr, addrlen, 0);
935 	memset(&key, 0, sizeof(key));
936 	key.addr = *addr;
937 	key.addrlen = addrlen;
938 	key.entry.hash = h;
939 	return slabhash_lookup(infra->client_ip_rates, h, &key, wr);
940 }
941 
942 /** create rate data item for name, number 1 in now */
infra_create_ratedata(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow)943 static void infra_create_ratedata(struct infra_cache* infra,
944 	uint8_t* name, size_t namelen, time_t timenow)
945 {
946 	hashvalue_type h = dname_query_hash(name, 0xab);
947 	struct rate_key* k = (struct rate_key*)calloc(1, sizeof(*k));
948 	struct rate_data* d = (struct rate_data*)calloc(1, sizeof(*d));
949 	if(!k || !d) {
950 		free(k);
951 		free(d);
952 		return; /* alloc failure */
953 	}
954 	k->namelen = namelen;
955 	k->name = memdup(name, namelen);
956 	if(!k->name) {
957 		free(k);
958 		free(d);
959 		return; /* alloc failure */
960 	}
961 	lock_rw_init(&k->entry.lock);
962 	k->entry.hash = h;
963 	k->entry.key = k;
964 	k->entry.data = d;
965 	d->qps[0] = 1;
966 	d->timestamp[0] = timenow;
967 	slabhash_insert(infra->domain_rates, h, &k->entry, d, NULL);
968 }
969 
970 /** create rate data item for ip address */
infra_ip_create_ratedata(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,time_t timenow,int mesh_wait)971 static void infra_ip_create_ratedata(struct infra_cache* infra,
972 	struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
973 	int mesh_wait)
974 {
975 	hashvalue_type h = hash_addr(addr, addrlen, 0);
976 	struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k));
977 	struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d));
978 	if(!k || !d) {
979 		free(k);
980 		free(d);
981 		return; /* alloc failure */
982 	}
983 	k->addr = *addr;
984 	k->addrlen = addrlen;
985 	lock_rw_init(&k->entry.lock);
986 	k->entry.hash = h;
987 	k->entry.key = k;
988 	k->entry.data = d;
989 	d->qps[0] = 1;
990 	d->timestamp[0] = timenow;
991 	d->mesh_wait = mesh_wait;
992 	slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
993 }
994 
995 /** Find the second and return its rate counter. If none and should_add, remove
996  *  oldest to accommodate. Else return none. */
infra_rate_find_second_or_none(void * data,time_t t,int should_add)997 static int* infra_rate_find_second_or_none(void* data, time_t t, int should_add)
998 {
999 	struct rate_data* d = (struct rate_data*)data;
1000 	int i, oldest;
1001 	for(i=0; i<RATE_WINDOW; i++) {
1002 		if(d->timestamp[i] == t)
1003 			return &(d->qps[i]);
1004 	}
1005 	if(!should_add) return NULL;
1006 	/* remove oldest timestamp, and insert it at t with 0 qps */
1007 	oldest = 0;
1008 	for(i=0; i<RATE_WINDOW; i++) {
1009 		if(d->timestamp[i] < d->timestamp[oldest])
1010 			oldest = i;
1011 	}
1012 	d->timestamp[oldest] = t;
1013 	d->qps[oldest] = 0;
1014 	return &(d->qps[oldest]);
1015 }
1016 
1017 /** find the second and return its rate counter, if none, remove oldest to
1018  *  accommodate */
infra_rate_give_second(void * data,time_t t)1019 static int* infra_rate_give_second(void* data, time_t t)
1020 {
1021     return infra_rate_find_second_or_none(data, t, 1);
1022 }
1023 
1024 /** find the second and return its rate counter only if it exists. Caller
1025  *  should check for NULL return value */
infra_rate_get_second(void * data,time_t t)1026 static int* infra_rate_get_second(void* data, time_t t)
1027 {
1028     return infra_rate_find_second_or_none(data, t, 0);
1029 }
1030 
infra_rate_max(void * data,time_t now,int backoff)1031 int infra_rate_max(void* data, time_t now, int backoff)
1032 {
1033 	struct rate_data* d = (struct rate_data*)data;
1034 	int i, max = 0;
1035 	for(i=0; i<RATE_WINDOW; i++) {
1036 		if(backoff) {
1037 			if(now-d->timestamp[i] <= RATE_WINDOW &&
1038 				d->qps[i] > max) {
1039 				max = d->qps[i];
1040 			}
1041 		} else {
1042 			if(now == d->timestamp[i]) {
1043 				return d->qps[i];
1044 			}
1045 		}
1046 	}
1047 	return max;
1048 }
1049 
infra_ratelimit_inc(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow,int backoff,struct query_info * qinfo,struct comm_reply * replylist)1050 int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
1051 	size_t namelen, time_t timenow, int backoff, struct query_info* qinfo,
1052 	struct comm_reply* replylist)
1053 {
1054 	int lim, max;
1055 	struct lruhash_entry* entry;
1056 
1057 	if(!infra_dp_ratelimit)
1058 		return 1; /* not enabled */
1059 
1060 	/* find ratelimit */
1061 	lim = infra_find_ratelimit(infra, name, namelen);
1062 	if(!lim)
1063 		return 1; /* disabled for this domain */
1064 
1065 	/* find or insert ratedata */
1066 	entry = infra_find_ratedata(infra, name, namelen, 1);
1067 	if(entry) {
1068 		int premax = infra_rate_max(entry->data, timenow, backoff);
1069 		int* cur = infra_rate_give_second(entry->data, timenow);
1070 		(*cur)++;
1071 		max = infra_rate_max(entry->data, timenow, backoff);
1072 		lock_rw_unlock(&entry->lock);
1073 
1074 		if(premax <= lim && max > lim) {
1075 			char buf[257], qnm[257], ts[12], cs[12], ip[128];
1076 			dname_str(name, buf);
1077 			dname_str(qinfo->qname, qnm);
1078 			sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
1079 			sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
1080 			ip[0]=0;
1081 			if(replylist) {
1082 				addr_to_str((struct sockaddr_storage *)&replylist->remote_addr,
1083 					replylist->remote_addrlen, ip, sizeof(ip));
1084 				verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
1085 			} else {
1086 				verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
1087 			}
1088 		}
1089 		return (max <= lim);
1090 	}
1091 
1092 	/* create */
1093 	infra_create_ratedata(infra, name, namelen, timenow);
1094 	return (1 <= lim);
1095 }
1096 
infra_ratelimit_dec(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow)1097 void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
1098 	size_t namelen, time_t timenow)
1099 {
1100 	struct lruhash_entry* entry;
1101 	int* cur;
1102 	if(!infra_dp_ratelimit)
1103 		return; /* not enabled */
1104 	entry = infra_find_ratedata(infra, name, namelen, 1);
1105 	if(!entry) return; /* not cached */
1106 	cur = infra_rate_get_second(entry->data, timenow);
1107 	if(cur == NULL) {
1108 		/* our timenow is not available anymore; nothing to decrease */
1109 		lock_rw_unlock(&entry->lock);
1110 		return;
1111 	}
1112 	if((*cur) > 0)
1113 		(*cur)--;
1114 	lock_rw_unlock(&entry->lock);
1115 }
1116 
infra_ratelimit_exceeded(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow,int backoff)1117 int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
1118 	size_t namelen, time_t timenow, int backoff)
1119 {
1120 	struct lruhash_entry* entry;
1121 	int lim, max;
1122 	if(!infra_dp_ratelimit)
1123 		return 0; /* not enabled */
1124 
1125 	/* find ratelimit */
1126 	lim = infra_find_ratelimit(infra, name, namelen);
1127 	if(!lim)
1128 		return 0; /* disabled for this domain */
1129 
1130 	/* find current rate */
1131 	entry = infra_find_ratedata(infra, name, namelen, 0);
1132 	if(!entry)
1133 		return 0; /* not cached */
1134 	max = infra_rate_max(entry->data, timenow, backoff);
1135 	lock_rw_unlock(&entry->lock);
1136 
1137 	return (max > lim);
1138 }
1139 
1140 size_t
infra_get_mem(struct infra_cache * infra)1141 infra_get_mem(struct infra_cache* infra)
1142 {
1143 	size_t s = sizeof(*infra) + slabhash_get_mem(infra->hosts);
1144 	if(infra->domain_rates) s += slabhash_get_mem(infra->domain_rates);
1145 	if(infra->client_ip_rates) s += slabhash_get_mem(infra->client_ip_rates);
1146 	/* ignore domain_limits because walk through tree is big */
1147 	return s;
1148 }
1149 
1150 /* Returns 1 if the limit has not been exceeded, 0 otherwise. */
1151 static int
check_ip_ratelimit(struct sockaddr_storage * addr,socklen_t addrlen,struct sldns_buffer * buffer,int premax,int max,int has_cookie)1152 check_ip_ratelimit(struct sockaddr_storage* addr, socklen_t addrlen,
1153 	struct sldns_buffer* buffer, int premax, int max, int has_cookie)
1154 {
1155 	int limit;
1156 
1157 	if(has_cookie) limit = infra_ip_ratelimit_cookie;
1158 	else           limit = infra_ip_ratelimit;
1159 
1160 	/* Disabled */
1161 	if(limit == 0) return 1;
1162 
1163 	if(premax <= limit && max > limit) {
1164 		char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
1165 		addr_to_str(addr, addrlen, client_ip, sizeof(client_ip));
1166 		qnm[0]=0;
1167 		if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
1168 			LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
1169 			(void)sldns_wire2str_rrquestion_buf(
1170 				sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
1171 				sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
1172 				qnm, sizeof(qnm));
1173 			if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
1174 				qnm[strlen(qnm)-1] = 0; /*remove newline*/
1175 			if(strchr(qnm, '\t'))
1176 				*strchr(qnm, '\t') = ' ';
1177 			if(strchr(qnm, '\t'))
1178 				*strchr(qnm, '\t') = ' ';
1179 			verbose(VERB_OPS, "ip_ratelimit exceeded %s %d%s %s",
1180 				client_ip, limit,
1181 				has_cookie?"(cookie)":"", qnm);
1182 		} else {
1183 			verbose(VERB_OPS, "ip_ratelimit exceeded %s %d%s (no query name)",
1184 				client_ip, limit,
1185 				has_cookie?"(cookie)":"");
1186 		}
1187 	}
1188 	return (max <= limit);
1189 }
1190 
infra_ip_ratelimit_inc(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,time_t timenow,int has_cookie,int backoff,struct sldns_buffer * buffer)1191 int infra_ip_ratelimit_inc(struct infra_cache* infra,
1192 	struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
1193 	int has_cookie, int backoff, struct sldns_buffer* buffer)
1194 {
1195 	int max;
1196 	struct lruhash_entry* entry;
1197 
1198 	/* not enabled */
1199 	if(!infra_ip_ratelimit) {
1200 		return 1;
1201 	}
1202 	/* find or insert ratedata */
1203 	entry = infra_find_ip_ratedata(infra, addr, addrlen, 1);
1204 	if(entry) {
1205 		int premax = infra_rate_max(entry->data, timenow, backoff);
1206 		int* cur = infra_rate_give_second(entry->data, timenow);
1207 		(*cur)++;
1208 		max = infra_rate_max(entry->data, timenow, backoff);
1209 		lock_rw_unlock(&entry->lock);
1210 		return check_ip_ratelimit(addr, addrlen, buffer, premax, max,
1211 			has_cookie);
1212 	}
1213 
1214 	/* create */
1215 	infra_ip_create_ratedata(infra, addr, addrlen, timenow, 0);
1216 	return 1;
1217 }
1218 
infra_wait_limit_allowed(struct infra_cache * infra,struct comm_reply * rep,int cookie_valid,struct config_file * cfg)1219 int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep,
1220 	int cookie_valid, struct config_file* cfg)
1221 {
1222 	struct lruhash_entry* entry;
1223 	if(cfg->wait_limit == 0)
1224 		return 1;
1225 
1226 	entry = infra_find_ip_ratedata(infra, &rep->client_addr,
1227 		rep->client_addrlen, 0);
1228 	if(entry) {
1229 		rbtree_type* tree;
1230 		struct wait_limit_netblock_info* w;
1231 		struct rate_data* d = (struct rate_data*)entry->data;
1232 		int mesh_wait = d->mesh_wait;
1233 		lock_rw_unlock(&entry->lock);
1234 
1235 		/* have the wait amount, check how much is allowed */
1236 		if(cookie_valid)
1237 			tree = &infra->wait_limits_cookie_netblock;
1238 		else	tree = &infra->wait_limits_netblock;
1239 		w = (struct wait_limit_netblock_info*)addr_tree_lookup(tree,
1240 			&rep->client_addr, rep->client_addrlen);
1241 		if(w) {
1242 			if(w->limit != -1 && mesh_wait > w->limit)
1243 				return 0;
1244 		} else {
1245 			/* if there is no IP netblock specific information,
1246 			 * use the configured value. */
1247 			if(mesh_wait > (cookie_valid?cfg->wait_limit_cookie:
1248 				cfg->wait_limit))
1249 				return 0;
1250 		}
1251 	}
1252 	return 1;
1253 }
1254 
infra_wait_limit_inc(struct infra_cache * infra,struct comm_reply * rep,time_t timenow,struct config_file * cfg)1255 void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep,
1256 	time_t timenow, struct config_file* cfg)
1257 {
1258 	struct lruhash_entry* entry;
1259 	if(cfg->wait_limit == 0)
1260 		return;
1261 
1262 	/* Find it */
1263 	entry = infra_find_ip_ratedata(infra, &rep->client_addr,
1264 		rep->client_addrlen, 1);
1265 	if(entry) {
1266 		struct rate_data* d = (struct rate_data*)entry->data;
1267 		d->mesh_wait++;
1268 		lock_rw_unlock(&entry->lock);
1269 		return;
1270 	}
1271 
1272 	/* Create it */
1273 	infra_ip_create_ratedata(infra, &rep->client_addr,
1274 		rep->client_addrlen, timenow, 1);
1275 }
1276 
infra_wait_limit_dec(struct infra_cache * infra,struct comm_reply * rep,struct config_file * cfg)1277 void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep,
1278 	struct config_file* cfg)
1279 {
1280 	struct lruhash_entry* entry;
1281 	if(cfg->wait_limit == 0)
1282 		return;
1283 
1284 	entry = infra_find_ip_ratedata(infra, &rep->client_addr,
1285 		rep->client_addrlen, 1);
1286 	if(entry) {
1287 		struct rate_data* d = (struct rate_data*)entry->data;
1288 		if(d->mesh_wait > 0)
1289 			d->mesh_wait--;
1290 		lock_rw_unlock(&entry->lock);
1291 	}
1292 }
1293