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