Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
ISC Open Source Projects
Kea
Commits
c6981a0e
Commit
c6981a0e
authored
Jan 03, 2013
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2315] Added storage for option definitions.
parent
0fe0d44a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
211 additions
and
7 deletions
+211
-7
src/lib/dhcp/option_definition.h
src/lib/dhcp/option_definition.h
+9
-1
src/lib/dhcpsrv/cfgmgr.cc
src/lib/dhcpsrv/cfgmgr.cc
+47
-4
src/lib/dhcpsrv/cfgmgr.h
src/lib/dhcpsrv/cfgmgr.h
+46
-1
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
+109
-1
No files found.
src/lib/dhcp/option_definition.h
View file @
c6981a0e
// 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
...
...
@@ -42,6 +42,14 @@ public:
isc
::
Exception
(
file
,
line
,
what
)
{
};
};
/// @brief Exception to be thrown when the particular option definition
/// duplicates existing option definition.
class
DuplicateOptionDefinition
:
public
Exception
{
public:
DuplicateOptionDefinition
(
const
char
*
file
,
size_t
line
,
const
char
*
what
)
:
isc
::
Exception
(
file
,
line
,
what
)
{
};
};
/// @brief Forward declaration to OptionDefinition.
class
OptionDefinition
;
...
...
src/lib/dhcpsrv/cfgmgr.cc
View file @
c6981a0e
// 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
...
...
@@ -21,15 +21,54 @@ using namespace isc::util;
namespace
isc
{
namespace
dhcp
{
CfgMgr
&
CfgMgr
::
instance
()
{
static
CfgMgr
cfg_mgr
;
return
(
cfg_mgr
);
}
void
CfgMgr
::
addOptionDef
(
const
OptionDefinitionPtr
&
def
,
const
std
::
string
&
option_space
)
{
// @todo we need better validation of the provided option space name here.
// This will be implemented when #2313 is merged.
if
(
option_space
.
empty
())
{
isc_throw
(
BadValue
,
"option space name must not be empty"
);
}
else
if
(
!
def
)
{
isc_throw
(
MalformedOptionDefinition
,
"option definition must not be NULL"
);
}
else
if
(
getOptionDef
(
option_space
,
def
->
getCode
()))
{
isc_throw
(
DuplicateOptionDefinition
,
"option definition already added"
<<
" to option space "
<<
option_space
);
}
option_def_spaces_
[
option_space
].
push_back
(
def
);
}
const
OptionDefContainer
&
CfgMgr
::
getOptionDefs
(
const
std
::
string
&
option_space
)
const
{
const
std
::
map
<
std
::
string
,
OptionDefContainer
>::
const_iterator
&
defs
=
option_def_spaces_
.
find
(
option_space
);
if
(
defs
==
option_def_spaces_
.
end
())
{
static
OptionDefContainer
empty_container
;
return
(
empty_container
);
}
return
(
defs
->
second
);
}
OptionDefinitionPtr
CfgMgr
::
getOptionDef
(
const
std
::
string
&
option_space
,
const
uint16_t
option_code
)
const
{
const
OptionDefContainer
&
defs
=
getOptionDefs
(
option_space
);
if
(
defs
.
empty
())
{
return
(
OptionDefinitionPtr
());
}
const
OptionDefContainerTypeIndex
&
idx
=
defs
.
get
<
1
>
();
const
OptionDefContainerTypeRange
&
range
=
idx
.
equal_range
(
option_code
);
if
(
std
::
distance
(
range
.
first
,
range
.
second
)
==
0
)
{
return
(
OptionDefinitionPtr
());
}
return
(
*
range
.
first
);
}
Subnet6Ptr
CfgMgr
::
getSubnet6
(
const
isc
::
asiolink
::
IOAddress
&
hint
)
{
...
...
@@ -101,6 +140,10 @@ void CfgMgr::addSubnet4(const Subnet4Ptr& subnet) {
subnets4_
.
push_back
(
subnet
);
}
void
CfgMgr
::
deleteOptionDefs
()
{
option_def_spaces_
.
clear
();
}
void
CfgMgr
::
deleteSubnets4
()
{
subnets4_
.
clear
();
}
...
...
src/lib/dhcpsrv/cfgmgr.h
View file @
c6981a0e
// 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
...
...
@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp/option.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/subnet.h>
#include <util/buffer.h>
...
...
@@ -77,6 +78,34 @@ public:
/// accessing it.
static
CfgMgr
&
instance
();
/// @brief Add new option definition.
///
/// @param def option definition to be added.
///
/// @throw isc::dhcp::DuplicateOptionDefinition when the particular
/// option definition already exists.
void
addOptionDef
(
const
OptionDefinitionPtr
&
def
,
const
std
::
string
&
option_space
);
/// @brief Return option definitions for particular option space.
///
/// @param option_space option space.
///
/// @return collection of option definitions for a particular
/// option space.
const
OptionDefContainer
&
getOptionDefs
(
const
std
::
string
&
option_space
)
const
;
/// @brief Return option definition for a particular option space and code.
///
/// @param option_space option space.
/// @param option_code option code.
///
/// @return an option definition or NULL pointer if option definition
/// has not been found.
OptionDefinitionPtr
getOptionDef
(
const
std
::
string
&
option_space
,
const
uint16_t
option_code
)
const
;
/// @brief get IPv6 subnet by address
///
/// Finds a matching subnet, based on an address. This can be used
...
...
@@ -86,6 +115,8 @@ public:
/// (for directly connected clients)
///
/// @param hint an address that belongs to a searched subnet
///
/// @return a subnet object
Subnet6Ptr
getSubnet6
(
const
isc
::
asiolink
::
IOAddress
&
hint
);
/// @brief get IPv6 subnet by interface-id
...
...
@@ -93,12 +124,19 @@ public:
/// Another possibility to find a subnet is based on interface-id.
///
/// @param interface_id content of interface-id option returned by a relay
///
/// @return a subnet object
/// @todo This method is not currently supported.
Subnet6Ptr
getSubnet6
(
OptionPtr
interface_id
);
/// @brief adds an IPv6 subnet
///
/// @param subnet new subnet to be added.
void
addSubnet6
(
const
Subnet6Ptr
&
subnet
);
/// @brief Delete all option definitions.
void
deleteOptionDefs
();
/// @todo: Add subnet6 removal routines. Currently it is not possible
/// to remove subnets. The only case where subnet6 removal would be
/// needed is a dynamic server reconfiguration - a use case that is not
...
...
@@ -125,6 +163,8 @@ public:
/// (for directly connected clients)
///
/// @param hint an address that belongs to a searched subnet
///
/// @return a subnet object
Subnet4Ptr
getSubnet4
(
const
isc
::
asiolink
::
IOAddress
&
hint
);
/// @brief adds a subnet4
...
...
@@ -169,6 +209,11 @@ protected:
/// pattern will use calling inRange() method on each subnet until
/// a match is found.
Subnet4Collection
subnets4_
;
private:
/// A map containing option definitions for different option spaces.
std
::
map
<
std
::
string
,
OptionDefContainer
>
option_def_spaces_
;
};
}
// namespace isc::dhcp
...
...
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
View file @
c6981a0e
...
...
@@ -43,9 +43,118 @@ public:
~
CfgMgrTest
()
{
CfgMgr
::
instance
().
deleteSubnets6
();
CfgMgr
::
instance
().
deleteOptionDefs
();
}
};
// This test verifies that multiple option definitions can be added
// under different option spaces.
TEST_F
(
CfgMgrTest
,
getOptionDefs
)
{
CfgMgr
&
cfg_mgr
=
CfgMgr
::
instance
();
// Create a set of option definitions with codes between 100 and 109.
for
(
uint16_t
code
=
100
;
code
<
110
;
++
code
)
{
std
::
ostringstream
option_name
;
// Option name is unique, e.g. option-100, option-101 etc.
option_name
<<
"option-"
<<
code
;
OptionDefinitionPtr
def
(
new
OptionDefinition
(
option_name
.
str
(),
code
,
"uint16"
));
// Add option definition to "isc" option space.
// Option codes are not duplicated so expect no error
// when adding them.
ASSERT_NO_THROW
(
cfg_mgr
.
addOptionDef
(
def
,
"isc"
));
}
// Create a set of option definitions with codes between 105 and 114 and
// add them to the different option space.
for
(
uint16_t
code
=
105
;
code
<
115
;
++
code
)
{
std
::
ostringstream
option_name
;
option_name
<<
"option-"
<<
code
;
OptionDefinitionPtr
def
(
new
OptionDefinition
(
option_name
.
str
(),
code
,
"uint16"
));
ASSERT_NO_THROW
(
cfg_mgr
.
addOptionDef
(
def
,
"abcde"
));
}
// Sanity check that all 10 option definitions are there.
const
OptionDefContainer
&
option_defs1
=
cfg_mgr
.
getOptionDefs
(
"isc"
);
ASSERT_EQ
(
10
,
option_defs1
.
size
());
// Iterate over all option definitions and check that they have
// valid codes. Also, their order should be the same as they
// were added (codes 100-109).
uint16_t
code
=
100
;
for
(
OptionDefContainer
::
const_iterator
it
=
option_defs1
.
begin
();
it
!=
option_defs1
.
end
();
++
it
,
++
code
)
{
OptionDefinitionPtr
def
(
*
it
);
ASSERT_TRUE
(
def
);
EXPECT_EQ
(
code
,
def
->
getCode
());
}
// Sanity check that all 10 option definitions are there.
const
OptionDefContainer
&
option_defs2
=
cfg_mgr
.
getOptionDefs
(
"abcde"
);
ASSERT_EQ
(
10
,
option_defs2
.
size
());
// Check that the option codes are valid.
code
=
105
;
for
(
OptionDefContainer
::
const_iterator
it
=
option_defs2
.
begin
();
it
!=
option_defs2
.
end
();
++
it
,
++
code
)
{
OptionDefinitionPtr
def
(
*
it
);
ASSERT_TRUE
(
def
);
EXPECT_EQ
(
code
,
def
->
getCode
());
}
// Let's make one more check that the empty set is returned when
// invalid option space is used.
const
OptionDefContainer
&
option_defs3
=
cfg_mgr
.
getOptionDefs
(
"non-existing"
);
ASSERT_TRUE
(
option_defs3
.
empty
());
}
// This test verifies that single option definition is correctly
// returned with getOptionDef function.
TEST_F
(
CfgMgrTest
,
getOptionDef
)
{
CfgMgr
&
cfg_mgr
=
CfgMgr
::
instance
();
// Create a set of option definitions with codes between 100 and 109.
for
(
uint16_t
code
=
100
;
code
<
110
;
++
code
)
{
std
::
ostringstream
option_name
;
// Option name is unique, e.g. option-100, option-101 etc.
option_name
<<
"option-"
<<
code
;
OptionDefinitionPtr
def
(
new
OptionDefinition
(
option_name
.
str
(),
code
,
"uint16"
));
// Add option definition to "isc" option space.
// Option codes are not duplicated so expect no error
// when adding them.
ASSERT_NO_THROW
(
cfg_mgr
.
addOptionDef
(
def
,
"isc"
));
}
// Create a set of option definitions with codes between 105 and 114 and
// add them to the different option space.
for
(
uint16_t
code
=
105
;
code
<
115
;
++
code
)
{
std
::
ostringstream
option_name
;
option_name
<<
"option-"
<<
code
;
OptionDefinitionPtr
def
(
new
OptionDefinition
(
option_name
.
str
(),
code
,
"uint16"
));
ASSERT_NO_THROW
(
cfg_mgr
.
addOptionDef
(
def
,
"abcde"
));
}
// Try to get option definitions one by one using all codes
// that we expect to be there.
for
(
uint16_t
code
=
100
;
code
<
110
;
++
code
)
{
OptionDefinitionPtr
def
=
cfg_mgr
.
getOptionDef
(
"isc"
,
code
);
ASSERT_TRUE
(
def
);
EXPECT_EQ
(
code
,
def
->
getCode
());
}
// Check that the option codes are valid.
for
(
uint16_t
code
=
105
;
code
<
115
;
++
code
)
{
OptionDefinitionPtr
def
=
cfg_mgr
.
getOptionDef
(
"abcde"
,
code
);
ASSERT_TRUE
(
def
);
EXPECT_EQ
(
code
,
def
->
getCode
());
}
// Try to query the option definition from an non-existing
// option space and expect NULL pointer.
OptionDefinitionPtr
def
=
cfg_mgr
.
getOptionDef
(
"non-existing"
,
56
);
ASSERT_FALSE
(
def
);
}
// This test verifies if the configuration manager is able to hold and return
// valid leases
...
...
@@ -79,7 +188,6 @@ TEST_F(CfgMgrTest, subnet4) {
// This test verifies if the configuration manager is able to hold and return
// valid leases
TEST_F
(
CfgMgrTest
,
subnet6
)
{
CfgMgr
&
cfg_mgr
=
CfgMgr
::
instance
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment