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
still_useful_timeout()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
infra_sizefunc(void * k,void * ATTR_UNUSED (d))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
infra_compfunc(void * key1,void * key2)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
infra_delkeyfunc(void * k,void * ATTR_UNUSED (arg))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
infra_deldatafunc(void * d,void * ATTR_UNUSED (arg))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
rate_sizefunc(void * k,void * ATTR_UNUSED (d))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
rate_compfunc(void * key1,void * key2)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
rate_delkeyfunc(void * k,void * ATTR_UNUSED (arg))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
rate_deldatafunc(void * d,void * ATTR_UNUSED (arg))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 */
domain_limit_findcreate(struct rbtree_type * domain_limits,char * name)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 */
infra_ratelimit_cfg_insert(struct rbtree_type * domain_limits,struct config_file * cfg)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
setup_domain_limits(struct rbtree_type * domain_limits,struct config_file * cfg)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*
wait_limit_netblock_findcreate(struct rbtree_type * tree,char * str)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
infra_wait_limit_netblock_insert(rbtree_type * wait_limits_netblock,rbtree_type * wait_limits_cookie_netblock,struct config_file * cfg)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
wait_limit_netblock_default(struct rbtree_type * tree,char * str,int limit)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
setup_wait_limits(rbtree_type * wait_limits_netblock,rbtree_type * wait_limits_cookie_netblock,struct config_file * cfg)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*
infra_create(struct config_file * cfg)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 */
domain_limit_free(rbnode_type * n,void * ATTR_UNUSED (arg))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
domain_limits_free(struct rbtree_type * domain_limits)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 */
wait_limit_netblock_del(rbnode_type * n,void * ATTR_UNUSED (arg))413 static void wait_limit_netblock_del(rbnode_type* n, void* ATTR_UNUSED(arg))
414 {
415 free(n);
416 }
417
418 void
wait_limits_free(struct rbtree_type * wait_limits_tree)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
infra_delete(struct infra_cache * infra)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*
infra_adjust(struct infra_cache * infra,struct config_file * cfg)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
hash_addr(struct sockaddr_storage * addr,socklen_t addrlen,int use_port)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
hash_infra(struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name)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*
infra_lookup_nottl(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name,size_t namelen,int wr)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
data_entry_init(struct infra_cache * infra,struct lruhash_entry * e,time_t timenow)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*
new_entry(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * name,size_t namelen,time_t tm)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
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)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
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)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
infra_update_tcp_works(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,uint8_t * nm,size_t nmlen)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
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)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
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)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
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)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
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)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
infra_find_ratelimit(struct infra_cache * infra,uint8_t * name,size_t namelen)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
ip_rate_sizefunc(void * k,void * ATTR_UNUSED (d))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
ip_rate_compfunc(void * key1,void * key2)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
ip_rate_delkeyfunc(void * k,void * ATTR_UNUSED (arg))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 */
infra_find_ratedata(struct infra_cache * infra,uint8_t * name,size_t namelen,int wr)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 */
infra_find_ip_ratedata(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,int wr)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 */
infra_create_ratedata(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow)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 */
infra_ip_create_ratedata(struct infra_cache * infra,struct sockaddr_storage * addr,socklen_t addrlen,time_t timenow,int mesh_wait)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. */
infra_rate_find_second_or_none(void * data,time_t t,int should_add)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 */
infra_rate_give_second(void * data,time_t t)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 */
infra_rate_get_second(void * data,time_t t)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
infra_rate_max(void * data,time_t now,int backoff)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
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)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
infra_ratelimit_dec(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow)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
infra_ratelimit_exceeded(struct infra_cache * infra,uint8_t * name,size_t namelen,time_t timenow,int backoff)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
infra_get_mem(struct infra_cache * infra)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
check_ip_ratelimit(struct sockaddr_storage * addr,socklen_t addrlen,struct sldns_buffer * buffer,int premax,int max,int has_cookie)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
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)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
infra_wait_limit_allowed(struct infra_cache * infra,struct comm_reply * rep,int cookie_valid,struct config_file * cfg)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
infra_wait_limit_inc(struct infra_cache * infra,struct comm_reply * rep,time_t timenow,struct config_file * cfg)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
infra_wait_limit_dec(struct infra_cache * infra,struct comm_reply * rep,struct config_file * cfg)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