Coverage Report

Created: 2026-07-16 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/zoneproperties.c
Line
Count
Source
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
/*! \file */
15
16
#include <isc/async.h>  /* WMM: remove include */
17
#include <isc/random.h> /* WMM: remove include */
18
19
#include <dns/kasp.h>
20
#include <dns/peer.h>
21
#include <dns/request.h>
22
#include <dns/ssu.h>
23
#include <dns/stats.h>
24
#include <dns/view.h>
25
#include <dns/zone.h>
26
#include <dns/zoneproperties.h>
27
28
#include "zone_p.h"
29
30
static void
31
default_journal(dns_zone_t *zone);
32
static void
33
zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
34
static void
35
zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
36
static void
37
zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
38
39
static void
40
0
free_rad_rcu(struct rcu_head *rcu_head) {
41
0
  dns_rad_t *rad = caa_container_of(rcu_head, dns_rad_t, rcu_head);
42
0
  dns_fixedname_invalidate(&rad->fname);
43
44
0
  isc_mem_putanddetach(&rad->mctx, rad, sizeof(*rad));
45
0
}
46
47
/*
48
 *  Single shot.
49
 */
50
void
51
0
dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
52
0
  char namebuf[1024];
53
54
0
  REQUIRE(DNS_ZONE_VALID(zone));
55
0
  REQUIRE(rdclass != dns_rdataclass_none);
56
57
  /*
58
   * Test and set.
59
   */
60
0
  LOCK_ZONE(zone);
61
0
  INSIST(zone != zone->raw);
62
0
  REQUIRE(zone->rdclass == dns_rdataclass_none ||
63
0
    zone->rdclass == rdclass);
64
0
  zone->rdclass = rdclass;
65
66
0
  if (zone->strnamerd != NULL) {
67
0
    isc_mem_free(zone->mctx, zone->strnamerd);
68
0
  }
69
0
  if (zone->strrdclass != NULL) {
70
0
    isc_mem_free(zone->mctx, zone->strrdclass);
71
0
  }
72
73
0
  zone_namerd_tostr(zone, namebuf, sizeof namebuf);
74
0
  zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
75
0
  zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
76
0
  zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
77
78
0
  if (dns__zone_inline_secure(zone)) {
79
0
    dns_zone_setclass(zone->raw, rdclass);
80
0
  }
81
0
  UNLOCK_ZONE(zone);
82
0
}
83
84
dns_rdataclass_t
85
0
dns_zone_getclass(dns_zone_t *zone) {
86
0
  REQUIRE(DNS_ZONE_VALID(zone));
87
88
0
  return zone->rdclass;
89
0
}
90
91
void
92
dns_zone_setnotifytype(dns_zone_t *zone, dns_rdatatype_t type,
93
0
           dns_notifytype_t notifytype) {
94
0
  REQUIRE(DNS_ZONE_VALID(zone));
95
96
0
  LOCK_ZONE(zone);
97
0
  switch (type) {
98
0
  case dns_rdatatype_soa:
99
0
    zone->notifysoa.notifytype = notifytype;
100
0
    break;
101
0
  case dns_rdatatype_cds:
102
0
    INSIST(notifytype == dns_notifytype_no ||
103
0
           notifytype == dns_notifytype_yes);
104
0
    zone->notifycds.notifytype = notifytype;
105
0
    break;
106
0
  default:
107
0
    UNREACHABLE();
108
0
  }
109
0
  UNLOCK_ZONE(zone);
110
0
}
111
112
void
113
0
dns_zone_setcheckdstype(dns_zone_t *zone, dns_checkdstype_t checkdstype) {
114
0
  REQUIRE(DNS_ZONE_VALID(zone));
115
116
0
  LOCK_ZONE(zone);
117
0
  zone->checkdstype = checkdstype;
118
0
  UNLOCK_ZONE(zone);
119
0
}
120
121
/*
122
 *  Single shot.
123
 */
124
void
125
0
dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
126
0
  char namebuf[1024];
127
128
0
  REQUIRE(DNS_ZONE_VALID(zone));
129
0
  REQUIRE(type != dns_zone_none);
130
131
  /*
132
   * Test and set.
133
   */
134
0
  LOCK_ZONE(zone);
135
0
  REQUIRE(zone->type == dns_zone_none || zone->type == type);
136
0
  zone->type = type;
137
138
0
  if (zone->strnamerd != NULL) {
139
0
    isc_mem_free(zone->mctx, zone->strnamerd);
140
0
  }
141
142
0
  zone_namerd_tostr(zone, namebuf, sizeof namebuf);
143
0
  zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
144
0
  UNLOCK_ZONE(zone);
145
0
}
146
147
void
148
0
dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
149
0
  size_t size = 0;
150
0
  unsigned int i;
151
0
  void *mem;
152
0
  char **tmp, *tmp2, *base;
153
154
0
  REQUIRE(DNS_ZONE_VALID(zone));
155
0
  REQUIRE(argv != NULL && *argv == NULL);
156
157
0
  LOCK_ZONE(zone);
158
0
  size = ISC_CHECKED_MUL(zone->db_argc + 1, sizeof(char *));
159
0
  for (i = 0; i < zone->db_argc; i++) {
160
0
    size += strlen(zone->db_argv[i]) + 1;
161
0
  }
162
0
  mem = isc_mem_allocate(mctx, size);
163
0
  {
164
0
    tmp = mem;
165
0
    tmp2 = mem;
166
0
    base = mem;
167
0
    tmp2 += ISC_CHECKED_MUL(zone->db_argc + 1, sizeof(char *));
168
0
    for (i = 0; i < zone->db_argc; i++) {
169
0
      *tmp++ = tmp2;
170
0
      strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
171
0
      tmp2 += strlen(tmp2) + 1;
172
0
    }
173
0
    *tmp = NULL;
174
0
  }
175
0
  UNLOCK_ZONE(zone);
176
0
  *argv = mem;
177
0
}
178
179
void
180
dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc,
181
0
       const char *const *dbargv) {
182
0
  char **argv = NULL;
183
0
  unsigned int i;
184
185
0
  REQUIRE(DNS_ZONE_VALID(zone));
186
0
  REQUIRE(dbargc >= 1);
187
0
  REQUIRE(dbargv != NULL);
188
189
0
  LOCK_ZONE(zone);
190
191
  /* Set up a new database argument list. */
192
0
  argv = isc_mem_cget(zone->mctx, dbargc, sizeof(*argv));
193
0
  for (i = 0; i < dbargc; i++) {
194
0
    argv[i] = NULL;
195
0
  }
196
0
  for (i = 0; i < dbargc; i++) {
197
0
    argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
198
0
  }
199
200
  /* Free the old list. */
201
0
  dns__zone_freedbargs(zone);
202
203
0
  zone->db_argc = dbargc;
204
0
  zone->db_argv = argv;
205
206
0
  UNLOCK_ZONE(zone);
207
0
}
208
209
void
210
0
dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
211
0
  REQUIRE(DNS_ZONE_VALID(zone));
212
213
0
  LOCK_ZONE(zone);
214
0
  dns__zone_setview_helper(zone, view);
215
0
  UNLOCK_ZONE(zone);
216
0
}
217
218
dns_view_t *
219
0
dns_zone_getview(dns_zone_t *zone) {
220
0
  REQUIRE(DNS_ZONE_VALID(zone));
221
222
0
  return zone->view;
223
0
}
224
225
void
226
0
dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
227
0
  char namebuf[1024];
228
229
0
  REQUIRE(DNS_ZONE_VALID(zone));
230
0
  REQUIRE(origin != NULL);
231
232
0
  LOCK_ZONE(zone);
233
0
  INSIST(zone != zone->raw);
234
0
  if (dns_name_dynamic(&zone->origin)) {
235
0
    dns_name_free(&zone->origin, zone->mctx);
236
0
    dns_name_init(&zone->origin);
237
0
  }
238
0
  dns_name_dup(origin, zone->mctx, &zone->origin);
239
240
0
  if (zone->strnamerd != NULL) {
241
0
    isc_mem_free(zone->mctx, zone->strnamerd);
242
0
  }
243
0
  if (zone->strname != NULL) {
244
0
    isc_mem_free(zone->mctx, zone->strname);
245
0
  }
246
247
0
  zone_namerd_tostr(zone, namebuf, sizeof namebuf);
248
0
  zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
249
0
  zone_name_tostr(zone, namebuf, sizeof namebuf);
250
0
  zone->strname = isc_mem_strdup(zone->mctx, namebuf);
251
252
0
  if (dns__zone_inline_secure(zone)) {
253
0
    dns_zone_setorigin(zone->raw, origin);
254
0
  }
255
0
  UNLOCK_ZONE(zone);
256
0
}
257
258
static void
259
0
setstring(dns_zone_t *zone, char **field, const char *value) {
260
0
  char *copy;
261
262
0
  if (value != NULL) {
263
0
    copy = isc_mem_strdup(zone->mctx, value);
264
0
  } else {
265
0
    copy = NULL;
266
0
  }
267
268
0
  if (*field != NULL) {
269
0
    isc_mem_free(zone->mctx, *field);
270
0
  }
271
272
0
  *field = copy;
273
0
}
274
275
typedef struct foundtoken foundtoken_t;
276
typedef struct token_names token_names_t;
277
typedef isc_result_t (*tokenparse_t)(const token_names_t *names,
278
             const foundtoken_t *token,
279
             isc_buffer_t *b);
280
281
struct foundtoken {
282
  const char *pos;
283
  size_t len;
284
  tokenparse_t parse;
285
};
286
287
struct token_names {
288
  dns_name_t *zonename;
289
  const char *viewname;
290
  const char *typename;
291
};
292
293
static int
294
0
foundtoken_order(const void *a, const void *b) {
295
  /* sort char pointers in order of which occurs first in memory */
296
0
  return ((foundtoken_t *)a)->pos - ((foundtoken_t *)b)->pos;
297
0
}
298
299
static isc_result_t
300
0
putmem(isc_buffer_t *b, const char *base, size_t length) {
301
0
  size_t space = isc_buffer_availablelength(b) - 1;
302
0
  if (space < length) {
303
0
    isc_buffer_putmem(b, (const unsigned char *)base, space);
304
0
    return ISC_R_NOSPACE;
305
0
  }
306
307
0
  isc_buffer_putmem(b, (const unsigned char *)base, length);
308
0
  return ISC_R_SUCCESS;
309
0
}
310
311
static isc_result_t
312
tokenparse_type(const token_names_t *names, const foundtoken_t *token,
313
0
    isc_buffer_t *b) {
314
0
  UNUSED(token);
315
316
0
  return putmem(b, names->typename, strlen(names->typename));
317
0
}
318
319
static isc_result_t
320
tokenparse_name(const token_names_t *names,
321
0
    const foundtoken_t *token ISC_ATTR_UNUSED, isc_buffer_t *b) {
322
0
  char name[DNS_NAME_FORMATSIZE];
323
324
0
  dns_name_format(names->zonename, name, sizeof(name));
325
0
  return putmem(b, name, strlen(name));
326
0
}
327
328
static isc_result_t
329
tokenparse_view(const token_names_t *names, const foundtoken_t *token,
330
0
    isc_buffer_t *b) {
331
0
  UNUSED(token);
332
333
0
  return putmem(b, names->viewname, strlen(names->viewname));
334
0
}
335
336
static isc_result_t
337
tokenparse_char(const token_names_t *names, const foundtoken_t *token,
338
0
    isc_buffer_t *b) {
339
0
  char name[DNS_NAME_FORMATSIZE];
340
0
  size_t chartokidx;
341
0
  char c;
342
343
0
  dns_name_format(names->zonename, name, sizeof(name));
344
345
0
  chartokidx = token->pos[token->len - 1] - '1';
346
0
  INSIST(chartokidx <= 2);
347
0
  if (chartokidx < strlen(name)) {
348
0
    c = name[chartokidx];
349
0
  } else {
350
0
    c = '.';
351
0
  }
352
0
  return putmem(b, &c, 1);
353
0
}
354
355
static isc_result_t
356
tokenparse_label(const token_names_t *names, const foundtoken_t *token,
357
0
     isc_buffer_t *b) {
358
0
  isc_result_t result;
359
0
  char buf[DNS_NAME_FORMATSIZE];
360
0
  dns_fixedname_t ft;
361
0
  dns_name_t *target = dns_fixedname_initname(&ft);
362
0
  unsigned int labels;
363
0
  char labeltokidx;
364
0
  int ilabel = -1;
365
366
0
  dns_name_copy(dns_rootname, target);
367
0
  labels = dns_name_countlabels(names->zonename);
368
369
0
  labeltokidx = isc_ascii_tolower(token->pos[token->len - 1]);
370
0
  if (token->len == 2) {
371
    /*
372
     * %z, %y, %x pattern
373
     */
374
0
    INSIST(labeltokidx >= 'x' && labeltokidx <= 'z');
375
0
  } else {
376
    /*
377
     * $label1, $label2, $label3 pattern
378
     */
379
0
    INSIST(labeltokidx >= '1' && labeltokidx <= '3');
380
0
  }
381
382
0
  if (labeltokidx == '1' || labeltokidx == 'z') {
383
0
    ilabel = labels - 1;
384
0
  } else if (labeltokidx == '2' || labeltokidx == 'y') {
385
0
    ilabel = labels - 2;
386
0
  } else if (labeltokidx == '3' || labeltokidx == 'x') {
387
0
    ilabel = labels - 3;
388
0
  }
389
390
0
  if (ilabel >= 0) {
391
0
    dns_name_getlabelsequence(names->zonename, ilabel, 1, target);
392
0
  }
393
0
  dns_name_format(target, buf, sizeof(buf));
394
0
  result = putmem(b, buf, strlen(buf));
395
396
0
  return result;
397
0
}
398
399
typedef struct {
400
  const char *name;
401
  tokenparse_t parse;
402
} token_t;
403
static const token_t tokens[] = {
404
  { "$type", tokenparse_type },  { "$name", tokenparse_name },
405
  { "$view", tokenparse_view },  { "$char1", tokenparse_char },
406
  { "$char2", tokenparse_char },   { "$char3", tokenparse_char },
407
  { "$label1", tokenparse_label }, { "$label2", tokenparse_label },
408
  { "$label3", tokenparse_label }, { "%t", tokenparse_type },
409
  { "%s", tokenparse_name },   { "%v", tokenparse_view },
410
  { "%1", tokenparse_char },   { "%2", tokenparse_char },
411
  { "%3", tokenparse_char },   { "%z", tokenparse_label },
412
  { "%y", tokenparse_label },  { "%x", tokenparse_label }
413
};
414
415
/*
416
 * Set the masterfile field, expanding:
417
 *
418
 *    - $name or "%s" to the zone name
419
 *    - $type or "%t" to the zone type
420
 *    - $view or "%v" to the view name.
421
 *    - $char1 or "%1" to the first character of the zone name
422
 *    - $char2 or "%2" to the second character of the zone name (or a dot if
423
 *      there is no second character)
424
 *    - $char3 or "%3" to the third character of the zone name (or a dot if
425
 *      there is no third character)
426
 *    - $label1 or "%z" to the toplevel domain of the zone (or a dot if it is
427
 *      the TLD)
428
 *    - $label2 or "%y" to the next label under the toplevel domain (or a dot if
429
 *      there is no next label)
430
 *    - $label2 or "%x" to the next-next label under the toplevel domain (or a
431
 *      dot if there is no next-next label)
432
 *
433
 * Cap the length at PATH_MAX.
434
 */
435
void
436
dns_zone_expandzonefile(isc_buffer_t *b, const char *filename,
437
      const dns_name_t *zonename, const char *viewname,
438
0
      const char *typename) {
439
0
  isc_result_t result;
440
0
  foundtoken_t founds[ARRAY_SIZE(tokens)];
441
0
  dns_fixedname_t fz;
442
0
  size_t tags = 0;
443
0
  token_names_t names = { .zonename = dns_fixedname_initname(&fz),
444
0
        .viewname = viewname,
445
0
        .typename = typename };
446
447
0
  REQUIRE(zonename != NULL);
448
0
  REQUIRE(filename != NULL);
449
0
  REQUIRE(typename != NULL);
450
451
0
  if (viewname == NULL) {
452
0
    names.viewname = "";
453
0
  }
454
455
  /* Normalize the name by converting to lower case */
456
0
  result = dns_name_downcase(zonename, names.zonename);
457
0
  INSIST(result == ISC_R_SUCCESS);
458
459
0
  for (size_t i = 0; i < ARRAY_SIZE(tokens); i++) {
460
0
    const token_t *token = &tokens[i];
461
0
    const char *p = strcasestr(filename, token->name);
462
463
0
    if (p != NULL) {
464
0
      founds[tags++] =
465
0
        (foundtoken_t){ .pos = p,
466
0
            .len = strlen(token->name),
467
0
            .parse = token->parse };
468
0
    }
469
0
  }
470
471
0
  if (tags == 0) {
472
0
    putmem(b, filename, strlen(filename));
473
0
    goto cleanup;
474
0
  }
475
476
  /* sort the tag offsets in order of occurrence */
477
0
  qsort(founds, tags, sizeof(foundtoken_t), foundtoken_order);
478
479
0
  const char *p = filename;
480
0
  for (size_t i = 0; i < tags; i++) {
481
0
    foundtoken_t *token = &founds[i];
482
483
0
    CHECK(putmem(b, p, token->pos - p));
484
485
0
    p = token->pos;
486
0
    INSIST(p != NULL);
487
0
    CHECK(token->parse(&names, token, b));
488
489
    /* Advance the input pointer past the token */
490
0
    p += founds[i].len;
491
0
  }
492
493
0
  const char *end = filename + strlen(filename);
494
0
  putmem(b, p, end - p);
495
496
0
cleanup:
497
0
  isc_buffer_putuint8(b, 0);
498
0
}
499
500
static void
501
0
setfilename(dns_zone_t *zone, char **field, const char *value) {
502
0
  char filename[PATH_MAX];
503
0
  isc_buffer_t b;
504
505
0
  if (value == NULL) {
506
0
    *field = NULL;
507
0
    return;
508
0
  }
509
510
0
  isc_buffer_init(&b, filename, sizeof(filename));
511
0
  dns_zone_expandzonefile(&b, value, &zone->origin,
512
0
        zone->view != NULL ? zone->view->name : NULL,
513
0
        dns_zonetype_name(zone->type));
514
0
  setstring(zone, field, filename);
515
0
}
516
517
void
518
dns_zone_setfile(dns_zone_t *zone, const char *file, const char *initial_file,
519
0
     dns_masterformat_t format, const dns_master_style_t *style) {
520
0
  REQUIRE(DNS_ZONE_VALID(zone));
521
0
  REQUIRE(zone->stream == NULL);
522
523
0
  LOCK_ZONE(zone);
524
0
  setfilename(zone, &zone->masterfile, file);
525
0
  setstring(zone, &zone->initfile, initial_file);
526
0
  zone->masterformat = format;
527
0
  if (format == dns_masterformat_text) {
528
0
    zone->masterstyle = style;
529
0
  }
530
0
  default_journal(zone);
531
0
  UNLOCK_ZONE(zone);
532
0
}
533
534
const char *
535
0
dns_zone_getfile(dns_zone_t *zone) {
536
0
  REQUIRE(DNS_ZONE_VALID(zone));
537
538
0
  return zone->masterfile;
539
0
}
540
541
void
542
dns_zone_setstream(dns_zone_t *zone, const FILE *stream,
543
0
       dns_masterformat_t format, const dns_master_style_t *style) {
544
0
  REQUIRE(DNS_ZONE_VALID(zone));
545
0
  REQUIRE(stream != NULL);
546
0
  REQUIRE(zone->masterfile == NULL);
547
548
0
  LOCK_ZONE(zone);
549
0
  zone->stream = stream;
550
0
  zone->masterformat = format;
551
0
  if (format == dns_masterformat_text) {
552
0
    zone->masterstyle = style;
553
0
  }
554
0
  default_journal(zone);
555
0
  UNLOCK_ZONE(zone);
556
0
}
557
558
dns_ttl_t
559
0
dns_zone_getmaxttl(dns_zone_t *zone) {
560
0
  REQUIRE(DNS_ZONE_VALID(zone));
561
562
0
  return zone->maxttl;
563
0
}
564
565
void
566
0
dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
567
0
  REQUIRE(DNS_ZONE_VALID(zone));
