/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 | } |