diff --git a/lib/dns/include/dns/peer.h b/lib/dns/include/dns/peer.h new file mode 100644 index 0000000000..90278ad990 --- /dev/null +++ b/lib/dns/include/dns/peer.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 1999, 2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef DNS_PEER_H +#define DNS_PEER_H 1 + +/***** + ***** Module Info + *****/ + +/* + * Data structures for peers (e.g. a 'server' config file statement) + */ + +/*** + *** Imports + ***/ + +#include + +#include + +#include +#include +#include + +#include +#include +#include + + +#define DNS_PEERLIST_MAGIC 0x7365524c /* seRL */ +#define DNS_PEER_MAGIC 0x53457276 /* SErv */ + +#define DNS_PEERLIST_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEERLIST_MAGIC) +#define DNS_PEER_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEER_MAGIC) + + +/*** + *** Types + ***/ + +typedef struct dns_peer dns_peer_t; +typedef struct dns_peerlist dns_peerlist_t; + +struct dns_peerlist +{ + isc_uint32_t magic; + isc_uint32_t refs; + + isc_mem_t *mem; + + ISC_LIST(dns_peer_t) elements; +}; + + +struct dns_peer +{ + isc_uint32_t magic; + isc_uint32_t refs; + + isc_mem_t *mem; + + isc_netaddr_t address; + isc_boolean_t bogus; + dns_transfer_format_t transfer_format; + int transfers; + isc_boolean_t support_ixfr; + dns_name_t *key; + + isc_uint32_t bitflags; + + ISC_LINK(dns_peer_t) next; +}; + + +/*** + *** Functions + ***/ + +isc_result_t dns_peerlist_new(isc_mem_t *mem, + dns_peerlist_t **list); +void dns_peerlist_attach(dns_peerlist_t *source, + dns_peerlist_t **target); +void dns_peerlist_detach(dns_peerlist_t **list); +void dns_peerlist_print(FILE *fp, int indent, + dns_peerlist_t *peers); + +/* After return caller still holds a reference to peer. */ +void dns_peerlist_addpeer(dns_peerlist_t *peers, + dns_peer_t *peer); + +/* ditto */ +isc_result_t dns_peerlist_peerbyaddr(dns_peerlist_t *peers, + isc_netaddr_t *addr, + dns_peer_t **retval); + +/* what he said. */ +isc_result_t dns_peerlist_currpeer(dns_peerlist_t *peers, + dns_peer_t **retval); + + + +isc_result_t dns_peer_new(isc_mem_t *mem, + isc_netaddr_t *ipaddr, + dns_peer_t **peer); +isc_result_t dns_peer_attach(dns_peer_t *source, dns_peer_t **target); +isc_result_t dns_peer_detach(dns_peer_t **list); +void dns_peer_print(FILE *fp, int indent, + dns_peer_t *peer); + +isc_result_t dns_peer_setbogus(dns_peer_t *peer, + isc_boolean_t newval); +isc_result_t dns_peer_getbogus(dns_peer_t *peer, + isc_boolean_t *retval); +isc_result_t dns_peer_setsupportixfr(dns_peer_t *peer, + isc_boolean_t newval); +isc_result_t dns_peer_getsupportixfr(dns_peer_t *peer, + isc_boolean_t *retval); +isc_result_t dns_peer_settransfers(dns_peer_t *peer, + isc_int32_t newval); +isc_result_t dns_peer_gettransfers(dns_peer_t *peer, + isc_int32_t *retval); +isc_result_t dns_peer_settransferformat(dns_peer_t *peer, + dns_transfer_format_t newval); +isc_result_t dns_peer_gettransferformat(dns_peer_t *peer, + dns_transfer_format_t *retval); +isc_result_t dns_peer_setkeybycharp(dns_peer_t *peer, + const char *keyval); +isc_result_t dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval); +isc_result_t dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval); + + +#endif /* DNS_CONFIG_CONFSERV_H */ diff --git a/lib/dns/peer.c b/lib/dns/peer.c new file mode 100644 index 0000000000..631d4b4fa5 --- /dev/null +++ b/lib/dns/peer.c @@ -0,0 +1,465 @@ +/* + * Copyright (C) 1999, 2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include + +#include /* XXXRTH */ + +#include + +#include +#include +#include + +#include +#include +#include + + +/* + * Bit positions in the dns_peer_t structure flags field + */ +#define BOGUS_BIT 0 +#define SERVER_TRANSFER_FORMAT_BIT 1 +#define TRANSFERS_BIT 2 +#define SUPPORT_IXFR_BIT 3 + +static isc_result_t dns_peerlist_delete(dns_peerlist_t **list); +static isc_result_t dns_peer_delete(dns_peer_t **peer); + +isc_result_t +dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) +{ + dns_peerlist_t *l; + + REQUIRE(list != NULL); + + l = isc_mem_get(mem, sizeof *l); + if (l == NULL) { + return (ISC_R_NOMEMORY); + } + + ISC_LIST_INIT(l->elements); + l->mem = mem; + l->refs = 1; + l->magic = DNS_PEERLIST_MAGIC; + + *list = l; + + return (ISC_R_SUCCESS); +} + + +void +dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) +{ + REQUIRE(DNS_PEERLIST_VALID(source)); + REQUIRE(target != NULL); + REQUIRE(*target == NULL); + + source->refs++; + + ENSURE(source->refs != 0xffffffffU); + + *target = source; +} + + +void +dns_peerlist_detach(dns_peerlist_t **list) +{ + dns_peerlist_t *plist; + + REQUIRE(list != NULL); + REQUIRE(*list != NULL); + REQUIRE(DNS_PEERLIST_VALID(*list)); + + plist = *list; + *list = NULL; + + REQUIRE(plist->refs > 0); + + plist->refs--; + + if (plist->refs == 0) { + dns_peerlist_delete(&plist); + } +} + +static isc_result_t +dns_peerlist_delete(dns_peerlist_t **list) +{ + dns_peerlist_t *l; + dns_peer_t *server, *stmp; + isc_result_t r; + + REQUIRE(list != NULL); + REQUIRE(DNS_PEERLIST_VALID(*list)); + + l = *list; + + REQUIRE(l->refs == 0); + + server = ISC_LIST_HEAD(l->elements); + while (server != NULL) { + stmp = ISC_LIST_NEXT(server, next); + ISC_LIST_UNLINK(l->elements, server, next); + r = dns_peer_detach(&server); + if (r != ISC_R_SUCCESS) { + return (r); + } + + server = stmp; + } + + l->magic = 0; + isc_mem_put(l->mem, l, sizeof *l); + + *list = NULL; + + return (ISC_R_SUCCESS); +} + + +void +dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) +{ + dns_peer_t *p = NULL; + + dns_peer_attach(peer, &p); + + ISC_LIST_APPEND(peers->elements, peer, next); +} + + + +isc_result_t +dns_peerlist_peerbyaddr(dns_peerlist_t *servers, + isc_netaddr_t *addr, dns_peer_t **retval) +{ + dns_peer_t *server; + isc_result_t res; + + REQUIRE(retval != NULL); + REQUIRE(DNS_PEERLIST_VALID(servers)); + + server = ISC_LIST_HEAD(servers->elements); + while (server != NULL) { + if (isc_netaddr_equal(addr, &server->address)) { + break; + } + + server = ISC_LIST_NEXT(server, next); + } + + if (server != NULL) { + *retval = server; + res = ISC_R_SUCCESS; + } else { + res = ISC_R_NOTFOUND; + } + + return (res); +} + + + +isc_result_t +dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) +{ + dns_peer_t *p = NULL; + + p = ISC_LIST_TAIL(peers->elements); + + dns_peer_attach(p, retval); + + return (ISC_R_SUCCESS); +} + + + + + + + +isc_result_t +dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) +{ + dns_peer_t *peer; + + REQUIRE(peerptr != NULL); + + peer = isc_mem_get(mem, sizeof *peer); + if (peer == NULL) { + return (ISC_R_NOMEMORY); + } + + peer->magic = DNS_PEER_MAGIC; + peer->address = *addr; + peer->mem = mem; + peer->bogus = ISC_FALSE; + peer->transfer_format = dns_one_answer; + peer->transfers = 0; + peer->support_ixfr = ISC_FALSE; + peer->key = NULL; + peer->refs = 1; + + memset(&peer->bitflags, 0x0, sizeof peer->bitflags); + + ISC_LINK_INIT(peer, next); + + *peerptr = peer; + + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_attach(dns_peer_t *source, dns_peer_t **target) +{ + REQUIRE(DNS_PEER_VALID(source)); + REQUIRE(target != NULL); + REQUIRE(*target == NULL); + + source->refs++; + + ENSURE(source->refs != 0xffffffffU); + + *target = source; + + return (ISC_R_SUCCESS); +} + + +isc_result_t +dns_peer_detach(dns_peer_t **peer) +{ + dns_peer_t *p; + + REQUIRE(peer != NULL); + REQUIRE(*peer != NULL); + REQUIRE(DNS_PEER_VALID(*peer)); + + p = *peer; + + REQUIRE(p->refs > 0); + + *peer = NULL; + p->refs--; + + if (p->refs == 0) { + dns_peer_delete(&p); + } + + return (ISC_R_SUCCESS); +} + + +static isc_result_t +dns_peer_delete(dns_peer_t **peer) +{ + dns_peer_t *p; + isc_mem_t *mem; + + REQUIRE(peer != NULL); + REQUIRE(DNS_PEER_VALID(*peer)); + + p = *peer; + + REQUIRE(p->refs == 0); + + mem = p->mem; + p->mem = NULL; + p->magic = 0; + + if (p->key != NULL) { + dns_name_free(p->key, mem); + isc_mem_put(mem, p->key, sizeof(dns_name_t)); + } + + isc_mem_put(mem, p, sizeof *p); + + *peer = NULL; + + return (ISC_R_SUCCESS); +} + + +isc_result_t +dns_peer_setbogus(dns_peer_t *peer, isc_boolean_t newval) +{ + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_CHECKBIT(BOGUS_BIT, &peer->bitflags); + + peer->bogus = newval; + DNS_SETBIT(BOGUS_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + + +isc_result_t +dns_peer_getbogus(dns_peer_t *peer, + isc_boolean_t *retval) +{ + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(retval != NULL); + + if (DNS_CHECKBIT(BOGUS_BIT, &peer->bitflags)) { + *retval = peer->bogus; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} + + +isc_result_t +dns_peer_setsupportixfr(dns_peer_t *peer, + isc_boolean_t newval) +{ + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_CHECKBIT(SUPPORT_IXFR_BIT, &peer->bitflags); + + peer->support_ixfr = newval; + DNS_SETBIT(SUPPORT_IXFR_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + + +isc_result_t +dns_peer_getsupportixfr(dns_peer_t *peer, + isc_boolean_t *retval) +{ + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(retval != NULL); + + if (DNS_CHECKBIT(SUPPORT_IXFR_BIT, &peer->bitflags)) { + *retval = peer->support_ixfr; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} + + +isc_result_t +dns_peer_settransfers(dns_peer_t *peer, + isc_int32_t newval) +{ + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_CHECKBIT(TRANSFERS_BIT, &peer->bitflags); + + peer->transfers = newval; + DNS_SETBIT(TRANSFERS_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + + +isc_result_t +dns_peer_gettransfers(dns_peer_t *peer, + isc_int32_t *retval) +{ + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(retval != NULL); + + if (DNS_CHECKBIT(TRANSFERS_BIT, &peer->bitflags)) { + *retval = peer->transfers; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} + + +isc_result_t +dns_peer_settransferformat(dns_peer_t *peer, + dns_transfer_format_t newval) +{ + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_CHECKBIT(SERVER_TRANSFER_FORMAT_BIT, + &peer->bitflags); + + peer->transfer_format = newval; + DNS_SETBIT(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + + +isc_result_t +dns_peer_gettransferformat(dns_peer_t *peer, + dns_transfer_format_t *retval) +{ + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(retval != NULL); + + if (DNS_CHECKBIT(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) { + *retval = peer->transfer_format; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} + + +isc_result_t +dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) +{ + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(retval != NULL); + + if (peer->key != NULL) { + *retval = peer->key; + } + + return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS); +} + + + + +isc_result_t +dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) +{ + isc_boolean_t exists = ISC_FALSE; + + if (peer->key != NULL) { + dns_name_free(peer->key, peer->mem); + isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t)); + exists = ISC_TRUE; + } + + peer->key = *keyval; + *keyval = NULL; + + return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS); +} +