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
Pavel Zhukov
Kea
Commits
41362fbd
Commit
41362fbd
authored
Dec 16, 2010
by
Jerry
Browse files
merge trac422 : Implement memory Data Source Class
git-svn-id:
svn://bind10.isc.org/svn/bind10/trunk@3866
e5f2f494-b856-4b98-b285-d166d9295462
parent
7e0a51e9
Changes
11
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
41362fbd
130. [func] jerry
src/lib/datasrc: Introduced a new class MemoryDataSrc to provide
the general interface for memory data source. For the initial
implementation, we don't make it a derived class of AbstractDataSrc
because the interface is so different(we'll eventually consider this
as part of the generalization work).
(Trac #422, svn r3566)
129. [func] jinmei
src/lib/dns: Added new functions masterLoad() for loading master
zone files. The initial implementation can only parse a limited
...
...
src/bin/auth/query.cc
View file @
41362fbd
...
...
@@ -26,10 +26,10 @@ namespace isc {
namespace
auth
{
void
Query
::
process
()
const
{
const
ZoneTable
::
FindResult
result
=
zone_table_
.
find
(
qname_
);
const
ZoneTable
::
FindResult
result
=
zone_table_
.
find
Zone
(
qname_
);
if
(
result
.
code
!=
ZoneTable
::
SUCCESS
&&
result
.
code
!=
ZoneTable
::
PARTIALMATCH
)
{
if
(
result
.
code
!=
isc
::
datasrc
::
result
::
SUCCESS
&&
result
.
code
!=
isc
::
datasrc
::
result
::
PARTIALMATCH
)
{
response_
.
setRcode
(
Rcode
::
SERVFAIL
());
return
;
}
...
...
src/bin/auth/tests/query_unittest.cc
View file @
41362fbd
...
...
@@ -55,7 +55,7 @@ TEST_F(QueryTest, noZone) {
TEST_F
(
QueryTest
,
matchZone
)
{
// add a matching zone. since the zone is empty right now, the response
// should have NXDOMAIN.
zone_table
.
add
(
ZonePtr
(
new
MemoryZone
(
qclass
,
Name
(
"example.com"
))));
zone_table
.
add
Zone
(
ZonePtr
(
new
MemoryZone
(
qclass
,
Name
(
"example.com"
))));
query
.
process
();
EXPECT_EQ
(
Rcode
::
NXDOMAIN
(),
response
.
getRcode
());
}
...
...
@@ -63,7 +63,7 @@ TEST_F(QueryTest, matchZone) {
TEST_F
(
QueryTest
,
noMatchZone
)
{
// there's a zone in the table but it doesn't match the qname. should
// result in SERVFAIL.
zone_table
.
add
(
ZonePtr
(
new
MemoryZone
(
qclass
,
Name
(
"example.org"
))));
zone_table
.
add
Zone
(
ZonePtr
(
new
MemoryZone
(
qclass
,
Name
(
"example.org"
))));
query
.
process
();
EXPECT_EQ
(
Rcode
::
SERVFAIL
(),
response
.
getRcode
());
}
...
...
src/lib/datasrc/Makefile.am
View file @
41362fbd
...
...
@@ -16,3 +16,4 @@ libdatasrc_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
libdatasrc_la_SOURCES
+=
query.h query.cc
libdatasrc_la_SOURCES
+=
cache.h cache.cc
libdatasrc_la_SOURCES
+=
zonetable.h zonetable.cc
libdatasrc_la_SOURCES
+=
memory_datasrc.h memory_datasrc.cc
src/lib/datasrc/memory_datasrc.cc
0 → 100644
View file @
41362fbd
// 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.
#include
<dns/name.h>
#include
<datasrc/memory_datasrc.h>
using
namespace
std
;
using
namespace
isc
::
dns
;
namespace
isc
{
namespace
datasrc
{
/// Implementation details for \c MemoryDataSrc hidden from the public
/// interface.
///
/// For now, \c MemoryDataSrc only contains a \c ZoneTable object, which
/// consists of (pointers to) \c MemoryZone objects, we may add more
/// member variables later for new features.
struct
MemoryDataSrc
::
MemoryDataSrcImpl
{
ZoneTable
zone_table
;
};
MemoryDataSrc
::
MemoryDataSrc
()
:
impl_
(
new
MemoryDataSrcImpl
)
{}
MemoryDataSrc
::~
MemoryDataSrc
()
{
delete
impl_
;
}
result
::
Result
MemoryDataSrc
::
addZone
(
ZonePtr
zone
)
{
if
(
!
zone
)
{
isc_throw
(
InvalidParameter
,
"Null pointer is passed to MemoryDataSrc::addZone()"
);
}
return
(
impl_
->
zone_table
.
addZone
(
zone
));
}
MemoryDataSrc
::
FindResult
MemoryDataSrc
::
findZone
(
const
isc
::
dns
::
Name
&
name
)
const
{
return
(
FindResult
(
impl_
->
zone_table
.
findZone
(
name
).
code
,
impl_
->
zone_table
.
findZone
(
name
).
zone
));
}
}
// end of namespace datasrc
}
// end of namespace dns
src/lib/datasrc/memory_datasrc.h
0 → 100644
View file @
41362fbd
// 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 __MEMORY_DATA_SOURCE_H
#define __MEMORY_DATA_SOURCE_H 1
#include
<datasrc/zonetable.h>
namespace
isc
{
namespace
dns
{
class
Name
;
};
namespace
datasrc
{
/// \brief A data source that uses in memory dedicated backend.
///
/// The \c MemoryDataSrc class represents a data source and provides a
/// basic interface to help DNS lookup processing. For a given domain
/// name, its \c findZone() method searches the in memory dedicated backend
/// for the zone that gives a longest match against that name.
///
/// The in memory dedicated backend are assumed to be of the same RR class,
/// but the \c MemoryDataSrc class does not enforce the assumption through
/// its interface.
/// For example, the \c addZone() method does not check if the new zone is of
/// the same RR class as that of the others already in the dedicated backend.
/// It is caller's responsibility to ensure this assumption.
///
/// <b>Notes to developer:</b>
///
/// For now, we don't make it a derived class of AbstractDataSrc because the
/// interface is so different (we'll eventually consider this as part of the
/// generalization work).
///
/// The addZone() method takes a (Boost) shared pointer because it would be
/// inconvenient to require the caller to maintain the ownership of zones,
/// while it wouldn't be safe to delete unnecessary zones inside the dedicated
/// backend.
///
/// The findZone() method takes a domain name and returns the best matching \c
/// MemoryZone in the form of (Boost) shared pointer, so that it can provide
/// the general interface for all data sources.
///
/// Currently, \c FindResult::zone is immutable for safety.
/// In future versions we may want to make it changeable. For example,
/// we may want to allow configuration update on an existing zone.
class
MemoryDataSrc
{
public:
/// \brief A helper structure to represent the search result of
/// <code>MemoryDataSrc::find()</code>.
///
/// This is a straightforward pair of the result code and a share pointer
/// to the found zone to represent the result of \c find().
/// We use this in order to avoid overloading the return value for both
/// the result code ("success" or "not found") and the found object,
/// i.e., avoid using \c NULL to mean "not found", etc.
///
/// This is a simple value class with no internal state, so for
/// convenience we allow the applications to refer to the members
/// directly.
///
/// See the description of \c find() for the semantics of the member
/// variables.
struct
FindResult
{
FindResult
(
result
::
Result
param_code
,
const
ConstZonePtr
param_zone
)
:
code
(
param_code
),
zone
(
param_zone
)
{}
const
result
::
Result
code
;
const
ConstZonePtr
zone
;
};
///
/// \name Constructors and Destructor.
///
/// \b Note:
/// The copy constructor and the assignment operator are intentionally
/// defined as private, making this class non copyable.
//@{
private:
MemoryDataSrc
(
const
MemoryDataSrc
&
source
);
MemoryDataSrc
&
operator
=
(
const
MemoryDataSrc
&
source
);
public:
/// Default constructor.
///
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
MemoryDataSrc
();
/// The destructor.
~
MemoryDataSrc
();
//@}
/// Add a \c Zone to the \c MemoryDataSrc.
///
/// \c Zone must not be associated with a NULL pointer; otherwise
/// an exception of class \c InvalidParameter will be thrown.
/// If internal resource allocation fails, a corresponding standard
/// exception will be thrown.
/// This method never throws an exception otherwise.
///
/// \param zone A \c Zone object to be added.
/// \return \c result::SUCCESS If the zone is successfully
/// added to the memory data source.
/// \return \c result::EXIST The memory data source already
/// stores a zone that has the same origin.
result
::
Result
addZone
(
ZonePtr
zone
);
/// Find a \c Zone that best matches the given name in the \c MemoryDataSrc.
///
/// It searches the internal storage for a \c Zone that gives the
/// longest match against \c name, and returns the result in the
/// form of a \c FindResult object as follows:
/// - \c code: The result code of the operation.
/// - \c result::SUCCESS: A zone that gives an exact match
// is found
/// - \c result::PARTIALMATCH: A zone whose origin is a
// super domain of \c name is found (but there is no exact match)
/// - \c result::NOTFOUND: For all other cases.
/// - \c zone: A <Boost> shared pointer to the found \c Zone object if one
// is found; otherwise \c NULL.
///
/// This method never throws an exception.
///
/// \param name A domain name for which the search is performed.
/// \return A \c FindResult object enclosing the search result (see above).
FindResult
findZone
(
const
isc
::
dns
::
Name
&
name
)
const
;
private:
struct
MemoryDataSrcImpl
;
MemoryDataSrcImpl
*
impl_
;
};
}
}
#endif // __DATA_SOURCE_MEMORY_H
// Local Variables:
// mode: c++
// End:
src/lib/datasrc/tests/Makefile.am
View file @
41362fbd
...
...
@@ -25,11 +25,12 @@ run_unittests_SOURCES += query_unittest.cc
run_unittests_SOURCES
+=
cache_unittest.cc
run_unittests_SOURCES
+=
test_datasrc.h test_datasrc.cc
run_unittests_SOURCES
+=
zonetable_unittest.cc
run_unittests_SOURCES
+=
memory_datasrc_unittest.cc
run_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
run_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
run_unittests_LDADD
=
$(GTEST_LDADD)
run_unittests_LDADD
+=
$(SQLITE_LIBS)
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/dns/libdns++.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/cc/libcc.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libexceptions.la
...
...
src/lib/datasrc/tests/memory_datasrc_unittest.cc
0 → 100644
View file @
41362fbd
// 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.
#include
<exceptions/exceptions.h>
#include
<dns/name.h>
#include
<dns/rrclass.h>
#include
<datasrc/zonetable.h>
#include
<datasrc/memory_datasrc.h>
#include
<gtest/gtest.h>
using
namespace
isc
::
dns
;
using
namespace
isc
::
datasrc
;
namespace
{
class
MemoryDataSrcTest
:
public
::
testing
::
Test
{
protected:
MemoryDataSrcTest
()
{}
MemoryDataSrc
memory_datasrc
;
};
TEST_F
(
MemoryDataSrcTest
,
add_find_Zone
)
{
// test add zone
// Bogus zone (NULL)
EXPECT_THROW
(
memory_datasrc
.
addZone
(
ZonePtr
()),
isc
::
InvalidParameter
);
// add zones with different names one by one
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"a"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"b"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"c"
)))));
// add zones with the same name suffix
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"x.d.e.f"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"o.w.y.d.e.f"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"p.w.y.d.e.f"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"q.w.y.d.e.f"
)))));
// add super zone and its subzone
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"g.h"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"i.g.h"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"z.d.e.f"
)))));
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"j.z.d.e.f"
)))));
// different zone class isn't allowed.
EXPECT_EQ
(
result
::
EXIST
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"q.w.y.d.e.f"
)))));
// names are compared in a case insensitive manner.
EXPECT_EQ
(
result
::
EXIST
,
memory_datasrc
.
addZone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"Q.W.Y.d.E.f"
)))));
// test find zone
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
findZone
(
Name
(
"a"
)).
code
);
EXPECT_EQ
(
Name
(
"a"
),
memory_datasrc
.
findZone
(
Name
(
"a"
)).
zone
->
getOrigin
());
EXPECT_EQ
(
result
::
SUCCESS
,
memory_datasrc
.
findZone
(
Name
(
"j.z.d.e.f"
)).
code
);
EXPECT_EQ
(
Name
(
"j.z.d.e.f"
),
memory_datasrc
.
findZone
(
Name
(
"j.z.d.e.f"
)).
zone
->
getOrigin
());
// NOTFOUND
EXPECT_EQ
(
result
::
NOTFOUND
,
memory_datasrc
.
findZone
(
Name
(
"d.e.f"
)).
code
);
EXPECT_EQ
(
ConstZonePtr
(),
memory_datasrc
.
findZone
(
Name
(
"d.e.f"
)).
zone
);
EXPECT_EQ
(
result
::
NOTFOUND
,
memory_datasrc
.
findZone
(
Name
(
"w.y.d.e.f"
)).
code
);
EXPECT_EQ
(
ConstZonePtr
(),
memory_datasrc
.
findZone
(
Name
(
"w.y.d.e.f"
)).
zone
);
// there's no exact match. the result should be the longest match,
// and the code should be PARTIALMATCH.
EXPECT_EQ
(
result
::
PARTIALMATCH
,
memory_datasrc
.
findZone
(
Name
(
"j.g.h"
)).
code
);
EXPECT_EQ
(
Name
(
"g.h"
),
memory_datasrc
.
findZone
(
Name
(
"g.h"
)).
zone
->
getOrigin
());
EXPECT_EQ
(
result
::
PARTIALMATCH
,
memory_datasrc
.
findZone
(
Name
(
"z.i.g.h"
)).
code
);
EXPECT_EQ
(
Name
(
"i.g.h"
),
memory_datasrc
.
findZone
(
Name
(
"z.i.g.h"
)).
zone
->
getOrigin
());
}
}
src/lib/datasrc/tests/zonetable_unittest.cc
View file @
41362fbd
...
...
@@ -53,61 +53,61 @@ protected:
ZonePtr
zone1
,
zone2
,
zone3
;
};
TEST_F
(
ZoneTableTest
,
add
)
{
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone1
));
EXPECT_EQ
(
ZoneTable
::
EXIST
,
zone_table
.
add
(
zone1
));
TEST_F
(
ZoneTableTest
,
add
Zone
)
{
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone1
));
EXPECT_EQ
(
result
::
EXIST
,
zone_table
.
add
Zone
(
zone1
));
// names are compared in a case insensitive manner.
EXPECT_EQ
(
ZoneTable
::
EXIST
,
zone_table
.
add
(
EXPECT_EQ
(
result
::
EXIST
,
zone_table
.
add
Zone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"EXAMPLE.COM"
)))));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone2
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone3
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone2
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone3
));
// Zone table is indexed only by name. Duplicate origin name with
// different zone class isn't allowed.
EXPECT_EQ
(
ZoneTable
::
EXIST
,
zone_table
.
add
(
EXPECT_EQ
(
result
::
EXIST
,
zone_table
.
add
Zone
(
ZonePtr
(
new
MemoryZone
(
RRClass
::
CH
(),
Name
(
"example.com"
)))));
/// Bogus zone (NULL)
EXPECT_THROW
(
zone_table
.
add
(
ZonePtr
()),
isc
::
InvalidParameter
);
EXPECT_THROW
(
zone_table
.
add
Zone
(
ZonePtr
()),
isc
::
InvalidParameter
);
}
TEST_F
(
ZoneTableTest
,
remove
)
{
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone1
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone2
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone3
));
TEST_F
(
ZoneTableTest
,
remove
Zone
)
{
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone1
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone2
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone3
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
remove
(
Name
(
"example.net"
)));
EXPECT_EQ
(
ZoneTable
::
NOTFOUND
,
zone_table
.
remove
(
Name
(
"example.net"
)));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
remove
Zone
(
Name
(
"example.net"
)));
EXPECT_EQ
(
result
::
NOTFOUND
,
zone_table
.
remove
Zone
(
Name
(
"example.net"
)));
}
TEST_F
(
ZoneTableTest
,
find
)
{
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone1
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone2
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone3
));
TEST_F
(
ZoneTableTest
,
find
Zone
)
{
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone1
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone2
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone3
));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
find
(
Name
(
"example.com"
)).
code
);
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
find
Zone
(
Name
(
"example.com"
)).
code
);
EXPECT_EQ
(
Name
(
"example.com"
),
zone_table
.
find
(
Name
(
"example.com"
)).
zone
->
getOrigin
());
zone_table
.
find
Zone
(
Name
(
"example.com"
)).
zone
->
getOrigin
());
EXPECT_EQ
(
ZoneTable
::
NOTFOUND
,
zone_table
.
find
(
Name
(
"example.org"
)).
code
);
EXPECT_EQ
(
static_cast
<
c
onst
Zone
*>
(
NULL
),
zone_table
.
find
(
Name
(
"example.org"
)).
zone
);
EXPECT_EQ
(
result
::
NOTFOUND
,
zone_table
.
find
Zone
(
Name
(
"example.org"
)).
code
);
EXPECT_EQ
(
C
onstZone
Ptr
(
),
zone_table
.
find
Zone
(
Name
(
"example.org"
)).
zone
);
// there's no exact match. the result should be the longest match,
// and the code should be PARTIALMATCH.
EXPECT_EQ
(
ZoneTable
::
PARTIALMATCH
,
zone_table
.
find
(
Name
(
"www.example.com"
)).
code
);
EXPECT_EQ
(
result
::
PARTIALMATCH
,
zone_table
.
find
Zone
(
Name
(
"www.example.com"
)).
code
);
EXPECT_EQ
(
Name
(
"example.com"
),
zone_table
.
find
(
Name
(
"www.example.com"
)).
zone
->
getOrigin
());
zone_table
.
find
Zone
(
Name
(
"www.example.com"
)).
zone
->
getOrigin
());
// make sure the partial match is indeed the longest match by adding
// a zone with a shorter origin and query again.
ZonePtr
zone_com
(
new
MemoryZone
(
RRClass
::
IN
(),
Name
(
"com"
)));
EXPECT_EQ
(
ZoneTable
::
SUCCESS
,
zone_table
.
add
(
zone_com
));
EXPECT_EQ
(
result
::
SUCCESS
,
zone_table
.
add
Zone
(
zone_com
));
EXPECT_EQ
(
Name
(
"example.com"
),
zone_table
.
find
(
Name
(
"www.example.com"
)).
zone
->
getOrigin
());
zone_table
.
find
Zone
(
Name
(
"www.example.com"
)).
zone
->
getOrigin
());
}
}
src/lib/datasrc/zonetable.cc
View file @
41362fbd
...
...
@@ -77,29 +77,30 @@ ZoneTable::~ZoneTable() {
delete
impl_
;
}
ZoneTable
::
Result
ZoneTable
::
add
(
ZonePtr
zone
)
{
result
::
Result
ZoneTable
::
add
Zone
(
ZonePtr
zone
)
{
if
(
!
zone
)
{
isc_throw
(
InvalidParameter
,
"Null pointer is passed to ZoneTable::add()"
);
"Null pointer is passed to ZoneTable::add
Zone
()"
);
}
if
(
impl_
->
zones
.
insert
(
ZoneTableImpl
::
NameAndZone
(
zone
->
getOrigin
(),
zone
)).
second
==
true
)
{
return
(
SUCCESS
);
return
(
result
::
SUCCESS
);
}
else
{
return
(
EXIST
);
return
(
result
::
EXIST
);
}
}
ZoneTable
::
Result
ZoneTable
::
remove
(
const
Name
&
origin
)
{
return
(
impl_
->
zones
.
erase
(
origin
)
==
1
?
SUCCESS
:
NOTFOUND
);
result
::
Result
ZoneTable
::
removeZone
(
const
Name
&
origin
)
{
return
(
impl_
->
zones
.
erase
(
origin
)
==
1
?
result
::
SUCCESS
:
result
::
NOTFOUND
);
}
ZoneTable
::
FindResult
ZoneTable
::
find
(
const
Name
&
name
)
const
{
ZoneTable
::
find
Zone
(
const
Name
&
name
)
const
{
// Inefficient internal loop to find a longest match.
// This will be replaced with a single call to more intelligent backend.
for
(
int
i
=
0
;
i
<
name
.
getLabelCount
();
++
i
)
{
...
...
@@ -107,11 +108,11 @@ ZoneTable::find(const Name& name) const {
ZoneTableImpl
::
ZoneMap
::
const_iterator
found
=
impl_
->
zones
.
find
(
matchname
);
if
(
found
!=
impl_
->
zones
.
end
())
{
return
(
FindResult
(
i
==
0
?
SUCCESS
:
PARTIALMATCH
,
(
*
found
).
second
.
get
()
));
return
(
FindResult
(
i
==
0
?
result
::
SUCCESS
:
result
::
PARTIALMATCH
,
(
*
found
).
second
));
}
}
return
(
FindResult
(
NOTFOUND
,
NULL
));
return
(
FindResult
(
result
::
NOTFOUND
,
ConstZonePtr
()
));
}
}
// end of namespace datasrc
}
// end of namespace isc
src/lib/datasrc/zonetable.h
View file @
41362fbd
...
...
@@ -26,6 +26,21 @@ class RRClass;
};
namespace
datasrc
{
namespace
result
{
/// Result codes of various public methods of in memory data source
///
/// The detailed semantics may differ in different methods.
/// See the description of specific methods for more details.
///
/// Note: this is intended to be used from other data sources eventually,
/// but for now it's specific to in memory data source and its backend.
enum
Result
{
SUCCESS
,
///< The operation is successful.
EXIST
,
///< The search key is already stored.
NOTFOUND
,
///< The specified object is not found.
PARTIALMATCH
///< \c Only a partial match is found.
};
}
/// \brief The base class for a single authoritative zone
///
...
...
@@ -223,81 +238,22 @@ private:
/// \brief A set of authoritative zones.
///
/// The \c ZoneTable class represents a set of zones of the same RR class
/// and provides a basic interface to help DNS lookup processing.
/// For a given domain name, its \c find() method searches the set for a zone
/// that gives a longest match against that name.
///
/// The set of zones are assumed to be of the same RR class, but the
/// \c ZoneTable class does not enforce the assumption through its interface.
/// For example, the \c add() method does not check if the new zone
/// is of the same RR class as that of the others already in the table.
/// It is caller's responsibility to ensure this assumption.
///
/// <b>Notes to developer:</b>
///
/// The add() method takes a (Boost) shared pointer because it would be
/// inconvenient to require the caller to maintain the ownership of zones,
/// while it wouldn't be safe to delete unnecessary zones inside the zone
/// table.
///
/// On the other hand, the find() method returns a bare pointer, rather than
/// the shared pointer, in order to minimize the dependency on Boost
/// definitions in our public interfaces. This means the caller can only
/// refer to the returned object (via the pointer) for a short period.
/// It should be okay for simple lookup purposes, but if we see the need
/// for keeping a \c Zone object for a longer period of context, we may
/// have to revisit this decision.
/// \c ZoneTable class is primarily intended to be used as a backend for the
/// \c MemoryDataSrc class, but is exposed as a separate class in case some
/// application wants to use it directly (e.g. for a customized data source
/// implementation).
///
/// Currently, \c FindResult::zone is immutable for safety.
/// In future versions we may want to make it changeable. For example,
/// we may want to allow configuration update on an existing zone.
///
/// In BIND 9's "zt" module, the equivalent of \c find() has an "option"
/// parameter. The only defined option is the one to specify the "no exact"
/// mode, and the only purpose of that mode is to prefer a second longest match
/// even if there is an exact match in order to deal with type DS query.
/// This trick may help enhance performance, but it also seems to make the
/// implementation complicated for a very limited, minor case. So, for now,
/// we don't introduce the special mode, and, since it was the only reason to