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