xref: /freebsd/contrib/unbound/services/cache/infra.h (revision 3e11bd9e2a2b1cbd4283c87c93e3cc75e3f2dacb)
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.
40  */
41 
42 #ifndef SERVICES_CACHE_INFRA_H
43 #define SERVICES_CACHE_INFRA_H
44 #include "util/storage/lruhash.h"
45 #include "util/rtt.h"
46 struct slabhash;
47 struct config_file;
48 
49 /**
50  * Host information kept for every server, per zone.
51  */
52 struct infra_key {
53 	/** the host address. */
54 	struct sockaddr_storage addr;
55 	/** length of addr. */
56 	socklen_t addrlen;
57 	/** zone name in wireformat */
58 	uint8_t* zonename;
59 	/** length of zonename */
60 	size_t namelen;
61 	/** hash table entry, data of type infra_data. */
62 	struct lruhash_entry entry;
63 };
64 
65 /**
66  * Host information encompasses host capabilities and retransmission timeouts.
67  * And lameness information (notAuthoritative, noEDNS, Recursive)
68  */
69 struct infra_data {
70 	/** TTL value for this entry. absolute time. */
71 	time_t ttl;
72 
73 	/** time in seconds (absolute) when probing re-commences, 0 disabled */
74 	time_t probedelay;
75 	/** round trip times for timeout calculation */
76 	struct rtt_info rtt;
77 
78 	/** edns version that the host supports, -1 means no EDNS */
79 	int edns_version;
80 	/** if the EDNS lameness is already known or not.
81 	 * EDNS lame is when EDNS queries or replies are dropped,
82 	 * and cause a timeout */
83 	uint8_t edns_lame_known;
84 
85 	/** is the host lame (does not serve the zone authoritatively),
86 	 * or is the host dnssec lame (does not serve DNSSEC data) */
87 	uint8_t isdnsseclame;
88 	/** is the host recursion lame (not AA, but RA) */
89 	uint8_t rec_lame;
90 	/** the host is lame (not authoritative) for A records */
91 	uint8_t lame_type_A;
92 	/** the host is lame (not authoritative) for other query types */
93 	uint8_t lame_other;
94 
95 	/** timeouts counter for type A */
96 	uint8_t timeout_A;
97 	/** timeouts counter for type AAAA */
98 	uint8_t timeout_AAAA;
99 	/** timeouts counter for others */
100 	uint8_t timeout_other;
101 };
102 
103 /**
104  * Infra cache
105  */
106 struct infra_cache {
107 	/** The hash table with hosts */
108 	struct slabhash* hosts;
109 	/** TTL value for host information, in seconds */
110 	int host_ttl;
111 };
112 
113 /** infra host cache default hash lookup size */
114 #define INFRA_HOST_STARTSIZE 32
115 /** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */
116 #define INFRA_BYTES_NAME 14
117 
118 /**
119  * Create infra cache.
120  * @param cfg: config parameters or NULL for defaults.
121  * @return: new infra cache, or NULL.
122  */
123 struct infra_cache* infra_create(struct config_file* cfg);
124 
125 /**
126  * Delete infra cache.
127  * @param infra: infrastructure cache to delete.
128  */
129 void infra_delete(struct infra_cache* infra);
130 
131 /**
132  * Adjust infra cache to use updated configuration settings.
133  * This may clean the cache. Operates a bit like realloc.
134  * There may be no threading or use by other threads.
135  * @param infra: existing cache. If NULL a new infra cache is returned.
136  * @param cfg: config options.
137  * @return the new infra cache pointer or NULL on error.
138  */
139 struct infra_cache* infra_adjust(struct infra_cache* infra,
140 	struct config_file* cfg);
141 
142 /**
143  * Plain find infra data function (used by the the other functions)
144  * @param infra: infrastructure cache.
145  * @param addr: host address.
146  * @param addrlen: length of addr.
147  * @param name: domain name of zone.
148  * @param namelen: length of domain name.
149  * @param wr: if true, writelock, else readlock.
150  * @return the entry, could be expired (this is not checked) or NULL.
151  */
152 struct lruhash_entry* infra_lookup_nottl(struct infra_cache* infra,
153 	struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name,
154 	size_t namelen, int wr);
155 
156 /**
157  * Find host information to send a packet. Creates new entry if not found.
158  * Lameness is empty. EDNS is 0 (try with first), and rtt is returned for
159  * the first message to it.
160  * Use this to send a packet only, because it also locks out others when
161  * probing is restricted.
162  * @param infra: infrastructure cache.
163  * @param addr: host address.
164  * @param addrlen: length of addr.
165  * @param name: domain name of zone.
166  * @param namelen: length of domain name.
167  * @param timenow: what time it is now.
168  * @param edns_vs: edns version it supports, is returned.
169  * @param edns_lame_known: if EDNS lame (EDNS is dropped in transit) has
170  * 	already been probed, is returned.
171  * @param to: timeout to use, is returned.
172  * @return: 0 on error.
173  */
174 int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
175 	socklen_t addrlen, uint8_t* name, size_t namelen,
176 	time_t timenow, int* edns_vs, uint8_t* edns_lame_known, int* to);
177 
178 /**
179  * Set a host to be lame for the given zone.
180  * @param infra: infrastructure cache.
181  * @param addr: host address.
182  * @param addrlen: length of addr.
183  * @param name: domain name of zone apex.
184  * @param namelen: length of domain name.
185  * @param timenow: what time it is now.
186  * @param dnsseclame: if true the host is set dnssec lame.
187  *	if false, the host is marked lame (not serving the zone).
188  * @param reclame: if true host is a recursor not AA server.
189  *      if false, dnsseclame or marked lame.
190  * @param qtype: the query type for which it is lame.
191  * @return: 0 on error.
192  */
193 int infra_set_lame(struct infra_cache* infra,
194         struct sockaddr_storage* addr, socklen_t addrlen,
195 	uint8_t* name, size_t namelen, time_t timenow, int dnsseclame,
196 	int reclame, uint16_t qtype);
197 
198 /**
199  * Update rtt information for the host.
200  * @param infra: infrastructure cache.
201  * @param addr: host address.
202  * @param addrlen: length of addr.
203  * @param name: zone name
204  * @param namelen: zone name length
205  * @param qtype: query type.
206  * @param roundtrip: estimate of roundtrip time in milliseconds or -1 for
207  * 	timeout.
208  * @param orig_rtt: original rtt for the query that timed out (roundtrip==-1).
209  * 	ignored if roundtrip != -1.
210  * @param timenow: what time it is now.
211  * @return: 0 on error. new rto otherwise.
212  */
213 int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
214 	socklen_t addrlen, uint8_t* name, size_t namelen, int qtype,
215 	int roundtrip, int orig_rtt, time_t timenow);
216 
217 /**
218  * Update information for the host, store that a TCP transaction works.
219  * @param infra: infrastructure cache.
220  * @param addr: host address.
221  * @param addrlen: length of addr.
222  * @param name: name of zone
223  * @param namelen: length of name
224  */
225 void infra_update_tcp_works(struct infra_cache* infra,
226         struct sockaddr_storage* addr, socklen_t addrlen,
227 	uint8_t* name, size_t namelen);
228 
229 /**
230  * Update edns information for the host.
231  * @param infra: infrastructure cache.
232  * @param addr: host address.
233  * @param addrlen: length of addr.
234  * @param name: name of zone
235  * @param namelen: length of name
236  * @param edns_version: the version that it publishes.
237  * 	If it is known to support EDNS then no-EDNS is not stored over it.
238  * @param timenow: what time it is now.
239  * @return: 0 on error.
240  */
241 int infra_edns_update(struct infra_cache* infra,
242         struct sockaddr_storage* addr, socklen_t addrlen,
243 	uint8_t* name, size_t namelen, int edns_version, time_t timenow);
244 
245 /**
246  * Get Lameness information and average RTT if host is in the cache.
247  * This information is to be used for server selection.
248  * @param infra: infrastructure cache.
249  * @param addr: host address.
250  * @param addrlen: length of addr.
251  * @param name: zone name.
252  * @param namelen: zone name length.
253  * @param qtype: the query to be made.
254  * @param lame: if function returns true, this returns lameness of the zone.
255  * @param dnsseclame: if function returns true, this returns if the zone
256  *	is dnssec-lame.
257  * @param reclame: if function returns true, this is if it is recursion lame.
258  * @param rtt: if function returns true, this returns avg rtt of the server.
259  * 	The rtt value is unclamped and reflects recent timeouts.
260  * @param timenow: what time it is now.
261  * @return if found in cache, or false if not (or TTL bad).
262  */
263 int infra_get_lame_rtt(struct infra_cache* infra,
264         struct sockaddr_storage* addr, socklen_t addrlen,
265 	uint8_t* name, size_t namelen, uint16_t qtype,
266 	int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow);
267 
268 /**
269  * Get additional (debug) info on timing.
270  * @param infra: infra cache.
271  * @param addr: host address.
272  * @param addrlen: length of addr.
273  * @param name: zone name
274  * @param namelen: zone name length
275  * @param rtt: the rtt_info is copied into here (caller alloced return struct).
276  * @param delay: probe delay (if any).
277  * @param timenow: what time it is now.
278  * @param tA: timeout counter on type A.
279  * @param tAAAA: timeout counter on type AAAA.
280  * @param tother: timeout counter on type other.
281  * @return TTL the infra host element is valid for. If -1: not found in cache.
282  *	TTL -2: found but expired.
283  */
284 long long infra_get_host_rto(struct infra_cache* infra,
285         struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name,
286 	size_t namelen, struct rtt_info* rtt, int* delay, time_t timenow,
287 	int* tA, int* tAAAA, int* tother);
288 
289 /**
290  * Get memory used by the infra cache.
291  * @param infra: infrastructure cache.
292  * @return memory in use in bytes.
293  */
294 size_t infra_get_mem(struct infra_cache* infra);
295 
296 /** calculate size for the hashtable, does not count size of lameness,
297  * so the hashtable is a fixed number of items */
298 size_t infra_sizefunc(void* k, void* d);
299 
300 /** compare two addresses, returns -1, 0, or +1 */
301 int infra_compfunc(void* key1, void* key2);
302 
303 /** delete key, and destroy the lock */
304 void infra_delkeyfunc(void* k, void* arg);
305 
306 /** delete data and destroy the lameness hashtable */
307 void infra_deldatafunc(void* d, void* arg);
308 
309 #endif /* SERVICES_CACHE_INFRA_H */
310