]>
Commit | Line | Data |
---|---|---|
89c4ed63 A |
1 | /* |
2 | * util/data/packed_rrset.h - data storage for a set of resource records. | |
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 data storage for RRsets. | |
40 | */ | |
41 | ||
42 | #ifndef UTIL_DATA_PACKED_RRSET_H | |
43 | #define UTIL_DATA_PACKED_RRSET_H | |
44 | #include "util/storage/lruhash.h" | |
45 | struct alloc_cache; | |
46 | struct regional; | |
47 | ||
48 | /** type used to uniquely identify rrsets. Cannot be reused without | |
49 | * clearing the cache. */ | |
50 | typedef uint64_t rrset_id_t; | |
51 | ||
52 | /** this rrset is NSEC and is at zone apex (at child side of zonecut) */ | |
53 | #define PACKED_RRSET_NSEC_AT_APEX 0x1 | |
54 | /** this rrset is A/AAAA and is in-zone-glue (from parent side of zonecut) */ | |
55 | #define PACKED_RRSET_PARENT_SIDE 0x2 | |
56 | /** this rrset is SOA and has the negative ttl (from nxdomain or nodata), | |
57 | * this is set on SOA rrsets in the authority section, to keep its TTL separate | |
58 | * from the SOA in the answer section from a direct SOA query or ANY query. */ | |
59 | #define PACKED_RRSET_SOA_NEG 0x4 | |
60 | ||
61 | /** | |
62 | * The identifying information for an RRset. | |
63 | */ | |
64 | struct packed_rrset_key { | |
65 | /** | |
66 | * The domain name. If not null (for id=0) it is allocated, and | |
67 | * contains the wireformat domain name. | |
68 | * This dname is not canonicalized. | |
69 | */ | |
70 | uint8_t* dname; | |
71 | /** | |
72 | * Length of the domain name, including last 0 root octet. | |
73 | */ | |
74 | size_t dname_len; | |
75 | /** | |
76 | * Flags. 32bit to be easy for hashing: | |
77 | * o PACKED_RRSET_NSEC_AT_APEX | |
78 | * o PACKED_RRSET_PARENT_SIDE | |
79 | * o PACKED_RRSET_SOA_NEG | |
80 | */ | |
81 | uint32_t flags; | |
82 | /** the rrset type in network format */ | |
83 | uint16_t type; | |
84 | /** the rrset class in network format */ | |
85 | uint16_t rrset_class; | |
86 | }; | |
87 | ||
88 | /** | |
89 | * This structure contains an RRset. A set of resource records that | |
90 | * share the same domain name, type and class. | |
91 | * | |
92 | * Due to memory management and threading, the key structure cannot be | |
93 | * deleted, although the data can be. The id can be set to 0 to store and the | |
94 | * structure can be recycled with a new id. | |
95 | */ | |
96 | struct ub_packed_rrset_key { | |
97 | /** | |
98 | * entry into hashtable. Note the lock is never destroyed, | |
99 | * even when this key is retired to the cache. | |
100 | * the data pointer (if not null) points to a struct packed_rrset. | |
101 | */ | |
102 | struct lruhash_entry entry; | |
103 | /** | |
104 | * the ID of this rrset. unique, based on threadid + sequenceno. | |
105 | * ids are not reused, except after flushing the cache. | |
106 | * zero is an unused entry, and never a valid id. | |
107 | * Check this value after getting entry.lock. | |
108 | * The other values in this struct may only be altered after changing | |
109 | * the id (which needs a writelock on entry.lock). | |
110 | */ | |
111 | rrset_id_t id; | |
112 | /** key data: dname, type and class */ | |
113 | struct packed_rrset_key rk; | |
114 | }; | |
115 | ||
116 | /** | |
117 | * RRset trustworthiness. Bigger value is more trust. RFC 2181. | |
118 | * The rrset_trust_add_noAA, rrset_trust_auth_noAA, rrset_trust_add_AA, | |
119 | * are mentioned as the same trustworthiness in 2181, but split up here | |
120 | * for ease of processing. | |
121 | * | |
122 | * rrset_trust_nonauth_ans_AA, rrset_trust_ans_noAA | |
123 | * are also mentioned as the same trustworthiness in 2181, but split up here | |
124 | * for ease of processing. | |
125 | * | |
126 | * Added trust_none for a sane initial value, smaller than anything else. | |
127 | * Added validated and ultimate trust for keys and rrsig validated content. | |
128 | */ | |
129 | enum rrset_trust { | |
130 | /** initial value for trust */ | |
131 | rrset_trust_none = 0, | |
132 | /** Additional information from non-authoritative answers */ | |
133 | rrset_trust_add_noAA, | |
134 | /** Data from the authority section of a non-authoritative answer */ | |
135 | rrset_trust_auth_noAA, | |
136 | /** Additional information from an authoritative answer */ | |
137 | rrset_trust_add_AA, | |
138 | /** non-authoritative data from the answer section of authoritative | |
139 | * answers */ | |
140 | rrset_trust_nonauth_ans_AA, | |
141 | /** Data from the answer section of a non-authoritative answer */ | |
142 | rrset_trust_ans_noAA, | |
143 | /** Glue from a primary zone, or glue from a zone transfer */ | |
144 | rrset_trust_glue, | |
145 | /** Data from the authority section of an authoritative answer */ | |
146 | rrset_trust_auth_AA, | |
147 | /** The authoritative data included in the answer section of an | |
148 | * authoritative reply */ | |
149 | rrset_trust_ans_AA, | |
150 | /** Data from a zone transfer, other than glue */ | |
151 | rrset_trust_sec_noglue, | |
152 | /** Data from a primary zone file, other than glue data */ | |
153 | rrset_trust_prim_noglue, | |
154 | /** DNSSEC(rfc4034) validated with trusted keys */ | |
155 | rrset_trust_validated, | |
156 | /** ultimately trusted, no more trust is possible; | |
157 | * trusted keys from the unbound configuration setup. */ | |
158 | rrset_trust_ultimate | |
159 | }; | |
160 | ||
161 | /** | |
162 | * Security status from validation for data. | |
163 | * The order is significant; more secure, more proven later. | |
164 | */ | |
165 | enum sec_status { | |
166 | /** UNCHECKED means that object has yet to be validated. */ | |
167 | sec_status_unchecked = 0, | |
168 | /** BOGUS means that the object (RRset or message) failed to validate | |
169 | * (according to local policy), but should have validated. */ | |
170 | sec_status_bogus, | |
171 | /** INDETERMINATE means that the object is insecure, but not | |
172 | * authoritatively so. Generally this means that the RRset is not | |
173 | * below a configured trust anchor. */ | |
174 | sec_status_indeterminate, | |
175 | /** INSECURE means that the object is authoritatively known to be | |
176 | * insecure. Generally this means that this RRset is below a trust | |
177 | * anchor, but also below a verified, insecure delegation. */ | |
178 | sec_status_insecure, | |
179 | /** SECURE means that the object (RRset or message) validated | |
180 | * according to local policy. */ | |
181 | sec_status_secure | |
182 | }; | |
183 | ||
184 | /** | |
185 | * RRset data. | |
186 | * | |
187 | * The data is packed, stored contiguously in memory. | |
188 | * memory layout: | |
189 | * o base struct | |
190 | * o rr_len size_t array | |
191 | * o rr_data uint8_t* array | |
192 | * o rr_ttl time_t array (after size_t and ptrs because those may be | |
193 | * 64bit and this array before those would make them unaligned). | |
194 | * Since the stuff before is 32/64bit, rr_ttl is 32 bit aligned. | |
195 | * o rr_data rdata wireformats | |
196 | * o rrsig_data rdata wireformat(s) | |
197 | * | |
198 | * Rdata is stored in wireformat. The dname is stored in wireformat. | |
199 | * TTLs are stored as absolute values (and could be expired). | |
200 | * | |
201 | * RRSIGs are stored in the arrays after the regular rrs. | |
202 | * | |
203 | * You need the packed_rrset_key to know dname, type, class of the | |
204 | * resource records in this RRset. (if signed the rrsig gives the type too). | |
205 | * | |
206 | * On the wire an RR is: | |
207 | * name, type, class, ttl, rdlength, rdata. | |
208 | * So we need to send the following per RR: | |
209 | * key.dname, ttl, rr_data[i]. | |
210 | * since key.dname ends with type and class. | |
211 | * and rr_data starts with the rdlength. | |
212 | * the ttl value to send changes due to time. | |
213 | */ | |
214 | struct packed_rrset_data { | |
215 | /** TTL (in seconds like time()) of the rrset. | |
216 | * Same for all RRs see rfc2181(5.2). */ | |
217 | time_t ttl; | |
218 | /** number of rrs. */ | |
219 | size_t count; | |
220 | /** number of rrsigs, if 0 no rrsigs */ | |
221 | size_t rrsig_count; | |
222 | /** the trustworthiness of the rrset data */ | |
223 | enum rrset_trust trust; | |
224 | /** security status of the rrset data */ | |
225 | enum sec_status security; | |
226 | /** length of every rr's rdata, rr_len[i] is size of rr_data[i]. */ | |
227 | size_t* rr_len; | |
228 | /** ttl of every rr. rr_ttl[i] ttl of rr i. */ | |
229 | time_t *rr_ttl; | |
230 | /** | |
231 | * Array of pointers to every rr's rdata. | |
232 | * The rr_data[i] rdata is stored in uncompressed wireformat. | |
233 | * The first uint16_t of rr_data[i] is network format rdlength. | |
234 | * | |
235 | * rr_data[count] to rr_data[count+rrsig_count] contain the rrsig data. | |
236 | */ | |
237 | uint8_t** rr_data; | |
238 | }; | |
239 | ||
240 | /** | |
241 | * An RRset can be represented using both key and data together. | |
242 | * Split into key and data structures to simplify implementation of | |
243 | * caching schemes. | |
244 | */ | |
245 | struct packed_rrset { | |
246 | /** domain name, type and class */ | |
247 | struct packed_rrset_key* k; | |
248 | /** ttl, count and rdatas (and rrsig) */ | |
249 | struct packed_rrset_data* d; | |
250 | }; | |
251 | ||
252 | /** | |
253 | * list of packed rrsets | |
254 | */ | |
255 | struct packed_rrset_list { | |
256 | /** next in list */ | |
257 | struct packed_rrset_list* next; | |
258 | /** rrset key and data */ | |
259 | struct packed_rrset rrset; | |
260 | }; | |
261 | ||
262 | /** | |
263 | * Delete packed rrset key and data, not entered in hashtables yet. | |
264 | * Used during parsing. | |
265 | * @param pkey: rrset key structure with locks, key and data pointers. | |
266 | * @param alloc: where to return the unfree-able key structure. | |
267 | */ | |
268 | void ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey, | |
269 | struct alloc_cache* alloc); | |
270 | ||
271 | /** | |
272 | * Memory size of rrset data. RRset data must be filled in correctly. | |
273 | * @param data: data to examine. | |
274 | * @return size in bytes. | |
275 | */ | |
276 | size_t packed_rrset_sizeof(struct packed_rrset_data* data); | |
277 | ||
278 | /** | |
279 | * Get TTL of rrset. RRset data must be filled in correctly. | |
280 | * @param key: rrset key, with data to examine. | |
281 | * @return ttl value. | |
282 | */ | |
283 | time_t ub_packed_rrset_ttl(struct ub_packed_rrset_key* key); | |
284 | ||
285 | /** | |
286 | * Calculate memory size of rrset entry. For hash table usage. | |
287 | * @param key: struct ub_packed_rrset_key*. | |
288 | * @param data: struct packed_rrset_data*. | |
289 | * @return size in bytes. | |
290 | */ | |
291 | size_t ub_rrset_sizefunc(void* key, void* data); | |
292 | ||
293 | /** | |
294 | * compares two rrset keys. | |
295 | * @param k1: struct ub_packed_rrset_key*. | |
296 | * @param k2: struct ub_packed_rrset_key*. | |
297 | * @return 0 if equal. | |
298 | */ | |
299 | int ub_rrset_compare(void* k1, void* k2); | |
300 | ||
301 | /** | |
302 | * compare two rrset data structures. | |
303 | * Compared rdata and rrsigdata, not the trust or ttl value. | |
304 | * @param d1: data to compare. | |
305 | * @param d2: data to compare. | |
306 | * @return 1 if equal. | |
307 | */ | |
308 | int rrsetdata_equal(struct packed_rrset_data* d1, struct packed_rrset_data* d2); | |
309 | ||
310 | /** | |
311 | * Old key to be deleted. RRset keys are recycled via alloc. | |
312 | * The id is set to 0. So that other threads, after acquiring a lock always | |
313 | * get the correct value, in this case the 0 deleted-special value. | |
314 | * @param key: struct ub_packed_rrset_key*. | |
315 | * @param userdata: alloc structure to use for recycling. | |
316 | */ | |
317 | void ub_rrset_key_delete(void* key, void* userdata); | |
318 | ||
319 | /** | |
320 | * Old data to be deleted. | |
321 | * @param data: what to delete. | |
322 | * @param userdata: user data ptr. | |
323 | */ | |
324 | void rrset_data_delete(void* data, void* userdata); | |
325 | ||
326 | /** | |
327 | * Calculate hash value for a packed rrset key. | |
328 | * @param key: the rrset key with name, type, class, flags. | |
329 | * @return hash value. | |
330 | */ | |
331 | hashvalue_t rrset_key_hash(struct packed_rrset_key* key); | |
332 | ||
333 | /** | |
334 | * Fixup pointers in fixed data packed_rrset_data blob. | |
335 | * After a memcpy of the data for example. Will set internal pointers right. | |
336 | * @param data: rrset data structure. Otherwise correctly filled in. | |
337 | */ | |
338 | void packed_rrset_ptr_fixup(struct packed_rrset_data* data); | |
339 | ||
340 | /** | |
341 | * Fixup TTLs in fixed data packed_rrset_data blob. | |
342 | * @param data: rrset data structure. Otherwise correctly filled in. | |
343 | * @param add: how many seconds to add, pass time(0) for example. | |
344 | */ | |
345 | void packed_rrset_ttl_add(struct packed_rrset_data* data, time_t add); | |
346 | ||
347 | /** | |
348 | * Utility procedure to extract CNAME target name from its rdata. | |
349 | * Failsafes; it will change passed dname to a valid dname or do nothing. | |
350 | * @param rrset: the rrset structure. Must be a CNAME. | |
351 | * Only first RR is used (multiple RRs are technically illegal anyway). | |
352 | * Also works on type DNAME. Returns target name. | |
353 | * @param dname: this pointer is updated to point into the cname rdata. | |
354 | * If a failsafe fails, nothing happens to the pointer (such as the | |
355 | * rdata was not a valid dname, not a CNAME, ...). | |
356 | * @param dname_len: length of dname is returned. | |
357 | */ | |
358 | void get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname, | |
359 | size_t* dname_len); | |
360 | ||
361 | /** | |
362 | * Get a printable string for a rrset trust value | |
363 | * @param s: rrset trust value | |
364 | * @return printable string. | |
365 | */ | |
366 | const char* rrset_trust_to_string(enum rrset_trust s); | |
367 | ||
368 | /** | |
369 | * Get a printable string for a security status value | |
370 | * @param s: security status | |
371 | * @return printable string. | |
372 | */ | |
373 | const char* sec_status_to_string(enum sec_status s); | |
374 | ||
375 | /** | |
376 | * Print string with neat domain name, type, class from rrset. | |
377 | * @param v: at what verbosity level to print this. | |
378 | * @param str: string of message. | |
379 | * @param rrset: structure with name, type and class. | |
380 | */ | |
381 | void log_rrset_key(enum verbosity_value v, const char* str, | |
382 | struct ub_packed_rrset_key* rrset); | |
383 | ||
384 | /** | |
385 | * Convert RR from RRset to string. | |
386 | * @param rrset: structure with data. | |
387 | * @param i: index of rr or RRSIG. | |
388 | * @param now: time that is subtracted from ttl before printout. Can be 0. | |
389 | * @param dest: destination string buffer. Must be nonNULL. | |
390 | * @param dest_len: length of dest buffer (>0). | |
391 | * @return false on failure. | |
392 | */ | |
393 | int packed_rr_to_string(struct ub_packed_rrset_key* rrset, size_t i, | |
394 | time_t now, char* dest, size_t dest_len); | |
395 | ||
396 | /** | |
397 | * Print the string with prefix, one rr per line. | |
398 | * @param v: at what verbosity level to print this. | |
399 | * @param str: string of message. | |
400 | * @param rrset: with name, and rdata, and rrsigs. | |
401 | */ | |
402 | void log_packed_rrset(enum verbosity_value v, const char* str, | |
403 | struct ub_packed_rrset_key* rrset); | |
404 | ||
405 | /** | |
406 | * Allocate rrset in region - no more locks needed | |
407 | * @param key: a (just from rrset cache looked up) rrset key + valid, | |
408 | * packed data record. | |
409 | * @param region: where to alloc the copy | |
410 | * @param now: adjust the TTLs to be relative (subtract from all TTLs). | |
411 | * @return new region-alloced rrset key or NULL on alloc failure. | |
412 | */ | |
413 | struct ub_packed_rrset_key* packed_rrset_copy_region( | |
414 | struct ub_packed_rrset_key* key, struct regional* region, | |
415 | time_t now); | |
416 | ||
417 | /** | |
418 | * Allocate rrset with malloc (from region or you are holding the lock). | |
419 | * @param key: key with data entry. | |
420 | * @param alloc: alloc_cache to create rrset_keys | |
421 | * @param now: adjust the TTLs to be absolute (add to all TTLs). | |
422 | * @return new region-alloced rrset key or NULL on alloc failure. | |
423 | */ | |
424 | struct ub_packed_rrset_key* packed_rrset_copy_alloc( | |
425 | struct ub_packed_rrset_key* key, struct alloc_cache* alloc, | |
426 | time_t now); | |
427 | ||
428 | #endif /* UTIL_DATA_PACKED_RRSET_H */ |