Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
a47f01b6
Commit
a47f01b6
authored
Dec 20, 2011
by
Michal 'vorner' Vaner
Browse files
Merge #1483
parents
b0d0bf39
87a72f00
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/bin/auth/query.cc
View file @
a47f01b6
...
...
@@ -15,6 +15,8 @@
#include <algorithm> // for std::max
#include <vector>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <dns/message.h>
#include <dns/rcode.h>
...
...
@@ -67,7 +69,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
// Find A rrset
if
(
qname_
!=
qname
||
qtype_
!=
RRType
::
A
())
{
ZoneFinder
::
FindResult
a_result
=
zone
.
find
(
qname
,
RRType
::
A
(),
NULL
,
ZoneFinder
::
FindResult
a_result
=
zone
.
find
(
qname
,
RRType
::
A
(),
options
|
dnssec_opt_
);
if
(
a_result
.
code
==
ZoneFinder
::
SUCCESS
)
{
response_
.
addRRset
(
Message
::
SECTION_ADDITIONAL
,
...
...
@@ -78,7 +80,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
// Find AAAA rrset
if
(
qname_
!=
qname
||
qtype_
!=
RRType
::
AAAA
())
{
ZoneFinder
::
FindResult
aaaa_result
=
zone
.
find
(
qname
,
RRType
::
AAAA
(),
NULL
,
options
|
dnssec_opt_
);
zone
.
find
(
qname
,
RRType
::
AAAA
(),
options
|
dnssec_opt_
);
if
(
aaaa_result
.
code
==
ZoneFinder
::
SUCCESS
)
{
response_
.
addRRset
(
Message
::
SECTION_ADDITIONAL
,
boost
::
const_pointer_cast
<
RRset
>
(
aaaa_result
.
rrset
),
...
...
@@ -90,7 +92,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
void
Query
::
addSOA
(
ZoneFinder
&
finder
)
{
ZoneFinder
::
FindResult
soa_result
(
finder
.
find
(
finder
.
getOrigin
(),
RRType
::
SOA
(),
NULL
,
dnssec_opt_
));
RRType
::
SOA
(),
dnssec_opt_
));
if
(
soa_result
.
code
!=
ZoneFinder
::
SUCCESS
)
{
isc_throw
(
NoSOA
,
"There's no SOA record in zone "
<<
finder
.
getOrigin
().
toText
());
...
...
@@ -146,7 +148,7 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
// otherwise we shouldn't have got NXDOMAIN for the original query in
// the first place).
const
ZoneFinder
::
FindResult
fresult
=
finder
.
find
(
wildname
,
RRType
::
NSEC
(),
NULL
,
RRType
::
NSEC
(),
dnssec_opt_
);
if
(
fresult
.
code
!=
ZoneFinder
::
NXDOMAIN
||
!
fresult
.
rrset
||
fresult
.
rrset
->
getRdataCount
()
==
0
)
{
...
...
@@ -171,7 +173,7 @@ Query::addWildcardProof(ZoneFinder& finder) {
// substitution. Confirm that by specifying NO_WILDCARD. It should result
// in NXDOMAIN and an NSEC RR that proves it should be returned.
const
ZoneFinder
::
FindResult
fresult
=
finder
.
find
(
qname_
,
RRType
::
NSEC
(),
NULL
,
finder
.
find
(
qname_
,
RRType
::
NSEC
(),
dnssec_opt_
|
ZoneFinder
::
NO_WILDCARD
);
if
(
fresult
.
code
!=
ZoneFinder
::
NXDOMAIN
||
!
fresult
.
rrset
||
fresult
.
rrset
->
getRdataCount
()
==
0
)
{
...
...
@@ -194,7 +196,7 @@ Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
boost
::
const_pointer_cast
<
RRset
>
(
nsec
),
dnssec_
);
const
ZoneFinder
::
FindResult
fresult
=
finder
.
find
(
qname_
,
RRType
::
NSEC
(),
NULL
,
finder
.
find
(
qname_
,
RRType
::
NSEC
(),
dnssec_opt_
|
ZoneFinder
::
NO_WILDCARD
);
if
(
fresult
.
code
!=
ZoneFinder
::
NXDOMAIN
||
!
fresult
.
rrset
||
fresult
.
rrset
->
getRdataCount
()
==
0
)
{
...
...
@@ -213,8 +215,7 @@ void
Query
::
addAuthAdditional
(
ZoneFinder
&
finder
)
{
// Fill in authority and addtional sections.
ZoneFinder
::
FindResult
ns_result
=
finder
.
find
(
finder
.
getOrigin
(),
RRType
::
NS
(),
NULL
,
dnssec_opt_
);
RRType
::
NS
(),
dnssec_opt_
);
// zone origin name should have NS records
if
(
ns_result
.
code
!=
ZoneFinder
::
SUCCESS
)
{
isc_throw
(
NoApexNS
,
"There's no apex NS records in zone "
<<
...
...
@@ -229,7 +230,6 @@ Query::addAuthAdditional(ZoneFinder& finder) {
void
Query
::
process
()
{
bool
keep_doing
=
true
;
const
bool
qtype_is_any
=
(
qtype_
==
RRType
::
ANY
());
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
,
false
);
...
...
@@ -251,147 +251,151 @@ Query::process() {
// Found a zone which is the nearest ancestor to QNAME, set the AA bit
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
);
response_
.
setRcode
(
Rcode
::
NOERROR
());
while
(
keep_doing
)
{
keep_doing
=
false
;
std
::
auto_ptr
<
RRsetList
>
target
(
qtype_is_any
?
new
RRsetList
:
NULL
);
const
ZoneFinder
::
FindResult
db_result
(
zfinder
.
find
(
qname_
,
qtype_
,
target
.
get
(),
dnssec_opt_
));
switch
(
db_result
.
code
)
{
case
ZoneFinder
::
DNAME
:
{
// First, put the dname into the answer
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
std
::
vector
<
ConstRRsetPtr
>
target
;
boost
::
function0
<
ZoneFinder
::
FindResult
>
find
;
if
(
qtype_is_any
)
{
find
=
boost
::
bind
(
&
ZoneFinder
::
findAll
,
&
zfinder
,
qname_
,
boost
::
ref
(
target
),
dnssec_opt_
);
}
else
{
find
=
boost
::
bind
(
&
ZoneFinder
::
find
,
&
zfinder
,
qname_
,
qtype_
,
dnssec_opt_
);
}
ZoneFinder
::
FindResult
db_result
(
find
());
switch
(
db_result
.
code
)
{
case
ZoneFinder
::
DNAME
:
{
// First, put the dname into the answer
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
/*
* Empty DNAME should never get in, as it is impossible to
* create one in master file.
*
* FIXME: Other way to prevent this should be done
*/
assert
(
db_result
.
rrset
->
getRdataCount
()
>
0
);
// Get the data of DNAME
const
rdata
::
generic
::
DNAME
&
dname
(
dynamic_cast
<
const
rdata
::
generic
::
DNAME
&>
(
db_result
.
rrset
->
getRdataIterator
()
->
getCurrent
()));
// The yet unmatched prefix dname
const
Name
prefix
(
qname_
.
split
(
0
,
qname_
.
getLabelCount
()
-
db_result
.
rrset
->
getName
().
getLabelCount
()));
// If we put it together, will it be too long?
// (The prefix contains trailing ., which will be removed
if
(
prefix
.
getLength
()
-
Name
::
ROOT_NAME
().
getLength
()
+
dname
.
getDname
().
getLength
()
>
Name
::
MAX_WIRE
)
{
/*
* Empty DNAME should never get in, as it is impossible to
* create one in master file.
*
* FIXME: Other way to prevent this should be done
* In case the synthesized name is too long, section 4.1
* of RFC 2672 mandates we return YXDOMAIN.
*/
assert
(
db_result
.
rrset
->
getRdataCount
()
>
0
);
// Get the data of DNAME
const
rdata
::
generic
::
DNAME
&
dname
(
dynamic_cast
<
const
rdata
::
generic
::
DNAME
&>
(
db_result
.
rrset
->
getRdataIterator
()
->
getCurrent
()));
// The yet unmatched prefix dname
const
Name
prefix
(
qname_
.
split
(
0
,
qname_
.
getLabelCount
()
-
db_result
.
rrset
->
getName
().
getLabelCount
()));
// If we put it together, will it be too long?
// (The prefix contains trailing ., which will be removed
if
(
prefix
.
getLength
()
-
Name
::
ROOT_NAME
().
getLength
()
+
dname
.
getDname
().
getLength
()
>
Name
::
MAX_WIRE
)
{
/*
* In case the synthesized name is too long, section 4.1
* of RFC 2672 mandates we return YXDOMAIN.
*/
response_
.
setRcode
(
Rcode
::
YXDOMAIN
());
return
;
}
// The new CNAME we are creating (it will be unsigned even
// with DNSSEC, the DNAME is signed and it can be validated
// by that)
RRsetPtr
cname
(
new
RRset
(
qname_
,
db_result
.
rrset
->
getClass
(),
RRType
::
CNAME
(),
db_result
.
rrset
->
getTTL
()));
// Construct the new target by replacing the end
cname
->
addRdata
(
rdata
::
generic
::
CNAME
(
qname_
.
split
(
0
,
qname_
.
getLabelCount
()
-
db_result
.
rrset
->
getName
().
getLabelCount
()).
concatenate
(
dname
.
getDname
())));
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
cname
,
dnssec_
);
break
;
response_
.
setRcode
(
Rcode
::
YXDOMAIN
());
return
;
}
case
ZoneFinder
::
CNAME
:
case
ZoneFinder
::
WILDCARD_CNAME
:
/*
* We don't do chaining yet. Therefore handling a CNAME is
* mostly the same as handling SUCCESS, but we didn't get
* what we expected. It means no exceptions in ANY or NS
* on the origin (though CNAME in origin is probably
* forbidden anyway).
*
* So, just put it there.
*/
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
// The new CNAME we are creating (it will be unsigned even
// with DNSSEC, the DNAME is signed and it can be validated
// by that)
RRsetPtr
cname
(
new
RRset
(
qname_
,
db_result
.
rrset
->
getClass
(),
RRType
::
CNAME
(),
db_result
.
rrset
->
getTTL
()));
// Construct the new target by replacing the end
cname
->
addRdata
(
rdata
::
generic
::
CNAME
(
qname_
.
split
(
0
,
qname_
.
getLabelCount
()
-
db_result
.
rrset
->
getName
().
getLabelCount
()).
concatenate
(
dname
.
getDname
())));
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
cname
,
dnssec_
);
break
;
}
case
ZoneFinder
::
CNAME
:
case
ZoneFinder
::
WILDCARD_CNAME
:
/*
* We don't do chaining yet. Therefore handling a CNAME is
* mostly the same as handling SUCCESS, but we didn't get
* what we expected. It means no exceptions in ANY or NS
* on the origin (though CNAME in origin is probably
* forbidden anyway).
*
* So, just put it there.
*/
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if
(
dnssec_
&&
db_result
.
code
==
ZoneFinder
::
WILDCARD_CNAME
)
{
addWildcardProof
(
*
result
.
zone_finder
);
}
break
;
case
ZoneFinder
::
SUCCESS
:
case
ZoneFinder
::
WILDCARD
:
if
(
qtype_is_any
)
{
// If quety type is ANY, insert all RRs under the domain
// into answer section.
BOOST_FOREACH
(
RRsetPtr
rrset
,
*
target
)
{
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
rrset
,
dnssec_
);
// Handle additional for answer section
addAdditional
(
*
result
.
zone_finder
,
*
rrset
.
get
());
}
}
else
{
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if
(
dnssec_
&&
db_result
.
code
==
ZoneFinder
::
WILDCARD_CNAME
)
{
addWildcardProof
(
*
result
.
zone_finder
);
}
break
;
case
ZoneFinder
::
SUCCESS
:
case
ZoneFinder
::
WILDCARD
:
if
(
qtype_is_any
)
{
// If quety type is ANY, insert all RRs under the domain
// into answer section.
BOOST_FOREACH
(
ConstRRsetPtr
rrset
,
target
)
{
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
boost
::
const_pointer_cast
<
RRset
>
(
rrset
),
dnssec_
);
// Handle additional for answer section
addAdditional
(
*
result
.
zone_finder
,
*
db_result
.
rrset
);
addAdditional
(
*
result
.
zone_finder
,
*
rrset
.
get
()
);
}
// If apex NS records haven't been provided in the answer
// section, insert apex NS records into the authority section
// and AAAA/A RRS of each of the NS RDATA into the additional
// section.
if
(
qname_
!=
result
.
zone_finder
->
getOrigin
()
||
db_result
.
code
!=
ZoneFinder
::
SUCCESS
||
(
qtype_
!=
RRType
::
NS
()
&&
!
qtype_is_any
))
{
addAuthAdditional
(
*
result
.
zone_finder
);
}
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if
(
dnssec_
&&
db_result
.
code
==
ZoneFinder
::
WILDCARD
)
{
addWildcardProof
(
*
result
.
zone_finder
);
}
break
;
case
ZoneFinder
::
DELEGATION
:
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
,
false
);
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
}
else
{
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
// Handle additional for answer section
addAdditional
(
*
result
.
zone_finder
,
*
db_result
.
rrset
);
break
;
case
ZoneFinder
::
NXDOMAIN
:
response_
.
setRcode
(
Rcode
::
NXDOMAIN
());
addSOA
(
*
result
.
zone_finder
);
if
(
dnssec_
&&
db_result
.
rrset
)
{
addNXDOMAINProof
(
zfinder
,
db_result
.
rrset
);
}
break
;
case
ZoneFinder
::
NXRRSET
:
addSOA
(
*
result
.
zone_finder
);
if
(
dnssec_
&&
db_result
.
rrset
)
{
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
}
break
;
case
ZoneFinder
::
WILDCARD_NXRRSET
:
addSOA
(
*
result
.
zone_finder
);
if
(
dnssec_
&&
db_result
.
rrset
)
{
addWildcardNXRRSETProof
(
zfinder
,
db_result
.
rrset
);
}
break
;
default:
// This is basically a bug of the data source implementation,
// but could also happen in the middle of development where
// we try to add a new result code.
isc_throw
(
isc
::
NotImplemented
,
"Unknown result code"
);
break
;
}
}
// If apex NS records haven't been provided in the answer
// section, insert apex NS records into the authority section
// and AAAA/A RRS of each of the NS RDATA into the additional
// section.
if
(
qname_
!=
result
.
zone_finder
->
getOrigin
()
||
db_result
.
code
!=
ZoneFinder
::
SUCCESS
||
(
qtype_
!=
RRType
::
NS
()
&&
!
qtype_is_any
))
{
addAuthAdditional
(
*
result
.
zone_finder
);
}
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if
(
dnssec_
&&
db_result
.
code
==
ZoneFinder
::
WILDCARD
)
{
addWildcardProof
(
*
result
.
zone_finder
);
}
break
;
case
ZoneFinder
::
DELEGATION
:
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
,
false
);
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
addAdditional
(
*
result
.
zone_finder
,
*
db_result
.
rrset
);
break
;
case
ZoneFinder
::
NXDOMAIN
:
response_
.
setRcode
(
Rcode
::
NXDOMAIN
());
addSOA
(
*
result
.
zone_finder
);
if
(
dnssec_
&&
db_result
.
rrset
)
{
addNXDOMAINProof
(
zfinder
,
db_result
.
rrset
);
}
break
;
case
ZoneFinder
::
NXRRSET
:
addSOA
(
*
result
.
zone_finder
);
if
(
dnssec_
&&
db_result
.
rrset
)
{
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
RRset
>
(
db_result
.
rrset
),
dnssec_
);
}
break
;
case
ZoneFinder
::
WILDCARD_NXRRSET
:
addSOA
(
*
result
.
zone_finder
);
if
(
dnssec_
&&
db_result
.
rrset
)
{
addWildcardNXRRSETProof
(
zfinder
,
db_result
.
rrset
);
}
break
;
default:
// This is basically a bug of the data source implementation,
// but could also happen in the middle of development where
// we try to add a new result code.
isc_throw
(
isc
::
NotImplemented
,
"Unknown result code"
);
break
;
}
}
...
...
src/bin/auth/tests/query_unittest.cc
View file @
a47f01b6
...
...
@@ -211,8 +211,10 @@ public:
virtual
isc
::
dns
::
RRClass
getClass
()
const
{
return
(
rrclass_
);
}
virtual
FindResult
find
(
const
isc
::
dns
::
Name
&
name
,
const
isc
::
dns
::
RRType
&
type
,
RRsetList
*
target
=
NULL
,
const
FindOptions
options
=
FIND_DEFAULT
);
virtual
FindResult
findAll
(
const
isc
::
dns
::
Name
&
name
,
std
::
vector
<
ConstRRsetPtr
>&
target
,
const
FindOptions
options
=
FIND_DEFAULT
);
// If false is passed, it makes the zone broken as if it didn't have the
// SOA.
...
...
@@ -304,9 +306,30 @@ substituteWild(const RRset& wild_rrset, const Name& real_name) {
return
(
rrset
);
}
ZoneFinder
::
FindResult
MockZoneFinder
::
findAll
(
const
Name
&
name
,
std
::
vector
<
ConstRRsetPtr
>&
target
,
const
FindOptions
options
)
{
ZoneFinder
::
FindResult
result
(
find
(
name
,
RRType
::
ANY
(),
options
));
if
(
result
.
code
==
NXRRSET
)
{
const
Domains
::
const_iterator
found_domain
=
domains_
.
find
(
name
);
if
(
!
found_domain
->
second
.
empty
())
{
for
(
RRsetStore
::
const_iterator
found_rrset
=
found_domain
->
second
.
begin
();
found_rrset
!=
found_domain
->
second
.
end
();
++
found_rrset
)
{
// Insert RRs under the domain name into target
target
.
push_back
(
found_rrset
->
second
);
}
return
(
FindResult
(
SUCCESS
,
RRsetPtr
()));
}
}
return
(
result
);
}
ZoneFinder
::
FindResult
MockZoneFinder
::
find
(
const
Name
&
name
,
const
RRType
&
type
,
RRsetList
*
target
,
const
FindOptions
options
)
const
FindOptions
options
)
{
// Emulating a broken zone: mandatory apex RRs are missing if specifically
// configured so (which are rare cases).
...
...
@@ -358,17 +381,6 @@ MockZoneFinder::find(const Name& name, const RRType& type,
return
(
FindResult
(
SUCCESS
,
rrset
));
}
// If not found but we have a target, fill it with all RRsets here
if
(
!
found_domain
->
second
.
empty
()
&&
target
!=
NULL
)
{
for
(
found_rrset
=
found_domain
->
second
.
begin
();
found_rrset
!=
found_domain
->
second
.
end
();
++
found_rrset
)
{
// Insert RRs under the domain name into target
target
->
addRRset
(
boost
::
const_pointer_cast
<
RRset
>
(
found_rrset
->
second
));
}
return
(
FindResult
(
SUCCESS
,
found_domain
->
second
.
begin
()
->
second
));
}
// Otherwise, if this domain name has CNAME, return it.
found_rrset
=
found_domain
->
second
.
find
(
RRType
::
CNAME
());
if
(
found_rrset
!=
found_domain
->
second
.
end
())
{
...
...
src/lib/datasrc/database.cc
View file @
a47f01b6
...
...
@@ -176,7 +176,8 @@ private:
DatabaseClient
::
Finder
::
FoundRRsets
DatabaseClient
::
Finder
::
getRRsets
(
const
string
&
name
,
const
WantedTypes
&
types
,
bool
check_ns
,
const
string
*
construct_name
)
bool
check_ns
,
const
string
*
construct_name
,
bool
any
)
{
RRsigStore
sig_store
;
bool
records_found
=
false
;
...
...
@@ -221,7 +222,7 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
columns
[
DatabaseAccessor
::
RDATA_COLUMN
]));
}
if
(
types
.
find
(
cur_type
)
!=
types
.
end
())
{
if
(
types
.
find
(
cur_type
)
!=
types
.
end
()
||
any
)
{
// This type is requested, so put it into result
const
RRTTL
cur_ttl
(
columns
[
DatabaseAccessor
::
TTL_COLUMN
]);
// Ths sigtype column was an optimization for finding the
...
...
@@ -286,6 +287,12 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
sig_store
.
appendSignatures
(
i
->
second
);
}
if
(
records_found
&&
any
)
{
result
[
RRType
::
ANY
()]
=
RRsetPtr
();
// These will be sitting on the other RRsets.
result
.
erase
(
RRType
::
RRSIG
());
}
return
(
FoundRRsets
(
records_found
,
result
));
}
...
...
@@ -389,6 +396,25 @@ DatabaseClient::Finder::findNSECCover(const Name& name) {
return
(
ConstRRsetPtr
());
}
ZoneFinder
::
FindResult
DatabaseClient
::
Finder
::
findAll
(
const
isc
::
dns
::
Name
&
name
,
std
::
vector
<
isc
::
dns
::
ConstRRsetPtr
>&
target
,
const
FindOptions
options
)
{
return
(
findInternal
(
name
,
RRType
::
ANY
(),
&
target
,
options
));
}
ZoneFinder
::
FindResult
DatabaseClient
::
Finder
::
find
(
const
isc
::
dns
::
Name
&
name
,
const
isc
::
dns
::
RRType
&
type
,
const
FindOptions
options
)
{
if
(
type
==
RRType
::
ANY
())
{
isc_throw
(
isc
::
Unexpected
,
"Use findAll to answer ANY"
);
}
return
(
findInternal
(
name
,
type
,
NULL
,
options
));
}
DatabaseClient
::
Finder
::
DelegationSearchResult
DatabaseClient
::
Finder
::
findDelegationPoint
(
const
isc
::
dns
::
Name
&
name
,
const
FindOptions
options
)
...
...
@@ -550,7 +576,8 @@ DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
ZoneFinder
::
FindResult
DatabaseClient
::
Finder
::
findWildcardMatch
(
const
isc
::
dns
::
Name
&
name
,
const
isc
::
dns
::
RRType
&
type
,
const
FindOptions
options
,
const
DelegationSearchResult
&
dresult
)
const
FindOptions
options
,
const
DelegationSearchResult
&
dresult
,
std
::
vector
<
isc
::
dns
::
ConstRRsetPtr
>*
target
)
{
// Note that during the search we are going to search not only for the
// requested type, but also for types that indicate a delegation -
...
...
@@ -569,7 +596,7 @@ DatabaseClient::Finder::findWildcardMatch(
// RFC 4592 section 4.4).
// Search for a match. The types are the same as with original query.
FoundRRsets
found
=
getRRsets
(
wildcard
,
final_types
,
true
,
&
construct_name
);
&
construct_name
,
type
==
RRType
::
ANY
()
);
if
(
found
.
first
)
{
// Found something - but what?
...
...
@@ -594,7 +621,7 @@ DatabaseClient::Finder::findWildcardMatch(
// The wildcard match is the best one, find the final result
// at it. Note that wildcard should never be the zone origin.
return
(
findOnNameResult
(
name
,
type
,
options
,
false
,
found
,
&
wildcard
));
found
,
&
wildcard
,
target
));
}
else
{
// more specified match found, cancel wildcard match
...
...
@@ -660,7 +687,9 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
const
FindOptions
options
,
const
bool
is_origin
,
const
FoundRRsets
&
found
,
const
string
*
wildname
)
const
string
*
wildname
,
std
::
vector
<
isc
::
dns
::
ConstRRsetPtr
>*
target
)
{
const
bool
wild
=
(
wildname
!=
NULL
);
...
...
@@ -698,14 +727,29 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
DATASRC_DATABASE_FOUND_CNAME
));
}
else
if
(
wti
!=
found
.
second
.
end
())
{
bool
any
(
type
==
RRType
::
ANY
());
isc
::
log
::
MessageID
lid
(
wild
?
DATASRC_DATABASE_WILDCARD_MATCH
:
DATASRC_DATABASE_FOUND_RRSET
);
if
(
any
)
{
// An ANY query, copy everything to the target instead of returning
// directly.
for
(
FoundIterator
it
(
found
.
second
.
begin
());
it
!=
found
.
second
.
end
();
++
it
)
{
if
(
it
->
second
)
{
// Skip over the empty ANY
target
->
push_back
(
it
->
second
);
}
}
lid
=
wild
?
DATASRC_DATABASE_WILDCARD_ANY
:
DATASRC_DATABASE_FOUND_ANY
;
}
// Found an RR matching the query, so return it. (Note that this
// includes the case where we were explicitly querying for a CNAME and
// found it. It also includes the case where we were querying for an
// NS RRset and found it at the apex of the zone.)
return
(
logAndCreateResult
(
name
,
wildname
,
type
,
wild
?
WILDCARD
:
SUCCESS
,
wti
->
second
,
wild
?
DATASRC_DATABASE_WILDCARD_MATCH
:
DATASRC_DATABASE_FOUND_RRSET
));
lid
));
}
// If we get here, we have found something at the requested name but not
...
...
@@ -747,7 +791,9 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
ZoneFinder
::
FindResult
DatabaseClient
::
Finder
::
findNoNameResult
(
const
Name
&
name
,
const
RRType
&
type
,
FindOptions
options
,
const
DelegationSearchResult
&
dresult
)
const
DelegationSearchResult
&
dresult
,
std
::
vector
<
isc
::
dns
::
ConstRRsetPtr
>*
target
)
{
const
bool
dnssec_data
=
((
options
&
FIND_DNSSEC
)
!=
0
);
...
...
@@ -771,7 +817,7 @@ DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
// (i.e. all results except NXDOMAIN) return it; otherwise fall
// through to the NXDOMAIN case below.
const
ZoneFinder
::
FindResult
wresult
=
findWildcardMatch
(
name
,
type
,
options
,
dresult
);
findWildcardMatch
(
name
,
type
,
options
,
dresult
,
target
);
if
(
wresult
.
code
!=
NXDOMAIN
)
{
return
(
FindResult
(
wresult
.
code
,
wresult
.
rrset
));
}
...
...
@@ -786,9 +832,9 @@ DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
}
ZoneFinder
::
FindResult
DatabaseClient
::
Finder
::
find
(
const
isc
::
dns
::
Name
&
name
,
DatabaseClient
::
Finder
::
find
Internal
(
const
isc
::
dns
::
Name
&
name
,
const
isc
::
dns
::
RRType
&
type
,
isc
::
dns
::
RRsetList
*
,
std
::
vector
<
isc
::
dns
::
ConstRRsetPtr
>*
target
,
const
FindOptions
options
)
{
LOG_DEBUG
(
logger
,
DBG_TRACE_DETAILED
,
DATASRC_DATABASE_FIND_RECORDS
)
...
...
@@ -820,16 +866,18 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
WantedTypes
final_types
(
FINAL_TYPES
());
final_types
.
insert
(
type
);
const
FoundRRsets
found
=
getRRsets
(
name
.
toText
(),
final_types
,
!
is_origin
);
!
is_origin
,
NULL
,
type
==
RRType
::
ANY
());
if
(
found
.
first
)
{
// Something found at the domain name. Look into it further to get
// the final result.
return
(
findOnNameResult
(
name
,
type
,
options
,
is_origin
,
found
,
NULL
));
return
(
findOnNameResult
(
name
,
type
,
options
,
is_origin
,
found
,
NULL
,
target
));
}
else
{
// Did not find anything at all at the domain name, so check for
// subdomains or wildcards.
return
(
findNoNameResult
(
name
,
type
,
options
,
dresult
));
return
(
findNoNameResult
(
name
,
type
,
options
,
dresult
,
target
));
}
}
...
...
@@ -897,7 +945,7 @@ public:
// Find the SOA of the zone (may or may not succeed). Note that
// this must be done before starting the iteration context.
soa_
=
DatabaseClient
::
Finder
(
accessor_
,
zone
.
second
,
zone_name
).
find
(
zone_name
,
RRType
::
SOA
()
,
NULL
).
rrset
;
find
(
zone_name
,
RRType
::
SOA
()).
rrset
;
// Request the context
context_
=
accessor_
->
getAllRecords
(
zone
.
second
);
...
...
src/lib/datasrc/database.h