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 /** ratelimit value for client ip addresses, 65 * in queries per second. */ 66 int infra_ip_ratelimit = 0; 67 68 size_t 69 infra_sizefunc(void* k, void* ATTR_UNUSED(d)) 70 { 71 struct infra_key* key = (struct infra_key*)k; 72 return sizeof(*key) + sizeof(struct infra_data) + key->namelen 73 + lock_get_mem(&key->entry.lock); 74 } 75 76 int 77 infra_compfunc(void* key1, void* key2) 78 { 79 struct infra_key* k1 = (struct infra_key*)key1; 80 struct infra_key* k2 = (struct infra_key*)key2; 81 int r = sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen); 82 if(r != 0) 83 return r; 84 if(k1->namelen != k2->namelen) { 85 if(k1->namelen < k2->namelen) 86 return -1; 87 return 1; 88 } 89 return query_dname_compare(k1->zonename, k2->zonename); 90 } 91 92 void 93 infra_delkeyfunc(void* k, void* ATTR_UNUSED(arg)) 94 { 95 struct infra_key* key = (struct infra_key*)k; 96 if(!key) 97 return; 98 lock_rw_destroy(&key->entry.lock); 99 free(key->zonename); 100 free(key); 101 } 102 103 void 104 infra_deldatafunc(void* d, void* ATTR_UNUSED(arg)) 105 { 106 struct infra_data* data = (struct infra_data*)d; 107 free(data); 108 } 109 110 size_t 111 rate_sizefunc(void* k, void* ATTR_UNUSED(d)) 112 { 113 struct rate_key* key = (struct rate_key*)k; 114 return sizeof(*key) + sizeof(struct rate_data) + key->namelen 115 + lock_get_mem(&key->entry.lock); 116 } 117 118 int 119 rate_compfunc(void* key1, void* key2) 120 { 121 struct rate_key* k1 = (struct rate_key*)key1; 122 struct rate_key* k2 = (struct rate_key*)key2; 123 if(k1->namelen != k2->namelen) { 124 if(k1->namelen < k2->namelen) 125 return -1; 126 return 1; 127 } 128 return query_dname_compare(k1->name, k2->name); 129 } 130 131 void 132 rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg)) 133 { 134 struct rate_key* key = (struct rate_key*)k; 135 if(!key) 136 return; 137 lock_rw_destroy(&key->entry.lock); 138 free(key->name); 139 free(key); 140 } 141 142 void 143 rate_deldatafunc(void* d, void* ATTR_UNUSED(arg)) 144 { 145 struct rate_data* data = (struct rate_data*)d; 146 free(data); 147 } 148 149 /** find or create element in domainlimit tree */ 150 static struct domain_limit_data* domain_limit_findcreate( 151 struct infra_cache* infra, char* name) 152 { 153 uint8_t* nm; 154 int labs; 155 size_t nmlen; 156 struct domain_limit_data* d; 157 158 /* parse name */ 159 nm = sldns_str2wire_dname(name, &nmlen); 160 if(!nm) { 161 log_err("could not parse %s", name); 162 return NULL; 163 } 164 labs = dname_count_labels(nm); 165 166 /* can we find it? */ 167 d = (struct domain_limit_data*)name_tree_find(&infra->domain_limits, 168 nm, nmlen, labs, LDNS_RR_CLASS_IN); 169 if(d) { 170 free(nm); 171 return d; 172 } 173 174 /* create it */ 175 d = (struct domain_limit_data*)calloc(1, sizeof(*d)); 176 if(!d) { 177 free(nm); 178 return NULL; 179 } 180 d->node.node.key = &d->node; 181 d->node.name = nm; 182 d->node.len = nmlen; 183 d->node.labs = labs; 184 d->node.dclass = LDNS_RR_CLASS_IN; 185 d->lim = -1; 186 d->below = -1; 187 if(!name_tree_insert(&infra->domain_limits, &d->node, nm, nmlen, 188 labs, LDNS_RR_CLASS_IN)) { 189 log_err("duplicate element in domainlimit tree"); 190 free(nm); 191 free(d); 192 return NULL; 193 } 194 return d; 195 } 196 197 /** insert rate limit configuration into lookup tree */ 198 static int infra_ratelimit_cfg_insert(struct infra_cache* infra, 199 struct config_file* cfg) 200 { 201 struct config_str2list* p; 202 struct domain_limit_data* d; 203 for(p = cfg->ratelimit_for_domain; p; p = p->next) { 204 d = domain_limit_findcreate(infra, p->str); 205 if(!d) 206 return 0; 207 d->lim = atoi(p->str2); 208 } 209 for(p = cfg->ratelimit_below_domain; p; p = p->next) { 210 d = domain_limit_findcreate(infra, p->str); 211 if(!d) 212 return 0; 213 d->below = atoi(p->str2); 214 } 215 return 1; 216 } 217 218 struct infra_cache* 219 infra_create(struct config_file* cfg) 220 { 221 struct infra_cache* infra = (struct infra_cache*)calloc(1, 222 sizeof(struct infra_cache)); 223 size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+ 224 sizeof(struct infra_data)+INFRA_BYTES_NAME); 225 infra->hosts = slabhash_create(cfg->infra_cache_slabs, 226 INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc, 227 &infra_delkeyfunc, &infra_deldatafunc, NULL); 228 if(!infra->hosts) { 229 free(infra); 230 return NULL; 231 } 232 infra->host_ttl = cfg->host_ttl; 233 name_tree_init(&infra->domain_limits); 234 infra_dp_ratelimit = cfg->ratelimit; 235 if(cfg->ratelimit != 0) { 236 infra->domain_rates = slabhash_create(cfg->ratelimit_slabs, 237 INFRA_HOST_STARTSIZE, cfg->ratelimit_size, 238 &rate_sizefunc, &rate_compfunc, &rate_delkeyfunc, 239 &rate_deldatafunc, NULL); 240 if(!infra->domain_rates) { 241 infra_delete(infra); 242 return NULL; 243 } 244 /* insert config data into ratelimits */ 245 if(!infra_ratelimit_cfg_insert(infra, cfg)) { 246 infra_delete(infra); 247 return NULL; 248 } 249 name_tree_init_parents(&infra->domain_limits); 250 } 251 infra_ip_ratelimit = cfg->ip_ratelimit; 252 infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs, 253 INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc, 254 &ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL); 255 if(!infra->client_ip_rates) { 256 infra_delete(infra); 257 return NULL; 258 } 259 return infra; 260 } 261 262 /** delete domain_limit entries */ 263 static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg)) 264 { 265 if(n) { 266 free(((struct domain_limit_data*)n)->node.name); 267 free(n); 268 } 269 } 270 271 void 272 infra_delete(struct infra_cache* infra) 273 { 274 if(!infra) 275 return; 276 slabhash_delete(infra->hosts); 277 slabhash_delete(infra->domain_rates); 278 traverse_postorder(&infra->domain_limits, domain_limit_free, NULL); 279 slabhash_delete(infra->client_ip_rates); 280 free(infra); 281 } 282 283 struct infra_cache* 284 infra_adjust(struct infra_cache* infra, struct config_file* cfg) 285 { 286 size_t maxmem; 287 if(!infra) 288 return infra_create(cfg); 289 infra->host_ttl = cfg->host_ttl; 290 maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+ 291 sizeof(struct infra_data)+INFRA_BYTES_NAME); 292 if(maxmem != slabhash_get_size(infra->hosts) || 293 cfg->infra_cache_slabs != infra->hosts->size) { 294 infra_delete(infra); 295 infra = infra_create(cfg); 296 } 297 return infra; 298 } 299 300 /** calculate the hash value for a host key 301 * set use_port to a non-0 number to use the port in 302 * the hash calculation; 0 to ignore the port.*/ 303 static hashvalue_type 304 hash_addr(struct sockaddr_storage* addr, socklen_t addrlen, 305 int use_port) 306 { 307 hashvalue_type h = 0xab; 308 /* select the pieces to hash, some OS have changing data inside */ 309 if(addr_is_ip6(addr, addrlen)) { 310 struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr; 311 h = hashlittle(&in6->sin6_family, sizeof(in6->sin6_family), h); 312 if(use_port){ 313 h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h); 314 } 315 h = hashlittle(&in6->sin6_addr, INET6_SIZE, h); 316 } else { 317 struct sockaddr_in* in = (struct sockaddr_in*)addr; 318 h = hashlittle(&in->sin_family, sizeof(in->sin_family), h); 319 if(use_port){ 320 h = hashlittle(&in->sin_port, sizeof(in->sin_port), h); 321 } 322 h = hashlittle(&in->sin_addr, INET_SIZE, h); 323 } 324 return h; 325 } 326 327 /** calculate infra hash for a key */ 328 static hashvalue_type 329 hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name) 330 { 331 return dname_query_hash(name, hash_addr(addr, addrlen, 1)); 332 } 333 334 /** lookup version that does not check host ttl (you check it) */ 335 struct lruhash_entry* 336 infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr, 337 socklen_t addrlen, uint8_t* name, size_t namelen, int wr) 338 { 339 struct infra_key k; 340 k.addrlen = addrlen; 341 memcpy(&k.addr, addr, addrlen); 342 k.namelen = namelen; 343 k.zonename = name; 344 k.entry.hash = hash_infra(addr, addrlen, name); 345 k.entry.key = (void*)&k; 346 k.entry.data = NULL; 347 return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr); 348 } 349 350 /** init the data elements */ 351 static void 352 data_entry_init(struct infra_cache* infra, struct lruhash_entry* e, 353 time_t timenow) 354 { 355 struct infra_data* data = (struct infra_data*)e->data; 356 data->ttl = timenow + infra->host_ttl; 357 rtt_init(&data->rtt); 358 data->edns_version = 0; 359 data->edns_lame_known = 0; 360 data->probedelay = 0; 361 data->isdnsseclame = 0; 362 data->rec_lame = 0; 363 data->lame_type_A = 0; 364 data->lame_other = 0; 365 data->timeout_A = 0; 366 data->timeout_AAAA = 0; 367 data->timeout_other = 0; 368 } 369 370 /** 371 * Create and init a new entry for a host 372 * @param infra: infra structure with config parameters. 373 * @param addr: host address. 374 * @param addrlen: length of addr. 375 * @param name: name of zone 376 * @param namelen: length of name. 377 * @param tm: time now. 378 * @return: the new entry or NULL on malloc failure. 379 */ 380 static struct lruhash_entry* 381 new_entry(struct infra_cache* infra, struct sockaddr_storage* addr, 382 socklen_t addrlen, uint8_t* name, size_t namelen, time_t tm) 383 { 384 struct infra_data* data; 385 struct infra_key* key = (struct infra_key*)malloc(sizeof(*key)); 386 if(!key) 387 return NULL; 388 data = (struct infra_data*)malloc(sizeof(struct infra_data)); 389 if(!data) { 390 free(key); 391 return NULL; 392 } 393 key->zonename = memdup(name, namelen); 394 if(!key->zonename) { 395 free(key); 396 free(data); 397 return NULL; 398 } 399 key->namelen = namelen; 400 lock_rw_init(&key->entry.lock); 401 key->entry.hash = hash_infra(addr, addrlen, name); 402 key->entry.key = (void*)key; 403 key->entry.data = (void*)data; 404 key->addrlen = addrlen; 405 memcpy(&key->addr, addr, addrlen); 406 data_entry_init(infra, &key->entry, tm); 407 return &key->entry; 408 } 409 410 int 411 infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, 412 socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow, 413 int* edns_vs, uint8_t* edns_lame_known, int* to) 414 { 415 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 416 nm, nmlen, 0); 417 struct infra_data* data; 418 int wr = 0; 419 if(e && ((struct infra_data*)e->data)->ttl < timenow) { 420 /* it expired, try to reuse existing entry */ 421 int old = ((struct infra_data*)e->data)->rtt.rto; 422 uint8_t tA = ((struct infra_data*)e->data)->timeout_A; 423 uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA; 424 uint8_t tother = ((struct infra_data*)e->data)->timeout_other; 425 lock_rw_unlock(&e->lock); 426 e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1); 427 if(e) { 428 /* if its still there we have a writelock, init */ 429 /* re-initialise */ 430 /* do not touch lameness, it may be valid still */ 431 data_entry_init(infra, e, timenow); 432 wr = 1; 433 /* TOP_TIMEOUT remains on reuse */ 434 if(old >= USEFUL_SERVER_TOP_TIMEOUT) { 435 ((struct infra_data*)e->data)->rtt.rto 436 = USEFUL_SERVER_TOP_TIMEOUT; 437 ((struct infra_data*)e->data)->timeout_A = tA; 438 ((struct infra_data*)e->data)->timeout_AAAA = tAAAA; 439 ((struct infra_data*)e->data)->timeout_other = tother; 440 } 441 } 442 } 443 if(!e) { 444 /* insert new entry */ 445 if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) 446 return 0; 447 data = (struct infra_data*)e->data; 448 *edns_vs = data->edns_version; 449 *edns_lame_known = data->edns_lame_known; 450 *to = rtt_timeout(&data->rtt); 451 slabhash_insert(infra->hosts, e->hash, e, data, NULL); 452 return 1; 453 } 454 /* use existing entry */ 455 data = (struct infra_data*)e->data; 456 *edns_vs = data->edns_version; 457 *edns_lame_known = data->edns_lame_known; 458 *to = rtt_timeout(&data->rtt); 459 if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) { 460 /* delay other queries, this is the probe query */ 461 if(!wr) { 462 lock_rw_unlock(&e->lock); 463 e = infra_lookup_nottl(infra, addr,addrlen,nm,nmlen, 1); 464 if(!e) { /* flushed from cache real fast, no use to 465 allocate just for the probedelay */ 466 return 1; 467 } 468 data = (struct infra_data*)e->data; 469 } 470 /* add 999 to round up the timeout value from msec to sec, 471 * then add a whole second so it is certain that this probe 472 * has timed out before the next is allowed */ 473 data->probedelay = timenow + ((*to)+1999)/1000; 474 } 475 lock_rw_unlock(&e->lock); 476 return 1; 477 } 478 479 int 480 infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr, 481 socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow, 482 int dnsseclame, int reclame, uint16_t qtype) 483 { 484 struct infra_data* data; 485 struct lruhash_entry* e; 486 int needtoinsert = 0; 487 e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1); 488 if(!e) { 489 /* insert it */ 490 if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) { 491 log_err("set_lame: malloc failure"); 492 return 0; 493 } 494 needtoinsert = 1; 495 } else if( ((struct infra_data*)e->data)->ttl < timenow) { 496 /* expired, reuse existing entry */ 497 data_entry_init(infra, e, timenow); 498 } 499 /* got an entry, now set the zone lame */ 500 data = (struct infra_data*)e->data; 501 /* merge data (if any) */ 502 if(dnsseclame) 503 data->isdnsseclame = 1; 504 if(reclame) 505 data->rec_lame = 1; 506 if(!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A) 507 data->lame_type_A = 1; 508 if(!dnsseclame && !reclame && qtype != LDNS_RR_TYPE_A) 509 data->lame_other = 1; 510 /* done */ 511 if(needtoinsert) 512 slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); 513 else { lock_rw_unlock(&e->lock); } 514 return 1; 515 } 516 517 void 518 infra_update_tcp_works(struct infra_cache* infra, 519 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm, 520 size_t nmlen) 521 { 522 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 523 nm, nmlen, 1); 524 struct infra_data* data; 525 if(!e) 526 return; /* doesn't exist */ 527 data = (struct infra_data*)e->data; 528 if(data->rtt.rto >= RTT_MAX_TIMEOUT) 529 /* do not disqualify this server altogether, it is better 530 * than nothing */ 531 data->rtt.rto = RTT_MAX_TIMEOUT-1000; 532 lock_rw_unlock(&e->lock); 533 } 534 535 int 536 infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, 537 socklen_t addrlen, uint8_t* nm, size_t nmlen, int qtype, 538 int roundtrip, int orig_rtt, time_t timenow) 539 { 540 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 541 nm, nmlen, 1); 542 struct infra_data* data; 543 int needtoinsert = 0; 544 int rto = 1; 545 if(!e) { 546 if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) 547 return 0; 548 needtoinsert = 1; 549 } else if(((struct infra_data*)e->data)->ttl < timenow) { 550 data_entry_init(infra, e, timenow); 551 } 552 /* have an entry, update the rtt */ 553 data = (struct infra_data*)e->data; 554 if(roundtrip == -1) { 555 rtt_lost(&data->rtt, orig_rtt); 556 if(qtype == LDNS_RR_TYPE_A) { 557 if(data->timeout_A < TIMEOUT_COUNT_MAX) 558 data->timeout_A++; 559 } else if(qtype == LDNS_RR_TYPE_AAAA) { 560 if(data->timeout_AAAA < TIMEOUT_COUNT_MAX) 561 data->timeout_AAAA++; 562 } else { 563 if(data->timeout_other < TIMEOUT_COUNT_MAX) 564 data->timeout_other++; 565 } 566 } else { 567 /* if we got a reply, but the old timeout was above server 568 * selection height, delete the timeout so the server is 569 * fully available again */ 570 if(rtt_unclamped(&data->rtt) >= USEFUL_SERVER_TOP_TIMEOUT) 571 rtt_init(&data->rtt); 572 rtt_update(&data->rtt, roundtrip); 573 data->probedelay = 0; 574 if(qtype == LDNS_RR_TYPE_A) 575 data->timeout_A = 0; 576 else if(qtype == LDNS_RR_TYPE_AAAA) 577 data->timeout_AAAA = 0; 578 else data->timeout_other = 0; 579 } 580 if(data->rtt.rto > 0) 581 rto = data->rtt.rto; 582 583 if(needtoinsert) 584 slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); 585 else { lock_rw_unlock(&e->lock); } 586 return rto; 587 } 588 589 long long infra_get_host_rto(struct infra_cache* infra, 590 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm, 591 size_t nmlen, struct rtt_info* rtt, int* delay, time_t timenow, 592 int* tA, int* tAAAA, int* tother) 593 { 594 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 595 nm, nmlen, 0); 596 struct infra_data* data; 597 long long ttl = -2; 598 if(!e) return -1; 599 data = (struct infra_data*)e->data; 600 if(data->ttl >= timenow) { 601 ttl = (long long)(data->ttl - timenow); 602 memmove(rtt, &data->rtt, sizeof(*rtt)); 603 if(timenow < data->probedelay) 604 *delay = (int)(data->probedelay - timenow); 605 else *delay = 0; 606 } 607 *tA = (int)data->timeout_A; 608 *tAAAA = (int)data->timeout_AAAA; 609 *tother = (int)data->timeout_other; 610 lock_rw_unlock(&e->lock); 611 return ttl; 612 } 613 614 int 615 infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr, 616 socklen_t addrlen, uint8_t* nm, size_t nmlen, int edns_version, 617 time_t timenow) 618 { 619 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 620 nm, nmlen, 1); 621 struct infra_data* data; 622 int needtoinsert = 0; 623 if(!e) { 624 if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) 625 return 0; 626 needtoinsert = 1; 627 } else if(((struct infra_data*)e->data)->ttl < timenow) { 628 data_entry_init(infra, e, timenow); 629 } 630 /* have an entry, update the rtt, and the ttl */ 631 data = (struct infra_data*)e->data; 632 /* do not update if noEDNS and stored is yesEDNS */ 633 if(!(edns_version == -1 && (data->edns_version != -1 && 634 data->edns_lame_known))) { 635 data->edns_version = edns_version; 636 data->edns_lame_known = 1; 637 } 638 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 int 646 infra_get_lame_rtt(struct infra_cache* infra, 647 struct sockaddr_storage* addr, socklen_t addrlen, 648 uint8_t* name, size_t namelen, uint16_t qtype, 649 int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow) 650 { 651 struct infra_data* host; 652 struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, 653 name, namelen, 0); 654 if(!e) 655 return 0; 656 host = (struct infra_data*)e->data; 657 *rtt = rtt_unclamped(&host->rtt); 658 if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay 659 && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) { 660 /* single probe for this domain, and we are not probing */ 661 /* unless the query type allows a probe to happen */ 662 if(qtype == LDNS_RR_TYPE_A) { 663 if(host->timeout_A >= TIMEOUT_COUNT_MAX) 664 *rtt = USEFUL_SERVER_TOP_TIMEOUT; 665 else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; 666 } else if(qtype == LDNS_RR_TYPE_AAAA) { 667 if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX) 668 *rtt = USEFUL_SERVER_TOP_TIMEOUT; 669 else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; 670 } else { 671 if(host->timeout_other >= TIMEOUT_COUNT_MAX) 672 *rtt = USEFUL_SERVER_TOP_TIMEOUT; 673 else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; 674 } 675 } 676 if(timenow > host->ttl) { 677 /* expired entry */ 678 /* see if this can be a re-probe of an unresponsive server */ 679 /* minus 1000 because that is outside of the RTTBAND, so 680 * blacklisted servers stay blacklisted if this is chosen */ 681 if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { 682 lock_rw_unlock(&e->lock); 683 *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; 684 *lame = 0; 685 *dnsseclame = 0; 686 *reclame = 0; 687 return 1; 688 } 689 lock_rw_unlock(&e->lock); 690 return 0; 691 } 692 /* check lameness first */ 693 if(host->lame_type_A && qtype == LDNS_RR_TYPE_A) { 694 lock_rw_unlock(&e->lock); 695 *lame = 1; 696 *dnsseclame = 0; 697 *reclame = 0; 698 return 1; 699 } else if(host->lame_other && qtype != LDNS_RR_TYPE_A) { 700 lock_rw_unlock(&e->lock); 701 *lame = 1; 702 *dnsseclame = 0; 703 *reclame = 0; 704 return 1; 705 } else if(host->isdnsseclame) { 706 lock_rw_unlock(&e->lock); 707 *lame = 0; 708 *dnsseclame = 1; 709 *reclame = 0; 710 return 1; 711 } else if(host->rec_lame) { 712 lock_rw_unlock(&e->lock); 713 *lame = 0; 714 *dnsseclame = 0; 715 *reclame = 1; 716 return 1; 717 } 718 /* no lameness for this type of query */ 719 lock_rw_unlock(&e->lock); 720 *lame = 0; 721 *dnsseclame = 0; 722 *reclame = 0; 723 return 1; 724 } 725 726 int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name, 727 size_t namelen) 728 { 729 int labs = dname_count_labels(name); 730 struct domain_limit_data* d = (struct domain_limit_data*) 731 name_tree_lookup(&infra->domain_limits, name, namelen, labs, 732 LDNS_RR_CLASS_IN); 733 if(!d) return infra_dp_ratelimit; 734 735 if(d->node.labs == labs && d->lim != -1) 736 return d->lim; /* exact match */ 737 738 /* find 'below match' */ 739 if(d->node.labs == labs) 740 d = (struct domain_limit_data*)d->node.parent; 741 while(d) { 742 if(d->below != -1) 743 return d->below; 744 d = (struct domain_limit_data*)d->node.parent; 745 } 746 return infra_dp_ratelimit; 747 } 748 749 size_t ip_rate_sizefunc(void* k, void* ATTR_UNUSED(d)) 750 { 751 struct ip_rate_key* key = (struct ip_rate_key*)k; 752 return sizeof(*key) + sizeof(struct ip_rate_data) 753 + lock_get_mem(&key->entry.lock); 754 } 755 756 int ip_rate_compfunc(void* key1, void* key2) 757 { 758 struct ip_rate_key* k1 = (struct ip_rate_key*)key1; 759 struct ip_rate_key* k2 = (struct ip_rate_key*)key2; 760 return sockaddr_cmp_addr(&k1->addr, k1->addrlen, 761 &k2->addr, k2->addrlen); 762 } 763 764 void ip_rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg)) 765 { 766 struct ip_rate_key* key = (struct ip_rate_key*)k; 767 if(!key) 768 return; 769 lock_rw_destroy(&key->entry.lock); 770 free(key); 771 } 772 773 /** find data item in array, for write access, caller unlocks */ 774 static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra, 775 uint8_t* name, size_t namelen, int wr) 776 { 777 struct rate_key key; 778 hashvalue_type h = dname_query_hash(name, 0xab); 779 memset(&key, 0, sizeof(key)); 780 key.name = name; 781 key.namelen = namelen; 782 key.entry.hash = h; 783 return slabhash_lookup(infra->domain_rates, h, &key, wr); 784 } 785 786 /** find data item in array for ip addresses */ 787 static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra, 788 struct comm_reply* repinfo, int wr) 789 { 790 struct ip_rate_key key; 791 hashvalue_type h = hash_addr(&(repinfo->addr), 792 repinfo->addrlen, 0); 793 memset(&key, 0, sizeof(key)); 794 key.addr = repinfo->addr; 795 key.addrlen = repinfo->addrlen; 796 key.entry.hash = h; 797 return slabhash_lookup(infra->client_ip_rates, h, &key, wr); 798 } 799 800 /** create rate data item for name, number 1 in now */ 801 static void infra_create_ratedata(struct infra_cache* infra, 802 uint8_t* name, size_t namelen, time_t timenow) 803 { 804 hashvalue_type h = dname_query_hash(name, 0xab); 805 struct rate_key* k = (struct rate_key*)calloc(1, sizeof(*k)); 806 struct rate_data* d = (struct rate_data*)calloc(1, sizeof(*d)); 807 if(!k || !d) { 808 free(k); 809 free(d); 810 return; /* alloc failure */ 811 } 812 k->namelen = namelen; 813 k->name = memdup(name, namelen); 814 if(!k->name) { 815 free(k); 816 free(d); 817 return; /* alloc failure */ 818 } 819 lock_rw_init(&k->entry.lock); 820 k->entry.hash = h; 821 k->entry.key = k; 822 k->entry.data = d; 823 d->qps[0] = 1; 824 d->timestamp[0] = timenow; 825 slabhash_insert(infra->domain_rates, h, &k->entry, d, NULL); 826 } 827 828 /** create rate data item for ip address */ 829 static void infra_ip_create_ratedata(struct infra_cache* infra, 830 struct comm_reply* repinfo, time_t timenow) 831 { 832 hashvalue_type h = hash_addr(&(repinfo->addr), 833 repinfo->addrlen, 0); 834 struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k)); 835 struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d)); 836 if(!k || !d) { 837 free(k); 838 free(d); 839 return; /* alloc failure */ 840 } 841 k->addr = repinfo->addr; 842 k->addrlen = repinfo->addrlen; 843 lock_rw_init(&k->entry.lock); 844 k->entry.hash = h; 845 k->entry.key = k; 846 k->entry.data = d; 847 d->qps[0] = 1; 848 d->timestamp[0] = timenow; 849 slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL); 850 } 851 852 /** find the second and return its rate counter, if none, remove oldest */ 853 static int* infra_rate_find_second(void* data, time_t t) 854 { 855 struct rate_data* d = (struct rate_data*)data; 856 int i, oldest; 857 for(i=0; i<RATE_WINDOW; i++) { 858 if(d->timestamp[i] == t) 859 return &(d->qps[i]); 860 } 861 /* remove oldest timestamp, and insert it at t with 0 qps */ 862 oldest = 0; 863 for(i=0; i<RATE_WINDOW; i++) { 864 if(d->timestamp[i] < d->timestamp[oldest]) 865 oldest = i; 866 } 867 d->timestamp[oldest] = t; 868 d->qps[oldest] = 0; 869 return &(d->qps[oldest]); 870 } 871 872 int infra_rate_max(void* data, time_t now) 873 { 874 struct rate_data* d = (struct rate_data*)data; 875 int i, max = 0; 876 for(i=0; i<RATE_WINDOW; i++) { 877 if(now-d->timestamp[i] <= RATE_WINDOW) { 878 if(d->qps[i] > max) 879 max = d->qps[i]; 880 } 881 } 882 return max; 883 } 884 885 int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, 886 size_t namelen, time_t timenow) 887 { 888 int lim, max; 889 struct lruhash_entry* entry; 890 891 if(!infra_dp_ratelimit) 892 return 1; /* not enabled */ 893 894 /* find ratelimit */ 895 lim = infra_find_ratelimit(infra, name, namelen); 896 if(!lim) 897 return 1; /* disabled for this domain */ 898 899 /* find or insert ratedata */ 900 entry = infra_find_ratedata(infra, name, namelen, 1); 901 if(entry) { 902 int premax = infra_rate_max(entry->data, timenow); 903 int* cur = infra_rate_find_second(entry->data, timenow); 904 (*cur)++; 905 max = infra_rate_max(entry->data, timenow); 906 lock_rw_unlock(&entry->lock); 907 908 if(premax < lim && max >= lim) { 909 char buf[257]; 910 dname_str(name, buf); 911 verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim); 912 } 913 return (max < lim); 914 } 915 916 /* create */ 917 infra_create_ratedata(infra, name, namelen, timenow); 918 return (1 < lim); 919 } 920 921 void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name, 922 size_t namelen, time_t timenow) 923 { 924 struct lruhash_entry* entry; 925 int* cur; 926 if(!infra_dp_ratelimit) 927 return; /* not enabled */ 928 entry = infra_find_ratedata(infra, name, namelen, 1); 929 if(!entry) return; /* not cached */ 930 cur = infra_rate_find_second(entry->data, timenow); 931 if((*cur) > 0) 932 (*cur)--; 933 lock_rw_unlock(&entry->lock); 934 } 935 936 int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name, 937 size_t namelen, time_t timenow) 938 { 939 struct lruhash_entry* entry; 940 int lim, max; 941 if(!infra_dp_ratelimit) 942 return 0; /* not enabled */ 943 944 /* find ratelimit */ 945 lim = infra_find_ratelimit(infra, name, namelen); 946 if(!lim) 947 return 0; /* disabled for this domain */ 948 949 /* find current rate */ 950 entry = infra_find_ratedata(infra, name, namelen, 0); 951 if(!entry) 952 return 0; /* not cached */ 953 max = infra_rate_max(entry->data, timenow); 954 lock_rw_unlock(&entry->lock); 955 956 return (max >= lim); 957 } 958 959 size_t 960 infra_get_mem(struct infra_cache* infra) 961 { 962 size_t s = sizeof(*infra) + slabhash_get_mem(infra->hosts); 963 if(infra->domain_rates) s += slabhash_get_mem(infra->domain_rates); 964 if(infra->client_ip_rates) s += slabhash_get_mem(infra->client_ip_rates); 965 /* ignore domain_limits because walk through tree is big */ 966 return s; 967 } 968 969 int infra_ip_ratelimit_inc(struct infra_cache* infra, 970 struct comm_reply* repinfo, time_t timenow) 971 { 972 int max; 973 struct lruhash_entry* entry; 974 975 /* not enabled */ 976 if(!infra_ip_ratelimit) { 977 return 1; 978 } 979 /* find or insert ratedata */ 980 entry = infra_find_ip_ratedata(infra, repinfo, 1); 981 if(entry) { 982 int premax = infra_rate_max(entry->data, timenow); 983 int* cur = infra_rate_find_second(entry->data, timenow); 984 (*cur)++; 985 max = infra_rate_max(entry->data, timenow); 986 lock_rw_unlock(&entry->lock); 987 988 if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) { 989 char client_ip[128]; 990 addr_to_str((struct sockaddr_storage *)&repinfo->addr, 991 repinfo->addrlen, client_ip, sizeof(client_ip)); 992 verbose(VERB_OPS, "ratelimit exceeded %s %d", client_ip, 993 infra_ip_ratelimit); 994 } 995 return (max <= infra_ip_ratelimit); 996 } 997 998 /* create */ 999 infra_ip_create_ratedata(infra, repinfo, timenow); 1000 return 1; 1001 } 1002