2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 16:15:27 +00:00

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
This commit is contained in:
Mark Andrews
2003-02-26 05:05:16 +00:00
parent ee84964a7d
commit b312748a11
14 changed files with 600 additions and 20 deletions

12
CHANGES
View File

@@ -1,3 +1,15 @@
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 1439. [bug] Named could return NOERROR with certian NOTIFY
failures. Return NOTAUTH is the NOTIFY zone is failures. Return NOTAUTH is the NOTIFY zone is
not being served. not being served.

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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 <config.h>
#include <stdlib.h> #include <stdlib.h>
@@ -996,6 +996,8 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
char textname[MXNAME]; char textname[MXNAME];
struct in_addr in4; struct in_addr in4;
struct in6_addr in6; struct in6_addr in6;
in_port_t srcport;
char *hash;
cmd = option[0]; cmd = option[0];
if (strlen(option) > 1) { if (strlen(option) > 1) {
@@ -1031,12 +1033,24 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
goto invalid_option; goto invalid_option;
switch (cmd) { switch (cmd) {
case 'b': 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) 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) else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1)
isc_sockaddr_fromin(&bind_address, &in4, 0); isc_sockaddr_fromin(&bind_address, &in4, srcport);
else else {
if (hash != NULL)
*hash = '#';
fatal("invalid address %s", value); fatal("invalid address %s", value);
}
if (hash != NULL)
*hash = '#';
specified_source = ISC_TRUE; specified_source = ISC_TRUE;
return (value_from_next); return (value_from_next);
case 'c': case 'c':

View File

@@ -16,7 +16,7 @@
- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - 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> <refentry>
@@ -153,7 +153,8 @@ ANY, A, MX, SIG, etc.
<para> <para>
The <option>-b</option> option sets the source IP address of the query The <option>-b</option> option sets the source IP address of the query
to <parameter>address</parameter>. This must be a valid address on 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>
<para> <para>

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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> #include <config.h>
@@ -49,6 +49,7 @@
#include <dns/master.h> #include <dns/master.h>
#include <dns/order.h> #include <dns/order.h>
#include <dns/peer.h> #include <dns/peer.h>
#include <dns/portlist.h>
#include <dns/rdataclass.h> #include <dns/rdataclass.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/rdatastruct.h> #include <dns/rdatastruct.h>
@@ -1748,6 +1749,26 @@ set_limits(cfg_obj_t **maps) {
SETLIMIT("files", openfiles, "open files"); 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 static isc_result_t
load_configuration(const char *filename, ns_server_t *server, load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time) 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 *options;
cfg_obj_t *views; cfg_obj_t *views;
cfg_obj_t *obj; cfg_obj_t *obj;
cfg_obj_t *v4ports, *v6ports;
cfg_obj_t *maps[3]; cfg_obj_t *maps[3];
cfg_obj_t *builtin_views; cfg_obj_t *builtin_views;
cfg_listelt_t *element; cfg_listelt_t *element;
@@ -1871,6 +1893,25 @@ load_configuration(const char *filename, ns_server_t *server,
INSIST(result == ISC_R_SUCCESS); INSIST(result == ISC_R_SUCCESS);
server->aclenv.match_mapped = cfg_obj_asboolean(obj); 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. * Set the EDNS UDP size when we don't match a view.
*/ */

View File

@@ -2,7 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN" <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd"> "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> <book>
<title>BIND 9 Administrator Reference Manual</title> <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-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-v6-synthesis { <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> 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 <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> 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> <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> </programlisting>
<para>If no <command>listen-on-v6</command> statement is specified, <para>If no <command>listen-on-v6</command> statement is specified,
the server will not listen on any IPv6 address.</para></sect3> the server will not listen on any IPv6 address.</para></sect3>
<sect3><title>Query Address</title> <sect3><title>Query Address</title>
<para>If the server doesn't know the answer to a question, it will <para>If the server doesn't know the answer to a question, it will
query other name servers. <command>query-source</command> specifies 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, If <command>address</command> is <command>*</command> or is omitted,
a wildcard IP address (<command>INADDR_ANY</command>) will be used. a wildcard IP address (<command>INADDR_ANY</command>) will be used.
If <command>port</command> is <command>*</command> or is omitted, 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 *; <programlisting>query-source address * port *;
query-source-v6 address * port *; query-source-v6 address * port *;
</programlisting> </programlisting>
@@ -3463,7 +3468,8 @@ query-source-v6 address * port *;
<para>The address specified in the <command>query-source</command> option <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 is used for both UDP and TCP queries, but the port applies only to
UDP queries. TCP queries always use a random 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> <sect3 id="zone_transfers"><title>Zone Transfers</title>
<para><acronym>BIND</acronym> has mechanisms in place to facilitate zone transfers <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>
<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> <sect3>
<title>Operating System Resource Limits</title> <title>Operating System Resource Limits</title>

View File

@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # 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@ srcdir = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
@@ -49,7 +49,7 @@ OBJS = acl.@O@ adb.@O@ byaddr.@O@ \
dnssec.@O@ ds.@O@ forward.@O@ journal.@O@ keytable.@O@ \ dnssec.@O@ ds.@O@ forward.@O@ journal.@O@ keytable.@O@ \
lib.@O@ log.@O@ lookup.@O@ \ lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@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@ \ rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rdata.@O@ rdatalist.@O@ \
rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ request.@O@ \ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ request.@O@ \
resolver.@O@ result.@O@ rootns.@O@ sdb.@O@ soa.@O@ ssu.@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 \ dnssec.c ds.c forward.c journal.c keytable.c \
lib.c log.c lookup.c \ lib.c log.c lookup.c \
master.c masterdump.c message.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 \ rbt.c rbtdb.c rbtdb64.c rdata.c rdatalist.c \
rdataset.c rdatasetiter.c rdataslab.c request.c \ rdataset.c rdatasetiter.c rdataslab.c request.c \
resolver.c result.c rootns.c sdb.c soa.c ssu.c \ resolver.c result.c rootns.c sdb.c soa.c ssu.c \

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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> #include <config.h>
@@ -35,6 +35,7 @@
#include <dns/events.h> #include <dns/events.h>
#include <dns/log.h> #include <dns/log.h>
#include <dns/message.h> #include <dns/message.h>
#include <dns/portlist.h>
#include <dns/tcpmsg.h> #include <dns/tcpmsg.h>
#include <dns/types.h> #include <dns/types.h>
@@ -55,6 +56,7 @@ struct dns_dispatchmgr {
unsigned int magic; unsigned int magic;
isc_mem_t *mctx; isc_mem_t *mctx;
dns_acl_t *blackhole; dns_acl_t *blackhole;
dns_portlist_t *portlist;
/* Locked by "lock". */ /* Locked by "lock". */
isc_mutex_t lock; isc_mutex_t lock;
@@ -986,6 +988,9 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
if (mgr->blackhole != NULL) if (mgr->blackhole != NULL)
dns_acl_detach(&mgr->blackhole); 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_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
isc_mem_detach(&mctx); 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); isc_mem_attach(mctx, &mgr->mctx);
mgr->blackhole = NULL; mgr->blackhole = NULL;
mgr->portlist = NULL;
result = isc_mutex_init(&mgr->lock); result = isc_mutex_init(&mgr->lock);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
@@ -1131,6 +1137,23 @@ dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {
return (mgr->blackhole); 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 static isc_result_t
dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
unsigned int buffersize, unsigned int maxbuffers, unsigned int buffersize, unsigned int maxbuffers,
@@ -1215,16 +1238,63 @@ dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
destroy_mgr(&mgr); 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))) #define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
static isc_boolean_t static isc_boolean_t
local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) { local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {
isc_sockaddr_t sockaddr;
isc_result_t result;
if (addr == NULL) if (addr == NULL)
return (ISC_TRUE); 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) if (result != ISC_R_SUCCESS)
return (result); 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); result = create_socket(sockmgr, localaddr, &sock);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto deallocate_dispatch; goto deallocate_dispatch;
if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) {
isc_socket_detach(&sock);
goto getsocket;
}
disp->socktype = isc_sockettype_udp; disp->socktype = isc_sockettype_udp;
disp->socket = sock; disp->socket = sock;

