Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
BIND
Commits
386d3a99
Commit
386d3a99
authored
Jun 23, 2008
by
Tatuya JINMEI 神明達哉
Browse files
2375. [security] Fully randomize UDP query ports to improve
forgery resilience. [RT #17949, #18098]
parent
40976ef8
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
386d3a99
...
...
@@ -24,7 +24,8 @@
2376. [bug] Change #2144 was not complete.
2375. [placeholder]
2375. [security] Fully randomize UDP query ports to improve
forgery resilience. [RT #17949, #18098]
2374. [bug] "blackhole" ACLs could cause named to segfault due
to some uninitialized memory. [RT #18095]
...
...
bin/named/bind9.xsl
View file @
386d3a99
...
...
@@ -15,7 +15,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: bind9.xsl,v 1.1
7
2008/0
4/09 22
:4
8
:1
7
jinmei Exp $ -->
<!-- $Id: bind9.xsl,v 1.1
8
2008/0
6/23 19
:4
1
:1
8
jinmei Exp $ -->
<xsl:stylesheet
version=
"1.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
...
...
@@ -86,7 +86,6 @@ td, th {
</head>
<body>
<div
class=
"header"
>
Bind 9 Configuration and Statistics
</div>
<br/>
<table>
...
...
bin/named/bind9.xsl.h
View file @
386d3a99
...
...
@@ -91,7 +91,6 @@ static char xslmsg[] =
" </head>
\n
"
" <body>
\n
"
" <div class=
\"
header
\"
>Bind 9 Configuration and Statistics</div>
\n
"
"
\n
"
" <br/>
\n
"
"
\n
"
" <table>
\n
"
...
...
bin/named/client.c
View file @
386d3a99
...
...
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.c,v 1.25
7
2008/0
4/03 06:09:04 tbox
Exp $ */
/* $Id: client.c,v 1.25
8
2008/0
6/23 19:41:18 jinmei
Exp $ */
#include <config.h>
...
...
@@ -1524,14 +1524,6 @@ client_request(isc_task_t *task, isc_event_t *event) {
dns_generalstats_increment
(
ns_g_server
->
nsstats
,
dns_nsstatscounter_tcp
);
/*
* Hash the incoming request here as it is after
* dns_dispatch_importrecv().
*/
dns_dispatch_hash
(
&
client
->
now
,
sizeof
(
client
->
now
));
dns_dispatch_hash
(
isc_buffer_base
(
buffer
),
isc_buffer_usedlength
(
buffer
));
/*
* It's a request. Parse it.
*/
...
...
bin/named/server.c
View file @
386d3a99
...
...
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.50
8
2008/0
5
/2
1 23:47:00 tbox
Exp $ */
/* $Id: server.c,v 1.50
9
2008/0
6
/2
3 19:41:18 jinmei
Exp $ */
/*! \file */
...
...
@@ -33,6 +33,7 @@
#include <isc/httpd.h>
#include <isc/lex.h>
#include <isc/parseint.h>
#include <isc/portset.h>
#include <isc/print.h>
#include <isc/resource.h>
#include <isc/stdio.h>
...
...
@@ -538,13 +539,15 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
*/
static
isc_result_t
get_view_querysource_dispatch
(
const
cfg_obj_t
**
maps
,
int
af
,
dns_dispatch_t
**
dispatchp
)
int
af
,
dns_dispatch_t
**
dispatchp
,
isc_boolean_t
is_firstview
)
{
isc_result_t
result
;
dns_dispatch_t
*
disp
;
isc_sockaddr_t
sa
;
unsigned
int
attrs
,
attrmask
;
const
cfg_obj_t
*
obj
=
NULL
;
unsigned
int
maxdispatchbuffers
;
/*
* Make compiler happy.
...
...
@@ -596,6 +599,20 @@ get_view_querysource_dispatch(const cfg_obj_t **maps,
attrs
|=
DNS_DISPATCHATTR_IPV6
;
break
;
}
if
(
isc_sockaddr_getport
(
&
sa
)
==
0
)
{
attrs
|=
DNS_DISPATCHATTR_EXCLUSIVE
;
maxdispatchbuffers
=
4096
;
}
else
{
INSIST
(
obj
!=
NULL
);
if
(
is_firstview
)
{
cfg_obj_log
(
obj
,
ns_g_lctx
,
ISC_LOG_INFO
,
"using specific query-source port "
"suppresses port randomization and can be "
"insecure."
);
}
maxdispatchbuffers
=
1000
;
}
attrmask
=
0
;
attrmask
|=
DNS_DISPATCHATTR_UDP
;
attrmask
|=
DNS_DISPATCHATTR_TCP
;
...
...
@@ -605,7 +622,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps,
disp
=
NULL
;
result
=
dns_dispatch_getudp
(
ns_g_dispatchmgr
,
ns_g_socketmgr
,
ns_g_taskmgr
,
&
sa
,
4096
,
1000
,
32768
,
16411
,
16433
,
maxdispatchbuffers
,
32768
,
16411
,
16433
,
attrs
,
attrmask
,
&
disp
);
if
(
result
!=
ISC_R_SUCCESS
)
{
isc_sockaddr_t
any
;
...
...
@@ -1015,7 +1032,6 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_boolean_t
rfc1918
;
isc_boolean_t
empty_zones_enable
;
const
cfg_obj_t
*
disablelist
=
NULL
;
isc_uint32_t
nqports
,
qports_updateinterval
;
dns_stats_t
*
resstats
=
NULL
;
dns_stats_t
*
resquerystats
=
NULL
;
...
...
@@ -1272,8 +1288,12 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*
* XXXRTH Hardwired number of tasks.
*/
CHECK
(
get_view_querysource_dispatch
(
maps
,
AF_INET
,
&
dispatch4
));
CHECK
(
get_view_querysource_dispatch
(
maps
,
AF_INET6
,
&
dispatch6
));
CHECK
(
get_view_querysource_dispatch
(
maps
,
AF_INET
,
&
dispatch4
,
ISC_TF
(
ISC_LIST_PREV
(
view
,
link
)
==
NULL
)));
CHECK
(
get_view_querysource_dispatch
(
maps
,
AF_INET6
,
&
dispatch6
,
ISC_TF
(
ISC_LIST_PREV
(
view
,
link
)
==
NULL
)));
if
(
dispatch4
==
NULL
&&
dispatch6
==
NULL
)
{
UNEXPECTED_ERROR
(
__FILE__
,
__LINE__
,
"unable to obtain neither an IPv4 nor"
...
...
@@ -1281,93 +1301,11 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
result
=
ISC_R_UNEXPECTED
;
goto
cleanup
;
}
obj
=
NULL
;
(
void
)
ns_config_get
(
maps
,
"use-queryport-pool"
,
&
obj
);
if
(
obj
==
NULL
||
cfg_obj_asboolean
(
obj
))
{
isc_sockaddr_t
sa
;
isc_boolean_t
logit4
=
ISC_FALSE
,
logit6
=
ISC_FALSE
;
resopts
|=
(
DNS_RESOLVER_USEDISPATCHPOOL4
|
DNS_RESOLVER_USEDISPATCHPOOL6
);
/* Check consistency with query-source(-v6) */
if
(
dispatch4
==
NULL
)
resopts
&=
~
DNS_RESOLVER_USEDISPATCHPOOL4
;
else
{
result
=
dns_dispatch_getlocaladdress
(
dispatch4
,
&
sa
);
INSIST
(
result
==
ISC_R_SUCCESS
);
if
(
isc_sockaddr_getport
(
&
sa
)
!=
0
)
{
logit4
=
ISC_TRUE
;
resopts
&=
~
DNS_RESOLVER_USEDISPATCHPOOL4
;
}
}
if
(
dispatch6
==
NULL
)
resopts
&=
~
DNS_RESOLVER_USEDISPATCHPOOL6
;
else
{
result
=
dns_dispatch_getlocaladdress
(
dispatch6
,
&
sa
);
INSIST
(
result
==
ISC_R_SUCCESS
);
if
(
isc_sockaddr_getport
(
&
sa
)
!=
0
)
{
logit6
=
ISC_TRUE
;
resopts
&=
~
DNS_RESOLVER_USEDISPATCHPOOL6
;
}
}
if
(
logit4
&&
obj
!=
NULL
)
cfg_obj_log
(
obj
,
ns_g_lctx
,
ISC_LOG_ERROR
,
"specific query-source port "
"cannot coexist with queryport-pool. "
"(Pool disabled)"
);
if
(
logit6
&&
obj
!=
NULL
)
cfg_obj_log
(
obj
,
ns_g_lctx
,
ISC_LOG_ERROR
,
"specific query-source-v6 port "
"cannot coexist with queryport-pool. "
"(Pool disabled)"
);
}
CHECK
(
dns_view_createresolver
(
view
,
ns_g_taskmgr
,
31
,
ns_g_socketmgr
,
ns_g_timermgr
,
resopts
,
ns_g_dispatchmgr
,
dispatch4
,
dispatch6
));
/*
* Query-port pool parameters.
*/
obj
=
NULL
;
nqports
=
8
;
result
=
ns_config_get
(
maps
,
"queryport-pool-ports"
,
&
obj
);
if
(
result
==
ISC_R_SUCCESS
)
{
if
((
resopts
&
(
DNS_RESOLVER_USEDISPATCHPOOL4
|
DNS_RESOLVER_USEDISPATCHPOOL6
))
==
0
)
{
cfg_obj_log
(
obj
,
ns_g_lctx
,
ISC_LOG_ERROR
,
"queryport-pool-ports is effective only "
"with 'use-queryport-pool yes' (ignored)"
);
}
else
nqports
=
cfg_obj_asuint32
(
obj
);
}
obj
=
NULL
;
qports_updateinterval
=
15
;
result
=
ns_config_get
(
maps
,
"queryport-pool-updateinterval"
,
&
obj
);
if
(
result
==
ISC_R_SUCCESS
)
{
if
((
resopts
&
(
DNS_RESOLVER_USEDISPATCHPOOL4
|
DNS_RESOLVER_USEDISPATCHPOOL6
))
==
0
)
{
cfg_obj_log
(
obj
,
ns_g_lctx
,
ISC_LOG_ERROR
,
"queryport-pool-updateinterval is "
"effective only with 'use-queryport-pool "
"yes' (ignored)"
);
}
else
qports_updateinterval
=
cfg_obj_asuint32
(
obj
);
}
if
((
resopts
&
(
DNS_RESOLVER_USEDISPATCHPOOL4
|
DNS_RESOLVER_USEDISPATCHPOOL6
))
!=
0
)
{
CHECK
(
dns_resolver_createdispatchpool
(
view
->
resolver
,
nqports
,
qports_updateinterval
*
60
));
}
if
(
resstats
==
NULL
)
{
CHECK
(
dns_generalstats_create
(
mctx
,
&
resstats
,
dns_resstatscounter_max
));
...
...
@@ -2674,8 +2612,6 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
view
!=
NULL
;
view
=
ISC_LIST_NEXT
(
view
,
link
))
{
dns_dispatch_t
*
dispatch6
;
isc_boolean_t
use_portpool
=
ISC_FALSE
;
unsigned
int
resopts
;
dispatch6
=
dns_resolver_dispatchv6
(
view
->
resolver
);
if
(
dispatch6
==
NULL
)
...
...
@@ -2683,19 +2619,16 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
result
=
dns_dispatch_getlocaladdress
(
dispatch6
,
&
addr
);
if
(
result
!=
ISC_R_SUCCESS
)
goto
fail
;
resopts
=
dns_resolver_getoptions
(
view
->
resolver
);
if
((
resopts
&
(
DNS_RESOLVER_USEDISPATCHPOOL4
|
DNS_RESOLVER_USEDISPATCHPOOL6
))
!=
0
)
{
/*
* If the resolver uses a dynamic pool of query ports
* with a specific source address, some of the current
* and future ports may override an existing wildcard
* IPv6 port. So we need to allow wildcard match
* in this case.
*/
use_portpool
=
ISC_TRUE
;
}
result
=
add_listenelt
(
mctx
,
list
,
&
addr
,
use_portpool
);
/*
* We always add non-wildcard address regardless of whether
* the port is 'any' (the fourth arg is TRUE): if the port is
* specific, we need to add it since it may conflict with a
* listening interface; if it's zero, we'll dynamically open
* query ports, and some of them may override an existing
* wildcard IPv6 port.
*/
result
=
add_listenelt
(
mctx
,
list
,
&
addr
,
ISC_TRUE
);
if
(
result
!=
ISC_R_SUCCESS
)
goto
fail
;
}
...
...
@@ -2884,24 +2817,41 @@ set_limits(const cfg_obj_t **maps) {
SETLIMIT
(
"files"
,
openfiles
,
"open files"
);
}
static
isc_result_t
port
li
st_fromconf
(
dns
_port
li
st_t
*
port
list
,
unsigned
int
family
,
const
cfg_obj
_t
*
po
rts
)
static
void
ports
e
t_fromconf
(
isc
_ports
e
t_t
*
port
set
,
const
cfg_obj_t
*
ports
,
isc_boolean
_t
po
sitive
)
{
const
cfg_listelt_t
*
element
;
isc_result_t
result
=
ISC_R_SUCCESS
;
for
(
element
=
cfg_list_first
(
ports
);
element
!=
NULL
;
element
=
cfg_list_next
(
element
))
{
const
cfg_obj_t
*
obj
=
cfg_listelt_value
(
element
);
in_port_t
port
=
(
in_port_t
)
cfg_obj_asuint32
(
obj
);
result
=
dns_portlist_add
(
portlist
,
family
,
port
);
if
(
result
!=
ISC_R_SUCCESS
)
break
;
if
(
cfg_obj_isuint32
(
obj
))
{
in_port_t
port
=
(
in_port_t
)
cfg_obj_asuint32
(
obj
);
if
(
positive
)
isc_portset_add
(
portset
,
port
);
else
isc_portset_remove
(
portset
,
port
);
}
else
{
const
cfg_obj_t
*
obj_loport
,
*
obj_hiport
;
in_port_t
loport
,
hiport
;
obj_loport
=
cfg_tuple_get
(
obj
,
"loport"
);
loport
=
(
in_port_t
)
cfg_obj_asuint32
(
obj_loport
);
obj_hiport
=
cfg_tuple_get
(
obj
,
"hiport"
);
hiport
=
(
in_port_t
)
cfg_obj_asuint32
(
obj_hiport
);
if
(
positive
)
isc_portset_addrange
(
portset
,
loport
,
hiport
);
else
{
isc_portset_removerange
(
portset
,
loport
,
hiport
);
}
}
}
return
(
result
);
}
static
isc_result_t
...
...
@@ -2940,7 +2890,7 @@ load_configuration(const char *filename, ns_server_t *server,
const
cfg_obj_t
*
options
;
const
cfg_obj_t
*
views
;
const
cfg_obj_t
*
obj
;
const
cfg_obj_t
*
v4ports
,
*
v6ports
;
const
cfg_obj_t
*
use
v4ports
,
*
avoidv4ports
,
*
usev6ports
,
*
avoid
v6ports
;
const
cfg_obj_t
*
maps
[
3
];
const
cfg_obj_t
*
builtin_views
;
const
cfg_listelt_t
*
element
;
...
...
@@ -2952,7 +2902,9 @@ load_configuration(const char *filename, ns_server_t *server,
isc_uint32_t
interface_interval
;
isc_uint32_t
heartbeat_interval
;
isc_uint32_t
udpsize
;
in_port_t
listen_port
;
in_port_t
listen_port
,
udpport_low
,
udpport_high
;
isc_portset_t
*
v4portset
=
NULL
;
isc_portset_t
*
v6portset
=
NULL
;
int
i
;
cfg_aclconfctx_init
(
&
aclconfctx
);
...
...
@@ -3069,24 +3021,64 @@ load_configuration(const char *filename, ns_server_t *server,
CHECKM
(
ns_statschannels_configure
(
ns_g_server
,
config
,
&
aclconfctx
),
"configuring statistics server(s)"
);
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
);
/*
* Configure sets of UDP query source ports.
*/
CHECKM
(
isc_portset_create
(
ns_g_mctx
,
&
v4portset
),
"creating UDP port set"
);
CHECKM
(
isc_portset_create
(
ns_g_mctx
,
&
v6portset
),
"creating UDP port set"
);
usev4ports
=
NULL
;
usev6ports
=
NULL
;
avoidv4ports
=
NULL
;
avoidv6ports
=
NULL
;
(
void
)
ns_config_get
(
maps
,
"use-v4-udp-ports"
,
&
usev4ports
);
if
(
usev4ports
!=
NULL
)
portset_fromconf
(
v4portset
,
usev4ports
,
ISC_TRUE
);
else
{
CHECKM
(
isc_net_getudpportrange
(
AF_INET
,
&
udpport_low
,
&
udpport_high
),
"get the default UDP/IPv4 port range"
);
if
(
udpport_low
==
udpport_high
)
isc_portset_add
(
v4portset
,
udpport_low
);
else
{
isc_portset_addrange
(
v4portset
,
udpport_low
,
udpport_high
);
}
isc_log_write
(
ns_g_lctx
,
NS_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_SERVER
,
ISC_LOG_INFO
,
"using default UDP/IPv4 port range: [%d, %d]"
,
udpport_low
,
udpport_high
);
}
(
void
)
ns_config_get
(
maps
,
"avoid-v4-udp-ports"
,
&
avoidv4ports
);
if
(
avoidv4ports
!=
NULL
)
portset_fromconf
(
v4portset
,
avoidv4ports
,
ISC_FALSE
);
(
void
)
ns_config_get
(
maps
,
"use-v6-udp-ports"
,
&
usev6ports
);
if
(
usev6ports
!=
NULL
)
portset_fromconf
(
v6portset
,
usev6ports
,
ISC_TRUE
);
else
{
CHECKM
(
isc_net_getudpportrange
(
AF_INET6
,
&
udpport_low
,
&
udpport_high
),
"get the default UDP/IPv6 port range"
);
if
(
udpport_low
==
udpport_high
)
isc_portset_add
(
v6portset
,
udpport_low
);
else
{
isc_portset_addrange
(
v6portset
,
udpport_low
,
udpport_high
);
}
isc_log_write
(
ns_g_lctx
,
NS_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_SERVER
,
ISC_LOG_INFO
,
"using default UDP/IPv6 port range: [%d, %d]"
,
udpport_low
,
udpport_high
);
}
(
void
)
ns_config_get
(
maps
,
"avoid-v6-udp-ports"
,
&
avoidv6ports
);
if
(
avoidv6ports
!=
NULL
)
portset_fromconf
(
v6portset
,
avoidv6ports
,
ISC_FALSE
);
dns_dispatchmgr_setavailports
(
ns_g_dispatchmgr
,
v4portset
,
v6portset
);
/*
* Set the EDNS UDP size when we don't match a view.
...
...
@@ -3569,6 +3561,12 @@ load_configuration(const char *filename, ns_server_t *server,
result
=
ISC_R_SUCCESS
;
cleanup:
if
(
v4portset
!=
NULL
)
isc_portset_destroy
(
ns_g_mctx
,
&
v4portset
);
if
(
v6portset
!=
NULL
)
isc_portset_destroy
(
ns_g_mctx
,
&
v6portset
);
cfg_aclconfctx_destroy
(
&
aclconfctx
);
if
(
parser
!=
NULL
)
{
...
...
configure.in
View file @
386d3a99
...
...
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
AC_REVISION($Revision: 1.44
3
$)
AC_REVISION($Revision: 1.44
4
$)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
...
...
@@ -317,6 +317,43 @@ lifconf.lifc_len = 0;
ISC_PLATFORM_HAVELIFCONF="#undef ISC_PLATFORM_HAVELIFCONF"])
AC_SUBST(ISC_PLATFORM_HAVELIFCONF)
#
# check if we have kqueue
#
AC_CHECK_FUNC(kqueue, ac_cv_have_kqueue=yes, ac_cv_have_kqueue=no)
case $ac_cv_have_kqueue in
yes)
ISC_PLATFORM_HAVEKQUEUE="#define ISC_PLATFORM_HAVEKQUEUE 1"
;;
*)
ISC_PLATFORM_HAVEKQUEUE="#undef ISC_PLATFORM_HAVEKQUEUE"
;;
esac
AC_SUBST(ISC_PLATFORM_HAVEKQUEUE)
#
# check if we have epoll
#
AC_CHECK_FUNC(epoll_create, ac_cv_have_epoll=yes, ac_cv_have_epoll=no)
case $ac_cv_have_epoll in
yes)
ISC_PLATFORM_HAVEEPOLL="#define ISC_PLATFORM_HAVEEPOLL 1"
;;
*)
ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL"
;;
esac
AC_SUBST(ISC_PLATFORM_HAVEEPOLL)
#
# check if we support /dev/poll
#
AC_CHECK_HEADERS(sys/devpoll.h,
ISC_PLATFORM_HAVEDEVPOLL="#define ISC_PLATFORM_HAVEDEVPOLL 1"
,
ISC_PLATFORM_HAVEDEVPOLL="#undef ISC_PLATFORM_HAVEDEVPOLL"
)
AC_SUBST(ISC_PLATFORM_HAVEDEVPOLL)
#
# check if we need to #include sys/select.h explicitly
...
...
doc/arm/Bv9ARM-book.xml
View file @
386d3a99
...
...
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.3
59
2008/06/
17 20:59:25 jreed
Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.3
60
2008/06/
23 19:41:18 jinmei
Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
...
...
@@ -2955,6 +2955,33 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para>
<varname>port_list</varname>
</para>
</entry>
<entry colname="2">
<para>
A list of an <varname>ip_port</varname> or a port
range.
A port range is specified in the form of
<userinput>range</userinput> followed by
two <varname>ip_port</varname>s,
<varname>port_low</varname> and
<varname>port_high</varname>, which represents
port numbers from <varname>port_low</varname> through
<varname>port_high</varname>, inclusive.
<varname>port_low</varname> must not be larger than
<varname>port_high</varname>.
For example,
<userinput>range 1024 65535</userinput> represents
ports from 1024 through 65535.
In either case an asterisk (`*') character is not
allowed as a valid <varname>ip_port</varname>.
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para>
...
...
@@ -4513,7 +4540,9 @@ category notify { null; };
<optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
<optional> allow-v6-synthesis { <replaceable>address_match_list</replaceable> }; </optional>
<optional> blackhole { <replaceable>address_match_list</replaceable> }; </optional>
<optional> use-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> avoid-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> use-v6-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>
...
...
@@ -6269,32 +6298,104 @@ listen-on-v6 port 1234 { !2001:db8::/32; any; };
If <command>address</command> is <command>*</command> (asterisk) or is omitted,
a wildcard IP address (<command>INADDR_ANY</command>)
will be used.
</para>
<para>
If <command>port</command> is <command>*</command> or is omitted,
a pool of random unprivileged ports will be used. See the
<command>use-queryport-pool</command>,
<command>queryport-pool-ports</command> and
<command>queryport-pool-updateinterval</command> options below for how the pool
is configured.
The <command>avoid-v4-udp-ports</command>
and <command>avoid-v6-udp-ports</command> options can be used
to prevent named
from selecting certain ports.
The defaults are:
a random port number from a pre-configured
range is picked up and will be used for each query.
The port range(s) is that specified in
the <command>use-v4-udp-ports</command> (for IPv4)
and <command>use-v6-udp-ports</command> (for IPv6)
options, excluding the ranges specified in
the <command>avoid-v4-udp-ports</command>
and <command>avoid-v6-udp-ports</command> options, respectively.
</para>
<para>
The defaults of the <command>query-source</command> and
<command>query-source-v6</command> options
are:
</para>
<programlisting>query-source address * port *;
query-source-v6 address * port *;
</programlisting>
<para>
If <command>use-v4-udp-ports</command> or
<command>use-v6-udp-ports</command> is unspecified,
<command>named</command> will check if the operating
system provides a programming interface to retrieve the
system's default range for ephemeral ports.
If such an interface is available,
<command>named</command> will use the corresponding system
default range; otherwise, it will use its own defaults:
</para>
<programlisting>use-v4-udp-ports { range 1024 65535; };
use-v6-udp-ports { range 1024 65535; };
</programlisting>
<para>
Note: make sure the ranges be sufficiently large for
security. A desirable size depends on various parameters,
but we generally recommend it contain at least 16384 ports
(14 bits of entropy).
Note also that the system's default range when used may be
too small for this purpose, and that the range may even be
changed while <command>named</command> is running; the new
range will automatically be applied when <command>named</command>
is reloaded.
It is encouraged to
configure <command>use-v4-udp-ports</command> and
<command>use-v6-udp-ports</command> explicitly so that the
ranges are sufficiently large and are reasonably
independent from the ranges used by other applications.
</para>
<para>
Note: the operational configuration
where <command>named</command> runs may prohibit the use
of some ports. For example, UNIX systems will not allow
<command>named</command> running without a root privilege
to use ports less than 1024.
If such ports are included in the specified (or detected)
set of query ports, the corresponding query attempts will
fail, resulting in resolution failures or delay.
It is therefore important to configure the set of ports
that can be safely used in the expected operational environment.
</para>
<para>
The defaults of the <command>avoid-v4-udp-ports</command> and