568
569
0
  LOCK_ZONE(zone);
570
0
  if (maxttl != 0) {
571
0
    DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL);
572
0
  } else {
573
0
    DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL);
574
0
  }
575
0
  zone->maxttl = maxttl;
576
0
  UNLOCK_ZONE(zone);
577
578
0
  return;
579
0
}
580
581
static void
582
0
default_journal(dns_zone_t *zone) {
583
0
  char *journal;
584
585
0
  REQUIRE(DNS_ZONE_VALID(zone));
586
0
  REQUIRE(LOCKED_ZONE(zone));
587
588
0
  if (zone->masterfile != NULL) {
589
    /* Calculate string length including '\0'. */
590
0
    int len = strlen(zone->masterfile) + sizeof(".jnl");
591
0
    journal = isc_mem_allocate(zone->mctx, len);
592
0
    strlcpy(journal, zone->masterfile, len);
593
0
    strlcat(journal, ".jnl", len);
594
0
  } else {
595
0
    journal = NULL;
596
0
  }
597
0
  setstring(zone, &zone->journal, journal);
598
0
  if (journal != NULL) {
599
0
    isc_mem_free(zone->mctx, journal);
600
0
  }
601
0
}
602
603
void
604
0
dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
605
0
  REQUIRE(DNS_ZONE_VALID(zone));
606
607
0
  LOCK_ZONE(zone);
608
0
  setstring(zone, &zone->journal, myjournal);
609
0
  UNLOCK_ZONE(zone);
610
0
}
611
612
char *
613
0
dns_zone_getjournal(dns_zone_t *zone) {
614
0
  REQUIRE(DNS_ZONE_VALID(zone));
615
616
0
  return zone->journal;
617
0
}
618
619
isc_mem_t *
620
0
dns_zone_getmctx(dns_zone_t *zone) {
621
0
  REQUIRE(DNS_ZONE_VALID(zone));
622
623
0
  return zone->mctx;
624
0
}
625
626
dns_zonemgr_t *
627
0
dns_zone_getmgr(dns_zone_t *zone) {
628
0
  REQUIRE(DNS_ZONE_VALID(zone));
629
630
0
  return zone->zmgr;
631
0
}
632
633
void
634
0
dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) {
635
0
  REQUIRE(DNS_ZONE_VALID(zone));
636
637
0
  LOCK_ZONE(zone);
638
0
  if (zone->kasp != NULL) {
639
0
    dns_kasp_detach(&zone->kasp);
640
0
  }
641
0
  if (kasp != NULL) {
642
0
    dns_kasp_attach(kasp, &zone->kasp);
643
0
  }
644
0
  UNLOCK_ZONE(zone);
645
0
}
646
647
void
648
0
dns_zone_setdefaultkasp(dns_zone_t *zone, dns_kasp_t *kasp) {
649
0
  REQUIRE(DNS_ZONE_VALID(zone));
650
651
0
  LOCK_ZONE(zone);
652
0
  if (zone->defaultkasp != NULL) {
653
0
    dns_kasp_detach(&zone->defaultkasp);
654
0
  }
655
0
  if (kasp != NULL) {
656
0
    dns_kasp_attach(kasp, &zone->defaultkasp);
657
0
  }
658
0
  UNLOCK_ZONE(zone);
659
0
}
660
661
dns_kasp_t *
662
0
dns_zone_getkasp(dns_zone_t *zone) {
663
0
  dns_kasp_t *kasp = NULL;
664
665
0
  REQUIRE(DNS_ZONE_VALID(zone));
666
667
0
  LOCK_ZONE(zone);
668
0
  if (dns__zone_inline_raw(zone) && zone->secure != NULL) {
669
0
    kasp = zone->secure->kasp;
670
0
  } else {
671
0
    kasp = zone->kasp;
672
0
  }
673
0
  UNLOCK_ZONE(zone);
674
675
0
  return kasp;
676
0
}
677
678
void
679
0
dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
680
0
  REQUIRE(DNS_ZONE_VALID(zone));
681
0
  REQUIRE(xfrsource != NULL);
682
683
0
  LOCK_ZONE(zone);
684
0
  zone->xfrsource4 = *xfrsource;
685
0
  UNLOCK_ZONE(zone);
686
0
}
687
688
void
689
0
dns_zone_getxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource) {
690
0
  REQUIRE(DNS_ZONE_VALID(zone));
691
0
  REQUIRE(xfrsource != NULL);
692
693
0
  LOCK_ZONE(zone);
694
0
  *xfrsource = zone->xfrsource4;
695
0
  UNLOCK_ZONE(zone);
696
0
}
697
698
void
699
0
dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
700
0
  REQUIRE(DNS_ZONE_VALID(zone));
701
0
  REQUIRE(xfrsource != NULL);
702
703
0
  LOCK_ZONE(zone);
704
0
  zone->xfrsource6 = *xfrsource;
705
0
  UNLOCK_ZONE(zone);
706
0
}
707
708
void
709
0
dns_zone_getxfrsource6(dns_zone_t *zone, isc_sockaddr_t *xfrsource) {
710
0
  REQUIRE(DNS_ZONE_VALID(zone));
711
0
  REQUIRE(xfrsource != NULL);
712
713
0
  LOCK_ZONE(zone);
714
0
  *xfrsource = zone->xfrsource6;
715
0
  UNLOCK_ZONE(zone);
716
0
}
717
718
void
719
0
dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) {
720
0
  REQUIRE(DNS_ZONE_VALID(zone));
721
0
  REQUIRE(parentalsrc != NULL);
722
723
0
  LOCK_ZONE(zone);
724
0
  zone->parentalsrc4 = *parentalsrc;
725
0
  UNLOCK_ZONE(zone);
726
0
}
727
728
void
729
0
dns_zone_getparentalsrc4(dns_zone_t *zone, isc_sockaddr_t *parentalsrc) {
730
0
  REQUIRE(DNS_ZONE_VALID(zone));
731
0
  REQUIRE(parentalsrc != NULL);
732
733
0
  LOCK_ZONE(zone);
734
0
  *parentalsrc = zone->parentalsrc4;
735
0
  UNLOCK_ZONE(zone);
736
0
}
737
738
void
739
0
dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) {
740
0
  REQUIRE(DNS_ZONE_VALID(zone));
741
742
0
  LOCK_ZONE(zone);
743
0
  zone->parentalsrc6 = *parentalsrc;
744
0
  UNLOCK_ZONE(zone);
745
0
}
746
747
void
748
0
dns_zone_getparentalsrc6(dns_zone_t *zone, isc_sockaddr_t *parentalsrc) {
749
0
  REQUIRE(DNS_ZONE_VALID(zone));
750
0
  REQUIRE(parentalsrc != NULL);
751
752
0
  LOCK_ZONE(zone);
753
0
  *parentalsrc = zone->parentalsrc6;
754
0
  UNLOCK_ZONE(zone);
755
0
}
756
757
void
758
dns_zone_setnotifysrc4(dns_zone_t *zone, dns_rdatatype_t type,
759
0
           const isc_sockaddr_t *notifysrc) {
760
0
  REQUIRE(DNS_ZONE_VALID(zone));
761
0
  REQUIRE(notifysrc != NULL);
762
763
0
  LOCK_ZONE(zone);
764
0
  switch (type) {
765
0
  case dns_rdatatype_soa:
766
0
    zone->notifysoa.notifysrc4 = *notifysrc;
767
0
    break;
768
0
  case dns_rdatatype_cds:
769
0
    zone->notifycds.notifysrc4 = *notifysrc;
770
0
    break;
771
0
  default:
772
0
    UNREACHABLE();
773
0
  }
774
0
  UNLOCK_ZONE(zone);
775
0
}
776
777
void
778
dns_zone_setnotifysrc6(dns_zone_t *zone, dns_rdatatype_t type,
779
0
           const isc_sockaddr_t *notifysrc) {
780
0
  REQUIRE(DNS_ZONE_VALID(zone));
781
0
  REQUIRE(notifysrc != NULL);
782
783
0
  LOCK_ZONE(zone);
784
0
  switch (type) {
785
0
  case dns_rdatatype_soa:
786
0
    zone->notifysoa.notifysrc6 = *notifysrc;
787
0
    break;
788
0
  case dns_rdatatype_cds:
789
0
    zone->notifycds.notifysrc6 = *notifysrc;
790
0
    break;
791
0
  default:
792
0
    UNREACHABLE();
793
0
  }
794
0
  UNLOCK_ZONE(zone);
795
0
}
796
797
static bool
798
0
has_pf(isc_sockaddr_t *addresses, size_t count, int pf) {
799
0
  for (size_t i = 0; i < count; i++) {
800
0
    if (isc_sockaddr_pf(&addresses[i]) == pf) {
801
0
      return true;
802
0
    }
803
0
  }
804
0
  return false;
805
0
}
806
807
static void
808
report_no_active_addresses(dns_zone_t *zone, isc_sockaddr_t *addresses,
809
0
         size_t count, const char *what) {
810
0
  if (isc_net_probeipv4() == ISC_R_DISABLED) {
811
0
    if (!has_pf(addresses, count, AF_INET6)) {
812
0
      dns_zone_log(zone, ISC_LOG_NOTICE,
813
0
             "IPv4 disabled and no IPv6 %s", what);
814
0
    }
815
0
  } else if (isc_net_probeipv6() == ISC_R_DISABLED) {
816
0
    if (!has_pf(addresses, count, AF_INET)) {
817
0
      dns_zone_log(zone, ISC_LOG_NOTICE,
818
0
             "IPv6 disabled and no IPv4 %s", what);
819
0
    }
820
0
  }
821
0
}
822
823
static void
824
setremote(dns_zone_t *zone, dns_remote_t *remote, const char *remotestr,
825
    isc_sockaddr_t *addresses, isc_sockaddr_t *sources,
826
    dns_name_t **keynames, dns_name_t **tlsnames, bool refresh,
827
0
    bool report, uint32_t count) {
828
0
  dns_remote_t newremote;
829
830
0
  REQUIRE(DNS_ZONE_VALID(zone));
831
0
  REQUIRE(DNS_REMOTE_VALID(remote));
832
833
0
  newremote.magic = DNS_REMOTE_MAGIC;
834
0
  newremote.addresses = addresses;
835
0
  newremote.sources = sources;
836
0
  newremote.keynames = keynames;
837
0
  newremote.tlsnames = tlsnames;
838
0
  newremote.addrcnt = count;
839
840
0
  if (dns_remote_equal(remote, &newremote)) {
841
0
    return;
842
0
  }
843
844
  /*
845
   * The refresh code assumes that 'servers' wouldn't change under it.
846
   * If it will change then kill off any current refresh in progress
847
   * and update the primaries info.  If it won't change then we can just
848
   * unlock and exit.
849
   */
850
0
  if (zone->request != NULL && refresh) {
851
0
    dns_request_cancel(zone->request);
852
0
  }
853
854
0
  dns_remote_clear(remote);
855
856
  /*
857
   * If count == 0, don't allocate any space for servers.
858
   */
859
0
  if (count == 0) {
860
0
    return;
861
0
  }
862
863
  /*
864
   * Now set up the address and key lists.
865
   */
866
0
  if (report) {
867
0
    report_no_active_addresses(zone, addresses, count, remotestr);
868
0
  }
869
870
0
  dns_remote_init(remote, count, addresses, sources, keynames, tlsnames,
871
0
      true, zone->mctx);
872
0
}
873
874
void
875
dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses,
876
           isc_sockaddr_t *sources, dns_name_t **keynames,
