2 * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: peer.c,v 1.29.128.2 2008/04/03 06:08:27 tbox Exp $ */
25 #include <isc/string.h>
27 #include <isc/sockaddr.h>
30 #include <dns/fixedname.h>
35 * Bit positions in the dns_peer_t structure flags field
38 #define SERVER_TRANSFER_FORMAT_BIT 1
39 #define TRANSFERS_BIT 2
40 #define PROVIDE_IXFR_BIT 3
41 #define REQUEST_IXFR_BIT 4
42 #define SUPPORT_EDNS_BIT 5
43 #define SERVER_UDPSIZE_BIT 6
44 #define SERVER_MAXUDP_BIT 7
45 #define REQUEST_NSID_BIT 8
48 peerlist_delete(dns_peerlist_t
**list
);
51 peer_delete(dns_peer_t
**peer
);
54 dns_peerlist_new(isc_mem_t
*mem
, dns_peerlist_t
**list
) {
57 REQUIRE(list
!= NULL
);
59 l
= isc_mem_get(mem
, sizeof(*l
));
61 return (ISC_R_NOMEMORY
);
63 ISC_LIST_INIT(l
->elements
);
66 l
->magic
= DNS_PEERLIST_MAGIC
;
70 return (ISC_R_SUCCESS
);
74 dns_peerlist_attach(dns_peerlist_t
*source
, dns_peerlist_t
**target
) {
75 REQUIRE(DNS_PEERLIST_VALID(source
));
76 REQUIRE(target
!= NULL
);
77 REQUIRE(*target
== NULL
);
81 ENSURE(source
->refs
!= 0xffffffffU
);
87 dns_peerlist_detach(dns_peerlist_t
**list
) {
88 dns_peerlist_t
*plist
;
90 REQUIRE(list
!= NULL
);
91 REQUIRE(*list
!= NULL
);
92 REQUIRE(DNS_PEERLIST_VALID(*list
));
97 REQUIRE(plist
->refs
> 0);
101 if (plist
->refs
== 0)
102 peerlist_delete(&plist
);
106 peerlist_delete(dns_peerlist_t
**list
) {
108 dns_peer_t
*server
, *stmp
;
110 REQUIRE(list
!= NULL
);
111 REQUIRE(DNS_PEERLIST_VALID(*list
));
115 REQUIRE(l
->refs
== 0);
117 server
= ISC_LIST_HEAD(l
->elements
);
118 while (server
!= NULL
) {
119 stmp
= ISC_LIST_NEXT(server
, next
);
120 ISC_LIST_UNLINK(l
->elements
, server
, next
);
121 dns_peer_detach(&server
);
126 isc_mem_put(l
->mem
, l
, sizeof(*l
));
132 dns_peerlist_addpeer(dns_peerlist_t
*peers
, dns_peer_t
*peer
) {
133 dns_peer_t
*p
= NULL
;
135 dns_peer_attach(peer
, &p
);
138 * More specifics to front of list.
140 for (p
= ISC_LIST_HEAD(peers
->elements
);
142 p
= ISC_LIST_NEXT(p
, next
))
143 if (p
->prefixlen
< peer
->prefixlen
)
147 ISC_LIST_INSERTBEFORE(peers
->elements
, p
, peer
, next
);
149 ISC_LIST_APPEND(peers
->elements
, peer
, next
);
154 dns_peerlist_peerbyaddr(dns_peerlist_t
*servers
,
155 isc_netaddr_t
*addr
, dns_peer_t
**retval
)
160 REQUIRE(retval
!= NULL
);
161 REQUIRE(DNS_PEERLIST_VALID(servers
));
163 server
= ISC_LIST_HEAD(servers
->elements
);
164 while (server
!= NULL
) {
165 if (isc_netaddr_eqprefix(addr
, &server
->address
,
169 server
= ISC_LIST_NEXT(server
, next
);
172 if (server
!= NULL
) {
176 res
= ISC_R_NOTFOUND
;
185 dns_peerlist_currpeer(dns_peerlist_t
*peers
, dns_peer_t
**retval
) {
186 dns_peer_t
*p
= NULL
;
188 p
= ISC_LIST_TAIL(peers
->elements
);
190 dns_peer_attach(p
, retval
);
192 return (ISC_R_SUCCESS
);
196 dns_peer_new(isc_mem_t
*mem
, isc_netaddr_t
*addr
, dns_peer_t
**peerptr
) {
197 unsigned int prefixlen
= 0;
199 REQUIRE(peerptr
!= NULL
);
200 switch(addr
->family
) {
211 return (dns_peer_newprefix(mem
, addr
, prefixlen
, peerptr
));
215 dns_peer_newprefix(isc_mem_t
*mem
, isc_netaddr_t
*addr
, unsigned int prefixlen
,
216 dns_peer_t
**peerptr
)
220 REQUIRE(peerptr
!= NULL
);
222 peer
= isc_mem_get(mem
, sizeof(*peer
));
224 return (ISC_R_NOMEMORY
);
226 peer
->magic
= DNS_PEER_MAGIC
;
227 peer
->address
= *addr
;
228 peer
->prefixlen
= prefixlen
;
230 peer
->bogus
= ISC_FALSE
;
231 peer
->transfer_format
= dns_one_answer
;
233 peer
->request_ixfr
= ISC_FALSE
;
234 peer
->provide_ixfr
= ISC_FALSE
;
237 peer
->transfer_source
= NULL
;
238 peer
->notify_source
= NULL
;
239 peer
->query_source
= NULL
;
241 memset(&peer
->bitflags
, 0x0, sizeof(peer
->bitflags
));
243 ISC_LINK_INIT(peer
, next
);
247 return (ISC_R_SUCCESS
);
251 dns_peer_attach(dns_peer_t
*source
, dns_peer_t
**target
) {
252 REQUIRE(DNS_PEER_VALID(source
));
253 REQUIRE(target
!= NULL
);
254 REQUIRE(*target
== NULL
);
258 ENSURE(source
->refs
!= 0xffffffffU
);
264 dns_peer_detach(dns_peer_t
**peer
) {
267 REQUIRE(peer
!= NULL
);
268 REQUIRE(*peer
!= NULL
);
269 REQUIRE(DNS_PEER_VALID(*peer
));
273 REQUIRE(p
->refs
> 0);
283 peer_delete(dns_peer_t
**peer
) {
287 REQUIRE(peer
!= NULL
);
288 REQUIRE(DNS_PEER_VALID(*peer
));
292 REQUIRE(p
->refs
== 0);
298 if (p
->key
!= NULL
) {
299 dns_name_free(p
->key
, mem
);
300 isc_mem_put(mem
, p
->key
, sizeof(dns_name_t
));
303 if (p
->transfer_source
!= NULL
) {
304 isc_mem_put(mem
, p
->transfer_source
,
305 sizeof(*p
->transfer_source
));
308 isc_mem_put(mem
, p
, sizeof(*p
));
314 dns_peer_setbogus(dns_peer_t
*peer
, isc_boolean_t newval
) {
315 isc_boolean_t existed
;
317 REQUIRE(DNS_PEER_VALID(peer
));
319 existed
= DNS_BIT_CHECK(BOGUS_BIT
, &peer
->bitflags
);
321 peer
->bogus
= newval
;
322 DNS_BIT_SET(BOGUS_BIT
, &peer
->bitflags
);
324 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
328 dns_peer_getbogus(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
329 REQUIRE(DNS_PEER_VALID(peer
));
330 REQUIRE(retval
!= NULL
);
332 if (DNS_BIT_CHECK(BOGUS_BIT
, &peer
->bitflags
)) {
333 *retval
= peer
->bogus
;
334 return (ISC_R_SUCCESS
);
336 return (ISC_R_NOTFOUND
);
341 dns_peer_setprovideixfr(dns_peer_t
*peer
, isc_boolean_t newval
) {
342 isc_boolean_t existed
;
344 REQUIRE(DNS_PEER_VALID(peer
));
346 existed
= DNS_BIT_CHECK(PROVIDE_IXFR_BIT
, &peer
->bitflags
);
348 peer
->provide_ixfr
= newval
;
349 DNS_BIT_SET(PROVIDE_IXFR_BIT
, &peer
->bitflags
);
351 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
355 dns_peer_getprovideixfr(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
356 REQUIRE(DNS_PEER_VALID(peer
));
357 REQUIRE(retval
!= NULL
);
359 if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT
, &peer
->bitflags
)) {
360 *retval
= peer
->provide_ixfr
;
361 return (ISC_R_SUCCESS
);
363 return (ISC_R_NOTFOUND
);
368 dns_peer_setrequestixfr(dns_peer_t
*peer
, isc_boolean_t newval
) {
369 isc_boolean_t existed
;
371 REQUIRE(DNS_PEER_VALID(peer
));
373 existed
= DNS_BIT_CHECK(REQUEST_IXFR_BIT
, &peer
->bitflags
);
375 peer
->request_ixfr
= newval
;
376 DNS_BIT_SET(REQUEST_IXFR_BIT
, &peer
->bitflags
);
378 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
382 dns_peer_getrequestixfr(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
383 REQUIRE(DNS_PEER_VALID(peer
));
384 REQUIRE(retval
!= NULL
);
386 if (DNS_BIT_CHECK(REQUEST_IXFR_BIT
, &peer
->bitflags
)) {
387 *retval
= peer
->request_ixfr
;
388 return (ISC_R_SUCCESS
);
390 return (ISC_R_NOTFOUND
);
394 dns_peer_setsupportedns(dns_peer_t
*peer
, isc_boolean_t newval
) {
395 isc_boolean_t existed
;
397 REQUIRE(DNS_PEER_VALID(peer
));
399 existed
= DNS_BIT_CHECK(SUPPORT_EDNS_BIT
, &peer
->bitflags
);
401 peer
->support_edns
= newval
;
402 DNS_BIT_SET(SUPPORT_EDNS_BIT
, &peer
->bitflags
);
404 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
408 dns_peer_getsupportedns(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
409 REQUIRE(DNS_PEER_VALID(peer
));
410 REQUIRE(retval
!= NULL
);
412 if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT
, &peer
->bitflags
)) {
413 *retval
= peer
->support_edns
;
414 return (ISC_R_SUCCESS
);
416 return (ISC_R_NOTFOUND
);
420 dns_peer_setrequestnsid(dns_peer_t
*peer
, isc_boolean_t newval
) {
421 isc_boolean_t existed
;
423 REQUIRE(DNS_PEER_VALID(peer
));
425 existed
= DNS_BIT_CHECK(REQUEST_NSID_BIT
, &peer
->bitflags
);
427 peer
->request_nsid
= newval
;
428 DNS_BIT_SET(REQUEST_NSID_BIT
, &peer
->bitflags
);
430 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
434 dns_peer_getrequestnsid(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
435 REQUIRE(DNS_PEER_VALID(peer
));
436 REQUIRE(retval
!= NULL
);
438 if (DNS_BIT_CHECK(REQUEST_NSID_BIT
, &peer
->bitflags
)) {
439 *retval
= peer
->request_nsid
;
440 return (ISC_R_SUCCESS
);
442 return (ISC_R_NOTFOUND
);
446 dns_peer_settransfers(dns_peer_t
*peer
, isc_uint32_t newval
) {
447 isc_boolean_t existed
;
449 REQUIRE(DNS_PEER_VALID(peer
));
451 existed
= DNS_BIT_CHECK(TRANSFERS_BIT
, &peer
->bitflags
);
453 peer
->transfers
= newval
;
454 DNS_BIT_SET(TRANSFERS_BIT
, &peer
->bitflags
);
456 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
460 dns_peer_gettransfers(dns_peer_t
*peer
, isc_uint32_t
*retval
) {
461 REQUIRE(DNS_PEER_VALID(peer
));
462 REQUIRE(retval
!= NULL
);
464 if (DNS_BIT_CHECK(TRANSFERS_BIT
, &peer
->bitflags
)) {
465 *retval
= peer
->transfers
;
466 return (ISC_R_SUCCESS
);
468 return (ISC_R_NOTFOUND
);
473 dns_peer_settransferformat(dns_peer_t
*peer
, dns_transfer_format_t newval
) {
474 isc_boolean_t existed
;
476 REQUIRE(DNS_PEER_VALID(peer
));
478 existed
= DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT
,
481 peer
->transfer_format
= newval
;
482 DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT
, &peer
->bitflags
);
484 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
488 dns_peer_gettransferformat(dns_peer_t
*peer
, dns_transfer_format_t
*retval
) {
489 REQUIRE(DNS_PEER_VALID(peer
));
490 REQUIRE(retval
!= NULL
);
492 if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT
, &peer
->bitflags
)) {
493 *retval
= peer
->transfer_format
;
494 return (ISC_R_SUCCESS
);
496 return (ISC_R_NOTFOUND
);
501 dns_peer_getkey(dns_peer_t
*peer
, dns_name_t
**retval
) {
502 REQUIRE(DNS_PEER_VALID(peer
));
503 REQUIRE(retval
!= NULL
);
505 if (peer
->key
!= NULL
) {
509 return (peer
->key
== NULL
? ISC_R_NOTFOUND
: ISC_R_SUCCESS
);
513 dns_peer_setkey(dns_peer_t
*peer
, dns_name_t
**keyval
) {
514 isc_boolean_t exists
= ISC_FALSE
;
516 if (peer
->key
!= NULL
) {
517 dns_name_free(peer
->key
, peer
->mem
);
518 isc_mem_put(peer
->mem
, peer
->key
, sizeof(dns_name_t
));
525 return (exists
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
529 dns_peer_setkeybycharp(dns_peer_t
*peer
, const char *keyval
) {
531 dns_fixedname_t fname
;
535 dns_fixedname_init(&fname
);
536 isc_buffer_init(&b
, keyval
, strlen(keyval
));
537 isc_buffer_add(&b
, strlen(keyval
));
538 result
= dns_name_fromtext(dns_fixedname_name(&fname
), &b
,
539 dns_rootname
, ISC_FALSE
, NULL
);
540 if (result
!= ISC_R_SUCCESS
)
543 name
= isc_mem_get(peer
->mem
, sizeof(dns_name_t
));
545 return (ISC_R_NOMEMORY
);
547 dns_name_init(name
, NULL
);
548 result
= dns_name_dup(dns_fixedname_name(&fname
), peer
->mem
, name
);
549 if (result
!= ISC_R_SUCCESS
) {
550 isc_mem_put(peer
->mem
, name
, sizeof(dns_name_t
));
554 result
= dns_peer_setkey(peer
, &name
);
555 if (result
!= ISC_R_SUCCESS
)
556 isc_mem_put(peer
->mem
, name
, sizeof(dns_name_t
));
562 dns_peer_settransfersource(dns_peer_t
*peer
,
563 const isc_sockaddr_t
*transfer_source
)
565 REQUIRE(DNS_PEER_VALID(peer
));
567 if (peer
->transfer_source
!= NULL
) {
568 isc_mem_put(peer
->mem
, peer
->transfer_source
,
569 sizeof(*peer
->transfer_source
));
570 peer
->transfer_source
= NULL
;
572 if (transfer_source
!= NULL
) {
573 peer
->transfer_source
= isc_mem_get(peer
->mem
,
574 sizeof(*peer
->transfer_source
));
575 if (peer
->transfer_source
== NULL
)
576 return (ISC_R_NOMEMORY
);
578 *peer
->transfer_source
= *transfer_source
;
580 return (ISC_R_SUCCESS
);
584 dns_peer_gettransfersource(dns_peer_t
*peer
, isc_sockaddr_t
*transfer_source
) {
585 REQUIRE(DNS_PEER_VALID(peer
));
586 REQUIRE(transfer_source
!= NULL
);
588 if (peer
->transfer_source
== NULL
)
589 return (ISC_R_NOTFOUND
);
590 *transfer_source
= *peer
->transfer_source
;
591 return (ISC_R_SUCCESS
);
595 dns_peer_setnotifysource(dns_peer_t
*peer
,
596 const isc_sockaddr_t
*notify_source
)
598 REQUIRE(DNS_PEER_VALID(peer
));
600 if (peer
->notify_source
!= NULL
) {
601 isc_mem_put(peer
->mem
, peer
->notify_source
,
602 sizeof(*peer
->notify_source
));
603 peer
->notify_source
= NULL
;
605 if (notify_source
!= NULL
) {
606 peer
->notify_source
= isc_mem_get(peer
->mem
,
607 sizeof(*peer
->notify_source
));
608 if (peer
->notify_source
== NULL
)
609 return (ISC_R_NOMEMORY
);
611 *peer
->notify_source
= *notify_source
;
613 return (ISC_R_SUCCESS
);
617 dns_peer_getnotifysource(dns_peer_t
*peer
, isc_sockaddr_t
*notify_source
) {
618 REQUIRE(DNS_PEER_VALID(peer
));
619 REQUIRE(notify_source
!= NULL
);
621 if (peer
->notify_source
== NULL
)
622 return (ISC_R_NOTFOUND
);
623 *notify_source
= *peer
->notify_source
;
624 return (ISC_R_SUCCESS
);
628 dns_peer_setquerysource(dns_peer_t
*peer
, const isc_sockaddr_t
*query_source
) {
629 REQUIRE(DNS_PEER_VALID(peer
));
631 if (peer
->query_source
!= NULL
) {
632 isc_mem_put(peer
->mem
, peer
->query_source
,
633 sizeof(*peer
->query_source
));
634 peer
->query_source
= NULL
;
636 if (query_source
!= NULL
) {
637 peer
->query_source
= isc_mem_get(peer
->mem
,
638 sizeof(*peer
->query_source
));
639 if (peer
->query_source
== NULL
)
640 return (ISC_R_NOMEMORY
);
642 *peer
->query_source
= *query_source
;
644 return (ISC_R_SUCCESS
);
648 dns_peer_getquerysource(dns_peer_t
*peer
, isc_sockaddr_t
*query_source
) {
649 REQUIRE(DNS_PEER_VALID(peer
));
650 REQUIRE(query_source
!= NULL
);
652 if (peer
->query_source
== NULL
)
653 return (ISC_R_NOTFOUND
);
654 *query_source
= *peer
->query_source
;
655 return (ISC_R_SUCCESS
);
659 dns_peer_setudpsize(dns_peer_t
*peer
, isc_uint16_t udpsize
) {
660 isc_boolean_t existed
;
662 REQUIRE(DNS_PEER_VALID(peer
));
664 existed
= DNS_BIT_CHECK(SERVER_UDPSIZE_BIT
, &peer
->bitflags
);
666 peer
->udpsize
= udpsize
;
667 DNS_BIT_SET(SERVER_UDPSIZE_BIT
, &peer
->bitflags
);
669 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
673 dns_peer_getudpsize(dns_peer_t
*peer
, isc_uint16_t
*udpsize
) {
675 REQUIRE(DNS_PEER_VALID(peer
));
676 REQUIRE(udpsize
!= NULL
);
678 if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT
, &peer
->bitflags
)) {
679 *udpsize
= peer
->udpsize
;
680 return (ISC_R_SUCCESS
);
682 return (ISC_R_NOTFOUND
);
687 dns_peer_setmaxudp(dns_peer_t
*peer
, isc_uint16_t maxudp
) {
688 isc_boolean_t existed
;
690 REQUIRE(DNS_PEER_VALID(peer
));
692 existed
= DNS_BIT_CHECK(SERVER_MAXUDP_BIT
, &peer
->bitflags
);
694 peer
->maxudp
= maxudp
;
695 DNS_BIT_SET(SERVER_MAXUDP_BIT
, &peer
->bitflags
);
697 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
701 dns_peer_getmaxudp(dns_peer_t
*peer
, isc_uint16_t
*maxudp
) {
703 REQUIRE(DNS_PEER_VALID(peer
));
704 REQUIRE(maxudp
!= NULL
);
706 if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT
, &peer
->bitflags
)) {
707 *maxudp
= peer
->maxudp
;
708 return (ISC_R_SUCCESS
);
710 return (ISC_R_NOTFOUND
);