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
37 * @brief
38 *
39 * @{
40 */
41 #pragma once
42
43 #include <dnscore/ptr_vector.h>
44 #include <dnscore/ptr_set.h>
45 #include <dnscore/u32_set.h>
46 #include <dnscore/typebitmap.h>
47 #include <dnscore/dnskey.h>
48 #include <dnscore/packet_reader.h>
49 #include <dnscore/packet_writer.h>
50 #include <dnscore/format.h>
51
52 #include <dnsdb/zdb_types.h>
53
54 struct logger_handle;
55
56 #define DNSSEC_CHAIN_SUPPORTED_MAX 16
57
58 #define DNSSEC_CHAIN_ADD 0x01
59 #define DNSSEC_CHAIN_DELETE 0x02
60 #define DNSSEC_CHAIN_REMAP 0x08 // to generate an update of the maps
61 #define DNSSEC_CHAIN_EXISTS 0x10
62 #define DNSSEC_CHAIN_BEGIN 0x20 // implies that the node is actually in the chain
63 #define DNSSEC_CHAIN_END 0x40 // implies that the node is actually in the chain
64 #define DNSSEC_CHAIN_MARK 0x80
65
66 #define DYNUPDATE_DIFF_RETURN_DNSKEY_ADDED 1 // only covers ZSK
67 #define DYNUPDATE_DIFF_RETURN_DNSKEY_REMOVED 2 // only covers ZSK
68 #define DYNUPDATE_DIFF_RETURN_DNSKEY_UPDATED 4 // the reported ZSK status was actually applied
69 #define DYNUPDATE_DIFF_RETURN_MASK 7
70
71 #define DYNUPDATE_DIFF_DRYRUN TRUE
72 #define DYNUPDATE_DIFF_RUN FALSE
73
74 #define ZDLABELT_TAG 0x544c4542414c445a
75 #define ZDFFLABL_TAG 0x4c42414c4646445a
76 #define ZDFFLBRR_TAG 0x4242424c4646445a
77 #define ZDFFFQDN_TAG 0x4e4451464646445a
78 #define ZDFFRRST_TAG 0x545352524646445a
79 #define DMSGPCKT_TAG 0x544b435047534d44
80
81 struct zone_diff_fqdn;
82 struct zone_diff_fqdn_rr_set;
83 struct dnssec_chain;
84
85 struct zone_diff_label_tree
86 {
87 const u8 *label;
88 struct zone_diff_fqdn *diff_fqdn;
89 ptr_set sub;
90 // maybe some flags ...
91 };
92
93 typedef struct zone_diff_label_tree zone_diff_label_tree;
94
95 struct zone_diff
96 {
97 ptr_set fqdn;
98 zone_diff_label_tree root; // contains everything but the apex (that would be nuts resource-wise)
99 const u8 *origin;
100 struct zone_diff_fqdn *apex; // quick access to the apex
101 s32 rrsig_validity_interval;
102 s32 rrsig_validity_regeneration;
103 s32 rrsig_validity_jitter;
104 s32 nttl;
105 bool rrsig_update_allowed;
106 bool has_active_zsk;
107 bool has_active_ksk;
108 bool may_remove_dnskey;
109 bool may_add_dnskey;
110 bool maintain_nsec;
111 bool maintain_nsec3;
112 };
113
114 typedef struct zone_diff zone_diff;
115
116 struct dnssec_chain_node_t_anon { const int hidden; };
117 typedef struct dnssec_chain_node_t_anon* dnssec_chain_node_t;
118
119 struct dnssec_chain_head_t_anon { const int hidden; };
120 typedef struct dnssec_chain_head_t_anon* dnssec_chain_head_t;
121
122 typedef int dnssec_chain_node_compare_method(const void* a_, const void* b_);
123
124 typedef bool dnssec_chain_node_fqdn_is_covered_method(const struct zone_diff_fqdn *diff_fqdn);
125 typedef bool dnssec_chain_node_fqdn_was_covered_method(const struct zone_diff_fqdn *diff_fqdn);
126 typedef dnssec_chain_node_t dnssec_chain_node_new_method(const u8 *fqdn, dnssec_chain_head_t chain);
127 typedef dnssec_chain_node_t dnssec_chain_node_prev_method(const dnssec_chain_node_t node_);
128 typedef void dnssec_chain_node_merge_method(dnssec_chain_node_t node_, dnssec_chain_node_t with_);
129 typedef dnssec_chain_node_t dnssec_chain_node_next_method(const dnssec_chain_node_t node_);
130 typedef void dnssec_chain_node_state_set_method(dnssec_chain_node_t node_, u8 value);
131 typedef u8 dnssec_chain_node_state_get_method(const dnssec_chain_node_t node_);
132 typedef void dnssec_chain_node_delete_method(dnssec_chain_node_t node_);
133 typedef void dnssec_chain_node_publish_delete_method(dnssec_chain_head_t chain_, dnssec_chain_node_t from_, dnssec_chain_node_t to_, zone_diff *diff, ptr_vector *collection);
134 typedef void dnssec_chain_node_publish_add_method(dnssec_chain_head_t chain_, dnssec_chain_node_t from_, dnssec_chain_node_t to_, zone_diff *diff, ptr_vector *collection);
135 typedef void dnssec_chain_node_publish_log_method(dnssec_chain_node_t from_, dnssec_chain_node_t to_);
136 typedef bool dnssec_chain_node_isempty_method(dnssec_chain_head_t chain_);
137 typedef void dnssec_chain_node_format_writer_init(dnssec_chain_node_t node_, format_writer *outfw);
138 typedef bool dnssec_chain_node_rrset_should_be_signed_method(const struct zone_diff_fqdn *diff_fqdn, const struct zone_diff_fqdn_rr_set *rr_set);
139
140 struct dnssec_chain_node_vtbl
141 {
142 dnssec_chain_node_fqdn_is_covered_method *fqdn_is_covered;
143 dnssec_chain_node_fqdn_was_covered_method *fqdn_was_covered;
144 dnssec_chain_node_new_method *node_new;
145 dnssec_chain_node_prev_method *node_prev;
146 dnssec_chain_node_merge_method *node_merge;
147 dnssec_chain_node_next_method *node_next;
148 dnssec_chain_node_state_set_method *state_set;
149 dnssec_chain_node_state_get_method *state_get;
150 dnssec_chain_node_delete_method *node_delete;
151 dnssec_chain_node_publish_delete_method *publish_delete;
152 dnssec_chain_node_publish_add_method *publish_add;
153 dnssec_chain_node_publish_log_method *publish_log;
154 dnssec_chain_node_compare_method *compare;
155 void (*ptr_set_node_delete_callback)(ptr_node*);
156 dnssec_chain_node_isempty_method *isempty;
157 dnssec_chain_node_format_writer_init *format_writer_init;
158 dnssec_chain_node_rrset_should_be_signed_method *rrset_should_be_signed;
159 const char * const __name__;
160 };
161
162 typedef struct dnssec_chain_node_vtbl dnssec_chain_node_vtbl;
163
164 struct dnssec_chain
165 {
166 zone_diff *diff;
167
168 ptr_set chain_diff;
169 const dnssec_chain_node_vtbl *chain;
170 dnssec_chain_head_t chains[DNSSEC_CHAIN_SUPPORTED_MAX];
171 bool chain_being_deleted[DNSSEC_CHAIN_SUPPORTED_MAX];
172 int chains_count;
173 };
174
175 typedef struct dnssec_chain dnssec_chain;
176
177 const dnssec_chain_node_vtbl *dynupdate_nosec_chain_get_vtbl();
178 const dnssec_chain_node_vtbl *dynupdate_nsec_chain_get_vtbl();
179 const dnssec_chain_node_vtbl *dynupdate_nsec3_chain_get_vtbl();
180 const dnssec_chain_node_vtbl *dynupdate_nsec3_optout_chain_get_vtbl();
181
182 /**
183 * Initialises a dnssec chain (editor).
184 * NSEC and NSEC3 chains cannot be mixed.
185 * The actual chain must be set using dnssec_chain_add_chain
186 *
187 * @param dc
188 * @param chain_functions
189 */
190
191 void dnssec_chain_init(dnssec_chain *dc, const dnssec_chain_node_vtbl *chain_functions, zone_diff* diff);
192
193 /**
194 * Adds a chain to the chain editor.
195 *
196 * NSEC3: one of the nsec3_zone* of the zone (add them one at a time).
197 * NSEC: the nsec_zone* of the zone.
198 *
199 * @param dc
200 * @param chain
201 * @param being_deleted tells the chain is on its way out and records should be removed, not added
202 */
203
204 void dnssec_chain_add_chain(dnssec_chain *dc, dnssec_chain_head_t chain, bool being_deleted);
205
206 /**
207 * Adds a node to the chain.
208 *
209 * @param dc
210 * @param fqdn
211 * @param rtype
212 */
213
214 void dnssec_chain_add(dnssec_chain *dc, const u8 *fqdn, u16 rtype);
215
216 /**
217 * Removes a node from the chain.
218 *
219 * @param dc
220 * @param fqdn
221 * @param rtype
222 */
223
224 void dnssec_chain_del(dnssec_chain *dc, const u8 *fqdn, u16 rtype);
225
226 /**
227 * Computes the changes of the chain into a del and an add records vector.
228 *
229 * @param diff
230 * @param origin
231 * @param nttl
232 */
233
234 void dnssec_chain_store_diff(dnssec_chain *dc, zone_diff *diff, ptr_vector *keys, ptr_vector *del, ptr_vector *add);
235
236 /**
237 * Releases the memory used by a chain
238 */
239
240 void dnssec_chain_finalize(dnssec_chain *dc);
241
242 /**
243 * Resource Record States
244 */
245
246 #define ZONE_DIFF_RR_ADD 1 // +
247 #define ZONE_DIFF_RR_REMOVE 2 // -
248 #define ZONE_DIFF_RR_RDATA_OWNED 4 // O
249 #define ZONE_DIFF_RR_VOLATILE 8 // V not in the diff set
250 #define ZONE_DIFF_RR_IN_ZONE 16 // E
251 #define ZONE_DIFF_RR_AUTOMATED 32 // A
252 #define ZONE_DIFF_RR_ADDED 64 // . done
253 #define ZONE_DIFF_RR_REMOVED 128 // . done
254
255 /**
256 * Diff changes
257 */
258
259 #define ZONE_DIFF_CHANGES_NONE 0
260 #define ZONE_DIFF_CHANGES_ADD 1
261 #define ZONE_DIFF_CHANGES_REMOVE 2
262 #define ZONE_DIFF_CHANGES_KEPT 4
263
264 struct zone_diff_label_rr
265 {
266 u8 *fqdn;
267 void *rdata;
268 s32 ttl;
269 u16 rtype;
270 u16 rclass;
271 u16 rdata_size;
272 u8 state;
273 };
274
275 typedef struct zone_diff_label_rr zone_diff_label_rr;
276
277 struct zone_diff_fqdn_rr_set
278 {
279 ptr_set rr;
280 intptr key_mask;
281 s32 org_ttl;
282 s32 new_ttl;
283 u16 rtype;
284 u16 rclass;
285 };
286
287 typedef struct zone_diff_fqdn_rr_set zone_diff_fqdn_rr_set;
288
289 struct zone_diff_fqdn
290 {
291 u32_set rrset;
292 u8 *fqdn;
293 /*struct zone_diff_fqdn *direct_parent;
294 u32 nonempty_children;*/
295 unsigned int type_map_changed:1,
296 all_rrset_added:1, // completely added
297 all_rrset_removed:1, // completely removed
298 is_apex:1,
299 will_be_removed:1,
300
301 at_delegation:1,
302 under_delegation:1,
303 will_have_ds:1,
304 will_be_non_empty:1,
305 will_have_children:1,
306
307 was_at_delegation:1,
308 was_under_delegation:1,
309 had_ds:1,
310 was_non_empty:1,
311 had_children:1,
312
313 rrsig_removed:1,
314 rrsig_added:1,
315 rrsig_kept:1,
316 is_nsec3:1,
317
318 children_added:1, // tells that the children are available in the diff, else it means that had_children = will_have_children
319
320 records_flags_set:1,
321 children_flags_set:1,
322
323 has_active_zsk:1,
324 has_active_ksk:1,
325
326 is_in_database:1;
327 };
328
329 typedef struct zone_diff_fqdn zone_diff_fqdn;
330
331 /**
332 * Initialises a zone diff
333 *
334 * @param diff
335 * @param origin
336 * @param nttl
337 * @param rrsig_push_allowed allows updating an RRSIG "manually" (external signing process)
338 */
339
340 void zone_diff_init(zone_diff *diff, zdb_zone *zone, bool rrsig_update_allowed);
341
342 /**
343 * Adds the SOA records for the incremental update.
344 *
345 * @param diff
346 * @return
347 */
348
349 ya_result zone_diff_set_soa(zone_diff *diff, zdb_rr_label *label);
350
351 /**
352 * Updates status and validates a diff.
353 *
354 * @param diff
355 * @return
356 */
357
358 ya_result zone_diff_validate(zone_diff *diff);
359
360 /**
361 * Stores changes of a diff into two vectors.
362 * Optionally keep track of record sets that need to be signed.
363 * Optionally notify a chain about changes.
364 *
365 * @param diff
366 * @param dc can be NULL
367 * @param rrset_to_sign_vector can be NULL
368 * @param remove
369 * @param add
370 * @return TRUE iff there is a DNSKEY rrset in the diff
371 */
372
373 s32 zone_diff_get_changes(zone_diff *diff, ptr_vector *rrset_to_sign_vector, ptr_vector *ksks, ptr_vector *zsks, ptr_vector *remove, ptr_vector *add);
374
375 /**
376 * Returns TRUE iff there are changes in the diff
377 *
378 * @param diff
379 * @param rrset_to_sign_vector can be NULL
380 *
381 * @return TRUE iff there are changes in the diff
382 */
383
384 bool zone_diff_has_changes(zone_diff *diff, ptr_vector *rrset_to_sign_vector);
385
zone_diff_fqdn_is_covered_by_nsec3(const zone_diff_fqdn * diff_fqdn)386 static inline bool zone_diff_fqdn_is_covered_by_nsec3(const zone_diff_fqdn *diff_fqdn)
387 {
388 return diff_fqdn->is_apex ||
389 (diff_fqdn->at_delegation && !diff_fqdn->under_delegation)|| // has NS records (but is not below NS records)
390 (!(diff_fqdn->at_delegation || diff_fqdn->under_delegation) && (diff_fqdn->will_be_non_empty || diff_fqdn->will_have_children))
391 // else it's under a delegation
392 ;
393 }
394
zone_diff_fqdn_was_covered_by__nsec3(const zone_diff_fqdn * diff_fqdn)395 static inline bool zone_diff_fqdn_was_covered_by__nsec3(const zone_diff_fqdn *diff_fqdn)
396 {
397 return diff_fqdn->is_apex ||
398 (diff_fqdn->was_at_delegation && !diff_fqdn->was_under_delegation) || // had NS records (but is not below NS records)
399 (!(diff_fqdn->was_at_delegation || diff_fqdn->was_under_delegation) && (diff_fqdn->was_non_empty || diff_fqdn->had_children))
400 // else it was under a delegation
401 ;
402 }
403
zone_diff_fqdn_is_covered_by_nsec3_optout(const zone_diff_fqdn * diff_fqdn)404 static inline bool zone_diff_fqdn_is_covered_by_nsec3_optout(const zone_diff_fqdn *diff_fqdn)
405 {
406 return diff_fqdn->is_apex ||
407 (diff_fqdn->at_delegation && !diff_fqdn->under_delegation && diff_fqdn->will_have_ds) || // has DS record(s)
408 (!(diff_fqdn->at_delegation || diff_fqdn->under_delegation) && (diff_fqdn->will_be_non_empty || diff_fqdn->will_have_children))
409 // else it's under a delegation
410 ;
411 }
412
zone_diff_fqdn_was_covered_by_nsec3_optout(const zone_diff_fqdn * diff_fqdn)413 static inline bool zone_diff_fqdn_was_covered_by_nsec3_optout(const zone_diff_fqdn *diff_fqdn)
414 {
415 return diff_fqdn->is_apex ||
416 (diff_fqdn->was_at_delegation && !diff_fqdn->was_under_delegation && diff_fqdn->had_ds) || // had DS record(s)
417 (!(diff_fqdn->was_at_delegation || diff_fqdn->was_under_delegation) && (diff_fqdn->was_non_empty || diff_fqdn->had_children))
418 // else it was under a delegation
419 ;
420 }
421
zone_diff_fqdn_is_covered_by_nsec(const zone_diff_fqdn * diff_fqdn)422 static inline bool zone_diff_fqdn_is_covered_by_nsec(const zone_diff_fqdn *diff_fqdn)
423 {
424 return diff_fqdn->is_apex || (!diff_fqdn->under_delegation && (diff_fqdn->will_be_non_empty /*|| diff_fqdn->will_have_children*/));
425 }
426
zone_diff_fqdn_was_covered_by_nsec(const zone_diff_fqdn * diff_fqdn)427 static inline bool zone_diff_fqdn_was_covered_by_nsec(const zone_diff_fqdn *diff_fqdn)
428 {
429 return diff_fqdn->is_apex || (!diff_fqdn->was_under_delegation && (diff_fqdn->was_non_empty /*|| diff_fqdn->will_have_children*/));
430 }
431
432 /**
433 * debug
434 *
435 * @param rr_set
436 * @param origin
437 * @param handle
438 * @param level
439 */
440
441
442 void zone_diff_fqdn_rr_set_log(const zone_diff_fqdn_rr_set *rr_set, const u8* origin, struct logger_handle *handle, int level);
443
444 /**
445 * debug
446 *
447 * @param origin
448 * @param diff_fqdn
449 * @param level
450 */
451
452 void zone_diff_fqdn_log(const zone_diff_fqdn* diff_fqdn, const u8 *origin, struct logger_handle *handle, int level);
453
454 /**
455 * debug
456 *
457 * @param diff
458 * @param handle
459 * @param level
460 */
461
462 void zone_diff_log(const zone_diff *diff, struct logger_handle *handle, int level);
463
464 /**
465 * debug
466 *
467 * @param diff
468 * @param handle
469 * @param level
470 */
471
472 int zone_diff_check_changes(const zone_diff *diff, struct logger_handle *handle, int level);
473
474 /**
475 * Signs RRSET with all active keys found in keys.
476 * Doesn't do any pertinence tests.
477 * It's only use now is to add RRSIG records to NSEC3 rrsets that have no valid signatures
478 *
479 */
480
481 void zone_diff_sign_rrset(zone_diff *diff, zdb_zone *zone, ptr_vector *keys, ptr_vector *add, zone_diff_fqdn_rr_set *rr_set, zone_diff_fqdn_rr_set *rrsig_rr_set);
482
483 /**
484 * Appends RRSIGs to remove/add vector, following the the need-to-be-signed RR set, using keys from KSK and ZSK vectors.
485 *
486 * @param diff
487 * @param rrset_to_sign_vector
488 * @param ksks
489 * @param zsks
490 * @param remove
491 * @param add
492 */
493
494 ya_result zone_diff_sign(zone_diff *diff, zdb_zone *zone, ptr_vector *rrset_to_sign_vector, ptr_vector *ksks, ptr_vector *zsks, ptr_vector *remove, ptr_vector* add);
495
496 /**
497 * Finalises a zone diff
498 *
499 * @param diff
500 */
501
502 void zone_diff_finalize(zone_diff *diff);
503
504 zone_diff_label_rr *zone_diff_label_rr_new(const u8 *fqdn, u16 rtype, u16 rclass, s32 ttl, void *rdata, u16 rdata_size, bool copy);
505 zone_diff_label_rr *zone_diff_label_rr_new_nordata(const u8 *fqdn, u16 rtype, u16 rclass, s32 ttl, u16 rdata_size);
506
507 void zone_diff_label_rr_init_tmp(zone_diff_label_rr *rr, const u8 *fqdn, u16 rtype, u16 rclass, s32 ttl, void *rdata, u16 rdata_size);
508
509 zone_diff_fqdn *zone_diff_fqdn_add_empty(zone_diff *diff, const u8 *fqdn);
510 zone_diff_fqdn *zone_diff_fqdn_add(zone_diff *diff, const u8 *fqdn, zdb_rr_label *label);
511 zone_diff_fqdn* zone_diff_add_static_fqdn(zone_diff *diff, const u8 *fqdn, zdb_rr_label *label);
512 void zone_diff_add_fqdn_children(zone_diff *diff, const u8 *fqdn, zdb_rr_label *label);
513
514 struct nsec3_node;
515
516 zone_diff_fqdn* zone_diff_add_nsec3(zone_diff *diff, const nsec3_zone* n3, const struct nsec3_node *item, s32 ttl, zone_diff_fqdn_rr_set **out_nsec3_rrset);
517
518 zone_diff_fqdn* zone_diff_add_nsec3_ex(zone_diff *diff, const ptr_vector *zsk_keys, const nsec3_zone* n3, const struct nsec3_node *item, s32 ttl, zone_diff_fqdn_rr_set **out_nsec3_rrset, s32 now, s32 regeneration);
519
520 // to detect empty non-terminals
521 bool zone_diff_fqdn_has_children(zone_diff *diff, const u8 *fqdn);
522
523
524
525 /**
526 * Enables the or_state flags in every record of the set.
527 *
528 * @param rrset
529 * @param or_state
530 */
531
532 void zone_diff_fqdn_rr_set_set_state(zone_diff_fqdn_rr_set *rrset, u8 or_state);
533
534 /**
535 * Returns true iff an rrset of the given type will be present after applying
536 * the diff.
537 *
538 * @param diff_fqdn
539 * @param rtype
540 * @return
541 */
542
543 bool zone_diff_will_have_rrset_type(const zone_diff_fqdn *diff_fqdn, u16 rtype);
544
545 bool zone_diff_remove_rrset_type(zone_diff_fqdn *diff_fqdn, u16 rtype);
546
547
548 /**
549 * Releases keys that will not be in the apex after the diff is applied.
550 *
551 * @param diff
552 * @param keys
553 */
554
555 void zone_diff_filter_out_keys(const zone_diff *diff, ptr_vector *keys);
556
557 zone_diff_fqdn_rr_set *zone_diff_fqdn_rr_set_add(zone_diff_fqdn *diff_fqdn, u16 rtype);
558
559 /**
560 * Returns the local copy of the specified RRSET
561 * DOES NOT create an emtpy set if it does not exist.
562 *
563 * @param diff_fqdn
564 * @param rtype
565 * @return
566 */
567
568 zone_diff_fqdn_rr_set *zone_diff_fqdn_rr_set_get(const zone_diff_fqdn *diff_fqdn, u16 rtype);
569
570 /**
571 * Returns the local copy of the specified RRSET
572 *
573 * @param diff_fqdn
574 * @param rtype
575 * @return
576 */
577
578 const zone_diff_fqdn_rr_set *zone_diff_fqdn_rr_get_const(const zone_diff_fqdn *diff_fqdn, u16 rtype);
579
580 zone_diff_fqdn_rr_set *zone_diff_fqdn_rr_get_if_exists(const zone_diff_fqdn *diff_fqdn, u16 rtype);
581
582 /**
583 * Returns the TTL of the RRSET if it exists
584 *
585 * @param rrset
586 * @return
587 */
588
589 s32 zone_diff_fqdn_rr_set_get_ttl(zone_diff_fqdn_rr_set *rrset);
590
591 /**
592 * Returns the TTL of the RRSET if it exists
593 *
594 * @param diff_fqdn
595 * @param rtype
596 * @return
597 */
598
599 s32 zone_diff_fqdn_rr_get_ttl(const zone_diff_fqdn *diff_fqdn, u16 rtype);
600
601 // Adds a record, if the record exists already in the set, delete the one in the set
602
603 void zone_diff_fqdn_rr_set_rr_add_replace(zone_diff_fqdn_rr_set *rr_set, zone_diff_label_rr *rr);
604
605 // Adds a record, if the record exists already in the set, delete the record and returns the one in the set
606
607 zone_diff_label_rr* zone_diff_fqdn_rr_set_rr_add_get(zone_diff_fqdn_rr_set *rr_set, zone_diff_label_rr *rr);
608
609 /**
610 * Deletes an RRSET if it's empty.
611 *
612 * @param diff_fqdn
613 * @param rtype
614 */
615
616 void zone_diff_fqdn_rr_clear(zone_diff_fqdn *diff_fqdn, u16 rtype);
617
618 /**
619 * Returns TRUE iff an rrset as been added or removed from the label.
620 * Stressing out this concerns RRSET as a whole.
621 *
622 * @param diff_fqdn
623 * @return
624 */
625
626 bool zone_diff_fqdn_type_map_changed(const zone_diff_fqdn *diff_fqdn);
627
628 /**
629 * find label for fqdn ...
630 *
631 * @param diff
632 * @param fqdn
633 * @param label
634 * @return
635 */
636
637 const zone_diff_fqdn *zone_diff_fqdn_get_const(const zone_diff *diff, const u8 *fqdn);
638
639 zone_diff_fqdn* zone_diff_fqdn_get(const zone_diff *diff, const u8 *fqdn);
640
641 /**
642 * Generates a type bit map based on the diff including records matching:
643 *
644 * (status & mask) == masked
645 *
646 * mask,masked
647 * all pre records : ZONE_DIFF_REMOVE|ZONE_DIFF_ADD == 0
648 * all post records: ZONE_DIFF_REMOVE = 0
649 *
650 * Note: it ignores the A and AAAA records when at or under a delegation.
651 *
652 * @param diff
653 * @param fqdn
654 * @param bitmap
655 * @param mask
656 * @param masked
657 * @return
658 */
659
660 u16 zone_diff_type_bit_map_generate(const zone_diff *diff, const u8 *fqdn, type_bit_maps_context *bitmap, u8 mask,
661 u8 masked, const u8 *chain_node_fqdn, bool append_existing_signatures);
662
663 /**
664 * Adds a record on a diff
665 *
666 * @param diff
667 * @param rr_label
668 * @param fqdn
669 * @param rtype
670 * @param rttl
671 * @param rdata_size
672 * @param rdata
673 */
674
675 zone_diff_label_rr* zone_diff_record_add(zone_diff *diff, zdb_rr_label *rr_label, const u8 *fqdn, u16 rtype, s32 rttl, u16 rdata_size, void *rdata);
676
677 /**
678 *
679 * Adds the removal of a specific record on a diff
680 *
681 * @param diff
682 * @param rr_label
683 * @param fqdn
684 * @param rtype
685 * @param rttl
686 * @param rdata_size
687 * @param rdata
688 */
689
690 void zone_diff_record_remove(zone_diff *diff, zdb_rr_label *rr_label, const u8 *fqdn, u16 rtype, s32 rttl, u16 rdata_size, void *rdata);
691
692 bool zone_diff_record_remove_existing(zone_diff *diff, zdb_rr_label *rr_label, const u8 *fqdn, u16 rtype, s32 rttl, u16 rdata_size, void *rdata);
693
694 void zone_diff_record_remove_automated(zone_diff *diff, zdb_rr_label *rr_label, const u8 *fqdn, u16 rtype, s32 rttl, u16 rdata_size, void *rdata);
695
696 /**
697 * Adds the removal of a record set on a diff
698 *
699 * @param diff
700 * @param rr_label
701 * @param fqdn
702 * @param rtype
703 */
704
705 void zone_diff_record_remove_all(zone_diff *diff, zdb_rr_label *rr_label, const u8 *fqdn, u16 rtype);
706
707 /**
708 * Adds the removal all record sets on a diff
709 *
710 * @param diff
711 * @param rr_label
712 * @param fqdn
713 * @param rtype
714 */
715
716 void zone_diff_record_remove_all_sets(zone_diff *diff, zdb_rr_label *rr_label, const u8 *fqdn);
717
diff_generate_signature_interval(zone_diff * diff)718 static inline s32 diff_generate_signature_interval(zone_diff *diff)
719 {
720 s32 maxinterval = diff->rrsig_validity_interval + rand() % (diff->rrsig_validity_jitter + 1);
721 return maxinterval;
722 }
723
724 /**
725 * Writes the del then add records to the journal,
726 * deletes the records marked as volatile,
727 * exchanges the locks of the zone,
728 * replays the journal
729 * exchanges the locks back.
730 *
731 * Returns the result of the replay or SUCCESS if there was nothing to replay.
732 *
733 * @param zone
734 * @param secondary_lock
735 * @param del_vector
736 * @param add_vector
737 * @return
738 */
739
740 ya_result dynupdate_diff_write_to_journal_and_replay(zdb_zone *zone, u8 secondary_lock, ptr_vector *del_vector, ptr_vector *add_vector);
741
742 void zone_diff_store_diff_dnskey_get_keys(zone_diff *diff, ptr_vector *ksks, ptr_vector *zsks);
743
744 /**
745 *
746 */
747
748 ya_result dynupdate_diff(zdb_zone *zone, packet_unpack_reader_data *reader, u16 count, u8 secondary_lock, bool dryrun);
749 /*
750 ya_result dynupdate_diff_chain(zdb_zone *zone, u8 secondary_lock)
751 {
752 zone_diff diff;
753 zone_diff_init(&diff, zone->origin, zone->min_ttl);
754 zone_diff_fqdn* diff_fqdn = zone_diff_add_fqdn(&diff, fqdn, zdb_rr_label *label)
755 zone_diff_finalize(&diff);
756 }
757 */
758
759 /**
760 * Adds a node to the chain from a zone_diff_fqdn
761 *
762 * @param dc
763 * @param fqdn
764 * @param rtype
765 *
766 * @return number of operations counted
767 */
768
769 int dnssec_chain_add_from_diff_fqdn(dnssec_chain *dc, const zone_diff_fqdn* diff_fqdn, u16 rtype);
770
771 /**
772 * Removes a node from the chain from a zone_diff_fqdn
773 *
774 * @param dc
775 * @param fqdn
776 * @param rtype
777 *
778 * @return number of operations counted
779 */
780
781 int dnssec_chain_del_from_diff_fqdn(dnssec_chain *dc, const zone_diff_fqdn* diff_fqdn, u16 rtype);
782
783 void zone_diff_record_state_format(const void* data, output_stream* os, s32 a, char b , bool c, void* reserved_for_method_parameters);
784
785 /** @} */
786
787