877
0
           dns_name_t **tlsnames, uint32_t count) {
878
0
  bool refresh = false;
879
0
  bool report = false;
880
881
0
  LOCK_ZONE(zone);
882
0
  setremote(zone, &zone->alsonotify, "also-notify", addresses, sources,
883
0
      keynames, tlsnames, refresh, report, count);
884
0
  UNLOCK_ZONE(zone);
885
0
}
886
887
void
888
dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses,
889
          isc_sockaddr_t *sources, dns_name_t **keynames,
890
0
          dns_name_t **tlsnames, uint32_t count) {
891
0
  bool refresh = true;
892
0
  bool report = true;
893
894
0
  LOCK_ZONE(zone);
895
0
  setremote(zone, &zone->primaries, "primaries", addresses, sources,
896
0
      keynames, tlsnames, refresh, report, count);
897
0
  DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES);
898
0
  UNLOCK_ZONE(zone);
899
0
}
900
901
void
902
dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses,
903
          isc_sockaddr_t *sources, dns_name_t **keynames,
904
0
          dns_name_t **tlsnames, uint32_t count) {
905
0
  bool refresh = false;
906
0
  bool report = true;
907
908
0
  LOCK_ZONE(zone);
909
0
  setremote(zone, &zone->parentals, "parental-agents", addresses, sources,
910
0
      keynames, tlsnames, refresh, report, count);
911
0
  UNLOCK_ZONE(zone);
912
0
}
913
914
void
915
dns_zone_setcdsendpoints(dns_zone_t *zone, isc_sockaddr_t *addresses,
916
       isc_sockaddr_t *sources, dns_name_t **keynames,
917
0
       dns_name_t **tlsnames, uint32_t count) {
918
0
  bool refresh = false;
919
0
  bool report = false;
920
921
0
  LOCK_ZONE(zone);
922
0
  setremote(zone, &zone->cds_endpoints, "cds-endpoints", addresses,
923
0
      sources, keynames, tlsnames, refresh, report, count);
924
0
  UNLOCK_ZONE(zone);
925
0
}
926
927
isc_result_t
928
0
dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
929
0
  isc_result_t result = ISC_R_SUCCESS;
930
931
0
  REQUIRE(DNS_ZONE_VALID(zone));
932
933
0
  ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
934
0
  if (zone->db == NULL) {
935
0
    result = DNS_R_NOTLOADED;
936
0
  } else {
937
0
    dns_db_attach(zone->db, dpb);
938
0
  }
939
0
  ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
940
941
0
  return result;
942
0
}
943
944
void
945
0
dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
946
0
  REQUIRE(DNS_ZONE_VALID(zone));
947
0
  REQUIRE(zone->type == dns_zone_staticstub);
948
949
0
  ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
950
0
  REQUIRE(zone->db == NULL);
951
0
  dns_db_attach(db, &zone->db);
952
0
  ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
953
0
}
954
955
void
956
0
dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
957
0
  REQUIRE(DNS_ZONE_VALID(zone));
958
0
  REQUIRE(val > 0);
959
960
0
  zone->minrefresh = val;
961
0
}
962
963
void
964
0
dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
965
0
  REQUIRE(DNS_ZONE_VALID(zone));
966
0
  REQUIRE(val > 0);
967
968
0
  zone->maxrefresh = val;
969
0
}
970
971
void
972
0
dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
973
0
  REQUIRE(DNS_ZONE_VALID(zone));
974
0
  REQUIRE(val > 0);
975
976
0
  zone->minretry = val;
977
0
}
978
979
void
980
0
dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
981
0
  REQUIRE(DNS_ZONE_VALID(zone));
982
0
  REQUIRE(val > 0);
983
984
0
  zone->maxretry = val;
985
0
}
986
987
uint32_t
988
0
dns_zone_getmaxrecords(dns_zone_t *zone) {
989
0
  REQUIRE(DNS_ZONE_VALID(zone));
990
991
0
  return zone->maxrecords;
992
0
}
993
994
void
995
0
dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
996
0
  REQUIRE(DNS_ZONE_VALID(zone));
997
998
0
  zone->maxrecords = val;
999
0
}
1000
1001
void
1002
0
dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) {
1003
0
  REQUIRE(DNS_ZONE_VALID(zone));
1004
1005
0
  zone->maxrrperset = val;
1006
0
  if (zone->db != NULL) {
1007
0
    dns_db_setmaxrrperset(zone->db, val);
1008
0
  }
1009
0
}
1010
1011
void
1012
0
dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t val) {
1013
0
  REQUIRE(DNS_ZONE_VALID(zone));
1014
1015
0
  zone->maxtypepername = val;
1016
0
  if (zone->db != NULL) {
1017
0
    dns_db_setmaxtypepername(zone->db, val);
1018
0
  }
1019
0
}
1020
1021
void
1022
0
dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
1023
0
  REQUIRE(DNS_ZONE_VALID(zone));
1024
1025
0
  dns_zone_clearnotifyacl(zone);
1026
1027
0
  LOCK_ZONE(zone);
1028
0
  dns_acl_attach(acl, &zone->notifysoa.notify_acl);
1029
0
  dns_acl_attach(acl, &zone->notifycds.notify_acl);
1030
0
  UNLOCK_ZONE(zone);
1031
0
}
1032
1033
void
1034
0
dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
1035
0
  REQUIRE(DNS_ZONE_VALID(zone));
1036
1037
0
  dns_zone_clearqueryacl(zone);
1038
1039
0
  LOCK_ZONE(zone);
1040
0
  dns_acl_attach(acl, &zone->query_acl);
1041
0
  UNLOCK_ZONE(zone);
1042
0
}
1043
1044
void
1045
0
dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
1046
0
  REQUIRE(DNS_ZONE_VALID(zone));
1047
1048
0
  dns_zone_clearqueryonacl(zone);
1049
1050
0
  LOCK_ZONE(zone);
1051
0
  dns_acl_attach(acl, &zone->queryon_acl);
1052
0
  UNLOCK_ZONE(zone);
1053
0
}
1054
1055
void
1056
0
dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
1057
0
  REQUIRE(DNS_ZONE_VALID(zone));
1058
1059
0
  dns_zone_clearupdateacl(zone);
1060
1061
0
  LOCK_ZONE(zone);
1062
0
  dns_acl_attach(acl, &zone->update_acl);
1063
0
  UNLOCK_ZONE(zone);
1064
0
}
1065
1066
void
1067
0
dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
1068
0
  REQUIRE(DNS_ZONE_VALID(zone));
1069
1070
0
  dns_zone_clearforwardacl(zone);
1071
1072
0
  LOCK_ZONE(zone);
1073
0
  dns_acl_attach(acl, &zone->forward_acl);
1074
0
  UNLOCK_ZONE(zone);
1075
0
}
1076
1077
void
1078
0
dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
1079
0
  REQUIRE(DNS_ZONE_VALID(zone));
1080
1081
0
  dns_zone_clearxfracl(zone);
1082
1083
0
  LOCK_ZONE(zone);
1084
0
  dns_acl_attach(acl, &zone->xfr_acl);
1085
0
  UNLOCK_ZONE(zone);
