No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / bind / dist / lib / dns / peer.c
blob49e85214af9c8ab69cd101325c2b7c6f750a1d2b
1 /* $NetBSD$ */
3 /*
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 */
22 /*! \file */
24 #include <config.h>
26 #include <isc/mem.h>
27 #include <isc/string.h>
28 #include <isc/util.h>
29 #include <isc/sockaddr.h>
31 #include <dns/bit.h>
32 #include <dns/fixedname.h>
33 #include <dns/name.h>
34 #include <dns/peer.h>
36 /*%
37 * Bit positions in the dns_peer_t structure flags field
39 #define BOGUS_BIT 0
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
49 static void
50 peerlist_delete(dns_peerlist_t **list);
52 static void
53 peer_delete(dns_peer_t **peer);
55 isc_result_t
56 dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) {
57 dns_peerlist_t *l;
59 REQUIRE(list != NULL);
61 l = isc_mem_get(mem, sizeof(*l));
62 if (l == NULL)
63 return (ISC_R_NOMEMORY);
65 ISC_LIST_INIT(l->elements);
66 l->mem = mem;
67 l->refs = 1;
68 l->magic = DNS_PEERLIST_MAGIC;
70 *list = l;
72 return (ISC_R_SUCCESS);
75 void
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);
81 source->refs++;
83 ENSURE(source->refs != 0xffffffffU);
85 *target = source;
88 void
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));
96 plist = *list;
97 *list = NULL;
99 REQUIRE(plist->refs > 0);
101 plist->refs--;
103 if (plist->refs == 0)
104 peerlist_delete(&plist);
107 static void
108 peerlist_delete(dns_peerlist_t **list) {
109 dns_peerlist_t *l;
110 dns_peer_t *server, *stmp;
112 REQUIRE(list != NULL);
113 REQUIRE(DNS_PEERLIST_VALID(*list));
115 l = *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);
124 server = stmp;
127 l->magic = 0;
128 isc_mem_put(l->mem, l, sizeof(*l));
130 *list = NULL;
133 void
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);
143 p != NULL;
144 p = ISC_LIST_NEXT(p, next))
145 if (p->prefixlen < peer->prefixlen)
146 break;
148 if (p != NULL)
149 ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next);
150 else
151 ISC_LIST_APPEND(peers->elements, peer, next);
155 isc_result_t
156 dns_peerlist_peerbyaddr(dns_peerlist_t *servers,
157 isc_netaddr_t *addr, dns_peer_t **retval)
159 dns_peer_t *server;
160 isc_result_t res;
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,
168 server->prefixlen))
169 break;
171 server = ISC_LIST_NEXT(server, next);
174 if (server != NULL) {
175 *retval = server;
176 res = ISC_R_SUCCESS;
177 } else {
178 res = ISC_R_NOTFOUND;
181 return (res);
186 isc_result_t
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);
197 isc_result_t
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) {
203 case AF_INET:
204 prefixlen = 32;
205 break;
206 case AF_INET6:
207 prefixlen = 128;
208 break;
209 default:
210 INSIST(0);
213 return (dns_peer_newprefix(mem, addr, prefixlen, peerptr));
216 isc_result_t
217 dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen,
218 dns_peer_t **peerptr)
220 dns_peer_t *peer;
222 REQUIRE(peerptr != NULL);
224 peer = isc_mem_get(mem, sizeof(*peer));
225 if (peer == NULL)
226 return (ISC_R_NOMEMORY);
228 peer->magic = DNS_PEER_MAGIC;
229 peer->address = *addr;
230 peer->prefixlen = prefixlen;
231 peer->mem = mem;
232 peer->bogus = ISC_FALSE;
233 peer->transfer_format = dns_one_answer;
234 peer->transfers = 0;
235 peer->request_ixfr = ISC_FALSE;
236 peer->provide_ixfr = ISC_FALSE;
237 peer->key = NULL;
238 peer->refs = 1;
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);
247 *peerptr = peer;
249 return (ISC_R_SUCCESS);
252 void
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);
258 source->refs++;
260 ENSURE(source->refs != 0xffffffffU);
262 *target = source;
265 void
266 dns_peer_detach(dns_peer_t **peer) {
267 dns_peer_t *p;
269 REQUIRE(peer != NULL);
270 REQUIRE(*peer != NULL);
271 REQUIRE(DNS_PEER_VALID(*peer));
273 p = *peer;
275 REQUIRE(p->refs > 0);
277 *peer = NULL;
278 p->refs--;
280 if (p->refs == 0)
281 peer_delete(&p);
284 static void
285 peer_delete(dns_peer_t **peer) {
286 dns_peer_t *p;
287 isc_mem_t *mem;
289 REQUIRE(peer != NULL);
290 REQUIRE(DNS_PEER_VALID(*peer));
292 p = *peer;
294 REQUIRE(p->refs == 0);
296 mem = p->mem;
297 p->mem = NULL;
298 p->magic = 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));
312 *peer = NULL;
315 isc_result_t
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);
329 isc_result_t
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);
337 } else
338 return (ISC_R_NOTFOUND);
342 isc_result_t
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);
356 isc_result_t
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);
364 } else {
365 return (ISC_R_NOTFOUND);
369 isc_result_t
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);
383 isc_result_t
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);
391 } else
392 return (ISC_R_NOTFOUND);
395 isc_result_t
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);
409 isc_result_t
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);
417 } else
418 return (ISC_R_NOTFOUND);
421 isc_result_t
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);
435 isc_result_t
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);
443 } else
444 return (ISC_R_NOTFOUND);
447 isc_result_t
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);
461 isc_result_t
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);
469 } else {
470 return (ISC_R_NOTFOUND);
474 isc_result_t
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,
481 &peer->bitflags);
483 peer->transfer_format = newval;
484 DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags);
486 return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
489 isc_result_t
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);
497 } else {
498 return (ISC_R_NOTFOUND);
502 isc_result_t
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) {
508 *retval = peer->key;
511 return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
514 isc_result_t
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));
521 exists = ISC_TRUE;
524 peer->key = *keyval;
525 *keyval = NULL;
527 return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS);
530 isc_result_t
531 dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
532 isc_buffer_t b;
533 dns_fixedname_t fname;
534 dns_name_t *name;
535 isc_result_t result;
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)
543 return (result);
545 name = isc_mem_get(peer->mem, sizeof(dns_name_t));
546 if (name == NULL)
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));
553 return (result);
556 result = dns_peer_setkey(peer, &name);
557 if (result != ISC_R_SUCCESS)
558 isc_mem_put(peer->mem, name, sizeof(dns_name_t));
560 return (result);
563 isc_result_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);
585 isc_result_t
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);
596 isc_result_t
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);
618 isc_result_t
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);
629 isc_result_t
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);
649 isc_result_t
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);
660 isc_result_t
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);
674 isc_result_t
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);
683 } else {
684 return (ISC_R_NOTFOUND);
688 isc_result_t
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);
702 isc_result_t
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);
711 } else {
712 return (ISC_R_NOTFOUND);