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 zone Routines for zone_data struct
36 * @ingroup yadifad
37 * @brief zone functions
38 *
39 * Implementation of routines for the zone_data struct
40 * - add
41 * - adjust
42 * - init
43 * - parse
44 * - print
45 * - remove database
46 *
47 * @{
48 */
49 /*------------------------------------------------------------------------------
50 *
51 * USE INCLUDES */
52 #include "server-config.h"
53 #include <string.h>
54 #include <arpa/inet.h> /* or netinet/in.h */
55
56 #include <dnscore/format.h>
57 #include <dnscore/timeformat.h>
58 #include <dnscore/logger.h>
59 #include <dnscore/mutex.h>
60 #include <dnscore/ptr_vector.h>
61 #include <dnscore/parsing.h>
62
63 #if DEBUG
64 #include <dnscore/u64_set.h>
65 #endif
66
67 #include <dnsdb/zdb-config-features.h> // else we get a chicken-egg issue on the following include
68
69 #if ZDB_HAS_DNSSEC_SUPPORT
70 #include <dnsdb/dnssec-keystore.h>
71 #include "dnssec-policy.h"
72 #include <dnsdb/nsec3.h>
73 #endif
74
75 #include "server.h"
76 #include "zone.h"
77 #include "server_error.h"
78 #include "config_error.h"
79 #include "database-service.h"
80 #include "zone-signature-policy.h"
81
82 #define ZONEDATA_TAG 0x41544144454e4f5a
83 #define ZDORIGIN_TAG 0x4e494749524f445a
84
85 #define DEBUG_ARC 0
86
87 #ifndef NAME_MAX
88 #define NAME_MAX 1024
89 #endif
90
91 #define MODULE_MSG_HANDLE g_server_logger
92
93 /* Zone file variables */
94 extern zone_data_set database_zone_desc;
95
96
97 static mutex_t zone_desc_rc_mtx = MUTEX_INITIALIZER;
98
99 #if DEBUG
100 static u64_set zone_desc_tracked_set = U64_SET_EMPTY;
101 static u64 zone_desc_next_id = 0;
102 #endif
103
104 static const char* type_to_name[4] =
105 {
106 "hint",
107 "master",
108 "slave",
109 "stub"
110 };
111
112 static const char *dnssec_to_name[4] =
113 {
114 "nosec",
115 "nsec",
116 "nsec3",
117 "nsec3-optout"
118 };
119
120
121
122 /*------------------------------------------------------------------------------
123 * STATIC PROTOTYPES */
124
125 /*------------------------------------------------------------------------------
126 * FUNCTIONS */
127
128 void
zone_set_lock(zone_data_set * dset)129 zone_set_lock(zone_data_set *dset)
130 {
131 group_mutex_lock(&dset->lock, GROUP_MUTEX_READ);
132 }
133
134 void
zone_set_unlock(zone_data_set * dset)135 zone_set_unlock(zone_data_set *dset)
136 {
137 group_mutex_unlock(&dset->lock, GROUP_MUTEX_READ);
138 }
139
140 void
zone_set_writer_lock(zone_data_set * dset)141 zone_set_writer_lock(zone_data_set *dset)
142 {
143 group_mutex_lock(&dset->lock, GROUP_MUTEX_WRITE);
144 }
145
146 void
zone_set_writer_unlock(zone_data_set * dset)147 zone_set_writer_unlock(zone_data_set *dset)
148 {
149 group_mutex_unlock(&dset->lock, GROUP_MUTEX_WRITE);
150 }
151
152 #if HAS_DYNAMIC_PROVISIONING
153 bool
zone_data_is_clone(zone_desc_s * desc)154 zone_data_is_clone(zone_desc_s *desc)
155 {
156 return (desc != NULL) && ((desc->dynamic_provisioning.flags & ZONE_CTRL_FLAG_CLONE) != 0);
157 }
158 #endif
159
160 static int
zone_dnsname_compare(const void * node_a,const void * node_b)161 zone_dnsname_compare(const void *node_a, const void *node_b)
162 {
163 const u8 *m_a = (const u8*)node_a;
164 const u8 *m_b = (const u8*)node_b;
165
166 return dnsname_compare(m_a, m_b);
167 }
168
169 void
zone_init(zone_data_set * dset)170 zone_init(zone_data_set *dset)
171 {
172 dset->set.root = NULL;
173 dset->set.compare = zone_dnsname_compare;
174 group_mutex_init(&dset->lock);
175 }
176
177 void
zone_finalize(zone_data_set * dset)178 zone_finalize(zone_data_set *dset)
179 {
180 group_mutex_destroy(&dset->lock);
181 dset->set.root = NULL;
182 dset->set.compare = zone_dnsname_compare;
183 }
184
185 /** @brief Initializing zone_data variable
186 *
187 * The function not only initialize a new zone_data struct, but if needed
188 * will add the struct to the linked list
189 *
190 * @param[in,out] dst the new zone_data struct
191 *
192 * @retval OK
193 */
194
195 zone_desc_s *
zone_alloc()196 zone_alloc()
197 {
198 zone_desc_s *zone_desc;
199
200 /* Alloc & clear zone_data structure */
201 ZALLOC_OBJECT_OR_DIE( zone_desc, zone_desc_s, ZONEDATA_TAG);
202 ZEROMEMORY(zone_desc, sizeof(zone_desc_s));
203
204 bpqueue_init(&zone_desc->commands);
205
206 mutex_init(&zone_desc->lock);
207 cond_init(&zone_desc->lock_cond);
208
209 zone_desc->qclass = CLASS_IN;
210
211 #if ZDB_HAS_DNSSEC_SUPPORT
212 #if HAS_RRSIG_MANAGEMENT_SUPPORT
213
214 zone_desc->signature.sig_validity_interval = MAX_S32;
215
216 zone_desc->signature.sig_validity_regeneration = MAX_S32;
217 /*
218 * The validity of newly generated signature will be off by at most this
219 */
220
221 zone_desc->signature.sig_validity_jitter = MAX_S32;
222
223 zone_desc->signature.scheduled_sig_invalid_first = MAX_S32;
224
225 #if HAS_MASTER_SUPPORT
226 ptr_set_init(&zone_desc->dnssec_policy_processed_key_suites);
227 zone_desc->dnssec_policy_processed_key_suites.compare = ptr_set_asciizp_node_compare;
228 #endif
229
230 #endif
231
232 #endif
233
234 zone_desc->rc = 1;
235
236 #if DEBUG
237 zone_desc->instance_time_us = timeus();
238 mutex_lock(&zone_desc_rc_mtx);
239 zone_desc->instance_id = zone_desc_next_id++;
240 u64_node* node = u64_set_insert(&zone_desc_tracked_set, zone_desc->instance_id);
241 node->value = zone_desc;
242 mutex_unlock(&zone_desc_rc_mtx);
243 #endif
244
245 log_debug6("new: ?@%p", zone_desc);
246
247 return zone_desc;
248 }
249
250 /** \brief
251 * Frees a zone data
252 *
253 * @param[in] src is a * to the zone data
254 */
255
256 zone_desc_s *
zone_clone(zone_desc_s * zone_desc)257 zone_clone(zone_desc_s *zone_desc)
258 {
259 zone_desc_s *clone = zone_alloc();
260
261 memcpy(clone, zone_desc, sizeof(zone_desc_s));
262
263 clone->masters = host_address_copy_list(zone_desc->masters);
264 clone->notifies = host_address_copy_list(zone_desc->notifies);
265
266 #if HAS_ACL_SUPPORT
267 /*
268 acl_unmerge_access_control(&zone_setup->ac, &g_config->ac); COMMENTED OUT
269 acl_access_control_clear(&zone_setup->ac); COMMENTED OUT
270 */
271 #endif
272
273 /* Free memory */
274 clone->domain = strdup(zone_domain(zone_desc));
275 clone->file_name = strdup(zone_desc->file_name);
276 clone->_origin = dnsname_dup(zone_origin(zone_desc));
277
278 clone->rc = 1;
279
280 #if HAS_DNSSEC_SUPPORT && HAS_RRSIG_MANAGEMENT_SUPPORT && ZDB_HAS_MASTER_SUPPORT
281 if(clone->dnssec_policy != NULL)
282 {
283 dnssec_policy_acquire(clone->dnssec_policy);
284 }
285 #endif
286
287 log_debug6("clone: %{dnsname}@%p of @%p rc=%i", zone_origin(zone_desc), clone, zone_desc, zone_desc->rc);
288
289 return clone;
290 }
291
292 void
zone_acquire(zone_desc_s * zone_desc)293 zone_acquire(zone_desc_s *zone_desc)
294 {
295 mutex_lock(&zone_desc_rc_mtx);
296 #if DEBUG && DEBUG_ARC
297 s32 old_rc = zone_desc->rc;
298 s32 rc =
299 #endif
300 ++zone_desc->rc;
301 mutex_unlock(&zone_desc_rc_mtx);
302 #if DEBUG && DEBUG_ARC
303 log_debug6("acquire: %{dnsname}@%p rc=%i", zone_origin(zone_desc), zone_desc, rc);
304 char prefix[80];
305 snformat(prefix, sizeof(prefix), "acquire: %{dnsname}@%p", zone_origin(zone_desc), zone_desc);
306 log_debug7("%s: RC from %i to %i", prefix, old_rc, rc);
307 debug_log_stacktrace(g_server_logger, MSG_DEBUG7, prefix);
308 #endif
309 }
310
311
312 void
zone_dump_allocated()313 zone_dump_allocated()
314 {
315 #if DEBUG
316 mutex_lock(&zone_desc_rc_mtx);
317
318 u64_set_iterator iter;
319 u64_set_iterator_init(&zone_desc_tracked_set, &iter);
320 while(u64_set_iterator_hasnext(&iter))
321 {
322 u64_node *node = u64_set_iterator_next_node(&iter);
323 zone_desc_s *zone_desc = (zone_desc_s*)node->value;
324
325 u32 status_flags = zone_get_status(zone_desc);
326 format_writer status_flags_fw = {zone_desc_status_flags_long_format, &status_flags};
327 log_debug1("zone dump: %p #%llu, %llu, rc=%u, %{dnsname} status=%w",zone_desc, zone_desc->instance_id, zone_desc->instance_time_us, zone_desc->rc, zone_origin(zone_desc), &status_flags_fw);
328 }
329
330 mutex_unlock(&zone_desc_rc_mtx);
331 #else
332 // not implemented
333 #endif
334 }
335
336 /**
337 *
338 * Decrements reference and eventually destroys the zone desc
339 *
340 * @param zone_desc
341 */
342
343 void
zone_release(zone_desc_s * zone_desc)344 zone_release(zone_desc_s *zone_desc)
345 {
346 // note: the zone MUST be locked by the caller
347
348 if(zone_desc != NULL)
349 {
350 mutex_lock(&zone_desc_rc_mtx);
351 #if DEBUG && DEBUG_ARC
352 s32 old_rc = zone_desc->rc;
353 #endif
354 s32 rc = --zone_desc->rc;
355 mutex_unlock(&zone_desc_rc_mtx);
356
357 #if DEBUG && DEBUG_ARC
358 log_debug6("release: %{dnsname}@%p rc=%i", zone_origin(zone_desc), zone_desc, rc);
359
360 char prefix[80];
361 snformat(prefix, sizeof(prefix), "release: %{dnsname}@%p", zone_origin(zone_desc), zone_desc);
362 log_debug7("%s: RC from %i to %i", prefix, old_rc, rc);
363 debug_log_stacktrace(g_server_logger, MSG_DEBUG7, prefix);
364 #endif
365
366 if(rc <= 0)
367 {
368 log_debug7("zone_free(%p): '%s' (%i)", zone_desc, zone_domain(zone_desc), rc);
369
370 if(zone_desc->loaded_zone != NULL)
371 {
372 alarm_close(zone_desc->loaded_zone->alarm_handle);
373 zone_desc->loaded_zone->alarm_handle = ALARM_HANDLE_INVALID;
374 zdb_zone_release(zone_desc->loaded_zone);
375 zone_desc->loaded_zone = NULL;
376 }
377
378 #if DEBUG
379 log_debug7("zone_free(%p): '%s' #%llu %llu", zone_desc, zone_domain(zone_desc), zone_desc->instance_id, zone_desc->instance_time_us);
380 mutex_lock(&zone_desc_rc_mtx);
381 u64_set_delete(&zone_desc_tracked_set, zone_desc->instance_id);
382 mutex_unlock(&zone_desc_rc_mtx);
383 #endif
384
385 host_address_delete_list(zone_desc->masters);
386 zone_desc->masters = NULL;
387
388 host_address_delete_list(zone_desc->notifies);
389 zone_desc->notifies = NULL;
390
391 #if HAS_DNSSEC_SUPPORT && HAS_RRSIG_MANAGEMENT_SUPPORT && ZDB_HAS_MASTER_SUPPORT
392 if(zone_desc->dnssec_policy != NULL)
393 {
394 dnssec_policy_release(zone_desc->dnssec_policy);
395 zone_desc->dnssec_policy = NULL;
396 }
397 #endif
398
399 #if HAS_ACL_SUPPORT
400 acl_unmerge_access_control(&zone_desc->ac);
401 acl_access_control_clear(&zone_desc->ac);
402 #endif
403 // Free the memory
404
405 free(zone_desc->domain);
406 free(zone_desc->file_name);
407 free(zone_desc->_origin);
408
409 cond_finalize(&zone_desc->lock_cond);
410 mutex_destroy(&zone_desc->lock);
411
412 #if DEBUG
413 memset(zone_desc, 0xfe, sizeof(zone_desc_s));
414 #endif
415 ZFREE_OBJECT(zone_desc);
416 }
417 }
418 }
419
420 void
zone_remove_all_matching(zone_data_set * dset,zone_data_matching_callback * matchcallback)421 zone_remove_all_matching(zone_data_set *dset, zone_data_matching_callback *matchcallback)
422 {
423 if(dset != NULL)
424 {
425 zone_set_lock(dset); // unlock checked
426 ptr_vector candidates = PTR_VECTOR_EMPTY;
427 ptr_set_iterator iter;
428 ptr_set_iterator_init(&dset->set, &iter);
429
430 while(ptr_set_iterator_hasnext(&iter))
431 {
432 ptr_node *zone_node = ptr_set_iterator_next_node(&iter);
433 zone_desc_s *zone_desc = (zone_desc_s*)zone_node->value;
434
435 if(zone_desc != NULL)
436 {
437 if(matchcallback(zone_desc))
438 {
439 ptr_vector_append(&candidates, zone_desc);
440 }
441 }
442 }
443
444 for(s32 i = 0; i <= candidates.offset; i++)
445 {
446 zone_desc_s *zone_desc = (zone_desc_s*)candidates.data[i];
447 ptr_set_delete(&dset->set, zone_origin(zone_desc));
448 zone_release(zone_desc);
449 }
450
451 ptr_vector_destroy(&candidates);
452
453 zone_set_unlock(dset);
454 }
455 }
456
457 #if 1 // NOT USED
458 /** \brief Frees all elements of the collection
459 *
460 * @param[in] src the collection
461 *
462 * @return NONE
463 */
464 void
zone_free_all(zone_data_set * dset)465 zone_free_all(zone_data_set *dset)
466 {
467 if(dset != NULL)
468 {
469 zone_set_lock(dset); // unlock checked
470
471 ptr_set_iterator iter;
472 ptr_set_iterator_init(&dset->set, &iter);
473
474 while(ptr_set_iterator_hasnext(&iter))
475 {
476 ptr_node *zone_node = ptr_set_iterator_next_node(&iter);
477 zone_desc_s *zone_desc = (zone_desc_s*)zone_node->value;
478
479 if(zone_desc != NULL)
480 {
481 #if DEBUG
482 // status should be idle
483
484 mutex_lock(&zone_desc_rc_mtx);
485 s32 rc = zone_desc->rc;
486 mutex_unlock(&zone_desc_rc_mtx);
487 #if DEBUG
488 zone_lock(zone_desc, ZONE_LOCK_LOAD);
489 zdb_zone *zone = zone_set_loaded_zone(zone_desc, NULL);
490 if(zone != NULL)
491 {
492 zdb_zone_release(zone);
493 }
494 zone_unlock(zone_desc, ZONE_LOCK_LOAD);
495 #endif
496 if(rc != 1)
497 {
498 if(rc > 0)
499 {
500 log_debug5("zone: warning, zone %{dnsname} has RC=%i", zone_origin(zone_desc), rc);
501 }
502 else
503 {
504 log_debug5("zone: warning, zone ? has RC=%i", rc);
505 }
506 }
507 #endif
508 zone_release(zone_desc);
509 }
510 }
511
512 ptr_set_destroy(&dset->set);
513
514 zone_set_unlock(dset);
515 }
516 }
517 #endif
518
519 ya_result
zone_complete_settings(zone_desc_s * zone_desc)520 zone_complete_settings(zone_desc_s *zone_desc)
521 {
522 // type
523
524 if(zone_desc->type == ZT_SLAVE)
525 {
526 if(zone_desc->masters == NULL /* || address_matched(zone_desc->masters, g_config->listen, g_config->port) */)
527 {
528 return DATABASE_ZONE_MISSING_MASTER;
529 }
530 }
531 #if HAS_MASTER_SUPPORT
532 else if(zone_desc->type == ZT_MASTER)
533 {
534 if(zone_desc->file_name == NULL || zone_desc->file_name[0] == '\0')
535 {
536 return ZONE_LOAD_MASTER_ZONE_FILE_UNDEFINED;
537 }
538 }
539 #endif
540 else // zone type is not supported
541 {
542 return DATABASE_ZONE_MISSING_TYPE;
543 }
544
545 // origin
546
547 if(zone_origin(zone_desc) == NULL)
548 {
549 if(zone_desc->domain == NULL)
550 {
551 return DATABASE_ZONE_MISSING_DOMAIN;
552 }
553
554 // else the origin can be set from the domain
555
556 // set the domain to lower case
557
558 char *p = zone_desc->domain;
559 while(*p != 0)
560 {
561 *p = tolower(*p);
562 p++;
563 }
564
565 ya_result return_code;
566
567 MALLOC_OR_DIE(u8*, zone_desc->_origin, strlen(zone_domain(zone_desc)) + 2, ZDORIGIN_TAG);
568
569 if(FAIL(return_code = cstr_to_dnsname(zone_desc->_origin, zone_domain(zone_desc))))
570 {
571 free(zone_desc->_origin);
572 zone_desc->_origin = NULL;
573
574 return return_code;
575 }
576 }
577
578 #if HAS_ACL_SUPPORT
579 // acl
580
581 acl_merge_access_control(&zone_desc->ac, g_config->ac);
582 #endif
583
584 #if ZDB_HAS_DNSSEC_SUPPORT
585 if(zone_desc->keys_path != NULL)
586 {
587 dnssec_keystore_add_domain(zone_origin(zone_desc), zone_desc->keys_path);
588 }
589 #endif
590
591 return SUCCESS;
592 }
593
594 #define ZONE_DESC_COMPARE_FIELD_PTR(field_a_, field_b_, comparator_, flag_) \
595 if(field_a_ != field_b_) \
596 { \
597 if((field_a_ != NULL) && (field_b_ != NULL)) \
598 { \
599 if(comparator_(field_a_, field_b_) != 0) \
600 { \
601 return_code |= flag_; \
602 } \
603 } \
604 else \
605 { \
606 return_code |= flag_; \
607 } \
608 }
609
610 #define ZONE_DESC_EQUALS_FIELD_PTR(field_a_, field_b_, comparator_, flag_) \
611 if(field_a_ != field_b_) \
612 { \
613 if((field_a_ != NULL) && (field_b_ != NULL)) \
614 { \
615 if(!comparator_(field_a_, field_b_)) \
616 { \
617 return_code |= flag_; \
618 } \
619 } \
620 else \
621 { \
622 return_code |= flag_; \
623 } \
624 }
625
626 s32
zone_desc_match(const zone_desc_s * a,const zone_desc_s * b)627 zone_desc_match(const zone_desc_s *a, const zone_desc_s *b)
628 {
629 u32 return_code = 0;
630
631 if(a == b)
632 {
633 return 0;
634 }
635
636 if((a == NULL) || (b == NULL))
637 {
638 return MIN_S32;
639 }
640
641 ZONE_DESC_COMPARE_FIELD_PTR(a->_origin, b->_origin, dnsname_compare, ZONE_DESC_MATCH_ORIGIN);
642 ZONE_DESC_COMPARE_FIELD_PTR(zone_domain(a),zone_domain(b),strcmp, ZONE_DESC_MATCH_DOMAIN);
643 if((a->file_name != NULL) && (b->file_name != NULL))
644 {
645 ZONE_DESC_COMPARE_FIELD_PTR(a->file_name,b->file_name,strcmp, ZONE_DESC_MATCH_FILE_NAME);
646 }
647 else if(a->file_name != b->file_name)
648 {
649 return_code |= ZONE_DESC_MATCH_FILE_NAME;
650 }
651 ZONE_DESC_EQUALS_FIELD_PTR(a->masters,b->masters,host_address_list_equals, ZONE_DESC_MATCH_MASTERS);
652 ZONE_DESC_EQUALS_FIELD_PTR(a->notifies,b->notifies,host_address_list_equals, ZONE_DESC_MATCH_NOTIFIES);
653
654 #if HAS_DNSSEC_SUPPORT && HAS_RRSIG_MANAGEMENT_SUPPORT && ZDB_HAS_MASTER_SUPPORT
655 if(a->dnssec_policy != b->dnssec_policy)
656 {
657 return_code |= ZONE_DESC_MATCH_DNSSEC_POLICIES;
658 }
659 #endif
660
661 #if HAS_ACL_SUPPORT
662 if(!acl_address_control_equals(&a->ac, &b->ac))
663 {
664 return_code |= ZONE_DESC_MATCH_ACL;
665 }
666 #endif
667
668 #if HAS_CTRL
669 if(memcmp(&a->dynamic_provisioning, &b->dynamic_provisioning, sizeof(dynamic_provisioning_s)) != 0)
670 {
671 return_code |= ZONE_DESC_MATCH_DYNAMIC;
672 }
673
674 ZONE_DESC_EQUALS_FIELD_PTR(a->slaves,b->slaves,host_address_list_equals, ZONE_DESC_MATCH_SLAVES);
675 #endif
676 /*
677 if(memcmp(&a->refresh, &b->refresh, sizeof(zone_data_refresh)) != 0)
678 {
679 return_code |= ZONE_DESC_MATCH_REFRESH;
680 }
681 */
682 if(memcmp(&a->notify, &b->notify, sizeof(zone_notify_s)) != 0)
683 {
684 return_code |= ZONE_DESC_MATCH_NOTIFY;
685 }
686
687 #if HAS_DNSSEC_SUPPORT
688 if(a->dnssec_mode != b->dnssec_mode)
689 {
690 return_code |= ZONE_DESC_MATCH_DNSSEC_MODE;
691 }
692 #endif
693
694 if(a->type != b->type)
695 {
696 return_code |= ZONE_DESC_MATCH_TYPE;
697 }
698
699 return return_code;
700 }
701
702 /**
703 * Adds the zone in the collection (if it's not there already)
704 * The zone must have at least it's domain set
705 */
706
707 ya_result
zone_register(zone_data_set * dset,zone_desc_s * zone_desc)708 zone_register(zone_data_set *dset, zone_desc_s *zone_desc)
709 {
710 zone_complete_settings(zone_desc);
711
712 if(zone_origin(zone_desc) == NULL)
713 {
714 if(zone_desc->domain == NULL)
715 {
716 log_err("config: zone: ?: no domain set (not loaded)", zone_domain(zone_desc));
717
718 return DATABASE_ZONE_MISSING_DOMAIN;
719 }
720 }
721
722 zone_set_writer_lock(dset);
723
724 ptr_node *zone_desc_node = ptr_set_find(&dset->set, zone_origin(zone_desc));
725
726 if(zone_desc_node != NULL)
727 {
728 // already known
729
730 zone_desc_s *current_zone_desc = (zone_desc_s*)zone_desc_node->value;
731
732 s32 zone_desc_match_bitmap = ~0;
733
734 if(current_zone_desc == zone_desc)
735 {
736 // already
737 log_debug("zone: %{dnsname} has already been set", zone_origin(zone_desc));
738
739 zone_set_writer_unlock(dset);
740
741 return SUCCESS;
742 }
743 else if((zone_desc_match_bitmap = zone_desc_match(zone_desc, current_zone_desc)) == 0)
744 {
745 // already
746 log_debug("zone: %{dnsname} has already been set this way", zone_origin(zone_desc));
747
748 zone_set_writer_unlock(dset);
749
750 return DATABASE_ZONE_CONFIG_CLONE;
751 }
752 else
753 {
754 /*
755 * compare the zones are decide (overwrite or replace ?)
756 *
757 * if the zones are equals : no operation
758 * if the zones differs ...
759 * ask for a reload of the desc
760 *
761 */
762
763 log_err("zone: %{dnsname} has been set in two different way (bitmap=%08x) (ignoring duplicate)", zone_origin(zone_desc), zone_desc_match_bitmap);
764
765 zone_set_writer_unlock(dset);
766
767 return DATABASE_ZONE_CONFIG_DUP;
768 }
769 }
770 else
771 {
772 log_debug("zone: %{dnsname} is a new zone", zone_origin(zone_desc));
773
774 zone_desc->_status_flags = ZONE_STATUS_STARTING_UP;
775 }
776
777 if(zone_desc->type == ZT_SLAVE)
778 {
779 log_debug1("zone: %{dnsname} is a slave, verifying master settings", zone_origin(zone_desc));
780
781 if(zone_desc->masters == NULL /* || address_matched(zone_desc->masters, g_config->listen, g_config->port) */)
782 {
783 zone_set_writer_unlock(dset);
784
785 log_err("zone: %{dnsname} has no master setting (not loaded)", zone_origin(zone_desc));
786
787 free(zone_desc->_origin);
788 zone_desc->_origin = NULL;
789
790 return DATABASE_ZONE_MISSING_MASTER;
791 }
792
793 log_debug("zone: %{dnsname} is a slave, master is %{hostaddr}", zone_origin(zone_desc), zone_desc->masters);
794 }
795
796 ya_result return_value;
797
798 ptr_node *node = ptr_set_insert(&dset->set, zone_desc->_origin);
799
800 if(node->value == NULL)
801 {
802 //log_info("zone: the zone %{dnsname} has been registered", zone_origin(zone_desc));
803
804 node->value = zone_desc;
805
806 ++dset->set_count;
807
808 return_value = SUCCESS;
809 }
810 else
811 {
812 // already
813 //log_err("zone: the zone %{dnsname} has already been set", zone_origin(zone_desc));
814
815 free(zone_desc->_origin);
816 zone_desc->_origin = NULL;
817
818 return_value = DATABASE_ZONE_CONFIG_DUP;
819 }
820
821 zone_set_writer_unlock(dset);
822
823 return return_value;
824 }
825
826 /**
827 * Removes the zone with the given origin from the collection.
828 * Returns a pointer to the zone. (The caller may destroy it if
829 * he wants)
830 */
831
832 zone_desc_s *
zone_unregister(zone_data_set * dset,const u8 * origin)833 zone_unregister(zone_data_set *dset, const u8 *origin)
834 {
835 zone_desc_s *zone_desc = NULL;
836
837 zone_set_writer_lock(dset);
838
839 ptr_node *node = ptr_set_find(&dset->set, origin);
840
841 if(node != NULL)
842 {
843 zone_desc = (zone_desc_s*)node->value;
844
845 if(zone_desc != NULL)
846 {
847 ptr_set_delete(&dset->set, origin);
848 --dset->set_count;
849 }
850 }
851
852 zone_set_writer_unlock(dset);
853
854 return zone_desc;
855 }
856
857 /**
858 * returns the zone_data from the zone config that's just after the name
859 * in lexicographic order
860 *
861 * @param name
862 * @return
863 */
864
865 zone_desc_s*
zone_getafterdnsname(const u8 * name)866 zone_getafterdnsname(const u8 *name)
867 {
868 zone_desc_s *zone_desc = NULL;
869
870 zone_set_lock(&database_zone_desc); // unlock checked
871
872 ptr_node *zone_node = ptr_set_find(&database_zone_desc.set, name);
873
874 if(zone_node != NULL)
875 {
876 zone_node = ptr_set_node_next(zone_node);
877
878 if(zone_node != NULL)
879 {
880 zone_desc = (zone_desc_s*)zone_node->value;
881 zone_acquire(zone_desc);
882 }
883 }
884
885 zone_set_unlock(&database_zone_desc);
886
887 return zone_desc;
888 }
889
890 zone_desc_s*
zone_acquirebydnsname(const u8 * name)891 zone_acquirebydnsname(const u8 *name)
892 {
893 zone_desc_s *zone_desc = NULL;
894
895 zone_set_lock(&database_zone_desc); // unlock checked
896
897 ptr_node *zone_node = ptr_set_find(&database_zone_desc.set, name);
898
899 if(zone_node != NULL)
900 {
901 zone_desc = (zone_desc_s*)zone_node->value;
902 zone_acquire(zone_desc);
903 }
904
905 zone_set_unlock(&database_zone_desc);
906
907 return zone_desc;
908 }
909
910
911
912
913
914 void
zone_setloading(zone_desc_s * zone_desc,bool v)915 zone_setloading(zone_desc_s *zone_desc, bool v)
916 {
917 const u32 mask = ZONE_STATUS_LOADING;
918
919 if(v)
920 {
921 zone_set_status(zone_desc, mask);
922 }
923 else
924 {
925 zone_clear_status(zone_desc, mask);
926 }
927 }
928
929 void
zone_setmustsavefile(zone_desc_s * zone_desc,bool v)930 zone_setmustsavefile(zone_desc_s *zone_desc, bool v)
931 {
932 const u32 mask = ZONE_STATUS_SAVETO_ZONE_FILE;
933
934 if(v)
935 {
936 zone_set_status(zone_desc, mask);
937 }
938 else
939 {
940 zone_clear_status(zone_desc, mask);
941 }
942 }
943
944 void
zone_setmustsaveaxfr(zone_desc_s * zone_desc,bool v)945 zone_setmustsaveaxfr(zone_desc_s *zone_desc, bool v)
946 {
947 const u32 mask = ZONE_STATUS_SAVETO_AXFR_FILE;
948
949 if(v)
950 {
951 zone_set_status(zone_desc, mask);
952 }
953 else
954 {
955 zone_clear_status(zone_desc, mask);
956 }
957 }
958
959 void
zone_setsavingfile(zone_desc_s * zone_desc,bool v)960 zone_setsavingfile(zone_desc_s *zone_desc, bool v)
961 {
962 const u32 mask = ZONE_STATUS_SAVING_ZONE_FILE;
963
964 if(v)
965 {
966 zone_set_status(zone_desc, mask);
967 }
968 else
969 {
970 zone_clear_status(zone_desc, mask);
971 }
972 }
973
974 void
zone_setsavingaxfr(zone_desc_s * zone_desc,bool v)975 zone_setsavingaxfr(zone_desc_s *zone_desc, bool v)
976 {
977 const u32 mask = ZONE_STATUS_SAVING_AXFR_FILE;
978
979 if(v)
980 {
981 zone_set_status(zone_desc, mask);
982 }
983 else
984 {
985 zone_clear_status(zone_desc, mask);
986 }
987 }
988
989 void
zone_setstartingup(zone_desc_s * zone_desc,bool v)990 zone_setstartingup(zone_desc_s *zone_desc, bool v)
991 {
992 const u32 mask = ZONE_STATUS_STARTING_UP;
993
994 if(v)
995 {
996 zone_set_status(zone_desc, mask);
997 }
998 else
999 {
1000 zone_clear_status(zone_desc, mask);
1001 }
1002 }
1003
1004 bool
zone_isidle(zone_desc_s * zone_desc)1005 zone_isidle(zone_desc_s *zone_desc)
1006 {
1007 return (zone_get_status(zone_desc) & ZONE_STATUS_BUSY) == 0;
1008 }
1009
1010 bool
zone_isfrozen(zone_desc_s * zone_desc)1011 zone_isfrozen(zone_desc_s *zone_desc)
1012 {
1013 return (zone_get_status(zone_desc) & ZONE_STATUS_FROZEN) != 0;
1014 }
1015
1016
1017
1018 bool
zone_isloading(zone_desc_s * zone_desc)1019 zone_isloading(zone_desc_s *zone_desc)
1020 {
1021 return ((zone_get_status(zone_desc) & ZONE_STATUS_LOADING) != 0);
1022 }
1023
1024 bool
zone_mustsavefile(zone_desc_s * zone_desc)1025 zone_mustsavefile(zone_desc_s *zone_desc)
1026 {
1027 return ((zone_get_status(zone_desc) & ZONE_STATUS_SAVETO_ZONE_FILE) != 0);
1028 }
1029
1030 bool
zone_mustsaveaxfr(zone_desc_s * zone_desc)1031 zone_mustsaveaxfr(zone_desc_s *zone_desc)
1032 {
1033 return ((zone_get_status(zone_desc) & ZONE_STATUS_SAVETO_AXFR_FILE) != 0);
1034 }
1035
1036 bool
zone_issavingfile(zone_desc_s * zone_desc)1037 zone_issavingfile(zone_desc_s *zone_desc)
1038 {
1039 return ((zone_get_status(zone_desc) & ZONE_STATUS_SAVING_ZONE_FILE) != 0);
1040 }
1041
1042 bool
zone_issavingaxfr(zone_desc_s * zone_desc)1043 zone_issavingaxfr(zone_desc_s *zone_desc)
1044 {
1045 return ((zone_get_status(zone_desc) & ZONE_STATUS_SAVING_AXFR_FILE) != 0);
1046 }
1047
1048 bool
zone_isstartingup(zone_desc_s * zone_desc)1049 zone_isstartingup(zone_desc_s *zone_desc)
1050 {
1051 return ((zone_get_status(zone_desc) & ZONE_STATUS_STARTING_UP) != 0);
1052 }
1053
1054 bool
zone_isdynamicupdating(zone_desc_s * zone_desc)1055 zone_isdynamicupdating(zone_desc_s *zone_desc)
1056 {
1057 return ((zone_get_status(zone_desc) & ZONE_STATUS_DYNAMIC_UPDATING) != 0);
1058 }
1059
1060 bool
zone_canbeedited(zone_desc_s * zone_desc)1061 zone_canbeedited(zone_desc_s *zone_desc)
1062 {
1063 return ((zone_get_status(zone_desc) & (ZONE_STATUS_STARTING_UP|ZONE_STATUS_DYNAMIC_UPDATING|ZONE_STATUS_SAVING_AXFR_FILE|ZONE_STATUS_SAVING_ZONE_FILE|ZONE_STATUS_LOADING)) == 0);
1064 }
1065
1066 bool
zone_ismaster(zone_desc_s * zone_desc)1067 zone_ismaster(zone_desc_s *zone_desc)
1068 {
1069 return zone_desc->type == ZT_MASTER;
1070 }
1071
1072 ya_result
zone_wait_unlocked(zone_desc_s * zone_desc)1073 zone_wait_unlocked(zone_desc_s *zone_desc)
1074 {
1075 log_debug6("zone_wait_unlocked(%{dnsname}@%p) ...", zone_origin(zone_desc), zone_desc);
1076
1077 mutex_lock(&zone_desc->lock);
1078
1079 if((zone_desc->lock_owner_count | zone_desc->lock_wait_count) != 0)
1080 {
1081 do
1082 {
1083 cond_wait(&zone_desc->lock_cond, &zone_desc->lock);
1084 }
1085 while((zone_desc->lock_owner_count | zone_desc->lock_wait_count) != 0);
1086 }
1087
1088 log_debug6("zone_wait_unlocked(%{dnsname}@%p) done", zone_origin(zone_desc), zone_desc);
1089
1090 cond_notify(&zone_desc->lock_cond);
1091
1092 mutex_unlock(&zone_desc->lock);
1093
1094
1095 return SUCCESS;
1096 }
1097
1098 bool
zone_is_obsolete(zone_desc_s * zone_desc)1099 zone_is_obsolete(zone_desc_s *zone_desc)
1100 {
1101 bool r;
1102
1103 mutex_lock(&zone_desc->lock);
1104
1105 r = ((zone_desc->lock_owner_count | zone_desc->lock_wait_count) == 0) &&
1106 ((zone_get_status(zone_desc) & (ZONE_STATUS_UNREGISTERING|ZONE_STATUS_MARKED_FOR_DESTRUCTION)) != 0);
1107
1108 cond_notify(&zone_desc->lock_cond);
1109 mutex_unlock(&zone_desc->lock);
1110
1111 return r;
1112 }
1113
1114 ya_result
zone_try_lock(zone_desc_s * zone_desc,u8 owner_id)1115 zone_try_lock(zone_desc_s *zone_desc, u8 owner_id)
1116 {
1117 #if DEBUG
1118 log_debug6("zone_try_lock(%{dnsname}@%p, %u", zone_origin(zone_desc), zone_desc, owner_id);
1119 debug_log_stacktrace(MODULE_MSG_HANDLE, MSG_DEBUG6, "zone_try_lock");
1120 #endif
1121
1122 ya_result return_value = LOCK_TIMEOUT;
1123
1124 mutex_lock(&zone_desc->lock);
1125
1126 if((zone_desc->lock_owner == ZONE_LOCK_NOBODY) || (zone_desc->lock_owner == owner_id))
1127 {
1128 zone_desc->lock_owner = owner_id & 0x7f;
1129
1130 zone_desc->lock_owner_count++;
1131
1132 return_value = owner_id;
1133 }
1134
1135 cond_notify(&zone_desc->lock_cond);
1136
1137 mutex_unlock(&zone_desc->lock);
1138
1139 return return_value;
1140 }
1141
1142 ya_result
zone_lock(zone_desc_s * zone_desc,u8 owner_id)1143 zone_lock(zone_desc_s *zone_desc, u8 owner_id)
1144 {
1145 ya_result return_value = LOCK_FAILED;
1146
1147 #if DEBUG
1148 log_debug6("zone_lock(%{dnsname}@%p, %02x)", zone_origin(zone_desc), zone_desc, owner_id);
1149 debug_log_stacktrace(MODULE_MSG_HANDLE, MSG_DEBUG6, "zone_lock");
1150 #endif
1151
1152 mutex_lock(&zone_desc->lock);
1153
1154 if((zone_desc->lock_owner != ZONE_LOCK_NOBODY) && (zone_desc->lock_owner != owner_id))
1155 {
1156 zone_desc->lock_wait_count++;
1157
1158 do
1159 {
1160 cond_wait(&zone_desc->lock_cond, &zone_desc->lock);
1161 }
1162 while((zone_desc->lock_owner != ZONE_LOCK_NOBODY) && (zone_desc->lock_owner != owner_id));
1163
1164 zone_desc->lock_wait_count--;
1165 }
1166
1167 zone_desc->lock_owner = owner_id & 0x7f;
1168 zone_desc->lock_owner_count++;
1169
1170 return_value = owner_id;
1171
1172 #if ZONE_LOCK_HAS_OWNER_ID
1173 zone_desc->lock_last_owner_tid = thread_self();
1174 #endif
1175
1176 if((owner_id & 0x80) == 0)
1177 {
1178 cond_notify(&zone_desc->lock_cond);
1179 }
1180
1181 mutex_unlock(&zone_desc->lock);
1182
1183 return return_value;
1184 }
1185
1186 ya_result
zone_try_lock_wait(zone_desc_s * zone_desc,u64 usec,u8 owner_id)1187 zone_try_lock_wait(zone_desc_s *zone_desc, u64 usec, u8 owner_id)
1188 {
1189 ya_result return_value = LOCK_FAILED;
1190
1191 #if DEBUG
1192 log_debug6("zone_try_lock_wait(%{dnsname}@%p, %llu, %02x)", zone_origin(zone_desc), zone_desc, usec, owner_id);
1193 debug_log_stacktrace(MODULE_MSG_HANDLE, MSG_DEBUG6, "zone_try_lock_wait");
1194 #endif
1195
1196 mutex_lock(&zone_desc->lock);
1197
1198 if((zone_desc->lock_owner != ZONE_LOCK_NOBODY) && (zone_desc->lock_owner != owner_id))
1199 {
1200 zone_desc->lock_wait_count++;
1201
1202 s64 start = timeus();
1203
1204 do
1205 {
1206 cond_timedwait(&zone_desc->lock_cond, &zone_desc->lock, usec);
1207
1208 s64 now = timeus();
1209
1210 if(now - start >= (s64)usec)
1211 {
1212 cond_notify(&zone_desc->lock_cond);
1213 mutex_unlock(&zone_desc->lock);
1214 return LOCK_TIMEOUT;
1215 }
1216 }
1217 while((zone_desc->lock_owner != ZONE_LOCK_NOBODY) && (zone_desc->lock_owner != owner_id));
1218
1219 zone_desc->lock_wait_count--;
1220 }
1221
1222 zone_desc->lock_owner = owner_id & 0x7f;
1223 zone_desc->lock_owner_count++;
1224
1225 return_value = owner_id;
1226
1227 #if ZONE_LOCK_HAS_OWNER_ID
1228 zone_desc->lock_last_owner_tid = thread_self();
1229 #endif
1230
1231 if((owner_id & 0x80) == 0)
1232 {
1233 cond_notify(&zone_desc->lock_cond);
1234 }
1235
1236 mutex_unlock(&zone_desc->lock);
1237
1238 return return_value;
1239 }
1240
1241 void
zone_unlock(zone_desc_s * zone_desc,u8 owner_mark)1242 zone_unlock(zone_desc_s *zone_desc, u8 owner_mark)
1243 {
1244 #if DEBUG
1245 log_debug6("zone_unlock(%{dnsname}@%p, %02x)", zone_origin(zone_desc), zone_desc, owner_mark);
1246 debug_log_stacktrace(MODULE_MSG_HANDLE, MSG_DEBUG6, "zone_unlock");
1247 #endif
1248
1249 mutex_lock(&zone_desc->lock);
1250
1251 yassert(zone_desc->lock_owner == (owner_mark & 0x7f));
1252 yassert(zone_desc->lock_owner_count > 0);
1253
1254 if((--zone_desc->lock_owner_count) == 0)
1255 {
1256 zone_desc->lock_owner = ZONE_LOCK_NOBODY;
1257 }
1258
1259 #if ZONE_LOCK_HAS_OWNER_ID
1260 thread_t tid = thread_self();
1261 if(zone_desc->lock_last_owner_tid == tid)
1262 {
1263 zone_desc->lock_last_owner_tid = 0;
1264 }
1265 #endif
1266
1267 cond_notify(&zone_desc->lock_cond);
1268
1269 mutex_unlock(&zone_desc->lock);
1270
1271 (void)owner_mark; // silence warning on NDEBUG builds
1272 }
1273
1274 bool
zone_islocked(zone_desc_s * zone_desc)1275 zone_islocked(zone_desc_s *zone_desc)
1276 {
1277 mutex_lock(&zone_desc->lock);
1278 bool ret = (zone_desc->lock_owner != ZONE_LOCK_NOBODY);
1279 mutex_unlock(&zone_desc->lock);
1280
1281 return ret;
1282 }
1283
1284 /**
1285 * Sets non-static values in a zone descriptor
1286 *
1287 * @param zone_desc
1288 */
1289
1290 void
zone_setdefaults(zone_desc_s * zone_desc)1291 zone_setdefaults(zone_desc_s *zone_desc)
1292 {
1293 u32 port;
1294
1295 if(FAIL(parse_u32_check_range(g_config->server_port, &port, 1, MAX_U16, BASE_10)))
1296 {
1297 port = DNS_DEFAULT_PORT;
1298 }
1299
1300 zone_desc->_status_flags = ZONE_STATUS_STARTING_UP;
1301
1302 #if HAS_ACL_SUPPORT
1303 acl_merge_access_control(&zone_desc->ac, g_config->ac);
1304 #endif
1305
1306 #if HAS_RRSIG_MANAGEMENT_SUPPORT && HAS_DNSSEC_SUPPORT
1307
1308 /*
1309 * The newly generated signatures will be valid for that amount of days
1310 */
1311
1312 if(zone_desc->signature.sig_validity_interval == MAX_S32)
1313 {
1314 zone_desc->signature.sig_validity_interval = MIN(g_config->sig_validity_interval, SIGNATURE_VALIDITY_INTERVAL_MAX); /* days */
1315 }
1316
1317 if(zone_desc->signature.sig_validity_regeneration == MAX_S32)
1318 {
1319 zone_desc->signature.sig_validity_regeneration = MIN(g_config->sig_validity_regeneration, SIGNATURE_VALIDITY_REGENERATION_MAX);
1320 }
1321
1322 /*
1323 * The validity of newly generated signature will be off by at most this
1324 */
1325
1326 if(zone_desc->signature.sig_validity_jitter == MAX_S32)
1327 {
1328 zone_desc->signature.sig_validity_jitter = MIN(g_config->sig_validity_jitter, SIGNATURE_VALIDITY_JITTER_MAX);
1329 }
1330
1331 /*
1332 * The first epoch when a signature will be marked as invalid.
1333 */
1334
1335 zone_desc->signature.sig_invalid_first = MAX_S32;
1336
1337 zone_desc->signature.scheduled_sig_invalid_first = MAX_S32;
1338 #endif
1339
1340 #if HAS_DYNAMIC_PROVISIONING
1341 memset(&zone_desc->dynamic_provisioning, 0, sizeof(dynamic_provisioning_s));
1342 //zone->dynamic_provisioning.flags |= ZONE_CTRL_FLAG_GENERATE_ZONE;
1343 #endif
1344
1345 zone_desc->notify.retry_count = atoi(S_NOTIFY_RETRY_COUNT);
1346 zone_desc->notify.retry_period = atoi(S_NOTIFY_RETRY_PERIOD) * 60;
1347 zone_desc->notify.retry_period_increase = atoi(S_NOTIFY_RETRY_PERIOD_INCREASE) * 60;
1348
1349 host_address_set_default_port_value(zone_desc->masters, ntohs(port));
1350 host_address_set_default_port_value(zone_desc->notifies, ntohs(port));
1351
1352 // seems incorrect here : acl_access_control_copy(&zone_desc->ac, &g_config->ac);
1353 }
1354
1355 /**
1356 * Merges the settings of a zone into another zone descriptor.
1357 *
1358 * @param desc_zone_desc
1359 * @param src_zone_desc
1360 * @return 0 if the zone are equals
1361 * 1 if some parts have been edited
1362 * or an error code
1363 */
1364
1365 ya_result
zone_setwithzone(zone_desc_s * desc_zone_desc,zone_desc_s * src_zone_desc)1366 zone_setwithzone(zone_desc_s *desc_zone_desc, zone_desc_s *src_zone_desc)
1367 {
1368 bool changed = FALSE;
1369
1370 if(desc_zone_desc->domain != NULL)
1371 {
1372 if(strcmp(zone_domain(desc_zone_desc), zone_domain(src_zone_desc)) != 0)
1373 {
1374 log_debug1("zone_setwithzone: domain does not match '%s'!='%s'", zone_domain(desc_zone_desc), zone_domain(src_zone_desc));
1375 return INVALID_STATE_ERROR;
1376 }
1377 }
1378 else
1379 {
1380 desc_zone_desc->domain = strdup(zone_domain(src_zone_desc));
1381 desc_zone_desc->qclass = src_zone_desc->qclass;
1382 desc_zone_desc->type = src_zone_desc->type;
1383 #if ZDB_HAS_DNSSEC_SUPPORT
1384 desc_zone_desc->dnssec_mode = src_zone_desc->dnssec_mode;
1385 #endif
1386 desc_zone_desc->dynamic_provisioning.flags = desc_zone_desc->dynamic_provisioning.flags;
1387 desc_zone_desc->_origin = dnsname_dup(zone_origin(src_zone_desc));
1388 desc_zone_desc->_status_flags = src_zone_desc->_status_flags;
1389 if(src_zone_desc->file_name != NULL)
1390 {
1391 desc_zone_desc->file_name = strdup(src_zone_desc->file_name);
1392 }
1393
1394 changed = TRUE;
1395 }
1396
1397 #if HAS_ACL_SUPPORT
1398 acl_access_control_copy(&desc_zone_desc->ac, &src_zone_desc->ac);
1399 #endif
1400
1401 #if HAS_RRSIG_MANAGEMENT_SUPPORT && HAS_DNSSEC_SUPPORT
1402
1403 /*
1404 * The newly generated signatures will be valid for that amount of days
1405 */
1406
1407 if(desc_zone_desc->signature.sig_validity_interval != src_zone_desc->signature.sig_validity_interval)
1408 {
1409 desc_zone_desc->signature.sig_validity_interval = src_zone_desc->signature.sig_validity_interval;
1410 changed = TRUE;
1411 }
1412
1413 if(desc_zone_desc->signature.sig_validity_regeneration != src_zone_desc->signature.sig_validity_regeneration)
1414 {
1415 desc_zone_desc->signature.sig_validity_regeneration = src_zone_desc->signature.sig_validity_regeneration;
1416 changed = TRUE;
1417 }
1418
1419 if(desc_zone_desc->signature.sig_validity_jitter != src_zone_desc->signature.sig_validity_jitter)
1420 {
1421 desc_zone_desc->signature.sig_validity_jitter = src_zone_desc->signature.sig_validity_jitter;
1422 changed = TRUE;
1423 }
1424
1425 /*
1426 * The first epoch when a signature will be marked as invalid.
1427 */
1428
1429 if(desc_zone_desc->signature.sig_invalid_first != src_zone_desc->signature.sig_invalid_first)
1430 {
1431 desc_zone_desc->signature.sig_invalid_first = src_zone_desc->signature.sig_invalid_first;
1432 changed = TRUE;
1433 }
1434
1435 if(desc_zone_desc->signature.scheduled_sig_invalid_first != src_zone_desc->signature.scheduled_sig_invalid_first)
1436 {
1437 desc_zone_desc->signature.scheduled_sig_invalid_first = src_zone_desc->signature.scheduled_sig_invalid_first;
1438 changed = TRUE;
1439 }
1440
1441 #endif
1442
1443 #if HAS_DYNAMIC_PROVISIONING
1444 if(memcmp(&desc_zone_desc->dynamic_provisioning, &src_zone_desc->dynamic_provisioning, sizeof(dynamic_provisioning_s)) != 0)
1445 {
1446 memcpy(&desc_zone_desc->dynamic_provisioning, &src_zone_desc->dynamic_provisioning, sizeof(dynamic_provisioning_s));
1447 changed = TRUE;
1448 }
1449 #endif
1450
1451 if(desc_zone_desc->notify.retry_count != src_zone_desc->notify.retry_count)
1452 {
1453 desc_zone_desc->notify.retry_count = src_zone_desc->notify.retry_count;
1454 changed = TRUE;
1455 }
1456
1457 if(desc_zone_desc->notify.retry_period != src_zone_desc->notify.retry_period)
1458 {
1459 desc_zone_desc->notify.retry_period = src_zone_desc->notify.retry_period;
1460 changed = TRUE;
1461 }
1462
1463 if(desc_zone_desc->notify.retry_period_increase != src_zone_desc->notify.retry_period_increase)
1464 {
1465 desc_zone_desc->notify.retry_period_increase = src_zone_desc->notify.retry_period_increase;
1466 changed = TRUE;
1467 }
1468
1469 if(desc_zone_desc->flags != src_zone_desc->flags)
1470 {
1471 desc_zone_desc->flags = src_zone_desc->flags;
1472 changed = TRUE;
1473 }
1474
1475 changed |= host_address_update_host_address_list(&desc_zone_desc->masters, src_zone_desc->masters);
1476 changed |= host_address_update_host_address_list(&desc_zone_desc->notifies, src_zone_desc->notifies);
1477 changed |= host_address_update_host_address_list(&desc_zone_desc->slaves, src_zone_desc->slaves);
1478
1479 if(src_zone_desc->file_name != NULL)
1480 {
1481 if(strcmp(desc_zone_desc->file_name, src_zone_desc->file_name) != 0)
1482 {
1483 free(desc_zone_desc->file_name);
1484 desc_zone_desc->file_name = strdup(src_zone_desc->file_name);
1485 changed = TRUE;
1486 }
1487 }
1488
1489 #if HAS_MASTER_SUPPORT
1490 // master zone without a file name ...
1491
1492 if((desc_zone_desc->file_name == NULL) && (desc_zone_desc->type == ZT_MASTER))
1493 {
1494 desc_zone_desc->dynamic_provisioning.flags |= ZONE_CTRL_FLAG_GENERATE_ZONE;
1495 changed = TRUE;
1496 }
1497 #endif
1498
1499 return (changed)?1:0; // 1 if changed, 0 is no operation performed
1500 }
1501
1502
1503
1504 /**
1505 *
1506 * helper formatting tool to print the zone descriptor status flags as a chain of characters
1507 *
1508 * @param value
1509 * @param os
1510 * @param padding
1511 * @param pad_char
1512 * @param left_justified
1513 * @param reserved_for_method_parameters
1514 */
1515
1516 #ifdef SHORT_VERSION_IS_LESS_CLEAR
1517
1518
1519 /**
1520 * used by zone_desc_status_flags_format
1521 */
1522
1523 static const char status_letters[32] = "IclL"
1524 "MUdD"
1525 "zZaA"
1526 "sSeE"
1527 "RxX#"
1528 "f---"
1529 "T---"
1530 "ur/!";
1531
1532 static void
zone_desc_status_flags_format(const void * value,output_stream * os,s32 padding,char pad_char,bool left_justified,void * reserved_for_method_parameters)1533 zone_desc_status_flags_format(const void *value, output_stream *os, s32 padding, char pad_char, bool left_justified, void* reserved_for_method_parameters)
1534 {
1535 (void)padding;
1536 (void)pad_char;
1537 (void)left_justified;
1538 (void)reserved_for_method_parameters;
1539 u32 status = *((u32*)value);
1540 const char *p = status_letters;
1541 if(status == 0)
1542 {
1543 output_stream_write(os, (const u8*)"i", 1);
1544 }
1545 else
1546 {
1547 do
1548 {
1549 if(status & 1)
1550 {
1551 output_stream_write(os, p, 1);
1552 }
1553
1554 p++;
1555 status >>= 1;
1556 }
1557 while(status != 0);
1558 }
1559 }
1560
1561 #endif
1562
1563 /**
1564 * used by zone_desc_status_flags_long_format
1565 */
1566
1567 static const char *status_words[32] =
1568 {
1569 //"IDLE",
1570 "STARTING-UP", // 0
1571 "MODIFIED",
1572 "LOAD",
1573 "LOADING",
1574 "MOUNTING",
1575 "UNMOUNTING", // 5
1576 "DROP",
1577 "DROPPING",
1578 "SAVETO-ZONE-FILE",
1579 "SAVING-ZONE-FILE",
1580 "SAVETO-AXFR-FILE", // 10
1581 "SAVING-AXFR-FILE",
1582 "SIGNATURES-UPDATE",
1583 "SIGNATURES-UPDATING",
1584 "DYNAMIC-UPDATE",
1585 "DYNAMIC-UPDATING", // 15
1586 "READONLY",
1587 "DOWNLOAD-XFR-FILE",
1588 "DOWNLOADING-XFR-FILE",
1589 "DROP-AFTER-RELOAD",
1590 "FROZEN", // 20
1591 "?",
1592 "?",
1593 "?",
1594 "DOWNLOADED",
1595 "?", // 25
1596 "?",
1597 "?",
1598 "ZONE-STATUS-UNREGISTERING",
1599 "REGISTERED",
1600 "MARKED-FOR-DESTRUCTION",
1601 "PROCESSING"
1602 };
1603
1604 void
zone_desc_status_flags_long_format(const void * value,output_stream * os,s32 padding,char pad_char,bool left_justified,void * reserved_for_method_parameters)1605 zone_desc_status_flags_long_format(const void *value, output_stream *os, s32 padding, char pad_char, bool left_justified, void* reserved_for_method_parameters)
1606 {
1607 (void)padding;
1608 (void)pad_char;
1609 (void)left_justified;
1610 (void)reserved_for_method_parameters;
1611 u32 status = *((u32*)value);
1612 const char **p = status_words;
1613 if(status == 0)
1614 {
1615 output_stream_write(os, (const u8*)"IDLE", 4);
1616 }
1617 else
1618 {
1619 do
1620 {
1621 if(status & 1)
1622 {
1623 const char *word = *p;
1624 output_stream_write(os, word, strlen(word));
1625 output_stream_write(os, (const char*)" ", 1);
1626 }
1627
1628 p++;
1629 status >>= 1;
1630 }
1631 while(status != 0);
1632 }
1633 }
1634
1635 #if HAS_ACL_SUPPORT
1636 /**
1637 *
1638 * helper formatting tool to print the ACL fields of the zone descriptor
1639 *
1640 * @param value
1641 * @param os
1642 * @param padding
1643 * @param pad_char
1644 * @param left_justified
1645 * @param reserved_for_method_parameters
1646 */
1647
1648 static void
zone_desc_ams_format(const void * value,output_stream * os,s32 padding,char pad_char,bool left_justified,void * reserved_for_method_parameters)1649 zone_desc_ams_format(const void *value, output_stream *os, s32 padding, char pad_char, bool left_justified, void* reserved_for_method_parameters)
1650 {
1651 (void)padding;
1652 (void)pad_char;
1653 (void)left_justified;
1654 (void)reserved_for_method_parameters;
1655 address_match_set *ams = (address_match_set*)value;
1656 acl_address_match_set_to_stream(os, ams);
1657 }
1658
1659 #endif
1660
1661 void
zone_desc_log(logger_handle * handle,u32 level,const zone_desc_s * zone_desc,const char * text)1662 zone_desc_log(logger_handle* handle, u32 level, const zone_desc_s *zone_desc, const char *text)
1663 {
1664 if(text == NULL)
1665 {
1666 text = "NULL";
1667 }
1668
1669 if(zone_desc == NULL)
1670 {
1671 logger_handle_msg(handle, level, "%s: NULL", text);
1672 return;
1673 }
1674
1675 logger_handle_msg(handle, level, "%s: %{dnsname} @%p '%s' file='%s'",
1676 text, FQDNNULL(zone_origin(zone_desc)), zone_desc, STRNULL(zone_domain(zone_desc)), STRNULL(zone_desc->file_name));
1677 u32 status_flags = zone_get_status(zone_desc);
1678 //format_writer status_flags_fw = {zone_desc_status_flags_format, &status_flags};
1679 format_writer status_flags_fw = {zone_desc_status_flags_long_format, &status_flags};
1680 logger_handle_msg(handle, level, "%s: %{dnsname} status=%w",
1681 text, FQDNNULL(zone_origin(zone_desc)), &status_flags_fw);
1682 #if ZDB_HAS_DNSSEC_SUPPORT
1683 logger_handle_msg(handle, level, "%s: %{dnsname} dnssec=%s type=%s flags=%x lock=%02hhx #olock=%d #wlock=%d",
1684 text, FQDNNULL(zone_origin(zone_desc)), zone_dnssec_to_name(zone_desc->dnssec_mode), zone_type_to_name(zone_desc->type),
1685 zone_desc->flags, zone_desc->lock_owner, zone_desc->lock_owner_count, zone_desc->lock_wait_count);
1686 #else
1687 logger_handle_msg(handle, level, "%s: %{dnsname} type=%s flags=%x lock=%02hhx #olock=%d #wlock=%d",
1688 text, FQDNNULL(zone_origin(zone_desc)), zone_type_to_name(zone_desc->type),
1689 zone_desc->flags, zone_desc->lock_owner, zone_desc->lock_owner_count, zone_desc->lock_wait_count);
1690 #endif
1691 logger_handle_msg(handle, level, "%s: %{dnsname} refreshed=%d retried=%d next=%d",
1692 text, FQDNNULL(zone_origin(zone_desc)), zone_desc->refresh.refreshed_time, zone_desc->refresh.retried_time, zone_desc->refresh.zone_update_next_time);
1693
1694 #if ZDB_HAS_DNSSEC_SUPPORT && HAS_RRSIG_MANAGEMENT_SUPPORT && ZDB_HAS_MASTER_SUPPORT
1695
1696 u32 sig_invalid_first = zone_desc->signature.sig_invalid_first;
1697 u32 scheduled_sig_invalid_first = zone_desc->signature.scheduled_sig_invalid_first;
1698
1699 logger_handle_msg(handle, level, "%s: %{dnsname} interval=%d jitter=%d regeneration=%d invalid=%T scheduled-update=%T",
1700 text, FQDNNULL(zone_origin(zone_desc)),
1701 zone_desc->signature.sig_validity_interval,
1702 zone_desc->signature.sig_validity_jitter,
1703 zone_desc->signature.sig_validity_regeneration,
1704 sig_invalid_first,
1705 scheduled_sig_invalid_first);
1706
1707 if(zone_desc->dnssec_policy != NULL)
1708 {
1709 logger_handle_msg(handle, level, "%s: %{dnsname} dnssec-policy: '%s'", text, FQDNNULL(zone_origin(zone_desc)), STRNULL(zone_desc->dnssec_policy->name));
1710 }
1711 else
1712 {
1713 logger_handle_msg(handle, level, "%s: %{dnsname} dnssec-policy: none", text, FQDNNULL(zone_origin(zone_desc)));
1714 }
1715
1716 #endif
1717
1718 logger_handle_msg(handle, level, "%s: %{dnsname} master=%{hostaddr}",
1719 text, FQDNNULL(zone_origin(zone_desc)), zone_desc->masters);
1720 logger_handle_msg(handle, level, "%s: %{dnsname} notified=%{hostaddrlist}",
1721 text, FQDNNULL(zone_origin(zone_desc)), zone_desc->notifies);
1722
1723 #if HAS_ACL_SUPPORT
1724 format_writer status_ams_fw = {zone_desc_ams_format, &zone_desc->ac.allow_query};
1725 logger_handle_msg(handle, level, "%s: %{dnsname} allow query=%w", text, FQDNNULL(zone_origin(zone_desc)), &status_ams_fw);
1726
1727 status_ams_fw.value = &zone_desc->ac.allow_update;
1728 logger_handle_msg(handle, level, "%s: %{dnsname} allow update=%w", text, FQDNNULL(zone_origin(zone_desc)), &status_ams_fw);
1729
1730 status_ams_fw.value = &zone_desc->ac.allow_update_forwarding;
1731 logger_handle_msg(handle, level, "%s: %{dnsname} allow update forwarding=%w", text, FQDNNULL(zone_origin(zone_desc)), &status_ams_fw);
1732
1733 status_ams_fw.value = &zone_desc->ac.allow_transfer;
1734 logger_handle_msg(handle, level, "%s: %{dnsname} allow transfer=%w", text, FQDNNULL(zone_origin(zone_desc)), &status_ams_fw);
1735
1736 status_ams_fw.value = &zone_desc->ac.allow_notify;
1737 logger_handle_msg(handle, level, "%s: %{dnsname} allow notify=%w", text, FQDNNULL(zone_origin(zone_desc)), &status_ams_fw);
1738 #endif
1739
1740 #if HAS_DYNAMIC_PROVISIONING
1741
1742 #if HAS_ACL_SUPPORT
1743 status_ams_fw.value = &zone_desc->ac.allow_control;
1744
1745 logger_handle_msg(handle, level, "%s: %{dnsname} allow control=%w", text, FQDNNULL(zone_origin(zone_desc)), &status_ams_fw);
1746 #endif
1747
1748 logger_handle_msg(handle, level, "%s: %{dnsname} + dp v=%hx flags=%hx expire=%x refresh=%x retry=%x ts=%x:%x",
1749 text, FQDNNULL(zone_origin(zone_desc)),
1750 zone_desc->dynamic_provisioning.version,
1751 zone_desc->dynamic_provisioning.flags,
1752 zone_desc->dynamic_provisioning.expire,
1753 zone_desc->dynamic_provisioning.refresh,
1754 zone_desc->dynamic_provisioning.retry,
1755 zone_desc->dynamic_provisioning.timestamp,
1756 zone_desc->dynamic_provisioning.timestamp_lo);
1757 logger_handle_msg(handle, level, "%s: %{dnsname} + dp slaves=%{hostaddrlist}",
1758 text, FQDNNULL(zone_origin(zone_desc)), zone_desc->slaves);
1759
1760 u32 command_count = zone_desc->commands.size;
1761 bpqueue_node_s *command_node = zone_desc->commands.first;
1762 for(u32 i = 0; i < command_count; i++)
1763 {
1764 zone_command_s *cmd = (zone_command_s*)command_node->data;
1765 logger_handle_msg(handle, level, "%s: %{dnsname} @%p & [%-2i] (%i) %s",
1766 text, FQDNNULL(zone_origin(zone_desc)), zone_desc,
1767 i, command_node->priority, database_service_operation_get_name(cmd->id));
1768
1769 command_node = command_node->next;
1770 }
1771
1772 #endif
1773 }
1774
1775 void
zone_desc_log_all(logger_handle * handle,u32 level,zone_data_set * dset,const char * text)1776 zone_desc_log_all(logger_handle* handle, u32 level, zone_data_set *dset, const char *text)
1777 {
1778 zone_set_lock(dset); // unlock checked
1779
1780 if(!ptr_set_isempty(&dset->set))
1781 {
1782 ptr_set_iterator iter;
1783 ptr_set_iterator_init(&dset->set, &iter);
1784
1785 while(ptr_set_iterator_hasnext(&iter))
1786 {
1787 ptr_node *zone_node = ptr_set_iterator_next_node(&iter);
1788 zone_desc_s *zone_desc = (zone_desc_s*)zone_node->value;
1789
1790 zone_desc_log(handle, level, zone_desc, text);
1791 }
1792
1793 zone_set_unlock(dset);
1794 }
1795 else
1796 {
1797 zone_set_unlock(dset);
1798
1799 #if DEBUG
1800 log_debug("zone_desc_log_all: %s set is empty", text);
1801 #endif
1802 }
1803 }
1804
1805 /**
1806 *
1807 * Calls the callback for all zone_desc.
1808 *
1809 * @param cb
1810 * @param args
1811 */
1812
1813 ya_result
zone_desc_for_all(zone_desc_for_all_callback * cb,void * args)1814 zone_desc_for_all(zone_desc_for_all_callback *cb, void *args)
1815 {
1816 ya_result ret = SUCCESS;
1817
1818 zone_set_lock(&database_zone_desc); // unlock checked
1819
1820 if(!ptr_set_isempty(&database_zone_desc.set))
1821 {
1822 ptr_set_iterator iter;
1823 ptr_set_iterator_init(&database_zone_desc.set, &iter);
1824
1825 while(ptr_set_iterator_hasnext(&iter))
1826 {
1827 ptr_node *zone_node = ptr_set_iterator_next_node(&iter);
1828 zone_desc_s *zone_desc = (zone_desc_s*)zone_node->value;
1829
1830 if(FAIL(ret = cb(zone_desc, args)))
1831 {
1832 return ret;
1833 }
1834 }
1835 }
1836
1837 zone_set_unlock(&database_zone_desc);
1838
1839 return ret;
1840 }
1841
1842 const char*
zone_type_to_name(zone_type t)1843 zone_type_to_name(zone_type t)
1844 {
1845 if((t >= ZT_HINT) && (t <= ZT_STUB))
1846 {
1847 return type_to_name[t];
1848 }
1849
1850 return "invalid";
1851 }
1852
1853 const char*
zone_dnssec_to_name(u32 dnssec_flags)1854 zone_dnssec_to_name(u32 dnssec_flags)
1855 {
1856 dnssec_flags &= ZONE_DNSSEC_FL_MASK;
1857 if(dnssec_flags < 4)
1858 {
1859 return dnssec_to_name[dnssec_flags];
1860 }
1861
1862 return "invalid";
1863 }
1864
1865 void
zone_enqueue_command(zone_desc_s * zone_desc,u32 id,void * parm,bool has_priority)1866 zone_enqueue_command(zone_desc_s *zone_desc, u32 id, void* parm, bool has_priority)
1867 {
1868 if(!has_priority && ((zone_get_status(zone_desc) & ZONE_STATUS_MARKED_FOR_DESTRUCTION) != 0))
1869 {
1870 log_err("tried to queue to a zone marked for destruction");
1871 return;
1872 }
1873
1874 #if DEBUG
1875 log_debug("zone_desc: enqueue command %{dnsname}@%p=%i %c %s",
1876 zone_origin(zone_desc), zone_desc, zone_desc->rc, (has_priority)?'H':'L', database_service_operation_get_name(id));
1877 #endif
1878
1879 if(zone_desc->commands_bits & (1 << id))
1880 {
1881 #if DEBUG
1882 log_debug("zone_desc: enqueue command %{dnsname}@%p=%i %c %s: already queued",
1883 zone_origin(zone_desc), zone_desc, zone_desc->rc, (has_priority)?'H':'L', database_service_operation_get_name(id));
1884 #endif
1885 return; // already queued
1886 }
1887
1888 zone_command_s *cmd;
1889 ZALLOC_OBJECT_OR_DIE( cmd, zone_command_s, ZONECMD_TAG);
1890 cmd->parm.ptr = parm;
1891 cmd->id = id;
1892 bpqueue_enqueue(&zone_desc->commands, cmd, (has_priority)?0:1);
1893 }
1894
1895 zone_command_s*
zone_dequeue_command(zone_desc_s * zone_desc)1896 zone_dequeue_command(zone_desc_s *zone_desc)
1897 {
1898 zone_command_s *cmd = (zone_command_s*)bpqueue_dequeue(&zone_desc->commands);
1899
1900 #if DEBUG
1901 if(cmd != NULL)
1902 {
1903 log_debug("zone_desc: dequeue command %{dnsname}@%p=%i - %s",
1904 zone_origin(zone_desc), zone_desc, zone_desc->rc, database_service_operation_get_name(cmd->id));
1905 }
1906 else
1907 {
1908 log_debug("zone_desc: dequeue command %{dnsname}@%p=%i - NULL",
1909 zone_origin(zone_desc), zone_desc, zone_desc->rc);
1910 }
1911 #endif
1912
1913 if(cmd != NULL)
1914 {
1915 zone_desc->commands_bits &= ~(1 << cmd->id);
1916 }
1917
1918 return cmd;
1919 }
1920
1921 void
zone_command_free(zone_command_s * cmd)1922 zone_command_free(zone_command_s *cmd)
1923 {
1924 ZFREE_OBJECT(cmd);
1925 }
1926
1927 zdb_zone *
zone_get_loaded_zone(zone_desc_s * zone_desc)1928 zone_get_loaded_zone(zone_desc_s *zone_desc)
1929 {
1930 yassert(zone_islocked(zone_desc));
1931
1932 zdb_zone *zone = zone_desc->loaded_zone; // OK
1933 if(zone != NULL)
1934 {
1935 zdb_zone_acquire(zone);
1936 }
1937 return zone;
1938 }
1939
1940 zdb_zone *
zone_set_loaded_zone(zone_desc_s * zone_desc,zdb_zone * zone)1941 zone_set_loaded_zone(zone_desc_s *zone_desc, zdb_zone *zone)
1942 {
1943 yassert(zone_islocked(zone_desc));
1944
1945 zdb_zone *old_zone = zone_desc->loaded_zone; // OK
1946 if(zone != NULL)
1947 {
1948 zdb_zone_acquire(zone);
1949 }
1950 zone_desc->loaded_zone = zone; // OK
1951
1952 return old_zone;
1953 }
1954
1955 bool
zone_has_loaded_zone(zone_desc_s * zone_desc)1956 zone_has_loaded_zone(zone_desc_s *zone_desc)
1957 {
1958 yassert(zone_islocked(zone_desc));
1959
1960 zdb_zone *zone = zone_desc->loaded_zone; // OK
1961 return zone != NULL;
1962 }
1963
1964 void
zone_set_status(zone_desc_s * zone_desc,u32 flags)1965 zone_set_status(zone_desc_s *zone_desc, u32 flags)
1966 {
1967 #if DEBUG
1968 log_debug("zone: %{dnsname}: %p: status %08x + %08x -> %08x", zone_origin(zone_desc), zone_desc, zone_desc->_status_flags, flags, zone_desc->_status_flags|flags);
1969 #endif
1970 zone_desc->_status_flags |= flags;
1971 }
1972
1973 u32
zone_get_set_status(zone_desc_s * zone_desc,u32 flags)1974 zone_get_set_status(zone_desc_s *zone_desc, u32 flags)
1975 {
1976 #if DEBUG
1977 log_debug("zone: %{dnsname}: %p: status %08x + %08x -> %08x", zone_origin(zone_desc), zone_desc, zone_desc->_status_flags, flags, zone_desc->_status_flags|flags);
1978 #endif
1979 u32 ret = zone_desc->_status_flags & flags;
1980 zone_desc->_status_flags |= flags;
1981 return ret;
1982 }
1983
1984 void
zone_clear_status(zone_desc_s * zone_desc,u32 flags)1985 zone_clear_status(zone_desc_s *zone_desc, u32 flags)
1986 {
1987 #if DEBUG
1988 log_debug("zone: %{dnsname}: %p: status %08x - %08x -> %08x", zone_origin(zone_desc), zone_desc, zone_desc->_status_flags, flags, zone_desc->_status_flags&~flags);
1989 #endif
1990
1991 zone_desc->_status_flags &= ~flags;
1992 if((flags & ZONE_STATUS_PROCESSING) == 0)
1993 {
1994 // poke
1995 database_fire_zone_processed(zone_desc);
1996 }
1997 }
1998
1999 u32
zone_get_status(const zone_desc_s * zone_desc)2000 zone_get_status(const zone_desc_s *zone_desc)
2001 {
2002 return zone_desc->_status_flags;
2003 }
2004
2005 #if ZDB_HAS_DNSSEC_SUPPORT && ZDB_HAS_RRSIG_MANAGEMENT_SUPPORT && ZDB_HAS_MASTER_SUPPORT
2006 void
zone_dnssec_status_update(zdb_zone * zone)2007 zone_dnssec_status_update(zdb_zone *zone)
2008 {
2009 u8 zone_dnssec_type = zone_policy_guess_dnssec_type(zone);
2010 u8 maintain_mode = zone_get_maintain_mode(zone);
2011
2012 bool update_chain0 = FALSE;
2013
2014 switch(zone_dnssec_type)
2015 {
2016 case ZONE_DNSSEC_FL_NOSEC:
2017 {
2018 if((maintain_mode & ZDB_ZONE_MAINTAIN_MASK) != 0)
2019 {
2020 zdb_rr_label_flag_and(zone->apex, ~(ZDB_RR_LABEL_NSEC | ZDB_RR_LABEL_NSEC3 | ZDB_RR_LABEL_NSEC3_OPTOUT));
2021 zone_set_maintain_mode(zone, 0);
2022 }
2023 break;
2024 }
2025 case ZONE_DNSSEC_FL_NSEC:
2026 {
2027 if((maintain_mode & ZDB_ZONE_MAINTAIN_NSEC) == 0)
2028 {
2029 zdb_rr_label_flag_or(zone->apex, ZDB_RR_LABEL_NSEC);
2030 zdb_rr_label_flag_and(zone->apex, ~(ZDB_RR_LABEL_NSEC3 | ZDB_RR_LABEL_NSEC3_OPTOUT));
2031 zone_set_maintain_mode(zone, ZDB_ZONE_MAINTAIN_NSEC);
2032 }
2033 break;
2034 }
2035 case ZONE_DNSSEC_FL_NSEC3:
2036 {
2037 if((maintain_mode & ZDB_ZONE_MAINTAIN_NSEC3) == 0)
2038 {
2039 zdb_rr_label_flag_or(zone->apex, ZDB_RR_LABEL_NSEC3);
2040 zdb_rr_label_flag_and(zone->apex, ~(ZDB_RR_LABEL_NSEC | ZDB_RR_LABEL_NSEC3_OPTOUT));
2041 zone_set_maintain_mode(zone, ZDB_ZONE_MAINTAIN_NSEC3);
2042 update_chain0 = TRUE;
2043 }
2044 break;
2045 }
2046 case ZONE_DNSSEC_FL_NSEC3_OPTOUT:
2047 {
2048 if((maintain_mode & ZDB_ZONE_MAINTAIN_NSEC3) == 0)
2049 {
2050 zdb_rr_label_flag_or(zone->apex, ZDB_RR_LABEL_NSEC3 | ZDB_RR_LABEL_NSEC3_OPTOUT);
2051 zdb_rr_label_flag_and(zone->apex, ~(ZDB_RR_LABEL_NSEC));
2052 zone_set_maintain_mode(zone, ZDB_ZONE_MAINTAIN_NSEC3_OPTOUT);
2053 update_chain0 = TRUE;
2054 }
2055 break;
2056 }
2057 }
2058
2059 if(update_chain0)
2060 {
2061 zdb_zone_lock(zone, ZDB_ZONE_MUTEX_LOAD);
2062 nsec3_zone_update_chain0_links(zone);
2063 zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_LOAD);
2064 }
2065 }
2066
2067 u8
zone_policy_guess_dnssec_type(zdb_zone * zone)2068 zone_policy_guess_dnssec_type(zdb_zone *zone)
2069 {
2070 u8 zone_dnssec_type = ZONE_DNSSEC_FL_NOSEC;
2071
2072 if(zdb_zone_has_nsec_records(zone))
2073 {
2074 zone_dnssec_type = ZONE_DNSSEC_FL_NSEC;
2075 }
2076 else if(zdb_zone_has_nsec3_records(zone))
2077 {
2078 if(zdb_zone_has_nsec3_optout_chain(zone))
2079 {
2080 zone_dnssec_type = ZONE_DNSSEC_FL_NSEC3_OPTOUT;
2081 }
2082 else
2083 {
2084 zone_dnssec_type = ZONE_DNSSEC_FL_NSEC3;
2085 }
2086 }
2087
2088 return zone_dnssec_type;
2089 }
2090
2091 bool
zone_policy_key_suite_is_marked_processed(zone_desc_s * zone_desc,const struct dnssec_policy_key_suite * kr)2092 zone_policy_key_suite_is_marked_processed(zone_desc_s *zone_desc, const struct dnssec_policy_key_suite *kr)
2093 {
2094 mutex_lock(&zone_desc->lock);
2095 ptr_node *node = ptr_set_find(&zone_desc->dnssec_policy_processed_key_suites, kr->name);
2096 mutex_unlock(&zone_desc->lock);
2097 return node != NULL;
2098 }
2099
2100 bool
zone_policy_key_suite_mark_processed(zone_desc_s * zone_desc,const struct dnssec_policy_key_suite * kr)2101 zone_policy_key_suite_mark_processed(zone_desc_s *zone_desc, const struct dnssec_policy_key_suite *kr)
2102 {
2103 bool ret = FALSE;
2104 mutex_lock(&zone_desc->lock);
2105 ptr_node *node = ptr_set_insert(&zone_desc->dnssec_policy_processed_key_suites, kr->name);
2106
2107 if(node->value != NULL)
2108 {
2109 node->value = (struct dnssec_policy_key_suite*)kr;
2110 ret = TRUE;
2111 }
2112 mutex_unlock(&zone_desc->lock);
2113 return ret;
2114 }
2115
2116 void
zone_policy_key_suite_unmark_processed(zone_desc_s * zone_desc,const struct dnssec_policy_key_suite * kr)2117 zone_policy_key_suite_unmark_processed(zone_desc_s *zone_desc, const struct dnssec_policy_key_suite *kr)
2118 {
2119 mutex_lock(&zone_desc->lock);
2120 ptr_set_delete(&zone_desc->dnssec_policy_processed_key_suites, kr->name);
2121 mutex_unlock(&zone_desc->lock);
2122 }
2123
2124 #endif
2125
2126 /** @} */
2127