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