BIND 10 trac2877, updated. 0a9abd16730fa7708967c4b17dd1a36b7c75f363 Changelog for #2877
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Apr 10 07:38:11 UTC 2013
The branch, trac2877 has been updated
via 0a9abd16730fa7708967c4b17dd1a36b7c75f363 (commit)
via 33bd949ac7288c61ed0a664b7329b50b36d180e5 (commit)
via ee44f96ae1e8556fa04077f708287cb017dbbd0e (commit)
via 1779eb23b4a147af7585f1c7d090f7c00ecaff6d (commit)
via cac02e9290600407bd6f3071c6654c1216278616 (commit)
via 403c7178590825e101e0822715fa557403ff5c33 (commit)
via 68863a7847788b6dfa9de464c5daf7e48db6a273 (commit)
via e744b4b23d47a3467cb0a69a9ace6baa1576ba5f (commit)
via 88e7a72ae29daf1dfd87cd4fb6ae31bbc6fb9684 (commit)
via 91a0d273da950aac6348bbc900ceca502a6974db (commit)
via 2b7e75de166cb416a60080ad34d8acbed4fd8119 (commit)
via 0d8a7d1e48a1b1df5fc09a65bacd550a4bba6d00 (commit)
via 06602f5a998ac727aadd8e094e633c569487ac8f (commit)
via 1eb1178479503a5daf0f0ba43bf729d64c6ecd7c (commit)
via 29c3f7f4e82d7e85f0f5fb692345fd55092796b4 (commit)
via d538f9ed878a0abf65a91b1ab70d86d58aaad9aa (commit)
via 3f3bc96b8f17677c90dc7cb049a36666164ef908 (commit)
via 25b5b6cabd4eb505b0a003718c30b3114440a16d (commit)
via 1032577a333784acde807d02124854a6ca57de71 (commit)
via 53c635403b6bd8a23c6f0b24bab357c6a355f277 (commit)
via c3a8a2254eb9d4226910524936292aa053fa39f7 (commit)
via 3b6cd417ea4ade9d616b12e7cb0577f892bf18b6 (commit)
via 492b1ef54094f220280d58b42ee0749ef829a045 (commit)
via 7c0534d4b3dcd4b318dca8ebdcb1f1424c14931b (commit)
via bd65ec46d25bb56ab77f50ebf8d6e431fda2d478 (commit)
via f5f3e572144232518b47dba3ed32a6cded151a47 (commit)
via ff8f84b695de0e5350af325c675ab2bdbab79cc0 (commit)
via 02fb3337a339f2043183ae66062a774ae6375e83 (commit)
via ab624f466e084edecb4a6299a56f8d33282a1ba0 (commit)
via 859e0b3e82d4cc5270d8fb557f0120dc35edd1a3 (commit)
via 3511c6e6512c0004d9332ea85d1d3d4c03a414e0 (commit)
from 21d0817bae3a1aded59cf3809bff5856dbba792a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 0a9abd16730fa7708967c4b17dd1a36b7c75f363
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Apr 10 09:17:28 2013 +0200
Changelog for #2877
commit 33bd949ac7288c61ed0a664b7329b50b36d180e5
Merge: ee44f96 21d0817
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Apr 10 09:11:12 2013 +0200
Merge #2877
Fix SQLite backend so the deletes are not so slow.
This is the urgent part of the fix; we'll have another half of the branch
later, to clean up some details.
commit ee44f96ae1e8556fa04077f708287cb017dbbd0e
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Tue Apr 9 12:29:03 2013 -0700
[master] editorial: removed a garbage character
commit 1779eb23b4a147af7585f1c7d090f7c00ecaff6d
Author: Thomas Markwalder <tmark at isc.org>
Date: Tue Apr 9 15:23:31 2013 -0400
[master] Added ChangeLog entry 600.
commit cac02e9290600407bd6f3071c6654c1216278616
Merge: 403c717 91a0d27
Author: Thomas Markwalder <tmark at isc.org>
Date: Tue Apr 9 15:16:32 2013 -0400
[master] Merge branch 'trac2837' always use STRICT_SQL mode in
mysql_lease_mgr.
commit 403c7178590825e101e0822715fa557403ff5c33
Author: Jeremy C. Reed <jreed at isc.org>
Date: Tue Apr 9 10:09:48 2013 -0500
[master] fix regression in MasterLoaderTest
I introduced problem by fixing a typo in a comment in a zone file.
The character positions or file sizes of the file were hardcoded
in the unit test. I had seen the failure on my system but didn't
associate it. (My mistake for not looking closely.)
The typo fix added one character so changed the hardcoded 549 to 500
and 506 to 507.
(Later maybe some macros should be used for this?)
commit 68863a7847788b6dfa9de464c5daf7e48db6a273
Merge: e744b4b 88e7a72
Author: Jeremy C. Reed <jreed at isc.org>
Date: Tue Apr 9 08:17:34 2013 -0500
[master]Merge branch 'master' of ssh://git.bind10.isc.org/var/bind10/git/bind10
merged
commit e744b4b23d47a3467cb0a69a9ace6baa1576ba5f
Author: Jeremy C. Reed <jreed at isc.org>
Date: Tue Apr 9 08:15:22 2013 -0500
[master] many spelling or typo fixes
mostly in documentation or in comments
reviewed by muks via jabber
includes output changes for two isc_throw.
commit 88e7a72ae29daf1dfd87cd4fb6ae31bbc6fb9684
Merge: 0d8a7d1 bd65ec4
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Apr 9 15:14:53 2013 +0200
Merge #2888
Fix failure to connect in msgq tests.
commit bd65ec46d25bb56ab77f50ebf8d6e431fda2d478
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Apr 3 12:04:44 2013 +0200
[2888] Close socket even on connect error
Even if we fail to connect, close the socket. It is loosely related to
the previous commit, as that one used unsuccessful connection attempts
to discover msgq is not ready yet and the unit tests complained. It
should have no real effect, since the garbage collector would reclaim
the socket after a while anyway.
commit f5f3e572144232518b47dba3ed32a6cded151a47
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Apr 3 11:59:21 2013 +0200
[2888] Try connecting instead of looking for socket file
This should solve the race condition when the socket file is created,
but connect to it does not work yet, because listen() was not called on
it yet. Really connecting ensures it is possible to connect.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 30 ++-
doc/guide/bind10-guide.xml | 14 +-
src/bin/bind10/init.py.in | 2 +-
src/bin/bind10/tests/init_test.py.in | 2 +-
src/bin/cfgmgr/plugins/tests/tsig_keys_test.py | 2 +-
src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in | 2 +-
src/bin/dhcp4/config_parser.cc | 93 ++++----
src/bin/dhcp4/config_parser.h | 3 +-
src/bin/dhcp4/ctrl_dhcp4_srv.h | 2 +-
src/bin/dhcp4/dhcp4_messages.mes | 2 +-
src/bin/dhcp4/dhcp4_srv.cc | 2 +-
src/bin/dhcp4/dhcp4_srv.h | 2 +-
src/bin/dhcp4/tests/config_parser_unittest.cc | 13 +-
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc | 4 +-
src/bin/dhcp6/config_parser.cc | 98 ++++----
src/bin/dhcp6/ctrl_dhcp6_srv.h | 2 +-
src/bin/dhcp6/dhcp6_srv.cc | 2 +-
src/bin/dhcp6/dhcp6_srv.h | 4 +-
src/bin/dhcp6/tests/config_parser_unittest.cc | 2 +-
src/bin/msgq/msgq.py.in | 2 +-
src/bin/msgq/tests/msgq_run_test.py | 17 +-
src/bin/msgq/tests/msgq_test.py | 6 +-
src/bin/stats/stats.py.in | 2 +-
src/bin/stats/stats_httpd.py.in | 2 +-
src/bin/stats/tests/b10-stats_test.py | 2 +-
src/bin/xfrin/tests/xfrin_test.py | 2 +-
src/bin/xfrin/xfrin.py.in | 4 +-
src/bin/zonemgr/zonemgr.py.in | 2 +-
src/lib/acl/loader.h | 4 +-
.../tests/testdata/message_nxdomain_large_ttl.wire | 2 +-
src/lib/config/ccsession.cc | 2 +-
src/lib/config/ccsession.h | 4 +-
src/lib/cryptolink/cryptolink.h | 2 +-
src/lib/datasrc/client.h | 2 +-
src/lib/datasrc/client_list.h | 2 +-
src/lib/datasrc/database.h | 6 +-
src/lib/datasrc/memory/domaintree.h | 2 +-
src/lib/datasrc/memory/rdata_serialization.h | 2 +-
src/lib/datasrc/sqlite3_accessor.h | 2 +-
.../datasrc/tests/zone_finder_context_unittest.cc | 2 +-
src/lib/dhcp/dhcp6.h | 2 +-
src/lib/dhcp/hwaddr.cc | 11 +-
src/lib/dhcp/hwaddr.h | 2 +
src/lib/dhcp/iface_mgr.h | 8 +-
src/lib/dhcp/iface_mgr_linux.cc | 4 +-
src/lib/dhcp/libdhcp++.cc | 19 +-
src/lib/dhcp/libdhcp++.h | 21 +-
src/lib/dhcp/option_custom.cc | 11 +-
src/lib/dhcp/option_definition.h | 4 +-
src/lib/dhcp/pkt6.cc | 235 ++++++++++++++++++-
src/lib/dhcp/pkt6.h | 106 ++++++++-
src/lib/dhcp/tests/hwaddr_unittest.cc | 11 +-
src/lib/dhcp/tests/option_custom_unittest.cc | 18 +-
src/lib/dhcp/tests/option_int_unittest.cc | 12 +-
src/lib/dhcp/tests/pkt6_unittest.cc | 247 +++++++++++++++++++-
src/lib/dhcpsrv/dhcp_config_parser.h | 103 +++++---
src/lib/dhcpsrv/lease_mgr.h | 2 -
src/lib/dhcpsrv/mysql_lease_mgr.cc | 16 +-
src/lib/dhcpsrv/subnet.h | 2 +-
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc | 121 ++++++++++
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc | 54 ++---
src/lib/dns/master_loader.cc | 2 +-
src/lib/dns/nsec3hash.cc | 2 +-
src/lib/dns/python/pydnspp_common.h | 2 +-
src/lib/dns/python/tests/nsec3hash_python_test.py | 2 +-
src/lib/dns/tests/labelsequence_unittest.cc | 2 +-
src/lib/dns/tests/master_loader_unittest.cc | 16 +-
src/lib/dns/tests/testdata/example.org | 2 +-
src/lib/log/log_dbglevels.h | 2 +-
src/lib/log/logger_manager_impl.h | 2 +-
src/lib/log/tests/Makefile.am | 4 +
.../log/tests/message_initializer_1_unittest.cc | 2 +-
src/lib/nsas/nameserver_entry.cc | 4 +-
src/lib/nsas/tests/nameserver_entry_unittest.cc | 6 +-
src/lib/nsas/tests/zone_entry_unittest.cc | 2 +-
src/lib/nsas/zone_entry.cc | 8 +-
src/lib/python/bind10_config.py.in | 2 +-
src/lib/python/isc/bind10/component.py | 2 +-
.../python/isc/bind10/tests/sockcreator_test.py | 2 +-
.../python/isc/bind10/tests/socket_cache_test.py | 2 +-
src/lib/python/isc/cc/session.py | 4 +-
src/lib/python/isc/config/ccsession.py | 2 +-
src/lib/python/isc/config/cfgmgr.py | 2 +-
src/lib/python/isc/config/tests/cfgmgr_test.py | 4 +-
src/lib/python/isc/datasrc/client_inc.cc | 2 +-
src/lib/python/isc/datasrc/client_python.cc | 2 +-
src/lib/python/isc/ddns/session.py | 2 +-
src/lib/python/isc/ddns/tests/session_tests.py | 2 +-
src/lib/python/isc/server_common/dns_tcp.py | 2 +-
src/lib/python/isc/sysinfo/sysinfo.py | 2 +-
src/lib/python/isc/util/socketserver_mixin.py | 2 +-
src/lib/resolve/tests/recursive_query_unittest.cc | 2 +-
src/lib/server_common/portconfig.cc | 2 +-
src/lib/util/python/gen_wiredata.py.in | 4 +-
src/lib/util/tests/fd_share_tests.cc | 2 +-
src/lib/util/unittests/resolver.h | 2 +-
src/lib/xfr/tests/client_test.cc | 2 +-
tests/lettuce/features/example.feature | 2 +-
tests/lettuce/features/nsec3_auth.feature | 2 +-
tests/tools/badpacket/option_info.h | 2 +-
tests/tools/dhcp-ubench/dhcp-perf-guide.xml | 2 +-
tests/tools/perfdhcp/command_options.cc | 2 +-
tests/tools/perfdhcp/pkt_transform.h | 2 +-
tests/tools/perfdhcp/stats_mgr.h | 4 +-
tests/tools/perfdhcp/test_control.cc | 6 +-
tests/tools/perfdhcp/test_control.h | 4 +-
.../perfdhcp/tests/command_options_unittest.cc | 2 +-
tools/system_messages.py | 2 +-
108 files changed, 1156 insertions(+), 341 deletions(-)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 953d2e8..aa90fff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+601. [bug]* jinmei, vorner
+ The "delete record" interface of the database based data source
+ was extended do that the parameter includes reversed name in
+ addition to the actual name. This may help the underlying
+ accessor implementation if reversed names are more convenient
+ for the delete operation. This was the case for the SQLite3
+ accessor implementation, and it now performs delete operations
+ much faster. At a higher level, this means IXFR and DDNS Updates
+ to the sqlite3 database are no longer so slow on large zones as
+ they were before.
+ (Trac #2877, git 33bd949ac7288c61ed0a664b7329b50b36d180e5)
+
+600. [bug] tmark
+ Changed mysql_lease_mgr to set the SQL mode option to STRICT. This
+ causes mysql it to treat invalid input data as an error. Rather than
+ "successfully" inserting a too large value by truncating it, the
+ insert will fail, and the lease manager will throw an exception.
+ Also, attempts to create a HWAddr (hardware address) object with
+ too long an array of data now throw an exception.
+ (Trac #2387, git cac02e9290600407bd6f3071c6654c1216278616)
+
+599. [func] tomek
+ libdhcp++: Pkt6 class is now able to parse and build relayed DHCPv6
+ messages.
+ (Trac #2827, git 29c3f7f4e82d7e85f0f5fb692345fd55092796b4)
+
+bind10-1.0.0beta1 released on April 4, 2013
+
598. [func]* jinmei
The separate "static" data source is now deprecated as it can be
served in the more generic "MasterFiles" type of data source.
@@ -87,7 +115,7 @@
statements. Also, the sqlite3-specific log messages have been moved
from the general datasource library to the sqlite3 datasource
(which also explicitely loads its messages).
- (Trac 2746, git 1c004d95a8b715500af448683e4a07e9b66ea926)
+ (Trac #2746, git 1c004d95a8b715500af448683e4a07e9b66ea926)
586. [func] marcin
libdhcp++: Removed unnecesary calls to the function which
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index dd8ec50..d0d1d4c 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -772,6 +772,16 @@ as a dependency earlier -->
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>--without-werror</term>
+ <listitem>
+ <simpara>Disable the default use of the
+ <option>-Werror</option> compiler flag so that
+ compiler warnings aren't build failures.
+ </simpara>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<note>
<para>
@@ -4100,7 +4110,7 @@ Dhcp4/subnet4 [] list (default)
> <userinput>config commit</userinput>
</screen>
Even though the "container" option does not carry any data except
- sub-options, the "data" field must be explictly set to an empty value.
+ sub-options, the "data" field must be explicitly set to an empty value.
This is required because in the current version of BIND 10 DHCP, the
default configuration values are not propagated to the configuration parsers:
if the "data" is not set the parser will assume that this
@@ -4812,7 +4822,7 @@ should include options from the isc option space:
> <userinput>config commit</userinput>
</screen>
Even though the "container" option does not carry any data except
- sub-options, the "data" field must be explictly set to an empty value.
+ sub-options, the "data" field must be explicitly set to an empty value.
This is required because in the current version of BIND 10 DHCP, the
default configuration values are not propagated to the configuration parsers:
if the "data" is not set the parser will assume that this
diff --git a/src/bin/bind10/init.py.in b/src/bin/bind10/init.py.in
index e57971a..efc0b04 100755
--- a/src/bin/bind10/init.py.in
+++ b/src/bin/bind10/init.py.in
@@ -223,7 +223,7 @@ class Init:
self.component_config = {}
# Some time in future, it may happen that a single component has
# multple processes (like a pipeline-like component). If so happens,
- # name "components" may be inapropriate. But as the code isn't probably
+ # name "components" may be inappropriate. But as the code isn't probably
# completely ready for it, we leave it at components for now. We also
# want to support multiple instances of a single component. If it turns
# out that we'll have a single component with multiple same processes
diff --git a/src/bin/bind10/tests/init_test.py.in b/src/bin/bind10/tests/init_test.py.in
index f384865..8ac6458 100644
--- a/src/bin/bind10/tests/init_test.py.in
+++ b/src/bin/bind10/tests/init_test.py.in
@@ -1595,7 +1595,7 @@ class TestInitComponents(unittest.TestCase):
init.components[53] = component
# case where the returned pid is unknown to us. nothing should
- # happpen then.
+ # happen then.
init.get_process_exit_status_called = False
init._get_process_exit_status = init._get_process_exit_status_unknown_pid
init.components_to_restart = []
diff --git a/src/bin/cfgmgr/plugins/tests/tsig_keys_test.py b/src/bin/cfgmgr/plugins/tests/tsig_keys_test.py
index 8c1639c..575879d 100644
--- a/src/bin/cfgmgr/plugins/tests/tsig_keys_test.py
+++ b/src/bin/cfgmgr/plugins/tests/tsig_keys_test.py
@@ -92,7 +92,7 @@ class TSigKeysTest(unittest.TestCase):
def test_bad_format(self):
"""
Test we fail on bad format. We don't really care much how here, though,
- as this should not get in trough config manager anyway.
+ as this should not get in through config manager anyway.
"""
self.assertNotEqual(None, tsig_keys.check({'bad_name': {}}))
self.assertNotEqual(None, tsig_keys.check({'keys': 'not_list'}))
diff --git a/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in b/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in
index 02b48bd..c7c1081 100644
--- a/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in
+++ b/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in
@@ -70,7 +70,7 @@ class TestPlugins(unittest.TestCase):
class TestConfigManagerStartup(unittest.TestCase):
def test_cfgmgr(self):
# some creative module use;
- # b10-cfgmgr has a hypen, so we use __import__
+ # b10-cfgmgr has a hyphen, so we use __import__
# this also gives us the chance to override the imported
# module ConfigManager in it.
b = __import__("b10-cfgmgr")
diff --git a/src/bin/dhcp4/config_parser.cc b/src/bin/dhcp4/config_parser.cc
index d8a586b..3a54c28 100644
--- a/src/bin/dhcp4/config_parser.cc
+++ b/src/bin/dhcp4/config_parser.cc
@@ -56,15 +56,6 @@ typedef isc::dhcp::DhcpConfigParser* ParserFactory(const std::string& config_id)
/// @brief a collection of factories that creates parsers for specified element names
typedef std::map<std::string, ParserFactory*> FactoryMap;
-/// @brief a collection of elements that store uint32 values (e.g. renew-timer = 900)
-typedef std::map<std::string, uint32_t> Uint32Storage;
-
-/// @brief a collection of elements that store string values
-typedef std::map<std::string, std::string> StringStorage;
-
-/// @brief Storage for parsed boolean values.
-typedef std::map<string, bool> BooleanStorage;
-
/// @brief Storage for option definitions.
typedef OptionSpaceContainer<OptionDefContainer,
OptionDefinitionPtr> OptionDefStorage;
@@ -198,7 +189,7 @@ public:
/// @brief Put a parsed value to the storage.
virtual void commit() {
if (storage_ != NULL && !param_name_.empty()) {
- (*storage_)[param_name_] = value_;
+ storage_->setParam(param_name_, value_);
}
}
@@ -292,7 +283,7 @@ public:
if (storage_ != NULL && !param_name_.empty()) {
// If a given parameter already exists in the storage we override
// its value. If it doesn't we insert a new element.
- (*storage_)[param_name_] = value_;
+ storage_->setParam(param_name_, value_);
}
}
@@ -364,7 +355,7 @@ public:
if (storage_ != NULL && !param_name_.empty()) {
// If a given parameter already exists in the storage we override
// its value. If it doesn't we insert a new element.
- (*storage_)[param_name_] = value_;
+ storage_->setParam(param_name_, value_);
}
}
@@ -735,7 +726,7 @@ private:
/// are invalid or insufficient this function emits an exception.
///
/// @warning this function does not check if options_ storage pointer
- /// is intitialized but this check is not needed here because it is done
+ /// is initialized but this check is not needed here because it is done
/// in the \ref build function.
///
/// @throw DhcpConfigError if parameters provided in the configuration
@@ -744,7 +735,7 @@ private:
// Option code is held in the uint32_t storage but is supposed to
// be uint16_t value. We need to check that value in the configuration
// does not exceed range of uint8_t and is not zero.
- uint32_t option_code = getParam<uint32_t>("code", uint32_values_);
+ uint32_t option_code = uint32_values_.getParam("code");
if (option_code == 0) {
isc_throw(DhcpConfigError, "option code must not be zero."
<< " Option code '0' is reserved in DHCPv4.");
@@ -753,9 +744,10 @@ private:
<< "', it must not exceed '"
<< std::numeric_limits<uint8_t>::max() << "'");
}
+
// Check that the option name has been specified, is non-empty and does not
- // contain spaces.
- std::string option_name = getParam<std::string>("name", string_values_);
+ // contain spaces
+ std::string option_name = string_values_.getParam("name");
if (option_name.empty()) {
isc_throw(DhcpConfigError, "name of the option with code '"
<< option_code << "' is empty");
@@ -764,7 +756,7 @@ private:
<< "', space character is not allowed");
}
- std::string option_space = getParam<std::string>("space", string_values_);
+ std::string option_space = string_values_.getParam("space");
if (!OptionSpace::validateName(option_space)) {
isc_throw(DhcpConfigError, "invalid option space name '"
<< option_space << "' specified for option '"
@@ -805,8 +797,8 @@ private:
}
// Get option data from the configuration database ('data' field).
- const std::string option_data = getParam<std::string>("data", string_values_);
- const bool csv_format = getParam<bool>("csv-format", boolean_values_);
+ const std::string option_data = string_values_.getParam("data");
+ const bool csv_format = boolean_values_.getParam("csv-format");
// Transform string of hexadecimal digits into binary format.
std::vector<uint8_t> binary;
@@ -838,7 +830,7 @@ private:
<< " does not have a definition.");
}
- // @todo We have a limited set of option definitions intiialized at the moment.
+ // @todo We have a limited set of option definitions initialized at the moment.
// In the future we want to initialize option definitions for all options.
// Consequently an error will be issued if an option definition does not exist
// for a particular option code. For now it is ok to create generic option
@@ -1080,8 +1072,9 @@ private:
/// @brief Create option definition from the parsed parameters.
void createOptionDef() {
+
// Get the option space name and validate it.
- std::string space = getParam<std::string>("space", string_values_);
+ std::string space = string_values_.getParam("space");
if (!OptionSpace::validateName(space)) {
isc_throw(DhcpConfigError, "invalid option space name '"
<< space << "'");
@@ -1089,12 +1082,11 @@ private:
// Get other parameters that are needed to create the
// option definition.
- std::string name = getParam<std::string>("name", string_values_);
- uint32_t code = getParam<uint32_t>("code", uint32_values_);
- std::string type = getParam<std::string>("type", string_values_);
- bool array_type = getParam<bool>("array", boolean_values_);
- std::string encapsulates = getParam<std::string>("encapsulate",
- string_values_);
+ std::string name = string_values_.getParam("name");
+ uint32_t code = uint32_values_.getParam("code");
+ std::string type = string_values_.getParam("type");
+ bool array_type = boolean_values_.getParam("array");
+ std::string encapsulates = string_values_.getParam("encapsulate");
// Create option definition.
OptionDefinitionPtr def;
@@ -1124,8 +1116,8 @@ private:
}
// The record-types field may carry a list of comma separated names
// of data types that form a record.
- std::string record_types = getParam<std::string>("record-types",
- string_values_);
+ std::string record_types = string_values_.getParam("record-types");
+
// Split the list of record types into tokens.
std::vector<std::string> record_tokens =
isc::util::str::tokens(record_types, ",");
@@ -1422,13 +1414,16 @@ private:
///
/// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing failed.
void createSubnet() {
- StringStorage::const_iterator it = string_values_.find("subnet");
- if (it == string_values_.end()) {
+ std::string subnet_txt;
+ try {
+ subnet_txt = string_values_.getParam("subnet");
+ } catch (DhcpConfigError) {
+ // Rethrow with precise error.
isc_throw(DhcpConfigError,
"Mandatory subnet definition in subnet missing");
}
+
// Remove any spaces or tabs.
- string subnet_txt = it->second;
boost::erase_all(subnet_txt, " ");
boost::erase_all(subnet_txt, "\t");
@@ -1440,7 +1435,7 @@ private:
size_t pos = subnet_txt.find("/");
if (pos == string::npos) {
isc_throw(DhcpConfigError,
- "Invalid subnet syntax (prefix/len expected):" << it->second);
+ "Invalid subnet syntax (prefix/len expected):" << subnet_txt);
}
// Try to create the address object. It also validates that
@@ -1540,7 +1535,6 @@ private:
/// @throw NotImplemented if trying to create a parser for unknown config element
DhcpConfigParser* createSubnet4ConfigParser(const std::string& config_id) {
FactoryMap factories;
-
factories["valid-lifetime"] = Uint32Parser::factory;
factories["renew-timer"] = Uint32Parser::factory;
factories["rebind-timer"] = Uint32Parser::factory;
@@ -1571,26 +1565,21 @@ private:
/// @throw DhcpConfigError when requested parameter is not present
Triplet<uint32_t> getParam(const std::string& name) {
uint32_t value = 0;
- bool found = false;
- Uint32Storage::iterator global = uint32_defaults.find(name);
- if (global != uint32_defaults.end()) {
- value = global->second;
- found = true;
- }
-
- Uint32Storage::iterator local = uint32_values_.find(name);
- if (local != uint32_values_.end()) {
- value = local->second;
- found = true;
- }
-
- if (found) {
- return (Triplet<uint32_t>(value));
- } else {
- isc_throw(DhcpConfigError, "Mandatory parameter " << name
+ try {
+ // look for local value
+ value = uint32_values_.getParam(name);
+ } catch (DhcpConfigError) {
+ try {
+ // no local, use global value
+ value = uint32_defaults.getParam(name);
+ } catch (DhcpConfigError) {
+ isc_throw(DhcpConfigError, "Mandatory parameter " << name
<< " missing (no global default and no subnet-"
<< "specific value)");
+ }
}
+
+ return (Triplet<uint32_t>(value));
}
/// storage for subnet-specific uint32 values
@@ -1859,7 +1848,7 @@ configureDhcp4Server(Dhcpv4Srv&, ConstElementPtr config_set) {
return (answer);
}
-const std::map<std::string, uint32_t>& getUint32Defaults() {
+const Uint32Storage& getUint32Defaults() {
return (uint32_defaults);
}
diff --git a/src/bin/dhcp4/config_parser.h b/src/bin/dhcp4/config_parser.h
index 4f1ea32..51a7556 100644
--- a/src/bin/dhcp4/config_parser.h
+++ b/src/bin/dhcp4/config_parser.h
@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <exceptions/exceptions.h>
+#include <dhcpsrv/dhcp_config_parser.h>
#include <cc/data.h>
#include <stdint.h>
#include <string>
@@ -66,7 +67,7 @@ configureDhcp4Server(Dhcpv4Srv&,
/// Uint32Parser works as expected.
///
/// @return a reference to a global uint32 values storage.
-const std::map<std::string, uint32_t>& getUint32Defaults();
+const Uint32Storage& getUint32Defaults();
}; // end of isc::dhcp namespace
}; // end of isc namespace
diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.h b/src/bin/dhcp4/ctrl_dhcp4_srv.h
index e45deff..8f14f4b 100644
--- a/src/bin/dhcp4/ctrl_dhcp4_srv.h
+++ b/src/bin/dhcp4/ctrl_dhcp4_srv.h
@@ -97,7 +97,7 @@ protected:
/// @brief A dummy configuration handler that always returns success.
///
/// This configuration handler does not perform configuration
- /// parsing and always returns success. A dummy hanlder should
+ /// parsing and always returns success. A dummy handler should
/// be installed using \ref isc::config::ModuleCCSession ctor
/// to get the initial configuration. This initial configuration
/// comprises values for only those elements that were modified
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
index 2f49ac8..8b3e255 100644
--- a/src/bin/dhcp4/dhcp4_messages.mes
+++ b/src/bin/dhcp4/dhcp4_messages.mes
@@ -74,7 +74,7 @@ many possible reasons for such a failure.
% DHCP4_LEASE_ALLOC lease %1 has been allocated for client-id %2, hwaddr %3
This debug message indicates that the server successfully granted a lease
in response to client's REQUEST message. This is a normal behavior and
-incicates successful operation.
+indicates successful operation.
% DHCP4_LEASE_ALLOC_FAIL failed to grant a lease for client-id %1, hwaddr %2
This message indicates that the server failed to grant a lease to the
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
index 261e213..c651275 100644
--- a/src/bin/dhcp4/dhcp4_srv.cc
+++ b/src/bin/dhcp4/dhcp4_srv.cc
@@ -343,7 +343,7 @@ Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
answer->setIndex(question->getIndex());
answer->setCiaddr(question->getCiaddr());
- answer->setSiaddr(IOAddress("0.0.0.0")); // explictly set this to 0
+ answer->setSiaddr(IOAddress("0.0.0.0")); // explicitly set this to 0
answer->setHops(question->getHops());
// copy MAC address
diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h
index 1c988b1..31d4794 100644
--- a/src/bin/dhcp4/dhcp4_srv.h
+++ b/src/bin/dhcp4/dhcp4_srv.h
@@ -216,7 +216,7 @@ protected:
/// @param msg_type specifies message type
void appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type);
- /// @brief Returns server-intentifier option
+ /// @brief Returns server-identifier option
///
/// @return server-id option
OptionPtr getServerID() { return serverid_; }
diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc
index 80b304c..dd11ec3 100644
--- a/src/bin/dhcp4/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp4/tests/config_parser_unittest.cc
@@ -52,15 +52,14 @@ public:
// Checks if global parameter of name have expected_value
void checkGlobalUint32(string name, uint32_t expected_value) {
- const std::map<std::string, uint32_t>& uint32_defaults = getUint32Defaults();
- std::map<std::string, uint32_t>::const_iterator it =
- uint32_defaults.find(name);
- if (it == uint32_defaults.end()) {
+ const Uint32Storage& uint32_defaults = getUint32Defaults();
+ try {
+ uint32_t actual_value = uint32_defaults.getParam(name);
+ EXPECT_EQ(expected_value, actual_value);
+ } catch (DhcpConfigError) {
ADD_FAILURE() << "Expected uint32 with name " << name
<< " not found";
- return;
}
- EXPECT_EQ(expected_value, it->second);
}
// Checks if the result of DHCP server configuration has
@@ -83,7 +82,7 @@ public:
/// option value. These parameters are: "name", "code", "data",
/// "csv-format" and "space".
///
- /// @param param_value string holiding option parameter value to be
+ /// @param param_value string holding option parameter value to be
/// injected into the configuration string.
/// @param parameter name of the parameter to be configured with
/// param value.
diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
index c938155..24842c9 100644
--- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
+++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
@@ -116,10 +116,10 @@ public:
/// @brief Configures options being requested in the PRL option.
///
- /// The lpr-servers option is NOT configured here altough it is
+ /// The lpr-servers option is NOT configured here although it is
/// added to the 'Parameter Request List' option in the
/// \ref addPrlOption. When requested option is not configured
- /// the server should not return it in its rensponse. The goal
+ /// the server should not return it in its response. The goal
/// of not configuring the requested option is to verify that
/// the server will not return it.
void configureRequestedOptions() {
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index 76ed228..0c09361 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -66,15 +66,6 @@ typedef isc::dhcp::DhcpConfigParser* ParserFactory(const std::string& config_id)
/// @brief Collection of factories that create parsers for specified element names
typedef std::map<std::string, ParserFactory*> FactoryMap;
-/// @brief Storage for parsed boolean values.
-typedef std::map<string, bool> BooleanStorage;
-
-/// @brief Collection of elements that store uint32 values (e.g. renew-timer = 900).
-typedef std::map<string, uint32_t> Uint32Storage;
-
-/// @brief Collection of elements that store string values.
-typedef std::map<string, string> StringStorage;
-
/// @brief Storage for option definitions.
typedef OptionSpaceContainer<OptionDefContainer,
OptionDefinitionPtr> OptionDefStorage;
@@ -209,7 +200,7 @@ public:
/// @brief Put a parsed value to the storage.
virtual void commit() {
if (storage_ != NULL && !param_name_.empty()) {
- (*storage_)[param_name_] = value_;
+ storage_->setParam(param_name_, value_);
}
}
@@ -317,7 +308,7 @@ public:
if (storage_ != NULL) {
// If a given parameter already exists in the storage we override
// its value. If it doesn't we insert a new element.
- (*storage_)[param_name_] = value_;
+ storage_->setParam(param_name_, value_);
}
}
@@ -393,7 +384,7 @@ public:
if (storage_ != NULL && !param_name_.empty()) {
// If a given parameter already exists in the storage we override
// its value. If it doesn't we insert a new element.
- (*storage_)[param_name_] = value_;
+ storage_->setParam(param_name_, value_);
}
}
@@ -764,7 +755,7 @@ private:
/// are invalid or insufficient this function emits an exception.
///
/// @warning this function does not check if options_ storage pointer
- /// is intitialized but this check is not needed here because it is done
+ /// is initialized but this check is not needed here because it is done
/// in the \ref build function.
///
/// @throw DhcpConfigError if parameters provided in the configuration
@@ -774,7 +765,7 @@ private:
// Option code is held in the uint32_t storage but is supposed to
// be uint16_t value. We need to check that value in the configuration
// does not exceed range of uint16_t and is not zero.
- uint32_t option_code = getParam<uint32_t>("code", uint32_values_);
+ uint32_t option_code = uint32_values_.getParam("code");
if (option_code == 0) {
isc_throw(DhcpConfigError, "option code must not be zero."
<< " Option code '0' is reserved in DHCPv6.");
@@ -785,7 +776,7 @@ private:
}
// Check that the option name has been specified, is non-empty and does not
// contain spaces.
- std::string option_name = getParam<std::string>("name", string_values_);
+ std::string option_name = string_values_.getParam("name");
if (option_name.empty()) {
isc_throw(DhcpConfigError, "name of the option with code '"
<< option_code << "' is empty");
@@ -794,7 +785,7 @@ private:
<< "', space character is not allowed");
}
- std::string option_space = getParam<std::string>("space", string_values_);
+ std::string option_space = string_values_.getParam("space");
if (!OptionSpace::validateName(option_space)) {
isc_throw(DhcpConfigError, "invalid option space name '"
<< option_space << "' specified for option '"
@@ -835,8 +826,8 @@ private:
}
// Get option data from the configuration database ('data' field).
- const std::string option_data = getParam<std::string>("data", string_values_);
- const bool csv_format = getParam<bool>("csv-format", boolean_values_);
+ const std::string option_data = string_values_.getParam("data");
+ const bool csv_format = boolean_values_.getParam("csv-format");
// Transform string of hexadecimal digits into binary format.
std::vector<uint8_t> binary;
@@ -868,7 +859,7 @@ private:
<< " does not have a definition.");
}
- // @todo We have a limited set of option definitions intiialized at the moment.
+ // @todo We have a limited set of option definitions initialized at the moment.
// In the future we want to initialize option definitions for all options.
// Consequently an error will be issued if an option definition does not exist
// for a particular option code. For now it is ok to create generic option
@@ -1109,7 +1100,7 @@ private:
/// @brief Create option definition from the parsed parameters.
void createOptionDef() {
// Get the option space name and validate it.
- std::string space = getParam<std::string>("space", string_values_);
+ std::string space = string_values_.getParam("space");
if (!OptionSpace::validateName(space)) {
isc_throw(DhcpConfigError, "invalid option space name '"
<< space << "'");
@@ -1117,12 +1108,11 @@ private:
// Get other parameters that are needed to create the
// option definition.
- std::string name = getParam<std::string>("name", string_values_);
- uint32_t code = getParam<uint32_t>("code", uint32_values_);
- std::string type = getParam<std::string>("type", string_values_);
- bool array_type = getParam<bool>("array", boolean_values_);
- std::string encapsulates = getParam<std::string>("encapsulate",
- string_values_);
+ std::string name = string_values_.getParam("name");
+ uint32_t code = uint32_values_.getParam("code");
+ std::string type = string_values_.getParam("type");
+ bool array_type = boolean_values_.getParam("array");
+ std::string encapsulates = string_values_.getParam("encapsulate");
// Create option definition.
OptionDefinitionPtr def;
@@ -1153,8 +1143,7 @@ private:
// The record-types field may carry a list of comma separated names
// of data types that form a record.
- std::string record_types = getParam<std::string>("record-types",
- string_values_);
+ std::string record_types = string_values_.getParam("record-types");
// Split the list of record types into tokens.
std::vector<std::string> record_tokens =
isc::util::str::tokens(record_types, ",");
@@ -1448,17 +1437,19 @@ private:
///
/// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing failed.
void createSubnet() {
-
- // Find a subnet string.
- StringStorage::const_iterator it = string_values_.find("subnet");
- if (it == string_values_.end()) {
+ std::string subnet_txt;
+ try {
+ subnet_txt = string_values_.getParam("subnet");
+ } catch (DhcpConfigError) {
+ // rethrow with precise error
isc_throw(DhcpConfigError,
"Mandatory subnet definition in subnet missing");
}
+
// Remove any spaces or tabs.
- string subnet_txt = it->second;
boost::erase_all(subnet_txt, " ");
boost::erase_all(subnet_txt, "\t");
+
// The subnet format is prefix/len. We are going to extract
// the prefix portion of a subnet string to create IOAddress
// object from it. IOAddress will be passed to the Subnet's
@@ -1467,7 +1458,7 @@ private:
size_t pos = subnet_txt.find("/");
if (pos == string::npos) {
isc_throw(DhcpConfigError,
- "Invalid subnet syntax (prefix/len expected):" << it->second);
+ "Invalid subnet syntax (prefix/len expected):" << subnet_txt);
}
// Try to create the address object. It also validates that
@@ -1487,11 +1478,11 @@ private:
// Get interface name. If it is defined, then the subnet is available
// directly over specified network interface.
-
- string iface;
- StringStorage::const_iterator iface_iter = string_values_.find("interface");
- if (iface_iter != string_values_.end()) {
- iface = iface_iter->second;
+ std::string iface;
+ try {
+ iface = string_values_.getParam("interface");
+ } catch (DhcpConfigError) {
+ // iface not mandatory so swallow the exception
}
/// @todo: Convert this to logger once the parser is working reliably
@@ -1624,26 +1615,21 @@ private:
/// @throw DhcpConfigError when requested parameter is not present
isc::dhcp::Triplet<uint32_t> getParam(const std::string& name) {
uint32_t value = 0;
- bool found = false;
- Uint32Storage::iterator global = uint32_defaults.find(name);
- if (global != uint32_defaults.end()) {
- value = global->second;
- found = true;
- }
-
- Uint32Storage::iterator local = uint32_values_.find(name);
- if (local != uint32_values_.end()) {
- value = local->second;
- found = true;
- }
-
- if (found) {
- return (isc::dhcp::Triplet<uint32_t>(value));
- } else {
- isc_throw(isc::dhcp::DhcpConfigError, "Mandatory parameter " << name
+ try {
+ // look for local value
+ value = uint32_values_.getParam(name);
+ } catch (DhcpConfigError) {
+ try {
+ // no local, use global value
+ value = uint32_defaults.getParam(name);
+ } catch (DhcpConfigError) {
+ isc_throw(DhcpConfigError, "Mandatory parameter " << name
<< " missing (no global default and no subnet-"
<< "specific value)");
+ }
}
+
+ return (Triplet<uint32_t>(value));
}
/// storage for subnet-specific uint32 values
diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.h b/src/bin/dhcp6/ctrl_dhcp6_srv.h
index 908304d..ffd43c3 100644
--- a/src/bin/dhcp6/ctrl_dhcp6_srv.h
+++ b/src/bin/dhcp6/ctrl_dhcp6_srv.h
@@ -95,7 +95,7 @@ protected:
/// @brief A dummy configuration handler that always returns success.
///
/// This configuration handler does not perform configuration
- /// parsing and always returns success. A dummy hanlder should
+ /// parsing and always returns success. A dummy handler should
/// be installed using \ref isc::config::ModuleCCSession ctor
/// to get the initial configuration. This initial configuration
/// comprises values for only those elements that were modified
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 4c19e74..75a5337 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -329,7 +329,7 @@ Dhcpv6Srv::generateServerID() {
// we will grow knobs to selectively turn them on or off. Also,
// this code is used only *once* during first start on a new machine
// and then server-id is stored. (or at least it will be once
- // DUID storage is implemente
+ // DUID storage is implemented)
// I wish there was a this_is_a_real_physical_interface flag...
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index bdcb560..c7b1f0f 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -40,7 +40,7 @@ namespace dhcp {
/// packets, processes them, manages leases assignment and generates
/// appropriate responses.
///
-/// @note Only one instance of this class is instantated as it encompasses
+/// @note Only one instance of this class is instantiated as it encompasses
/// the whole operation of the server. Nothing, however, enforces the
/// singleton status of the object.
class Dhcpv6Srv : public boost::noncopyable {
@@ -69,7 +69,7 @@ public:
/// @brief Destructor. Used during DHCPv6 service shutdown.
virtual ~Dhcpv6Srv();
- /// @brief Returns server-intentifier option.
+ /// @brief Returns server-indentifier option.
///
/// @return server-id option
OptionPtr getServerID() { return serverid_; }
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index 63fc980..f4ebf0c 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -88,7 +88,7 @@ public:
/// option value. These parameters are: "name", "code", "data" and
/// "csv-format".
///
- /// @param param_value string holiding option parameter value to be
+ /// @param param_value string holding option parameter value to be
/// injected into the configuration string.
/// @param parameter name of the parameter to be configured with
/// param value.
diff --git a/src/bin/msgq/msgq.py.in b/src/bin/msgq/msgq.py.in
index 8cf6191..efa3cbd 100755
--- a/src/bin/msgq/msgq.py.in
+++ b/src/bin/msgq/msgq.py.in
@@ -790,7 +790,7 @@ class MsgQ:
if not self.running:
return
- # TODO: Any config handlig goes here.
+ # TODO: Any config handling goes here.
return isc.config.create_answer(0)
diff --git a/src/bin/msgq/tests/msgq_run_test.py b/src/bin/msgq/tests/msgq_run_test.py
index 8e8cb65..95173e0 100644
--- a/src/bin/msgq/tests/msgq_run_test.py
+++ b/src/bin/msgq/tests/msgq_run_test.py
@@ -72,12 +72,21 @@ class MsgqRunTest(unittest.TestCase):
# Start msgq
self.__msgq = subprocess.Popen([MSGQ_PATH, '-s', SOCKET_PATH],
close_fds=True)
- # Wait for it to become ready (up to the alarm-set timeout)
- while not os.path.exists(SOCKET_PATH):
- # Just a short wait, so we don't hog CPU, but don't wait too long
- time.sleep(0.01)
# Some testing data
self.__no_recpt = {"result": [-1, "No such recipient"]}
+ # Wait for it to become ready (up to the alarm-set timeout)
+ connection = None
+ while not connection:
+ try:
+ # If the msgq is ready, this'll succeed. If not, it'll throw
+ # session error.
+ connection = isc.cc.session.Session(SOCKET_PATH)
+ except isc.cc.session.SessionError:
+ time.sleep(0.1) # Retry after a short time
+ # We have the connection now, that means it works. Close this
+ # connection, we won't use it. Each test gets enough new connections
+ # of its own.
+ connection.close()
def __message(self, data):
"""
diff --git a/src/bin/msgq/tests/msgq_test.py b/src/bin/msgq/tests/msgq_test.py
index 98705bf..e5a5656 100644
--- a/src/bin/msgq/tests/msgq_test.py
+++ b/src/bin/msgq/tests/msgq_test.py
@@ -186,7 +186,7 @@ class MsgQTest(unittest.TestCase):
The test is not exhaustive as it doesn't test all combination
of existence of the recipient, addressing schemes, want_answer
header and the reply header. It is not needed, these should
- be mostly independant. That means, for example, if the message
+ be mostly independent. That means, for example, if the message
is a reply and there's no recipient to send it to, the error
would not be generated no matter if we addressed the recipient
by lname or group. If we included everything, the test would
@@ -338,7 +338,7 @@ class BadSocket:
self.send_exception = send_exception
# completely wrap all calls and member access
- # (except explicitely overridden ones)
+ # (except explicitly overridden ones)
def __getattr__(self, name, *args):
attr = getattr(self.socket, name)
if isinstance(attr, collections.Callable):
@@ -834,7 +834,7 @@ class SocketTests(unittest.TestCase):
self.assertIsNone(self.__killed_socket)
def test_send_data_interrupt(self):
- '''send() is interruptted. send_data() returns 0, sock isn't killed.'''
+ '''send() is interrupted. send_data() returns 0, sock isn't killed.'''
expected_blockings = []
for eno in [errno.EAGAIN, errno.EWOULDBLOCK, errno.EINTR]:
self.__sock_error.errno = eno
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
index 577afe6..7ec530b 100755
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -194,7 +194,7 @@ class Stats:
'''Constructor
module_ccsession_class is parameterized so that test can specify
- a mocked class to test the behavior without involing network I/O.
+ a mocked class to test the behavior without involving network I/O.
In other cases this parameter shouldn't be specified.
'''
diff --git a/src/bin/stats/stats_httpd.py.in b/src/bin/stats/stats_httpd.py.in
index 82b9dcc..c3cdb76 100755
--- a/src/bin/stats/stats_httpd.py.in
+++ b/src/bin/stats/stats_httpd.py.in
@@ -407,7 +407,7 @@ class StatsHttpd:
old_config = self.config.copy()
self.load_config(new_config)
# If the http sockets aren't opened or
- # if new_config doesn't have'listen_on', it returns
+ # if new_config doesn't have 'listen_on', it returns
if len(self.httpd) == 0 or 'listen_on' not in new_config:
return isc.config.ccsession.create_answer(0)
self.close_httpd()
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index f807168..540c707 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -376,7 +376,7 @@ class TestStats(unittest.TestCase):
'report_time': 42})),
('update_module', ())], call_log)
- # Then update faked timestamp so the intial polling will happen, and
+ # Then update faked timestamp so the initial polling will happen, and
# confirm that.
call_log = []
stats.get_timestamp = lambda: 10
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index 68158db..5759bb1 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -2193,7 +2193,7 @@ class TestXfrinProcess(unittest.TestCase):
master_addrinfo, tsig_key)
# An awkward check that would specifically identify an old bug
- # where initialziation of XfrinConnection._tsig_ctx_creator caused
+ # where initialization of XfrinConnection._tsig_ctx_creator caused
# self reference and subsequently led to reference leak.
orig_ref = sys.getrefcount(conn)
conn._tsig_ctx_creator = None
diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in
index 0a67718..52d230b 100755
--- a/src/bin/xfrin/xfrin.py.in
+++ b/src/bin/xfrin/xfrin.py.in
@@ -187,7 +187,7 @@ def get_soa_serial(soa_rdata):
class XfrinState:
'''
- The states of the incomding *XFR state machine.
+ The states of the incoming *XFR state machine.
We (will) handle both IXFR and AXFR with a single integrated state
machine because they cannot be distinguished immediately - an AXFR
@@ -269,7 +269,7 @@ class XfrinState:
can be used as singleton objects. For now, however, we always instantiate
a new object for every state transition, partly because the introduction
of singleton will make a code bit complicated, and partly because
- the overhead of object instantiotion wouldn't be significant for xfrin.
+ the overhead of object instantiation wouldn't be significant for xfrin.
'''
def set_xfrstate(self, conn, new_state):
diff --git a/src/bin/zonemgr/zonemgr.py.in b/src/bin/zonemgr/zonemgr.py.in
index 619e017..fcb929a 100755
--- a/src/bin/zonemgr/zonemgr.py.in
+++ b/src/bin/zonemgr/zonemgr.py.in
@@ -191,7 +191,7 @@ class ZonemgrRefresh:
self._set_zone_retry_timer(zone_name_class)
def zone_handle_notify(self, zone_name_class, master):
- """Handle an incomding NOTIFY message via the Auth module.
+ """Handle an incoming NOTIFY message via the Auth module.
It returns True if the specified zone matches one of the locally
configured list of secondary zones; otherwise returns False.
diff --git a/src/lib/acl/loader.h b/src/lib/acl/loader.h
index fc69b44..52fdc74 100644
--- a/src/lib/acl/loader.h
+++ b/src/lib/acl/loader.h
@@ -329,7 +329,7 @@ public:
const List &list(description->listValue());
boost::shared_ptr<ACL<Context, Action> > result(
new ACL<Context, Action>(default_action_));
- // Run trough the list of elements
+ // Run through the list of elements
for (List::const_iterator i(list.begin()); i != list.end(); ++i) {
Map map;
try {
@@ -417,7 +417,7 @@ private:
}
default: {
// This is the AND-abbreviated form. We need to create an
- // AND (or "ALL") operator, loop trough the whole map and
+ // AND (or "ALL") operator, loop through the whole map and
// fill it in. We do a small trick - we create bunch of
// single-item maps, call this loader recursively (therefore
// it will get into the "case 1" branch, where there is
diff --git a/src/lib/cache/tests/testdata/message_nxdomain_large_ttl.wire b/src/lib/cache/tests/testdata/message_nxdomain_large_ttl.wire
index 142d8cf..f1971de 100644
--- a/src/lib/cache/tests/testdata/message_nxdomain_large_ttl.wire
+++ b/src/lib/cache/tests/testdata/message_nxdomain_large_ttl.wire
@@ -19,7 +19,7 @@ b1fe 8583
## Authority
##
# example.org: type SOA, class IN, mname ns1.example.org
-# TTL: 3 Hourse, 1 second (10801seconds)
+# TTL: 3 Hours, 1 second (10801 seconds)
c0 0e 00 06 00 01 00 00 2a 31 00 22 03 6e 73 31 c0
0e 05 61 64 6d 69 6e c0 0e 00 00 04 d2 00 00 0e
10 00 00 07 08 00 24 ea 00 00 00 2a 31
diff --git a/src/lib/config/ccsession.cc b/src/lib/config/ccsession.cc
index f65831d..d094ab9 100644
--- a/src/lib/config/ccsession.cc
+++ b/src/lib/config/ccsession.cc
@@ -165,7 +165,7 @@ namespace {
// getValue() (main problem described in ticket #993)
// This returns either the value set for the given relative id,
// or its default value
-// (intentially defined here so this interface does not get
+// (intentionally defined here so this interface does not get
// included in ConfigData as it is)
ConstElementPtr getValueOrDefault(ConstElementPtr config_part,
const std::string& relative_id,
diff --git a/src/lib/config/ccsession.h b/src/lib/config/ccsession.h
index 15290e6..995a5cd 100644
--- a/src/lib/config/ccsession.h
+++ b/src/lib/config/ccsession.h
@@ -313,12 +313,12 @@ public:
* spec_is_filename is true (the default), then a
* filename is assumed, otherwise a module name.
* \param handler The handler functor called whenever there's a change.
- * Called once initally from this function. May be NULL
+ * Called once initially from this function. May be NULL
* if you don't want any handler to be called and you're
* fine with requesting the data through
* getRemoteConfigValue() each time.
*
- * The handler should not throw, or it'll fall trough and
+ * The handler should not throw, or it'll fall through and
* the exception will get into strange places, probably
* aborting the application.
* \param spec_is_filename Says if spec_name is filename or module name.
diff --git a/src/lib/cryptolink/cryptolink.h b/src/lib/cryptolink/cryptolink.h
index 859065b..408ed00 100644
--- a/src/lib/cryptolink/cryptolink.h
+++ b/src/lib/cryptolink/cryptolink.h
@@ -101,7 +101,7 @@ class CryptoLinkImpl;
/// There is only one way to access it, through getCryptoLink(), which
/// returns a reference to the initialized library. On the first call,
/// it will be initialized automatically. You can however initialize it
-/// manually through a call to the initalize(), before your first call
+/// manually through a call to initialize(), before your first call
/// to getCryptoLink. Any subsequent call to initialize() will be a
/// noop.
///
diff --git a/src/lib/datasrc/client.h b/src/lib/datasrc/client.h
index 9c5d262..6929946 100644
--- a/src/lib/datasrc/client.h
+++ b/src/lib/datasrc/client.h
@@ -206,7 +206,7 @@ public:
///
/// The default implementation throws isc::NotImplemented. This allows
/// for easy and fast deployment of minimal custom data sources, where
- /// the user/implementator doesn't have to care about anything else but
+ /// the user/implementer doesn't have to care about anything else but
/// the actual queries. Also, in some cases, it isn't possible to traverse
/// the zone from logic point of view (eg. dynamically generated zone
/// data).
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index cd19c10..49e0779 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -174,7 +174,7 @@ public:
/// \brief Negative answer constructor.
///
- /// This conscructs a result for negative answer. Both pointers are
+ /// This constructs a result for negative answer. Both pointers are
/// NULL, and exact_match_ is false.
FindResult() :
dsrc_client_(NULL),
diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h
index e6610ff..88a4140 100644
--- a/src/lib/datasrc/database.h
+++ b/src/lib/datasrc/database.h
@@ -173,7 +173,7 @@ public:
///
/// This method looks up a zone for the given name in the database. It
/// should match only exact zone name (eg. name is equal to the zone's
- /// apex), as the DatabaseClient will loop trough the labels itself and
+ /// apex), as the DatabaseClient will loop through the labels itself and
/// find the most suitable zone.
///
/// It is not specified if and what implementation of this method may
@@ -326,7 +326,7 @@ public:
/// \note In case there are multiple NSEC3 chains and they collide
/// (unlikely, but it can happen), this can return multiple NSEC3
/// records.
- /// \exception any Since any implementaion can be used, the caller should
+ /// \exception any Since any implementation can be used, the caller should
/// expect any exception to be thrown.
/// \exception isc::NotImplemented in case the database does not support
/// NSEC3
@@ -880,7 +880,7 @@ public:
/// database.
///
/// Application should not come directly in contact with this class
- /// (it should handle it trough generic ZoneFinder pointer), therefore
+ /// (it should handle it through generic ZoneFinder pointer), therefore
/// it could be completely hidden in the .cc file. But it is provided
/// to allow testing and for rare cases when a database needs slightly
/// different handling, so it can be subclassed.
diff --git a/src/lib/datasrc/memory/domaintree.h b/src/lib/datasrc/memory/domaintree.h
index 6e8b062..d503a11 100644
--- a/src/lib/datasrc/memory/domaintree.h
+++ b/src/lib/datasrc/memory/domaintree.h
@@ -1684,7 +1684,7 @@ DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
}
}
- // Exchange the node at the top of the path, as we move horizontaly
+ // Exchange the node at the top of the path, as we move horizontally
// through the domain tree
node_path.pop();
node_path.push(node);
diff --git a/src/lib/datasrc/memory/rdata_serialization.h b/src/lib/datasrc/memory/rdata_serialization.h
index a6146a5..3314406 100644
--- a/src/lib/datasrc/memory/rdata_serialization.h
+++ b/src/lib/datasrc/memory/rdata_serialization.h
@@ -364,7 +364,7 @@ struct RdataEncodeSpec;
/// from the field sequence, you'll need to build the complete
/// wire-format data, and then construct a dns::Rdata object from it.
///
-/// To use it, contstruct it with the data you got from RDataEncoder,
+/// To use it, construct it with the data you got from RDataEncoder,
/// provide it with callbacks and then iterate through the data.
/// The callbacks are called with the data fields contained in the
/// data.
diff --git a/src/lib/datasrc/sqlite3_accessor.h b/src/lib/datasrc/sqlite3_accessor.h
index d014193..4d05ef6 100644
--- a/src/lib/datasrc/sqlite3_accessor.h
+++ b/src/lib/datasrc/sqlite3_accessor.h
@@ -250,7 +250,7 @@ public:
virtual std::string findPreviousName(int zone_id, const std::string& rname)
const;
- /// \brief Conrete implemantion of the pure virtual method of
+ /// \brief Concrete implementation of the pure virtual method of
/// DatabaseAccessor
virtual std::string findPreviousNSEC3Hash(int zone_id,
const std::string& hash) const;
diff --git a/src/lib/datasrc/tests/zone_finder_context_unittest.cc b/src/lib/datasrc/tests/zone_finder_context_unittest.cc
index 614b1be..1ce1cee 100644
--- a/src/lib/datasrc/tests/zone_finder_context_unittest.cc
+++ b/src/lib/datasrc/tests/zone_finder_context_unittest.cc
@@ -105,7 +105,7 @@ createSQLite3ClientWithNS(RRClass zclass, const Name& zname) {
}
// The test class. Its parameterized so we can share the test scnearios
-// for any concrete data source implementaitons.
+// for any concrete data source implementations.
class ZoneFinderContextTest :
public ::testing::TestWithParam<ClientCreator>
{
diff --git a/src/lib/dhcp/dhcp6.h b/src/lib/dhcp/dhcp6.h
index 874ee46..d5201a9 100644
--- a/src/lib/dhcp/dhcp6.h
+++ b/src/lib/dhcp/dhcp6.h
@@ -114,7 +114,7 @@ extern const int dhcpv6_type_name_max;
// Define hardware types
// Taken from http://www.iana.org/assignments/arp-parameters/
#define HWTYPE_ETHERNET 0x0001
-#define HWTYPE_INIFINIBAND 0x0020
+#define HWTYPE_INFINIBAND 0x0020
// Taken from http://www.iana.org/assignments/enterprise-numbers
#define ENTERPRISE_ID_ISC 2495
diff --git a/src/lib/dhcp/hwaddr.cc b/src/lib/dhcp/hwaddr.cc
index d19f2ad..eb23b44 100644
--- a/src/lib/dhcp/hwaddr.cc
+++ b/src/lib/dhcp/hwaddr.cc
@@ -14,9 +14,11 @@
#include <dhcp/hwaddr.h>
#include <dhcp/dhcp4.h>
+#include <exceptions/exceptions.h>
#include <iomanip>
#include <sstream>
#include <vector>
+#include <string.h>
namespace isc {
namespace dhcp {
@@ -27,10 +29,17 @@ HWAddr::HWAddr()
HWAddr::HWAddr(const uint8_t* hwaddr, size_t len, uint8_t htype)
:hwaddr_(hwaddr, hwaddr + len), htype_(htype) {
+ if (len > MAX_HWADDR_LEN) {
+ isc_throw(InvalidParameter, "hwaddr length exceeds MAX_HWADDR_LEN");
+ }
}
HWAddr::HWAddr(const std::vector<uint8_t>& hwaddr, uint8_t htype)
:hwaddr_(hwaddr), htype_(htype) {
+ if (hwaddr.size() > MAX_HWADDR_LEN) {
+ isc_throw(InvalidParameter,
+ "address vector size exceeds MAX_HWADDR_LEN");
+ }
}
std::string HWAddr::toText() const {
@@ -50,7 +59,7 @@ std::string HWAddr::toText() const {
}
bool HWAddr::operator==(const HWAddr& other) const {
- return ((this->htype_ == other.htype_) &&
+ return ((this->htype_ == other.htype_) &&
(this->hwaddr_ == other.hwaddr_));
}
diff --git a/src/lib/dhcp/hwaddr.h b/src/lib/dhcp/hwaddr.h
index 93b06a1..13a16bf 100644
--- a/src/lib/dhcp/hwaddr.h
+++ b/src/lib/dhcp/hwaddr.h
@@ -27,6 +27,8 @@ namespace dhcp {
/// @brief Hardware type that represents information from DHCPv4 packet
struct HWAddr {
public:
+ /// @brief Maximum size of a hardware address.
+ static const size_t MAX_HWADDR_LEN = 20;
/// @brief default constructor
HWAddr();
diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h
index a669a6d..a5e6b51 100644
--- a/src/lib/dhcp/iface_mgr.h
+++ b/src/lib/dhcp/iface_mgr.h
@@ -253,7 +253,7 @@ public:
/// network interface name
std::string name_;
- /// interface index (a value that uniquely indentifies an interface)
+ /// interface index (a value that uniquely identifies an interface)
int ifindex_;
/// list of assigned addresses
@@ -585,7 +585,7 @@ protected:
///
/// This method will eventually detect available interfaces. For now
/// it offers stub implementation. First interface name and link-local
- /// IPv6 address is read from intefaces.txt file.
+ /// IPv6 address is read from interfaces.txt file.
void
detectIfaces();
@@ -594,7 +594,7 @@ protected:
/// This implementations reads a single line from interfaces.txt file
/// and pretends to detect such interface. First interface name and
/// link-local IPv6 address or IPv4 address is read from the
- /// intefaces.txt file.
+ /// interfaces.txt file.
void
stubDetectIfaces();
@@ -674,7 +674,7 @@ private:
/// @param remote_addr remote address to connect to
/// @param port port to be used
/// @return local address to be used to connect to remote address
- /// @throw isc::Unexpected if unable to indentify local address
+ /// @throw isc::Unexpected if unable to identify local address
isc::asiolink::IOAddress
getLocalAddress(const isc::asiolink::IOAddress& remote_addr,
const uint16_t port);
diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc
index e7d5048..bfb267e 100644
--- a/src/lib/dhcp/iface_mgr_linux.cc
+++ b/src/lib/dhcp/iface_mgr_linux.cc
@@ -67,7 +67,7 @@ public:
/// interfaces) uses memory aliasing. Linux kernel returns a memory
/// blob that should be interpreted as series of nlmessages. There
/// are different nlmsg structures defined with varying size. They
-/// have one thing common - inital fields are laid out in the same
+/// have one thing common - initial fields are laid out in the same
/// way as nlmsghdr. Therefore different messages can be represented
/// as nlmsghdr with followed variable number of bytes that are
/// message-specific. The only reasonable way to represent this in
@@ -476,7 +476,7 @@ void IfaceMgr::detectIfaces() {
iface.setHWType(interface_info->ifi_type);
iface.setFlags(interface_info->ifi_flags);
- // Does inetface have LL_ADDR?
+ // Does interface have LL_ADDR?
if (attribs_table[IFLA_ADDRESS]) {
iface.setMac(static_cast<const uint8_t*>(RTA_DATA(attribs_table[IFLA_ADDRESS])),
RTA_PAYLOAD(attribs_table[IFLA_ADDRESS]));
diff --git a/src/lib/dhcp/libdhcp++.cc b/src/lib/dhcp/libdhcp++.cc
index 78f511d..697c33e 100644
--- a/src/lib/dhcp/libdhcp++.cc
+++ b/src/lib/dhcp/libdhcp++.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 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
@@ -128,7 +128,9 @@ LibDHCP::optionFactory(Option::Universe u,
size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
- isc::dhcp::Option::OptionCollection& options) {
+ isc::dhcp::Option::OptionCollection& options,
+ size_t* relay_msg_offset /* = 0 */,
+ size_t* relay_msg_len /* = 0 */) {
size_t offset = 0;
size_t length = buf.size();
@@ -143,6 +145,7 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
while (offset + 4 <= length) {
uint16_t opt_type = isc::util::readUint16(&buf[offset]);
offset += 2;
+
uint16_t opt_len = isc::util::readUint16(&buf[offset]);
offset += 2;
@@ -151,6 +154,16 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
return (offset);
}
+ if (opt_type == D6O_RELAY_MSG && relay_msg_offset && relay_msg_len) {
+ // remember offset of the beginning of the relay-msg option
+ *relay_msg_offset = offset;
+ *relay_msg_len = opt_len;
+
+ // do not create that relay-msg option
+ offset += opt_len;
+ continue;
+ }
+
// Get all definitions with the particular option code. Note that option
// code is non-unique within this container however at this point we
// expect to get one option definition with the particular code. If more
@@ -193,7 +206,7 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
}
size_t LibDHCP::unpackOptions4(const OptionBuffer& buf,
- isc::dhcp::Option::OptionCollection& options) {
+ isc::dhcp::Option::OptionCollection& options) {
size_t offset = 0;
// Get the list of stdandard option definitions.
diff --git a/src/lib/dhcp/libdhcp++.h b/src/lib/dhcp/libdhcp++.h
index c242611..9d8bcab 100644
--- a/src/lib/dhcp/libdhcp++.h
+++ b/src/lib/dhcp/libdhcp++.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 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
@@ -115,14 +115,27 @@ public:
/// @brief Parses provided buffer as DHCPv6 options and creates Option objects.
///
- /// Parses provided buffer and stores created Option objects
- /// in options container.
+ /// Parses provided buffer and stores created Option objects in options
+ /// container. The last two parameters are optional and are used in
+ /// relay parsing. If they are specified, relay-msg option is not created,
+ /// but rather those two parameters are specified to point out where
+ /// the relay-msg option resides and what is its length. This is perfromance
+ /// optimization that avoids unnecessary copying of potentially large
+ /// relay-msg option. It is not used for anything, except in the next
+ /// iteration its content will be treated as buffer to be parsed.
///
/// @param buf Buffer to be parsed.
/// @param options Reference to option container. Options will be
/// put here.
+ /// @param relay_msg_offset reference to a size_t structure. If specified,
+ /// offset to beginning of relay_msg option will be stored in it.
+ /// @param relay_msg_len reference to a size_t structure. If specified,
+ /// length of the relay_msg option will be stored in it.
+ /// @return offset to the first byte after last parsed option
static size_t unpackOptions6(const OptionBuffer& buf,
- isc::dhcp::Option::OptionCollection& options);
+ isc::dhcp::Option::OptionCollection& options,
+ size_t* relay_msg_offset = 0,
+ size_t* relay_msg_len = 0);
/// Registers factory method that produces options of specific option types.
///
diff --git a/src/lib/dhcp/option_custom.cc b/src/lib/dhcp/option_custom.cc
index 3d2a1a9..e807928 100644
--- a/src/lib/dhcp/option_custom.cc
+++ b/src/lib/dhcp/option_custom.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013 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
@@ -230,7 +230,7 @@ OptionCustom::createBuffers(const OptionBuffer& data_buf) {
// 1 byte larger than the size of the string
// representation of this FQDN.
data_size = fqdn.size() + 1;
- } else {
+ } else if ( (*field == OPT_BINARY_TYPE) || (*field == OPT_STRING_TYPE) ) {
// In other case we are dealing with string or binary value
// which size can't be determined. Thus we consume the
// remaining part of the buffer for it. Note that variable
@@ -238,14 +238,11 @@ OptionCustom::createBuffers(const OptionBuffer& data_buf) {
// that the validate() function in OptionDefinition object
// should have checked wheter it is a case for this option.
data_size = std::distance(data, data_buf.end());
- }
- if (data_size == 0) {
+ } else {
// If we reached the end of buffer we assume that this option is
// truncated because there is no remaining data to initialize
// an option field.
- if (data_size == 0) {
- isc_throw(OutOfRange, "option buffer truncated");
- }
+ isc_throw(OutOfRange, "option buffer truncated");
}
} else {
// Our data field requires that there is a certain chunk of
diff --git a/src/lib/dhcp/option_definition.h b/src/lib/dhcp/option_definition.h
index 233f778..0aa0e17 100644
--- a/src/lib/dhcp/option_definition.h
+++ b/src/lib/dhcp/option_definition.h
@@ -167,7 +167,7 @@ public:
///
/// This constructor sets the name of the option space that is
/// encapsulated by this option. The encapsulated option space
- /// indentifies sub-options that are carried within this option.
+ /// identifies sub-options that are carried within this option.
/// This constructor does not allow to set array indicator
/// because options comprising an array of data fields must
/// not be used with sub-options.
@@ -186,7 +186,7 @@ public:
///
/// This constructor sets the name of the option space that is
/// encapsulated by this option. The encapsulated option space
- /// indentifies sub-options that are carried within this option.
+ /// identifies sub-options that are carried within this option.
/// This constructor does not allow to set array indicator
/// because options comprising an array of data fields must
/// not be used with sub-options.
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index c3a98bf..c97281e 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 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
@@ -21,10 +21,17 @@
#include <sstream>
using namespace std;
+using namespace isc::asiolink;
namespace isc {
namespace dhcp {
+Pkt6::RelayInfo::RelayInfo()
+ :msg_type_(0), hop_count_(0), linkaddr_("::"), peeraddr_("::"), relay_msg_len_(0) {
+ // interface_id_, subscriber_id_, remote_id_ initialized to NULL
+ // echo_options_ initialized to empty collection
+}
+
Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */) :
proto_(proto),
msg_type_(0),
@@ -54,9 +61,61 @@ Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/) :
}
uint16_t Pkt6::len() {
+ if (relay_info_.empty()) {
+ return (directLen());
+ } else {
+ // Unfortunately we need to re-calculate relay size every time, because
+ // we need to make sure that once a new option is added, its extra size
+ // is reflected in Pkt6::len().
+ calculateRelaySizes();
+ return (relay_info_[0].relay_msg_len_ + getRelayOverhead(relay_info_[0]));
+ }
+}
+
+OptionPtr Pkt6::getRelayOption(uint16_t opt_type, uint8_t relay_level) {
+ if (relay_level >= relay_info_.size()) {
+ isc_throw(OutOfRange, "This message was relayed " << relay_info_.size() << " time(s)."
+ << " There is no info about " << relay_level + 1 << " relay.");
+ }
+
+ for (Option::OptionCollection::iterator it = relay_info_[relay_level].options_.begin();
+ it != relay_info_[relay_level].options_.end(); ++it) {
+ if ((*it).second->getType() == opt_type) {
+ return (it->second);
+ }
+ }
+
+ return (OptionPtr());
+}
+
+uint16_t Pkt6::getRelayOverhead(const RelayInfo& relay) const {
+ uint16_t len = DHCPV6_RELAY_HDR_LEN // fixed header
+ + Option::OPTION6_HDR_LEN; // header of the relay-msg option
+
+ for (Option::OptionCollection::const_iterator opt = relay.options_.begin();
+ opt != relay.options_.end(); ++opt) {
+ len += (opt->second)->len();
+ }
+
+ return (len);
+}
+
+uint16_t Pkt6::calculateRelaySizes() {
+
+ uint16_t len = directLen(); // start with length of all options
+
+ for (int relay_index = relay_info_.size(); relay_index > 0; --relay_index) {
+ relay_info_[relay_index - 1].relay_msg_len_ = len;
+ len += getRelayOverhead(relay_info_[relay_index - 1]);
+ }
+
+ return (len);
+}
+
+uint16_t Pkt6::directLen() const {
uint16_t length = DHCPV6_PKT_HDR_LEN; // DHCPv6 header
- for (Option::OptionCollection::iterator it = options_.begin();
+ for (Option::OptionCollection::const_iterator it = options_.begin();
it != options_.end();
++it) {
length += (*it).second->len();
@@ -82,6 +141,50 @@ Pkt6::pack() {
bool
Pkt6::packUDP() {
try {
+
+ // is this a relayed packet?
+ if (!relay_info_.empty()) {
+
+ // calculate size needed for each relay (if there is only one relay,
+ // then it will be equal to "regular" length + relay-forw header +
+ // size of relay-msg option header + possibly size of interface-id
+ // option (if present). If there is more than one relay, the whole
+ // process is called iteratively for each relay.
+ calculateRelaySizes();
+
+ // Now for each relay, we need to...
+ for (vector<RelayInfo>::iterator relay = relay_info_.begin();
+ relay != relay_info_.end(); ++relay) {
+
+ // build relay-forw/relay-repl header (see RFC3315, section 7)
+ bufferOut_.writeUint8(relay->msg_type_);
+ bufferOut_.writeUint8(relay->hop_count_);
+ bufferOut_.writeData(&(relay->linkaddr_.toBytes()[0]),
+ isc::asiolink::V6ADDRESS_LEN);
+ bufferOut_.writeData(&relay->peeraddr_.toBytes()[0],
+ isc::asiolink::V6ADDRESS_LEN);
+
+ // store every option in this relay scope. Usually that will be
+ // only interface-id, but occasionally other options may be
+ // present here as well (vendor-opts for Cable modems,
+ // subscriber-id, remote-id, options echoed back from Echo
+ // Request Option, etc.)
+ for (Option::OptionCollection::const_iterator opt =
+ relay->options_.begin();
+ opt != relay->options_.end(); ++opt) {
+ (opt->second)->pack(bufferOut_);
+ }
+
+ // and include header relay-msg option. Its payload will be
+ // generated in the next iteration (if there are more relays)
+ // or outside the loop (if there are no more relays and the
+ // payload is a direct message)
+ bufferOut_.writeUint16(D6O_RELAY_MSG);
+ bufferOut_.writeUint16(relay->relay_msg_len_);
+ }
+
+ }
+
// DHCPv6 header: message-type (1 octect) + transaction id (3 octets)
bufferOut_.writeUint8(msg_type_);
// store 3-octet transaction-id
@@ -127,12 +230,43 @@ Pkt6::unpackUDP() {
return (false);
}
msg_type_ = data_[0];
- transid_ = ( (data_[1]) << 16 ) +
- ((data_[2]) << 8) + (data_[3]);
+ switch (msg_type_) {
+ case DHCPV6_SOLICIT:
+ case DHCPV6_ADVERTISE:
+ case DHCPV6_REQUEST:
+ case DHCPV6_CONFIRM:
+ case DHCPV6_RENEW:
+ case DHCPV6_REBIND:
+ case DHCPV6_REPLY:
+ case DHCPV6_DECLINE:
+ case DHCPV6_RECONFIGURE:
+ case DHCPV6_INFORMATION_REQUEST:
+ default: // assume that uknown messages are not using relay format
+ {
+ return (unpackMsg(data_.begin(), data_.end()));
+ }
+ case DHCPV6_RELAY_FORW:
+ case DHCPV6_RELAY_REPL:
+ return (unpackRelayMsg());
+ }
+}
+
+bool
+Pkt6::unpackMsg(OptionBuffer::const_iterator begin,
+ OptionBuffer::const_iterator end) {
+ if (std::distance(begin, end) < 4) {
+ // truncated message (less than 4 bytes)
+ return (false);
+ }
+
+ msg_type_ = *begin++;
+
+ transid_ = ( (*begin++) << 16 ) +
+ ((*begin++) << 8) + (*begin++);
transid_ = transid_ & 0xffffff;
try {
- OptionBuffer opt_buffer(data_.begin() + 4, data_.end());
+ OptionBuffer opt_buffer(begin, end);
LibDHCP::unpackOptions6(opt_buffer, options_);
} catch (const Exception& e) {
@@ -143,6 +277,97 @@ Pkt6::unpackUDP() {
}
bool
+Pkt6::unpackRelayMsg() {
+
+ // we use offset + bufsize, because we want to avoid creating unnecessary
+ // copies. There may be up to 32 relays. While using InputBuffer would
+ // be probably a bit cleaner, copying data up to 32 times is unacceptable
+ // price here. Hence a single buffer with offets and lengths.
+ size_t bufsize = data_.size();
+ size_t offset = 0;
+
+ while (bufsize >= DHCPV6_RELAY_HDR_LEN) {
+
+ RelayInfo relay;
+
+ size_t relay_msg_offset = 0;
+ size_t relay_msg_len = 0;
+
+ // parse fixed header first (first 34 bytes)
+ relay.msg_type_ = data_[offset++];
+ relay.hop_count_ = data_[offset++];
+ relay.linkaddr_ = IOAddress::fromBytes(AF_INET6, &data_[offset]);
+ offset += isc::asiolink::V6ADDRESS_LEN;
+ relay.peeraddr_ = IOAddress::fromBytes(AF_INET6, &data_[offset]);
+ offset += isc::asiolink::V6ADDRESS_LEN;
+ bufsize -= DHCPV6_RELAY_HDR_LEN; // 34 bytes (1+1+16+16)
+
+ try {
+ // parse the rest as options
+ OptionBuffer opt_buffer(&data_[offset], &data_[offset+bufsize]);
+ LibDHCP::unpackOptions6(opt_buffer, relay.options_, &relay_msg_offset,
+ &relay_msg_len);
+
+ /// @todo: check that each option appears at most once
+ //relay.interface_id_ = options->getOption(D6O_INTERFACE_ID);
+ //relay.subscriber_id_ = options->getOption(D6O_SUBSCRIBER_ID);
+ //relay.remote_id_ = options->getOption(D6O_REMOTE_ID);
+
+ if (relay_msg_offset == 0 || relay_msg_len == 0) {
+ isc_throw(BadValue, "Mandatory relay-msg option missing");
+ }
+
+ // store relay information parsed so far
+ addRelayInfo(relay);
+
+ /// @todo: implement ERO here
+
+ if (relay_msg_len >= bufsize) {
+ // length of the relay_msg option extends beyond end of the message
+ isc_throw(Unexpected, "Relay-msg option is truncated.");
+ return false;
+ }
+ uint8_t inner_type = data_[offset + relay_msg_offset];
+ offset += relay_msg_offset; // offset is relative
+ bufsize = relay_msg_len; // length is absolute
+
+ if ( (inner_type != DHCPV6_RELAY_FORW) &&
+ (inner_type != DHCPV6_RELAY_REPL)) {
+ // Ok, the inner message is not encapsulated, let's decode it
+ // directly
+ return (unpackMsg(data_.begin() + offset, data_.begin() + offset
+ + relay_msg_len));
+ }
+
+ // Oh well, there's inner relay-forw or relay-repl inside. Let's
+ // unpack it as well. The next loop iteration will take care
+ // of that.
+ } catch (const Exception& e) {
+ /// @todo: throw exception here once we turn this function to void.
+ return (false);
+ }
+ }
+
+ if ( (offset == data_.size()) && (bufsize == 0) ) {
+ // message has been parsed completely
+ return (true);
+ }
+
+ /// @todo: log here that there are additional unparsed bytes
+ return (true);
+}
+
+void
+Pkt6::addRelayInfo(const RelayInfo& relay) {
+ if (relay_info_.size() > 32) {
+ isc_throw(BadValue, "Massage cannot be encapsulated more than 32 times");
+ }
+
+ /// @todo: Implement type checks here (e.g. we could receive relay-forw in relay-repl)
+ relay_info_.push_back(relay);
+}
+
+bool
Pkt6::unpackTCP() {
isc_throw(Unexpected, "DHCPv6 over TCP (bulk leasequery and failover) "
"not implemented yet.");
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
index afb85d2..0bf4192 100644
--- a/src/lib/dhcp/pkt6.h
+++ b/src/lib/dhcp/pkt6.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 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
@@ -32,15 +32,40 @@ namespace dhcp {
class Pkt6 {
public:
- /// specifes DHCPv6 packet header length
+ /// specifies non-relayed DHCPv6 packet header length (over UDP)
const static size_t DHCPV6_PKT_HDR_LEN = 4;
+ /// specifies relay DHCPv6 packet header length (over UDP)
+ const static size_t DHCPV6_RELAY_HDR_LEN = 34;
+
/// DHCPv6 transport protocol
enum DHCPv6Proto {
UDP = 0, // most packets are UDP
TCP = 1 // there are TCP DHCPv6 packets (bulk leasequery, failover)
};
+
+ /// @brief structure that describes a single relay information
+ ///
+ /// Client sends messages. Each relay along its way will encapsulate the message.
+ /// This structure represents all information added by a single relay.
+ struct RelayInfo {
+
+ /// @brief default constructor
+ RelayInfo();
+ uint8_t msg_type_; ///< message type (RELAY-FORW oro RELAY-REPL)
+ uint8_t hop_count_; ///< number of traversed relays (up to 32)
+ isc::asiolink::IOAddress linkaddr_;///< fixed field in relay-forw/relay-reply
+ isc::asiolink::IOAddress peeraddr_;///< fixed field in relay-forw/relay-reply
+
+ /// @brief length of the relay_msg_len
+ /// Used when calculating length during pack/unpack
+ uint16_t relay_msg_len_;
+
+ /// options received from a specified relay, except relay-msg option
+ isc::dhcp::Option::OptionCollection options_;
+ };
+
/// Constructor, used in replying to a message
///
/// @param msg_type type of message (SOLICIT=1, ADVERTISE=2, ...)
@@ -89,7 +114,6 @@ public:
/// @return reference to output buffer
const isc::util::OutputBuffer& getBuffer() const { return (bufferOut_); };
-
/// @brief Returns reference to input buffer.
///
/// @return reference to input buffer
@@ -160,6 +184,23 @@ public:
/// @return pointer to found option (or NULL)
OptionPtr getOption(uint16_t type);
+ /// @brief returns option inserted by relay
+ ///
+ /// Returns an option from specified relay scope (inserted by a given relay
+ /// if this is received packet or to be decapsulated by a given relay if
+ /// this is a transmitted packet). nesting_level specifies which relay
+ /// scope is to be used. 0 is the outermost encapsulation (relay closest to
+ /// the server). pkt->relay_info_.size() - 1 is the innermost encapsulation
+ /// (relay closest to the client).
+ ///
+ /// @throw isc::OutOfRange if nesting level has invalid value.
+ ///
+ /// @param option_code code of the requested option
+ /// @param nesting_level see description above
+ ///
+ /// @return pointer to the option (or NULL if there is no such option)
+ OptionPtr getRelayOption(uint16_t option_code, uint8_t nesting_level);
+
/// @brief Returns all instances of specified type.
///
/// Returns all instances of options of the specified type. DHCPv6 protocol
@@ -246,7 +287,7 @@ public:
/// @brief Returns packet timestamp.
///
/// Returns packet timestamp value updated when
- /// packet is received or send.
+ /// packet is received or sent.
///
/// @return packet timestamp.
const boost::posix_time::ptime& getTimestamp() const { return timestamp_; }
@@ -259,8 +300,18 @@ public:
/// @return interface name
void setIface(const std::string& iface ) { iface_ = iface; };
+ /// @brief add information about one traversed relay
+ ///
+ /// This adds information about one traversed relay, i.e.
+ /// one relay-forw or relay-repl level of encapsulation.
+ ///
+ /// @param relay structure with necessary relay information
+ void addRelayInfo(const RelayInfo& relay);
+
/// collection of options present in this message
///
+ /// @todo: Text mentions protected, but this is really public
+ ///
/// @warning This protected member is accessed by derived
/// classes directly. One of such derived classes is
/// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
@@ -305,6 +356,15 @@ public:
/// be freed by the caller.
const char* getName() const;
+ /// relay information
+ ///
+ /// this is a public field. Otherwise we hit one of the two problems:
+ /// we return reference to an internal field (and that reference could
+ /// be potentially used past Pkt6 object lifetime causing badness) or
+ /// we return a copy (which is inefficient and also causes any updates
+ /// to be impossible). Therefore public field is considered the best
+ /// (or least bad) solution.
+ std::vector<RelayInfo> relay_info_;
protected:
/// Builds on wire packet for TCP transmission.
///
@@ -340,6 +400,44 @@ protected:
/// @return true, if build was successful
bool unpackUDP();
+ /// @brief unpacks direct (non-relayed) message
+ ///
+ /// This method unpacks specified buffer range as a direct
+ /// (e.g. solicit or request) message. This method is called from
+ /// unpackUDP() when received message is detected to be direct.
+ ///
+ /// @param begin start of the buffer
+ /// @param end end of the buffer
+ /// @return true if parsing was successful and there are no leftover bytes
+ bool unpackMsg(OptionBuffer::const_iterator begin,
+ OptionBuffer::const_iterator end);
+
+ /// @brief unpacks relayed message (RELAY-FORW or RELAY-REPL)
+ ///
+ /// This method is called from unpackUDP() when received message
+ /// is detected to be relay-message. It goes iteratively over
+ /// all relays (if there are multiple encapsulation levels).
+ ///
+ /// @return true if parsing was successful
+ bool unpackRelayMsg();
+
+ /// @brief calculates overhead introduced in specified relay
+ ///
+ /// It is used when calculating message size and packing message
+ /// @param relay RelayInfo structure that holds information about relay
+ /// @return number of bytes needed to store relay information
+ uint16_t getRelayOverhead(const RelayInfo& relay) const;
+
+ /// @brief calculates overhead for all relays defined for this message
+ /// @return number of bytes needed to store all relay information
+ uint16_t calculateRelaySizes();
+
+ /// @brief calculates size of the message as if it was not relayed at all
+ ///
+ /// This is equal to len() if the message was not relayed.
+ /// @return number of bytes required to store the message
+ uint16_t directLen() const;
+
/// UDP (usually) or TCP (bulk leasequery or failover)
DHCPv6Proto proto_;
diff --git a/src/lib/dhcp/tests/hwaddr_unittest.cc b/src/lib/dhcp/tests/hwaddr_unittest.cc
index 144d62d..bf2eb9a 100644
--- a/src/lib/dhcp/tests/hwaddr_unittest.cc
+++ b/src/lib/dhcp/tests/hwaddr_unittest.cc
@@ -40,9 +40,11 @@ TEST(HWAddrTest, constructor) {
const uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
const uint8_t htype = HTYPE_ETHER;
-
vector<uint8_t> data2(data1, data1 + sizeof(data1));
+ // Over the limit data
+ vector<uint8_t> big_data_vector(HWAddr::MAX_HWADDR_LEN + 1, 0);
+
scoped_ptr<HWAddr> hwaddr1(new HWAddr(data1, sizeof(data1), htype));
scoped_ptr<HWAddr> hwaddr2(new HWAddr(data2, htype));
scoped_ptr<HWAddr> hwaddr3(new HWAddr());
@@ -55,6 +57,13 @@ TEST(HWAddrTest, constructor) {
EXPECT_EQ(0, hwaddr3->hwaddr_.size());
EXPECT_EQ(htype, hwaddr3->htype_);
+
+ // Check that over the limit data length throws exception
+ EXPECT_THROW(HWAddr(&big_data_vector[0], big_data_vector.size(), HTYPE_ETHER),
+ InvalidParameter);
+
+ // Check that over the limit vector throws exception
+ EXPECT_THROW(HWAddr(big_data_vector, HTYPE_ETHER), InvalidParameter);
}
// This test checks if the comparison operators are sane.
diff --git a/src/lib/dhcp/tests/option_custom_unittest.cc b/src/lib/dhcp/tests/option_custom_unittest.cc
index e0ae727..2a9f771 100644
--- a/src/lib/dhcp/tests/option_custom_unittest.cc
+++ b/src/lib/dhcp/tests/option_custom_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013 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
@@ -262,7 +262,7 @@ TEST_F(OptionCustomTest, int16Data) {
// We should have just one data field.
ASSERT_EQ(1, option->getDataFieldsNum());
- // Initialize value to 0 explicitely to make sure that is
+ // Initialize value to 0 explicitly to make sure that is
// modified by readInteger function to expected -234.
int16_t value = 0;
ASSERT_NO_THROW(value = option->readInteger<int16_t>(0));
@@ -295,7 +295,7 @@ TEST_F(OptionCustomTest, int32Data) {
// We should have just one data field.
ASSERT_EQ(1, option->getDataFieldsNum());
- // Initialize value to 0 explicitely to make sure that is
+ // Initialize value to 0 explicitly to make sure that is
// modified by readInteger function to expected -234.
int32_t value = 0;
ASSERT_NO_THROW(value = option->readInteger<int32_t>(0));
@@ -766,9 +766,15 @@ TEST_F(OptionCustomTest, recordDataTruncated) {
// 2 bytes of uint16_t value and IPv6 address. Option definitions specifies
// 3 data fields for this option but the length of the data is insufficient
// to initialize 3 data field.
- EXPECT_THROW(
- option.reset(new OptionCustom(opt_def, Option::V6, buf.begin(), buf.begin() + 18)),
- isc::OutOfRange
+
+ // @todo:
+ // Currently the code was modified to allow empty string or empty binary data
+ // Potentially change this back to EXPECT_THROW(..., OutOfRange) once we
+ // decide how to treat zero length strings and binary data (they are typically
+ // valid or invalid on a per option basis, so there likely won't be a single
+ // one answer to all)
+ EXPECT_NO_THROW(
+ option.reset(new OptionCustom(opt_def, Option::V6, buf.begin(), buf.begin() + 18))
);
// Try to further reduce the length of the buffer to make it insufficient
diff --git a/src/lib/dhcp/tests/option_int_unittest.cc b/src/lib/dhcp/tests/option_int_unittest.cc
index 81ebcf0..96212c2 100644
--- a/src/lib/dhcp/tests/option_int_unittest.cc
+++ b/src/lib/dhcp/tests/option_int_unittest.cc
@@ -296,7 +296,7 @@ TEST_F(OptionIntTest, basicInt32V6) {
TEST_F(OptionIntTest, setValueUint8) {
boost::shared_ptr<OptionInt<uint8_t> > opt(new OptionInt<uint8_t>(Option::V6,
D6O_PREFERENCE, 123));
- // Check if constructor intitialized the option value correctly.
+ // Check if constructor initialized the option value correctly.
EXPECT_EQ(123, opt->getValue());
// Override the value.
opt->setValue(111);
@@ -310,7 +310,7 @@ TEST_F(OptionIntTest, setValueUint8) {
TEST_F(OptionIntTest, setValueInt8) {
boost::shared_ptr<OptionInt<int8_t> > opt(new OptionInt<int8_t>(Option::V6,
D6O_PREFERENCE, -123));
- // Check if constructor intitialized the option value correctly.
+ // Check if constructor initialized the option value correctly.
EXPECT_EQ(-123, opt->getValue());
// Override the value.
opt->setValue(-111);
@@ -325,7 +325,7 @@ TEST_F(OptionIntTest, setValueInt8) {
TEST_F(OptionIntTest, setValueUint16) {
boost::shared_ptr<OptionInt<uint16_t> > opt(new OptionInt<uint16_t>(Option::V6,
D6O_ELAPSED_TIME, 123));
- // Check if constructor intitialized the option value correctly.
+ // Check if constructor initialized the option value correctly.
EXPECT_EQ(123, opt->getValue());
// Override the value.
opt->setValue(0x0102);
@@ -339,7 +339,7 @@ TEST_F(OptionIntTest, setValueUint16) {
TEST_F(OptionIntTest, setValueInt16) {
boost::shared_ptr<OptionInt<int16_t> > opt(new OptionInt<int16_t>(Option::V6,
D6O_ELAPSED_TIME, -16500));
- // Check if constructor intitialized the option value correctly.
+ // Check if constructor initialized the option value correctly.
EXPECT_EQ(-16500, opt->getValue());
// Override the value.
opt->setValue(-20100);
@@ -353,7 +353,7 @@ TEST_F(OptionIntTest, setValueInt16) {
TEST_F(OptionIntTest, setValueUint32) {
boost::shared_ptr<OptionInt<uint32_t> > opt(new OptionInt<uint32_t>(Option::V6,
D6O_CLT_TIME, 123));
- // Check if constructor intitialized the option value correctly.
+ // Check if constructor initialized the option value correctly.
EXPECT_EQ(123, opt->getValue());
// Override the value.
opt->setValue(0x01020304);
@@ -367,7 +367,7 @@ TEST_F(OptionIntTest, setValueUint32) {
TEST_F(OptionIntTest, setValueInt32) {
boost::shared_ptr<OptionInt<int32_t> > opt(new OptionInt<int32_t>(Option::V6,
D6O_CLT_TIME, -120100));
- // Check if constructor intitialized the option value correctly.
+ // Check if constructor initialized the option value correctly.
EXPECT_EQ(-120100, opt->getValue());
// Override the value.
opt->setValue(-125000);
diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc
index cdaad3b..b5a745e 100644
--- a/src/lib/dhcp/tests/pkt6_unittest.cc
+++ b/src/lib/dhcp/tests/pkt6_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 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
@@ -17,9 +17,15 @@
#include <asiolink/io_address.h>
#include <dhcp/dhcp6.h>
#include <dhcp/option.h>
+#include <dhcp/option_custom.h>
+#include <dhcp/option6_ia.h>
+#include <dhcp/option_int.h>
+#include <dhcp/option_int_array.h>
#include <dhcp/pkt6.h>
#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <util/encode/hex.h>
#include <gtest/gtest.h>
#include <iostream>
@@ -99,6 +105,67 @@ Pkt6* capture1() {
return (pkt);
}
+/// @brief creates doubly relayed solicit message
+///
+/// This is a traffic capture exported from wireshark. It includes a SOLICIT
+/// message that passed through two relays. Each relay include interface-id,
+/// remote-id and relay-forw encapsulation. It is especially interesting,
+/// because of the following properties:
+/// - double encapsulation
+/// - first relay inserts relay-msg before extra options
+/// - second relay inserts relay-msg after extra options
+/// - both relays are from different vendors
+/// - interface-id are different for each relay
+/// - first relay inserts valid remote-id
+/// - second relay inserts remote-id with empty vendor data
+/// - the solicit message requests for custom options in ORO
+/// - there are option types in RELAY-FORW that do not appear in SOLICIT
+/// - there are option types in SOLICT that do not appear in RELAY-FORW
+///
+/// RELAY-FORW
+/// - relay message option
+/// - RELAY-FORW
+/// - interface-id option
+/// - remote-id option
+/// - RELAY-FORW
+/// SOLICIT
+/// - client-id option
+/// - ia_na option
+/// - elapsed time
+/// - ORO
+/// - interface-id option
+/// - remote-id option
+///
+/// The original capture was posted to dibbler users mailing list.
+///
+/// @return created double relayed SOLICIT message
+Pkt6* capture2() {
+
+ // string exported from Wireshark
+ string hex_string =
+ "0c01200108880db800010000000000000000fe80000000000000020021fffe5c18a900"
+ "09007d0c0000000000000000000000000000000000fe80000000000000020021fffe5c"
+ "18a9001200154953414d3134342065746820312f312f30352f30310025000400000de9"
+ "00090036016b4fe20001000e0001000118b033410000215c18a90003000c00000001ff"
+ "ffffffffffffff00080002000000060006001700f200f30012001c4953414d3134347c"
+ "3239397c697076367c6e743a76703a313a313130002500120000197f0001000118b033"
+ "410000215c18a9";
+
+ std::vector<uint8_t> bin;
+
+ // Decode the hex string and store it in bin (which happens
+ // to be OptionBuffer format)
+ isc::util::encode::decodeHex(hex_string, bin);
+
+ Pkt6* pkt = new Pkt6(&bin[0], bin.size());
+ pkt->setRemotePort(547);
+ pkt->setRemoteAddr(IOAddress("fe80::1234"));
+ pkt->setLocalPort(547);
+ pkt->setLocalAddr(IOAddress("ff05::1:3"));
+ pkt->setIndex(2);
+ pkt->setIface("eth0");
+ return (pkt);
+}
TEST_F(Pkt6Test, unpack_solicit1) {
Pkt6* sol = capture1();
@@ -306,5 +373,183 @@ TEST_F(Pkt6Test, getName) {
}
}
+// This test verifies that a fancy solicit that passed through two
+// relays can be parsed properly. See capture2() method description
+// for details regarding the packet.
+TEST_F(Pkt6Test, relayUnpack) {
+ boost::scoped_ptr<Pkt6> msg(capture2());
+
+ EXPECT_NO_THROW(msg->unpack());
+
+ EXPECT_EQ(DHCPV6_SOLICIT, msg->getType());
+ EXPECT_EQ(217, msg->len());
+
+ ASSERT_EQ(2, msg->relay_info_.size());
+
+ OptionPtr opt;
+
+ // part 1: Check options inserted by the first relay
+
+ // There should be 2 options in first relay
+ EXPECT_EQ(2, msg->relay_info_[0].options_.size());
+
+ // There should be interface-id option
+ ASSERT_TRUE(opt = msg->getRelayOption(D6O_INTERFACE_ID, 0));
+ OptionBuffer data = opt->getData();
+ EXPECT_EQ(32, opt->len()); // 28 bytes of data + 4 bytes header
+ EXPECT_EQ(data.size(), 28);
+ // That's a strange interface-id, but this is a real life example
+ EXPECT_TRUE(0 == memcmp("ISAM144|299|ipv6|nt:vp:1:110", &data[0], 28));
+
+ // get the remote-id option
+ ASSERT_TRUE(opt = msg->getRelayOption(D6O_REMOTE_ID, 0));
+ EXPECT_EQ(22, opt->len()); // 18 bytes of data + 4 bytes header
+ boost::shared_ptr<OptionCustom> custom = boost::dynamic_pointer_cast<OptionCustom>(opt);
+
+ uint32_t vendor_id = custom->readInteger<uint32_t>(0);
+ EXPECT_EQ(6527, vendor_id); // 6527 = Panthera Networks
+
+ uint8_t expected_remote_id[] = { 0x00, 0x01, 0x00, 0x01, 0x18, 0xb0, 0x33, 0x41, 0x00,
+ 0x00, 0x21, 0x5c, 0x18, 0xa9 };
+ OptionBuffer remote_id = custom->readBinary(1);
+ ASSERT_EQ(sizeof(expected_remote_id), remote_id.size());
+ ASSERT_EQ(0, memcmp(expected_remote_id, &remote_id[0], remote_id.size()));
+
+ // part 2: Check options inserted by the second relay
+
+ // get the interface-id from the second relay
+ ASSERT_TRUE(opt = msg->getRelayOption(D6O_INTERFACE_ID, 1));
+ data = opt->getData();
+ EXPECT_EQ(25, opt->len()); // 21 bytes + 4 bytes header
+ EXPECT_EQ(data.size(), 21);
+ EXPECT_TRUE(0 == memcmp("ISAM144 eth 1/1/05/01", &data[0], 21));
+
+ // get the remote-id option
+ ASSERT_TRUE(opt = msg->getRelayOption(D6O_REMOTE_ID, 1));
+ EXPECT_EQ(8, opt->len());
+ custom = boost::dynamic_pointer_cast<OptionCustom>(opt);
+
+ vendor_id = custom->readInteger<uint32_t>(0);
+ EXPECT_EQ(3561, vendor_id); // 3561 = Broadband Forum
+ // @todo: See if we can validate empty remote-id field
+
+ // Let's check if there is no leak between options stored in
+ // the SOLICIT message and the relay.
+ EXPECT_FALSE(opt = msg->getRelayOption(D6O_IA_NA, 1));
+
+
+ // Part 3: Let's check options in the message itself
+ // This is not redundant compared to other direct messages tests,
+ // as we parsed it differently
+ EXPECT_EQ(DHCPV6_SOLICIT, msg->getType());
+ EXPECT_EQ(0x6b4fe2, msg->getTransid());
+
+ ASSERT_TRUE(opt = msg->getOption(D6O_CLIENTID));
+ EXPECT_EQ(18, opt->len()); // 14 bytes of data + 4 bytes of header
+ uint8_t expected_client_id[] = { 0x00, 0x01, 0x00, 0x01, 0x18, 0xb0, 0x33, 0x41, 0x00,
+ 0x00, 0x21, 0x5c, 0x18, 0xa9 };
+ data = opt->getData();
+ ASSERT_EQ(data.size(), sizeof(expected_client_id));
+ ASSERT_EQ(0, memcmp(&data[0], expected_client_id, data.size()));
+
+ ASSERT_TRUE(opt = msg->getOption(D6O_IA_NA));
+ boost::shared_ptr<Option6IA> ia =
+ boost::dynamic_pointer_cast<Option6IA>(opt);
+ ASSERT_TRUE(ia);
+ EXPECT_EQ(1, ia->getIAID());
+ EXPECT_EQ(0xffffffff, ia->getT1());
+ EXPECT_EQ(0xffffffff, ia->getT2());
+
+ ASSERT_TRUE(opt = msg->getOption(D6O_ELAPSED_TIME));
+ EXPECT_EQ(6, opt->len()); // 2 bytes of data + 4 bytes of header
+ boost::shared_ptr<OptionInt<uint16_t> > elapsed =
+ boost::dynamic_pointer_cast<OptionInt<uint16_t> > (opt);
+ ASSERT_TRUE(elapsed);
+ EXPECT_EQ(0, elapsed->getValue());
+
+ ASSERT_TRUE(opt = msg->getOption(D6O_ORO));
+ boost::shared_ptr<OptionIntArray<uint16_t> > oro =
+ boost::dynamic_pointer_cast<OptionIntArray<uint16_t> > (opt);
+ const std::vector<uint16_t> oro_list = oro->getValues();
+ EXPECT_EQ(3, oro_list.size());
+ EXPECT_EQ(23, oro_list[0]);
+ EXPECT_EQ(242, oro_list[1]);
+ EXPECT_EQ(243, oro_list[2]);
+}
+
+// This test verified that message with relay information can be
+// packed and then unpacked.
+TEST_F(Pkt6Test, relayPack) {
+
+ boost::scoped_ptr<Pkt6> parent(new Pkt6(DHCPV6_ADVERTISE, 0x020304));
+
+ Pkt6::RelayInfo relay1;
+ relay1.msg_type_ = DHCPV6_RELAY_REPL;
+ relay1.hop_count_ = 17; // not very miningful, but useful for testing
+ relay1.linkaddr_ = IOAddress("2001:db8::1");
+ relay1.peeraddr_ = IOAddress("fe80::abcd");
+
+ uint8_t relay_opt_data[] = { 1, 2, 3, 4, 5, 6, 7, 8};
+ vector<uint8_t> relay_data(relay_opt_data, relay_opt_data + sizeof(relay_opt_data));
+
+ OptionPtr optRelay1(new Option(Option::V6, 200, relay_data));
+
+ relay1.options_.insert(pair<int, boost::shared_ptr<Option> >(optRelay1->getType(), optRelay1));
+
+ OptionPtr opt1(new Option(Option::V6, 100));
+ OptionPtr opt2(new Option(Option::V6, 101));
+ OptionPtr opt3(new Option(Option::V6, 102));
+ // let's not use zero-length option type 3 as it is IA_NA
+
+ parent->addRelayInfo(relay1);
+
+ parent->addOption(opt1);
+ parent->addOption(opt2);
+ parent->addOption(opt3);
+
+ EXPECT_EQ(DHCPV6_ADVERTISE, parent->getType());
+
+ EXPECT_TRUE(parent->pack());
+
+ EXPECT_EQ(Pkt6::DHCPV6_PKT_HDR_LEN + 3 * Option::OPTION6_HDR_LEN // ADVERTISE
+ + Pkt6::DHCPV6_RELAY_HDR_LEN // relay header
+ + Option::OPTION6_HDR_LEN // relay-msg
+ + optRelay1->len(),
+ parent->len());
+
+ // create second packet,based on assembled data from the first one
+ boost::scoped_ptr<Pkt6> clone(new Pkt6(static_cast<const uint8_t*>(
+ parent->getBuffer().getData()),
+ parent->getBuffer().getLength()));
+
+ // now recreate options list
+ EXPECT_TRUE( clone->unpack() );
+
+ // transid, message-type should be the same as before
+ EXPECT_EQ(parent->getTransid(), parent->getTransid());
+ EXPECT_EQ(DHCPV6_ADVERTISE, clone->getType());
+
+ EXPECT_TRUE( clone->getOption(100));
+ EXPECT_TRUE( clone->getOption(101));
+ EXPECT_TRUE( clone->getOption(102));
+ EXPECT_FALSE(clone->getOption(103));
+
+ // Now check relay info
+ ASSERT_EQ(1, clone->relay_info_.size());
+ EXPECT_EQ(DHCPV6_RELAY_REPL, clone->relay_info_[0].msg_type_);
+ EXPECT_EQ(17, clone->relay_info_[0].hop_count_);
+ EXPECT_EQ("2001:db8::1", clone->relay_info_[0].linkaddr_.toText());
+ EXPECT_EQ("fe80::abcd", clone->relay_info_[0].peeraddr_.toText());
+
+ // There should be exactly one option
+ EXPECT_EQ(1, clone->relay_info_[0].options_.size());
+ OptionPtr opt = clone->getRelayOption(200, 0);
+ EXPECT_TRUE(opt);
+ EXPECT_EQ(opt->getType() , optRelay1->getType());
+ EXPECT_EQ(opt->len(), optRelay1->len());
+ OptionBuffer data = opt->getData();
+ ASSERT_EQ(data.size(), sizeof(relay_opt_data));
+ EXPECT_EQ(0, memcmp(relay_opt_data, relay_opt_data, sizeof(relay_opt_data)));
+}
}
diff --git a/src/lib/dhcpsrv/dhcp_config_parser.h b/src/lib/dhcpsrv/dhcp_config_parser.h
index cb419f8..8abdfc8 100644
--- a/src/lib/dhcpsrv/dhcp_config_parser.h
+++ b/src/lib/dhcpsrv/dhcp_config_parser.h
@@ -15,6 +15,12 @@
#ifndef DHCP_CONFIG_PARSER_H
#define DHCP_CONFIG_PARSER_H
+#include <exceptions/exceptions.h>
+#include <cc/data.h>
+#include <stdint.h>
+#include <string>
+#include <map>
+
namespace isc {
namespace dhcp {
@@ -122,38 +128,83 @@ public:
/// This method is expected to be called after @c build(), and only once.
/// The result is undefined otherwise.
virtual void commit() = 0;
+};
-protected:
+/// @brief A template class that stores named elements of a given data type.
+///
+/// This template class is provides data value storage for configuration parameters
+/// of a given data type. The values are stored by parameter name and as instances
+/// of type "ValueType".
+///
+/// @param ValueType is the data type of the elements to store.
+template<typename ValueType>
+class ValueStorage {
+ public:
+ /// @brief Stores the the parameter and its value in the store.
+ ///
+ /// If the parameter does not exist in the store, then it will be added,
+ /// otherwise its data value will be updated with the given value.
+ ///
+ /// @param name is the name of the paramater to store.
+ /// @param value is the data value to store.
+ void setParam(const std::string name, const ValueType& value) {
+ values_[name] = value;
+ }
- /// @brief Return the parsed entry from the provided storage.
- ///
- /// This method returns the parsed entry from the provided
- /// storage. If the entry is not found, then exception is
- /// thrown.
- ///
- /// @param param_id name of the configuration entry.
- /// @param storage storage where the entry should be searched.
- /// @tparam ReturnType type of the returned value.
- /// @tparam StorageType type of the storage.
- ///
- /// @throw DhcpConfigError if the entry has not been found
- /// in the storage.
- template<typename ReturnType, typename StorageType>
- static ReturnType getParam(const std::string& param_id,
- const StorageType& storage) {
- typename StorageType::const_iterator param = storage.find(param_id);
- if (param == storage.end()) {
- isc_throw(DhcpConfigError, "missing parameter '"
- << param_id << "'");
+ /// @brief Returns the data value for the given parameter.
+ ///
+ /// Finds and returns the data value for the given parameter.
+ /// @param name is the name of the parameter for which the data
+ /// value is desired.
+ ///
+ /// @return The paramater's data value of type <ValueType>.
+ /// @throw DhcpConfigError if the parameter is not found.
+ ValueType getParam(const std::string& name) const {
+ typename std::map<std::string, ValueType>::const_iterator param
+ = values_.find(name);
+
+ if (param == values_.end()) {
+ isc_throw(DhcpConfigError, "Missing parameter '"
+ << name << "'");
+ }
+
+ return (param->second);
}
- ReturnType value = param->second;
- return (value);
- }
+ /// @brief Remove the parameter from the store.
+ ///
+ /// Deletes the entry for the given parameter from the store if it
+ /// exists.
+ ///
+ /// @param name is the name of the paramater to delete.
+ void delParam(const std::string& name) {
+ values_.erase(name);
+ }
+
+ /// @brief Deletes all of the entries from the store.
+ ///
+ void clear() {
+ values_.clear();
+ }
+
+
+ private:
+ /// @brief An std::map of the data values, keyed by parameter names.
+ std::map<std::string, ValueType> values_;
};
-} // end of isc::dhcp namespace
-} // end of isc namespace
+/// @brief a collection of elements that store uint32 values (e.g. renew-timer = 900)
+typedef ValueStorage<uint32_t> Uint32Storage;
+
+/// @brief a collection of elements that store string values
+typedef ValueStorage<std::string> StringStorage;
+
+/// @brief Storage for parsed boolean values.
+typedef ValueStorage<bool> BooleanStorage;
+
+}; // end of isc::dhcp namespace
+}; // end of isc namespace
#endif // DHCP_CONFIG_PARSER_H
+
diff --git a/src/lib/dhcpsrv/lease_mgr.h b/src/lib/dhcpsrv/lease_mgr.h
index 7d328e7..02e517e 100644
--- a/src/lib/dhcpsrv/lease_mgr.h
+++ b/src/lib/dhcpsrv/lease_mgr.h
@@ -211,8 +211,6 @@ struct Lease {
/// would be required. As this is a critical part of the code that will be used
/// extensively, direct access is warranted.
struct Lease4 : public Lease {
- /// @brief Maximum size of a hardware address
- static const size_t HWADDR_MAX = 20;
/// @brief Address extension
///
diff --git a/src/lib/dhcpsrv/mysql_lease_mgr.cc b/src/lib/dhcpsrv/mysql_lease_mgr.cc
index b9706e4..9828085 100644
--- a/src/lib/dhcpsrv/mysql_lease_mgr.cc
+++ b/src/lib/dhcpsrv/mysql_lease_mgr.cc
@@ -94,9 +94,6 @@ namespace {
/// colon separators.
const size_t ADDRESS6_TEXT_MAX_LEN = 39;
-/// @brief Maximum size of a hardware address.
-const size_t HWADDR_MAX_LEN = 20;
-
/// @brief MySQL True/False constants
///
/// Declare typed values so as to avoid problems of data conversion. These
@@ -533,7 +530,7 @@ private:
std::string columns_[LEASE_COLUMNS];///< Column names
my_bool error_[LEASE_COLUMNS]; ///< Error array
std::vector<uint8_t> hwaddr_; ///< Hardware address
- uint8_t hwaddr_buffer_[HWADDR_MAX_LEN];
+ uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
///< Hardware address buffer
unsigned long hwaddr_length_; ///< Hardware address length
std::vector<uint8_t> client_id_; ///< Client identification
@@ -1109,6 +1106,17 @@ MySqlLeaseMgr::openDatabase() {
mysql_error(mysql_));
}
+ // Set SQL mode options for the connection: SQL mode governs how what
+ // constitutes insertable data for a given column, and how to handle
+ // invalid data. We want to ensure we get the strictest behavior and
+ // to reject invalid data with an error.
+ const char *sql_mode = "SET SESSION sql_mode ='STRICT_ALL_TABLES'";
+ result = mysql_options(mysql_, MYSQL_INIT_COMMAND, sql_mode);
+ if (result != 0) {
+ isc_throw(DbOpenError, "unable to set SQL mode options: " <<
+ mysql_error(mysql_));
+ }
+
// Open the database.
//
// The option CLIENT_FOUND_ROWS is specified so that in an UPDATE,
diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h
index 5a16647..4c7cbcc 100644
--- a/src/lib/dhcpsrv/subnet.h
+++ b/src/lib/dhcpsrv/subnet.h
@@ -47,7 +47,7 @@ namespace dhcp {
/// @todo: Implement support for options here
-/// @brief Unique indentifier for a subnet (both v4 and v6)
+/// @brief Unique identifier for a subnet (both v4 and v6)
typedef uint32_t SubnetID;
class Subnet {
diff --git a/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc b/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
index 9b3d61b..be31bab 100644
--- a/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
+++ b/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
@@ -15,6 +15,7 @@
#include <config.h>
#include <dhcpsrv/cfgmgr.h>
+#include <dhcpsrv/dhcp_config_parser.h>
#include <exceptions/exceptions.h>
#include <gtest/gtest.h>
@@ -36,6 +37,126 @@ using boost::scoped_ptr;
namespace {
+// This test verifies that BooleanStorage functions properly.
+TEST(ValueStorageTest, BooleanTesting) {
+ BooleanStorage testStore;
+
+ // Verify that we can add and retrieve parameters.
+ testStore.setParam("firstBool", false);
+ testStore.setParam("secondBool", true);
+
+ EXPECT_FALSE(testStore.getParam("firstBool"));
+ EXPECT_TRUE(testStore.getParam("secondBool"));
+
+ // Verify that we can update paramaters.
+ testStore.setParam("firstBool", true);
+ testStore.setParam("secondBool", false);
+
+ EXPECT_TRUE(testStore.getParam("firstBool"));
+ EXPECT_FALSE(testStore.getParam("secondBool"));
+
+ // Verify that we can delete a parameter and it will no longer be found.
+ testStore.delParam("firstBool");
+ EXPECT_THROW(testStore.getParam("firstBool"), isc::dhcp::DhcpConfigError);
+
+ // Verify that the delete was safe and the store still operates.
+ EXPECT_FALSE(testStore.getParam("secondBool"));
+
+ // Verify that looking for a parameter that never existed throws.
+ ASSERT_THROW(testStore.getParam("bogusBool"), isc::dhcp::DhcpConfigError);
+
+ // Verify that attempting to delete a parameter that never existed does not throw.
+ EXPECT_NO_THROW(testStore.delParam("bogusBool"));
+
+ // Verify that we can empty the list.
+ testStore.clear();
+ EXPECT_THROW(testStore.getParam("secondBool"), isc::dhcp::DhcpConfigError);
+
+}
+
+// This test verifies that Uint32Storage functions properly.
+TEST(ValueStorageTest, Uint32Testing) {
+ Uint32Storage testStore;
+
+ uint32_t intOne = 77;
+ uint32_t intTwo = 33;
+
+ // Verify that we can add and retrieve parameters.
+ testStore.setParam("firstInt", intOne);
+ testStore.setParam("secondInt", intTwo);
+
+ EXPECT_EQ(testStore.getParam("firstInt"), intOne);
+ EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
+
+ // Verify that we can update parameters.
+ testStore.setParam("firstInt", --intOne);
+ testStore.setParam("secondInt", ++intTwo);
+
+ EXPECT_EQ(testStore.getParam("firstInt"), intOne);
+ EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
+
+ // Verify that we can delete a parameter and it will no longer be found.
+ testStore.delParam("firstInt");
+ EXPECT_THROW(testStore.getParam("firstInt"), isc::dhcp::DhcpConfigError);
+
+ // Verify that the delete was safe and the store still operates.
+ EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
+
+ // Verify that looking for a parameter that never existed throws.
+ ASSERT_THROW(testStore.getParam("bogusInt"), isc::dhcp::DhcpConfigError);
+
+ // Verify that attempting to delete a parameter that never existed does not throw.
+ EXPECT_NO_THROW(testStore.delParam("bogusInt"));
+
+ // Verify that we can empty the list.
+ testStore.clear();
+ EXPECT_THROW(testStore.getParam("secondInt"), isc::dhcp::DhcpConfigError);
+}
+
+// This test verifies that StringStorage functions properly.
+TEST(ValueStorageTest, StringTesting) {
+ StringStorage testStore;
+
+ std::string stringOne = "seventy-seven";
+ std::string stringTwo = "thirty-three";
+
+ // Verify that we can add and retrieve parameters.
+ testStore.setParam("firstString", stringOne);
+ testStore.setParam("secondString", stringTwo);
+
+ EXPECT_EQ(testStore.getParam("firstString"), stringOne);
+ EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
+
+ // Verify that we can update parameters.
+ stringOne.append("-boo");
+ stringTwo.append("-boo");
+
+ testStore.setParam("firstString", stringOne);
+ testStore.setParam("secondString", stringTwo);
+
+ EXPECT_EQ(testStore.getParam("firstString"), stringOne);
+ EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
+
+ // Verify that we can delete a parameter and it will no longer be found.
+ testStore.delParam("firstString");
+ EXPECT_THROW(testStore.getParam("firstString"), isc::dhcp::DhcpConfigError);
+
+ // Verify that the delete was safe and the store still operates.
+ EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
+
+ // Verify that looking for a parameter that never existed throws.
+ ASSERT_THROW(testStore.getParam("bogusString"), isc::dhcp::DhcpConfigError);
+
+ // Verify that attempting to delete a parameter that never existed does not throw.
+ EXPECT_NO_THROW(testStore.delParam("bogusString"));
+
+ // Verify that we can empty the list.
+ testStore.clear();
+ EXPECT_THROW(testStore.getParam("secondString"), isc::dhcp::DhcpConfigError);
+}
+
+
+
class CfgMgrTest : public ::testing::Test {
public:
CfgMgrTest() {
diff --git a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
index 226afe9..5b2fa9e 100644
--- a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
+++ b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
@@ -18,6 +18,7 @@
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/mysql_lease_mgr.h>
#include <dhcpsrv/tests/test_utils.h>
+#include <exceptions/exceptions.h>
#include <gtest/gtest.h>
@@ -883,28 +884,23 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSize) {
vector<Lease4Ptr> leases = createLeases4();
// Now add leases with increasing hardware address size.
- for (uint8_t i = 0; i <= Lease4::HWADDR_MAX; ++i) {
+ for (uint8_t i = 0; i <= HWAddr::MAX_HWADDR_LEN; ++i) {
leases[1]->hwaddr_.resize(i, i);
EXPECT_TRUE(lmptr_->addLease(leases[1]));
// @todo: Simply use HWAddr directly once 2589 is implemented
- Lease4Collection returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER));
+ Lease4Collection returned =
+ lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER));
+
ASSERT_EQ(1, returned.size());
detailCompareLease(leases[1], *returned.begin());
(void) lmptr_->deleteLease(leases[1]->addr_);
}
- // Expect some problem when accessing a lease that had too long a hardware
- // address. (The 42 is a random value put in each byte of the address.)
- // In fact the address is stored in a truncated form, so we won't find it
- // when we look.
- // @todo Check if there is some way of detecting that data added
- // to the database is truncated. There does not appear to
- // be any indication in the C API.
- leases[1]->hwaddr_.resize(Lease4::HWADDR_MAX + 100, 42);
- EXPECT_TRUE(lmptr_->addLease(leases[1]));
- // @todo: Simply use HWAddr directly once 2589 is implemented
- Lease4Collection returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER));
- EXPECT_EQ(0, returned.size());
+ // Database should not let us add one that is too big
+ // (The 42 is a random value put in each byte of the address.)
+ // @todo: 2589 will make this test impossible
+ leases[1]->hwaddr_.resize(HWAddr::MAX_HWADDR_LEN + 100, 42);
+ EXPECT_THROW(lmptr_->addLease(leases[1]), isc::dhcp::DbOperationError);
}
/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
@@ -921,8 +917,9 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
// Get the leases matching the hardware address of lease 1 and
// subnet ID of lease 1. Result should be a single lease - lease 1.
// @todo: Simply use HWAddr directly once 2589 is implemented
- Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER),
- leases[1]->subnet_id_);
+ Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
+ HTYPE_ETHER), leases[1]->subnet_id_);
+
ASSERT_TRUE(returned);
detailCompareLease(leases[1], returned);
@@ -957,8 +954,9 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
leases[1]->addr_ = leases[2]->addr_;
EXPECT_TRUE(lmptr_->addLease(leases[1]));
// @todo: Simply use HWAddr directly once 2589 is implemented
- EXPECT_THROW(returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER),
- leases[1]->subnet_id_),
+ EXPECT_THROW(returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
+ HTYPE_ETHER),
+ leases[1]->subnet_id_),
isc::dhcp::MultipleRecords);
// Delete all leases in the database
@@ -979,28 +977,22 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetIdSize) {
// Now add leases with increasing hardware address size and check
// that they can be retrieved.
- for (uint8_t i = 0; i <= Lease4::HWADDR_MAX; ++i) {
+ for (uint8_t i = 0; i <= HWAddr::MAX_HWADDR_LEN; ++i) {
leases[1]->hwaddr_.resize(i, i);
EXPECT_TRUE(lmptr_->addLease(leases[1]));
// @todo: Simply use HWAddr directly once 2589 is implemented
- Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER),
+ Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
+ HTYPE_ETHER),
leases[1]->subnet_id_);
ASSERT_TRUE(returned);
detailCompareLease(leases[1], returned);
(void) lmptr_->deleteLease(leases[1]->addr_);
}
- // Expect some error when getting a lease with too long a hardware
- // address. Set the contents of each byte to 42, a random value.
- // @todo Check if there is some way of detecting that data added
- // to the database is truncated. There does not appear to
- // be any indication in the C API.
- leases[1]->hwaddr_.resize(Lease4::HWADDR_MAX + 100, 42);
- EXPECT_TRUE(lmptr_->addLease(leases[1]));
- // @todo: Simply use HWAddr directly once 2589 is implemented
- Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER),
- leases[1]->subnet_id_);
- EXPECT_FALSE(returned);
+ // Database should not let us add one that is too big
+ // (The 42 is a random value put in each byte of the address.)
+ leases[1]->hwaddr_.resize(HWAddr::MAX_HWADDR_LEN + 100, 42);
+ EXPECT_THROW(lmptr_->addLease(leases[1]), isc::dhcp::DbOperationError);
}
/// @brief Check GetLease4 methods - access by Client ID
diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc
index 1c822ea..5c96563 100644
--- a/src/lib/dns/master_loader.cc
+++ b/src/lib/dns/master_loader.cc
@@ -400,7 +400,7 @@ private:
const Name zone_origin_;
Name active_origin_; // The origin used during parsing
// (modifiable by $ORIGIN)
- shared_ptr<Name> last_name_; // Last seen name (for INITAL_WS handling)
+ shared_ptr<Name> last_name_; // Last seen name (for INITIAL_WS handling)
const RRClass zone_class_;
MasterLoaderCallbacks callbacks_;
const AddRRCallback add_callback_;
diff --git a/src/lib/dns/nsec3hash.cc b/src/lib/dns/nsec3hash.cc
index 8fe3cf1..0e03798 100644
--- a/src/lib/dns/nsec3hash.cc
+++ b/src/lib/dns/nsec3hash.cc
@@ -45,7 +45,7 @@ namespace {
/// calculation specified in RFC5155.
///
/// Currently the only pre-defined algorithm in the RFC is SHA1. So we don't
-/// over-generalize it at the moment, and rather hardocde it and assume that
+/// over-generalize it at the moment, and rather hardcode it and assume that
/// specific algorithm.
///
/// The implementation details are only open within this file, but to avoid
diff --git a/src/lib/dns/python/pydnspp_common.h b/src/lib/dns/python/pydnspp_common.h
index 4095f54..8e498b3 100644
--- a/src/lib/dns/python/pydnspp_common.h
+++ b/src/lib/dns/python/pydnspp_common.h
@@ -50,7 +50,7 @@ int addClassVariable(PyTypeObject& c, const char* name, PyObject* obj);
/// \brief Initialize a wrapped class type, and add to module
///
-/// The type object is initalized, and its refcount is increased after
+/// The type object is initialized, and its refcount is increased after
/// successful addition to the module.
///
/// \param type The type object to initialize
diff --git a/src/lib/dns/python/tests/nsec3hash_python_test.py b/src/lib/dns/python/tests/nsec3hash_python_test.py
index 320529a..f3d1cfb 100644
--- a/src/lib/dns/python/tests/nsec3hash_python_test.py
+++ b/src/lib/dns/python/tests/nsec3hash_python_test.py
@@ -41,7 +41,7 @@ class NSEC3HashTest(unittest.TestCase):
RRClass.IN,
"1 0 12 aabbccdd"), 1)
- # Invaid type of RDATA
+ # Invalid type of RDATA
self.assertRaises(TypeError, NSEC3Hash, Rdata(RRType.A, RRClass.IN,
"192.0.2.1"))
diff --git a/src/lib/dns/tests/labelsequence_unittest.cc b/src/lib/dns/tests/labelsequence_unittest.cc
index 62cbcec..a3ac767 100644
--- a/src/lib/dns/tests/labelsequence_unittest.cc
+++ b/src/lib/dns/tests/labelsequence_unittest.cc
@@ -949,7 +949,7 @@ public:
foo_example("foo.example."),
org("org")
{
- // explicitely set to non-zero data, to make sure
+ // explicitly set to non-zero data, to make sure
// we don't try to use data we don't set
memset(buf, 0xff, LabelSequence::MAX_SERIALIZED_LENGTH);
}
diff --git a/src/lib/dns/tests/master_loader_unittest.cc b/src/lib/dns/tests/master_loader_unittest.cc
index 653da05..ce9b8f7 100644
--- a/src/lib/dns/tests/master_loader_unittest.cc
+++ b/src/lib/dns/tests/master_loader_unittest.cc
@@ -167,8 +167,8 @@ TEST_F(MasterLoaderTest, basicLoad) {
// Hardcode expected values taken from the test data file, assuming it
// won't change too often.
- EXPECT_EQ(549, loader_->getSize());
- EXPECT_EQ(549, loader_->getPosition());
+ EXPECT_EQ(550, loader_->getSize());
+ EXPECT_EQ(550, loader_->getPosition());
checkBasicRRs();
}
@@ -227,20 +227,20 @@ TEST_F(MasterLoaderTest, includeAndIncremental) {
EXPECT_EQ(zone_data.size(), loader_->getSize());
EXPECT_EQ(first_rr.size(), loader_->getPosition());
- // Read next 4. It includes $INCLUDE processing. Magic number of 549
- // is the size of the test zone file (see above); 506 is the position in
+ // Read next 4. It includes $INCLUDE processing. Magic number of 550
+ // is the size of the test zone file (see above); 507 is the position in
// the file at the end of 4th RR (due to extra comments it's smaller than
// the file size).
loader_->loadIncremental(4);
- EXPECT_EQ(zone_data.size() + 549, loader_->getSize());
- EXPECT_EQ(first_rr.size() + include_str.size() + 506,
+ EXPECT_EQ(zone_data.size() + 550, loader_->getSize());
+ EXPECT_EQ(first_rr.size() + include_str.size() + 507,
loader_->getPosition());
// Read the last one. At this point getSize and getPosition return
// the same value, indicating progress of 100%.
loader_->loadIncremental(1);
- EXPECT_EQ(zone_data.size() + 549, loader_->getSize());
- EXPECT_EQ(zone_data.size() + 549, loader_->getPosition());
+ EXPECT_EQ(zone_data.size() + 550, loader_->getSize());
+ EXPECT_EQ(zone_data.size() + 550, loader_->getPosition());
// we were not interested in checking RRs in this test. clear them to
// not confuse TearDown().
diff --git a/src/lib/dns/tests/testdata/example.org b/src/lib/dns/tests/testdata/example.org
index 4163fc0..2708ef4 100644
--- a/src/lib/dns/tests/testdata/example.org
+++ b/src/lib/dns/tests/testdata/example.org
@@ -13,5 +13,5 @@ example.org. 3600 IN SOA ( ; The SOA, split across lines for testing
; Some empty lines here. They are to make sure the loader can skip them.
www 3600 IN A 192.0.2.1 ; Test a relative name as well.
- 3600 IN AAAA 2001:db8::1 ; And initial whitespace hanling
+ 3600 IN AAAA 2001:db8::1 ; And initial whitespace handling
; Here be just some space, no RRs
diff --git a/src/lib/log/log_dbglevels.h b/src/lib/log/log_dbglevels.h
index a459bed..ccf89b9 100644
--- a/src/lib/log/log_dbglevels.h
+++ b/src/lib/log/log_dbglevels.h
@@ -42,7 +42,7 @@
/// libraries.
///
/// This file defines a set of standard debug levels for use across all loggers.
-/// In this way users can have some expection of what will be output when
+/// In this way users can have some expectation of what will be output when
/// enabling debugging. Symbols are prefixed DBGLVL so as not to clash with
/// DBG_ symbols in the various modules.
///
diff --git a/src/lib/log/logger_manager_impl.h b/src/lib/log/logger_manager_impl.h
index bcb2fc7..7a49820 100644
--- a/src/lib/log/logger_manager_impl.h
+++ b/src/lib/log/logger_manager_impl.h
@@ -55,7 +55,7 @@ public:
/// \brief Initialize Processing
///
- /// This resets the hierachy of loggers back to their defaults. This means
+ /// This resets the hierarchy of loggers back to their defaults. This means
/// that all non-root loggers (if they exist) are set to NOT_SET, and the
/// root logger reset to logging informational messages.
void processInit();
diff --git a/src/lib/log/tests/Makefile.am b/src/lib/log/tests/Makefile.am
index 3b10cf6..306d5f9 100644
--- a/src/lib/log/tests/Makefile.am
+++ b/src/lib/log/tests/Makefile.am
@@ -25,6 +25,7 @@ logger_example_CPPFLAGS = $(AM_CPPFLAGS)
logger_example_LDFLAGS = $(AM_LDFLAGS)
logger_example_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
logger_example_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
+logger_example_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
logger_example_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
logger_example_LDADD += $(AM_LDADD) $(LOG4CPLUS_LIBS)
@@ -34,6 +35,7 @@ init_logger_test_CPPFLAGS = $(AM_CPPFLAGS)
init_logger_test_LDFLAGS = $(AM_LDFLAGS)
init_logger_test_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
init_logger_test_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
+init_logger_test_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
init_logger_test_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
init_logger_test_LDADD += $(AM_LDADD) $(LOG4CPLUS_LIBS)
@@ -43,6 +45,7 @@ buffer_logger_test_CPPFLAGS = $(AM_CPPFLAGS)
buffer_logger_test_LDFLAGS = $(AM_LDFLAGS)
buffer_logger_test_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
buffer_logger_test_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
+buffer_logger_test_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
buffer_logger_test_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
buffer_logger_test_LDADD += $(AM_LDADD) $(LOG4CPLUS_LIBS)
@@ -53,6 +56,7 @@ logger_lock_test_CPPFLAGS = $(AM_CPPFLAGS)
logger_lock_test_LDFLAGS = $(AM_LDFLAGS)
logger_lock_test_LDADD = $(top_builddir)/src/lib/log/libb10-log.la
logger_lock_test_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
+logger_lock_test_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
logger_lock_test_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
logger_lock_test_LDADD += $(AM_LDADD) $(LOG4CPLUS_LIBS)
diff --git a/src/lib/log/tests/message_initializer_1_unittest.cc b/src/lib/log/tests/message_initializer_1_unittest.cc
index fea6033..761231d 100644
--- a/src/lib/log/tests/message_initializer_1_unittest.cc
+++ b/src/lib/log/tests/message_initializer_1_unittest.cc
@@ -98,7 +98,7 @@ TEST(MessageInitializerTest1, Duplicates) {
MessageInitializer::clearDuplicates();
ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
- // Do it again to make sure, let's explicitely provide false now
+ // Do it again to make sure, let's explicitly provide false now
const MessageInitializer init_message_initializer_unittest_3(dupe);
MessageInitializer::loadDictionary(false);
ASSERT_EQ(1, MessageInitializer::getDuplicates().size());
diff --git a/src/lib/nsas/nameserver_entry.cc b/src/lib/nsas/nameserver_entry.cc
index bca8f73..8bed10d 100644
--- a/src/lib/nsas/nameserver_entry.cc
+++ b/src/lib/nsas/nameserver_entry.cc
@@ -91,7 +91,7 @@ NameserverEntry::getAddresses(AddressVector& addresses,
if (!has_address_[family] && expect_address_[family]) {
return IN_PROGRESS;
}
- // If we do not expect the address, then fall trough to READY
+ // If we do not expect the address, then fall through to READY
case EXPIRED: // If expired_ok, we pretend to be ready
case READY:
if (!has_address_[family]) {
@@ -149,7 +149,7 @@ NameserverEntry::setAddressRTT(const IOAddress& address, uint32_t rtt) {
}
}
- // Hack. C++ does not allow ++ on enums, enumerating trough them is pain
+ // Hack. C++ does not allow ++ on enums, enumerating through them is pain
switch (family) {
case V4_ONLY: family = V6_ONLY; break;
default: return;
diff --git a/src/lib/nsas/tests/nameserver_entry_unittest.cc b/src/lib/nsas/tests/nameserver_entry_unittest.cc
index 3aca08f..e0ec0ad 100644
--- a/src/lib/nsas/tests/nameserver_entry_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_entry_unittest.cc
@@ -59,10 +59,10 @@ protected:
};
private:
/**
- * \short Fills an rrset into the NameserverEntry trough resolver.
+ * \short Fills an rrset into the NameserverEntry through resolver.
*
* This function is used when we want to pass data to a NameserverEntry
- * trough the resolver.
+ * through the resolver.
* \param resolver The resolver used by the NameserverEntry
* \param index Index of the query in the resolver.
* \param set The answer. If the pointer is empty, it is taken
@@ -79,7 +79,7 @@ private:
}
}
protected:
- /// Fills the nameserver entry with data trough ask IP
+ /// Fills the nameserver entry with data through ask IP
void fillNSEntry(boost::shared_ptr<NameserverEntry> entry,
RRsetPtr rrv4, RRsetPtr rrv6)
{
diff --git a/src/lib/nsas/tests/zone_entry_unittest.cc b/src/lib/nsas/tests/zone_entry_unittest.cc
index 74b0c8a..8754906 100644
--- a/src/lib/nsas/tests/zone_entry_unittest.cc
+++ b/src/lib/nsas/tests/zone_entry_unittest.cc
@@ -228,7 +228,7 @@ TEST_F(ZoneEntryTest, ChangedNS) {
EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
// It should not be answered yet, it should ask for the IP addresses
- // (trough the NameserverEntry there)
+ // (through the NameserverEntry there)
EXPECT_TRUE(callback_->successes_.empty());
EXPECT_EQ(0, callback_->unreachable_count_);
EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
diff --git a/src/lib/nsas/zone_entry.cc b/src/lib/nsas/zone_entry.cc
index 8a72e5f..6d15533 100644
--- a/src/lib/nsas/zone_entry.cc
+++ b/src/lib/nsas/zone_entry.cc
@@ -93,7 +93,7 @@ class ZoneEntry::ResolverCallback :
* If there are in the hash table, it is used. If not, they are
* created. This might still fail, if the list is empty.
*
- * It then calls process, to go trough the list of nameservers,
+ * It then calls process, to go through the list of nameservers,
* examining them and seeing if some addresses are already there
* and to ask for the rest of them.
*/
@@ -389,7 +389,7 @@ class ZoneEntry::NameserverCallback : public NameserverEntry::Callback {
* \short Callback method.
*
* This is called by NameserverEntry when the change happens.
- * We just call process to go trough relevant nameservers and call
+ * We just call process to go through relevant nameservers and call
* any callbacks we can.
*/
virtual void operator()(NameserverPtr ns) {
@@ -451,8 +451,8 @@ ZoneEntry::process(AddressFamily family,
* one handle it when we return to it.
*
* If we didn't do it, one instance would call "resolve". If it
- * was from cache, it would imediatelly recurse back to another
- * process (trough the nameserver callback, etc), which would
+ * was from cache, it would immediately recurse back to another
+ * process (through the nameserver callback, etc), which would
* take that only one nameserver and trigger all callbacks.
* Only then would resolve terminate and we could ask for the
* second nameserver. This way, we first receive all the
diff --git a/src/lib/python/bind10_config.py.in b/src/lib/python/bind10_config.py.in
index 7ef660b..e56e908 100644
--- a/src/lib/python/bind10_config.py.in
+++ b/src/lib/python/bind10_config.py.in
@@ -33,7 +33,7 @@ def reload():
SYSCONFPATH="@sysconfdir@/@PACKAGE@".replace('${prefix}', PREFIX)
# B10_FROM_SOURCE is set in the environment for internal tests and
- # an experimental run without installagion. In that case we need to
+ # an experimental run without installation. In that case we need to
# specialize some configuration variables, generally so that they refer
# to somewhere in the source tree instead of the appropriate places
# after installation.
diff --git a/src/lib/python/isc/bind10/component.py b/src/lib/python/isc/bind10/component.py
index 2efb376..4621fae 100644
--- a/src/lib/python/isc/bind10/component.py
+++ b/src/lib/python/isc/bind10/component.py
@@ -490,7 +490,7 @@ class Component(BaseComponent):
class Configurator:
"""
This thing keeps track of configuration changes and starts and stops
- components as it goes. It also handles the inital startup and final
+ components as it goes. It also handles the initial startup and final
shutdown.
Note that this will allow you to stop (by invoking reconfigure) a core
diff --git a/src/lib/python/isc/bind10/tests/sockcreator_test.py b/src/lib/python/isc/bind10/tests/sockcreator_test.py
index f67781c..e87387c 100644
--- a/src/lib/python/isc/bind10/tests/sockcreator_test.py
+++ b/src/lib/python/isc/bind10/tests/sockcreator_test.py
@@ -306,7 +306,7 @@ class WrapTests(unittest.TestCase):
p1.close()
p1 = socket.fromfd(t2.read_fd(), socket.AF_UNIX, socket.SOCK_STREAM)
- # Now, pass some data trough the socket
+ # Now, pass some data through the socket
p1.send(b'A')
data = p2.recv(1)
self.assertEqual(b'A', data)
diff --git a/src/lib/python/isc/bind10/tests/socket_cache_test.py b/src/lib/python/isc/bind10/tests/socket_cache_test.py
index f713a5c..6a53a27 100644
--- a/src/lib/python/isc/bind10/tests/socket_cache_test.py
+++ b/src/lib/python/isc/bind10/tests/socket_cache_test.py
@@ -58,7 +58,7 @@ class SocketTest(Test):
def test_init(self):
"""
- Checks the intrnals of the cache just after the creation.
+ Checks the internals of the cache just after the creation.
"""
self.assertEqual('UDP', self.__socket.protocol)
self.assertEqual(self.__address, self.__socket.address)
diff --git a/src/lib/python/isc/cc/session.py b/src/lib/python/isc/cc/session.py
index fced424..636dd08 100644
--- a/src/lib/python/isc/cc/session.py
+++ b/src/lib/python/isc/cc/session.py
@@ -67,7 +67,9 @@ class Session:
logger.debug(logger.DBGLVL_TRACE_BASIC, PYCC_LNAME_RECEIVED,
self._lname)
except socket.error as se:
- raise SessionError(se)
+ if self._socket:
+ self._socket.close()
+ raise SessionError(se)
@property
def lname(self):
diff --git a/src/lib/python/isc/config/ccsession.py b/src/lib/python/isc/config/ccsession.py
index c6d9791..e801309 100644
--- a/src/lib/python/isc/config/ccsession.py
+++ b/src/lib/python/isc/config/ccsession.py
@@ -194,7 +194,7 @@ class ModuleCCSession(ConfigData):
it will read the system-wide Logging configuration and call
the logger manager to apply it. It will also inform the
logger manager when the logging configuration gets updated.
- The module does not need to do anything except intializing
+ The module does not need to do anything except initializing
its loggers, and provide log messages. Defaults to true.
socket_file: If cc_session was none, this optional argument
diff --git a/src/lib/python/isc/config/cfgmgr.py b/src/lib/python/isc/config/cfgmgr.py
index fe4924c..d100aa8 100644
--- a/src/lib/python/isc/config/cfgmgr.py
+++ b/src/lib/python/isc/config/cfgmgr.py
@@ -442,7 +442,7 @@ class ConfigManager:
# polymorphism instead of branching. But it just might turn out it
# will get solved by itself when we move everything to virtual modules
# (which is possible solution to the offline configuration problem)
- # or when we solve the incorect behaviour here when a config is
+ # or when we solve the incorrect behaviour here when a config is
# rejected (spying modules don't know it was rejected and some modules
# might have been committed already).
if module_name in self.virtual_modules:
diff --git a/src/lib/python/isc/config/tests/cfgmgr_test.py b/src/lib/python/isc/config/tests/cfgmgr_test.py
index c1fe970..ee6c98d 100644
--- a/src/lib/python/isc/config/tests/cfgmgr_test.py
+++ b/src/lib/python/isc/config/tests/cfgmgr_test.py
@@ -201,7 +201,7 @@ class TestConfigManager(unittest.TestCase):
def test_paths(self):
"""
- Test data_path and database filename is passed trough to
+ Test data_path and database filename is passed through to
underlying ConfigManagerData.
"""
cm = ConfigManager("datapath", "filename", self.fake_session)
@@ -541,7 +541,7 @@ class TestConfigManager(unittest.TestCase):
# We run the same three times, with different return values
def single_test(value, returnFunc, expectedResult):
# Because closures can't assign to closed-in variables, we pass
- # it trough self
+ # it through self
self.called_with = None
def check_test(new_data):
self.called_with = new_data
diff --git a/src/lib/python/isc/datasrc/client_inc.cc b/src/lib/python/isc/datasrc/client_inc.cc
index 7b6fac5..a59ff85 100644
--- a/src/lib/python/isc/datasrc/client_inc.cc
+++ b/src/lib/python/isc/datasrc/client_inc.cc
@@ -177,7 +177,7 @@ datasource, or when an internal error occurs.\n\
\n\
The default implementation throws isc.datasrc.NotImplemented. This allows for\n\
easy and fast deployment of minimal custom data sources, where the\n\
-user/implementator doesn't have to care about anything else but the\n\
+user/implementer doesn't have to care about anything else but the\n\
actual queries. Also, in some cases, it isn't possible to traverse the\n\
zone from logic point of view (eg. dynamically generated zone data).\n\
\n\
diff --git a/src/lib/python/isc/datasrc/client_python.cc b/src/lib/python/isc/datasrc/client_python.cc
index a30ae38..df19492 100644
--- a/src/lib/python/isc/datasrc/client_python.cc
+++ b/src/lib/python/isc/datasrc/client_python.cc
@@ -162,7 +162,7 @@ DataSourceClient_getIterator(PyObject* po_self, PyObject* args) {
try {
bool separate_rrs = false;
if (separate_rrs_obj != NULL) {
- // store result in local var so we can explicitely check for
+ // store result in local var so we can explicitly check for
// -1 error return value
int separate_rrs_true = PyObject_IsTrue(separate_rrs_obj);
if (separate_rrs_true == 1) {
diff --git a/src/lib/python/isc/ddns/session.py b/src/lib/python/isc/ddns/session.py
index 3368523..febdfdc 100644
--- a/src/lib/python/isc/ddns/session.py
+++ b/src/lib/python/isc/ddns/session.py
@@ -656,7 +656,7 @@ class UpdateSession:
'''
# For a number of cases, we may need to remove data in the zone
# (note; SOA is handled separately by __do_update, so that one
- # is explicitely ignored here)
+ # is explicitly ignored here)
if rrset.get_type() == RRType.SOA:
return
result, orig_rrset, _ = self.__diff.find(rrset.get_name(),
diff --git a/src/lib/python/isc/ddns/tests/session_tests.py b/src/lib/python/isc/ddns/tests/session_tests.py
index bc25310..4880d72 100644
--- a/src/lib/python/isc/ddns/tests/session_tests.py
+++ b/src/lib/python/isc/ddns/tests/session_tests.py
@@ -209,7 +209,7 @@ class SessionTestBase(unittest.TestCase):
def tearDown(self):
# With the Updater created in _get_update_zone, and tests
# doing all kinds of crazy stuff, one might get database locked
- # errors if it doesn't clean up explicitely after each test
+ # errors if it doesn't clean up explicitly after each test
self._session = None
def check_response(self, msg, expected_rcode):
diff --git a/src/lib/python/isc/server_common/dns_tcp.py b/src/lib/python/isc/server_common/dns_tcp.py
index 2ab5c8f..2cbd47a 100644
--- a/src/lib/python/isc/server_common/dns_tcp.py
+++ b/src/lib/python/isc/server_common/dns_tcp.py
@@ -267,7 +267,7 @@ class DNSTCPContext:
when this object is deallocated, but Python seems to expect socket
objects should be explicitly closed before deallocation. So it's
generally advisable for the user of this object to call this method
- explictily when it doesn't need the context.
+ explicitly when it doesn't need the context.
This method can be called more than once or can be called after
other I/O related methods have returned CLOSED; it's compatible
diff --git a/src/lib/python/isc/sysinfo/sysinfo.py b/src/lib/python/isc/sysinfo/sysinfo.py
index 099ac89..7bf0669 100644
--- a/src/lib/python/isc/sysinfo/sysinfo.py
+++ b/src/lib/python/isc/sysinfo/sysinfo.py
@@ -415,7 +415,7 @@ class SysInfoFreeBSD(SysInfoFreeBSDOSX):
self._platform_is_smp = True # the value doesn't matter
except subprocess.CalledProcessError:
# if this variable isn't defined we should see this exception.
- # intepret it as an indication of non-SMP kernel.
+ # interpret it as an indication of non-SMP kernel.
self._platform_is_smp = False
except OSError:
pass
diff --git a/src/lib/python/isc/util/socketserver_mixin.py b/src/lib/python/isc/util/socketserver_mixin.py
index e954fe1..da04b6f 100644
--- a/src/lib/python/isc/util/socketserver_mixin.py
+++ b/src/lib/python/isc/util/socketserver_mixin.py
@@ -39,7 +39,7 @@ class NoPollMixIn:
socketserver.BaseServer or some derived classes of it, and it must
be placed before the corresponding socketserver class. In
addition, the constructor of this mix-in must be called
- explicitely in the derived class. For example, a basic TCP server
+ explicitly in the derived class. For example, a basic TCP server
without the problem of polling is created as follows:
class MyServer(NoPollMixIn, socketserver.TCPServer):
diff --git a/src/lib/resolve/tests/recursive_query_unittest.cc b/src/lib/resolve/tests/recursive_query_unittest.cc
index e5e46e1..acbbb03 100644
--- a/src/lib/resolve/tests/recursive_query_unittest.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest.cc
@@ -971,7 +971,7 @@ TEST_F(RecursiveQueryTest, CachedNS) {
// point and ask NSAS for it. NSAS will in turn ask resolver for NS record
// of the delegation point. We then pick it up from the fake resolver
// and check it is the correct one. This checks the delegation point
- // travels safely trough the whole path there (it would be enough to check
+ // travels safely through the whole path there (it would be enough to check
// it up to NSAS, but replacing NSAS is more complicated, so we just
// include in the test as well for simplicity).
diff --git a/src/lib/server_common/portconfig.cc b/src/lib/server_common/portconfig.cc
index 122c740..7bc6876 100644
--- a/src/lib/server_common/portconfig.cc
+++ b/src/lib/server_common/portconfig.cc
@@ -135,7 +135,7 @@ installListenAddresses(const AddressList& new_addresses,
* set successuflly or none of them will be used. whether this
* behavior is user desired, maybe we need revisited it later. And
* if address setting is more smarter, it should check whether some
- * part of the new address already in used to avoid interuption the
+ * part of the new address already in used to avoid interrupting the
* service.
*
* If the address setting still failed, we can live with it, since
diff --git a/src/lib/util/python/gen_wiredata.py.in b/src/lib/util/python/gen_wiredata.py.in
index c219e25..d181f73 100755
--- a/src/lib/util/python/gen_wiredata.py.in
+++ b/src/lib/util/python/gen_wiredata.py.in
@@ -138,7 +138,7 @@ the type. But there are some common configurable entries. See the
description of the RR class. The most important one would be "as_rr".
It controls whether the entry should be treated as an RR (with name,
type, class and TTL) or only as an RDATA. By default as_rr is
-"False", so if an entry is to be intepreted as an RR, an as_rr entry
+"False", so if an entry is to be interpreted as an RR, an as_rr entry
must be explicitly specified with a value of "True".
Another common entry is "rdlen". It specifies the RDLEN field value
@@ -762,7 +762,7 @@ class TXT(RR):
value will be used. If this parameter isn't specified either,
the length of the string will be used. Note that it means
this parameter (or any stringlenN) doesn't have to be specified
- unless you want to intentially build a broken character string.
+ unless you want to intentionally build a broken character string.
- string (string): the default string. If nstring >= 1 and the
corresponding stringN isn't specified in the spec file, this
string will be used.
diff --git a/src/lib/util/tests/fd_share_tests.cc b/src/lib/util/tests/fd_share_tests.cc
index b8000e1..bb69204 100644
--- a/src/lib/util/tests/fd_share_tests.cc
+++ b/src/lib/util/tests/fd_share_tests.cc
@@ -66,7 +66,7 @@ TEST(FDShare, transfer) {
if (close(pipes[0])) {
exit(1);
}
- // Send "data" trough the received fd, close it and be done
+ // Send "data" through the received fd, close it and be done
if (!write_data(fd, "data", 4) || close(fd) == -1) {
exit(1);
}
diff --git a/src/lib/util/unittests/resolver.h b/src/lib/util/unittests/resolver.h
index 560a892..127fd54 100644
--- a/src/lib/util/unittests/resolver.h
+++ b/src/lib/util/unittests/resolver.h
@@ -60,7 +60,7 @@ class TestResolver : public isc::resolve::ResolverInterface {
PresetAnswers answers_;
public:
typedef std::pair<isc::dns::QuestionPtr, CallbackPtr> Request;
- /// \brief List of requests the tested class sent trough resolve
+ /// \brief List of requests the tested class sent through resolve
std::vector<Request> requests;
/// \brief Destructor
diff --git a/src/lib/xfr/tests/client_test.cc b/src/lib/xfr/tests/client_test.cc
index 6c9f4ad..ce783b0 100644
--- a/src/lib/xfr/tests/client_test.cc
+++ b/src/lib/xfr/tests/client_test.cc
@@ -24,7 +24,7 @@ using namespace isc::xfr;
namespace {
-TEST(ClientTest, connetFile) {
+TEST(ClientTest, connectFile) {
// File path is too long
struct sockaddr_un s; // can't be const; some compiler complains
EXPECT_THROW(XfroutClient(string(sizeof(s.sun_path), 'x')).connect(),
diff --git a/tests/lettuce/features/example.feature b/tests/lettuce/features/example.feature
index f2df6d4..86d20d3 100644
--- a/tests/lettuce/features/example.feature
+++ b/tests/lettuce/features/example.feature
@@ -26,7 +26,7 @@ Feature: Example feature
Scenario: New database
# This test checks whether a database file is automatically created
- # Underwater, we take advantage of our intialization routines so
+ # Underwater, we take advantage of our initialization routines so
# that we are sure this file does not exist, see
# features/terrain/terrain.py
diff --git a/tests/lettuce/features/nsec3_auth.feature b/tests/lettuce/features/nsec3_auth.feature
index 4e5ed5b..6d3a556 100644
--- a/tests/lettuce/features/nsec3_auth.feature
+++ b/tests/lettuce/features/nsec3_auth.feature
@@ -241,7 +241,7 @@ Feature: NSEC3 Authoritative service
"""
#
- # Below are additional tests, not explicitely stated in RFC5155
+ # Below are additional tests, not explicitly stated in RFC5155
#
Scenario: 7.2.2 other; Name Error where one NSEC3 covers multiple parts of proof (closest encloser)
diff --git a/tests/tools/badpacket/option_info.h b/tests/tools/badpacket/option_info.h
index 944f60e..8cc0fe9 100644
--- a/tests/tools/badpacket/option_info.h
+++ b/tests/tools/badpacket/option_info.h
@@ -151,7 +151,7 @@ public:
/// \param index A valid index (one of the values in the 'Index' enum).
///
/// \return Maximum allowed value for this option. If the option is a bit
- /// in the flags field of the DNS message hearder, this will be 1.
+ /// in the flags field of the DNS message header, this will be 1.
static uint32_t maxval(int index);
/// \brief Check Array Index
diff --git a/tests/tools/dhcp-ubench/dhcp-perf-guide.xml b/tests/tools/dhcp-ubench/dhcp-perf-guide.xml
index 417968d..0115cd6 100644
--- a/tests/tools/dhcp-ubench/dhcp-perf-guide.xml
+++ b/tests/tools/dhcp-ubench/dhcp-perf-guide.xml
@@ -316,7 +316,7 @@
turned to several modes of operation. Its value can be
modified in SQLite_uBenchmark::connect(). See
http://www.sqlite.org/pragma.html#pragma_journal_mode for
- detailed explanantion.</para>
+ a detailed explanation.</para>
<para>sqlite_bench supports precompiled statements. Please use
'-c no|yes' to define which should be used: basic SQL query (no) or
diff --git a/tests/tools/perfdhcp/command_options.cc b/tests/tools/perfdhcp/command_options.cc
index 9169600..c0ae6fa 100644
--- a/tests/tools/perfdhcp/command_options.cc
+++ b/tests/tools/perfdhcp/command_options.cc
@@ -433,7 +433,7 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) {
}
if (server_name_.empty()) {
isc_throw(InvalidParameter,
- "without an inteface server is required");
+ "without an interface, server is required");
}
// If DUID is not specified from command line we need to
diff --git a/tests/tools/perfdhcp/pkt_transform.h b/tests/tools/perfdhcp/pkt_transform.h
index c94e9ba..51c1c0b 100644
--- a/tests/tools/perfdhcp/pkt_transform.h
+++ b/tests/tools/perfdhcp/pkt_transform.h
@@ -54,7 +54,7 @@ public:
/// if the option's offset + its size is beyond the packet's size.
///
/// \param universe Universe used, V4 or V6
- /// \param in_buffer Input buffer holding intial packet
+ /// \param in_buffer Input buffer holding initial packet
/// data, this can be directly read from template file
/// \param options Options collection with offsets
/// \param transid_offset offset of transaction id in a packet,
diff --git a/tests/tools/perfdhcp/stats_mgr.h b/tests/tools/perfdhcp/stats_mgr.h
index 5e143e6..2ad5aa9 100644
--- a/tests/tools/perfdhcp/stats_mgr.h
+++ b/tests/tools/perfdhcp/stats_mgr.h
@@ -719,7 +719,7 @@ public:
/// \brief Private default constructor.
///
/// Default constructor is private because we want the client
- /// class to specify exchange type explicitely.
+ /// class to specify exchange type explicitly.
ExchangeStats();
/// \brief Erase packet from the list of sent packets.
@@ -905,7 +905,7 @@ public:
/// \brief Increment specified counter.
///
- /// Increement counter value by one.
+ /// Increment counter value by one.
///
/// \param counter_key key poiting to the counter in the counters map.
/// \param value value to increment counter by.
diff --git a/tests/tools/perfdhcp/test_control.cc b/tests/tools/perfdhcp/test_control.cc
index 4a3075a..0cd69b4 100644
--- a/tests/tools/perfdhcp/test_control.cc
+++ b/tests/tools/perfdhcp/test_control.cc
@@ -905,8 +905,8 @@ TestControl::readPacketTemplate(const std::string& file_name) {
hex_digits.push_back(file_contents[i]);
} else if (!isxdigit(file_contents[i]) &&
!isspace(file_contents[i])) {
- isc_throw(BadValue, "the '" << file_contents[i] << "' is not a"
- " heaxadecimal digit");
+ isc_throw(BadValue, "'" << file_contents[i] << "' is not a"
+ " hexadecimal digit");
}
}
// Expect even number of digits.
@@ -1864,7 +1864,7 @@ TestControl::updateSendDue() {
// timer resolution.
duration = time_duration::ticks_per_second() / rate;
}
- // Calculate due time to initate next chunk of exchanges.
+ // Calculate due time to initiate next chunk of exchanges.
send_due_ = last_sent_ + time_duration(0, 0, 0, duration);
// Check if it is already due.
ptime now(microsec_clock::universal_time());
diff --git a/tests/tools/perfdhcp/test_control.h b/tests/tools/perfdhcp/test_control.h
index d3196f7..f1b1300 100644
--- a/tests/tools/perfdhcp/test_control.h
+++ b/tests/tools/perfdhcp/test_control.h
@@ -909,7 +909,7 @@ private:
/// \brief Handle interrupt signal.
///
/// Function sets flag indicating that program has been
- /// interupted.
+ /// interrupted.
///
/// \param sig signal (ignored)
static void handleInterrupt(int sig);
@@ -970,7 +970,7 @@ private:
NumberGeneratorPtr transid_gen_; ///< Transaction id generator.
NumberGeneratorPtr macaddr_gen_; ///< Numbers generator for MAC address.
- /// Buffer holiding server id received in first packet
+ /// Buffer holding server id received in first packet
dhcp::OptionBuffer first_packet_serverid_;
/// Packet template buffers.
diff --git a/tests/tools/perfdhcp/tests/command_options_unittest.cc b/tests/tools/perfdhcp/tests/command_options_unittest.cc
index bda256f..7a109fb 100644
--- a/tests/tools/perfdhcp/tests/command_options_unittest.cc
+++ b/tests/tools/perfdhcp/tests/command_options_unittest.cc
@@ -546,7 +546,7 @@ TEST_F(CommandOptionsTest, Interface) {
// In order to make this test portable we need to know
// at least one interface name on OS where test is run.
// Interface Manager has ability to detect interfaces.
- // Although we don't call initIsInterface explicitely
+ // Although we don't call initIsInterface explicitly
// here it is called by CommandOptions object interally
// so this function is covered by the test.
dhcp::IfaceMgr& iface_mgr = dhcp::IfaceMgr::instance();
diff --git a/tools/system_messages.py b/tools/system_messages.py
index 08a35e1..869a164 100644
--- a/tools/system_messages.py
+++ b/tools/system_messages.py
@@ -268,7 +268,7 @@ def addToDictionary(msgid, msgtext, desc, filename):
name of the message file in the messages manual.
"""
- # If the ID is in the dictionary, append a "(n)" to the name - this wil
+ # If the ID is in the dictionary, append a "(n)" to the name - this will
# flag that there are multiple instances. (However, this is an error -
# each ID should be unique in BIND-10.)
if msgid in dictionary:
More information about the bind10-changes
mailing list