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
Kea
Commits
db3d9fdf
Commit
db3d9fdf
authored
Feb 09, 2012
by
Jeremy C. Reed
Browse files
[master]Merge branch 'master' of
ssh://git.bind10.isc.org/var/bind10/git/bind10
parents
6bb65848
2858b209
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
src/bin/auth/query.cc
View file @
db3d9fdf
...
...
@@ -257,13 +257,27 @@ Query::addAuthAdditional(ZoneFinder& finder) {
}
}
namespace
{
// A simple wrapper for DataSourceClient::findZone(). Normally we can simply
// check the closest zone to the qname, but for type DS query we need to
// look into the parent zone. Nevertheless, if there is no "parent" (i.e.,
// the qname consists of a single label, which also means it's the root name),
// we should search the deepest zone we have (which should be the root zone;
// otherwise it's a query error).
DataSourceClient
::
FindResult
findZone
(
const
DataSourceClient
&
client
,
const
Name
&
qname
,
RRType
qtype
)
{
if
(
qtype
!=
RRType
::
DS
()
||
qname
.
getLabelCount
()
==
1
)
{
return
(
client
.
findZone
(
qname
));
}
return
(
client
.
findZone
(
qname
.
split
(
1
)));
}
}
void
Query
::
process
()
{
const
bool
qtype_is_any
=
(
qtype_
==
RRType
::
ANY
());
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
,
false
);
const
DataSourceClient
::
FindResult
result
=
datasrc_client_
.
findZone
(
qname_
);
// Found a zone which is the nearest ancestor to QNAME
const
DataSourceClient
::
FindResult
result
=
findZone
(
datasrc_client_
,
qname_
,
qtype_
);
// If we have no matching authoritative zone for the query name, return
// REFUSED. In short, this is to be compatible with BIND 9, but the
...
...
@@ -272,16 +286,26 @@ Query::process() {
// https://lists.isc.org/mailman/htdig/bind10-dev/2010-December/001633.html
if
(
result
.
code
!=
result
::
SUCCESS
&&
result
.
code
!=
result
::
PARTIALMATCH
)
{
// If we tried to find a "parent zone" for a DS query and failed,
// we may still have authority at the child side. If we do, the query
// has to be handled there.
if
(
qtype_
==
RRType
::
DS
()
&&
qname_
.
getLabelCount
()
>
1
&&
processDSAtChild
())
{
return
;
}
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
,
false
);
response_
.
setRcode
(
Rcode
::
REFUSED
());
return
;
}
ZoneFinder
&
zfinder
=
*
result
.
zone_finder
;
// Found a zone which is the nearest ancestor to QNAME, set the AA bit
// We have authority for a zone that contain the query name (possibly
// indirectly via delegation). Look into the zone.
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
);
response_
.
setRcode
(
Rcode
::
NOERROR
());
std
::
vector
<
ConstRRsetPtr
>
target
;
boost
::
function0
<
ZoneFinder
::
FindResult
>
find
;
const
bool
qtype_is_any
=
(
qtype_
==
RRType
::
ANY
());
if
(
qtype_is_any
)
{
find
=
boost
::
bind
(
&
ZoneFinder
::
findAll
,
&
zfinder
,
qname_
,
boost
::
ref
(
target
),
dnssec_opt_
);
...
...
@@ -389,6 +413,14 @@ Query::process() {
}
break
;
case
ZoneFinder
::
DELEGATION
:
// If a DS query resulted in delegation, we also need to check
// if we are an authority of the child, too. If so, we need to
// complete the process in the child as specified in Section
// 2.2.1.2. of RFC3658.
if
(
qtype_
==
RRType
::
DS
()
&&
processDSAtChild
())
{
return
;
}
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
,
false
);
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
db_result
.
rrset
),
...
...
@@ -422,5 +454,37 @@ Query::process() {
}
}
bool
Query
::
processDSAtChild
()
{
const
DataSourceClient
::
FindResult
zresult
=
datasrc_client_
.
findZone
(
qname_
);
if
(
zresult
.
code
!=
result
::
SUCCESS
)
{
return
(
false
);
}
// We are receiving a DS query at the child side of the owner name,
// where the DS isn't supposed to belong. We should return a "no data"
// response as described in Section 3.1.4.1 of RFC4035 and Section
// 2.2.1.1 of RFC 3658. find(DS) should result in NXRRSET, in which
// case (and if DNSSEC is required) we also add the proof for that,
// but even if find() returns an unexpected result, we don't bother.
// The important point in this case is to return SOA so that the resolver
// that happens to contact us can hunt for the appropriate parent zone
// by seeing the SOA.
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
);
response_
.
setRcode
(
Rcode
::
NOERROR
());
addSOA
(
*
zresult
.
zone_finder
);
const
ZoneFinder
::
FindResult
ds_result
=
zresult
.
zone_finder
->
find
(
qname_
,
RRType
::
DS
(),
dnssec_opt_
);
if
(
ds_result
.
code
==
ZoneFinder
::
NXRRSET
)
{
if
(
dnssec_
)
{
addNXRRsetProof
(
*
zresult
.
zone_finder
,
ds_result
);
}
}
return
(
true
);
}
}
}
src/bin/auth/query.h
View file @
db3d9fdf
...
...
@@ -178,6 +178,23 @@ private:
/// data for the query are to be found.
void
addAuthAdditional
(
isc
::
datasrc
::
ZoneFinder
&
finder
);
/// \brief Process a DS query possible at the child side of zone cut.
///
/// This private method is a subroutine of process(), and is called if
/// there's a possibility that this server has authority for the child
/// side of the DS's owner name (and it's detected that the server at
/// least doesn't have authority at the parent side). This method
/// first checks if it has authority for the child, and if does,
/// just build a "no data" response with SOA for the zone origin
/// (possibly with a proof for the no data) as specified in Section
/// 2.2.1.1 of RFC3658.
///
/// It returns true if this server has authority of the child; otherwise
/// it returns false. In the former case, the caller is expected to
/// terminate the query processing, because it should have been completed
/// within this method.
bool
processDSAtChild
();
public:
/// Constructor from query parameters.
///
...
...
src/bin/auth/tests/query_unittest.cc
View file @
db3d9fdf
This diff is collapsed.
Click to expand it.
src/lib/datasrc/tests/memory_datasrc_unittest.cc
View file @
db3d9fdf
...
...
@@ -762,11 +762,13 @@ TEST_F(InMemoryZoneFinderTest, delegationWithDS) {
EXPECT_EQ
(
SUCCESS
,
zone_finder_
.
add
(
rr_child_ds_
));
// Normal types of query should result in delegation, but DS query
// should be considered in-zone.
// should be considered in-zone
(but only exactly at the delegation point)
.
findTest
(
Name
(
"child.example.org"
),
RRType
::
A
(),
ZoneFinder
::
DELEGATION
,
true
,
rr_child_ns_
);
findTest
(
Name
(
"child.example.org"
),
RRType
::
DS
(),
ZoneFinder
::
SUCCESS
,
true
,
rr_child_ds_
);
findTest
(
Name
(
"grand.child.example.org"
),
RRType
::
DS
(),
ZoneFinder
::
DELEGATION
,
true
,
rr_child_ns_
);
// There's nothing special for DS query at the zone apex. It would
// normally result in NXRRSET.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment