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 ### #######
36  *  @ingroup yadifad
37  *  @brief
38  *
39  * @{
40  */
41 /*----------------------------------------------------------------------------*/
42 
43 #ifndef ZONE_DESC_H
44 #define ZONE_DESC_H
45 
46 #include <dnscore/host_address.h>
47 #include <dnscore/mutex.h>
48 #include <dnscore/list-sl.h>
49 #include <dnscore/basic-priority-queue.h>
50 
51 #include <dnsdb/zdb_types.h>
52 
53 #include <dnscore/acl.h>
54 #include <dnscore/ptr_set.h>
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
60 #define ZONE_LOCK_HAS_OWNER_ID 0 // debug
61 
62 #if ZONE_LOCK_HAS_OWNER_ID
63 #pragma message("***********************************************************")
64 #pragma message("***********************************************************")
65 #pragma message("ZONE_LOCK_HAS_OWNER_ID 1")
66 #pragma message("***********************************************************")
67 #pragma message("***********************************************************")
68 #endif
69 
70 #define     ZT_HINT         0       /**< zone file: hint */
71 #define     ZT_MASTER       1       /**< zone file: master */
72 #define     ZT_SLAVE        2       /**< zone file: slave */
73 #define     ZT_STUB         3       /**< zone file: stub */
74 #define     ZT_UNKNOWN      4       /**< zone file: unknown */
75 
76 #define     ZT_STRING_HINT      "hint"
77 #define     ZT_STRING_MASTER    "master"
78 #define     ZT_STRING_SLAVE     "slave"
79 #define     ZT_STRING_PRIMARY   "primary"
80 #define     ZT_STRING_SECONDARY "secondary"
81 #define     ZT_STRING_STUB      "stub"
82 #define     ZT_STRING_UNKNOWN   "unknown"
83 
84 
85 #define     ZONE_DNSSEC_FL_NOSEC            0
86 #define     ZONE_DNSSEC_FL_NSEC             1
87 #define     ZONE_DNSSEC_FL_NSEC3            2
88 #define     ZONE_DNSSEC_FL_NSEC3_OPTOUT     3
89 
90 #define     ZONE_DNSSEC_FL_MASK             7
91 
92 #define     ZONE_CTRL_FLAG_CLONE            1   /* has a parent in the config */
93 #define     ZONE_CTRL_FLAG_EDITED           2   /* has been edited dynamically (it's a dynamic provisioning zone) */
94 #define     ZONE_CTRL_FLAG_READ_FROM_CONF   4   /* has been read from the configuration file */
95 #define     ZONE_CTRL_FLAG_READ_FROM_DIFF   8   /* has been read from the configuration updates file */
96 #define     ZONE_CTRL_FLAG_SAVED_TO_DIFF   16   /* has been saved to the configuration updates file */
97 #define     ZONE_CTRL_FLAG_DYNAMIC         32   //
98 #define     ZONE_CTRL_FLAG_GENERATE_ZONE  128
99 
100 // behavioural flags
101 
102 #define     ZONE_FLAG_NOTIFY_AUTO                  1
103 #define     ZONE_FLAG_DROP_BEFORE_LOAD             2        // drops the old instance of a zone before loading it again (spare memory)
104 #define     ZONE_FLAG_NO_MASTER_UPDATES            4        /* so a slave will not ask for updates
105                                                              * edf: I added this so I would not hammer
106                                                              *      the root servers when doing tests
107                                                              */
108 #if HAS_MASTER_SUPPORT
109 #define     ZONE_FLAG_MAINTAIN_DNSSEC              8
110 #endif
111 #define     ZONE_FLAG_TRUE_MULTIMASTER            16        // drops a zone whenever changing the master
112 #define     ZONE_FLAG_DROP_CURRENT_ZONE_ON_LOAD   32        // only triggered while changing the true master: the current zone will be dropped
113 #if HAS_MASTER_SUPPORT
114 #define     ZONE_FLAG_RRSIG_NSUPDATE_ALLOWED      64        // allows to push a signature with an update
115 #define     ZONE_FLAG_MAINTAIN_ZONE_BEFORE_MOUNT 128        // must finishing applying policies and signature before mounting the zone
116 #endif
117 
118 // status flags
119 // iIclLMUdDzZaAsSeERxX#---T---ur/!
120 //#define     ZONE_STATUS_IDLE                    0x00000000      /* i nothing happening at ALL */
121 
122 #define     ZONE_STATUS_STARTING_UP             0x00000001      /* I before we even tried to load it */
123 
124 #define     ZONE_STATUS_LOAD                    0x00000004      /* l loading of the zone queried */
125 #define     ZONE_STATUS_LOADING                 0x00000008      /* L in the process of loading the zone */
126 #define     ZONE_STATUS_MOUNTING                0x00000010      /* M loading of the zone queried */
127 #define     ZONE_STATUS_UNMOUNTING              0x00000020      /* U in the process of loading the zone */
128 #define     ZONE_STATUS_DROP                    0x00000040      /* d unloading of the zone queried */
129 #define     ZONE_STATUS_DROPPING                0x00000080      /* D in the process of unloading the zone */
130 #define     ZONE_STATUS_SAVETO_ZONE_FILE        0x00000100      /* z dumping to ... queried */
131 #define     ZONE_STATUS_SAVING_ZONE_FILE        0x00000200      /* Z dumping to ... at this moment */
132 #define     ZONE_STATUS_SAVETO_AXFR_FILE        0x00000400      /* a dumping to ... queried */
133 #define     ZONE_STATUS_SAVING_AXFR_FILE        0x00000800      /* A dumping to ... at this moment */
134 #define     ZONE_STATUS_SIGNATURES_UPDATE       0x00001000      /* s needs to update the signatures (?) */
135 #define     ZONE_STATUS_SIGNATURES_UPDATING     0x00002000      /* S updating signatures */
136 #define     ZONE_STATUS_DYNAMIC_UPDATE          0x00004000      /* e needs to update the database (?) */
137 #define     ZONE_STATUS_DYNAMIC_UPDATING        0x00008000      /* E updating the database */
138 #define     ZONE_STATUS_READONLY_______NOT_USED 0x00010000      /* R database updates not allowed */
139 #define     ZONE_STATUS_DOWNLOAD_XFR_FILE       0x00020000      /* x */
140 #define     ZONE_STATUS_DOWNLOADING_XFR_FILE    0x00040000      /* X */
141 #define     ZONE_STATUS_DROP_AFTER_RELOAD       0x00080000      /* # when a config reload occurrs, this flag is set to all zones
142                                                                  *   when the zone has its config reloaded, it is cleared
143                                                                  *   all zones with this bit set after the reload are dropped
144                                                                  */
145 #define     ZONE_STATUS_FROZEN                  0x00100000      /* f zone is read only <-> READONLY ? */
146 #define     ZONE_STATUS_TEMPLATE_SOURCE_FILE    0x00200000
147 #define     ZONE_STATUS_MUST_CLEAR_JOURNAL      0x00400000
148 #define     ZONE_STATUS_NOTIFIED                0x00800000
149 #define     ZONE_STATUS_DOWNLOADED              0x01000000      /* T the file is on disk, soon to be loaded */
150 
151 #define     ZONE_STATUS_UPDATE_FROM_MASTER      0x02000000
152 #define     ZONE_STATUS_LOAD_AFTER_DROP         0x04000000
153 #define     ZONE_STATUS_RESERVED1               0x08000000
154 #define     ZONE_STATUS_UNREGISTERING           0x10000000      /* u */
155 #define     ZONE_STATUS_REGISTERED              0x20000000      /* r this instance of the zone is registered */
156 #define     ZONE_STATUS_MARKED_FOR_DESTRUCTION  0x40000000      /* / a "destroy" command has been put in the queue */
157 #define     ZONE_STATUS_PROCESSING              0x80000000      /* ! */
158 
159 #define     ZONE_STATUS_BUSY (\
160     ZONE_STATUS_LOAD|ZONE_STATUS_LOADING                            |\
161     ZONE_STATUS_MOUNTING|ZONE_STATUS_UNMOUNTING                     |\
162     ZONE_STATUS_DROP|ZONE_STATUS_DROPPING                           |\
163     ZONE_STATUS_SAVETO_ZONE_FILE|ZONE_STATUS_SAVING_ZONE_FILE       |\
164     ZONE_STATUS_SAVETO_AXFR_FILE|ZONE_STATUS_SAVING_AXFR_FILE       |\
165     ZONE_STATUS_SIGNATURES_UPDATE|ZONE_STATUS_SIGNATURES_UPDATING   |\
166     ZONE_STATUS_DYNAMIC_UPDATE|ZONE_STATUS_DYNAMIC_UPDATING         |\
167     ZONE_STATUS_DOWNLOAD_XFR_FILE|ZONE_STATUS_DOWNLOADING_XFR_FILE  |\
168     ZONE_STATUS_PROCESSING                                          |\
169     0)
170 
171 // locks owners
172 
173 #define     ZONE_LOCK_NOBODY             0x00
174 #define     ZONE_LOCK_READONLY           0x01
175 #define     ZONE_LOCK_LOAD               0x82
176 #define     ZONE_LOCK_UNLOAD             0x83
177 #define     ZONE_LOCK_LOAD_DESC          0x84
178 #define     ZONE_LOCK_DESC_UNLOAD        0x85
179 #define     ZONE_LOCK_REPLACE_DESC       0x86
180 #define     ZONE_LOCK_DOWNLOAD_DESC      0x87
181 #define     ZONE_LOCK_MOUNT              0x88
182 #define     ZONE_LOCK_UNMOUNT            0x89
183 #define     ZONE_LOCK_SERVICE            0x8a
184 #define     ZONE_LOCK_SIGNATURE          0x8b
185 #define     ZONE_LOCK_FREEZE             0x8c
186 #define     ZONE_LOCK_UNFREEZE           0x8d
187 #define     ZONE_LOCK_SAVE               0x8e
188 #define     ZONE_LOCK_DYNUPDATE          0x8f
189 
190 enum zone_type
191 {
192     UNKNOWN = ZT_UNKNOWN,
193     HINT = ZT_HINT,
194     MASTER = ZT_MASTER,
195     SLAVE = ZT_SLAVE,
196     STUB = ZT_STUB,
197     INVALID = MAX_S32       /* ensures the enum is 32 bits (at least) */
198 };
199 
200 typedef enum zone_type zone_type;
201 
202     /**
203      *
204      * About slave refresh:
205      *
206      * REFRESH  A 32 bit time interval before the zone should be
207      *          refreshed.
208      * RETRY    A 32 bit time interval that should elapse before a
209      *          failed refresh should be retried.
210      * EXPIRE   A 32 bit time value that specifies the upper limit on
211      *          the time interval that can elapse before the zone is no
212      *          longer authoritative.
213      */
214 
215 typedef struct zone_refresh_s zone_refresh_s;
216 struct zone_refresh_s
217 {
218     // last successful refresh time
219     u32 refreshed_time;
220     // last time we retried
221     u32 retried_time;
222     // for the sole use of retry.c (updated and used by it)
223     u32 zone_update_next_time;
224     /*
225     // last advertised serial (notification)
226     u32 advertised_serial;
227     // queued to handle notification
228     bool notification_handling;
229     */
230 };
231 
232 typedef struct zone_notify_s zone_notify_s;
233 struct zone_notify_s
234 {
235     /* retry count */
236     u32 retry_count;
237     /* period in minutes */
238     u32 retry_period;
239     /* increase of the period (in minutes) after each retry */
240     u32 retry_period_increase;
241 };
242 
243 #if HAS_RRSIG_MANAGEMENT_SUPPORT && HAS_DNSSEC_SUPPORT
244 
245 #define ZONE_SIGNATURE_INVALID_FIRST_ASSUME_BROKEN 0
246 
247 typedef struct zone_signature_s zone_signature_s;
248 
249 struct zone_signature_s
250 {
251     // The newly generated signatures will be valid for that amount of days
252     u32 sig_validity_interval;
253     // The amount of time before expiration to update a signature
254     u32 sig_validity_regeneration;
255     // The validity of newly generated signature will be off by at most this
256     u32 sig_validity_jitter;
257     // The earliest epoch at which a signature in the zone is expired.
258     u32 sig_invalid_first;
259     // The first epoch when a signature will be updated
260     u32 scheduled_sig_invalid_first;
261 };
262 
263 #endif
264 
265 
266 /// @note HAS_DYNAMIC_PROVISIONING
267 typedef struct dynamic_provisioning_s dynamic_provisioning_s;
268 
269 struct dynamic_provisioning_s
270 {
271     u8  version;
272     u8  padding;
273     u16 flags;
274     u32 timestamp;
275     u32 refresh;
276     u32 retry;
277     u32 expire;
278     u32 timestamp_lo;   /* 0 for now */
279     u32 checksum;       /* MUST BE LAST FIELD */
280 };
281 ///
282 
283 #define ZONE_DESC_MATCH_ORIGIN          0x00000001
284 #define ZONE_DESC_MATCH_DOMAIN          0x00000002
285 #define ZONE_DESC_MATCH_FILE_NAME       0x00000004
286 #define ZONE_DESC_MATCH_MASTERS         0x00000008
287 #define ZONE_DESC_MATCH_NOTIFIES        0x00000010
288 #define ZONE_DESC_MATCH_DYNAMIC         0x00000020
289 #define ZONE_DESC_MATCH_SLAVES          0x00000040
290 #define ZONE_DESC_MATCH_REFRESH         0x00000080
291 #define ZONE_DESC_MATCH_NOTIFY          0x00000100
292 #define ZONE_DESC_MATCH_DNSSEC_MODE     0x00000200
293 #define ZONE_DESC_MATCH_TYPE            0x00000400
294 #define ZONE_DESC_MATCH_ACL             0x00000800
295 #define ZONE_DESC_MATCH_DNSSEC_POLICIES 0x00001000
296 
297 struct dnssec_policy;
298 
299 typedef struct zone_desc_s zone_desc_s;
300 
301 struct zone_desc_s
302 {
303     // fqdn
304     u8                                                           *_origin;      // cannot change
305     // ascii domain name
306     char                                                          *domain;      // cannot change
307     // name of the file on disk
308     char                                                       *file_name;      // may change
309     // path where to find the keys
310     char                                                       *keys_path;      // can be NULL
311     // The list of the masters (for a slave)
312     host_address                                                 *masters;      // may change
313     // If master which are the servers to notify for updates IXFR or AXFR
314     host_address                                                *notifies;      // may change
315 #if ZDB_HAS_ACL_SUPPORT
316     // Restrited list of ip address allowed to query */
317     access_control                                                     ac;      // may change (content is made of pointers)
318 #endif
319     // zone notify settings
320     zone_notify_s                                                  notify;      // may change (3 * 32 bits)
321 #if HAS_DNSSEC_SUPPORT
322 
323 #if HAS_RRSIG_MANAGEMENT_SUPPORT
324 
325 #if HAS_MASTER_SUPPORT
326     struct dnssec_policy                                   *dnssec_policy;
327     ptr_set                            dnssec_policy_processed_key_suites;
328 #endif
329 
330     // zone signature settings
331     zone_signature_s                                            signature;      // may change (5 * 32 bits)
332 #endif
333 
334     u32                                                       dnssec_mode;      // needs to be u32 (config descriptor requirement)
335 #endif
336     // zone refresh status
337     zone_refresh_s                                                refresh;      // internal (3 * 32 bits)
338     volatile u32                                            _status_flags;      // internal
339     volatile u32                                           last_processor;      // internal, diagnostic
340     u32                                                             flags;      // may change ? (notify auto, drop before load, ...)
341     u32                                                   journal_size_kb;      // may change, expressed in kb, 0 "choose", 2^32-1 "
342     u32                                                     stored_serial;      // serial of the last stored full zone image
343     /* Type of zone file (master, slave, stub, unknown) */
344     u32                                            download_failure_count;      // axfr or ixfr downloads that failed since the last one that succeeded
345     zone_type                                                        type;
346     u16                                                            qclass;      // cannot change, most likely CLASS_IN
347     u8                                                multimaster_retries;      // config : how many failures before changing master
348     u8                                               multimaster_failures;      // the number of error on the current primary master (reset on success)
349 
350     // instead of having a priority queue with two levels, two queues will do
351     // the job
352     bpqueue_s                                                    commands;      // queue of commands
353     /// @note HAS_DYNAMIC_PROVISIONING
354     dynamic_provisioning_s dynamic_provisioning;                                // proprietary
355     host_address *slaves;                                                       // proprietary
356 
357     zdb_zone                                                *loaded_zone;       // internal, keeps an RC, has to be increased by users grabbing it (mutex required)
358     ///
359     /* marks */
360     mutex_t                                                         lock;
361     cond_t                                                     lock_cond;
362 
363     u32                                                    commands_bits;
364 
365     volatile s32                                                      rc;
366     volatile s32                                         lock_wait_count;
367     volatile s32                                        lock_owner_count;
368     volatile u8                                               lock_owner;
369 
370 #if ZONE_LOCK_HAS_OWNER_ID
371     volatile thread_t                               lock_last_owner_tid;
372 #endif
373 
374 #if DEBUG
375     u64                                                 instance_time_us;
376     u64                                                      instance_id;
377 #endif
378 };
379 
zone_origin(const zone_desc_s * zone_desc)380 static inline const u8* zone_origin(const zone_desc_s *zone_desc)
381 {
382     return zone_desc->_origin;
383 }
384 
zone_domain(const zone_desc_s * zone_desc)385 static inline const char* zone_domain(const zone_desc_s *zone_desc)
386 {
387     return zone_desc->domain;
388 }
389 
390 #ifdef __cplusplus
391 }
392 #endif
393 
394 #endif /* ZONE_DESC_H */
395 
396 /** @} */
397