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