xref: /freebsd/contrib/unbound/services/cache/infra.h (revision be771a7b7f4580a30d99e41a5bb1b93a385a119d)
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