infra.h revision 269257
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"
46struct slabhash;
47struct config_file;
48
49/**
50 * Host information kept for every server, per zone.
51 */
52struct 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 */
69struct 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 */
106struct 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 */
123struct infra_cache* infra_create(struct config_file* cfg);
124
125/**
126 * Delete infra cache.
127 * @param infra: infrastructure cache to delete.
128 */
129void 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 */
139struct 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 */
152struct 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 */
174int 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 */
193int 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 */
213int 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 */
225void 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 */
241int 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 */
263int 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 */
284long 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 */
294size_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 */
298size_t infra_sizefunc(void* k, void* d);
299
300/** compare two addresses, returns -1, 0, or +1 */
301int infra_compfunc(void* key1, void* key2);
302
303/** delete key, and destroy the lock */
304void infra_delkeyfunc(void* k, void* arg);
305
306/** delete data and destroy the lameness hashtable */
307void infra_deldatafunc(void* d, void* arg);
308
309#endif /* SERVICES_CACHE_INFRA_H */
310