1086
0
}
1087
1088
dns_acl_t *
1089
0
dns_zone_getqueryacl(dns_zone_t *zone) {
1090
0
  REQUIRE(DNS_ZONE_VALID(zone));
1091
1092
0
  return zone->query_acl;
1093
0
}
1094
1095
dns_acl_t *
1096
0
dns_zone_getqueryonacl(dns_zone_t *zone) {
1097
0
  REQUIRE(DNS_ZONE_VALID(zone));
1098
1099
0
  return zone->queryon_acl;
1100
0
}
1101
1102
dns_acl_t *
1103
0
dns_zone_getupdateacl(dns_zone_t *zone) {
1104
0
  REQUIRE(DNS_ZONE_VALID(zone));
1105
1106
0
  return zone->update_acl;
1107
0
}
1108
1109
dns_acl_t *
1110
0
dns_zone_getforwardacl(dns_zone_t *zone) {
1111
0
  REQUIRE(DNS_ZONE_VALID(zone));
1112
1113
0
  return zone->forward_acl;
1114
0
}
1115
1116
dns_acl_t *
1117
0
dns_zone_getxfracl(dns_zone_t *zone) {
1118
0
  REQUIRE(DNS_ZONE_VALID(zone));
1119
1120
0
  return zone->xfr_acl;
1121
0
}
1122
1123
void
1124
0
dns_zone_clearupdateacl(dns_zone_t *zone) {
1125
0
  REQUIRE(DNS_ZONE_VALID(zone));
1126
1127
0
  LOCK_ZONE(zone);
1128
0
  if (zone->update_acl != NULL) {
1129
0
    dns_acl_detach(&zone->update_acl);
1130
0
  }
1131
0
  UNLOCK_ZONE(zone);
1132
0
}
1133
1134
void
1135
0
dns_zone_clearforwardacl(dns_zone_t *zone) {
1136
0
  REQUIRE(DNS_ZONE_VALID(zone));
1137
1138
0
  LOCK_ZONE(zone);
1139
0
  if (zone->forward_acl != NULL) {
1140
0
    dns_acl_detach(&zone->forward_acl);
1141
0
  }
1142
0
  UNLOCK_ZONE(zone);
1143
0
}
1144
1145
void
1146
0
dns_zone_clearnotifyacl(dns_zone_t *zone) {
1147
0
  REQUIRE(DNS_ZONE_VALID(zone));
1148
1149
0
  LOCK_ZONE(zone);
1150
0
  if (zone->notifysoa.notify_acl != NULL) {
1151
0
    dns_acl_detach(&zone->notifysoa.notify_acl);
1152
0
  }
1153
0
  if (zone->notifycds.notify_acl != NULL) {
1154
0
    dns_acl_detach(&zone->notifycds.notify_acl);
1155
0
  }
1156
0
  UNLOCK_ZONE(zone);
1157
0
}
1158
1159
void
1160
0
dns_zone_clearqueryacl(dns_zone_t *zone) {
1161
0
  REQUIRE(DNS_ZONE_VALID(zone));
1162
1163
0
  LOCK_ZONE(zone);
1164
0
  if (zone->query_acl != NULL) {
1165
0
    dns_acl_detach(&zone->query_acl);
1166
0
  }
1167
0
  UNLOCK_ZONE(zone);
1168
0
}
1169
1170
void
1171
0
dns_zone_clearqueryonacl(dns_zone_t *zone) {
1172
0
  REQUIRE(DNS_ZONE_VALID(zone));
1173
1174
0
  LOCK_ZONE(zone);
1175
0
  if (zone->queryon_acl != NULL) {
1176
0
    dns_acl_detach(&zone->queryon_acl);
1177
0
  }
1178
0
  UNLOCK_ZONE(zone);
1179
0
}
1180
1181
void
1182
0
dns_zone_clearxfracl(dns_zone_t *zone) {
1183
0
  REQUIRE(DNS_ZONE_VALID(zone));
1184
1185
0
  LOCK_ZONE(zone);
1186
0
  if (zone->xfr_acl != NULL) {
1187
0
    dns_acl_detach(&zone->xfr_acl);
1188
0
  }
1189
0
  UNLOCK_ZONE(zone);
1190
0
}
1191
1192
bool
1193
0
dns_zone_getupdatedisabled(dns_zone_t *zone) {
1194
0
  REQUIRE(DNS_ZONE_VALID(zone));
1195
0
  return zone->update_disabled;
1196
0
}
1197
1198
void
1199
0
dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
1200
0
  REQUIRE(DNS_ZONE_VALID(zone));
1201
0
  zone->update_disabled = state;
1202
0
}
1203
1204
bool
1205
0
dns_zone_getzeronosoattl(dns_zone_t *zone) {
1206
0
  REQUIRE(DNS_ZONE_VALID(zone));
1207
0
  return zone->zero_no_soa_ttl;
1208
0
}
1209
1210
void
1211
0
dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
1212
0
  REQUIRE(DNS_ZONE_VALID(zone));
1213
0
  zone->zero_no_soa_ttl = state;
1214
0
}
1215
1216
void
1217
0
dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
1218
0
  REQUIRE(DNS_ZONE_VALID(zone));
1219
1220
0
  zone->check_names = severity;
1221
0
}
1222
1223
dns_severity_t
1224
0
dns_zone_getchecknames(dns_zone_t *zone) {
1225
0
  REQUIRE(DNS_ZONE_VALID(zone));
1226
1227
0
  return zone->check_names;
1228
0
}
1229
1230
void
1231
0
dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
1232
0
  REQUIRE(DNS_ZONE_VALID(zone));
1233
1234
0
  zone->journalsize = size;
1235
0
}
1236
1237
int32_t
1238
0
dns_zone_getjournalsize(dns_zone_t *zone) {
1239
0
  REQUIRE(DNS_ZONE_VALID(zone));
1240
1241
0
  return zone->journalsize;
1242
0
}
1243
1244
static void
1245
0
zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
1246
0
  isc_result_t result = ISC_R_FAILURE;
1247
0
  isc_buffer_t buffer;
1248
1249
0
  REQUIRE(buf != NULL);
1250
0
  REQUIRE(length > 1U);
1251
1252
  /*
1253
   * Leave space for terminating '\0'.
1254
   */
1255
0
  isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
1256
0
  if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
1257
0
    if (dns_name_dynamic(&zone->origin)) {
1258
0
      result = dns_name_totext(
1259
0
        &zone->origin, DNS_NAME_OMITFINALDOT, &buffer);
1260
0
    }
1261
0
    if (result != ISC_R_SUCCESS &&
1262
0
        isc_buffer_availablelength(&buffer) >=
1263
0
          (sizeof("<UNKNOWN>") - 1))
1264
0
    {
1265
0
      isc_buffer_putstr(&buffer, "<UNKNOWN>");
1266
0
    }
1267
1268
0
    if (isc_buffer_availablelength(&buffer) > 0) {
1269
0
      isc_buffer_putstr(&buffer, "/");
1270
0
    }
1271
0
    (void)dns_rdataclass_totext(zone->rdclass, &buffer);
1272
0
  }
1273
1274
0
  if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
1275
0
      strcmp(zone->view->name, "_default") != 0 &&
1276
0
      strlen(zone->view->name) < isc_buffer_availablelength(&buffer))
1277
0
  {
1278
0
    isc_buffer_putstr(&buffer, "/");
1279
0
    isc_buffer_putstr(&buffer, zone->view->name);
1280
0
  }
1281
0
  if (dns__zone_inline_secure(zone) &&
1282
0
      9U < isc_buffer_availablelength(&buffer))
1283
0
  {
1284
0
    isc_buffer_putstr(&buffer, " (signed)");
1285
0
  }
1286
0
  if (dns__zone_inline_raw(zone) &&
1287
0
      11U < isc_buffer_availablelength(&buffer))
1288
0
  {
1289
0
    isc_buffer_putstr(&buffer, " (unsigned)");
1290
0
  }
1291
1292
0
  buf[isc_buffer_usedlength(&buffer)] = '\0';
1293
0
}
1294
1295
static void
1296
0
zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
1297
0
  isc_result_t result = ISC_R_FAILURE;
1298
0
  isc_buffer_t buffer;
1299
1300
0
  REQUIRE(buf != NULL);
1301
0
  REQUIRE(length > 1U);
1302
1303
  /*
1304
   * Leave space for terminating '\0'.
1305
   */
1306
0
  isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
1307
0
  if (dns_name_dynamic(&zone->origin)) {
1308
0
    result = dns_name_totext(&zone->origin, DNS_NAME_OMITFINALDOT,
1309
0
           &buffer);
1310
0
  }
1311
0
  if (result != ISC_R_SUCCESS &&
1312
0
      isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
1313
0
  {
1314
0
    isc_buffer_putstr(&buffer, "<UNKNOWN>");
1315
0
  }
1316
1317
0
  buf[isc_buffer_usedlength(&buffer)] = '\0';
1318
0
}
1319
1320
static void
1321
0
zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
1322
0
  isc_buffer_t buffer;
1323
1324
0
  REQUIRE(buf != NULL);
1325
0
  REQUIRE(length > 1U);
1326
1327
  /*
1328
   * Leave space for terminating '\0'.
1329
   */
1330
0
  isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
1331
0
  (void)dns_rdataclass_totext(zone->rdclass, &buffer);
1332
1333
0
  buf[isc_buffer_usedlength(&buffer)] = '\0';
1334
0
}
1335
1336
void
1337
0
dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
1338
0
  REQUIRE(DNS_ZONE_VALID(zone));
1339
0
  REQUIRE(buf != NULL);
1340
1341
0
  LOCK_ZONE(zone);
1342
0
  zone_namerd_tostr(zone, buf, length);
1343
0
  UNLOCK_ZONE(zone);
1344
0
}
1345
1346
void
1347
0
dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
1348
0
  REQUIRE(DNS_ZONE_VALID(zone));
