diff options
Diffstat (limited to 'contrib/bind9/lib/dns/peer.c')
-rw-r--r-- | contrib/bind9/lib/dns/peer.c | 173 |
1 files changed, 167 insertions, 6 deletions
diff --git a/contrib/bind9/lib/dns/peer.c b/contrib/bind9/lib/dns/peer.c index 8b6ccdb..7d878b5 100644 --- a/contrib/bind9/lib/dns/peer.c +++ b/contrib/bind9/lib/dns/peer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.c,v 1.14.2.1.10.6 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: peer.c,v 1.19.18.8 2006/02/28 03:10:48 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -29,7 +31,7 @@ #include <dns/name.h> #include <dns/peer.h> -/* +/*% * Bit positions in the dns_peer_t structure flags field */ #define BOGUS_BIT 0 @@ -38,6 +40,8 @@ #define PROVIDE_IXFR_BIT 3 #define REQUEST_IXFR_BIT 4 #define SUPPORT_EDNS_BIT 5 +#define SERVER_UDPSIZE_BIT 6 +#define SERVER_MAXUDP_BIT 7 static void peerlist_delete(dns_peerlist_t **list); @@ -65,7 +69,6 @@ dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { return (ISC_R_SUCCESS); } - void dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { REQUIRE(DNS_PEERLIST_VALID(source)); @@ -130,7 +133,20 @@ dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) { dns_peer_attach(peer, &p); - ISC_LIST_APPEND(peers->elements, peer, next); + /* + * More specifics to front of list. + */ + for (p = ISC_LIST_HEAD(peers->elements); + p != NULL; + p = ISC_LIST_NEXT(p, next)) + if (p->prefixlen < peer->prefixlen) + break; + + if (p != NULL) + ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next); + else + ISC_LIST_APPEND(peers->elements, peer, next); + } isc_result_t @@ -145,7 +161,8 @@ dns_peerlist_peerbyaddr(dns_peerlist_t *servers, server = ISC_LIST_HEAD(servers->elements); while (server != NULL) { - if (isc_netaddr_equal(addr, &server->address)) + if (isc_netaddr_eqprefix(addr, &server->address, + server->prefixlen)) break; server = ISC_LIST_NEXT(server, next); @@ -176,6 +193,27 @@ dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) { isc_result_t dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { + unsigned int prefixlen = 0; + + REQUIRE(peerptr != NULL); + switch(addr->family) { + case AF_INET: + prefixlen = 32; + break; + case AF_INET6: + prefixlen = 128; + break; + default: + INSIST(0); + } + + return (dns_peer_newprefix(mem, addr, prefixlen, peerptr)); +} + +isc_result_t +dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen, + dns_peer_t **peerptr) +{ dns_peer_t *peer; REQUIRE(peerptr != NULL); @@ -186,6 +224,7 @@ dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { peer->magic = DNS_PEER_MAGIC; peer->address = *addr; + peer->prefixlen = prefixlen; peer->mem = mem; peer->bogus = ISC_FALSE; peer->transfer_format = dns_one_answer; @@ -195,6 +234,8 @@ dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { peer->key = NULL; peer->refs = 1; peer->transfer_source = NULL; + peer->notify_source = NULL; + peer->query_source = NULL; memset(&peer->bitflags, 0x0, sizeof(peer->bitflags)); @@ -522,3 +563,123 @@ dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { *transfer_source = *peer->transfer_source; return (ISC_R_SUCCESS); } + +isc_result_t +dns_peer_setnotifysource(dns_peer_t *peer, + const isc_sockaddr_t *notify_source) +{ + REQUIRE(DNS_PEER_VALID(peer)); + + if (peer->notify_source != NULL) { + isc_mem_put(peer->mem, peer->notify_source, + sizeof(*peer->notify_source)); + peer->notify_source = NULL; + } + if (notify_source != NULL) { + peer->notify_source = isc_mem_get(peer->mem, + sizeof(*peer->notify_source)); + if (peer->notify_source == NULL) + return (ISC_R_NOMEMORY); + + *peer->notify_source = *notify_source; + } + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) { + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(notify_source != NULL); + + if (peer->notify_source == NULL) + return (ISC_R_NOTFOUND); + *notify_source = *peer->notify_source; + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) { + REQUIRE(DNS_PEER_VALID(peer)); + + if (peer->query_source != NULL) { + isc_mem_put(peer->mem, peer->query_source, + sizeof(*peer->query_source)); + peer->query_source = NULL; + } + if (query_source != NULL) { + peer->query_source = isc_mem_get(peer->mem, + sizeof(*peer->query_source)); + if (peer->query_source == NULL) + return (ISC_R_NOMEMORY); + + *peer->query_source = *query_source; + } + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) { + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(query_source != NULL); + + if (peer->query_source == NULL) + return (ISC_R_NOTFOUND); + *query_source = *peer->query_source; + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize) { + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); + + peer->udpsize = udpsize; + DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize) { + + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(udpsize != NULL); + + if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { + *udpsize = peer->udpsize; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} + +isc_result_t +dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp) { + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags); + + peer->maxudp = maxudp; + DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp) { + + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(maxudp != NULL); + + if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) { + *maxudp = peer->maxudp; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} |