View File

@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # 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@ srcdir = @srcdir@
VPATH = @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 \ dnssec.h ds.h events.h fixedname.h journal.h keyflags.h \
keytable.h keyvalues.h lib.h log.h master.h masterdump.h \ keytable.h keyvalues.h lib.h log.h master.h masterdump.h \
message.h name.h ncache.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 \ rdata.h rdataclass.h rdatalist.h rdataset.h rdatasetiter.h \
rdataslab.h rdatatype.h request.h resolver.h result.h \ rdataslab.h rdatatype.h request.h resolver.h result.h \
rootns.h sdb.h secalg.h secproto.h soa.h ssu.h \ rootns.h sdb.h secalg.h secproto.h soa.h ssu.h \

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1 #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. * 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 isc_result_t
dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,

View File

@@ -0,0 +1,99 @@
/*
* 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

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_TYPES_H
#define DNS_TYPES_H 1 #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_order dns_order_t;
typedef struct dns_peer dns_peer_t; typedef struct dns_peer dns_peer_t;
typedef struct dns_peerlist dns_peerlist_t; typedef struct dns_peerlist dns_peerlist_t;
typedef struct dns_portlist dns_portlist_t;
typedef struct dns_rbt dns_rbt_t; typedef struct dns_rbt dns_rbt_t;
typedef isc_uint16_t dns_rcode_t; typedef isc_uint16_t dns_rcode_t;
typedef struct dns_rdata dns_rdata_t; typedef struct dns_rdata dns_rdata_t;

258
lib/dns/portlist.c Normal file
View File

@@ -0,0 +1,258 @@
/*
* 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)
return (-1);
if (e1->port > e2->port)
return (1);
return (0);
}
isc_result_t
dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) {
dns_portlist_t *portlist;
isc_result_t result;
REQUIRE(portlistp != NULL && *portlistp == NULL);
portlist = isc_mem_get(mctx, sizeof(*portlist));
if (portlist == NULL)
return (ISC_R_NOMEMORY);
result = isc_mutex_init(&portlist->lock);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, portlist, sizeof(*portlist));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_mutex_init() failed: %s",
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
}
isc_refcount_init(&portlist->refcount, 1);
portlist->list = NULL;
portlist->allocated = 0;
portlist->active = 0;
portlist->mctx = NULL;
isc_mem_attach(mctx, &portlist->mctx);
portlist->magic = DNS_PORTLIST_MAGIC;
*portlistp = portlist;
return (ISC_R_SUCCESS);
}
static dns_element_t *
find_port(dns_element_t *list, unsigned int len, in_port_t port) {
unsigned int try = len / 2;
unsigned int min = 0;
unsigned int max = len - 1;
unsigned int last = len;
while (1) {
if (list[try].port == port)
return (&list[try]);
if (port > list[try].port) {
if (try == max)
return (NULL);
min = try;
try = try + (max - try + 1) / 2;
INSIST(try <= max);
if (try == last)
return (NULL);
last = min;
} else {
if (try == min)
return (NULL);
max = try;
try = try - (try - min + 1) / 2;
INSIST(try >= min);
if (try == last)
return (NULL);
last = max;
}
}
}
isc_result_t
dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port) {
dns_element_t *el;
isc_result_t result;
REQUIRE(DNS_VALID_PORTLIST(portlist));
REQUIRE(af == AF_INET || af == AF_INET6);
LOCK(&portlist->lock);
if (portlist->active != 0) {
el = find_port(portlist->list, portlist->active, port);
if (el != NULL) {
if (af == AF_INET)
el->flags |= DNS_PL_INET;
else
el->flags |= DNS_PL_INET6;
result = ISC_R_SUCCESS;
goto unlock;
}
}
if (portlist->allocated <= portlist->active) {
unsigned int allocated;
allocated = portlist->allocated + DNS_PL_ALLOCATE;
el = isc_mem_get(portlist->mctx, sizeof(*el) * allocated);
if (el == NULL) {
result = ISC_R_NOMEMORY;
goto unlock;
}
if (portlist->list != NULL) {
memcpy(el, portlist->list,
portlist->allocated * sizeof(*el));
isc_mem_put(portlist->mctx, portlist->list,
portlist->allocated * sizeof(*el));
}
portlist->list = el;
portlist->allocated = allocated;
}
portlist->list[portlist->active].port = port;
if (af == AF_INET)
portlist->list[portlist->active].flags = DNS_PL_INET;
else
portlist->list[portlist->active].flags = DNS_PL_INET6;
portlist->active++;
qsort(portlist->list, portlist->active, sizeof(*el), compare);
result = ISC_R_SUCCESS;
unlock:
UNLOCK(&portlist->lock);
return (result);
}
void
dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port) {
dns_element_t *el;
REQUIRE(DNS_VALID_PORTLIST(portlist));
REQUIRE(af == AF_INET || af == AF_INET6);
LOCK(&portlist->lock);
if (portlist->active != 0) {
el = find_port(portlist->list, portlist->active, port);
if (el != NULL) {
if (af == AF_INET)
el->flags &= ~DNS_PL_INET;
else
el->flags &= ~DNS_PL_INET6;
if (el->flags == 0) {
*el = portlist->list[portlist->active];
portlist->active--;
qsort(portlist->list, portlist->active,
sizeof(*el), compare);
}
}
}
UNLOCK(&portlist->lock);
}
isc_boolean_t
dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port) {
dns_element_t *el;
isc_boolean_t result = ISC_FALSE;
REQUIRE(DNS_VALID_PORTLIST(portlist));
REQUIRE(af == AF_INET || af == AF_INET6);
LOCK(&portlist->lock);
if (portlist->active != 0) {
el = find_port(portlist->list, portlist->active, port);
if (el != NULL) {
if (af == AF_INET && (el->flags & DNS_PL_INET) != 0)
result = ISC_TRUE;
if (af == AF_INET6 && (el->flags & DNS_PL_INET6) != 0)
result = ISC_TRUE;
}
}
UNLOCK(&portlist->lock);
return (result);
}
void
dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) {
REQUIRE(DNS_VALID_PORTLIST(portlist));
REQUIRE(portlistp != NULL && *portlistp == NULL);
isc_refcount_increment(&portlist->refcount, NULL);
*portlistp = portlist;
}
void
dns_portlist_detach(dns_portlist_t **portlistp) {
dns_portlist_t *portlist;
unsigned int count;
REQUIRE(portlistp != NULL);
portlist = *portlistp;
REQUIRE(DNS_VALID_PORTLIST(portlist));
*portlistp = NULL;
isc_refcount_decrement(&portlist->refcount, &count);
if (count == 0) {
portlist->magic = 0;
isc_refcount_destroy(&portlist->refcount);
if (portlist->list != NULL)
isc_mem_put(portlist->mctx, portlist->list,
portlist->allocated *
sizeof(*portlist->list));
DESTROYLOCK(&portlist->lock);
isc_mem_putanddetach(&portlist->mctx, portlist,
sizeof(*portlist));
}
}

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: namedconf.c,v 1.16 2003/02/26 02:04:00 marka Exp $ */ /* $Id: namedconf.c,v 1.17 2003/02/26 05:05:16 marka Exp $ */
#include <config.h> #include <config.h>
@@ -488,6 +488,35 @@ doc_serverid(cfg_printer_t *pctx, const cfg_type_t *type) {
static cfg_type_t cfg_type_serverid = { static cfg_type_t cfg_type_serverid = {
"serverid", parse_serverid, NULL, doc_serverid, NULL, NULL }; "serverid", parse_serverid, NULL, doc_serverid, NULL, NULL };
/*
* Port list.
*/
static isc_result_t
parse_port(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
isc_result_t result;
UNUSED(type);
CHECK(cfg_parse_uint32(pctx, NULL, ret));
if ((*ret)->value.uint32 > 0xffff) {
cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid port");
cfg_obj_destroy(pctx, ret);
result = ISC_R_RANGE;
}
cleanup:
return (result);
}
static cfg_type_t cfg_type_port = {
"port", parse_port, NULL, cfg_doc_terminal,
NULL, NULL
};
static cfg_type_t cfg_type_bracketed_portlist = {
"bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
&cfg_rep_list, &cfg_type_port
};
/* /*
* Clauses that can be found within the top level of the named.conf * Clauses that can be found within the top level of the named.conf
* file only. * file only.
@@ -521,6 +550,8 @@ namedconf_or_view_clauses[] = {
*/ */
static cfg_clausedef_t static cfg_clausedef_t
options_clauses[] = { options_clauses[] = {
{ "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
{ "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
{ "blackhole", &cfg_type_bracketed_aml, 0 }, { "blackhole", &cfg_type_bracketed_aml, 0 },
{ "coresize", &cfg_type_size, 0 }, { "coresize", &cfg_type_size, 0 },
{ "datasize", &cfg_type_size, 0 }, { "datasize", &cfg_type_size, 0 },

View File

@@ -1649,6 +1649,7 @@
./lib/dns/include/dns/nxt.h C 1999,2000,2001 ./lib/dns/include/dns/nxt.h C 1999,2000,2001
./lib/dns/include/dns/order.h C 2002 ./lib/dns/include/dns/order.h C 2002
./lib/dns/include/dns/peer.h C 2000,2001 ./lib/dns/include/dns/peer.h C 2000,2001
./lib/dns/include/dns/portlist.h C 2003
./lib/dns/include/dns/rbt.h C 1999,2000,2001 ./lib/dns/include/dns/rbt.h C 1999,2000,2001
./lib/dns/include/dns/rcode.h C 1999,2000,2001 ./lib/dns/include/dns/rcode.h C 1999,2000,2001
./lib/dns/include/dns/rdata.h C 1998,1999,2000,2001,2002 ./lib/dns/include/dns/rdata.h C 1998,1999,2000,2001,2002
@@ -1695,6 +1696,7 @@
./lib/dns/nxt.c C 1999,2000,2001 ./lib/dns/nxt.c C 1999,2000,2001
./lib/dns/order.c C 2002 ./lib/dns/order.c C 2002
./lib/dns/peer.c C 2000,2001 ./lib/dns/peer.c C 2000,2001
./lib/dns/portlist.c C 2003
./lib/dns/rbt.c C 1999,2000,2001 ./lib/dns/rbt.c C 1999,2000,2001
./lib/dns/rbtdb.c C 1999,2000,2001 ./lib/dns/rbtdb.c C 1999,2000,2001
./lib/dns/rbtdb.h C 1999,2000,2001 ./lib/dns/rbtdb.h C 1999,2000,2001