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).
This commit is contained in:
Mark Andrews
2003-08-27 01:39:27 +00:00
parent e921ddd8f4
commit 2d7ca109c5
12 changed files with 243 additions and 20 deletions
+12
View File
@@ -8,6 +8,18 @@
1438. [func] Log TSIG (if any) when logging NOTIFY requests.
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).
1436. [func] dns_zonemgr_resumexfrs() can be used to restart
stalled transfers.
+18 -4
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.c,v 1.157.2.13.2.8 2003/08/15 02:00:32 marka Exp $ */
/* $Id: dig.c,v 1.157.2.13.2.9 2003/08/27 01:39:22 marka Exp $ */
#include <config.h>
#include <stdlib.h>
@@ -994,6 +994,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) > 1U) {
@@ -1029,12 +1031,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':
+3 -2
View File
@@ -16,7 +16,7 @@
- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: dig.docbook,v 1.4.2.7.4.2 2003/08/14 06:40:30 marka Exp $ -->
<!-- $Id: dig.docbook,v 1.4.2.7.4.3 2003/08/27 01:39:22 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>
+42 -1
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.339.2.15.2.29 2003/08/26 07:54:18 marka Exp $ */
/* $Id: server.c,v 1.339.2.15.2.30 2003/08/27 01:39:23 marka Exp $ */
#include <config.h>
@@ -50,6 +50,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>
@@ -1790,6 +1791,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)
@@ -1800,6 +1821,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;
@@ -1913,6 +1935,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.
*/
+21 -3
View File
@@ -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.155.2.27.2.22 2003/08/26 05:56:15 marka Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.155.2.27.2.23 2003/08/27 01:39:23 marka Exp $ -->
<book>
<title>BIND 9 Administrator Reference Manual</title>
@@ -2693,6 +2693,8 @@ statement in the <filename>named.conf</filename> file:</para>
<optional> allow-recursion { <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>
@@ -3368,6 +3370,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 nameservers. <command>query-source</command> specifies
@@ -3376,7 +3379,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>
@@ -3384,7 +3389,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
@@ -3598,6 +3604,18 @@ may use. The default is <literal>default</literal>.</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>Server Resource Limits</title>
+3 -3
View File
@@ -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.126.2.3.2.3 2003/08/25 04:16:22 marka Exp $
# $Id: Makefile.in,v 1.126.2.3.2.4 2003/08/27 01:39:25 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -49,7 +49,7 @@ OBJS = acl.@O@ adb.@O@ byaddr.@O@ \
dnssec.@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 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 \
+83 -2
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dispatch.c,v 1.101.2.6.2.2 2003/08/19 02:53:57 marka Exp $ */
/* $Id: dispatch.c,v 1.101.2.6.2.3 2003/08/27 01:39:25 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;
+2 -2
View File
@@ -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.43.2.1.10.1 2003/08/25 04:16:25 marka Exp $
# $Id: Makefile.in,v 1.43.2.1.10.2 2003/08/27 01:39:25 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,7 +27,7 @@ HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h \
dnssec.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 \
+23 -1
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dispatch.h,v 1.45.2.2 2003/03/06 04:38:22 marka Exp $ */
/* $Id: dispatch.h,v 1.45.2.2.4.1 2003/08/27 01:39:25 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,
+2 -1
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: types.h,v 1.103.12.4 2003/08/25 04:16:25 marka Exp $ */
/* $Id: types.h,v 1.103.12.5 2003/08/27 01:39:25 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;
+32 -1
View File
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: namedconf.c,v 1.21.44.12 2003/08/26 05:56:18 marka Exp $ */
/* $Id: namedconf.c,v 1.21.44.13 2003/08/27 01:39:26 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.
@@ -526,6 +555,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 },
+2
View File
@@ -1556,6 +1556,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
@@ -1601,6 +1602,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,2003
./lib/dns/rbtdb.c C 1999,2000,2001,2002,2003
./lib/dns/rbtdb.h C 1999,2000,2001