Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
7e7171de
Commit
7e7171de
authored
Sep 28, 2012
by
Tomek Mrugalski
🛰
Browse files
[2269] dhcp6 config parser now returns status codes and does not throw.
parent
4a6553ba
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/config_parser.cc
View file @
7e7171de
...
...
@@ -21,16 +21,16 @@
#include
<boost/scoped_ptr.hpp>
#include
<boost/lexical_cast.hpp>
#include
<boost/algorithm/string.hpp>
#include
<asiolink/io_address.h>
#include
<cc/data.h>
#include
<config/ccsession.h>
#include
<asiolink/io_address.h>
#include
<dhcp6/config_parser.h>
#include
<log/logger_support.h>
#include
<dhcp/triplet.h>
#include
<dhcp/pool.h>
#include
<dhcp/subnet.h>
#include
<dhcp/cfgmgr.h>
#include
<dhcp6/config_parser.h>
#include
<dhcp6/dhcp6_log.h>
#include
<log/logger_support.h>
using
namespace
std
;
using
namespace
isc
::
data
;
...
...
@@ -43,9 +43,7 @@ typedef boost::shared_ptr<Dhcp6ConfigParser> ParserPtr;
typedef
pair
<
string
,
ConstElementPtr
>
ConfigPair
;
typedef
std
::
vector
<
ParserPtr
>
ParserCollection
;
typedef
Dhcp6ConfigParser
*
ParserFactory
(
const
std
::
string
&
config_id
);
typedef
std
::
map
<
std
::
string
,
ParserFactory
*>
FactoryMap
;
typedef
std
::
map
<
string
,
uint32_t
>
Uint32Storage
;
/// @brief That is a map with global parameters that will be used as defaults
Uint32Storage
uint32_defaults
;
...
...
@@ -54,23 +52,40 @@ typedef std::map<string, string> StringStorage;
StringStorage
string_defaults
;
typedef
std
::
vector
<
Pool6Ptr
>
PoolStorage
;
PoolStorage
pool_defaults
;
/// @brief a dummy configuration parser
///
/// It is a debugging parser. It does not configure anything,
/// will accept any configuration and will just print it out
/// on commit.
/// on commit. Useful for debugging existing configurations and
/// adding new ones.
class
DummyParser
:
public
Dhcp6ConfigParser
{
public:
/// @brief Constructor
///
/// See \ref Dhcp6ConfigParser class for details.
///
/// @param param_name name of the parsed parameter
DummyParser
(
const
std
::
string
&
param_name
)
:
param_name_
(
param_name
)
{
}
/// @brief builds parameter value
///
/// See \ref Dhcp6ConfigParser class for details.
virtual
void
build
(
ConstElementPtr
new_config
)
{
std
::
cout
<<
"Build for token: ["
<<
param_name_
<<
"] = ["
<<
value_
->
str
()
<<
"]"
<<
std
::
endl
;
value_
=
new_config
;
}
/// @brief pretends to apply the configuration
///
/// This is a method required by base class. It pretends to apply the
/// configuration, but in fact it only prints the parameter out.
///
/// See \ref Dhcp6ConfigParser class for details.
virtual
void
commit
()
{
// Debug message. The whole DummyParser class is used only for parser
// debugging, and is not used in production code. It is very convenient
...
...
@@ -79,21 +94,45 @@ public:
<<
value_
->
str
()
<<
"]"
<<
std
::
endl
;
}
/// @brief factory that constructs DummyParser objects
///
/// @param param_name name of the parameter to be parsed
static
Dhcp6ConfigParser
*
Factory
(
const
std
::
string
&
param_name
)
{
return
(
new
DummyParser
(
param_name
));
}
protected:
/// name of the parsed parameter
std
::
string
param_name_
;
/// pointer to the actual value of the parameter
ConstElementPtr
value_
;
};
/// @brief Configuration parser for uint32 types
///
/// This class is a generic parser that is able to handle any uint32 integer
/// type. By default it stores the value in external global container
/// (uint32_defaults). If used in smaller scopes (e.g. to parse parameters
/// in subnet config), it can be pointed to a different storage, using
/// setStorage() method. This class follows the parser interface, laid out
/// in its base class, \ref Dhcp6ConfigParser.
class
Uint32Parser
:
public
Dhcp6ConfigParser
{
public:
/// @brief constructor for Uint32Parser
/// @param param_name name of the parameter that is going to be parsed
Uint32Parser
(
const
std
::
string
&
param_name
)
:
storage_
(
&
uint32_defaults
),
param_name_
(
param_name
)
{
}
/// @brief builds parameter value
///
/// Parses configuration entry and stored it in storage. See
/// \ref setStorage() for details.
///
/// @param value pointer to the content of parsed values
virtual
void
build
(
ConstElementPtr
value
)
{
try
{
value_
=
boost
::
lexical_cast
<
uint32_t
>
(
value
->
str
());
...
...
@@ -104,9 +143,20 @@ public:
storage_
->
insert
(
pair
<
string
,
uint32_t
>
(
param_name_
,
value_
));
}
/// @brief does nothing
///
/// This method is required for all parser. The value itself
/// is not commited anywhere. Higher level parsers are expected to
/// use values stored in the storage, e.g. renew-timer for a given
/// subnet is stored in subnet-specific storage. It is not commited
/// here, but is rather used by \ref Subnet6Parser when constructing
/// the subnet.
virtual
void
commit
()
{
}
/// @brief factory that constructs DummyParser objects
///
/// @param param_name name of the parameter to be parsed
static
Dhcp6ConfigParser
*
Factory
(
const
std
::
string
&
param_name
)
{
return
(
new
Uint32Parser
(
param_name
));
}
...
...
@@ -325,13 +375,18 @@ public:
Triplet
<
uint32_t
>
valid
=
getParam
(
"valid-lifetime"
);
/// @todo: Convert this to logger once the parser is working reliably
cout
<<
"Adding subnet "
<<
addr
.
toText
()
<<
"/"
<<
(
int
)
len
<<
" with params t1="
<<
t1
<<
", t2="
<<
t2
<<
", pref="
<<
pref
<<
", valid="
<<
valid
<<
endl
;
stringstream
tmp
;
tmp
<<
addr
.
toText
()
<<
"/"
<<
(
int
)
len
<<
" with params t1="
<<
t1
<<
", t2="
<<
t2
<<
", pref="
<<
pref
<<
", valid="
<<
valid
;
Subnet6Ptr
subnet
(
new
Subnet6
(
addr
,
len
,
t1
,
t2
,
pref
,
valid
));
LOG_INFO
(
dhcp6_logger
,
DHCP6_CONFIG_NEW_SUBNET
).
arg
(
tmp
.
str
(
));
Subnet6Ptr
subnet
(
new
Subnet6
(
addr
,
len
,
t1
,
t2
,
pref
,
valid
));
for
(
PoolStorage
::
iterator
it
=
pools_
.
begin
();
it
!=
pools_
.
end
();
++
it
)
{
subnet
->
addPool6
(
*
it
);
}
CfgMgr
::
instance
().
addSubnet6
(
subnet
);
}
...
...
@@ -418,6 +473,12 @@ public:
}
void
commit
()
{
// @todo: Implement more subtle reconfiguration than toss
// the old one and replace with the new one.
// remove old subnets
CfgMgr
::
instance
().
deleteSubnets6
();
BOOST_FOREACH
(
ParserPtr
subnet
,
subnets_
)
{
subnet
->
commit
();
}
...
...
@@ -469,7 +530,7 @@ Dhcp6ConfigParser* createGlobalDhcp6ConfigParser(const std::string& config_id) {
}
ConstElementPtr
configureDhcp6Server
(
Dhcpv6Srv
&
server
,
ConstElementPtr
config_set
)
{
configureDhcp6Server
(
Dhcpv6Srv
&
,
ConstElementPtr
config_set
)
{
if
(
!
config_set
)
{
isc_throw
(
Dhcp6ConfigError
,
"Null pointer is passed to configuration parser"
);
...
...
@@ -488,20 +549,29 @@ configureDhcp6Server(Dhcpv6Srv& server, ConstElementPtr config_set) {
parser
->
build
(
config_pair
.
second
);
parsers
.
push_back
(
parser
);
}
}
catch
(
const
Dhcp6ConfigError
&
ex
)
{
throw
;
// simply rethrowing it
}
catch
(
const
isc
::
Exception
&
ex
)
{
isc_throw
(
Dhcp6ConfigError
,
"Server configuration failed: "
<<
ex
.
what
());
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
string
(
"Configuration parsing failed:"
)
+
ex
.
what
());
return
(
answer
);
}
catch
(...)
{
// for things like bad_cast in boost::lexical_cast
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
string
(
"Configuration parsing failed"
));
}
try
{
BOOST_FOREACH
(
ParserPtr
parser
,
parsers
)
{
parser
->
commit
();
}
}
catch
(
const
isc
::
Exception
&
ex
)
{
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
2
,
string
(
"Configuration commit failed:"
)
+
ex
.
what
());
return
(
answer
);
}
catch
(...)
{
isc_throw
(
Dhcp6ConfigError
,
"Unrecoverable error: "
"a configuration parser threw in commit"
);
// for things like bad_cast in boost::lexical_cast
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
2
,
string
(
"Configuration commit failed"
));
}
LOG_INFO
(
dhcp6_logger
,
DHCP6_CONFIG_COMPLETE
).
arg
(
config_details
);
...
...
src/bin/dhcp6/config_parser.h
View file @
7e7171de
...
...
@@ -162,7 +162,7 @@ configureDhcp6Server(Dhcpv6Srv& server,
/// is to be created.
/// \return A pointer to an \c Dhcp6ConfigParser object.
Dhcp6ConfigParser
*
createDhcp6ConfigParser
(
Dhcpv6Srv
&
server
,
const
std
::
string
&
config_id
);
const
std
::
string
&
config_id
);
};
// end of isc::dhcp namespace
};
// end of isc namespace
...
...
src/bin/dhcp6/dhcp6_messages.mes
View file @
7e7171de
...
...
@@ -111,6 +111,10 @@ This is a debug message that is issued every time the server receives
configuration. That happens during every start up and also when server
configuration change is committed by the administrator.
% DHCP6_CONFIG_NEW_SUBNET A new subnet has been added to configuration: %1
This is an informational message that the configuration has extended
and specified new subnet is now supported.
% DHCP6_CONFIG_COMPLETE DHCPv6 server has completed configuration: %1
This is an informational message that announces successful processing
of a new configuration. That may happen as a result of one of two
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment