/src/bind9/lib/dns/peer.c
Line | Count | Source (jump to first uncovered line) |
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 <inttypes.h> |
17 | | #include <stdbool.h> |
18 | | |
19 | | #include <isc/mem.h> |
20 | | #include <isc/sockaddr.h> |
21 | | #include <isc/string.h> |
22 | | #include <isc/util.h> |
23 | | |
24 | | #include <dns/bit.h> |
25 | | #include <dns/fixedname.h> |
26 | | #include <dns/name.h> |
27 | | #include <dns/peer.h> |
28 | | |
29 | | /*** |
30 | | *** Types |
31 | | ***/ |
32 | | |
33 | | struct dns_peerlist { |
34 | | unsigned int magic; |
35 | | isc_refcount_t refs; |
36 | | |
37 | | isc_mem_t *mem; |
38 | | |
39 | | ISC_LIST(dns_peer_t) elements; |
40 | | }; |
41 | | |
42 | | struct dns_peer { |
43 | | unsigned int magic; |
44 | | isc_refcount_t refs; |
45 | | |
46 | | isc_mem_t *mem; |
47 | | |
48 | | isc_netaddr_t address; |
49 | | unsigned int prefixlen; |
50 | | bool bogus; |
51 | | dns_transfer_format_t transfer_format; |
52 | | uint32_t transfers; |
53 | | bool support_ixfr; |
54 | | bool provide_ixfr; |
55 | | bool request_ixfr; |
56 | | bool support_edns; |
57 | | bool request_nsid; |
58 | | bool send_cookie; |
59 | | bool request_expire; |
60 | | bool force_tcp; |
61 | | bool tcp_keepalive; |
62 | | bool check_axfr_id; |
63 | | dns_name_t *key; |
64 | | isc_sockaddr_t *transfer_source; |
65 | | isc_dscp_t transfer_dscp; |
66 | | isc_sockaddr_t *notify_source; |
67 | | isc_dscp_t notify_dscp; |
68 | | isc_sockaddr_t *query_source; |
69 | | isc_dscp_t query_dscp; |
70 | | uint16_t udpsize; /* receive size */ |
71 | | uint16_t maxudp; /* transmit size */ |
72 | | uint16_t padding; /* pad block size */ |
73 | | uint8_t ednsversion; /* edns version */ |
74 | | |
75 | | uint32_t bitflags; |
76 | | |
77 | | ISC_LINK(dns_peer_t) next; |
78 | | }; |
79 | | |
80 | | /*% |
81 | | * Bit positions in the dns_peer_t structure flags field |
82 | | */ |
83 | | #define BOGUS_BIT 0 |
84 | | #define SERVER_TRANSFER_FORMAT_BIT 1 |
85 | | #define TRANSFERS_BIT 2 |
86 | | #define PROVIDE_IXFR_BIT 3 |
87 | | #define REQUEST_IXFR_BIT 4 |
88 | | #define SUPPORT_EDNS_BIT 5 |
89 | | #define SERVER_UDPSIZE_BIT 6 |
90 | | #define SERVER_MAXUDP_BIT 7 |
91 | | #define REQUEST_NSID_BIT 8 |
92 | | #define SEND_COOKIE_BIT 9 |
93 | | #define NOTIFY_DSCP_BIT 10 |
94 | | #define TRANSFER_DSCP_BIT 11 |
95 | | #define QUERY_DSCP_BIT 12 |
96 | | #define REQUEST_EXPIRE_BIT 13 |
97 | | #define EDNS_VERSION_BIT 14 |
98 | | #define FORCE_TCP_BIT 15 |
99 | | #define SERVER_PADDING_BIT 16 |
100 | | #define REQUEST_TCP_KEEPALIVE_BIT 17 |
101 | | |
102 | | static void |
103 | | peerlist_delete(dns_peerlist_t **list); |
104 | | |
105 | | static void |
106 | | peer_delete(dns_peer_t **peer); |
107 | | |
108 | | isc_result_t |
109 | 0 | dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { |
110 | 0 | dns_peerlist_t *l; |
111 | |
|
112 | 0 | REQUIRE(list != NULL); |
113 | | |
114 | 0 | l = isc_mem_get(mem, sizeof(*l)); |
115 | |
|
116 | 0 | ISC_LIST_INIT(l->elements); |
117 | 0 | l->mem = mem; |
118 | 0 | isc_refcount_init(&l->refs, 1); |
119 | 0 | l->magic = DNS_PEERLIST_MAGIC; |
120 | |
|
121 | 0 | *list = l; |
122 | |
|
123 | 0 | return (ISC_R_SUCCESS); |
124 | 0 | } |
125 | | |
126 | | void |
127 | 0 | dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { |
128 | 0 | REQUIRE(DNS_PEERLIST_VALID(source)); |
129 | 0 | REQUIRE(target != NULL); |
130 | 0 | REQUIRE(*target == NULL); |
131 | | |
132 | 0 | isc_refcount_increment(&source->refs); |
133 | | |
134 | 0 | *target = source; |
135 | 0 | } |
136 | | |
137 | | void |
138 | 0 | dns_peerlist_detach(dns_peerlist_t **list) { |
139 | 0 | dns_peerlist_t *plist; |
140 | |
|
141 | 0 | REQUIRE(list != NULL); |
142 | 0 | REQUIRE(*list != NULL); |
143 | 0 | REQUIRE(DNS_PEERLIST_VALID(*list)); |
144 | | |
145 | 0 | plist = *list; |
146 | 0 | *list = NULL; |
147 | |
|
148 | 0 | if (isc_refcount_decrement(&plist->refs) == 1) { |
149 | 0 | peerlist_delete(&plist); |
150 | 0 | } |
151 | 0 | } |
152 | | |
153 | | static void |
154 | 0 | peerlist_delete(dns_peerlist_t **list) { |
155 | 0 | dns_peerlist_t *l; |
156 | 0 | dns_peer_t *server, *stmp; |
157 | |
|
158 | 0 | REQUIRE(list != NULL); |
159 | 0 | REQUIRE(DNS_PEERLIST_VALID(*list)); |
160 | | |
161 | 0 | l = *list; |
162 | 0 | *list = NULL; |
163 | |
|
164 | 0 | isc_refcount_destroy(&l->refs); |
165 | | |
166 | 0 | server = ISC_LIST_HEAD(l->elements); |
167 | 0 | while (server != NULL) { |
168 | 0 | stmp = ISC_LIST_NEXT(server, next); |
169 | 0 | ISC_LIST_UNLINK(l->elements, server, next); |
170 | 0 | dns_peer_detach(&server); |
171 | 0 | server = stmp; |
172 | 0 | } |
173 | |
|
174 | 0 | l->magic = 0; |
175 | 0 | isc_mem_put(l->mem, l, sizeof(*l)); |
176 | 0 | } |
177 | | |
178 | | void |
179 | 0 | dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) { |
180 | 0 | dns_peer_t *p = NULL; |
181 | |
|
182 | 0 | dns_peer_attach(peer, &p); |
183 | | |
184 | | /* |
185 | | * More specifics to front of list. |
186 | | */ |
187 | 0 | for (p = ISC_LIST_HEAD(peers->elements); p != NULL; |
188 | 0 | p = ISC_LIST_NEXT(p, next)) { |
189 | 0 | if (p->prefixlen < peer->prefixlen) { |
190 | 0 | break; |
191 | 0 | } |
192 | 0 | } |
193 | |
|
194 | 0 | if (p != NULL) { |
195 | 0 | ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next); |
196 | 0 | } else { |
197 | 0 | ISC_LIST_APPEND(peers->elements, peer, next); |
198 | 0 | } |
199 | 0 | } |
200 | | |
201 | | isc_result_t |
202 | | dns_peerlist_peerbyaddr(dns_peerlist_t *servers, const isc_netaddr_t *addr, |
203 | 0 | dns_peer_t **retval) { |
204 | 0 | dns_peer_t *server; |
205 | 0 | isc_result_t res; |
206 | |
|
207 | 0 | REQUIRE(retval != NULL); |
208 | 0 | REQUIRE(DNS_PEERLIST_VALID(servers)); |
209 | | |
210 | 0 | server = ISC_LIST_HEAD(servers->elements); |
211 | 0 | while (server != NULL) { |
212 | 0 | if (isc_netaddr_eqprefix(addr, &server->address, |
213 | 0 | server->prefixlen)) { |
214 | 0 | break; |
215 | 0 | } |
216 | | |
217 | 0 | server = ISC_LIST_NEXT(server, next); |
218 | 0 | } |
219 | |
|
220 | 0 | if (server != NULL) { |
221 | 0 | *retval = server; |
222 | 0 | res = ISC_R_SUCCESS; |
223 | 0 | } else { |
224 | 0 | res = ISC_R_NOTFOUND; |
225 | 0 | } |
226 | |
|
227 | 0 | return (res); |
228 | 0 | } |
229 | | |
230 | | isc_result_t |
231 | 0 | dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) { |
232 | 0 | dns_peer_t *p = NULL; |
233 | |
|
234 | 0 | p = ISC_LIST_TAIL(peers->elements); |
235 | |
|
236 | 0 | dns_peer_attach(p, retval); |
237 | |
|
238 | 0 | return (ISC_R_SUCCESS); |
239 | 0 | } |
240 | | |
241 | | isc_result_t |
242 | 0 | dns_peer_new(isc_mem_t *mem, const isc_netaddr_t *addr, dns_peer_t **peerptr) { |
243 | 0 | unsigned int prefixlen = 0; |
244 | |
|
245 | 0 | REQUIRE(peerptr != NULL); |
246 | 0 | switch (addr->family) { |
247 | 0 | case AF_INET: |
248 | 0 | prefixlen = 32; |
249 | 0 | break; |
250 | 0 | case AF_INET6: |
251 | 0 | prefixlen = 128; |
252 | 0 | break; |
253 | 0 | default: |
254 | 0 | INSIST(0); |
255 | 0 | ISC_UNREACHABLE(); |
256 | 0 | } |
257 | | |
258 | 0 | return (dns_peer_newprefix(mem, addr, prefixlen, peerptr)); |
259 | 0 | } |
260 | | |
261 | | isc_result_t |
262 | | dns_peer_newprefix(isc_mem_t *mem, const isc_netaddr_t *addr, |
263 | 0 | unsigned int prefixlen, dns_peer_t **peerptr) { |
264 | 0 | dns_peer_t *peer; |
265 | |
|
266 | 0 | REQUIRE(peerptr != NULL && *peerptr == NULL); |
267 | | |
268 | 0 | peer = isc_mem_get(mem, sizeof(*peer)); |
269 | |
|
270 | 0 | *peer = (dns_peer_t){ |
271 | 0 | .magic = DNS_PEER_MAGIC, |
272 | 0 | .address = *addr, |
273 | 0 | .prefixlen = prefixlen, |
274 | 0 | .mem = mem, |
275 | 0 | .transfer_format = dns_one_answer, |
276 | 0 | }; |
277 | |
|
278 | 0 | isc_refcount_init(&peer->refs, 1); |
279 | |
|
280 | 0 | ISC_LINK_INIT(peer, next); |
281 | |
|
282 | 0 | *peerptr = peer; |
283 | |
|
284 | 0 | return (ISC_R_SUCCESS); |
285 | 0 | } |
286 | | |
287 | | void |
288 | 0 | dns_peer_attach(dns_peer_t *source, dns_peer_t **target) { |
289 | 0 | REQUIRE(DNS_PEER_VALID(source)); |
290 | 0 | REQUIRE(target != NULL); |
291 | 0 | REQUIRE(*target == NULL); |
292 | | |
293 | 0 | isc_refcount_increment(&source->refs); |
294 | | |
295 | 0 | *target = source; |
296 | 0 | } |
297 | | |
298 | | void |
299 | 0 | dns_peer_detach(dns_peer_t **peer) { |
300 | 0 | dns_peer_t *p; |
301 | |
|
302 | 0 | REQUIRE(peer != NULL); |
303 | 0 | REQUIRE(*peer != NULL); |
304 | 0 | REQUIRE(DNS_PEER_VALID(*peer)); |
305 | | |
306 | 0 | p = *peer; |
307 | 0 | *peer = NULL; |
308 | |
|
309 | 0 | if (isc_refcount_decrement(&p->refs) == 1) { |
310 | 0 | peer_delete(&p); |
311 | 0 | } |
312 | 0 | } |
313 | | |
314 | | static void |
315 | 0 | peer_delete(dns_peer_t **peer) { |
316 | 0 | dns_peer_t *p; |
317 | 0 | isc_mem_t *mem; |
318 | |
|
319 | 0 | REQUIRE(peer != NULL); |
320 | 0 | REQUIRE(DNS_PEER_VALID(*peer)); |
321 | | |
322 | 0 | p = *peer; |
323 | 0 | *peer = NULL; |
324 | |
|
325 | 0 | isc_refcount_destroy(&p->refs); |
326 | | |
327 | 0 | mem = p->mem; |
328 | 0 | p->mem = NULL; |
329 | 0 | p->magic = 0; |
330 | |
|
331 | 0 | if (p->key != NULL) { |
332 | 0 | dns_name_free(p->key, mem); |
333 | 0 | isc_mem_put(mem, p->key, sizeof(dns_name_t)); |
334 | 0 | } |
335 | |
|
336 | 0 | if (p->query_source != NULL) { |
337 | 0 | isc_mem_put(mem, p->query_source, sizeof(*p->query_source)); |
338 | 0 | } |
339 | |
|
340 | 0 | if (p->notify_source != NULL) { |
341 | 0 | isc_mem_put(mem, p->notify_source, sizeof(*p->notify_source)); |
342 | 0 | } |
343 | |
|
344 | 0 | if (p->transfer_source != NULL) { |
345 | 0 | isc_mem_put(mem, p->transfer_source, |
346 | 0 | sizeof(*p->transfer_source)); |
347 | 0 | } |
348 | |
|
349 | 0 | isc_mem_put(mem, p, sizeof(*p)); |
350 | 0 | } |
351 | | |
352 | | isc_result_t |
353 | 0 | dns_peer_setbogus(dns_peer_t *peer, bool newval) { |
354 | 0 | bool existed; |
355 | |
|
356 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
357 | | |
358 | 0 | existed = DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags); |
359 | |
|
360 | 0 | peer->bogus = newval; |
361 | 0 | DNS_BIT_SET(BOGUS_BIT, &peer->bitflags); |
362 | |
|
363 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
364 | 0 | } |
365 | | |
366 | | isc_result_t |
367 | 0 | dns_peer_getbogus(dns_peer_t *peer, bool *retval) { |
368 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
369 | 0 | REQUIRE(retval != NULL); |
370 | | |
371 | 0 | if (DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags)) { |
372 | 0 | *retval = peer->bogus; |
373 | 0 | return (ISC_R_SUCCESS); |
374 | 0 | } else { |
375 | 0 | return (ISC_R_NOTFOUND); |
376 | 0 | } |
377 | 0 | } |
378 | | |
379 | | isc_result_t |
380 | 0 | dns_peer_setprovideixfr(dns_peer_t *peer, bool newval) { |
381 | 0 | bool existed; |
382 | |
|
383 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
384 | | |
385 | 0 | existed = DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags); |
386 | |
|
387 | 0 | peer->provide_ixfr = newval; |
388 | 0 | DNS_BIT_SET(PROVIDE_IXFR_BIT, &peer->bitflags); |
389 | |
|
390 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
391 | 0 | } |
392 | | |
393 | | isc_result_t |
394 | 0 | dns_peer_getprovideixfr(dns_peer_t *peer, bool *retval) { |
395 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
396 | 0 | REQUIRE(retval != NULL); |
397 | | |
398 | 0 | if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags)) { |
399 | 0 | *retval = peer->provide_ixfr; |
400 | 0 | return (ISC_R_SUCCESS); |
401 | 0 | } else { |
402 | 0 | return (ISC_R_NOTFOUND); |
403 | 0 | } |
404 | 0 | } |
405 | | |
406 | | isc_result_t |
407 | 0 | dns_peer_setrequestixfr(dns_peer_t *peer, bool newval) { |
408 | 0 | bool existed; |
409 | |
|
410 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
411 | | |
412 | 0 | existed = DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags); |
413 | |
|
414 | 0 | peer->request_ixfr = newval; |
415 | 0 | DNS_BIT_SET(REQUEST_IXFR_BIT, &peer->bitflags); |
416 | |
|
417 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
418 | 0 | } |
419 | | |
420 | | isc_result_t |
421 | 0 | dns_peer_getrequestixfr(dns_peer_t *peer, bool *retval) { |
422 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
423 | 0 | REQUIRE(retval != NULL); |
424 | | |
425 | 0 | if (DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags)) { |
426 | 0 | *retval = peer->request_ixfr; |
427 | 0 | return (ISC_R_SUCCESS); |
428 | 0 | } else { |
429 | 0 | return (ISC_R_NOTFOUND); |
430 | 0 | } |
431 | 0 | } |
432 | | |
433 | | isc_result_t |
434 | 0 | dns_peer_setsupportedns(dns_peer_t *peer, bool newval) { |
435 | 0 | bool existed; |
436 | |
|
437 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
438 | | |
439 | 0 | existed = DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags); |
440 | |
|
441 | 0 | peer->support_edns = newval; |
442 | 0 | DNS_BIT_SET(SUPPORT_EDNS_BIT, &peer->bitflags); |
443 | |
|
444 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
445 | 0 | } |
446 | | |
447 | | isc_result_t |
448 | 0 | dns_peer_getsupportedns(dns_peer_t *peer, bool *retval) { |
449 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
450 | 0 | REQUIRE(retval != NULL); |
451 | | |
452 | 0 | if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags)) { |
453 | 0 | *retval = peer->support_edns; |
454 | 0 | return (ISC_R_SUCCESS); |
455 | 0 | } else { |
456 | 0 | return (ISC_R_NOTFOUND); |
457 | 0 | } |
458 | 0 | } |
459 | | |
460 | | isc_result_t |
461 | 0 | dns_peer_setrequestnsid(dns_peer_t *peer, bool newval) { |
462 | 0 | bool existed; |
463 | |
|
464 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
465 | | |
466 | 0 | existed = DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags); |
467 | |
|
468 | 0 | peer->request_nsid = newval; |
469 | 0 | DNS_BIT_SET(REQUEST_NSID_BIT, &peer->bitflags); |
470 | |
|
471 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
472 | 0 | } |
473 | | |
474 | | isc_result_t |
475 | 0 | dns_peer_getrequestnsid(dns_peer_t *peer, bool *retval) { |
476 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
477 | 0 | REQUIRE(retval != NULL); |
478 | | |
479 | 0 | if (DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags)) { |
480 | 0 | *retval = peer->request_nsid; |
481 | 0 | return (ISC_R_SUCCESS); |
482 | 0 | } else { |
483 | 0 | return (ISC_R_NOTFOUND); |
484 | 0 | } |
485 | 0 | } |
486 | | |
487 | | isc_result_t |
488 | 0 | dns_peer_setsendcookie(dns_peer_t *peer, bool newval) { |
489 | 0 | bool existed; |
490 | |
|
491 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
492 | | |
493 | 0 | existed = DNS_BIT_CHECK(SEND_COOKIE_BIT, &peer->bitflags); |
494 | |
|
495 | 0 | peer->send_cookie = newval; |
496 | 0 | DNS_BIT_SET(SEND_COOKIE_BIT, &peer->bitflags); |
497 | |
|
498 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
499 | 0 | } |
500 | | |
501 | | isc_result_t |
502 | 0 | dns_peer_getsendcookie(dns_peer_t *peer, bool *retval) { |
503 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
504 | 0 | REQUIRE(retval != NULL); |
505 | | |
506 | 0 | if (DNS_BIT_CHECK(SEND_COOKIE_BIT, &peer->bitflags)) { |
507 | 0 | *retval = peer->send_cookie; |
508 | 0 | return (ISC_R_SUCCESS); |
509 | 0 | } else { |
510 | 0 | return (ISC_R_NOTFOUND); |
511 | 0 | } |
512 | 0 | } |
513 | | |
514 | | isc_result_t |
515 | 0 | dns_peer_setrequestexpire(dns_peer_t *peer, bool newval) { |
516 | 0 | bool existed; |
517 | |
|
518 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
519 | | |
520 | 0 | existed = DNS_BIT_CHECK(REQUEST_EXPIRE_BIT, &peer->bitflags); |
521 | |
|
522 | 0 | peer->request_expire = newval; |
523 | 0 | DNS_BIT_SET(REQUEST_EXPIRE_BIT, &peer->bitflags); |
524 | |
|
525 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
526 | 0 | } |
527 | | |
528 | | isc_result_t |
529 | 0 | dns_peer_getrequestexpire(dns_peer_t *peer, bool *retval) { |
530 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
531 | 0 | REQUIRE(retval != NULL); |
532 | | |
533 | 0 | if (DNS_BIT_CHECK(REQUEST_EXPIRE_BIT, &peer->bitflags)) { |
534 | 0 | *retval = peer->request_expire; |
535 | 0 | return (ISC_R_SUCCESS); |
536 | 0 | } else { |
537 | 0 | return (ISC_R_NOTFOUND); |
538 | 0 | } |
539 | 0 | } |
540 | | |
541 | | isc_result_t |
542 | 0 | dns_peer_setforcetcp(dns_peer_t *peer, bool newval) { |
543 | 0 | bool existed; |
544 | |
|
545 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
546 | | |
547 | 0 | existed = DNS_BIT_CHECK(FORCE_TCP_BIT, &peer->bitflags); |
548 | |
|
549 | 0 | peer->force_tcp = newval; |
550 | 0 | DNS_BIT_SET(FORCE_TCP_BIT, &peer->bitflags); |
551 | |
|
552 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
553 | 0 | } |
554 | | |
555 | | isc_result_t |
556 | 0 | dns_peer_getforcetcp(dns_peer_t *peer, bool *retval) { |
557 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
558 | 0 | REQUIRE(retval != NULL); |
559 | | |
560 | 0 | if (DNS_BIT_CHECK(FORCE_TCP_BIT, &peer->bitflags)) { |
561 | 0 | *retval = peer->force_tcp; |
562 | 0 | return (ISC_R_SUCCESS); |
563 | 0 | } else { |
564 | 0 | return (ISC_R_NOTFOUND); |
565 | 0 | } |
566 | 0 | } |
567 | | |
568 | | isc_result_t |
569 | 0 | dns_peer_settcpkeepalive(dns_peer_t *peer, bool newval) { |
570 | 0 | bool existed; |
571 | |
|
572 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
573 | | |
574 | 0 | existed = DNS_BIT_CHECK(REQUEST_TCP_KEEPALIVE_BIT, &peer->bitflags); |
575 | |
|
576 | 0 | peer->tcp_keepalive = newval; |
577 | 0 | DNS_BIT_SET(REQUEST_TCP_KEEPALIVE_BIT, &peer->bitflags); |
578 | |
|
579 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
580 | 0 | } |
581 | | |
582 | | isc_result_t |
583 | 0 | dns_peer_gettcpkeepalive(dns_peer_t *peer, bool *retval) { |
584 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
585 | 0 | REQUIRE(retval != NULL); |
586 | | |
587 | 0 | if (DNS_BIT_CHECK(REQUEST_TCP_KEEPALIVE_BIT, &peer->bitflags)) { |
588 | 0 | *retval = peer->tcp_keepalive; |
589 | 0 | return (ISC_R_SUCCESS); |
590 | 0 | } else { |
591 | 0 | return (ISC_R_NOTFOUND); |
592 | 0 | } |
593 | 0 | } |
594 | | |
595 | | isc_result_t |
596 | 0 | dns_peer_settransfers(dns_peer_t *peer, uint32_t newval) { |
597 | 0 | bool existed; |
598 | |
|
599 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
600 | | |
601 | 0 | existed = DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags); |
602 | |
|
603 | 0 | peer->transfers = newval; |
604 | 0 | DNS_BIT_SET(TRANSFERS_BIT, &peer->bitflags); |
605 | |
|
606 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
607 | 0 | } |
608 | | |
609 | | isc_result_t |
610 | 0 | dns_peer_gettransfers(dns_peer_t *peer, uint32_t *retval) { |
611 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
612 | 0 | REQUIRE(retval != NULL); |
613 | | |
614 | 0 | if (DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags)) { |
615 | 0 | *retval = peer->transfers; |
616 | 0 | return (ISC_R_SUCCESS); |
617 | 0 | } else { |
618 | 0 | return (ISC_R_NOTFOUND); |
619 | 0 | } |
620 | 0 | } |
621 | | |
622 | | isc_result_t |
623 | 0 | dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval) { |
624 | 0 | bool existed; |
625 | |
|
626 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
627 | | |
628 | 0 | existed = DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); |
629 | |
|
630 | 0 | peer->transfer_format = newval; |
631 | 0 | DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); |
632 | |
|
633 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
634 | 0 | } |
635 | | |
636 | | isc_result_t |
637 | 0 | dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval) { |
638 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
639 | 0 | REQUIRE(retval != NULL); |
640 | | |
641 | 0 | if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) { |
642 | 0 | *retval = peer->transfer_format; |
643 | 0 | return (ISC_R_SUCCESS); |
644 | 0 | } else { |
645 | 0 | return (ISC_R_NOTFOUND); |
646 | 0 | } |
647 | 0 | } |
648 | | |
649 | | isc_result_t |
650 | 0 | dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) { |
651 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
652 | 0 | REQUIRE(retval != NULL); |
653 | | |
654 | 0 | if (peer->key != NULL) { |
655 | 0 | *retval = peer->key; |
656 | 0 | } |
657 | |
|
658 | 0 | return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS); |
659 | 0 | } |
660 | | |
661 | | isc_result_t |
662 | 0 | dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) { |
663 | 0 | bool exists = false; |
664 | |
|
665 | 0 | if (peer->key != NULL) { |
666 | 0 | dns_name_free(peer->key, peer->mem); |
667 | 0 | isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t)); |
668 | 0 | exists = true; |
669 | 0 | } |
670 | |
|
671 | 0 | peer->key = *keyval; |
672 | 0 | *keyval = NULL; |
673 | |
|
674 | 0 | return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS); |
675 | 0 | } |
676 | | |
677 | | isc_result_t |
678 | 0 | dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { |
679 | 0 | isc_buffer_t b; |
680 | 0 | dns_fixedname_t fname; |
681 | 0 | dns_name_t *name; |
682 | 0 | isc_result_t result; |
683 | |
|
684 | 0 | dns_fixedname_init(&fname); |
685 | 0 | isc_buffer_constinit(&b, keyval, strlen(keyval)); |
686 | 0 | isc_buffer_add(&b, strlen(keyval)); |
687 | 0 | result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname, |
688 | 0 | 0, NULL); |
689 | 0 | if (result != ISC_R_SUCCESS) { |
690 | 0 | return (result); |
691 | 0 | } |
692 | | |
693 | 0 | name = isc_mem_get(peer->mem, sizeof(dns_name_t)); |
694 | |
|
695 | 0 | dns_name_init(name, NULL); |
696 | 0 | dns_name_dup(dns_fixedname_name(&fname), peer->mem, name); |
697 | |
|
698 | 0 | result = dns_peer_setkey(peer, &name); |
699 | 0 | if (result != ISC_R_SUCCESS) { |
700 | 0 | isc_mem_put(peer->mem, name, sizeof(dns_name_t)); |
701 | 0 | } |
702 | |
|
703 | 0 | return (result); |
704 | 0 | } |
705 | | |
706 | | isc_result_t |
707 | | dns_peer_settransfersource(dns_peer_t *peer, |
708 | 0 | const isc_sockaddr_t *transfer_source) { |
709 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
710 | | |
711 | 0 | if (peer->transfer_source != NULL) { |
712 | 0 | isc_mem_put(peer->mem, peer->transfer_source, |
713 | 0 | sizeof(*peer->transfer_source)); |
714 | 0 | peer->transfer_source = NULL; |
715 | 0 | } |
716 | 0 | if (transfer_source != NULL) { |
717 | 0 | peer->transfer_source = |
718 | 0 | isc_mem_get(peer->mem, sizeof(*peer->transfer_source)); |
719 | |
|
720 | 0 | *peer->transfer_source = *transfer_source; |
721 | 0 | } |
722 | 0 | return (ISC_R_SUCCESS); |
723 | 0 | } |
724 | | |
725 | | isc_result_t |
726 | 0 | dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { |
727 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
728 | 0 | REQUIRE(transfer_source != NULL); |
729 | | |
730 | 0 | if (peer->transfer_source == NULL) { |
731 | 0 | return (ISC_R_NOTFOUND); |
732 | 0 | } |
733 | 0 | *transfer_source = *peer->transfer_source; |
734 | 0 | return (ISC_R_SUCCESS); |
735 | 0 | } |
736 | | |
737 | | isc_result_t |
738 | | dns_peer_setnotifysource(dns_peer_t *peer, |
739 | 0 | const isc_sockaddr_t *notify_source) { |
740 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
741 | | |
742 | 0 | if (peer->notify_source != NULL) { |
743 | 0 | isc_mem_put(peer->mem, peer->notify_source, |
744 | 0 | sizeof(*peer->notify_source)); |
745 | 0 | peer->notify_source = NULL; |
746 | 0 | } |
747 | 0 | if (notify_source != NULL) { |
748 | 0 | peer->notify_source = isc_mem_get(peer->mem, |
749 | 0 | sizeof(*peer->notify_source)); |
750 | |
|
751 | 0 | *peer->notify_source = *notify_source; |
752 | 0 | } |
753 | 0 | return (ISC_R_SUCCESS); |
754 | 0 | } |
755 | | |
756 | | isc_result_t |
757 | 0 | dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) { |
758 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
759 | 0 | REQUIRE(notify_source != NULL); |
760 | | |
761 | 0 | if (peer->notify_source == NULL) { |
762 | 0 | return (ISC_R_NOTFOUND); |
763 | 0 | } |
764 | 0 | *notify_source = *peer->notify_source; |
765 | 0 | return (ISC_R_SUCCESS); |
766 | 0 | } |
767 | | |
768 | | isc_result_t |
769 | 0 | dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) { |
770 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
771 | | |
772 | 0 | if (peer->query_source != NULL) { |
773 | 0 | isc_mem_put(peer->mem, peer->query_source, |
774 | 0 | sizeof(*peer->query_source)); |
775 | 0 | peer->query_source = NULL; |
776 | 0 | } |
777 | 0 | if (query_source != NULL) { |
778 | 0 | peer->query_source = isc_mem_get(peer->mem, |
779 | 0 | sizeof(*peer->query_source)); |
780 | |
|
781 | 0 | *peer->query_source = *query_source; |
782 | 0 | } |
783 | 0 | return (ISC_R_SUCCESS); |
784 | 0 | } |
785 | | |
786 | | isc_result_t |
787 | 0 | dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) { |
788 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
789 | 0 | REQUIRE(query_source != NULL); |
790 | | |
791 | 0 | if (peer->query_source == NULL) { |
792 | 0 | return (ISC_R_NOTFOUND); |
793 | 0 | } |
794 | 0 | *query_source = *peer->query_source; |
795 | 0 | return (ISC_R_SUCCESS); |
796 | 0 | } |
797 | | |
798 | | isc_result_t |
799 | 0 | dns_peer_setudpsize(dns_peer_t *peer, uint16_t udpsize) { |
800 | 0 | bool existed; |
801 | |
|
802 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
803 | | |
804 | 0 | existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); |
805 | |
|
806 | 0 | peer->udpsize = udpsize; |
807 | 0 | DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); |
808 | |
|
809 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
810 | 0 | } |
811 | | |
812 | | isc_result_t |
813 | 0 | dns_peer_getudpsize(dns_peer_t *peer, uint16_t *udpsize) { |
814 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
815 | 0 | REQUIRE(udpsize != NULL); |
816 | | |
817 | 0 | if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { |
818 | 0 | *udpsize = peer->udpsize; |
819 | 0 | return (ISC_R_SUCCESS); |
820 | 0 | } else { |
821 | 0 | return (ISC_R_NOTFOUND); |
822 | 0 | } |
823 | 0 | } |
824 | | |
825 | | isc_result_t |
826 | 0 | dns_peer_setmaxudp(dns_peer_t *peer, uint16_t maxudp) { |
827 | 0 | bool existed; |
828 | |
|
829 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
830 | | |
831 | 0 | existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags); |
832 | |
|
833 | 0 | peer->maxudp = maxudp; |
834 | 0 | DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags); |
835 | |
|
836 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
837 | 0 | } |
838 | | |
839 | | isc_result_t |
840 | 0 | dns_peer_getmaxudp(dns_peer_t *peer, uint16_t *maxudp) { |
841 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
842 | 0 | REQUIRE(maxudp != NULL); |
843 | | |
844 | 0 | if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) { |
845 | 0 | *maxudp = peer->maxudp; |
846 | 0 | return (ISC_R_SUCCESS); |
847 | 0 | } else { |
848 | 0 | return (ISC_R_NOTFOUND); |
849 | 0 | } |
850 | 0 | } |
851 | | |
852 | | isc_result_t |
853 | 0 | dns_peer_setpadding(dns_peer_t *peer, uint16_t padding) { |
854 | 0 | bool existed; |
855 | |
|
856 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
857 | | |
858 | 0 | existed = DNS_BIT_CHECK(SERVER_PADDING_BIT, &peer->bitflags); |
859 | |
|
860 | 0 | if (padding > 512) { |
861 | 0 | padding = 512; |
862 | 0 | } |
863 | 0 | peer->padding = padding; |
864 | 0 | DNS_BIT_SET(SERVER_PADDING_BIT, &peer->bitflags); |
865 | |
|
866 | 0 | return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); |
867 | 0 | } |
868 | | |
869 | | isc_result_t |
870 | 0 | dns_peer_getpadding(dns_peer_t *peer, uint16_t *padding) { |
871 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
872 | 0 | REQUIRE(padding != NULL); |
873 | | |
874 | 0 | if (DNS_BIT_CHECK(SERVER_PADDING_BIT, &peer->bitflags)) { |
875 | 0 | *padding = peer->padding; |
876 | 0 | return (ISC_R_SUCCESS); |
877 | 0 | } else { |
878 | 0 | return (ISC_R_NOTFOUND); |
879 | 0 | } |
880 | 0 | } |
881 | | |
882 | | isc_result_t |
883 | 0 | dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp) { |
884 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
885 | 0 | REQUIRE(dscp < 64); |
886 | | |
887 | 0 | peer->notify_dscp = dscp; |
888 | 0 | DNS_BIT_SET(NOTIFY_DSCP_BIT, &peer->bitflags); |
889 | 0 | return (ISC_R_SUCCESS); |
890 | 0 | } |
891 | | |
892 | | isc_result_t |
893 | 0 | dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { |
894 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
895 | 0 | REQUIRE(dscpp != NULL); |
896 | | |
897 | 0 | if (DNS_BIT_CHECK(NOTIFY_DSCP_BIT, &peer->bitflags)) { |
898 | 0 | *dscpp = peer->notify_dscp; |
899 | 0 | return (ISC_R_SUCCESS); |
900 | 0 | } |
901 | 0 | return (ISC_R_NOTFOUND); |
902 | 0 | } |
903 | | |
904 | | isc_result_t |
905 | 0 | dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp) { |
906 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
907 | 0 | REQUIRE(dscp < 64); |
908 | | |
909 | 0 | peer->transfer_dscp = dscp; |
910 | 0 | DNS_BIT_SET(TRANSFER_DSCP_BIT, &peer->bitflags); |
911 | 0 | return (ISC_R_SUCCESS); |
912 | 0 | } |
913 | | |
914 | | isc_result_t |
915 | 0 | dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp) { |
916 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
917 | 0 | REQUIRE(dscpp != NULL); |
918 | | |
919 | 0 | if (DNS_BIT_CHECK(TRANSFER_DSCP_BIT, &peer->bitflags)) { |
920 | 0 | *dscpp = peer->transfer_dscp; |
921 | 0 | return (ISC_R_SUCCESS); |
922 | 0 | } |
923 | 0 | return (ISC_R_NOTFOUND); |
924 | 0 | } |
925 | | |
926 | | isc_result_t |
927 | 0 | dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp) { |
928 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
929 | 0 | REQUIRE(dscp < 64); |
930 | | |
931 | 0 | peer->query_dscp = dscp; |
932 | 0 | DNS_BIT_SET(QUERY_DSCP_BIT, &peer->bitflags); |
933 | 0 | return (ISC_R_SUCCESS); |
934 | 0 | } |
935 | | |
936 | | isc_result_t |
937 | 0 | dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { |
938 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
939 | 0 | REQUIRE(dscpp != NULL); |
940 | | |
941 | 0 | if (DNS_BIT_CHECK(QUERY_DSCP_BIT, &peer->bitflags)) { |
942 | 0 | *dscpp = peer->query_dscp; |
943 | 0 | return (ISC_R_SUCCESS); |
944 | 0 | } |
945 | 0 | return (ISC_R_NOTFOUND); |
946 | 0 | } |
947 | | |
948 | | isc_result_t |
949 | 0 | dns_peer_setednsversion(dns_peer_t *peer, uint8_t ednsversion) { |
950 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
951 | | |
952 | 0 | peer->ednsversion = ednsversion; |
953 | 0 | DNS_BIT_SET(EDNS_VERSION_BIT, &peer->bitflags); |
954 | |
|
955 | 0 | return (ISC_R_SUCCESS); |
956 | 0 | } |
957 | | |
958 | | isc_result_t |
959 | 0 | dns_peer_getednsversion(dns_peer_t *peer, uint8_t *ednsversion) { |
960 | 0 | REQUIRE(DNS_PEER_VALID(peer)); |
961 | 0 | REQUIRE(ednsversion != NULL); |
962 | | |
963 | 0 | if (DNS_BIT_CHECK(EDNS_VERSION_BIT, &peer->bitflags)) { |
964 | 0 | *ednsversion = peer->ednsversion; |
965 | 0 | return (ISC_R_SUCCESS); |
966 | 0 | } else { |
967 | 0 | return (ISC_R_NOTFOUND); |
968 | 0 | } |
969 | 0 | } |