1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup types The types used in the database
36 * @ingroup dnsdb
37 * @brief The types used in the database
38 *
39 * The types used in the database
40 *
41 * @{
42 */
43 #ifndef _ZDB_TYPES_H
44 #define _ZDB_TYPES_H
45
46 #include <dnscore/dnscore-config-features.h>
47 #include <dnsdb/zdb-config-features.h>
48
49 #if DNSCORE_HAVE_STDATOMIC_H
50 #include <stdatomic.h>
51 #else
52 #include <dnscore/thirdparty/stdatomic.h>
53 #endif
54
55 #include <dnscore/dnsname.h>
56 #include <dnscore/zalloc.h>
57 #include <dnscore/rfc.h>
58 #include <dnscore/message.h>
59 #include <dnscore/alarm.h>
60 #include <dnscore/mutex.h>
61 #include <dnscore/acl.h>
62
63 #include <dnsdb/zdb_config.h>
64 #include <dnsdb/dictionary.h>
65 //#include <dnsdb/journal.h>
66
67 #include <dnsdb/zdb_error.h>
68
69 #ifdef __cplusplus
70 extern "C"
71 {
72 #endif
73
74 struct journal;
75
76 #define ROOT_LABEL ((u8*)"")
77
78 #define ZDB_ZONE_LOCK_HAS_OWNER_ID 0 // debug
79
80 #if ZDB_ZONE_LOCK_HAS_OWNER_ID
81 #pragma message("***********************************************************")
82 #pragma message("***********************************************************")
83 #pragma message("ZDB_ZONE_LOCK_HAS_OWNER_ID 1")
84 #pragma message("***********************************************************")
85 #pragma message("***********************************************************")
86 #endif
87
88
89 /* zdb_ttlrdata
90 *
91 * This record is allocated in:
92 *
93 * zdb_zone_load
94 * zdb_add_global
95 *
96 *
97 */
98
99 typedef struct zdb_packed_ttlrdata zdb_packed_ttlrdata;
100
101 struct zdb_packed_ttlrdata
102 { /* DO NOT CHANGE THE ORDER OF THE FIELDS !!! */
103 zdb_packed_ttlrdata* next; /* 4 8 */
104 s32 ttl; /* 4 4 */
105 u16 rdata_size; /* 2 2 */
106 u8 rdata_start[1];
107 };
108
zdb_packed_ttlrdata_count(const zdb_packed_ttlrdata * rrset)109 static inline int zdb_packed_ttlrdata_count(const zdb_packed_ttlrdata *rrset)
110 {
111 int count = 0;
112
113 const zdb_packed_ttlrdata* p = rrset;
114
115 while(p != NULL)
116 {
117 ++count;
118 p = p->next;
119 }
120
121 return count;
122 }
123
124 // a zdb_packed_ttlrdata ready to store a valid SOA
125
126 struct zdb_packed_ttlrdata_soa
127 { /* DO NOT CHANGE THE ORDER OF THE FIELDS !!! */
128 zdb_packed_ttlrdata* next; /* 4 8 */
129 u32 ttl; /* 4 4 */
130 u16 rdata_size; /* 2 2 */
131 u8 rdata_start[MAX_SOA_RDATA_LENGTH];
132 };
133
134 #define ZDB_RDATABUF_TAG 0x4655424154414452
135 #define ZDB_RECORD_TAG 0x4443455242445a /** "ZDBRECD" */
136
137 #define ZDB_RECORD_SIZE_FROM_RDATASIZE(rdata_size_) (sizeof(zdb_packed_ttlrdata)-1+(rdata_size_))
138 #define ZDB_RECORD_SIZE(record_) ZDB_RECORD_SIZE_FROM_RDATASIZE((record_)->rdata_size)
139
140 #if !DNSCORE_HAS_ZALLOC_SUPPORT
141
142 #define ZDB_RECORD_ZALLOC(record,ttl_,len_,rdata_) \
143 { \
144 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record),sizeof(zdb_packed_ttlrdata)-1+len_,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
145 (record)->ttl=ttl_; \
146 (record)->rdata_size=len_; \
147 MEMCOPY(&(record)->rdata_start[0],rdata_,len_); \
148 }
149
150 #define ZDB_RECORD_ZALLOC_EMPTY(record,ttl_,len_) \
151 { \
152 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record),sizeof(zdb_packed_ttlrdata)-1+len_,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
153 (record)->ttl=ttl_; \
154 (record)->rdata_size=len_; \
155 }
156
157 #define ZDB_RECORD_CLONE(record_s_,record_d_) \
158 { \
159 u32 size=sizeof(zdb_packed_ttlrdata)-1+(record_s_)->rdata_size; \
160 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_d_),size,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
161 record_d_->ttl=record_s_->ttl; \
162 record_d_->rdata_size=record_s_->rdata_size; \
163 MEMCOPY(&(record_d_)->rdata_start[0],&(record_s_)->rdata_start[0],record_s_->rdata_size); \
164 }
165
166 #define ZDB_RECORD_ZFREE(record) free(record)
167
168 #define ZDB_RECORD_SAFE_ZFREE(record) free(record)
169
170 #else // DNSCORE_HAS_ZALLOC_SUPPORT
171
172 #if !(HAS_ZALLOC_DEBUG_SUPPORT && DNSCORE_DEBUG_HAS_BLOCK_TAG)
173
174 #define ZDB_RECORD_ZALLOC(record_,ttl_,len_,rdata_) \
175 { \
176 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE(len_); \
177 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
178 { \
179 record_=(zdb_packed_ttlrdata*)zalloc_line((size-1)>>3); \
180 } \
181 else \
182 { \
183 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_),sizeof(zdb_packed_ttlrdata)-1+len_,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
184 } \
185 \
186 (record_)->ttl=ttl_; \
187 (record_)->rdata_size=len_; \
188 MEMCOPY(&(record_)->rdata_start[0],rdata_,len_); \
189 }
190
191 #define ZDB_RECORD_ZALLOC_EMPTY(record_,ttl_,len_) \
192 { \
193 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE(len_); \
194 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
195 { \
196 record_=(zdb_packed_ttlrdata*)zalloc_line((size-1)>>3); \
197 } \
198 else \
199 { \
200 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_),sizeof(zdb_packed_ttlrdata)-1+len_,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
201 } \
202 \
203 (record_)->ttl=ttl_; \
204 (record_)->rdata_size=len_; \
205 }
206
207 #define ZDB_RECORD_CLONE(record_s_,record_d_) \
208 { \
209 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE((record_s_)->rdata_size);\
210 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
211 { \
212 record_d_=(zdb_packed_ttlrdata*)zalloc_line((size-1)>>3); \
213 } \
214 else \
215 { \
216 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_d_),size,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
217 } \
218 record_d_->ttl=record_s_->ttl; \
219 record_d_->rdata_size=record_s_->rdata_size; \
220 MEMCOPY(&(record_d_)->rdata_start[0],&(record_s_)->rdata_start[0],record_s_->rdata_size); \
221 }
222
223 #else // HAS_ZALLOC_DEBUG_SUPPORT && DNSCORE_DEBUG_HAS_BLOCK_TAG
224
225 #define ZDB_RECORD_ZALLOC(record_,ttl_,len_,rdata_) \
226 { \
227 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE(len_); \
228 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
229 { \
230 record_=(zdb_packed_ttlrdata*)zalloc_line((size-1)>>3,ZDB_RECORD_TAG); \
231 } \
232 else \
233 { \
234 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_),sizeof(zdb_packed_ttlrdata)-1+len_,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
235 } \
236 \
237 (record_)->ttl=ttl_; \
238 (record_)->rdata_size=len_; \
239 MEMCOPY(&(record_)->rdata_start[0],rdata_,len_); \
240 }
241
242 #define ZDB_RECORD_ZALLOC_EMPTY(record_,ttl_,len_) \
243 { \
244 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE(len_); \
245 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
246 { \
247 record_=(zdb_packed_ttlrdata*)zalloc_line((size-1)>>3,ZDB_RECORD_TAG); \
248 } \
249 else \
250 { \
251 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_),sizeof(zdb_packed_ttlrdata)-1+len_,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
252 } \
253 \
254 (record_)->ttl=ttl_; \
255 (record_)->rdata_size=len_; \
256 }
257
258 #define ZDB_RECORD_CLONE(record_s_,record_d_) \
259 { \
260 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE((record_s_)->rdata_size);\
261 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
262 { \
263 record_d_=(zdb_packed_ttlrdata*)zalloc_line((size-1)>>3,ZDB_RECORD_TAG); \
264 } \
265 else \
266 { \
267 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_d_),size,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
268 } \
269 record_d_->ttl=record_s_->ttl; \
270 record_d_->rdata_size=record_s_->rdata_size; \
271 MEMCOPY(&(record_d_)->rdata_start[0],&(record_s_)->rdata_start[0],record_s_->rdata_size); \
272 }
273
274 #endif // HAS_ZALLOC_DEBUG_SUPPORT && DNSCORE_DEBUG_HAS_BLOCK_TAG
275
276 /* DOES NOT CHECKS FOR NULL */
277 #define ZDB_RECORD_ZFREE(record_) \
278 { \
279 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE((record_)->rdata_size); \
280 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
281 { \
282 zfree_line(record_,(size-1)>>3); \
283 } \
284 else \
285 { \
286 free(record_); \
287 } \
288 }
289
290 /* DOES CHECKS FOR NULL */
291 #define ZDB_RECORD_SAFE_ZFREE(record_) \
292 if(record_ != NULL) \
293 { \
294 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE((record_)->rdata_size); \
295 if(size<=ZALLOC_PG_PAGEABLE_MAXSIZE) \
296 { \
297 zfree_line(record_,(size-1)>>3); \
298 } \
299 else \
300 { \
301 free(record_); \
302 } \
303 }
304
305 #endif // DNSCORE_HAS_ZALLOC_SUPPORT
306
307 #define ZDB_RECORD_MALLOC_EMPTY(record_,ttl_,rdata_size_) \
308 { \
309 u32 size=ZDB_RECORD_SIZE_FROM_RDATASIZE(rdata_size_); \
310 MALLOC_OR_DIE(zdb_packed_ttlrdata*,(record_),size,ZDB_RECORD_TAG); /* ZALLOC IMPOSSIBLE */ \
311 (record_)->ttl=ttl_; \
312 (record_)->rdata_size=rdata_size_; \
313 }
314
315 /*
316 * These macros existed when 2 different ways for storing the record were
317 * available at compile time.
318 *
319 * The zdb_packed_ttlrdata having proved to be the best (by far),
320 * the other one has been removed.
321 *
322 */
323
324 #define ZDB_PACKEDRECORD_PTR_RDATAPTR(record_) (&(record_)->rdata_start[0])
325 #define ZDB_PACKEDRECORD_PTR_RDATASIZE(record_) ((record_)->rdata_size)
326
zdb_packed_ttlrdata_compare_records(const zdb_packed_ttlrdata * rr0,const zdb_packed_ttlrdata * rr1)327 static inline int zdb_packed_ttlrdata_compare_records(const zdb_packed_ttlrdata *rr0, const zdb_packed_ttlrdata *rr1)
328 {
329 int s0 = ZDB_PACKEDRECORD_PTR_RDATASIZE(rr0);
330 int s1 = ZDB_PACKEDRECORD_PTR_RDATASIZE(rr1);
331 int s = MIN(s0, s1);
332 int d;
333
334 if(s > 0)
335 {
336 d = memcmp(ZDB_PACKEDRECORD_PTR_RDATAPTR(rr0), ZDB_PACKEDRECORD_PTR_RDATAPTR(rr1), s);
337 if(d == 0)
338 {
339 d = s0 - s1;
340
341 if(d == 0)
342 {
343 d = rr0->ttl - rr1->ttl;
344 }
345 }
346 }
347 else
348 {
349 d = s0 - s1;
350
351 if(d == 0)
352 {
353 d = rr0->ttl - rr1->ttl;
354 }
355 }
356
357 return d;
358 }
359
360
361 #define ZDB_RECORD_PTR_RDATASIZE(record_) ((record_)->rdata_size)
362 #define ZDB_RECORD_PTR_RDATAPTR(record_) ((record_)->rdata_pointer)
363
364 typedef struct zdb_ttlrdata zdb_ttlrdata;
365
366 struct zdb_ttlrdata
367 {
368 zdb_ttlrdata* next; /* 4 8 */
369 u32 ttl; /* 4 4 */
370 u16 rdata_size; /* 2 2 */
371 u16 padding_reserved;
372 void* rdata_pointer; /* 4 8 */
373 };
374
375 #define ZDB_PACKEDRECORD_RDATADESC(type_,ttlrdata_) { (type_), ZDB_PACKEDRECORD_PTR_RDATASIZE(ttlrdata_), ZDB_PACKEDRECORD_PTR_RDATAPTR(ttlrdata_)}
376 #define ZDB_RECORD_RDATADESC(type_,ttlrdata_) { (type_), ZDB_RECORD_PTR_RDATASIZE(ttlrdata_), ZDB_RECORD_PTR_RDATAPTR(ttlrdata_)}
377
378 #define TTLRDATA_INLINESIZE THIS_SHOULD_NOT_BE_USED_IN_PACKED_MODE
379
380 #define ZDB_RECORD_TTLRDATA_SET(record,ttl_,len_,rdata_) \
381 { \
382 (record).ttl=ttl_; \
383 (record).rdata_size=len_; \
384 (record).rdata_pointer=rdata_; \
385 }
386
387 typedef btree zdb_rr_collection;
388
389 #define ZDB_RESOURCERECORD_TAG 0x444345524c4c5546 /** "FULLRECD" */
390
391 /* zdb_zone */
392
393 typedef struct zdb_zone zdb_zone;
394
395 #define LABEL_HAS_RECORDS(label_) ((label_)->resource_record_set != NULL)
396
397 typedef struct zdb_resourcerecord zdb_resourcerecord;
398
399 struct zdb_resourcerecord
400 {
401 zdb_resourcerecord* next; /* 4 8 */
402 zdb_packed_ttlrdata* ttl_rdata; /* 4 8 */
403 const u8* name; /* 4 8 */
404 u16 zclass; /* 2 2 */
405 u16 rtype; /* 2 2 */
406 u32 ttl;
407 }; /* 16 28 => 16 32 */
408
409 /* zdb_rr_label */
410
411 typedef dictionary zdb_rr_label_set;
412
413 typedef struct zdb_rr_label zdb_rr_label;
414
415 #if ZDB_HAS_DNSSEC_SUPPORT
416
417 #if ZDB_HAS_NSEC_SUPPORT
418
419 typedef struct nsec_label_extension nsec_label;
420 typedef struct nsec_label_extension nsec_label_extension;
421 typedef struct nsec_node nsec_zone;
422
423 #endif
424
425 #if ZDB_HAS_NSEC3_SUPPORT
426
427 typedef struct nsec3_zone nsec3_zone;
428
429 #endif
430
431 typedef struct dnssec_zone_extension dnssec_zone_extension;
432
433 struct dnssec_zone_extension
434 {
435 #if ZDB_HAS_NSEC_SUPPORT
436 /*
437 * A pointer to an array of nsec_label (nsec_label buffer[])
438 * The size is the same as the dictionnary
439 */
440 nsec_zone* nsec;
441 #endif
442
443 #if ZDB_HAS_NSEC3_SUPPORT
444 nsec3_zone* nsec3;
445 #endif
446 };
447
448 typedef union nsec_label_union nsec_label_union;
449
450 struct nsec_label_extension
451 {
452 struct nsec_node* node;
453 };
454
455 union nsec_label_union
456 {
457 /* NSEC */
458 #if ZDB_HAS_NSEC_SUPPORT
459 nsec_label_extension nsec;
460 #endif
461
462 /* NSEC3 */
463 #if ZDB_HAS_NSEC3_SUPPORT
464 struct nsec3_label_extension* nsec3;
465 #endif
466
467 /* Placeholder */
468 void* dnssec;
469 };
470
471 #endif
472
473 /*
474 * RR_LABEL flags
475 */
476
477 /*
478 * For the apex, marks a label as being the apex
479 */
480
481 #define ZDB_RR_LABEL_APEX 0x0001
482
483 /*
484 * For any label but the apex : marks it as being a delegation (contains an NS record)
485 */
486
487 #define ZDB_RR_LABEL_DELEGATION 0x0002
488
489 /*
490 * For any label, means there is a delegation (somewhere) above
491 */
492
493 #define ZDB_RR_LABEL_UNDERDELEGATION 0x0004
494
495 /*
496 * For any label : marks that one owns a '*' label
497 */
498
499 #define ZDB_RR_LABEL_GOT_WILD 0x0008
500
501 /*
502 * Explicitly mark a label as owner of a (single) CNAME
503 */
504
505 #define ZDB_RR_LABEL_HASCNAME 0x0010
506
507 /*
508 * Explicitly mark a label as owner of a something that is not a CNAME nor RRSIG nor NSEC
509 */
510
511 #define ZDB_RR_LABEL_DROPCNAME 0x0020
512
513 #define ZDB_RR_LABEL_N3COVERED 0x0040 // expected coverage
514 #define ZDB_RR_LABEL_N3OCOVERED 0x0080 // expected coverage
515
516
517 #if ZDB_HAS_DNSSEC_SUPPORT
518 /*
519 * This flag means that the label has a valid NSEC structure
520 *
521 * IT IS NOT VALID TO CHECK THIS TO SEE IF A ZONE IS NSEC
522 */
523 #define ZDB_RR_LABEL_NSEC 0x0100
524
525 /*
526 * This flag means that the label has a valid NSEC3 structure
527 *
528 * IT IS NOT VALID TO CHECK THIS TO SEE IF A ZONE IS NSEC3
529 */
530 #define ZDB_RR_LABEL_NSEC3 0x0200 // structure
531
532 /*
533 * The zone is (NSEC3) + OPTOUT (NSEC3 should also be set)
534 *
535 * IT IS NOT VALID TO CHECK THIS TO SEE IF A ZONE IS NSEC3
536 */
537
538 #define ZDB_RR_LABEL_NSEC3_OPTOUT 0x0400 // structure
539
540 #define ZDB_RR_LABEL_DNSSEC_MASK 0x0700
541 #define ZDB_RR_LABEL_DNSSEC_SHIFT 8
542
543 /*
544 * Marks a label so it cannot be deleted.
545 * Used for incremental changes when it is known that an empty terminal will have records added.
546 * (Avoiding to delete then re-create several structures)
547 */
548 #define ZDB_RR_LABEL_KEEP 0x0800
549
550 #endif
551
552 #define ZDB_RR_LABEL_HAS_NS 0x1000 // quick check of the presence of an NS record
553 #define ZDB_RR_LABEL_HAS_DS 0x2000 // quick check of the presence of an DS record
554
555 #define ZDB_LABEL_UNDERDELEGATION(__l__) ((((__l__)->_flags)&ZDB_RR_LABEL_UNDERDELEGATION)!=0)
556 #define ZDB_LABEL_ATDELEGATION(__l__) ((((__l__)->_flags)&ZDB_RR_LABEL_DELEGATION)!=0)
557 #define ZDB_LABEL_ATORUNDERDELEGATION(__l__) ((((__l__)->_flags)&(ZDB_RR_LABEL_DELEGATION|ZDB_RR_LABEL_UNDERDELEGATION))!=0)
558
559 struct zdb_rr_label
560 {
561 zdb_rr_label* next; /* dictionnary_node* next */ /* 4 8 */
562 zdb_rr_label_set sub; /* dictionnary of N children labels */ /* 16 24 */
563
564 zdb_rr_collection resource_record_set; /* resource records for the ²label (a btree)*/ /* 4 4 */
565
566 #if ZDB_HAS_DNSSEC_SUPPORT
567 nsec_label_union nsec;
568 #endif
569
570 u16 _flags; /* NSEC, NSEC3, and 6 for future usage ... */
571
572 u8 name[1]; /* label */ /* 4 8 */
573 /* No zone ptr */
574 }; /* 28 44 => 32 48 */
575
zdb_rr_label_flag_or(zdb_rr_label * rr_label,u16 or_mask)576 static inline void zdb_rr_label_flag_or(zdb_rr_label *rr_label, u16 or_mask)
577 {
578
579 rr_label->_flags |= or_mask;
580 }
581
zdb_rr_label_flag_and(zdb_rr_label * rr_label,u16 and_mask)582 static inline void zdb_rr_label_flag_and(zdb_rr_label *rr_label, u16 and_mask)
583 {
584
585 rr_label->_flags &= and_mask;
586 }
587
zdb_rr_label_flag_or_and(zdb_rr_label * rr_label,u16 or_mask,u16 and_mask)588 static inline void zdb_rr_label_flag_or_and(zdb_rr_label *rr_label, u16 or_mask, u16 and_mask)
589 {
590
591 rr_label->_flags = (rr_label->_flags |or_mask) & and_mask;
592 }
593
zdb_rr_label_flag_isset(const zdb_rr_label * rr_label,u16 and_mask)594 static inline bool zdb_rr_label_flag_isset(const zdb_rr_label *rr_label, u16 and_mask)
595 {
596 return (rr_label->_flags & and_mask) != 0;
597 }
598
zdb_rr_label_flag_matches(const zdb_rr_label * rr_label,u16 and_mask)599 static inline bool zdb_rr_label_flag_matches(const zdb_rr_label *rr_label, u16 and_mask)
600 {
601 return (rr_label->_flags & and_mask) == and_mask;
602 }
603
604
zdb_rr_label_flag_isclear(const zdb_rr_label * rr_label,u16 and_mask)605 static inline bool zdb_rr_label_flag_isclear(const zdb_rr_label *rr_label, u16 and_mask)
606 {
607 return (rr_label->_flags & and_mask) == 0;
608 }
609
zdb_rr_label_flag_get(const zdb_rr_label * rr_label)610 static inline u16 zdb_rr_label_flag_get(const zdb_rr_label *rr_label)
611 {
612 return rr_label->_flags;
613 }
614
zdb_rr_label_is_apex(const zdb_rr_label * rr_label)615 static inline bool zdb_rr_label_is_apex(const zdb_rr_label *rr_label)
616 {
617 return zdb_rr_label_flag_isset(rr_label, ZDB_RR_LABEL_APEX);
618 }
619
zdb_rr_label_is_not_apex(const zdb_rr_label * rr_label)620 static inline bool zdb_rr_label_is_not_apex(const zdb_rr_label *rr_label)
621 {
622 return zdb_rr_label_flag_isclear(rr_label, ZDB_RR_LABEL_APEX);
623 }
624
625 #define ZDB_ZONE_MUTEX_EXCLUSIVE_FLAG 0x80
626 #define ZDB_ZONE_MUTEX_LOCKMASK_FLAG 0x7f
627
628 #define ZDB_ZONE_MUTEX_UNLOCKMASK_FLAG 0x7f
629
630 #define ZDB_ZONE_MUTEX_NOBODY GROUP_MUTEX_NOBODY
631 #define ZDB_ZONE_MUTEX_SIMPLEREADER 0x01 /* non-conflicting */
632 #define ZDB_ZONE_MUTEX_RRSIG_UPDATER 0x82 /* conflicting */
633 #define ZDB_ZONE_MUTEX_XFR 0x84 /* conflicting, cannot by nature be launched more than once in parallel. new ones have to be discarded */
634 #define ZDB_ZONE_MUTEX_REFRESH 0x85 /* conflicting, can never be launched more than once. new ones have to be discarded */
635 #define ZDB_ZONE_MUTEX_DYNUPDATE 0x86 /* conflicting */
636 #define ZDB_ZONE_MUTEX_UNFREEZE 0x87 /* conflicting, needs to be sure nobody else (ie: the freeze) is acting at the same time */
637 #define ZDB_ZONE_MUTEX_INVALIDATE 0x88 /* conflicting */
638 #define ZDB_ZONE_MUTEX_REPLACE 0x89 /* conflicting */
639 #define ZDB_ZONE_MUTEX_LOAD 0x8a /* conflicting but this case is impossible */
640 #define ZDB_ZONE_MUTEX_NSEC3 0x8b /* conflicting, marks an hard operation to be done */
641 #define ZDB_ZONE_MUTEX_DESTROY 0xff /* conflicting, can never be launched more than once. The zone will be destroyed before unlock. */
642
643 typedef ya_result zdb_zone_access_filter(const message_data* /*mesg*/, const void* /*zone_extension*/);
644
645 #define ALARM_KEY_ZONE_SIGNATURE_UPDATE 1
646 #define ALARM_KEY_ZONE_AXFR_QUERY 2
647 #define ALARM_KEY_ZONE_REFRESH 3
648
649 #define ALARM_KEY_ZONE_DNSKEY_PUBLISH 4
650 #define ALARM_KEY_ZONE_DNSKEY_UNPUBLISH 5
651 #define ALARM_KEY_ZONE_DNSKEY_ACTIVATE 6
652 #define ALARM_KEY_ZONE_DNSKEY_DEACTIVATE 7
653
654 #define ALARM_KEY_ZONE_NOTIFY_SLAVES 8
655
656 #define ZDB_ZONE_KEEP_RAW_SIZE 1
657
658 #define ZDB_ZONE_STATUS_NEED_REFRESH 1
659 #define ZDB_ZONE_STATUS_DUMPING_AXFR 2
660 #define ZDB_ZONE_STATUS_WILL_NOTIFY 4 // in the queue
661 #define ZDB_ZONE_STATUS_MODIFIED 8 // content has been changed since last time (typically, a replay has been done)
662 #define ZDB_ZONE_STATUS_WILL_NOTIFY_AGAIN 16
663 #define ZDB_ZONE_STATUS_SAVE_CLEAR_JOURNAL_AFTER_MOUNT 32 // if a corrupted chain has been
664
665 #define ZDB_ZONE_ERROR_STATUS_DIFF_FAILEDNOUSABLE_KEYS 1
666
667 /*
668 * The zone has expired or is a stub (while the real zone is being loaded)
669 */
670
671 #define ZDB_ZONE_STATUS_INVALID 64
672
673 /*
674 * Forbid updates of the zone
675 */
676 #define ZDB_ZONE_STATUS_FROZEN 128
677
678 #define ZDB_ZONE_STATUS_IN_DYNUPDATE_DIFF 256
679
680
681 //#define ZDB_ZONE_STATUS_KEEP_TEXT_UNUSED 16 // when storing an image, always keep it as text (slower, bigger)
682
683 #define ZDB_ZONE_HAS_OPTOUT_COVERAGE 1 // assumed true, until something else is found
684 #define ZDB_ZONE_MAINTAIN_NOSEC 0
685 #define ZDB_ZONE_MAINTAIN_NSEC 2
686 #define ZDB_ZONE_MAINTAIN_NSEC3 4
687 #define ZDB_ZONE_MAINTAIN_NSEC3_OPTOUT 5
688 #define ZDB_ZONE_MAINTAIN_MASK 7
689 #define ZDB_ZONE_RRSIG_PUSH_ALLOWED 8 // feature requested internally
690
691 #define ZDB_ZONE_MAINTENANCE_ON_MOUNT 16 // means the sanity decided the zone should probably be maintained ASAP
692 #define ZDB_ZONE_MAINTAIN_QUEUED 32
693 #define ZDB_ZONE_MAINTAINED 64
694 #define ZDB_ZONE_MAINTENANCE_PAUSED 128
695
696
697
698
699
700 struct dnskey_keyring;
701 /*
702 #define UNSIGNED_TYPE_VALUE_MAX(__type__) ((__type__)~0)
703 #define SIGNED_TYPE_VALUE_MAX(__type__) (((__type__)~0)>>1)
704 #define SIGNED_TYPE_VALUE_MIN(__type__) (((__type__)~0) - (((__type__)~0)>>1))
705
706 #define UNSIGNED_VAR_VALUE_MAX(__var__) ((~0ULL)>>((sizeof(~0ULL) - sizeof(__var__)) * 8LL))
707 #define SIGNED_VAR_VALUE_MAX(__var__) (UNSIGNED_VAR_VALUE_MAX(__var__)>>1)
708 #define SIGNED_VAR_VALUE_MIN(__var__) (UNSIGNED_VAR_VALUE_MAX(__var__) - SIGNED_VAR_VALUE_MAX(__var__))
709
710 #define UNSIGNED_VAR_VALUE_IS_MAX(__var__) (__var__ == UNSIGNED_VAR_VALUE_MAX(__var__))
711 #define SIGNED_VAR_VALUE_IS_MAX(__var__) (__var__ == SIGNED_VAR_VALUE_MAX(__var__))
712 */
713 #define ZDB_ZONE_HAS_JNL_REFERENCE 0
714
715 struct zdb_zone_update_signatures_ctx
716 {
717 u8 *current_fqdn;
718 s32 earliest_signature_expiration;
719 u16 labels_at_once;
720 s8 chain_index;
721 };
722
723 typedef struct zdb_zone_update_signatures_ctx zdb_zone_update_signatures_ctx;
724
725 struct zdb;
726 struct zdb_zone;
727
728 typedef ya_result zdb_zone_resolve(struct zdb_zone *zone, message_data *data, struct zdb *db);
729
730 /**
731 * A zone can be loaded from disk
732 * A zone can be stored to disk
733 * A zone image can be downloaded from a master
734 *
735 * A masters loads an image from a text oh hierarchical image.
736 * If the hierarchical image is allowed as a source (meaning no text image anymore), no AXFR image should ever be stored.
737 * If only the text image is allowed, then the AXFR image should be stored as hierarchical.
738 *
739 * A slave downloads an AXFR image, then incremental changes, and stores the image on disk when the journal requests it.
740 * This last storage step can be done as an AXFR image, a hierarchical image, or even a text image (but that one should not exist on a slave).
741 * It means the only time an AXFR image should (partially) exist on the disk from the time its being downloaded from a master to the time
742 * it's stored again in a (better) form.
743 *
744 */
745
746 struct zdb_zone
747 {
748 u8 *origin; /* dnsname, origin */
749 zdb_rr_label *apex; /* pointer to the zone cut, 1 name for : SOA, NS, ... */
750
751 #if ZDB_HAS_DNSSEC_SUPPORT
752 dnssec_zone_extension nsec;
753 #endif
754
755 zdb_zone_access_filter* query_access_filter;
756 access_control *acl; /**
757 * This pointer is meant to be used by the server so it can associate data with the zone
758 * without having to do the match on its side too.
759 *
760 */
761
762 #if ZDB_HAS_DNSSEC_SUPPORT
763 zdb_zone_update_signatures_ctx progressive_signature_update;
764 #endif
765
766 s32 min_ttl; /* a copy of the min-ttl from the SOA */
767
768 /*
769 * AXFR handling.
770 *
771 * In order to be nicer with the resources of the machine and more reactive we are adding a pace mechanism.
772 * MASTER:
773 * init: ts=1, serial = real serial - 1
774 * axfr(1): ts=0, serial = real serial, writing on disk, streaming to client until axfr_timestamp>1 OR axfr_serial has changed
775 * (both meaning the file has fully been written on disk)
776 * axfr(2): ts=0, serial = real serial, reading from the file being written
777 * axfr(3): ts=T, serial = real serial, reading from the written file
778 * axfr(4): now - ts > too_much, do axfr(1)
779 * SLAVE:
780 * : ts=last time the axfr has been fully done, serial = serial in the axfr on file
781 *
782 */
783
784 volatile u32 axfr_timestamp; // The last time when an AXFR has ENDED to be written on disk, if 0, an AXFR is being written right now
785 volatile u32 axfr_serial; // The serial number of the AXFR (being written) on disk
786 volatile u32 text_serial; // The serial number of the TEXT on disk
787 #if ZDB_HAS_DNSSEC_SUPPORT
788 s32 sig_validity_interval_seconds;
789 s32 sig_validity_regeneration_seconds;
790 s32 sig_validity_jitter_seconds;
791 u32 sig_quota; // starts at 100, updated so a batch does not takes more than a fraction of a second
792 #endif
793
794 alarm_t alarm_handle; // 32 bits
795 volatile s32 rc; // reference counter when it reaches 0, the zone and its content should be destroyed asap
796 volatile s32 lock_count; // the number of owners with the current lock ID
797 volatile u8 lock_owner; // the ID of who can manipulate the zone
798 volatile u8 lock_reserved_owner; // to the next-owner mechanism (reserve an ownership change)
799
800 volatile u8 _flags; // extended flags (optout coverage)
801 volatile u8 _error_status; // various error status used to avoid repetition
802 volatile atomic_uint_fast32_t _status; // extended status flags for background tasks not part of the normal operations
803 #if ZDB_RECORDS_MAX_CLASS
804 u16 zclass;
805 #endif
806
807 mutex_t lock_mutex;
808 cond_t lock_cond;
809 #if ZDB_ZONE_LOCK_HAS_OWNER_ID
810 thread_t lock_last_owner_id;
811 thread_t lock_last_reserved_owner_id;
812 #endif
813
814 #if DNSCORE_HAS_MUTEX_DEBUG_SUPPORT
815 stacktrace lock_trace;
816 thread_t lock_id;
817 s64 lock_timestamp;
818 #endif
819
820 #if ZDB_ZONE_KEEP_RAW_SIZE
821 volatile s64 wire_size; // approximation of the size of a zone. updated on load and store of the zone on disk
822 volatile u64 write_time_elapsed; // the time that was spent writing the zone in a file (ie: axfr)
823 #endif
824
825 #if ZDB_ZONE_HAS_JNL_REFERENCE
826 /** journal is only to be accessed trough the journal_* functions */
827 struct journal *_journal;
828 #endif
829
830 dnsname_vector origin_vector; // note: the origin vector is truncated to it's used length (sparing quite a lot of memory)
831
832 }; /* 18 34 => 20 40 */
833
834 /* zdb_zone_label */
835
836 typedef dictionary zdb_zone_label_set;
837
838 typedef struct zdb_zone_label zdb_zone_label;
839
840 struct zdb_zone_label
841 {
842 zdb_zone_label* next; /* used to link labels with the same hash into a SLL */
843 zdb_zone_label_set sub; /* labels of the sub-level */
844 u8* name; /* label name */
845
846 zdb_zone *zone; /* zone cut starting at this level */
847 }; /* 32 56 */
848
849 typedef zdb_zone_label* zdb_zone_label_pointer_array[DNSNAME_MAX_SECTIONS];
850
851 /* zdb */
852
853 #define ZDB_MUTEX_NOBODY GROUP_MUTEX_NOBODY
854 #define ZDB_MUTEX_READER 0x01
855 #define ZDB_MUTEX_WRITER 0x82 // only one allowed at once
856 typedef struct zdb zdb;
857
858 #define ZDBCLASS_TAG 0x5353414c4342445a
859
860 struct zdb
861 {
862 zdb_zone_label* root;
863 alarm_t alarm_handle;
864 group_mutex_t mutex;
865 u16 zclass;
866 };
867
868 typedef zdb_ttlrdata** zdb_ttlrdata_pointer_array;
869
870 /*
871 *
872 */
873
874 typedef struct zdb_query_ex_answer zdb_query_ex_answer;
875
876 struct zdb_query_ex_answer
877 {
878 zdb_resourcerecord *answer;
879 zdb_resourcerecord *authority;
880 zdb_resourcerecord *additional;
881 u8 depth; // CNAME
882 u8 delegation; // set as an integer to avoid testing for it
883 };
884
885 /**
886 * Iterator through the (rr) labels in a zone
887 */
888
889 typedef struct zdb_zone_label_iterator zdb_zone_label_iterator;
890
891 #define ZDB_ZONE_LABEL_ITERATOR_CAN_SKIP_CHILDREN 0
892
893 struct zdb_zone_label_iterator /// 47136 bytes on a 64 bits architecture
894 {
895 const zdb_zone* zone;
896 zdb_rr_label* current_label;
897 s32 top;
898 s32 current_top; /* "top" of the label pointer by current_label */
899 #if ZDB_ZONE_LABEL_ITERATOR_CAN_SKIP_CHILDREN
900 s32 prev_top; /* "top" of the label returned with "_next" */
901 s32 __reserved__;
902 #endif
903 dnslabel_stack dnslabels;
904 dictionary_iterator stack[DNSNAME_MAX_SECTIONS];
905 };
906
907 #define RRL_PROCEED 0
908 #define RRL_SLIP 1
909 #define RRL_DROP 2
910
911 typedef ya_result rrl_process_callback(message_data *mesg, zdb_query_ex_answer *ans_auth_add);
912
913 u32 zdb_zone_get_status(zdb_zone *zone);
914 u32 zdb_zone_set_status(zdb_zone *zone, u32 status);
915 u32 zdb_zone_clear_status(zdb_zone *zone, u32 status);
916
917 bool zdb_zone_error_status_getnot_set(zdb_zone *zone, u8 error_status);
918 void zdb_zone_error_status_clear(zdb_zone *zone, u8 error_status);
919
920 /*
921 u8 zdb_zone_get_flags(zdb_zone *zone);
922 u8 zdb_zone_set_flags(zdb_zone *zone, u8 flags);
923 u8 zdb_zone_clear_flags(zdb_zone *zone, u8 flags);
924 */
zdb_zone_invalid(zdb_zone * zone)925 static inline bool zdb_zone_invalid(zdb_zone *zone)
926 {
927 return (zdb_zone_get_status(zone) & ZDB_ZONE_STATUS_INVALID) != 0;
928 }
929
zdb_zone_valid(zdb_zone * zone)930 static inline bool zdb_zone_valid(zdb_zone *zone)
931 {
932 return (zdb_zone_get_status(zone) & ZDB_ZONE_STATUS_INVALID) == 0;
933 }
934
zdb_zone_set_dumping_axfr(zdb_zone * zone)935 static inline void zdb_zone_set_dumping_axfr(zdb_zone *zone)
936 {
937 zdb_zone_set_status(zone, ZDB_ZONE_STATUS_DUMPING_AXFR);
938 }
939
zdb_zone_get_set_dumping_axfr(zdb_zone * zone)940 static inline bool zdb_zone_get_set_dumping_axfr(zdb_zone *zone)
941 {
942 u8 status = zdb_zone_set_status(zone, ZDB_ZONE_STATUS_DUMPING_AXFR);
943 return (status & ZDB_ZONE_STATUS_DUMPING_AXFR) != 0;
944 }
945
zdb_zone_clear_dumping_axfr(zdb_zone * zone)946 static inline void zdb_zone_clear_dumping_axfr(zdb_zone *zone)
947 {
948 zdb_zone_clear_status(zone, ZDB_ZONE_STATUS_DUMPING_AXFR);
949 }
950
zdb_zone_is_dumping_axfr(zdb_zone * zone)951 static inline bool zdb_zone_is_dumping_axfr(zdb_zone *zone)
952 {
953 return (zdb_zone_get_status(zone) & ZDB_ZONE_STATUS_DUMPING_AXFR) != 0;
954 }
955
zdb_zone_set_store_clear_journal_after_mount(zdb_zone * zone)956 static inline void zdb_zone_set_store_clear_journal_after_mount(zdb_zone *zone)
957 {
958 zdb_zone_set_status(zone, ZDB_ZONE_STATUS_SAVE_CLEAR_JOURNAL_AFTER_MOUNT);
959 }
960
zdb_zone_clear_store_clear_journal_after_mount(zdb_zone * zone)961 static inline void zdb_zone_clear_store_clear_journal_after_mount(zdb_zone *zone)
962 {
963 zdb_zone_clear_status(zone, ZDB_ZONE_STATUS_SAVE_CLEAR_JOURNAL_AFTER_MOUNT);
964 }
965
zdb_zone_is_store_clear_journal_after_mount(zdb_zone * zone)966 static inline bool zdb_zone_is_store_clear_journal_after_mount(zdb_zone *zone)
967 {
968 return (zdb_zone_get_status(zone) & ZDB_ZONE_STATUS_SAVE_CLEAR_JOURNAL_AFTER_MOUNT) != 0;
969 }
970
zdb_zone_set_invalid(zdb_zone * zone)971 static inline void zdb_zone_set_invalid(zdb_zone *zone)
972 {
973 zdb_zone_set_status(zone, ZDB_ZONE_STATUS_INVALID);
974 }
975
zdb_zone_clear_invalid(zdb_zone * zone)976 static inline void zdb_zone_clear_invalid(zdb_zone *zone)
977 {
978 zdb_zone_clear_status(zone, ZDB_ZONE_STATUS_INVALID);
979 }
980
zdb_zone_is_invalid(zdb_zone * zone)981 static inline bool zdb_zone_is_invalid(zdb_zone *zone)
982 {
983 return (zdb_zone_get_status(zone) & ZDB_ZONE_STATUS_INVALID) != 0;
984 }
985
zdb_zone_set_frozen(zdb_zone * zone)986 static inline void zdb_zone_set_frozen(zdb_zone *zone)
987 {
988 zdb_zone_set_status(zone, ZDB_ZONE_STATUS_FROZEN);
989 }
990
zdb_zone_clear_frozen(zdb_zone * zone)991 static inline void zdb_zone_clear_frozen(zdb_zone *zone)
992 {
993 zdb_zone_clear_status(zone, ZDB_ZONE_STATUS_FROZEN);
994 }
995
zdb_zone_is_frozen(zdb_zone * zone)996 static inline bool zdb_zone_is_frozen(zdb_zone *zone)
997 {
998 return (zdb_zone_get_status(zone) & ZDB_ZONE_STATUS_FROZEN) != 0;
999 }
1000
1001 #ifdef __cplusplus
1002 }
1003 #endif
1004
1005 #endif /* _ZDB_TYPES_H */
1006
1007 /** @} */
1008