1349
0
  REQUIRE(buf != NULL);
1350
0
  zone_name_tostr(zone, buf, length);
1351
0
}
1352
1353
void
1354
0
dns_zone_setminxfrratein(dns_zone_t *zone, uint32_t bytes, uint32_t seconds) {
1355
0
  REQUIRE(DNS_ZONE_VALID(zone));
1356
1357
0
  zone->minxfrratebytesin = bytes;
1358
0
  zone->minxfrratesecondsin = seconds;
1359
0
}
1360
1361
uint32_t
1362
0
dns_zone_getminxfrratebytesin(dns_zone_t *zone) {
1363
0
  REQUIRE(DNS_ZONE_VALID(zone));
1364
1365
0
  return zone->minxfrratebytesin;
1366
0
}
1367
1368
uint32_t
1369
0
dns_zone_getminxfrratesecondsin(dns_zone_t *zone) {
1370
0
  REQUIRE(DNS_ZONE_VALID(zone));
1371
1372
0
  return zone->minxfrratesecondsin;
1373
0
}
1374
1375
void
1376
0
dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
1377
0
  REQUIRE(DNS_ZONE_VALID(zone));
1378
1379
0
  zone->maxxfrin = maxxfrin;
1380
0
}
1381
1382
uint32_t
1383
0
dns_zone_getmaxxfrin(dns_zone_t *zone) {
1384
0
  REQUIRE(DNS_ZONE_VALID(zone));
1385
1386
0
  return zone->maxxfrin;
1387
0
}
1388
1389
void
1390
0
dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
1391
0
  REQUIRE(DNS_ZONE_VALID(zone));
1392
0
  zone->maxxfrout = maxxfrout;
1393
0
}
1394
1395
uint32_t
1396
0
dns_zone_getmaxxfrout(dns_zone_t *zone) {
1397
0
  REQUIRE(DNS_ZONE_VALID(zone));
1398
1399
0
  return zone->maxxfrout;
1400
0
}
1401
1402
dns_zonetype_t
1403
0
dns_zone_gettype(dns_zone_t *zone) {
1404
0
  REQUIRE(DNS_ZONE_VALID(zone));
1405
1406
0
  return zone->type;
1407
0
}
1408
1409
dns_name_t *
1410
0
dns_zone_getorigin(dns_zone_t *zone) {
1411
0
  REQUIRE(DNS_ZONE_VALID(zone));
1412
1413
0
  return &zone->origin;
1414
0
}
1415
1416
void
1417
0
dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
1418
0
  REQUIRE(DNS_ZONE_VALID(zone));
1419
1420
0
  if (idlein == 0) {
1421
0
    idlein = DNS_DEFAULT_IDLEIN;
1422
0
  }
1423
0
  zone->idlein = idlein;
1424
0
}
1425
1426
uint32_t
1427
0
dns_zone_getidlein(dns_zone_t *zone) {
1428
0
  REQUIRE(DNS_ZONE_VALID(zone));
1429
1430
0
  return zone->idlein;
1431
0
}
1432
1433
void
1434
0
dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
1435
0
  REQUIRE(DNS_ZONE_VALID(zone));
1436
1437
0
  zone->idleout = idleout;
1438
0
}
1439
1440
uint32_t
1441
0
dns_zone_getidleout(dns_zone_t *zone) {
1442
0
  REQUIRE(DNS_ZONE_VALID(zone));
1443
1444
0
  return zone->idleout;
1445
0
}
1446
1447
void
1448
0
dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
1449
0
  REQUIRE(DNS_ZONE_VALID(zone));
1450
0
  REQUIRE(table != NULL);
1451
0
  REQUIRE(*table == NULL);
1452
1453
0
  LOCK_ZONE(zone);
1454
0
  if (zone->ssutable != NULL) {
1455
0
    dns_ssutable_attach(zone->ssutable, table);
1456
0
  }
1457
0
  UNLOCK_ZONE(zone);
1458
0
}
1459
1460
void
1461
0
dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
1462
0
  REQUIRE(DNS_ZONE_VALID(zone));
1463
1464
0
  LOCK_ZONE(zone);
1465
0
  if (zone->ssutable != NULL) {
1466
0
    dns_ssutable_detach(&zone->ssutable);
1467
0
  }
1468
0
  if (table != NULL) {
1469
0
    dns_ssutable_attach(table, &zone->ssutable);
1470
0
  }
1471
0
  UNLOCK_ZONE(zone);
1472
0
}
1473
1474
void
1475
0
dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
1476
0
  REQUIRE(DNS_ZONE_VALID(zone));
1477
1478
0
  zone->sigvalidityinterval = interval;
1479
0
}
1480
1481
uint32_t
1482
0
dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
1483
0
  REQUIRE(DNS_ZONE_VALID(zone));
1484
1485
0
  return zone->sigvalidityinterval;
1486
0
}
1487
1488
void
1489
0
dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
1490
0
  REQUIRE(DNS_ZONE_VALID(zone));
1491
1492
0
  zone->keyvalidityinterval = interval;
1493
0
}
1494
1495
uint32_t
1496
0
dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
1497
0
  REQUIRE(DNS_ZONE_VALID(zone));
1498
1499
0
  return zone->keyvalidityinterval;
1500
0
}
1501
1502
void
1503
0
dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
1504
0
  REQUIRE(DNS_ZONE_VALID(zone));
1505
1506
0
  LOCK_ZONE(zone);
1507
0
  zone->sigresigninginterval = interval;
1508
0
  dns__zone_set_resigntime(zone);
1509
0
  if (zone->loop != NULL) {
1510
0
    dns__zone_settimer(zone, isc_time_now());
1511
0
  }
1512
0
  UNLOCK_ZONE(zone);
1513
0
}
1514
1515
uint32_t
1516
0
dns_zone_getsigresigninginterval(dns_zone_t *zone) {
1517
0
  REQUIRE(DNS_ZONE_VALID(zone));
1518
1519
0
  return zone->sigresigninginterval;
1520
0
}
1521
1522
void
1523
0
dns_zone_getsourceaddr(dns_zone_t *zone, isc_sockaddr_t *sourceaddr) {
1524
0
  REQUIRE(DNS_ZONE_VALID(zone));
1525
0
  REQUIRE(sourceaddr != NULL);
1526
1527
0
  LOCK_ZONE(zone);
1528
0
  INSIST(dns_remote_count(&zone->primaries) > 0);
1529
0
  *sourceaddr = zone->sourceaddr;
1530
0
  UNLOCK_ZONE(zone);
1531
0
}
1532
1533
isc_result_t
1534
0
dns_zone_getprimaryaddr(dns_zone_t *zone, isc_sockaddr_t *primaryaddr) {
1535
0
  isc_result_t result = ISC_R_NOMORE;
1536
1537
0
  REQUIRE(DNS_ZONE_VALID(zone));
1538
0
  REQUIRE(primaryaddr != NULL);
1539
1540
0
  LOCK_ZONE(zone);
1541
0
  INSIST(dns_remote_count(&zone->primaries) > 0);
1542
0
  if (!dns_remote_done(&zone->primaries)) {
1543
0
    *primaryaddr = dns_remote_curraddr(&zone->primaries);
1544
0
    result = ISC_R_SUCCESS;
1545
0
  }
1546
0
  UNLOCK_ZONE(zone);
1547
1548
0
  return result;
1549
0
}
1550
1551
isc_time_t
1552
0
dns_zone_getxfrintime(dns_zone_t *zone) {
1553
0
  isc_time_t xfrintime;
1554
1555
0
  REQUIRE(DNS_ZONE_VALID(zone));
1556
1557
0
  LOCK_ZONE(zone);
1558
0
  xfrintime = zone->xfrintime;
1559
0
  UNLOCK_ZONE(zone);
1560
1561
0
  return xfrintime;
1562
0
}
1563
1564
void
1565
0
dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
1566
0
  REQUIRE(DNS_ZONE_VALID(zone));
1567
0
  REQUIRE(zone->stats == NULL);
1568
1569
0
  LOCK_ZONE(zone);
1570
0
  zone->stats = NULL;
1571
0
  isc_stats_attach(stats, &zone->stats);
1572
0
  UNLOCK_ZONE(zone);
1573
0
}
1574
1575
void
1576
0
dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
1577
0
  REQUIRE(DNS_ZONE_VALID(zone));
1578
1579
0
  LOCK_ZONE(zone);
1580
0
  if (zone->requeststats_on && stats == NULL) {
1581
0
    zone->requeststats_on = false;
1582
0
  } else if (!zone->requeststats_on && stats != NULL) {
1583
0
    if (zone->requeststats == NULL) {
1584
0
      isc_stats_attach(stats, &zone->requeststats);
1585
0
    }
1586
0
    zone->requeststats_on = true;
1587
0
  }
1588
0
  UNLOCK_ZONE(zone);
1589
0
}
1590
1591
void
1592
0
dns_zone_setrcvquerystats(dns_zone_t *zone, isc_statsmulti_t *stats) {
1593
0
  REQUIRE(DNS_ZONE_VALID(zone));
1594
1595
0
  LOCK_ZONE(zone);
1596
0
  if (zone->requeststats_on && stats != NULL) {
1597
0
    if (zone->rcvquerystats == NULL) {
1598
0
      isc_statsmulti_attach(stats, &zone->rcvquerystats);
1599
0
      zone->requeststats_on = true;
1600
0
    }
1601
0
  }
1602
0
  UNLOCK_ZONE(zone);
1603
0
}
1604
1605
void
1606
0
dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
1607
0
  REQUIRE(DNS_ZONE_VALID(zone));
1608
1609
0
  LOCK_ZONE(zone);
1610
0
  if (stats != NULL && zone->dnssecsignstats == NULL) {
1611
0
    dns_stats_attach(stats, &zone->dnssecsignstats);
1612
0
  }
