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