1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * services/cache/infra.h - infrastructure cache, server rtt and capabilities 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 393005e0a3SDag-Erling Smørgrav * This file contains the infrastructure cache, as well as rate limiting. 403005e0a3SDag-Erling Smørgrav * Note that there are two sorts of rate-limiting here: 413005e0a3SDag-Erling Smørgrav * - Pre-cache, per-query rate limiting (query ratelimits) 423005e0a3SDag-Erling Smørgrav * - Post-cache, per-domain name rate limiting (infra-ratelimits) 43b7579f77SDag-Erling Smørgrav */ 44b7579f77SDag-Erling Smørgrav 45b7579f77SDag-Erling Smørgrav #ifndef SERVICES_CACHE_INFRA_H 46b7579f77SDag-Erling Smørgrav #define SERVICES_CACHE_INFRA_H 47b7579f77SDag-Erling Smørgrav #include "util/storage/lruhash.h" 4809a3aaf3SDag-Erling Smørgrav #include "util/storage/dnstree.h" 49b7579f77SDag-Erling Smørgrav #include "util/rtt.h" 503005e0a3SDag-Erling Smørgrav #include "util/netevent.h" 513005e0a3SDag-Erling Smørgrav #include "util/data/msgreply.h" 52b7579f77SDag-Erling Smørgrav struct slabhash; 53b7579f77SDag-Erling Smørgrav struct config_file; 54b7579f77SDag-Erling Smørgrav 55*be771a7bSCy Schubert /** number of timeouts for a type when the domain can be blocked ; 56*be771a7bSCy Schubert * even if another type has completely rtt maxed it, the different type 57*be771a7bSCy Schubert * can do this number of packets (until those all timeout too) */ 58*be771a7bSCy Schubert #define TIMEOUT_COUNT_MAX 3 59*be771a7bSCy Schubert 60*be771a7bSCy Schubert 61*be771a7bSCy Schubert /** Timeout when only a single probe query per IP is allowed. 62*be771a7bSCy Schubert * Any RTO above this number is considered a probe. 63*be771a7bSCy Schubert * It is synchronized (caped) with USEFUL_SERVER_TOP_TIMEOUT so that probing 64*be771a7bSCy Schubert * keeps working even if that configurable number drops below the default 65*be771a7bSCy Schubert * 12000 ms of probing. */ 66*be771a7bSCy Schubert extern int PROBE_MAXRTO; 67*be771a7bSCy Schubert 68b7579f77SDag-Erling Smørgrav /** 69b7579f77SDag-Erling Smørgrav * Host information kept for every server, per zone. 70b7579f77SDag-Erling Smørgrav */ 71b7579f77SDag-Erling Smørgrav struct infra_key { 72b7579f77SDag-Erling Smørgrav /** the host address. */ 73b7579f77SDag-Erling Smørgrav struct sockaddr_storage addr; 74b7579f77SDag-Erling Smørgrav /** length of addr. */ 75b7579f77SDag-Erling Smørgrav socklen_t addrlen; 76b7579f77SDag-Erling Smørgrav /** zone name in wireformat */ 77b7579f77SDag-Erling Smørgrav uint8_t* zonename; 78b7579f77SDag-Erling Smørgrav /** length of zonename */ 79b7579f77SDag-Erling Smørgrav size_t namelen; 80b7579f77SDag-Erling Smørgrav /** hash table entry, data of type infra_data. */ 81b7579f77SDag-Erling Smørgrav struct lruhash_entry entry; 82b7579f77SDag-Erling Smørgrav }; 83b7579f77SDag-Erling Smørgrav 84b7579f77SDag-Erling Smørgrav /** 85b7579f77SDag-Erling Smørgrav * Host information encompasses host capabilities and retransmission timeouts. 86b7579f77SDag-Erling Smørgrav * And lameness information (notAuthoritative, noEDNS, Recursive) 87b7579f77SDag-Erling Smørgrav */ 88b7579f77SDag-Erling Smørgrav struct infra_data { 89b7579f77SDag-Erling Smørgrav /** TTL value for this entry. absolute time. */ 9017d15b25SDag-Erling Smørgrav time_t ttl; 91b7579f77SDag-Erling Smørgrav 92b7579f77SDag-Erling Smørgrav /** time in seconds (absolute) when probing re-commences, 0 disabled */ 9317d15b25SDag-Erling Smørgrav time_t probedelay; 94b7579f77SDag-Erling Smørgrav /** round trip times for timeout calculation */ 95b7579f77SDag-Erling Smørgrav struct rtt_info rtt; 96b7579f77SDag-Erling Smørgrav 97b7579f77SDag-Erling Smørgrav /** edns version that the host supports, -1 means no EDNS */ 98b7579f77SDag-Erling Smørgrav int edns_version; 99b7579f77SDag-Erling Smørgrav /** if the EDNS lameness is already known or not. 100b7579f77SDag-Erling Smørgrav * EDNS lame is when EDNS queries or replies are dropped, 101b7579f77SDag-Erling Smørgrav * and cause a timeout */ 102b7579f77SDag-Erling Smørgrav uint8_t edns_lame_known; 103b7579f77SDag-Erling Smørgrav 104b7579f77SDag-Erling Smørgrav /** is the host lame (does not serve the zone authoritatively), 105b7579f77SDag-Erling Smørgrav * or is the host dnssec lame (does not serve DNSSEC data) */ 106b7579f77SDag-Erling Smørgrav uint8_t isdnsseclame; 107b7579f77SDag-Erling Smørgrav /** is the host recursion lame (not AA, but RA) */ 108b7579f77SDag-Erling Smørgrav uint8_t rec_lame; 109b7579f77SDag-Erling Smørgrav /** the host is lame (not authoritative) for A records */ 110b7579f77SDag-Erling Smørgrav uint8_t lame_type_A; 111b7579f77SDag-Erling Smørgrav /** the host is lame (not authoritative) for other query types */ 112b7579f77SDag-Erling Smørgrav uint8_t lame_other; 113b7579f77SDag-Erling Smørgrav 114b7579f77SDag-Erling Smørgrav /** timeouts counter for type A */ 115b7579f77SDag-Erling Smørgrav uint8_t timeout_A; 116b7579f77SDag-Erling Smørgrav /** timeouts counter for type AAAA */ 117b7579f77SDag-Erling Smørgrav uint8_t timeout_AAAA; 118b7579f77SDag-Erling Smørgrav /** timeouts counter for others */ 119b7579f77SDag-Erling Smørgrav uint8_t timeout_other; 120b7579f77SDag-Erling Smørgrav }; 121b7579f77SDag-Erling Smørgrav 122b7579f77SDag-Erling Smørgrav /** 123b7579f77SDag-Erling Smørgrav * Infra cache 124b7579f77SDag-Erling Smørgrav */ 125b7579f77SDag-Erling Smørgrav struct infra_cache { 126b7579f77SDag-Erling Smørgrav /** The hash table with hosts */ 127b7579f77SDag-Erling Smørgrav struct slabhash* hosts; 128b7579f77SDag-Erling Smørgrav /** TTL value for host information, in seconds */ 129b7579f77SDag-Erling Smørgrav int host_ttl; 130369c6923SCy Schubert /** the hosts that are down are kept probed for recovery */ 131369c6923SCy Schubert int infra_keep_probing; 13209a3aaf3SDag-Erling Smørgrav /** hash table with query rates per name: rate_key, rate_data */ 13309a3aaf3SDag-Erling Smørgrav struct slabhash* domain_rates; 13409a3aaf3SDag-Erling Smørgrav /** ratelimit settings for domains, struct domain_limit_data */ 1353005e0a3SDag-Erling Smørgrav rbtree_type domain_limits; 1363005e0a3SDag-Erling Smørgrav /** hash table with query rates per client ip: ip_rate_key, ip_rate_data */ 1373005e0a3SDag-Erling Smørgrav struct slabhash* client_ip_rates; 138335c7cdaSCy Schubert /** tree of addr_tree_node, with wait_limit_netblock_info information */ 139335c7cdaSCy Schubert rbtree_type wait_limits_netblock; 140335c7cdaSCy Schubert /** tree of addr_tree_node, with wait_limit_netblock_info information */ 141335c7cdaSCy Schubert rbtree_type wait_limits_cookie_netblock; 14209a3aaf3SDag-Erling Smørgrav }; 14309a3aaf3SDag-Erling Smørgrav 14409a3aaf3SDag-Erling Smørgrav /** ratelimit, unless overridden by domain_limits, 0 is off */ 14509a3aaf3SDag-Erling Smørgrav extern int infra_dp_ratelimit; 14609a3aaf3SDag-Erling Smørgrav 14709a3aaf3SDag-Erling Smørgrav /** 14809a3aaf3SDag-Erling Smørgrav * ratelimit settings for domains 14909a3aaf3SDag-Erling Smørgrav */ 15009a3aaf3SDag-Erling Smørgrav struct domain_limit_data { 15109a3aaf3SDag-Erling Smørgrav /** key for rbtree, must be first in struct, name of domain */ 15209a3aaf3SDag-Erling Smørgrav struct name_tree_node node; 15309a3aaf3SDag-Erling Smørgrav /** ratelimit for exact match with this name, -1 if not set */ 15409a3aaf3SDag-Erling Smørgrav int lim; 15509a3aaf3SDag-Erling Smørgrav /** ratelimit for names below this name, -1 if not set */ 15609a3aaf3SDag-Erling Smørgrav int below; 15709a3aaf3SDag-Erling Smørgrav }; 15809a3aaf3SDag-Erling Smørgrav 15909a3aaf3SDag-Erling Smørgrav /** 16009a3aaf3SDag-Erling Smørgrav * key for ratelimit lookups, a domain name 16109a3aaf3SDag-Erling Smørgrav */ 16209a3aaf3SDag-Erling Smørgrav struct rate_key { 16309a3aaf3SDag-Erling Smørgrav /** lruhash key entry */ 16409a3aaf3SDag-Erling Smørgrav struct lruhash_entry entry; 16509a3aaf3SDag-Erling Smørgrav /** domain name in uncompressed wireformat */ 16609a3aaf3SDag-Erling Smørgrav uint8_t* name; 16709a3aaf3SDag-Erling Smørgrav /** length of name */ 16809a3aaf3SDag-Erling Smørgrav size_t namelen; 16909a3aaf3SDag-Erling Smørgrav }; 17009a3aaf3SDag-Erling Smørgrav 1713005e0a3SDag-Erling Smørgrav /** ip ratelimit, 0 is off */ 1723005e0a3SDag-Erling Smørgrav extern int infra_ip_ratelimit; 1738f76bb7dSCy Schubert /** ip ratelimit for DNS Cookie clients, 0 is off */ 1748f76bb7dSCy Schubert extern int infra_ip_ratelimit_cookie; 1753005e0a3SDag-Erling Smørgrav 1763005e0a3SDag-Erling Smørgrav /** 1773005e0a3SDag-Erling Smørgrav * key for ip_ratelimit lookups, a source IP. 1783005e0a3SDag-Erling Smørgrav */ 1793005e0a3SDag-Erling Smørgrav struct ip_rate_key { 1803005e0a3SDag-Erling Smørgrav /** lruhash key entry */ 1813005e0a3SDag-Erling Smørgrav struct lruhash_entry entry; 1823005e0a3SDag-Erling Smørgrav /** client ip information */ 1833005e0a3SDag-Erling Smørgrav struct sockaddr_storage addr; 1843005e0a3SDag-Erling Smørgrav /** length of address */ 1853005e0a3SDag-Erling Smørgrav socklen_t addrlen; 1863005e0a3SDag-Erling Smørgrav }; 1873005e0a3SDag-Erling Smørgrav 18809a3aaf3SDag-Erling Smørgrav /** number of seconds to track qps rate */ 18909a3aaf3SDag-Erling Smørgrav #define RATE_WINDOW 2 19009a3aaf3SDag-Erling Smørgrav 19109a3aaf3SDag-Erling Smørgrav /** 19209a3aaf3SDag-Erling Smørgrav * Data for ratelimits per domain name 19309a3aaf3SDag-Erling Smørgrav * It is incremented when a non-cache-lookup happens for that domain name. 19409a3aaf3SDag-Erling Smørgrav * The name is the delegation point we have for the name. 19509a3aaf3SDag-Erling Smørgrav * If a new delegation point is found (a referral reply), the previous 19609a3aaf3SDag-Erling Smørgrav * delegation point is decremented, and the new one is charged with the query. 19709a3aaf3SDag-Erling Smørgrav */ 19809a3aaf3SDag-Erling Smørgrav struct rate_data { 19909a3aaf3SDag-Erling Smørgrav /** queries counted, for that second. 0 if not in use. */ 20009a3aaf3SDag-Erling Smørgrav int qps[RATE_WINDOW]; 20109a3aaf3SDag-Erling Smørgrav /** what the timestamp is of the qps array members, counter is 20209a3aaf3SDag-Erling Smørgrav * valid for that timestamp. Usually now and now-1. */ 20309a3aaf3SDag-Erling Smørgrav time_t timestamp[RATE_WINDOW]; 204335c7cdaSCy Schubert /** the number of queries waiting in the mesh */ 205335c7cdaSCy Schubert int mesh_wait; 206b7579f77SDag-Erling Smørgrav }; 207b7579f77SDag-Erling Smørgrav 2083005e0a3SDag-Erling Smørgrav #define ip_rate_data rate_data 2093005e0a3SDag-Erling Smørgrav 210335c7cdaSCy Schubert /** 211335c7cdaSCy Schubert * Data to store the configuration per netblock for the wait limit 212335c7cdaSCy Schubert */ 213335c7cdaSCy Schubert struct wait_limit_netblock_info { 214335c7cdaSCy Schubert /** The addr tree node, this must be first. */ 215335c7cdaSCy Schubert struct addr_tree_node node; 216335c7cdaSCy Schubert /** the limit on the amount */ 217335c7cdaSCy Schubert int limit; 218335c7cdaSCy Schubert }; 219335c7cdaSCy Schubert 220b7579f77SDag-Erling Smørgrav /** infra host cache default hash lookup size */ 221b7579f77SDag-Erling Smørgrav #define INFRA_HOST_STARTSIZE 32 222b7579f77SDag-Erling Smørgrav /** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */ 223b7579f77SDag-Erling Smørgrav #define INFRA_BYTES_NAME 14 224b7579f77SDag-Erling Smørgrav 225b7579f77SDag-Erling Smørgrav /** 226b7579f77SDag-Erling Smørgrav * Create infra cache. 227b7579f77SDag-Erling Smørgrav * @param cfg: config parameters or NULL for defaults. 228b7579f77SDag-Erling Smørgrav * @return: new infra cache, or NULL. 229b7579f77SDag-Erling Smørgrav */ 230b7579f77SDag-Erling Smørgrav struct infra_cache* infra_create(struct config_file* cfg); 231b7579f77SDag-Erling Smørgrav 232b7579f77SDag-Erling Smørgrav /** 233b7579f77SDag-Erling Smørgrav * Delete infra cache. 234b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache to delete. 235b7579f77SDag-Erling Smørgrav */ 236b7579f77SDag-Erling Smørgrav void infra_delete(struct infra_cache* infra); 237b7579f77SDag-Erling Smørgrav 238b7579f77SDag-Erling Smørgrav /** 239b7579f77SDag-Erling Smørgrav * Adjust infra cache to use updated configuration settings. 240b7579f77SDag-Erling Smørgrav * This may clean the cache. Operates a bit like realloc. 241b7579f77SDag-Erling Smørgrav * There may be no threading or use by other threads. 242b7579f77SDag-Erling Smørgrav * @param infra: existing cache. If NULL a new infra cache is returned. 243b7579f77SDag-Erling Smørgrav * @param cfg: config options. 244b7579f77SDag-Erling Smørgrav * @return the new infra cache pointer or NULL on error. 245b7579f77SDag-Erling Smørgrav */ 246b7579f77SDag-Erling Smørgrav struct infra_cache* infra_adjust(struct infra_cache* infra, 247b7579f77SDag-Erling Smørgrav struct config_file* cfg); 248b7579f77SDag-Erling Smørgrav 249b7579f77SDag-Erling Smørgrav /** 25056850988SCy Schubert * Plain find infra data function (used by the other functions) 251b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 252b7579f77SDag-Erling Smørgrav * @param addr: host address. 253b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 254b7579f77SDag-Erling Smørgrav * @param name: domain name of zone. 255b7579f77SDag-Erling Smørgrav * @param namelen: length of domain name. 256b7579f77SDag-Erling Smørgrav * @param wr: if true, writelock, else readlock. 257b7579f77SDag-Erling Smørgrav * @return the entry, could be expired (this is not checked) or NULL. 258b7579f77SDag-Erling Smørgrav */ 259b7579f77SDag-Erling Smørgrav struct lruhash_entry* infra_lookup_nottl(struct infra_cache* infra, 260b7579f77SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, 261b7579f77SDag-Erling Smørgrav size_t namelen, int wr); 262b7579f77SDag-Erling Smørgrav 263b7579f77SDag-Erling Smørgrav /** 264b7579f77SDag-Erling Smørgrav * Find host information to send a packet. Creates new entry if not found. 265b7579f77SDag-Erling Smørgrav * Lameness is empty. EDNS is 0 (try with first), and rtt is returned for 266b7579f77SDag-Erling Smørgrav * the first message to it. 267b7579f77SDag-Erling Smørgrav * Use this to send a packet only, because it also locks out others when 268b7579f77SDag-Erling Smørgrav * probing is restricted. 269b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 270b7579f77SDag-Erling Smørgrav * @param addr: host address. 271b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 272b7579f77SDag-Erling Smørgrav * @param name: domain name of zone. 273b7579f77SDag-Erling Smørgrav * @param namelen: length of domain name. 274b7579f77SDag-Erling Smørgrav * @param timenow: what time it is now. 275b7579f77SDag-Erling Smørgrav * @param edns_vs: edns version it supports, is returned. 276b7579f77SDag-Erling Smørgrav * @param edns_lame_known: if EDNS lame (EDNS is dropped in transit) has 277b7579f77SDag-Erling Smørgrav * already been probed, is returned. 278b7579f77SDag-Erling Smørgrav * @param to: timeout to use, is returned. 279b7579f77SDag-Erling Smørgrav * @return: 0 on error. 280b7579f77SDag-Erling Smørgrav */ 281b7579f77SDag-Erling Smørgrav int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, 282b7579f77SDag-Erling Smørgrav socklen_t addrlen, uint8_t* name, size_t namelen, 28317d15b25SDag-Erling Smørgrav time_t timenow, int* edns_vs, uint8_t* edns_lame_known, int* to); 284b7579f77SDag-Erling Smørgrav 285b7579f77SDag-Erling Smørgrav /** 286b7579f77SDag-Erling Smørgrav * Set a host to be lame for the given zone. 287b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 288b7579f77SDag-Erling Smørgrav * @param addr: host address. 289b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 290b7579f77SDag-Erling Smørgrav * @param name: domain name of zone apex. 291b7579f77SDag-Erling Smørgrav * @param namelen: length of domain name. 292b7579f77SDag-Erling Smørgrav * @param timenow: what time it is now. 293b7579f77SDag-Erling Smørgrav * @param dnsseclame: if true the host is set dnssec lame. 294b7579f77SDag-Erling Smørgrav * if false, the host is marked lame (not serving the zone). 295b7579f77SDag-Erling Smørgrav * @param reclame: if true host is a recursor not AA server. 296b7579f77SDag-Erling Smørgrav * if false, dnsseclame or marked lame. 297b7579f77SDag-Erling Smørgrav * @param qtype: the query type for which it is lame. 298b7579f77SDag-Erling Smørgrav * @return: 0 on error. 299b7579f77SDag-Erling Smørgrav */ 300b7579f77SDag-Erling Smørgrav int infra_set_lame(struct infra_cache* infra, 301b7579f77SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, 30217d15b25SDag-Erling Smørgrav uint8_t* name, size_t namelen, time_t timenow, int dnsseclame, 303b7579f77SDag-Erling Smørgrav int reclame, uint16_t qtype); 304b7579f77SDag-Erling Smørgrav 305b7579f77SDag-Erling Smørgrav /** 306b7579f77SDag-Erling Smørgrav * Update rtt information for the host. 307b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 308b7579f77SDag-Erling Smørgrav * @param addr: host address. 309b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 310b7579f77SDag-Erling Smørgrav * @param name: zone name 311b7579f77SDag-Erling Smørgrav * @param namelen: zone name length 312b7579f77SDag-Erling Smørgrav * @param qtype: query type. 313b7579f77SDag-Erling Smørgrav * @param roundtrip: estimate of roundtrip time in milliseconds or -1 for 314b7579f77SDag-Erling Smørgrav * timeout. 315b7579f77SDag-Erling Smørgrav * @param orig_rtt: original rtt for the query that timed out (roundtrip==-1). 316b7579f77SDag-Erling Smørgrav * ignored if roundtrip != -1. 317b7579f77SDag-Erling Smørgrav * @param timenow: what time it is now. 318b7579f77SDag-Erling Smørgrav * @return: 0 on error. new rto otherwise. 319b7579f77SDag-Erling Smørgrav */ 320b7579f77SDag-Erling Smørgrav int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, 321b7579f77SDag-Erling Smørgrav socklen_t addrlen, uint8_t* name, size_t namelen, int qtype, 32217d15b25SDag-Erling Smørgrav int roundtrip, int orig_rtt, time_t timenow); 323b7579f77SDag-Erling Smørgrav 324b7579f77SDag-Erling Smørgrav /** 325b7579f77SDag-Erling Smørgrav * Update information for the host, store that a TCP transaction works. 326b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 327b7579f77SDag-Erling Smørgrav * @param addr: host address. 328b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 329b7579f77SDag-Erling Smørgrav * @param name: name of zone 330b7579f77SDag-Erling Smørgrav * @param namelen: length of name 331b7579f77SDag-Erling Smørgrav */ 332b7579f77SDag-Erling Smørgrav void infra_update_tcp_works(struct infra_cache* infra, 333b7579f77SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, 334b7579f77SDag-Erling Smørgrav uint8_t* name, size_t namelen); 335b7579f77SDag-Erling Smørgrav 336b7579f77SDag-Erling Smørgrav /** 337b7579f77SDag-Erling Smørgrav * Update edns information for the host. 338b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 339b7579f77SDag-Erling Smørgrav * @param addr: host address. 340b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 341b7579f77SDag-Erling Smørgrav * @param name: name of zone 342b7579f77SDag-Erling Smørgrav * @param namelen: length of name 343b7579f77SDag-Erling Smørgrav * @param edns_version: the version that it publishes. 344b7579f77SDag-Erling Smørgrav * If it is known to support EDNS then no-EDNS is not stored over it. 345b7579f77SDag-Erling Smørgrav * @param timenow: what time it is now. 346b7579f77SDag-Erling Smørgrav * @return: 0 on error. 347b7579f77SDag-Erling Smørgrav */ 348b7579f77SDag-Erling Smørgrav int infra_edns_update(struct infra_cache* infra, 349b7579f77SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, 35017d15b25SDag-Erling Smørgrav uint8_t* name, size_t namelen, int edns_version, time_t timenow); 351b7579f77SDag-Erling Smørgrav 352b7579f77SDag-Erling Smørgrav /** 353b7579f77SDag-Erling Smørgrav * Get Lameness information and average RTT if host is in the cache. 354b7579f77SDag-Erling Smørgrav * This information is to be used for server selection. 355b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 356b7579f77SDag-Erling Smørgrav * @param addr: host address. 357b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 358b7579f77SDag-Erling Smørgrav * @param name: zone name. 359b7579f77SDag-Erling Smørgrav * @param namelen: zone name length. 360b7579f77SDag-Erling Smørgrav * @param qtype: the query to be made. 361b7579f77SDag-Erling Smørgrav * @param lame: if function returns true, this returns lameness of the zone. 362b7579f77SDag-Erling Smørgrav * @param dnsseclame: if function returns true, this returns if the zone 363b7579f77SDag-Erling Smørgrav * is dnssec-lame. 364b7579f77SDag-Erling Smørgrav * @param reclame: if function returns true, this is if it is recursion lame. 365b7579f77SDag-Erling Smørgrav * @param rtt: if function returns true, this returns avg rtt of the server. 366b7579f77SDag-Erling Smørgrav * The rtt value is unclamped and reflects recent timeouts. 367b7579f77SDag-Erling Smørgrav * @param timenow: what time it is now. 368b7579f77SDag-Erling Smørgrav * @return if found in cache, or false if not (or TTL bad). 369b7579f77SDag-Erling Smørgrav */ 370b7579f77SDag-Erling Smørgrav int infra_get_lame_rtt(struct infra_cache* infra, 371b7579f77SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, 372b7579f77SDag-Erling Smørgrav uint8_t* name, size_t namelen, uint16_t qtype, 37317d15b25SDag-Erling Smørgrav int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow); 374b7579f77SDag-Erling Smørgrav 375b7579f77SDag-Erling Smørgrav /** 376b7579f77SDag-Erling Smørgrav * Get additional (debug) info on timing. 377b7579f77SDag-Erling Smørgrav * @param infra: infra cache. 378b7579f77SDag-Erling Smørgrav * @param addr: host address. 379b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 380b7579f77SDag-Erling Smørgrav * @param name: zone name 381b7579f77SDag-Erling Smørgrav * @param namelen: zone name length 382b7579f77SDag-Erling Smørgrav * @param rtt: the rtt_info is copied into here (caller alloced return struct). 383b7579f77SDag-Erling Smørgrav * @param delay: probe delay (if any). 384b7579f77SDag-Erling Smørgrav * @param timenow: what time it is now. 385b7579f77SDag-Erling Smørgrav * @param tA: timeout counter on type A. 386b7579f77SDag-Erling Smørgrav * @param tAAAA: timeout counter on type AAAA. 387b7579f77SDag-Erling Smørgrav * @param tother: timeout counter on type other. 388b7579f77SDag-Erling Smørgrav * @return TTL the infra host element is valid for. If -1: not found in cache. 389b7579f77SDag-Erling Smørgrav * TTL -2: found but expired. 390b7579f77SDag-Erling Smørgrav */ 39117d15b25SDag-Erling Smørgrav long long infra_get_host_rto(struct infra_cache* infra, 392b7579f77SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, 39317d15b25SDag-Erling Smørgrav size_t namelen, struct rtt_info* rtt, int* delay, time_t timenow, 394b7579f77SDag-Erling Smørgrav int* tA, int* tAAAA, int* tother); 395b7579f77SDag-Erling Smørgrav 396b7579f77SDag-Erling Smørgrav /** 39709a3aaf3SDag-Erling Smørgrav * Increment the query rate counter for a delegation point. 39809a3aaf3SDag-Erling Smørgrav * @param infra: infra cache. 39909a3aaf3SDag-Erling Smørgrav * @param name: zone name 40009a3aaf3SDag-Erling Smørgrav * @param namelen: zone name length 40109a3aaf3SDag-Erling Smørgrav * @param timenow: what time it is now. 4029cf5bc93SCy Schubert * @param backoff: if backoff is enabled. 403e86b9096SDag-Erling Smørgrav * @param qinfo: for logging, query name. 404e86b9096SDag-Erling Smørgrav * @param replylist: for logging, querier's address (if any). 40509a3aaf3SDag-Erling Smørgrav * @return 1 if it could be incremented. 0 if the increment overshot the 40609a3aaf3SDag-Erling Smørgrav * ratelimit or if in the previous second the ratelimit was exceeded. 40709a3aaf3SDag-Erling Smørgrav * Failures like alloc failures are not returned (probably as 1). 40809a3aaf3SDag-Erling Smørgrav */ 40909a3aaf3SDag-Erling Smørgrav int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, 4109cf5bc93SCy Schubert size_t namelen, time_t timenow, int backoff, struct query_info* qinfo, 411e86b9096SDag-Erling Smørgrav struct comm_reply* replylist); 41209a3aaf3SDag-Erling Smørgrav 41309a3aaf3SDag-Erling Smørgrav /** 41409a3aaf3SDag-Erling Smørgrav * Decrement the query rate counter for a delegation point. 41509a3aaf3SDag-Erling Smørgrav * Because the reply received for the delegation point was pleasant, 41609a3aaf3SDag-Erling Smørgrav * we do not charge this delegation point with it (i.e. it was a referral). 41709a3aaf3SDag-Erling Smørgrav * Should call it with same second as when inc() was called. 41809a3aaf3SDag-Erling Smørgrav * @param infra: infra cache. 41909a3aaf3SDag-Erling Smørgrav * @param name: zone name 42009a3aaf3SDag-Erling Smørgrav * @param namelen: zone name length 42109a3aaf3SDag-Erling Smørgrav * @param timenow: what time it is now. 42209a3aaf3SDag-Erling Smørgrav */ 42309a3aaf3SDag-Erling Smørgrav void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name, 42409a3aaf3SDag-Erling Smørgrav size_t namelen, time_t timenow); 42509a3aaf3SDag-Erling Smørgrav 42609a3aaf3SDag-Erling Smørgrav /** 42709a3aaf3SDag-Erling Smørgrav * See if the query rate counter for a delegation point is exceeded. 42809a3aaf3SDag-Erling Smørgrav * So, no queries are going to be allowed. 42909a3aaf3SDag-Erling Smørgrav * @param infra: infra cache. 43009a3aaf3SDag-Erling Smørgrav * @param name: zone name 43109a3aaf3SDag-Erling Smørgrav * @param namelen: zone name length 43209a3aaf3SDag-Erling Smørgrav * @param timenow: what time it is now. 4339cf5bc93SCy Schubert * @param backoff: if backoff is enabled. 43409a3aaf3SDag-Erling Smørgrav * @return true if exceeded. 43509a3aaf3SDag-Erling Smørgrav */ 43609a3aaf3SDag-Erling Smørgrav int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name, 4379cf5bc93SCy Schubert size_t namelen, time_t timenow, int backoff); 43809a3aaf3SDag-Erling Smørgrav 4399cf5bc93SCy Schubert /** find the maximum rate stored. 0 if no information. 4409cf5bc93SCy Schubert * When backoff is enabled look for the maximum in the whole RATE_WINDOW. */ 4419cf5bc93SCy Schubert int infra_rate_max(void* data, time_t now, int backoff); 44209a3aaf3SDag-Erling Smørgrav 443c7f4d7adSDag-Erling Smørgrav /** find the ratelimit in qps for a domain. 0 if no limit for domain. */ 44409a3aaf3SDag-Erling Smørgrav int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name, 44509a3aaf3SDag-Erling Smørgrav size_t namelen); 44609a3aaf3SDag-Erling Smørgrav 4473005e0a3SDag-Erling Smørgrav /** Update query ratelimit hash and decide 4483005e0a3SDag-Erling Smørgrav * whether or not a query should be dropped. 4493005e0a3SDag-Erling Smørgrav * @param infra: infra cache 450865f46b2SCy Schubert * @param addr: client address 451865f46b2SCy Schubert * @param addrlen: client address length 4523005e0a3SDag-Erling Smørgrav * @param timenow: what time it is now. 4538f76bb7dSCy Schubert * @param has_cookie: if the request came with a DNS Cookie. 4549cf5bc93SCy Schubert * @param backoff: if backoff is enabled. 455e86b9096SDag-Erling Smørgrav * @param buffer: with query for logging. 4563005e0a3SDag-Erling Smørgrav * @return 1 if it could be incremented. 0 if the increment overshot the 4573005e0a3SDag-Erling Smørgrav * ratelimit and the query should be dropped. */ 4583005e0a3SDag-Erling Smørgrav int infra_ip_ratelimit_inc(struct infra_cache* infra, 459865f46b2SCy Schubert struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow, 4608f76bb7dSCy Schubert int has_cookie, int backoff, struct sldns_buffer* buffer); 4613005e0a3SDag-Erling Smørgrav 46209a3aaf3SDag-Erling Smørgrav /** 463b7579f77SDag-Erling Smørgrav * Get memory used by the infra cache. 464b7579f77SDag-Erling Smørgrav * @param infra: infrastructure cache. 465b7579f77SDag-Erling Smørgrav * @return memory in use in bytes. 466b7579f77SDag-Erling Smørgrav */ 467b7579f77SDag-Erling Smørgrav size_t infra_get_mem(struct infra_cache* infra); 468b7579f77SDag-Erling Smørgrav 469b7579f77SDag-Erling Smørgrav /** calculate size for the hashtable, does not count size of lameness, 470b7579f77SDag-Erling Smørgrav * so the hashtable is a fixed number of items */ 471b7579f77SDag-Erling Smørgrav size_t infra_sizefunc(void* k, void* d); 472b7579f77SDag-Erling Smørgrav 473b7579f77SDag-Erling Smørgrav /** compare two addresses, returns -1, 0, or +1 */ 474b7579f77SDag-Erling Smørgrav int infra_compfunc(void* key1, void* key2); 475b7579f77SDag-Erling Smørgrav 476b7579f77SDag-Erling Smørgrav /** delete key, and destroy the lock */ 477b7579f77SDag-Erling Smørgrav void infra_delkeyfunc(void* k, void* arg); 478b7579f77SDag-Erling Smørgrav 479b7579f77SDag-Erling Smørgrav /** delete data and destroy the lameness hashtable */ 480b7579f77SDag-Erling Smørgrav void infra_deldatafunc(void* d, void* arg); 481b7579f77SDag-Erling Smørgrav 48209a3aaf3SDag-Erling Smørgrav /** calculate size for the hashtable */ 48309a3aaf3SDag-Erling Smørgrav size_t rate_sizefunc(void* k, void* d); 48409a3aaf3SDag-Erling Smørgrav 48509a3aaf3SDag-Erling Smørgrav /** compare two names, returns -1, 0, or +1 */ 48609a3aaf3SDag-Erling Smørgrav int rate_compfunc(void* key1, void* key2); 48709a3aaf3SDag-Erling Smørgrav 48809a3aaf3SDag-Erling Smørgrav /** delete key, and destroy the lock */ 48909a3aaf3SDag-Erling Smørgrav void rate_delkeyfunc(void* k, void* arg); 49009a3aaf3SDag-Erling Smørgrav 49109a3aaf3SDag-Erling Smørgrav /** delete data */ 49209a3aaf3SDag-Erling Smørgrav void rate_deldatafunc(void* d, void* arg); 49309a3aaf3SDag-Erling Smørgrav 4943005e0a3SDag-Erling Smørgrav /* calculate size for the client ip hashtable */ 4953005e0a3SDag-Erling Smørgrav size_t ip_rate_sizefunc(void* k, void* d); 4963005e0a3SDag-Erling Smørgrav 4973005e0a3SDag-Erling Smørgrav /* compare two addresses */ 4983005e0a3SDag-Erling Smørgrav int ip_rate_compfunc(void* key1, void* key2); 4993005e0a3SDag-Erling Smørgrav 5003005e0a3SDag-Erling Smørgrav /* delete key, and destroy the lock */ 5013005e0a3SDag-Erling Smørgrav void ip_rate_delkeyfunc(void* d, void* arg); 5023005e0a3SDag-Erling Smørgrav 5033005e0a3SDag-Erling Smørgrav /* delete data */ 5043005e0a3SDag-Erling Smørgrav #define ip_rate_deldatafunc rate_deldatafunc 5053005e0a3SDag-Erling Smørgrav 506335c7cdaSCy Schubert /** See if the IP address can have another reply in the wait limit */ 507335c7cdaSCy Schubert int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep, 508335c7cdaSCy Schubert int cookie_valid, struct config_file* cfg); 509335c7cdaSCy Schubert 510335c7cdaSCy Schubert /** Increment number of waiting replies for IP */ 511335c7cdaSCy Schubert void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep, 512335c7cdaSCy Schubert time_t timenow, struct config_file* cfg); 513335c7cdaSCy Schubert 514335c7cdaSCy Schubert /** Decrement number of waiting replies for IP */ 515335c7cdaSCy Schubert void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep, 516335c7cdaSCy Schubert struct config_file* cfg); 517335c7cdaSCy Schubert 518*be771a7bSCy Schubert /** setup wait limits tree (0 on failure) */ 519*be771a7bSCy Schubert int setup_wait_limits(struct rbtree_type* wait_limits_netblock, 520*be771a7bSCy Schubert struct rbtree_type* wait_limits_cookie_netblock, 521*be771a7bSCy Schubert struct config_file* cfg); 522*be771a7bSCy Schubert 523*be771a7bSCy Schubert /** Free the wait limits and wait cookie limits tree. */ 524*be771a7bSCy Schubert void wait_limits_free(struct rbtree_type* wait_limits_tree); 525*be771a7bSCy Schubert 526*be771a7bSCy Schubert /** setup domain limits tree (0 on failure) */ 527*be771a7bSCy Schubert int setup_domain_limits(struct rbtree_type* domain_limits, 528*be771a7bSCy Schubert struct config_file* cfg); 529*be771a7bSCy Schubert 530*be771a7bSCy Schubert /** Free the domain limits tree. */ 531*be771a7bSCy Schubert void domain_limits_free(struct rbtree_type* domain_limits); 532*be771a7bSCy Schubert 533*be771a7bSCy Schubert /** exported for unit test */ 534*be771a7bSCy Schubert int still_useful_timeout(); 535*be771a7bSCy Schubert 536b7579f77SDag-Erling Smørgrav #endif /* SERVICES_CACHE_INFRA_H */ 537