1613
0
  UNLOCK_ZONE(zone);
1614
0
}
1615
1616
dns_stats_t *
1617
0
dns_zone_getdnssecsignstats(dns_zone_t *zone) {
1618
0
  REQUIRE(DNS_ZONE_VALID(zone));
1619
1620
0
  return zone->dnssecsignstats;
1621
0
}
1622
1623
isc_stats_t *
1624
0
dns_zone_getrequeststats(dns_zone_t *zone) {
1625
  /*
1626
   * We don't lock zone for efficiency reason.  This is not catastrophic
1627
   * because requeststats must always be valid when requeststats_on is
1628
   * true.
1629
   * Some counters may be incremented while requeststats_on is becoming
1630
   * false, or some cannot be incremented just after the statistics are
1631
   * installed, but it shouldn't matter much in practice.
1632
   */
1633
0
  if (zone->requeststats_on) {
1634
0
    return zone->requeststats;
1635
0
  } else {
1636
0
    return NULL;
1637
0
  }
1638
0
}
1639
1640
/*
1641
 * Return the received query stats bucket
1642
 * see note from dns_zone_getrequeststats()
1643
 */
1644
isc_statsmulti_t *
1645
0
dns_zone_getrcvquerystats(dns_zone_t *zone) {
1646
0
  if (zone->requeststats_on) {
1647
0
    return zone->rcvquerystats;
1648
0
  } else {
1649
0
    return NULL;
1650
0
  }
1651
0
}
1652
1653
void
1654
0
dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
1655
0
  REQUIRE(DNS_ZONE_VALID(zone));
1656
1657
0
  LOCK_ZONE(zone);
1658
0
  setstring(zone, &zone->keydirectory, directory);
1659
0
  UNLOCK_ZONE(zone);
1660
0
}
1661
1662
const char *
1663
0
dns_zone_getkeydirectory(dns_zone_t *zone) {
1664
0
  REQUIRE(DNS_ZONE_VALID(zone));
1665
1666
0
  return zone->keydirectory;
1667
0
}
1668
1669
void
1670
0
dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
1671
0
  REQUIRE(DNS_ZONE_VALID(zone));
1672
0
  zone->checkmx = checkmx;
1673
0
}
1674
1675
void
1676
0
dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
1677
0
  REQUIRE(DNS_ZONE_VALID(zone));
1678
0
  zone->checksrv = checksrv;
1679
0
}
1680
1681
void
1682
0
dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
1683
0
  REQUIRE(DNS_ZONE_VALID(zone));
1684
0
  zone->checkns = checkns;
1685
0
}
1686
1687
void
1688
dns_zone_setcheckisservedby(dns_zone_t *zone,
1689
0
          dns_checkisservedbyfunc_t checkisservedby) {
1690
0
  REQUIRE(DNS_ZONE_VALID(zone));
1691
0
  zone->checkisservedby = checkisservedby;
1692
0
}
1693
1694
void
1695
0
dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
1696
0
  REQUIRE(DNS_ZONE_VALID(zone));
1697
1698
0
  LOCK_ZONE(zone);
1699
0
  zone->isself = isself;
1700
0
  zone->isselfarg = arg;
1701
0
  UNLOCK_ZONE(zone);
1702
0
}
1703
1704
void
1705
0
dns__zone_getisself(dns_zone_t *zone, dns_isselffunc_t *isself, void **arg) {
1706
0
  REQUIRE(DNS_ZONE_VALID(zone));
1707
0
  REQUIRE(isself != NULL);
1708
0
  REQUIRE(arg != NULL && *arg == NULL);
1709
1710
0
  *isself = zone->isself;
1711
0
  *arg = zone->isselfarg;
1712
0
}
1713
1714
void
1715
dns_zone_setnotifydefer(dns_zone_t *zone, dns_rdatatype_t type,
1716
0
      uint32_t defer) {
1717
0
  REQUIRE(DNS_ZONE_VALID(zone));
1718
1719
0
  LOCK_ZONE(zone);
1720
0
  switch (type) {
1721
0
  case dns_rdatatype_soa:
1722
0
    zone->notifysoa.notifydefer = defer;
1723
0
    break;
1724
0
  case dns_rdatatype_cds:
1725
    /* not applicable to NOTIFY(CDS), unused */
1726
0
    zone->notifycds.notifydefer = defer;
1727
0
    break;
1728
0
  default:
1729
0
    UNREACHABLE();
1730
0
  }
1731
0
  UNLOCK_ZONE(zone);
1732
0
}
1733
1734
void
1735
dns_zone_setnotifydelay(dns_zone_t *zone, dns_rdatatype_t type,
1736
0
      uint32_t delay) {
1737
0
  REQUIRE(DNS_ZONE_VALID(zone));
1738
1739
0
  LOCK_ZONE(zone);
1740
0
  switch (type) {
1741
0
  case dns_rdatatype_soa:
1742
0
    zone->notifysoa.notifydelay = delay;
1743
0
    break;
1744
0
  case dns_rdatatype_cds:
1745
    /* not applicable to NOTIFY(CDS), unused */
1746
0
    zone->notifycds.notifydelay = delay;
1747
0
    break;
1748
0
  default:
1749
0
    UNREACHABLE();
1750
0
  }
1751
0
  UNLOCK_ZONE(zone);
1752
0
}
1753
1754
void
1755
0
dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
1756
0
  REQUIRE(DNS_ZONE_VALID(zone));
1757
1758
0
  if (nodes == 0) {
1759
0
    nodes = 1;
1760
0
  }
1761
0
  zone->nodes = nodes;
1762
0
}
1763
1764
void
1765
0
dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
1766
0
  REQUIRE(DNS_ZONE_VALID(zone));
1767
1768
  /*
1769
   * We treat signatures as a signed value so explicitly
1770
   * limit its range here.
1771
   */
1772
0
  if (signatures > INT32_MAX) {
1773
0
    signatures = INT32_MAX;
1774
0
  } else if (signatures == 0) {
1775
0
    signatures = 1;
1776
0
  }
1777
0
  zone->signatures = signatures;
1778
0
}
1779
1780
uint32_t
1781
0
dns_zone_getsignatures(dns_zone_t *zone) {
1782
0
  REQUIRE(DNS_ZONE_VALID(zone));
1783
0
  return zone->signatures;
1784
0
}
1785
1786
void
1787
0
dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
1788
0
  REQUIRE(DNS_ZONE_VALID(zone));
1789
0
  zone->privatetype = type;
1790
0
}
1791
1792
dns_rdatatype_t
1793
0
dns_zone_getprivatetype(dns_zone_t *zone) {
1794
0
  REQUIRE(DNS_ZONE_VALID(zone));
1795
0
  return zone->privatetype;
1796
0
}
1797
1798
void
1799
0
dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
1800
0
  REQUIRE(DNS_ZONE_VALID(zone));
1801
1802
0
  LOCK_ZONE(zone);
1803
0
  zone->automatic = automatic;
1804
0
  UNLOCK_ZONE(zone);
1805
0
}
1806
1807
bool
1808
0
dns_zone_getautomatic(dns_zone_t *zone) {
1809
0
  REQUIRE(DNS_ZONE_VALID(zone));
1810
0
  return zone->automatic;
1811
0
}
1812
1813
void
1814
0
dns_zone_setadded(dns_zone_t *zone, bool added) {
1815
0
  REQUIRE(DNS_ZONE_VALID(zone));
1816
1817
0
  LOCK_ZONE(zone);
1818
0
  zone->added = added;
1819
0
  UNLOCK_ZONE(zone);
1820
0
}
1821
1822
bool
1823
0
dns_zone_getadded(dns_zone_t *zone) {
1824
0
  REQUIRE(DNS_ZONE_VALID(zone));
1825
0
  return zone->added;
1826
0
}
1827
1828
void
1829
0
dns_zone_setmodded(dns_zone_t *zone, bool modded) {
1830
0
  REQUIRE(DNS_ZONE_VALID(zone));
1831
1832
0
  LOCK_ZONE(zone);
1833
0
  zone->modded = modded;
1834
0
  UNLOCK_ZONE(zone);
1835
0
}
1836
1837
bool
1838
0
dns_zone_getmodded(dns_zone_t *zone) {
1839
0
  REQUIRE(DNS_ZONE_VALID(zone));
1840
0
  return zone->modded;
1841
0
}
1842
1843
isc_result_t
1844
0
dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
1845
0
  REQUIRE(DNS_ZONE_VALID(zone));
1846
0
  if (interval == 0) {
1847
0
    return ISC_R_RANGE;
1848
0
  }
1849
  /* Maximum value: 24 hours (3600 minutes) */
1850
0
  if (interval > (24 * 60)) {
1851
0
    interval = (24 * 60);
1852
0
  }
1853
  /* Multiply by 60 for seconds */
1854
0
  zone->refreshkeyinterval = interval * 60;
1855
0
  return ISC_R_SUCCESS;
1856
0
}
1857
1858
void
1859
0
dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
1860
0
  REQUIRE(DNS_ZONE_VALID(zone));
1861
0
  zone->requestixfr = flag;
1862
0
}
1863
1864
bool
1865
0
dns_zone_getrequestixfr(dns_zone_t *zone) {
1866
0
  REQUIRE(DNS_ZONE_VALID(zone));
1867
0
  return zone->requestixfr;
1868
0
}
1869
1870
void
1871
0
dns_zone_setrequestixfrmaxdiffs(dns_zone_t *zone, uint32_t maxdiffs) {
1872
0
  REQUIRE(DNS_ZONE_VALID(zone));
1873
0
  zone->requestixfr_maxdiffs = maxdiffs;
1874
0
}
1875
1876
bool
1877
0
dns_zone_getrequestixfrmaxdiffs(dns_zone_t *zone) {
1878
0
  REQUIRE(DNS_ZONE_VALID(zone));
1879
0
  return zone->requestixfr_maxdiffs;
1880
0
}
1881
1882
void
1883
0
dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) {
1884
0
  REQUIRE(DNS_ZONE_VALID(zone));
1885
0
  zone->ixfr_ratio = ratio;
1886
0
}
1887
1888
uint32_t
1889
0
dns_zone_getixfrratio(dns_zone_t *zone) {
1890
0
  REQUIRE(DNS_ZONE_VALID(zone));
1891
0
  return zone->ixfr_ratio;
1892
0
}
1893
1894
void
1895
0
dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
1896
0
  REQUIRE(DNS_ZONE_VALID(zone));
