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