1 /* 2 * services/cache/infra.h - 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, as well as rate limiting. 40 * Note that there are two sorts of rate-limiting here: 41 * - Pre-cache, per-query rate limiting (query ratelimits) 42 * - Post-cache, per-domain name rate limiting (infra-ratelimits) 43 */ 44 45 #ifndef SERVICES_CACHE_INFRA_H 46 #define SERVICES_CACHE_INFRA_H 47 #include "util/storage/lruhash.h" 48 #include "util/storage/dnstree.h" 49 #include "util/rtt.h" 50 #include "util/netevent.h" 51 #include "util/data/msgreply.h" 52 struct slabhash; 53 struct config_file; 54 55 /** 56 * Host information kept for every server, per zone. 57 */ 58 struct infra_key { 59 /** the host address. */ 60 struct sockaddr_storage addr; 61 /** length of addr. */ 62 socklen_t addrlen; 63 /** zone name in wireformat */ 64 uint8_t* zonename; 65 /** length of zonename */ 66 size_t namelen; 67 /** hash table entry, data of type infra_data. */ 68 struct lruhash_entry entry; 69 }; 70 71 /** 72 * Host information encompasses host capabilities and retransmission timeouts. 73 * And lameness information (notAuthoritative, noEDNS, Recursive) 74 */ 75 struct infra_data { 76 /** TTL value for this entry. absolute time. */ 77 time_t ttl; 78 79 /** time in seconds (absolute) when probing re-commences, 0 disabled */ 80 time_t probedelay; 81 /** round trip times for timeout calculation */ 82 struct rtt_info rtt; 83 84 /** edns version that the host supports, -1 means no EDNS */ 85 int edns_version; 86 /** if the EDNS lameness is already known or not. 87 * EDNS lame is when EDNS queries or replies are dropped, 88 * and cause a timeout */ 89 uint8_t edns_lame_known; 90 91 /** is the host lame (does not serve the zone authoritatively), 92 * or is the host dnssec lame (does not serve DNSSEC data) */ 93 uint8_t isdnsseclame; 94 /** is the host recursion lame (not AA, but RA) */ 95 uint8_t rec_lame; 96 /** the host is lame (not authoritative) for A records */ 97 uint8_t lame_type_A; 98 /** the host is lame (not authoritative) for other query types */ 99 uint8_t lame_other; 100 101 /** timeouts counter for type A */ 102 uint8_t timeout_A; 103 /** timeouts counter for type AAAA */ 104 uint8_t timeout_AAAA; 105 /** timeouts counter for others */ 106 uint8_t timeout_other; 107 }; 108 109 /** 110 * Infra cache 111 */ 112 struct infra_cache { 113 /** The hash table with hosts */ 114 struct slabhash* hosts; 115 /** TTL value for host information, in seconds */ 116 int host_ttl; 117 /** hash table with query rates per name: rate_key, rate_data */ 118 struct slabhash* domain_rates; 119 /** ratelimit settings for domains, struct domain_limit_data */ 120 rbtree_type domain_limits; 121 /** hash table with query rates per client ip: ip_rate_key, ip_rate_data */ 122 struct slabhash* client_ip_rates; 123 }; 124 125 /** ratelimit, unless overridden by domain_limits, 0 is off */ 126 extern int infra_dp_ratelimit; 127 128 /** 129 * ratelimit settings for domains 130 */ 131 struct domain_limit_data { 132 /** key for rbtree, must be first in struct, name of domain */ 133 struct name_tree_node node; 134 /** ratelimit for exact match with this name, -1 if not set */ 135 int lim; 136 /** ratelimit for names below this name, -1 if not set */ 137 int below; 138 }; 139 140 /** 141 * key for ratelimit lookups, a domain name 142 */ 143 struct rate_key { 144 /** lruhash key entry */ 145 struct lruhash_entry entry; 146 /** domain name in uncompressed wireformat */ 147 uint8_t* name; 148 /** length of name */ 149 size_t namelen; 150 }; 151 152 /** ip ratelimit, 0 is off */ 153 extern int infra_ip_ratelimit; 154 155 /** 156 * key for ip_ratelimit lookups, a source IP. 157 */ 158 struct ip_rate_key { 159 /** lruhash key entry */ 160 struct lruhash_entry entry; 161 /** client ip information */ 162 struct sockaddr_storage addr; 163 /** length of address */ 164 socklen_t addrlen; 165 }; 166 167 /** number of seconds to track qps rate */ 168 #define RATE_WINDOW 2 169 170 /** 171 * Data for ratelimits per domain name 172 * It is incremented when a non-cache-lookup happens for that domain name. 173 * The name is the delegation point we have for the name. 174 * If a new delegation point is found (a referral reply), the previous 175 * delegation point is decremented, and the new one is charged with the query. 176 */ 177 struct rate_data { 178 /** queries counted, for that second. 0 if not in use. */ 179 int qps[RATE_WINDOW]; 180 /** what the timestamp is of the qps array members, counter is 181 * valid for that timestamp. Usually now and now-1. */ 182 time_t timestamp[RATE_WINDOW]; 183 }; 184 185 #define ip_rate_data rate_data 186 187 /** infra host cache default hash lookup size */ 188 #define INFRA_HOST_STARTSIZE 32 189 /** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */ 190 #define INFRA_BYTES_NAME 14 191 192 /** 193 * Create infra cache. 194 * @param cfg: config parameters or NULL for defaults. 195 * @return: new infra cache, or NULL. 196 */ 197 struct infra_cache* infra_create(struct config_file* cfg); 198 199 /** 200 * Delete infra cache. 201 * @param infra: infrastructure cache to delete. 202 */ 203 void infra_delete(struct infra_cache* infra); 204 205 /** 206 * Adjust infra cache to use updated configuration settings. 207 * This may clean the cache. Operates a bit like realloc. 208 * There may be no threading or use by other threads. 209 * @param infra: existing cache. If NULL a new infra cache is returned. 210 * @param cfg: config options. 211 * @return the new infra cache pointer or NULL on error. 212 */ 213 struct infra_cache* infra_adjust(struct infra_cache* infra, 214 struct config_file* cfg); 215 216 /** 217 * Plain find infra data function (used by the the other functions) 218 * @param infra: infrastructure cache. 219 * @param addr: host address. 220 * @param addrlen: length of addr. 221 * @param name: domain name of zone. 222 * @param namelen: length of domain name. 223 * @param wr: if true, writelock, else readlock. 224 * @return the entry, could be expired (this is not checked) or NULL. 225 */ 226 struct lruhash_entry* infra_lookup_nottl(struct infra_cache* infra, 227 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, 228 size_t namelen, int wr); 229 230 /** 231 * Find host information to send a packet. Creates new entry if not found. 232 * Lameness is empty. EDNS is 0 (try with first), and rtt is returned for 233 * the first message to it. 234 * Use this to send a packet only, because it also locks out others when 235 * probing is restricted. 236 * @param infra: infrastructure cache. 237 * @param addr: host address. 238 * @param addrlen: length of addr. 239 * @param name: domain name of zone. 240 * @param namelen: length of domain name. 241 * @param timenow: what time it is now. 242 * @param edns_vs: edns version it supports, is returned. 243 * @param edns_lame_known: if EDNS lame (EDNS is dropped in transit) has 244 * already been probed, is returned. 245 * @param to: timeout to use, is returned. 246 * @return: 0 on error. 247 */ 248 int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, 249 socklen_t addrlen, uint8_t* name, size_t namelen, 250 time_t timenow, int* edns_vs, uint8_t* edns_lame_known, int* to); 251 252 /** 253 * Set a host to be lame for the given zone. 254 * @param infra: infrastructure cache. 255 * @param addr: host address. 256 * @param addrlen: length of addr. 257 * @param name: domain name of zone apex. 258 * @param namelen: length of domain name. 259 * @param timenow: what time it is now. 260 * @param dnsseclame: if true the host is set dnssec lame. 261 * if false, the host is marked lame (not serving the zone). 262 * @param reclame: if true host is a recursor not AA server. 263 * if false, dnsseclame or marked lame. 264 * @param qtype: the query type for which it is lame. 265 * @return: 0 on error. 266 */ 267 int infra_set_lame(struct infra_cache* infra, 268 struct sockaddr_storage* addr, socklen_t addrlen, 269 uint8_t* name, size_t namelen, time_t timenow, int dnsseclame, 270 int reclame, uint16_t qtype); 271 272 /** 273 * Update rtt information for the host. 274 * @param infra: infrastructure cache. 275 * @param addr: host address. 276 * @param addrlen: length of addr. 277 * @param name: zone name 278 * @param namelen: zone name length 279 * @param qtype: query type. 280 * @param roundtrip: estimate of roundtrip time in milliseconds or -1 for 281 * timeout. 282 * @param orig_rtt: original rtt for the query that timed out (roundtrip==-1). 283 * ignored if roundtrip != -1. 284 * @param timenow: what time it is now. 285 * @return: 0 on error. new rto otherwise. 286 */ 287 int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, 288 socklen_t addrlen, uint8_t* name, size_t namelen, int qtype, 289 int roundtrip, int orig_rtt, time_t timenow); 290 291 /** 292 * Update information for the host, store that a TCP transaction works. 293 * @param infra: infrastructure cache. 294 * @param addr: host address. 295 * @param addrlen: length of addr. 296 * @param name: name of zone 297 * @param namelen: length of name 298 */ 299 void infra_update_tcp_works(struct infra_cache* infra, 300 struct sockaddr_storage* addr, socklen_t addrlen, 301 uint8_t* name, size_t namelen); 302 303 /** 304 * Update edns information for the host. 305 * @param infra: infrastructure cache. 306 * @param addr: host address. 307 * @param addrlen: length of addr. 308 * @param name: name of zone 309 * @param namelen: length of name 310 * @param edns_version: the version that it publishes. 311 * If it is known to support EDNS then no-EDNS is not stored over it. 312 * @param timenow: what time it is now. 313 * @return: 0 on error. 314 */ 315 int infra_edns_update(struct infra_cache* infra, 316 struct sockaddr_storage* addr, socklen_t addrlen, 317 uint8_t* name, size_t namelen, int edns_version, time_t timenow); 318 319 /** 320 * Get Lameness information and average RTT if host is in the cache. 321 * This information is to be used for server selection. 322 * @param infra: infrastructure cache. 323 * @param addr: host address. 324 * @param addrlen: length of addr. 325 * @param name: zone name. 326 * @param namelen: zone name length. 327 * @param qtype: the query to be made. 328 * @param lame: if function returns true, this returns lameness of the zone. 329 * @param dnsseclame: if function returns true, this returns if the zone 330 * is dnssec-lame. 331 * @param reclame: if function returns true, this is if it is recursion lame. 332 * @param rtt: if function returns true, this returns avg rtt of the server. 333 * The rtt value is unclamped and reflects recent timeouts. 334 * @param timenow: what time it is now. 335 * @return if found in cache, or false if not (or TTL bad). 336 */ 337 int infra_get_lame_rtt(struct infra_cache* infra, 338 struct sockaddr_storage* addr, socklen_t addrlen, 339 uint8_t* name, size_t namelen, uint16_t qtype, 340 int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow); 341 342 /** 343 * Get additional (debug) info on timing. 344 * @param infra: infra cache. 345 * @param addr: host address. 346 * @param addrlen: length of addr. 347 * @param name: zone name 348 * @param namelen: zone name length 349 * @param rtt: the rtt_info is copied into here (caller alloced return struct). 350 * @param delay: probe delay (if any). 351 * @param timenow: what time it is now. 352 * @param tA: timeout counter on type A. 353 * @param tAAAA: timeout counter on type AAAA. 354 * @param tother: timeout counter on type other. 355 * @return TTL the infra host element is valid for. If -1: not found in cache. 356 * TTL -2: found but expired. 357 */ 358 long long infra_get_host_rto(struct infra_cache* infra, 359 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, 360 size_t namelen, struct rtt_info* rtt, int* delay, time_t timenow, 361 int* tA, int* tAAAA, int* tother); 362 363 /** 364 * Increment the query rate counter for a delegation point. 365 * @param infra: infra cache. 366 * @param name: zone name 367 * @param namelen: zone name length 368 * @param timenow: what time it is now. 369 * @param qinfo: for logging, query name. 370 * @param replylist: for logging, querier's address (if any). 371 * @return 1 if it could be incremented. 0 if the increment overshot the 372 * ratelimit or if in the previous second the ratelimit was exceeded. 373 * Failures like alloc failures are not returned (probably as 1). 374 */ 375 int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, 376 size_t namelen, time_t timenow, struct query_info* qinfo, 377 struct comm_reply* replylist); 378 379 /** 380 * Decrement the query rate counter for a delegation point. 381 * Because the reply received for the delegation point was pleasant, 382 * we do not charge this delegation point with it (i.e. it was a referral). 383 * Should call it with same second as when inc() was called. 384 * @param infra: infra cache. 385 * @param name: zone name 386 * @param namelen: zone name length 387 * @param timenow: what time it is now. 388 */ 389 void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name, 390 size_t namelen, time_t timenow); 391 392 /** 393 * See if the query rate counter for a delegation point is exceeded. 394 * So, no queries are going to be allowed. 395 * @param infra: infra cache. 396 * @param name: zone name 397 * @param namelen: zone name length 398 * @param timenow: what time it is now. 399 * @return true if exceeded. 400 */ 401 int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name, 402 size_t namelen, time_t timenow); 403 404 /** find the maximum rate stored, not too old. 0 if no information. */ 405 int infra_rate_max(void* data, time_t now); 406 407 /** find the ratelimit in qps for a domain. 0 if no limit for domain. */ 408 int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name, 409 size_t namelen); 410 411 /** Update query ratelimit hash and decide 412 * whether or not a query should be dropped. 413 * @param infra: infra cache 414 * @param repinfo: information about client 415 * @param timenow: what time it is now. 416 * @param buffer: with query for logging. 417 * @return 1 if it could be incremented. 0 if the increment overshot the 418 * ratelimit and the query should be dropped. */ 419 int infra_ip_ratelimit_inc(struct infra_cache* infra, 420 struct comm_reply* repinfo, time_t timenow, 421 struct sldns_buffer* buffer); 422 423 /** 424 * Get memory used by the infra cache. 425 * @param infra: infrastructure cache. 426 * @return memory in use in bytes. 427 */ 428 size_t infra_get_mem(struct infra_cache* infra); 429 430 /** calculate size for the hashtable, does not count size of lameness, 431 * so the hashtable is a fixed number of items */ 432 size_t infra_sizefunc(void* k, void* d); 433 434 /** compare two addresses, returns -1, 0, or +1 */ 435 int infra_compfunc(void* key1, void* key2); 436 437 /** delete key, and destroy the lock */ 438 void infra_delkeyfunc(void* k, void* arg); 439 440 /** delete data and destroy the lameness hashtable */ 441 void infra_deldatafunc(void* d, void* arg); 442 443 /** calculate size for the hashtable */ 444 size_t rate_sizefunc(void* k, void* d); 445 446 /** compare two names, returns -1, 0, or +1 */ 447 int rate_compfunc(void* key1, void* key2); 448 449 /** delete key, and destroy the lock */ 450 void rate_delkeyfunc(void* k, void* arg); 451 452 /** delete data */ 453 void rate_deldatafunc(void* d, void* arg); 454 455 /* calculate size for the client ip hashtable */ 456 size_t ip_rate_sizefunc(void* k, void* d); 457 458 /* compare two addresses */ 459 int ip_rate_compfunc(void* key1, void* key2); 460 461 /* delete key, and destroy the lock */ 462 void ip_rate_delkeyfunc(void* d, void* arg); 463 464 /* delete data */ 465 #define ip_rate_deldatafunc rate_deldatafunc 466 467 #endif /* SERVICES_CACHE_INFRA_H */ 468