1897
0
  zone->requestexpire = flag;
1898
0
}
1899
1900
bool
1901
0
dns_zone_getrequestexpire(dns_zone_t *zone) {
1902
0
  REQUIRE(DNS_ZONE_VALID(zone));
1903
0
  return zone->requestexpire;
1904
0
}
1905
1906
void
1907
0
dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
1908
0
  REQUIRE(DNS_ZONE_VALID(zone));
1909
0
  zone->updatemethod = method;
1910
0
}
1911
1912
dns_updatemethod_t
1913
0
dns_zone_getserialupdatemethod(dns_zone_t *zone) {
1914
0
  REQUIRE(DNS_ZONE_VALID(zone));
1915
0
  return zone->updatemethod;
1916
0
}
1917
1918
void
1919
0
dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
1920
0
  REQUIRE(DNS_ZONE_VALID(zone));
1921
0
  REQUIRE(loadtime != NULL);
1922
1923
0
  LOCK_ZONE(zone);
1924
0
  *loadtime = zone->loadtime;
1925
0
  UNLOCK_ZONE(zone);
1926
0
}
1927
1928
void
1929
0
dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
1930
0
  REQUIRE(DNS_ZONE_VALID(zone));
1931
0
  REQUIRE(expiretime != NULL);
1932
1933
0
  LOCK_ZONE(zone);
1934
0
  *expiretime = zone->expiretime;
1935
0
  UNLOCK_ZONE(zone);
1936
0
}
1937
1938
void
1939
0
dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
1940
0
  REQUIRE(DNS_ZONE_VALID(zone));
1941
0
  REQUIRE(refreshtime != NULL);
1942
1943
0
  LOCK_ZONE(zone);
1944
0
  *refreshtime = zone->refreshtime;
1945
0
  UNLOCK_ZONE(zone);
1946
0
}
1947
1948
void
1949
0
dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
1950
0
  REQUIRE(DNS_ZONE_VALID(zone));
1951
0
  REQUIRE(refreshkeytime != NULL);
1952
1953
0
  LOCK_ZONE(zone);
1954
0
  *refreshkeytime = zone->refreshkeytime;
1955
0
  UNLOCK_ZONE(zone);
1956
0
}
1957
1958
void
1959
0
dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
1960
0
  REQUIRE(DNS_ZONE_VALID(zone));
1961
1962
0
  zone->statlevel = level;
1963
0
}
1964
1965
dns_zonestat_level_t
1966
0
dns_zone_getstatlevel(dns_zone_t *zone) {
1967
0
  REQUIRE(DNS_ZONE_VALID(zone));
1968
1969
0
  return zone->statlevel;
1970
0
}
1971
1972
unsigned int
1973
0
dns_zone_gettid(dns_zone_t *zone) {
1974
0
  return zone->tid;
1975
0
}
1976
1977
isc_loop_t *
1978
0
dns_zone_getloop(dns_zone_t *zone) {
1979
0
  return zone->loop;
1980
0
}
1981
1982
isc_result_t
1983
0
dns_zone_getrad(dns_zone_t *zone, dns_name_t *name) {
1984
0
  isc_result_t result = ISC_R_NOTFOUND;
1985
1986
0
  REQUIRE(DNS_ZONE_VALID(zone));
1987
0
  REQUIRE(DNS_NAME_VALID(name));
1988
1989
0
  rcu_read_lock();
1990
0
  dns_rad_t *rad = rcu_dereference(zone->rad);
1991
0
  if (rad != NULL) {
1992
0
    dns_name_t *inner = dns_fixedname_name(&rad->fname);
1993
0
    dns_name_copy(inner, name);
1994
0
    result = ISC_R_SUCCESS;
1995
0
  }
1996
0
  rcu_read_unlock();
1997
1998
0
  return result;
1999
0
}
2000
2001
void
2002
0
dns_zone_setrad(dns_zone_t *zone, dns_name_t *name) {
2003
0
  REQUIRE(DNS_ZONE_VALID(zone));
2004
0
  REQUIRE(name == NULL || DNS_NAME_VALID(name));
2005
2006
0
  rcu_read_lock();
2007
0
  dns_rad_t *new_rad = NULL;
2008
0
  if (name != NULL) {
2009
0
    new_rad = isc_mem_get(zone->mctx, sizeof(*new_rad));
2010
0
    *new_rad = (dns_rad_t){};
2011
0
    dns_fixedname_init(&new_rad->fname);
2012
2013
0
    isc_mem_attach(zone->mctx, &new_rad->mctx);
2014
0
    dns_name_copy(name, dns_fixedname_name(&new_rad->fname));
2015
0
  }
2016
0
  dns_rad_t *xchg_rad = rcu_xchg_pointer(&zone->rad, new_rad);
2017
2018
0
  if (xchg_rad != NULL) {
2019
0
    call_rcu(&xchg_rad->rcu_head, free_rad_rcu);
2020
0
  }
2021
0
  rcu_read_unlock();
2022
0
}
2023
2024
void *
2025
0
dns_zone_gethooktable(dns_zone_t *zone) {
2026
0
  REQUIRE(DNS_ZONE_VALID(zone));
2027
0
  return zone->hooktable;
2028
0
}
2029
2030
void
2031
dns_zone_sethooktable(dns_zone_t *zone, void *hooktable,
2032
0
          void (*hooktable_free)(isc_mem_t *, void **)) {
2033
0
  REQUIRE(DNS_ZONE_VALID(zone));
2034
0
  REQUIRE(zone->hooktable == NULL);
2035
0
  REQUIRE(zone->hooktable_free == NULL);
2036
2037
0
  zone->hooktable = hooktable;
2038
0
  zone->hooktable_free = hooktable_free;
2039
0
}
2040
2041
void
2042
0
dns_zone_setcfg(dns_zone_t *zone, const char *cfg) {
2043
0
  REQUIRE(DNS_ZONE_VALID(zone));
2044
2045
0
  if (zone->cfg != NULL) {
2046
0
    isc_mem_free(zone->mctx, zone->cfg);
2047
0
  }
2048
0
  if (cfg != NULL) {
2049
0
    zone->cfg = isc_mem_strdup(zone->mctx, cfg);
2050
0
  }
2051
0
}
2052
2053
const char *
2054
0
dns_zone_getcfg(dns_zone_t *zone) {
2055
0
  REQUIRE(DNS_ZONE_VALID(zone));
2056
2057
0
  return zone->cfg;
2058
0
}
2059
2060
/*
2061
 * Get the transport type used for the SOA query to the current primary server
2062
 * before an ongoing incoming zone transfer.
2063
 *
2064
 * Requires:
2065
 *      The zone is locked by the caller.
2066
 */
2067
static dns_transport_type_t
2068
0
get_request_transport_type(dns_zone_t *zone) {
2069
0
  dns_transport_type_t transport_type = DNS_TRANSPORT_NONE;
2070
2071
0
  if (zone->transport != NULL) {
2072
0
    transport_type = dns_transport_get_type(zone->transport);
2073
0
  } else {
2074
0
    transport_type = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC))
2075
0
           ? DNS_TRANSPORT_TCP
2076
0
           : DNS_TRANSPORT_UDP;
2077
2078
    /* Check if the peer is forced to always use TCP. */
2079
0
    if (transport_type != DNS_TRANSPORT_TCP &&
2080
0
        !dns_remote_done(&zone->primaries))
2081
0
    {
2082
0
      isc_result_t result;
2083
0
      isc_sockaddr_t primaryaddr;
2084
0
      isc_netaddr_t primaryip;
2085
0
      dns_peer_t *peer = NULL;
2086
2087
0
      primaryaddr = dns_remote_curraddr(&zone->primaries);
2088
0
      isc_netaddr_fromsockaddr(&primaryip, &primaryaddr);
2089
0
      result = dns_peerlist_peerbyaddr(zone->view->peers,
2090
0
               &primaryip, &peer);
2091
0
      if (result == ISC_R_SUCCESS && peer != NULL) {
2092
0
        bool usetcp;
2093
0
        result = dns_peer_getforcetcp(peer, &usetcp);
2094
0
        if (result == ISC_R_SUCCESS && usetcp) {
2095
0
          transport_type = DNS_TRANSPORT_TCP;
2096
0
        }
2097
0
      }
2098
0
    }
2099
0
  }
2100
2101
0
  return transport_type;
2102
0
}
2103
2104
dns_transport_type_t
2105
0
dns_zone_getrequesttransporttype(dns_zone_t *zone) {
2106
0
  dns_transport_type_t transport_type;
2107
2108
0
  REQUIRE(DNS_ZONE_VALID(zone));
2109
2110
0
  LOCK_ZONE(zone);
2111
0
  transport_type = get_request_transport_type(zone);
2112
0
  UNLOCK_ZONE(zone);
2113
2114
0
  return transport_type;
2115
0
}
2116
2117
dns_keystorelist_t *
2118
0
dns_zone_getkeystores(dns_zone_t *zone) {
2119
0
  return zone->zmgr->keystores;
2120
0
}
2121
2122
isc_stats_t *
2123
0
dns_zone_getgluecachestats(dns_zone_t *zone) {
2124
0
  REQUIRE(DNS_ZONE_VALID(zone));
2125
2126
0
  return zone->gluecachestats;
2127
0
}