4 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: peer.c,v 1.33 2009/09/02 23:48:02 tbox Exp */
27 #include <isc/string.h>
29 #include <isc/sockaddr.h>
32 #include <dns/fixedname.h>
37 * Bit positions in the dns_peer_t structure flags field
40 #define SERVER_TRANSFER_FORMAT_BIT 1
41 #define TRANSFERS_BIT 2
42 #define PROVIDE_IXFR_BIT 3
43 #define REQUEST_IXFR_BIT 4
44 #define SUPPORT_EDNS_BIT 5
45 #define SERVER_UDPSIZE_BIT 6
46 #define SERVER_MAXUDP_BIT 7
47 #define REQUEST_NSID_BIT 8
50 peerlist_delete(dns_peerlist_t
**list
);
53 peer_delete(dns_peer_t
**peer
);
56 dns_peerlist_new(isc_mem_t
*mem
, dns_peerlist_t
**list
) {
59 REQUIRE(list
!= NULL
);
61 l
= isc_mem_get(mem
, sizeof(*l
));
63 return (ISC_R_NOMEMORY
);
65 ISC_LIST_INIT(l
->elements
);
68 l
->magic
= DNS_PEERLIST_MAGIC
;
72 return (ISC_R_SUCCESS
);
76 dns_peerlist_attach(dns_peerlist_t
*source
, dns_peerlist_t
**target
) {
77 REQUIRE(DNS_PEERLIST_VALID(source
));
78 REQUIRE(target
!= NULL
);
79 REQUIRE(*target
== NULL
);
83 ENSURE(source
->refs
!= 0xffffffffU
);
89 dns_peerlist_detach(dns_peerlist_t
**list
) {
90 dns_peerlist_t
*plist
;
92 REQUIRE(list
!= NULL
);
93 REQUIRE(*list
!= NULL
);
94 REQUIRE(DNS_PEERLIST_VALID(*list
));
99 REQUIRE(plist
->refs
> 0);
103 if (plist
->refs
== 0)
104 peerlist_delete(&plist
);
108 peerlist_delete(dns_peerlist_t
**list
) {
110 dns_peer_t
*server
, *stmp
;
112 REQUIRE(list
!= NULL
);
113 REQUIRE(DNS_PEERLIST_VALID(*list
));
117 REQUIRE(l
->refs
== 0);
119 server
= ISC_LIST_HEAD(l
->elements
);
120 while (server
!= NULL
) {
121 stmp
= ISC_LIST_NEXT(server
, next
);
122 ISC_LIST_UNLINK(l
->elements
, server
, next
);
123 dns_peer_detach(&server
);
128 isc_mem_put(l
->mem
, l
, sizeof(*l
));
134 dns_peerlist_addpeer(dns_peerlist_t
*peers
, dns_peer_t
*peer
) {
135 dns_peer_t
*p
= NULL
;
137 dns_peer_attach(peer
, &p
);
140 * More specifics to front of list.
142 for (p
= ISC_LIST_HEAD(peers
->elements
);
144 p
= ISC_LIST_NEXT(p
, next
))
145 if (p
->prefixlen
< peer
->prefixlen
)
149 ISC_LIST_INSERTBEFORE(peers
->elements
, p
, peer
, next
);
151 ISC_LIST_APPEND(peers
->elements
, peer
, next
);
156 dns_peerlist_peerbyaddr(dns_peerlist_t
*servers
,
157 isc_netaddr_t
*addr
, dns_peer_t
**retval
)
162 REQUIRE(retval
!= NULL
);
163 REQUIRE(DNS_PEERLIST_VALID(servers
));
165 server
= ISC_LIST_HEAD(servers
->elements
);
166 while (server
!= NULL
) {
167 if (isc_netaddr_eqprefix(addr
, &server
->address
,
171 server
= ISC_LIST_NEXT(server
, next
);
174 if (server
!= NULL
) {
178 res
= ISC_R_NOTFOUND
;
187 dns_peerlist_currpeer(dns_peerlist_t
*peers
, dns_peer_t
**retval
) {
188 dns_peer_t
*p
= NULL
;
190 p
= ISC_LIST_TAIL(peers
->elements
);
192 dns_peer_attach(p
, retval
);
194 return (ISC_R_SUCCESS
);
198 dns_peer_new(isc_mem_t
*mem
, isc_netaddr_t
*addr
, dns_peer_t
**peerptr
) {
199 unsigned int prefixlen
= 0;
201 REQUIRE(peerptr
!= NULL
);
202 switch(addr
->family
) {
213 return (dns_peer_newprefix(mem
, addr
, prefixlen
, peerptr
));
217 dns_peer_newprefix(isc_mem_t
*mem
, isc_netaddr_t
*addr
, unsigned int prefixlen
,
218 dns_peer_t
**peerptr
)
222 REQUIRE(peerptr
!= NULL
);
224 peer
= isc_mem_get(mem
, sizeof(*peer
));
226 return (ISC_R_NOMEMORY
);
228 peer
->magic
= DNS_PEER_MAGIC
;
229 peer
->address
= *addr
;
230 peer
->prefixlen
= prefixlen
;
232 peer
->bogus
= ISC_FALSE
;
233 peer
->transfer_format
= dns_one_answer
;
235 peer
->request_ixfr
= ISC_FALSE
;
236 peer
->provide_ixfr
= ISC_FALSE
;
239 peer
->transfer_source
= NULL
;
240 peer
->notify_source
= NULL
;
241 peer
->query_source
= NULL
;
243 memset(&peer
->bitflags
, 0x0, sizeof(peer
->bitflags
));
245 ISC_LINK_INIT(peer
, next
);
249 return (ISC_R_SUCCESS
);
253 dns_peer_attach(dns_peer_t
*source
, dns_peer_t
**target
) {
254 REQUIRE(DNS_PEER_VALID(source
));
255 REQUIRE(target
!= NULL
);
256 REQUIRE(*target
== NULL
);
260 ENSURE(source
->refs
!= 0xffffffffU
);
266 dns_peer_detach(dns_peer_t
**peer
) {
269 REQUIRE(peer
!= NULL
);
270 REQUIRE(*peer
!= NULL
);
271 REQUIRE(DNS_PEER_VALID(*peer
));
275 REQUIRE(p
->refs
> 0);
285 peer_delete(dns_peer_t
**peer
) {
289 REQUIRE(peer
!= NULL
);
290 REQUIRE(DNS_PEER_VALID(*peer
));
294 REQUIRE(p
->refs
== 0);
300 if (p
->key
!= NULL
) {
301 dns_name_free(p
->key
, mem
);
302 isc_mem_put(mem
, p
->key
, sizeof(dns_name_t
));
305 if (p
->transfer_source
!= NULL
) {
306 isc_mem_put(mem
, p
->transfer_source
,
307 sizeof(*p
->transfer_source
));
310 isc_mem_put(mem
, p
, sizeof(*p
));
316 dns_peer_setbogus(dns_peer_t
*peer
, isc_boolean_t newval
) {
317 isc_boolean_t existed
;
319 REQUIRE(DNS_PEER_VALID(peer
));
321 existed
= DNS_BIT_CHECK(BOGUS_BIT
, &peer
->bitflags
);
323 peer
->bogus
= newval
;
324 DNS_BIT_SET(BOGUS_BIT
, &peer
->bitflags
);
326 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
330 dns_peer_getbogus(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
331 REQUIRE(DNS_PEER_VALID(peer
));
332 REQUIRE(retval
!= NULL
);
334 if (DNS_BIT_CHECK(BOGUS_BIT
, &peer
->bitflags
)) {
335 *retval
= peer
->bogus
;
336 return (ISC_R_SUCCESS
);
338 return (ISC_R_NOTFOUND
);
343 dns_peer_setprovideixfr(dns_peer_t
*peer
, isc_boolean_t newval
) {
344 isc_boolean_t existed
;
346 REQUIRE(DNS_PEER_VALID(peer
));
348 existed
= DNS_BIT_CHECK(PROVIDE_IXFR_BIT
, &peer
->bitflags
);
350 peer
->provide_ixfr
= newval
;
351 DNS_BIT_SET(PROVIDE_IXFR_BIT
, &peer
->bitflags
);
353 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
357 dns_peer_getprovideixfr(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
358 REQUIRE(DNS_PEER_VALID(peer
));
359 REQUIRE(retval
!= NULL
);
361 if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT
, &peer
->bitflags
)) {
362 *retval
= peer
->provide_ixfr
;
363 return (ISC_R_SUCCESS
);
365 return (ISC_R_NOTFOUND
);
370 dns_peer_setrequestixfr(dns_peer_t
*peer
, isc_boolean_t newval
) {
371 isc_boolean_t existed
;
373 REQUIRE(DNS_PEER_VALID(peer
));
375 existed
= DNS_BIT_CHECK(REQUEST_IXFR_BIT
, &peer
->bitflags
);
377 peer
->request_ixfr
= newval
;
378 DNS_BIT_SET(REQUEST_IXFR_BIT
, &peer
->bitflags
);
380 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
384 dns_peer_getrequestixfr(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
385 REQUIRE(DNS_PEER_VALID(peer
));
386 REQUIRE(retval
!= NULL
);
388 if (DNS_BIT_CHECK(REQUEST_IXFR_BIT
, &peer
->bitflags
)) {
389 *retval
= peer
->request_ixfr
;
390 return (ISC_R_SUCCESS
);
392 return (ISC_R_NOTFOUND
);
396 dns_peer_setsupportedns(dns_peer_t
*peer
, isc_boolean_t newval
) {
397 isc_boolean_t existed
;
399 REQUIRE(DNS_PEER_VALID(peer
));
401 existed
= DNS_BIT_CHECK(SUPPORT_EDNS_BIT
, &peer
->bitflags
);
403 peer
->support_edns
= newval
;
404 DNS_BIT_SET(SUPPORT_EDNS_BIT
, &peer
->bitflags
);
406 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
410 dns_peer_getsupportedns(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
411 REQUIRE(DNS_PEER_VALID(peer
));
412 REQUIRE(retval
!= NULL
);
414 if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT
, &peer
->bitflags
)) {
415 *retval
= peer
->support_edns
;
416 return (ISC_R_SUCCESS
);
418 return (ISC_R_NOTFOUND
);
422 dns_peer_setrequestnsid(dns_peer_t
*peer
, isc_boolean_t newval
) {
423 isc_boolean_t existed
;
425 REQUIRE(DNS_PEER_VALID(peer
));
427 existed
= DNS_BIT_CHECK(REQUEST_NSID_BIT
, &peer
->bitflags
);
429 peer
->request_nsid
= newval
;
430 DNS_BIT_SET(REQUEST_NSID_BIT
, &peer
->bitflags
);
432 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
436 dns_peer_getrequestnsid(dns_peer_t
*peer
, isc_boolean_t
*retval
) {
437 REQUIRE(DNS_PEER_VALID(peer
));
438 REQUIRE(retval
!= NULL
);
440 if (DNS_BIT_CHECK(REQUEST_NSID_BIT
, &peer
->bitflags
)) {
441 *retval
= peer
->request_nsid
;
442 return (ISC_R_SUCCESS
);
444 return (ISC_R_NOTFOUND
);
448 dns_peer_settransfers(dns_peer_t
*peer
, isc_uint32_t newval
) {
449 isc_boolean_t existed
;
451 REQUIRE(DNS_PEER_VALID(peer
));
453 existed
= DNS_BIT_CHECK(TRANSFERS_BIT
, &peer
->bitflags
);
455 peer
->transfers
= newval
;
456 DNS_BIT_SET(TRANSFERS_BIT
, &peer
->bitflags
);
458 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
462 dns_peer_gettransfers(dns_peer_t
*peer
, isc_uint32_t
*retval
) {
463 REQUIRE(DNS_PEER_VALID(peer
));
464 REQUIRE(retval
!= NULL
);
466 if (DNS_BIT_CHECK(TRANSFERS_BIT
, &peer
->bitflags
)) {
467 *retval
= peer
->transfers
;
468 return (ISC_R_SUCCESS
);
470 return (ISC_R_NOTFOUND
);
475 dns_peer_settransferformat(dns_peer_t
*peer
, dns_transfer_format_t newval
) {
476 isc_boolean_t existed
;
478 REQUIRE(DNS_PEER_VALID(peer
));
480 existed
= DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT
,
483 peer
->transfer_format
= newval
;
484 DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT
, &peer
->bitflags
);
486 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
490 dns_peer_gettransferformat(dns_peer_t
*peer
, dns_transfer_format_t
*retval
) {
491 REQUIRE(DNS_PEER_VALID(peer
));
492 REQUIRE(retval
!= NULL
);
494 if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT
, &peer
->bitflags
)) {
495 *retval
= peer
->transfer_format
;
496 return (ISC_R_SUCCESS
);
498 return (ISC_R_NOTFOUND
);
503 dns_peer_getkey(dns_peer_t
*peer
, dns_name_t
**retval
) {
504 REQUIRE(DNS_PEER_VALID(peer
));
505 REQUIRE(retval
!= NULL
);
507 if (peer
->key
!= NULL
) {
511 return (peer
->key
== NULL
? ISC_R_NOTFOUND
: ISC_R_SUCCESS
);
515 dns_peer_setkey(dns_peer_t
*peer
, dns_name_t
**keyval
) {
516 isc_boolean_t exists
= ISC_FALSE
;
518 if (peer
->key
!= NULL
) {
519 dns_name_free(peer
->key
, peer
->mem
);
520 isc_mem_put(peer
->mem
, peer
->key
, sizeof(dns_name_t
));
527 return (exists
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
531 dns_peer_setkeybycharp(dns_peer_t
*peer
, const char *keyval
) {
533 dns_fixedname_t fname
;
537 dns_fixedname_init(&fname
);
538 isc_buffer_init(&b
, keyval
, strlen(keyval
));
539 isc_buffer_add(&b
, strlen(keyval
));
540 result
= dns_name_fromtext(dns_fixedname_name(&fname
), &b
,
541 dns_rootname
, 0, NULL
);
542 if (result
!= ISC_R_SUCCESS
)
545 name
= isc_mem_get(peer
->mem
, sizeof(dns_name_t
));
547 return (ISC_R_NOMEMORY
);
549 dns_name_init(name
, NULL
);
550 result
= dns_name_dup(dns_fixedname_name(&fname
), peer
->mem
, name
);
551 if (result
!= ISC_R_SUCCESS
) {
552 isc_mem_put(peer
->mem
, name
, sizeof(dns_name_t
));
556 result
= dns_peer_setkey(peer
, &name
);
557 if (result
!= ISC_R_SUCCESS
)
558 isc_mem_put(peer
->mem
, name
, sizeof(dns_name_t
));
564 dns_peer_settransfersource(dns_peer_t
*peer
,
565 const isc_sockaddr_t
*transfer_source
)
567 REQUIRE(DNS_PEER_VALID(peer
));
569 if (peer
->transfer_source
!= NULL
) {
570 isc_mem_put(peer
->mem
, peer
->transfer_source
,
571 sizeof(*peer
->transfer_source
));
572 peer
->transfer_source
= NULL
;
574 if (transfer_source
!= NULL
) {
575 peer
->transfer_source
= isc_mem_get(peer
->mem
,
576 sizeof(*peer
->transfer_source
));
577 if (peer
->transfer_source
== NULL
)
578 return (ISC_R_NOMEMORY
);
580 *peer
->transfer_source
= *transfer_source
;
582 return (ISC_R_SUCCESS
);
586 dns_peer_gettransfersource(dns_peer_t
*peer
, isc_sockaddr_t
*transfer_source
) {
587 REQUIRE(DNS_PEER_VALID(peer
));
588 REQUIRE(transfer_source
!= NULL
);
590 if (peer
->transfer_source
== NULL
)
591 return (ISC_R_NOTFOUND
);
592 *transfer_source
= *peer
->transfer_source
;
593 return (ISC_R_SUCCESS
);
597 dns_peer_setnotifysource(dns_peer_t
*peer
,
598 const isc_sockaddr_t
*notify_source
)
600 REQUIRE(DNS_PEER_VALID(peer
));
602 if (peer
->notify_source
!= NULL
) {
603 isc_mem_put(peer
->mem
, peer
->notify_source
,
604 sizeof(*peer
->notify_source
));
605 peer
->notify_source
= NULL
;
607 if (notify_source
!= NULL
) {
608 peer
->notify_source
= isc_mem_get(peer
->mem
,
609 sizeof(*peer
->notify_source
));
610 if (peer
->notify_source
== NULL
)
611 return (ISC_R_NOMEMORY
);
613 *peer
->notify_source
= *notify_source
;
615 return (ISC_R_SUCCESS
);
619 dns_peer_getnotifysource(dns_peer_t
*peer
, isc_sockaddr_t
*notify_source
) {
620 REQUIRE(DNS_PEER_VALID(peer
));
621 REQUIRE(notify_source
!= NULL
);
623 if (peer
->notify_source
== NULL
)
624 return (ISC_R_NOTFOUND
);
625 *notify_source
= *peer
->notify_source
;
626 return (ISC_R_SUCCESS
);
630 dns_peer_setquerysource(dns_peer_t
*peer
, const isc_sockaddr_t
*query_source
) {
631 REQUIRE(DNS_PEER_VALID(peer
));
633 if (peer
->query_source
!= NULL
) {
634 isc_mem_put(peer
->mem
, peer
->query_source
,
635 sizeof(*peer
->query_source
));
636 peer
->query_source
= NULL
;
638 if (query_source
!= NULL
) {
639 peer
->query_source
= isc_mem_get(peer
->mem
,
640 sizeof(*peer
->query_source
));
641 if (peer
->query_source
== NULL
)
642 return (ISC_R_NOMEMORY
);
644 *peer
->query_source
= *query_source
;
646 return (ISC_R_SUCCESS
);
650 dns_peer_getquerysource(dns_peer_t
*peer
, isc_sockaddr_t
*query_source
) {
651 REQUIRE(DNS_PEER_VALID(peer
));
652 REQUIRE(query_source
!= NULL
);
654 if (peer
->query_source
== NULL
)
655 return (ISC_R_NOTFOUND
);
656 *query_source
= *peer
->query_source
;
657 return (ISC_R_SUCCESS
);
661 dns_peer_setudpsize(dns_peer_t
*peer
, isc_uint16_t udpsize
) {
662 isc_boolean_t existed
;
664 REQUIRE(DNS_PEER_VALID(peer
));
666 existed
= DNS_BIT_CHECK(SERVER_UDPSIZE_BIT
, &peer
->bitflags
);
668 peer
->udpsize
= udpsize
;
669 DNS_BIT_SET(SERVER_UDPSIZE_BIT
, &peer
->bitflags
);
671 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
675 dns_peer_getudpsize(dns_peer_t
*peer
, isc_uint16_t
*udpsize
) {
677 REQUIRE(DNS_PEER_VALID(peer
));
678 REQUIRE(udpsize
!= NULL
);
680 if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT
, &peer
->bitflags
)) {
681 *udpsize
= peer
->udpsize
;
682 return (ISC_R_SUCCESS
);
684 return (ISC_R_NOTFOUND
);
689 dns_peer_setmaxudp(dns_peer_t
*peer
, isc_uint16_t maxudp
) {
690 isc_boolean_t existed
;
692 REQUIRE(DNS_PEER_VALID(peer
));
694 existed
= DNS_BIT_CHECK(SERVER_MAXUDP_BIT
, &peer
->bitflags
);
696 peer
->maxudp
= maxudp
;
697 DNS_BIT_SET(SERVER_MAXUDP_BIT
, &peer
->bitflags
);
699 return (existed
? ISC_R_EXISTS
: ISC_R_SUCCESS
);
703 dns_peer_getmaxudp(dns_peer_t
*peer
, isc_uint16_t
*maxudp
) {
705 REQUIRE(DNS_PEER_VALID(peer
));
706 REQUIRE(maxudp
!= NULL
);
708 if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT
, &peer
->bitflags
)) {
709 *maxudp
= peer
->maxudp
;
710 return (ISC_R_SUCCESS
);
712 return (ISC_R_NOTFOUND
);