Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
ISC Open Source Projects
Kea
Commits
6f31530f
Commit
6f31530f
authored
Mar 02, 2012
by
JINMEI Tatuya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[1607] adjusted auth::Query to use ZoneFinder::Context::getAdditional().
parent
29fab381
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
110 deletions
+87
-110
src/bin/auth/query.cc
src/bin/auth/query.cc
+82
-71
src/bin/auth/query.h
src/bin/auth/query.h
+5
-39
No files found.
src/bin/auth/query.cc
View file @
6f31530f
...
...
@@ -12,82 +12,83 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#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>
#include <dns/rrtype.h>
#include <dns/rdataclass.h>
#include <datasrc/client.h>
#include <auth/query.h>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <algorithm> // for std::max
#include <vector>
using
namespace
std
;
using
namespace
isc
::
dns
;
using
namespace
isc
::
datasrc
;
using
namespace
isc
::
dns
::
rdata
;
namespace
isc
{
namespace
auth
{
// Commonly used helper callback object for vector<ConstRRsetPtr> to
// insert them to (the specified section of) a message.
namespace
{
class
RRsetInserter
{
public:
RRsetInserter
(
Message
&
msg
,
Message
::
Section
section
,
bool
dnssec
)
:
msg_
(
msg
),
section_
(
section
),
dnssec_
(
dnssec
)
{}
void
operator
()(
const
ConstRRsetPtr
&
rrset
)
{
msg_
.
addRRset
(
section_
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
rrset
),
dnssec_
);
}
void
Query
::
addAdditional
(
ZoneFinder
&
zone
,
const
AbstractRRset
&
rrset
)
{
RdataIteratorPtr
rdata_iterator
(
rrset
.
getRdataIterator
());
for
(;
!
rdata_iterator
->
isLast
();
rdata_iterator
->
next
())
{
const
Rdata
&
rdata
(
rdata_iterator
->
getCurrent
());
if
(
rrset
.
getType
()
==
RRType
::
NS
())
{
// Need to perform the search in the "GLUE OK" mode.
const
generic
::
NS
&
ns
=
dynamic_cast
<
const
generic
::
NS
&>
(
rdata
);
addAdditionalAddrs
(
zone
,
ns
.
getNSName
(),
ZoneFinder
::
FIND_GLUE_OK
);
}
else
if
(
rrset
.
getType
()
==
RRType
::
MX
())
{
const
generic
::
MX
&
mx
(
dynamic_cast
<
const
generic
::
MX
&>
(
rdata
));
addAdditionalAddrs
(
zone
,
mx
.
getMXName
());
}
private:
Message
&
msg_
;
const
Message
::
Section
section_
;
const
bool
dnssec_
;
};
// This is a "constant" vector storing desired RR types for the additional
// section. The vector is filled first time it's used.
const
vector
<
RRType
>&
A_AND_AAAA
()
{
static
vector
<
RRType
>
needed_types
;
if
(
needed_types
.
empty
())
{
needed_types
.
push_back
(
RRType
::
A
());
needed_types
.
push_back
(
RRType
::
AAAA
());
}
return
(
needed_types
);
}
// A wrapper for ZoneFinder::Context::getAdditional() so we don't include
// duplicate RRs. This is not efficient, and we should actually unify
// this at the end of the process() method. See also #1688.
void
Query
::
addAdditionalAddrs
(
ZoneFinder
&
zone
,
const
Name
&
qname
,
const
ZoneFinder
::
FindOptions
option
s
)
getAdditional
(
const
Name
&
qname
,
RRType
qtype
,
ZoneFinder
::
Context
&
ctx
,
vector
<
ConstRRsetPtr
>&
result
s
)
{
// Out of zone name
NameComparisonResult
result
=
zone
.
getOrigin
().
compare
(
qname
);
if
((
result
.
getRelation
()
!=
NameComparisonResult
::
SUPERDOMAIN
)
&&
(
result
.
getRelation
()
!=
NameComparisonResult
::
EQUAL
))
return
;
// Omit additional data which has already been provided in the answer
// section from the additional.
//
// All the address rrset with the owner name of qname have been inserted
// into ANSWER section.
if
(
qname_
==
qname
&&
qtype_
==
RRType
::
ANY
())
return
;
// Find A rrset
if
(
qname_
!=
qname
||
qtype_
!=
RRType
::
A
())
{
ZoneFinderContextPtr
a_ctx
=
zone
.
find
(
qname
,
RRType
::
A
(),
options
|
dnssec_opt_
);
if
(
a_ctx
->
code
==
ZoneFinder
::
SUCCESS
)
{
response_
.
addRRset
(
Message
::
SECTION_ADDITIONAL
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
a_ctx
->
rrset
),
dnssec_
);
}
}
// Find AAAA rrset
if
(
qname_
!=
qname
||
qtype_
!=
RRType
::
AAAA
())
{
ZoneFinderContextPtr
aaaa_ctx
=
zone
.
find
(
qname
,
RRType
::
AAAA
(),
options
|
dnssec_opt_
);
if
(
aaaa_ctx
->
code
==
ZoneFinder
::
SUCCESS
)
{
response_
.
addRRset
(
Message
::
SECTION_ADDITIONAL
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
aaaa_ctx
->
rrset
),
dnssec_
);
vector
<
ConstRRsetPtr
>
additionals
;
ctx
.
getAdditional
(
A_AND_AAAA
(),
additionals
);
vector
<
ConstRRsetPtr
>::
const_iterator
it
=
additionals
.
begin
();
vector
<
ConstRRsetPtr
>::
const_iterator
it_end
=
additionals
.
end
();
for
(;
it
!=
it_end
;
++
it
)
{
if
((
qtype
==
(
*
it
)
->
getType
()
||
qtype
==
RRType
::
ANY
())
&&
qname
==
(
*
it
)
->
getName
())
{
continue
;
}
results
.
push_back
(
*
it
);
}
}
}
namespace
isc
{
namespace
auth
{
void
Query
::
addSOA
(
ZoneFinder
&
finder
)
{
...
...
@@ -339,21 +340,24 @@ Query::addNXRRsetProof(ZoneFinder& finder,
}
void
Query
::
addAuthAdditional
(
ZoneFinder
&
finder
)
{
Query
::
addAuthAdditional
(
ZoneFinder
&
finder
,
vector
<
ConstRRsetPtr
>&
additionals
)
{
const
Name
&
origin
=
finder
.
getOrigin
();
// Fill in authority and addtional sections.
ConstZoneFinderContextPtr
ns_context
=
finder
.
find
(
finder
.
getOrigin
(),
RRType
::
NS
(),
dnssec_opt_
);
ConstZoneFinderContextPtr
ns_context
=
finder
.
find
(
origin
,
RRType
::
NS
(),
dnssec_opt_
);
// zone origin name should have NS records
if
(
ns_context
->
code
!=
ZoneFinder
::
SUCCESS
)
{
isc_throw
(
NoApexNS
,
"There's no apex NS records in zone "
<<
finder
.
getOrigin
().
toText
());
}
else
{
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
ns_context
->
rrset
),
dnssec_
);
// Handle additional for authority section
addAdditional
(
finder
,
*
ns_context
->
rrset
);
finder
.
getOrigin
().
toText
());
}
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
ns_context
->
rrset
),
dnssec_
);
getAdditional
(
qname_
,
qtype_
,
*
ns_context
,
additionals
);
}
namespace
{
...
...
@@ -402,7 +406,8 @@ Query::process() {
// indirectly via delegation). Look into the zone.
response_
.
setHeaderFlag
(
Message
::
HEADERFLAG_AA
);
response_
.
setRcode
(
Rcode
::
NOERROR
());
std
::
vector
<
ConstRRsetPtr
>
target
;
vector
<
ConstRRsetPtr
>
target
;
vector
<
ConstRRsetPtr
>
additionals
;
boost
::
function0
<
ZoneFinderContextPtr
>
find
;
const
bool
qtype_is_any
=
(
qtype_
==
RRType
::
ANY
());
if
(
qtype_is_any
)
{
...
...
@@ -484,16 +489,16 @@ Query::process() {
BOOST_FOREACH
(
ConstRRsetPtr
rrset
,
target
)
{
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
rrset
),
dnssec_
);
// Handle additional for answer section
addAdditional
(
*
result
.
zone_finder
,
*
rrset
.
get
());
}
}
else
{
response_
.
addRRset
(
Message
::
SECTION_ANSWER
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
db_context
->
rrset
),
dnssec_
);
// Handle additional for answer section
addAdditional
(
*
result
.
zone_finder
,
*
db_context
->
rrset
);
}
// Retrieve additional records for the answer
getAdditional
(
qname_
,
qtype_
,
*
db_context
,
additionals
);
// 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
...
...
@@ -502,7 +507,7 @@ Query::process() {
db_context
->
code
!=
ZoneFinder
::
SUCCESS
||
(
qtype_
!=
RRType
::
NS
()
&&
!
qtype_is_any
))
{
addAuthAdditional
(
*
result
.
zone_finder
);
addAuthAdditional
(
*
result
.
zone_finder
,
additionals
);
}
// If the answer is a result of wildcard substitution,
...
...
@@ -524,12 +529,14 @@ Query::process() {
response_
.
addRRset
(
Message
::
SECTION_AUTHORITY
,
boost
::
const_pointer_cast
<
AbstractRRset
>
(
db_context
->
rrset
),
dnssec_
);
// Retrieve additional records for the name servers
db_context
->
getAdditional
(
A_AND_AAAA
(),
additionals
);
// If DNSSEC is requested, see whether there is a DS
// record for this delegation.
if
(
dnssec_
)
{
addDS
(
*
result
.
zone_finder
,
db_context
->
rrset
->
getName
());
}
addAdditional
(
*
result
.
zone_finder
,
*
db_context
->
rrset
);
break
;
case
ZoneFinder
::
NXDOMAIN
:
response_
.
setRcode
(
Rcode
::
NXDOMAIN
());
...
...
@@ -555,6 +562,10 @@ Query::process() {
isc_throw
(
isc
::
NotImplemented
,
"Unknown result code"
);
break
;
}
for_each
(
additionals
.
begin
(),
additionals
.
end
(),
RRsetInserter
(
response_
,
Message
::
SECTION_ADDITIONAL
,
dnssec_
));
}
bool
...
...
src/bin/auth/query.h
View file @
6f31530f
...
...
@@ -15,8 +15,11 @@
*/
#include <exceptions/exceptions.h>
#include <dns/rrset.h>
#include <datasrc/zone.h>
#include <vector>
namespace
isc
{
namespace
dns
{
class
Message
;
...
...
@@ -129,44 +132,6 @@ private:
void
addWildcardNXRRSETProof
(
isc
::
datasrc
::
ZoneFinder
&
finder
,
isc
::
dns
::
ConstRRsetPtr
nsec
);
/// \brief Look up additional data (i.e., address records for the names
/// included in NS or MX records) and add them to the additional section.
///
/// Note: Any additional data which has already been provided in the
/// answer section (i.e., if the original query happend to be for the
/// address of the DNS server), it should be omitted from the additional.
///
/// This method may throw a exception because its underlying methods may
/// throw exceptions.
///
/// \param zone The ZoneFinder through which the additional data for the
/// query is to be found.
/// \param rrset The RRset (i.e., NS or MX rrset) which require additional
/// processing.
void
addAdditional
(
isc
::
datasrc
::
ZoneFinder
&
zone
,
const
isc
::
dns
::
AbstractRRset
&
rrset
);
/// \brief Find address records for a specified name.
///
/// Search the specified zone for AAAA/A RRs of each of the NS/MX RDATA
/// (domain name), and insert the found ones into the additional section
/// if address records are available. By default the search will stop
/// once it encounters a zone cut.
///
/// Note: we need to perform the search in the "GLUE OK" mode for NS RDATA,
/// which means that we should include A/AAAA RRs under a zone cut.
/// The glue records must exactly match the name in the NS RDATA, without
/// CNAME or wildcard processing.
///
/// \param zone The \c ZoneFinder through which the address records is to
/// be found.
/// \param qname The name in rrset RDATA.
/// \param options The search options.
void
addAdditionalAddrs
(
isc
::
datasrc
::
ZoneFinder
&
zone
,
const
isc
::
dns
::
Name
&
qname
,
const
isc
::
datasrc
::
ZoneFinder
::
FindOptions
options
=
isc
::
datasrc
::
ZoneFinder
::
FIND_DEFAULT
);
/// \brief Look up a zone's NS RRset and their address records for an
/// authoritative answer, and add them to the additional section.
///
...
...
@@ -185,7 +150,8 @@ private:
///
/// \param finder The \c ZoneFinder through which the NS and additional
/// data for the query are to be found.
void
addAuthAdditional
(
isc
::
datasrc
::
ZoneFinder
&
finder
);
void
addAuthAdditional
(
isc
::
datasrc
::
ZoneFinder
&
finder
,
std
::
vector
<
isc
::
dns
::
ConstRRsetPtr
>&
additionals
);
/// \brief Process a DS query possible at the child side of zone cut.
///
...
...
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