Commit b312748a authored by Mark Andrews's avatar Mark Andrews
Browse files

1442. [func] New fuctions for manipulating port lists:

                        dns_portlist_create(), dns_portlist_add(),
                        dns_portlist_remove(), dns_portlist_match(),
                        dns_portlist_attach() and dns_portlist_detach().

1441.   [func]          It is now possible to tell dig to bind to a specific
                        source port.

1440.   [func]          It is now possible to tell named to avoid using
                        certian source ports (avoid-v4-udp-ports,
                        avoid-v6-udp-ports).
developer: marka
reviewer: explorer
parent ee84964a
1442. [func] New fuctions for manipulating port lists:
dns_portlist_create(), dns_portlist_add(),
dns_portlist_remove(), dns_portlist_match(),
dns_portlist_attach() and dns_portlist_detach().
1441. [func] It is now possible to tell dig to bind to a specific
source port.
1440. [func] It is now possible to tell named to avoid using
certian source ports (avoid-v4-udp-ports,
avoid-v6-udp-ports).
1439. [bug] Named could return NOERROR with certian NOTIFY
failures. Return NOTAUTH is the NOTIFY zone is
not being served.
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.c,v 1.180 2002/08/29 07:45:04 marka Exp $ */
/* $Id: dig.c,v 1.181 2003/02/26 05:05:13 marka Exp $ */
#include <config.h>
#include <stdlib.h>
......@@ -996,6 +996,8 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
char textname[MXNAME];
struct in_addr in4;
struct in6_addr in6;
in_port_t srcport;
char *hash;
cmd = option[0];
if (strlen(option) > 1) {
......@@ -1031,12 +1033,24 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
goto invalid_option;
switch (cmd) {
case 'b':
hash = index(value, '#');
if (hash != NULL) {
srcport = (in_port_t) parse_uint(hash + 1,
"port number", MAXPORT);
*hash = '\0';
} else
srcport = 0;
if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1)
isc_sockaddr_fromin6(&bind_address, &in6, 0);
isc_sockaddr_fromin6(&bind_address, &in6, srcport);
else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1)
isc_sockaddr_fromin(&bind_address, &in4, 0);
else
isc_sockaddr_fromin(&bind_address, &in4, srcport);
else {
if (hash != NULL)
*hash = '#';
fatal("invalid address %s", value);
}
if (hash != NULL)
*hash = '#';
specified_source = ISC_TRUE;
return (value_from_next);
case 'c':
......
......@@ -16,7 +16,7 @@
- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: dig.docbook,v 1.15 2003/02/25 22:40:23 marka Exp $ -->
<!-- $Id: dig.docbook,v 1.16 2003/02/26 05:05:13 marka Exp $ -->
<refentry>
......@@ -153,7 +153,8 @@ ANY, A, MX, SIG, etc.
<para>
The <option>-b</option> option sets the source IP address of the query
to <parameter>address</parameter>. This must be a valid address on
one of the host's network interfaces.
one of the host's network interfaces or "0.0.0.0" or "::". An optional port
may be specified by appending "#&lt;port&gt;"
</para>
<para>
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.396 2003/02/26 03:45:58 marka Exp $ */
/* $Id: server.c,v 1.397 2003/02/26 05:05:14 marka Exp $ */
#include <config.h>
......@@ -49,6 +49,7 @@
#include <dns/master.h>
#include <dns/order.h>
#include <dns/peer.h>
#include <dns/portlist.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
......@@ -1748,6 +1749,26 @@ set_limits(cfg_obj_t **maps) {
SETLIMIT("files", openfiles, "open files");
}
static isc_result_t
portlist_fromconf(dns_portlist_t *portlist, unsigned int family,
cfg_obj_t *ports)
{
cfg_listelt_t *element;
isc_result_t result = ISC_R_SUCCESS;
for (element = cfg_list_first(ports);
element != NULL;
element = cfg_list_next(element)) {
cfg_obj_t *obj = cfg_listelt_value(element);
in_port_t port = cfg_obj_asuint32(obj);
result = dns_portlist_add(portlist, family, port);
if (result != ISC_R_SUCCESS)
break;
}
return (result);
}
static isc_result_t
load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time)
......@@ -1758,6 +1779,7 @@ load_configuration(const char *filename, ns_server_t *server,
cfg_obj_t *options;
cfg_obj_t *views;
cfg_obj_t *obj;
cfg_obj_t *v4ports, *v6ports;
cfg_obj_t *maps[3];
cfg_obj_t *builtin_views;
cfg_listelt_t *element;
......@@ -1871,6 +1893,25 @@ load_configuration(const char *filename, ns_server_t *server,
INSIST(result == ISC_R_SUCCESS);
server->aclenv.match_mapped = cfg_obj_asboolean(obj);
v4ports = NULL;
v6ports = NULL;
(void)ns_config_get(maps, "avoid-v4-udp-ports", &v4ports);
(void)ns_config_get(maps, "avoid-v6-udp-ports", &v6ports);
if (v4ports != NULL || v6ports != NULL) {
dns_portlist_t *portlist = NULL;
result = dns_portlist_create(ns_g_mctx, &portlist);
if (result == ISC_R_SUCCESS && v4ports != NULL)
result = portlist_fromconf(portlist, AF_INET, v4ports);
if (result == ISC_R_SUCCESS && v6ports != NULL)
portlist_fromconf(portlist, AF_INET6, v6ports);
if (result == ISC_R_SUCCESS)
dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, portlist);
if (portlist != NULL)
dns_portlist_detach(&portlist);
CHECK(result);
} else
dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, NULL);
/*
* Set the EDNS UDP size when we don't match a view.
*/
......
......@@ -2,7 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
<!-- File: $Id: Bv9ARM-book.xml,v 1.215 2003/02/26 02:03:58 marka Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.216 2003/02/26 05:05:14 marka Exp $ -->
<book>
<title>BIND 9 Administrator Reference Manual</title>
......@@ -2727,6 +2727,8 @@ statement in the <filename>named.conf</filename> file:</para>
<optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-v6-synthesis { <replaceable>address_match_list</replaceable> }; </optional>
<optional> blackhole { <replaceable>address_match_list</replaceable> }; </optional>
<optional> avoid-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> avoid-v6-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> listen-on <optional> port <replaceable>ip_port</replaceable> </optional> { <replaceable>address_match_list</replaceable> }; </optional>
<optional> listen-on-v6 <optional> port <replaceable>ip_port</replaceable> </optional> { <replaceable>address_match_list</replaceable> }; </optional>
<optional> query-source <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
......@@ -3447,6 +3449,7 @@ and on port 1234 of IPv6 addresses that is not in the prefix
</programlisting>
<para>If no <command>listen-on-v6</command> statement is specified,
the server will not listen on any IPv6 address.</para></sect3>
<sect3><title>Query Address</title>
<para>If the server doesn't know the answer to a question, it will
query other name servers. <command>query-source</command> specifies
......@@ -3455,7 +3458,9 @@ IPv6, there is a separate <command>query-source-v6</command> option.
If <command>address</command> is <command>*</command> or is omitted,
a wildcard IP address (<command>INADDR_ANY</command>) will be used.
If <command>port</command> is <command>*</command> or is omitted,
a random unprivileged port will be used. The defaults are</para>
a random unprivileged port will be used, <command>avoid-v4-udp-ports</command>
and <command>avoid-v6-udp-ports</command> can be used to prevent named
from selecting certian ports. The defaults are</para>
<programlisting>query-source address * port *;
query-source-v6 address * port *;
</programlisting>
......@@ -3463,7 +3468,8 @@ query-source-v6 address * port *;
<para>The address specified in the <command>query-source</command> option
is used for both UDP and TCP queries, but the port applies only to
UDP queries. TCP queries always use a random
unprivileged port.</para></note></sect3>
unprivileged port.</para></note>
</sect3>
<sect3 id="zone_transfers"><title>Zone Transfers</title>
<para><acronym>BIND</acronym> has mechanisms in place to facilitate zone transfers
......@@ -3619,6 +3625,18 @@ but applies to notify messages sent to IPv6 addresses.</para>
</sect3>
<sect3>
<title>Bad UDP Port Lists</title>
<para>
<command>avoid-v4-udp-ports</command> and <command>avoid-v6-udp-ports</command>
specify a list of IPv4 and IPv6 UDP ports that will not be used as system
assigned source ports for UDP sockets. These lists are expected to be
used to prevent named using "well known" ports in the system assigned range
that have become unusable due to wide spread use of acls containing these
ports.
</para>
</sect3>
<sect3>
<title>Operating System Resource Limits</title>
......
......@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.136 2002/12/13 02:51:40 marka Exp $
# $Id: Makefile.in,v 1.137 2003/02/26 05:05:15 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
......@@ -49,7 +49,7 @@ OBJS = acl.@O@ adb.@O@ byaddr.@O@ \
dnssec.@O@ ds.@O@ forward.@O@ journal.@O@ keytable.@O@ \
lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
name.@O@ ncache.@O@ nxt.@O@ order.@O@ peer.@O@ \
name.@O@ ncache.@O@ nxt.@O@ order.@O@ peer.@O@ portlist.@O@ \
rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rdata.@O@ rdatalist.@O@ \
rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ request.@O@ \
resolver.@O@ result.@O@ rootns.@O@ sdb.@O@ soa.@O@ ssu.@O@ \
......@@ -65,7 +65,7 @@ SRCS = acl.c adb.c byaddr.c \
dnssec.c ds.c forward.c journal.c keytable.c \
lib.c log.c lookup.c \
master.c masterdump.c message.c \
name.c ncache.c nxt.c order.c peer.c \
name.c ncache.c nxt.c order.c peer.c portlist.c \
rbt.c rbtdb.c rbtdb64.c rdata.c rdatalist.c \
rdataset.c rdatasetiter.c rdataslab.c request.c \
resolver.c result.c rootns.c sdb.c soa.c ssu.c \
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dispatch.c,v 1.111 2002/12/05 03:55:09 marka Exp $ */
/* $Id: dispatch.c,v 1.112 2003/02/26 05:05:15 marka Exp $ */
#include <config.h>
......@@ -35,6 +35,7 @@
#include <dns/events.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/portlist.h>
#include <dns/tcpmsg.h>
#include <dns/types.h>
......@@ -55,6 +56,7 @@ struct dns_dispatchmgr {
unsigned int magic;
isc_mem_t *mctx;
dns_acl_t *blackhole;
dns_portlist_t *portlist;
/* Locked by "lock". */
isc_mutex_t lock;
......@@ -986,6 +988,9 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
if (mgr->blackhole != NULL)
dns_acl_detach(&mgr->blackhole);
if (mgr->portlist != NULL)
dns_portlist_detach(&mgr->portlist);
isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
isc_mem_detach(&mctx);
}
......@@ -1038,6 +1043,7 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
isc_mem_attach(mctx, &mgr->mctx);
mgr->blackhole = NULL;
mgr->portlist = NULL;
result = isc_mutex_init(&mgr->lock);
if (result != ISC_R_SUCCESS)
......@@ -1131,6 +1137,23 @@ dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {
return (mgr->blackhole);
}
void
dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
dns_portlist_t *portlist)
{
REQUIRE(VALID_DISPATCHMGR(mgr));
if (mgr->portlist != NULL)
dns_portlist_detach(&mgr->portlist);
if (portlist != NULL)
dns_portlist_attach(portlist, &mgr->portlist);
}
dns_portlist_t *
dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) {
REQUIRE(VALID_DISPATCHMGR(mgr));
return (mgr->portlist);
}
static isc_result_t
dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
unsigned int buffersize, unsigned int maxbuffers,
......@@ -1215,16 +1238,63 @@ dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
destroy_mgr(&mgr);
}
static isc_boolean_t
blacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock) {
isc_sockaddr_t sockaddr;
isc_result_t result;
if (mgr->portlist == NULL)
return (ISC_FALSE);
result = isc_socket_getsockname(sock, &sockaddr);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
if (mgr->portlist != NULL &&
dns_portlist_match(mgr->portlist, isc_sockaddr_pf(&sockaddr),
isc_sockaddr_getport(&sockaddr)))
return (ISC_TRUE);
return (ISC_FALSE);
}
#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
static isc_boolean_t
local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {
isc_sockaddr_t sockaddr;
isc_result_t result;
if (addr == NULL)
return (ISC_TRUE);
return (isc_sockaddr_equal(&disp->local, addr));
/*
* Don't match wildcard ports against newly blacklisted ports.
*/
if (disp->mgr->portlist != NULL &&
isc_sockaddr_getport(addr) == 0 &&
isc_sockaddr_getport(&disp->local) == 0 &&
blacklisted(disp->mgr, disp->socket))
return (ISC_FALSE);
/*
* Check if we match the binding <address,port>.
* Wildcard ports match/fail here.
*/
if (isc_sockaddr_equal(&disp->local, addr))
return (ISC_TRUE);
if (isc_sockaddr_getport(addr) == 0)
return (ISC_FALSE);
/*
* Check if we match a bound wildcard port <address,port>.
*/
if (!isc_sockaddr_eqaddr(&disp->local, addr))
return (ISC_FALSE);
result = isc_socket_getsockname(disp->socket, &sockaddr);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
return (isc_sockaddr_equal(&disp->local, &sockaddr));
}
/*
......@@ -1635,9 +1705,20 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
if (result != ISC_R_SUCCESS)
return (result);
/*
* This assumes that the IP stack will *not* quickly reallocate
* the same port. If it does continually reallocate the same port
* then we need a mechanism to hold all the blacklisted sockets
* until we find a usable socket.
*/
getsocket:
result = create_socket(sockmgr, localaddr, &sock);
if (result != ISC_R_SUCCESS)
goto deallocate_dispatch;
if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) {
isc_socket_detach(&sock);
goto getsocket;
}
disp->socktype = isc_sockettype_udp;
disp->socket = sock;
......
......@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.47 2002/11/27 09:52:56 marka Exp $
# $Id: Makefile.in,v 1.48 2003/02/26 05:05:15 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
......@@ -27,7 +27,7 @@ HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h \
dnssec.h ds.h events.h fixedname.h journal.h keyflags.h \
keytable.h keyvalues.h lib.h log.h master.h masterdump.h \
message.h name.h ncache.h \
nxt.h peer.h rbt.h rcode.h \
nxt.h peer.h portlist.h rbt.h rcode.h \
rdata.h rdataclass.h rdatalist.h rdataset.h rdatasetiter.h \
rdataslab.h rdatatype.h request.h resolver.h result.h \
rootns.h sdb.h secalg.h secproto.h soa.h ssu.h \
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dispatch.h,v 1.46 2002/09/04 02:26:13 jinmei Exp $ */
/* $Id: dispatch.h,v 1.47 2003/02/26 05:05:15 marka Exp $ */
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
......@@ -179,6 +179,28 @@ dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr);
* A pointer to the current blackhole list, or NULL.
*/
void
dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
dns_portlist_t *portlist);
/*
* Sets a list of UDP ports that won't be used when creating a udp
* dispatch with a wildcard port.
*
* Requires:
* mgr is a valid dispatchmgr
* portlist to be NULL or a valid port list.
*/
dns_portlist_t *
dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr);
/*
* Return the current port list.
*
* Requires:
* mgr is a valid dispatchmgr
*/
isc_result_t
dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
......
/*
* Copyright (C) 2003 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.
*/
/* $Id: portlist.h,v 1.2 2003/02/26 05:05:15 marka Exp $ */
#include <isc/lang.h>
#include <isc/net.h>
#include <isc/types.h>
#include <dns/types.h>
ISC_LANG_BEGINDECLS
isc_result_t
dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp);
/*
* Create a port list.
*
* Requires:
* 'mctx' to be valid.
* 'portlistp' to be non NULL and '*portlistp' to be NULL;
*
* Returns:
* ISC_R_SUCCESS
* ISC_R_NOMEMORY
* ISC_R_UNEXPECTED
*/
isc_result_t
dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port);
/*
* Add the given <port,af> tuple to the portlist.
*
* Requires:
* 'portlist' to be valid.
* 'af' to be AF_INET or AF_INET6
*
* Returns:
* ISC_R_SUCCESS
* ISC_R_NOMEMORY
*/
void
dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port);
/*
* Remove the given <port,af> tuple to the portlist.
*
* Requires:
* 'portlist' to be valid.
* 'af' to be AF_INET or AF_INET6
*/
isc_boolean_t
dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port);
/*
* Find the given <port,af> tuple to the portlist.
*
* Requires:
* 'portlist' to be valid.
* 'af' to be AF_INET or AF_INET6
*
* Returns
* ISC_TRUE if the tuple is found, ISC_FALSE otherwise.
*/
void
dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp);
/*
* Attach to a port list.
*
* Requires:
* 'portlist' to be valid.
* 'portlistp' to be non NULL and '*portlistp' to be NULL;
*/
void
dns_portlist_detach(dns_portlist_t **portlistp);
/*
* Detach from a port list.
*
* Requires:
* '*portlistp' to be valid.
*/
ISC_LANG_ENDDECLS
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: types.h,v 1.107 2002/11/27 09:52:56 marka Exp $ */
/* $Id: types.h,v 1.108 2003/02/26 05:05:15 marka Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
......@@ -78,6 +78,7 @@ typedef unsigned char dns_offsets_t[128];
typedef struct dns_order dns_order_t;
typedef struct dns_peer dns_peer_t;
typedef struct dns_peerlist dns_peerlist_t;
typedef struct dns_portlist dns_portlist_t;
typedef struct dns_rbt dns_rbt_t;
typedef isc_uint16_t dns_rcode_t;
typedef struct dns_rdata dns_rdata_t;
......
/*
* Copyright (C) 2003 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.
*/
/* $Id: portlist.c,v 1.2 2003/02/26 05:05:15 marka Exp $ */
#include <stdlib.h>
#include <isc/mem.h>
#include <isc/magic.h>
#include <isc/mutex.h>
#include <isc/net.h>
#include <isc/refcount.h>
#include <isc/result.h>
#include <isc/types.h>
#include <isc/util.h>
#include <dns/types.h>
#include <dns/portlist.h>
#define DNS_PORTLIST_MAGIC ISC_MAGIC('P','L','S','T')
#define DNS_VALID_PORTLIST(p) ISC_MAGIC_VALID(p, DNS_PORTLIST_MAGIC)
typedef struct dns_element {
in_port_t port;
isc_uint16_t flags;
} dns_element_t;
struct dns_portlist {
unsigned int magic;
isc_mem_t *mctx;
isc_refcount_t refcount;
isc_mutex_t lock;
dns_element_t *list;
unsigned int allocated;
unsigned int active;
};
#define DNS_PL_INET 0x0001
#define DNS_PL_INET6 0x0002
#define DNS_PL_ALLOCATE 16
static int
compare(const void *arg1, const void *arg2) {
const dns_element_t *e1 = (const dns_element_t *)arg1;
const dns_element_t *e2 = (const dns_element_t *)arg2;
if (e1->port < e2->port)