Skip to content
GitLab
Projects
Groups
Snippets
/
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
82f0bc8e
Commit
82f0bc8e
authored
Mar 15, 2011
by
Jelte Jansen
Browse files
Merge branch 'trac501'
parents
f1bb311e
629023f2
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/lib/nsas/Makefile.am
View file @
82f0bc8e
...
...
@@ -37,5 +37,6 @@ libnsas_la_SOURCES += zone_entry.cc zone_entry.h
libnsas_la_SOURCES
+=
fetchable.h
libnsas_la_SOURCES
+=
address_request_callback.h
libnsas_la_SOURCES
+=
random_number_generator.h
libnsas_la_SOURCES
+=
glue_hints.h glue_hints.cc
CLEANFILES
=
*
.gcno
*
.gcda
src/lib/nsas/glue_hints.cc
0 → 100644
View file @
82f0bc8e
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
"glue_hints.h"
#include
<dns/rrset.h>
#include
<dns/rdata.h>
#include
<dns/rrtype.h>
#include
<dns/rdataclass.h>
#include
<asiolink/io_address.h>
#include
<nsas/nameserver_entry.h>
using
namespace
isc
::
dns
;
using
namespace
isc
::
nsas
;
// This is a simple implementation for finding glue
//
// It iterates over the AUTHORITY section of the given Message,
// and for each NS RR it iterates over the ADDITIONAL section to
// see if there are A or AAAA records.
//
// Of course, this could be done more efficiently. One option is to
// reverse this; check for A and AAAA records (since those will only
// be there if there actually is glue, while NS records will be present
// in any delegation). However, it may be even better to let the
// Response Classifier decide on glue, while it is validating the packet
//
// (er, TODO, so to speak. discuss.)
// Helper functions
namespace
{
// Add the contents of the given A or AAAA rrset to the given
// addressvector
//
// This creates an 'dummy' NameserverEntry value, because that
// is enforced by NameserverAddress. We may want to reconsider
// the need for that (perhaps we can change it so that if it is
// NULL, all NSAS-related calls to the NameserverAddress object
// become nops)
void
addRRset
(
std
::
vector
<
NameserverAddress
>&
addresses
,
const
RRsetPtr
rrset
)
{
const
std
::
string
ns_name
=
rrset
->
getName
().
toText
();
RdataIteratorPtr
rdi
=
rrset
->
getRdataIterator
();
while
(
!
rdi
->
isLast
())
{
AddressEntry
entry
(
asiolink
::
IOAddress
(
rdi
->
getCurrent
().
toText
()));
boost
::
shared_ptr
<
NameserverEntry
>
ns_entry
(
new
NameserverEntry
(
ns_name
,
rrset
->
getClass
()));
NameserverAddress
ns_address
(
ns_entry
,
entry
,
V4_ONLY
);
addresses
.
push_back
(
ns_address
);
rdi
->
next
();
}
}
}
namespace
isc
{
namespace
nsas
{
GlueHints
::
GlueHints
(
const
std
::
string
&
zone_name
,
const
isc
::
dns
::
Message
&
delegation_message
)
{
for
(
RRsetIterator
rssi
=
delegation_message
.
beginSection
(
Message
::
SECTION_AUTHORITY
);
rssi
!=
delegation_message
.
endSection
(
Message
::
SECTION_AUTHORITY
);
++
rssi
)
{
if
((
*
rssi
)
->
getType
()
==
RRType
::
NS
()
&&
(
*
rssi
)
->
getName
().
toText
()
==
zone_name
)
{
addGlueForRRset
(
*
rssi
,
delegation_message
);
}
}
}
bool
GlueHints
::
hasGlue
(
AddressFamily
family
)
const
{
return
((
addresses_v4
.
size
()
>
0
&&
(
family
==
ANY_OK
||
family
==
V4_ONLY
))
||
(
addresses_v6
.
size
()
>
0
&&
(
family
==
ANY_OK
||
family
==
V6_ONLY
)));
}
NameserverAddress
GlueHints
::
getGlue
(
AddressFamily
family
)
const
{
// TODO: once we have a more general random lib, use that. Since
// this is simply glue, and we don't need a weighted selection,
// for now srandom should be good enough. Once #583 has been merged,
// (or better yet, once that one and the weighted random have gone
// together in a util lib), we can use that.
int
max
=
0
;
size_t
v4s
=
addresses_v4
.
size
();
size_t
v6s
=
addresses_v6
.
size
();
if
(
family
==
ANY_OK
||
family
==
V4_ONLY
)
{
max
+=
v4s
;
}
if
(
family
==
ANY_OK
||
family
==
V6_ONLY
)
{
max
+=
v6s
;
}
assert
(
max
>
0
);
long
int
selection
=
random
()
%
max
;
if
(
family
==
ANY_OK
)
{
if
(
selection
<=
v4s
)
{
return
addresses_v4
[
selection
];
}
else
{
return
addresses_v6
[
selection
-
v4s
];
}
}
else
if
(
family
==
V4_ONLY
)
{
return
addresses_v4
[
selection
];
}
else
if
(
family
==
V6_ONLY
)
{
return
addresses_v6
[
selection
];
}
else
{
// Unknown family
assert
(
false
);
}
}
// Add the A and AAAA records from the given message for the given
// NS name to the relevant address vector
// (A rrsets are added to addresses_v4, AAAA rrsets are added to
// addresses_v6).
void
GlueHints
::
addGlueForName
(
const
Name
&
name
,
const
Message
&
message
)
{
for
(
RRsetIterator
rssi
=
message
.
beginSection
(
Message
::
SECTION_ADDITIONAL
);
rssi
!=
message
.
endSection
(
Message
::
SECTION_ADDITIONAL
);
++
rssi
)
{
if
((
*
rssi
)
->
getName
()
==
name
)
{
if
((
*
rssi
)
->
getType
()
==
RRType
::
A
())
{
addRRset
(
addresses_v4
,
*
rssi
);
}
else
if
((
*
rssi
)
->
getType
()
==
RRType
::
AAAA
())
{
addRRset
(
addresses_v6
,
*
rssi
);
}
}
}
}
// Add the glue for the given NS RRset in the message to the
// relevant vectors.
void
GlueHints
::
addGlueForRRset
(
const
RRsetPtr
rrset
,
const
Message
&
message
)
{
RdataIteratorPtr
rdi
=
rrset
->
getRdataIterator
();
while
(
!
rdi
->
isLast
())
{
isc
::
dns
::
Name
name
(
dynamic_cast
<
const
rdata
::
generic
::
NS
&>
(
rdi
->
getCurrent
()).
getNSName
());
addGlueForName
(
name
,
message
);
rdi
->
next
();
}
}
}
// namespace nsas
}
// namespace isc
src/lib/nsas/glue_hints.h
0 → 100644
View file @
82f0bc8e
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __GLUE_HINTS_H
#define __GLUE_HINTS_H
#include
<vector>
#include
<dns/message.h>
#include
"nsas_types.h"
#include
"nameserver_address.h"
namespace
isc
{
namespace
nsas
{
class
GlueHints
{
public:
/// \brief Empty constructor
GlueHints
()
{};
/// \brief Constructor
///
/// Creates a glue hint object, with the glue data found in the
/// given packet.
///
/// \param zone_name The name of the zone to find glue for
/// \param delegation_message The Message that may contain glue
GlueHints
(
const
std
::
string
&
zone_name
,
const
isc
::
dns
::
Message
&
delegation_message
);
/// \brief Check if there is glue for the given AddressFamily
///
/// \param family the AddressFamily to check for glue for
/// \return true if there is glue for that family. false if not
bool
hasGlue
(
AddressFamily
family
)
const
;
/// \brief Get a random glue address for the given family
///
/// ONLY call this if hasGlue() returned true.
///
/// \param family the AddressFamily to get glue for
/// \return a NameserverAddress specified by the glue
NameserverAddress
getGlue
(
AddressFamily
family
)
const
;
private:
void
addGlueForName
(
const
isc
::
dns
::
Name
&
name
,
const
isc
::
dns
::
Message
&
message
);
void
addGlueForRRset
(
const
isc
::
dns
::
RRsetPtr
rrset
,
const
isc
::
dns
::
Message
&
message
);
std
::
vector
<
NameserverAddress
>
addresses_v4
;
std
::
vector
<
NameserverAddress
>
addresses_v6
;
};
}
}
#endif // __GLUE_HINTS_H
src/lib/nsas/nameserver_address_store.cc
View file @
82f0bc8e
...
...
@@ -29,6 +29,7 @@
#include
"nameserver_entry.h"
#include
"nameserver_address_store.h"
#include
"zone_entry.h"
#include
"glue_hints.h"
#include
"address_request_callback.h"
using
namespace
isc
::
dns
;
...
...
@@ -80,7 +81,8 @@ newZone(
void
NameserverAddressStore
::
lookup
(
const
string
&
zone
,
const
RRClass
&
class_code
,
boost
::
shared_ptr
<
AddressRequestCallback
>
callback
,
AddressFamily
family
)
boost
::
shared_ptr
<
AddressRequestCallback
>
callback
,
AddressFamily
family
,
const
GlueHints
glue_hints
)
{
pair
<
bool
,
boost
::
shared_ptr
<
ZoneEntry
>
>
zone_obj
(
zone_hash_
->
getOrAdd
(
HashKey
(
zone
,
class_code
),
boost
::
bind
(
newZone
,
&
resolver_
,
&
zone
,
&
class_code
,
...
...
@@ -90,7 +92,8 @@ NameserverAddressStore::lookup(const string& zone, const RRClass& class_code,
}
else
{
zone_lru_
->
touch
(
zone_obj
.
second
);
}
zone_obj
.
second
->
addCallback
(
callback
,
family
);
zone_obj
.
second
->
addCallback
(
callback
,
family
,
glue_hints
);
}
void
...
...
src/lib/nsas/nameserver_address_store.h
View file @
82f0bc8e
...
...
@@ -23,6 +23,7 @@
#include
<resolve/resolver_interface.h>
#include
"nsas_types.h"
#include
"glue_hints.h"
namespace
isc
{
// Some forward declarations, so we do not need to include so many headers
...
...
@@ -85,7 +86,7 @@ public:
/// \param family Which address is requested.
void
lookup
(
const
std
::
string
&
zone
,
const
dns
::
RRClass
&
class_code
,
boost
::
shared_ptr
<
AddressRequestCallback
>
callback
,
AddressFamily
family
=
ANY_OK
);
family
=
ANY_OK
,
const
GlueHints
=
GlueHints
()
);
/// \brief cancel the given lookup action
///
...
...
src/lib/nsas/zone_entry.cc
View file @
82f0bc8e
...
...
@@ -224,7 +224,8 @@ class ZoneEntry::ResolverCallback :
};
void
ZoneEntry
::
addCallback
(
CallbackPtr
callback
,
AddressFamily
family
)
{
ZoneEntry
::
addCallback
(
CallbackPtr
callback
,
AddressFamily
family
,
const
GlueHints
glue_hints
)
{
Lock
lock
(
mutex_
);
bool
ask
(
false
);
...
...
@@ -238,11 +239,18 @@ ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
if
(
getState
()
==
EXPIRED
||
getState
()
==
NOT_ASKED
)
{
ask
=
true
;
}
// We do not have the answer right away, just queue the callback
bool
execute
(
!
ask
&&
getState
()
!=
IN_PROGRESS
&&
callbacks_
[
family
].
empty
());
callbacks_
[
family
].
push_back
(
callback
);
// Unless there was glue
if
(
ask
&&
glue_hints
.
hasGlue
(
family
))
{
callback
->
success
(
glue_hints
.
getGlue
(
family
));
}
else
{
callbacks_
[
family
].
push_back
(
callback
);
}
if
(
execute
)
{
// Try to process it right away, store if not possible to handle
process
(
family
,
NameserverPtr
());
...
...
src/lib/nsas/zone_entry.h
View file @
82f0bc8e
...
...
@@ -32,6 +32,7 @@
#include
"fetchable.h"
#include
"nsas_types.h"
#include
"random_number_generator.h"
#include
"glue_hints.h"
namespace
isc
{
namespace
nsas
{
...
...
@@ -97,9 +98,13 @@ public:
*
* \param callback The callback itself.
* \param family Which address family is acceptable as an answer?
* \param glue_hints If a non-empty glue-hints object is passed,
* and the NSAS does not have an immediate answer, it will
* call back immediately with one of the glue hints.
*/
void
addCallback
(
boost
::
shared_ptr
<
AddressRequestCallback
>
callback
,
AddressFamily
family
);
callback
,
AddressFamily
family
,
const
GlueHints
glue_hints
=
GlueHints
());
/**
* \short Remove a callback from the list
...
...
src/lib/resolve/recursive_query.cc
View file @
82f0bc8e
...
...
@@ -330,7 +330,7 @@ private:
isc
::
resolve
::
ResponseClassifier
::
classify
(
question_
,
incoming
,
cname_target
,
cname_count_
);
bool
found_ns
_address
=
false
;
bool
found_ns
=
false
;
switch
(
category
)
{
case
isc
::
resolve
::
ResponseClassifier
::
ANSWER
:
...
...
@@ -384,7 +384,7 @@ private:
// classifier should have error'd)
// TODO: should we check if it really is subzone?
for
(
RRsetIterator
rrsi
=
incoming
.
beginSection
(
Message
::
SECTION_AUTHORITY
);
rrsi
!=
incoming
.
endSection
(
Message
::
SECTION_AUTHORITY
)
&&
!
found_ns
_address
;
rrsi
!=
incoming
.
endSection
(
Message
::
SECTION_AUTHORITY
)
&&
!
found_ns
;
++
rrsi
)
{
ConstRRsetPtr
rrs
=
*
rrsi
;
if
(
rrs
->
getType
()
==
RRType
::
NS
())
{
...
...
@@ -393,18 +393,26 @@ private:
// libraries, so as not to need many conversions)
cur_zone_
=
rrs
->
getName
().
toText
();
dlog
(
"Referred to zone "
+
cur_zone_
);
found_ns
_address
=
true
;
found_ns
=
true
;
break
;
}
}
if
(
found_ns
_address
)
{
if
(
found_ns
)
{
// next resolver round
// we do NOT use doLookup() here, but send() (i.e. we
// skip the cache), since if we had the final answer
// instead of a delegation cached, we would have been
// there by now.
send
();
GlueHints
glue_hints
(
cur_zone_
,
incoming
);
// Ask the NSAS for an address, or glue.
// This will eventually result in either sendTo()
// or stop() being called by nsas_callback_
assert
(
!
nsas_callback_out_
);
nsas_callback_out_
=
true
;
nsas_
.
lookup
(
cur_zone_
,
question_
.
getClass
(),
nsas_callback_
,
ANY_OK
,
glue_hints
);
return
false
;
}
else
{
dlog
(
"No NS RRset in referral?"
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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