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