2 * services/cache/infra.h - infrastructure cache, server rtt and capabilities
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
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)
45 #ifndef SERVICES_CACHE_INFRA_H
46 #define SERVICES_CACHE_INFRA_H
47 #include "util/storage/lruhash.h"
48 #include "util/storage/dnstree.h"
50 #include "util/netevent.h"
51 #include "util/data/msgreply.h"
56 * Host information kept for every server, per zone.
59 /** the host address. */
60 struct sockaddr_storage addr;
61 /** length of addr. */
63 /** zone name in wireformat */
65 /** length of zonename */
67 /** hash table entry, data of type infra_data. */
68 struct lruhash_entry entry;
72 * Host information encompasses host capabilities and retransmission timeouts.
73 * And lameness information (notAuthoritative, noEDNS, Recursive)
76 /** TTL value for this entry. absolute time. */
79 /** time in seconds (absolute) when probing re-commences, 0 disabled */
81 /** round trip times for timeout calculation */
84 /** edns version that the host supports, -1 means no EDNS */
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;
91 /** is the host lame (does not serve the zone authoritatively),
92 * or is the host dnssec lame (does not serve DNSSEC data) */
94 /** is the host recursion lame (not AA, but RA) */
96 /** the host is lame (not authoritative) for A records */
98 /** the host is lame (not authoritative) for other query types */
101 /** timeouts counter for type A */
103 /** timeouts counter for type AAAA */
104 uint8_t timeout_AAAA;
105 /** timeouts counter for others */
106 uint8_t timeout_other;
113 /** The hash table with hosts */
114 struct slabhash* hosts;
115 /** TTL value for host information, in seconds */
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;
125 /** ratelimit, unless overridden by domain_limits, 0 is off */
126 extern int infra_dp_ratelimit;
129 * ratelimit settings for domains
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 */
136 /** ratelimit for names below this name, -1 if not set */
141 * key for ratelimit lookups, a domain name
144 /** lruhash key entry */
145 struct lruhash_entry entry;
146 /** domain name in uncompressed wireformat */
148 /** length of name */
152 /** ip ratelimit, 0 is off */
153 extern int infra_ip_ratelimit;
156 * key for ip_ratelimit lookups, a source IP.
159 /** lruhash key entry */
160 struct lruhash_entry entry;
161 /** client ip information */
162 struct sockaddr_storage addr;
163 /** length of address */
167 /** number of seconds to track qps rate */
168 #define RATE_WINDOW 2
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.
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];
185 #define ip_rate_data rate_data
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
193 * Create infra cache.
194 * @param cfg: config parameters or NULL for defaults.
195 * @return: new infra cache, or NULL.
197 struct infra_cache* infra_create(struct config_file* cfg);
200 * Delete infra cache.
201 * @param infra: infrastructure cache to delete.
203 void infra_delete(struct infra_cache* infra);
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.
213 struct infra_cache* infra_adjust(struct infra_cache* infra,
214 struct config_file* cfg);
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.
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);
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.
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);
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.
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);
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
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.
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);
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
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);
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.
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);
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
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).
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);
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.
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);
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 * @return 1 if it could be incremented. 0 if the increment overshot the
370 * ratelimit or if in the previous second the ratelimit was exceeded.
371 * Failures like alloc failures are not returned (probably as 1).
373 int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
374 size_t namelen, time_t timenow);
377 * Decrement the query rate counter for a delegation point.
378 * Because the reply received for the delegation point was pleasant,
379 * we do not charge this delegation point with it (i.e. it was a referral).
380 * Should call it with same second as when inc() was called.
381 * @param infra: infra cache.
382 * @param name: zone name
383 * @param namelen: zone name length
384 * @param timenow: what time it is now.
386 void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
387 size_t namelen, time_t timenow);
390 * See if the query rate counter for a delegation point is exceeded.
391 * So, no queries are going to be allowed.
392 * @param infra: infra cache.
393 * @param name: zone name
394 * @param namelen: zone name length
395 * @param timenow: what time it is now.
396 * @return true if exceeded.
398 int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
399 size_t namelen, time_t timenow);
401 /** find the maximum rate stored, not too old. 0 if no information. */
402 int infra_rate_max(void* data, time_t now);
404 /** find the ratelimit in qps for a domain. 0 if no limit for domain. */
405 int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
408 /** Update query ratelimit hash and decide
409 * whether or not a query should be dropped.
410 * @param infra: infra cache
411 * @param repinfo: information about client
412 * @param timenow: what time it is now.
413 * @return 1 if it could be incremented. 0 if the increment overshot the
414 * ratelimit and the query should be dropped. */
415 int infra_ip_ratelimit_inc(struct infra_cache* infra,
416 struct comm_reply* repinfo, time_t timenow);
419 * Get memory used by the infra cache.
420 * @param infra: infrastructure cache.
421 * @return memory in use in bytes.
423 size_t infra_get_mem(struct infra_cache* infra);
425 /** calculate size for the hashtable, does not count size of lameness,
426 * so the hashtable is a fixed number of items */
427 size_t infra_sizefunc(void* k, void* d);
429 /** compare two addresses, returns -1, 0, or +1 */
430 int infra_compfunc(void* key1, void* key2);
432 /** delete key, and destroy the lock */
433 void infra_delkeyfunc(void* k, void* arg);
435 /** delete data and destroy the lameness hashtable */
436 void infra_deldatafunc(void* d, void* arg);
438 /** calculate size for the hashtable */
439 size_t rate_sizefunc(void* k, void* d);
441 /** compare two names, returns -1, 0, or +1 */
442 int rate_compfunc(void* key1, void* key2);
444 /** delete key, and destroy the lock */
445 void rate_delkeyfunc(void* k, void* arg);
448 void rate_deldatafunc(void* d, void* arg);
450 /* calculate size for the client ip hashtable */
451 size_t ip_rate_sizefunc(void* k, void* d);
453 /* compare two addresses */
454 int ip_rate_compfunc(void* key1, void* key2);
456 /* delete key, and destroy the lock */
457 void ip_rate_delkeyfunc(void* d, void* arg);
460 #define ip_rate_deldatafunc rate_deldatafunc
462 #endif /* SERVICES_CACHE_INFRA_H */