mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04: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:
parent
ee84964a7d
commit
b312748a11
14 changed files with 600 additions and 20 deletions
12
CHANGES
12
CHANGES
|
|
@ -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
|
||||
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 "#<port>"
|
||||
</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,
|
||||
|
|
|
|||
99
lib/dns/include/dns/portlist.h
Normal file
99
lib/dns/include/dns/portlist.h
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
258
lib/dns/portlist.c
Normal file
258
lib/dns/portlist.c
Normal 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));
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* 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>
|
||||
|
||||
|
|
@ -488,6 +488,35 @@ doc_serverid(cfg_printer_t *pctx, const cfg_type_t *type) {
|
|||
static cfg_type_t cfg_type_serverid = {
|
||||
"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
|
||||
* file only.
|
||||
|
|
@ -521,6 +550,8 @@ namedconf_or_view_clauses[] = {
|
|||
*/
|
||||
static cfg_clausedef_t
|
||||
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 },
|
||||
{ "coresize", &cfg_type_size, 0 },
|
||||
{ "datasize", &cfg_type_size, 0 },
|
||||
|
|
|
|||
|
|
@ -1649,6 +1649,7 @@
|
|||
./lib/dns/include/dns/nxt.h C 1999,2000,2001
|
||||
./lib/dns/include/dns/order.h C 2002
|
||||
./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/rcode.h C 1999,2000,2001
|
||||
./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/order.c C 2002
|
||||
./lib/dns/peer.c C 2000,2001
|
||||
./lib/dns/portlist.c C 2003
|
||||
./lib/dns/rbt.c C 1999,2000,2001
|
||||
./lib/dns/rbtdb.c C 1999,2000,2001
|
||||
./lib/dns/rbtdb.h C 1999,2000,2001
|
||||
|
|
|
|||
Loading…
Reference in a new issue