Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
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
7eef7d97
Commit
7eef7d97
authored
Mar 04, 2017
by
Francis Dupont
Browse files
[5145b] Merged trac5126 diffs
parent
f15dee70
Changes
21
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
7eef7d97
...
...
@@ -201,6 +201,21 @@ for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(template alias)
feature="template alias"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[template<int i>
class I {
public: int get() { return i; };
};
using Zero = I<0>;],
[Zero Z;
return Z.get();])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(lambda support)
feature="lambda"
AC_COMPILE_IFELSE(
...
...
@@ -1467,11 +1482,11 @@ AC_ARG_ENABLE(generate_parser, [AC_HELP_STRING([--enable-generate-parser],
enable_generate_parser=$enableval, enable_generate_parser=no)
# Check if flex is avaible. Flex is not needed for building Kea sources,
# unless you want to regenerate grammar
in src/lib/eval
# unless you want to regenerate grammar
s
AC_PROG_LEX
# Check if bison is available. Bison is not needed for building Kea sources,
# unless you want to regenerate grammar
in src/lib/eval
# unless you want to regenerate grammar
s
AC_PROG_YACC
if test "x$enable_generate_parser" != "xno"; then
...
...
@@ -1485,7 +1500,7 @@ if test "x$enable_generate_parser" != "xno"; then
fi
# Ok, let's check if we have at least 3.0.0 version of the bison. The code used
# to generate
src/lib/eval
parser is roughly based on bison 3.0 examples.
# to generate parser
s
is roughly based on bison 3.0 examples.
cat > bisontest.y << EOF
%require "3.0.0"
%token X
...
...
@@ -1599,20 +1614,28 @@ AM_COND_IF([HAVE_OPTRESET], [AC_DEFINE([HAVE_OPTRESET], [1], [Check for optreset
AC_DEFINE([CONFIG_H_WAS_INCLUDED], [1], [config.h inclusion marker])
AC_CONFIG_FILES([compatcheck/Makefile
AC_CONFIG_FILES([Makefile
compatcheck/Makefile
dns++.pc
doc/
design/datasrc/
Makefile
doc/Makefile
doc/design/Makefile
doc/design/datasrc/Makefile
doc/guide/Makefile
doc/Makefile
doc/version.ent
ext/Makefile
ext/coroutine/Makefile
ext/gtest/Makefile
ext/Makefile
m4macros/Makefile
Makefile
src/Makefile
src/bin/Makefile
src/bin/admin/Makefile
src/bin/admin/kea-admin
src/bin/admin/tests/Makefile
src/bin/admin/tests/cql_tests.sh
src/bin/admin/tests/data/Makefile
src/bin/admin/tests/memfile_tests.sh
src/bin/admin/tests/mysql_tests.sh
src/bin/admin/tests/pgsql_tests.sh
src/bin/agent/Makefile
src/bin/agent/tests/Makefile
src/bin/agent/tests/ca_process_tests.sh
...
...
@@ -1644,15 +1667,6 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/bin/perfdhcp/Makefile
src/bin/perfdhcp/tests/Makefile
src/bin/perfdhcp/tests/testdata/Makefile
src/bin/admin/Makefile
src/bin/admin/kea-admin
src/bin/admin/tests/Makefile
src/bin/admin/tests/data/Makefile
src/bin/admin/tests/memfile_tests.sh
src/bin/admin/tests/mysql_tests.sh
src/bin/admin/tests/pgsql_tests.sh
src/bin/admin/tests/cql_tests.sh
src/bin/agent/tests/test_libraries.h
src/hooks/Makefile
src/hooks/dhcp/Makefile
src/hooks/dhcp/user_chk/Makefile
...
...
@@ -1685,6 +1699,8 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/dns/gen-rdatacode.py
src/lib/dns/tests/Makefile
src/lib/dns/tests/testdata/Makefile
src/lib/eval/Makefile
src/lib/eval/tests/Makefile
src/lib/exceptions/Makefile
src/lib/exceptions/tests/Makefile
src/lib/hooks/Makefile
...
...
@@ -1710,10 +1726,10 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/process/spec_config.h.pre
src/lib/process/tests/Makefile
src/lib/process/testutils/Makefile
src/lib/testutils/Makefile
src/lib/testutils/dhcp_test_lib.sh
src/lib/stats/Makefile
src/lib/stats/tests/Makefile
src/lib/testutils/Makefile
src/lib/testutils/dhcp_test_lib.sh
src/lib/util/Makefile
src/lib/util/io/Makefile
src/lib/util/python/Makefile
...
...
@@ -1723,11 +1739,10 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/util/threads/Makefile
src/lib/util/threads/tests/Makefile
src/lib/util/unittests/Makefile
src/lib/eval/Makefile
src/lib/eval/tests/Makefile
src/share/Makefile
src/share/database/Makefile
src/share/database/scripts/Makefile
src/share/database/scripts/cql/Makefile
src/share/database/scripts/mysql/Makefile
src/share/database/scripts/mysql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/mysql/upgrade_2.0_to_3.0.sh
...
...
@@ -1737,17 +1752,16 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/share/database/scripts/pgsql/Makefile
src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
src/share/database/scripts/cql/Makefile
tools/Makefile
tools/path_replacer.sh
])
AC_CONFIG_COMMANDS([permissions], [
AC_CONFIG_COMMANDS([permissions], [
chmod +x src/bin/admin/kea-admin
chmod +x src/bin/dhcp4/tests/dhcp4_process_tests.sh
chmod +x src/bin/dhcp6/tests/dhcp6_process_tests.sh
chmod +x src/bin/keactrl/keactrl
chmod +x src/bin/keactrl/tests/keactrl_tests.sh
chmod +x src/bin/admin/kea-admin
chmod +x src/lib/dns/gen-rdatacode.py
chmod +x src/lib/log/tests/console_test.sh
chmod +x src/lib/log/tests/destination_test.sh
...
...
src/bin/dhcp4/dhcp4to6_ipc.cc
View file @
7eef7d97
// Copyright (C) 2015-201
6
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-201
7
Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
...
...
@@ -35,7 +35,7 @@ Dhcp4to6Ipc& Dhcp4to6Ipc::instance() {
}
void
Dhcp4to6Ipc
::
open
()
{
uint
32
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
uint
16
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
if
(
port
==
0
)
{
Dhcp4o6IpcBase
::
close
();
return
;
...
...
@@ -45,8 +45,7 @@ void Dhcp4to6Ipc::open() {
}
int
old_fd
=
socket_fd_
;
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
static_cast
<
uint16_t
>
(
port
),
ENDPOINT_TYPE_V4
);
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
port
,
ENDPOINT_TYPE_V4
);
if
((
old_fd
==
-
1
)
&&
(
socket_fd_
!=
old_fd
))
{
IfaceMgr
::
instance
().
addExternalSocket
(
socket_fd_
,
Dhcp4to6Ipc
::
handler
);
...
...
src/bin/dhcp4/json_config_parser.cc
View file @
7eef7d97
...
...
@@ -341,24 +341,9 @@ public:
cfg
->
setDeclinePeriod
(
probation_period
);
// Set the DHCPv4-over-DHCPv6 interserver port.
// @todo Change for uint16_t
uint32_t
dhcp4o6_port
=
getUint32
(
global
,
"dhcp4o6-port"
);
uint16_t
dhcp4o6_port
=
getUint16
(
global
,
"dhcp4o6-port"
);
cfg
->
setDhcp4o6Port
(
dhcp4o6_port
);
}
private:
/// @brief Returns a value converted to uint32_t
///
/// Instantiation of getIntType() to uint32_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return an uint32_t value
uint32_t
getUint32
(
isc
::
data
::
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint32_t
>
(
scope
,
name
));
}
};
}
// anonymous namespace
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
7eef7d97
...
...
@@ -4557,14 +4557,6 @@ TEST_F(Dhcp4ParserTest, invalidClientClassDictionary) {
" } ]
\n
"
"}
\n
"
;
ConstElementPtr
json
;
ASSERT_NO_THROW
(
json
=
parseJSON
(
config
));
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
1
);
EXPECT_THROW
(
parseDHCP4
(
config
),
Dhcp4ParseError
);
}
...
...
src/bin/dhcp6/dhcp6to4_ipc.cc
View file @
7eef7d97
// Copyright (C) 2015-201
6
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-201
7
Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
...
...
@@ -34,7 +34,7 @@ Dhcp6to4Ipc& Dhcp6to4Ipc::instance() {
}
void
Dhcp6to4Ipc
::
open
()
{
uint
32
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
uint
16
_t
port
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getDhcp4o6Port
();
if
(
port
==
0
)
{
Dhcp4o6IpcBase
::
close
();
return
;
...
...
@@ -44,8 +44,7 @@ void Dhcp6to4Ipc::open() {
}
int
old_fd
=
socket_fd_
;
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
static_cast
<
uint16_t
>
(
port
),
ENDPOINT_TYPE_V6
);
socket_fd_
=
Dhcp4o6IpcBase
::
open
(
port
,
ENDPOINT_TYPE_V6
);
if
((
old_fd
==
-
1
)
&&
(
socket_fd_
!=
old_fd
))
{
IfaceMgr
::
instance
().
addExternalSocket
(
socket_fd_
,
Dhcp6to4Ipc
::
handler
);
...
...
src/bin/dhcp6/json_config_parser.cc
View file @
7eef7d97
...
...
@@ -214,18 +214,6 @@ public:
private:
/// @brief Get an uint8_t value
///
/// Instantiation of getIntType() to uint8_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return uint8_t value
/// @throw isc::dhcp::DhcpConfigError when it is not an uint8_t
uint8_t
getUint8
(
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint8_t
>
(
scope
,
name
));
}
/// Pointer to the created pool object.
isc
::
dhcp
::
Pool6Ptr
pool_
;
...
...
@@ -547,24 +535,9 @@ public:
srv_config
->
setDeclinePeriod
(
probation_period
);
// Set the DHCPv4-over-DHCPv6 interserver port.
// @todo Change for uint16_t
uint32_t
dhcp4o6_port
=
getUint32
(
global
,
"dhcp4o6-port"
);
uint16_t
dhcp4o6_port
=
getUint16
(
global
,
"dhcp4o6-port"
);
srv_config
->
setDhcp4o6Port
(
dhcp4o6_port
);
}
private:
/// @brief Returns a value converted to uint32_t
///
/// Instantiation of getIntType() to uint32_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return an uint32_t value
uint32_t
getUint32
(
isc
::
data
::
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint32_t
>
(
scope
,
name
));
}
};
}
// anonymous namespace
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
7eef7d97
...
...
@@ -4969,13 +4969,6 @@ TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
" } ]
\n
"
"}
\n
"
;
ConstElementPtr
json
=
parseJSON
(
config
);
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
1
);
EXPECT_THROW
(
parseDHCP6
(
config
),
Dhcp6ParseError
);
}
...
...
src/lib/cc/simple_parser.cc
View file @
7eef7d97
...
...
@@ -74,7 +74,7 @@ SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr p
}
ConstElementPtr
elem
=
parent
->
get
(
name
);
if
(
!
elem
)
{
return
(
data
::
Element
::
ZERO_POSITION
());
return
(
parent
->
getPosition
());
}
return
(
elem
->
getPosition
());
}
...
...
src/lib/cc/simple_parser.h
View file @
7eef7d97
...
...
@@ -104,9 +104,9 @@ class SimpleParser {
/// @brief Utility method that returns position of an element
///
/// It's mostly useful for logging.
When any necessary parameter is
///
missing (ei
the
r
parent
is null or it doesn't contain specified
///
name) ZERO_POSITION is returned
.
/// It's mostly useful for logging.
If the element is missing
/// the parent
position is returned or ZERO_POSITION if parent
///
is null
.
///
/// @param name position of that element will be returned
/// @param parent parent element (optional)
...
...
@@ -203,6 +203,44 @@ protected:
<<
"' ("
<<
getPosition
(
name
,
scope
)
<<
")"
);
}
}
/// @brief Returns a value converted to uint32_t
///
/// Instantiation of getIntType() to uint32_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return an uint32_t value
/// @throw isc::dhcp::DhcpConfigError when it is not an uint32_t
uint32_t
getUint32
(
isc
::
data
::
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint32_t
>
(
scope
,
name
));
}
/// @brief Returns a value converted to uint16_t
///
/// Instantiation of getIntType() to uint16_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return an uint16_t value
/// @throw isc::dhcp::DhcpConfigError when it is not an uint16_t
uint16_t
getUint16
(
isc
::
data
::
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint16_t
>
(
scope
,
name
));
}
/// @brief Get an uint8_t value
///
/// Instantiation of getIntType() to uint8_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter
/// @return uint8_t value
/// @throw isc::dhcp::DhcpConfigError when it is not an uint8_t
uint8_t
getUint8
(
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint8_t
>
(
scope
,
name
));
}
};
};
...
...
src/lib/cc/tests/simple_parser_unittest.cc
View file @
7eef7d97
...
...
@@ -58,14 +58,9 @@ public:
class
SimpleParserClassTest
:
public
SimpleParser
{
public:
/// @brief Instantiation of getIntType for uint8_t
///
/// @param scope specified parameter will be extracted from this scope
/// @param name name of the parameter for error report
/// @return an uint8_t value
uint8_t
getUint8
(
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getIntType
<
uint8_t
>
(
scope
,
name
));
}
/// Make getUint8 public
using
SimpleParser
::
getUint8
;
/// @brief Instantiation of getAndConvert
///
...
...
src/lib/dhcpsrv/parsers/client_class_def_parser.cc
View file @
7eef7d97
...
...
@@ -62,86 +62,87 @@ void
ClientClassDefParser
::
parse
(
ClientClassDictionaryPtr
&
class_dictionary
,
ConstElementPtr
class_def_cfg
,
uint16_t
family
)
{
// name is now mandatory
std
::
string
name
=
getString
(
class_def_cfg
,
"name"
);
if
(
name
.
empty
())
{
isc_throw
(
DhcpConfigError
,
"not empty parameter 'name' is required "
<<
getPosition
(
"name"
,
class_def_cfg
)
<<
")"
);
}
try
{
std
::
string
name
;
std
::
string
next_server_txt
=
"0.0.0.0"
;
std
::
string
sname
;
std
::
string
filename
;
ExpressionPtr
match_expr
;
CfgOptionPtr
options
(
new
CfgOption
());
// Parse the elements that make up the client class definition.
BOOST_FOREACH
(
ConfigPair
param
,
class_def_cfg
->
mapValue
())
{
std
::
string
entry
(
param
.
first
);
ConstElementPtr
value
(
param
.
second
);
if
(
entry
==
"name"
)
{
name
=
value
->
stringValue
();
}
else
if
(
entry
==
"test"
)
{
ExpressionParser
parser
;
parser
.
parse
(
match_expr
,
value
,
family
);
}
else
if
(
entry
==
"option-data"
)
{
OptionDataListParser
opts_parser
(
family
);
opts_parser
.
parse
(
options
,
value
);
}
else
if
(
entry
==
"next-server"
)
{
next_server_txt
=
value
->
stringValue
();
}
else
if
(
entry
==
"server-hostname"
)
{
sname
=
value
->
stringValue
();
}
else
if
(
entry
==
"boot-file-name"
)
{
filename
=
value
->
stringValue
();
}
else
{
isc_throw
(
DhcpConfigError
,
"invalid parameter '"
<<
entry
<<
"' ("
<<
value
->
getPosition
()
<<
")"
);
}
}
// Parse matching expression
ExpressionPtr
match_expr
;
ConstElementPtr
test
=
class_def_cfg
->
get
(
"test"
);
if
(
test
)
{
ExpressionParser
parser
;
parser
.
parse
(
match_expr
,
test
,
family
);
}
// name is now mandatory
if
(
name
.
empty
())
{
isc_throw
(
DhcpConfigError
,
"not empty parameter 'name' is required"
);
}
// Parse option data
CfgOptionPtr
options
(
new
CfgOption
());
ConstElementPtr
option_data
=
class_def_cfg
->
get
(
"option-data"
);
if
(
option_data
)
{
OptionDataListParser
opts_parser
(
family
);
opts_parser
.
parse
(
options
,
option_data
);
}
// Let's parse the next-server field
IOAddress
next_server
(
"0.0.0.0"
);
// Let's try to parse the next-server field
IOAddress
next_server
(
"0.0.0.0"
);
if
(
class_def_cfg
->
contains
(
"next-server"
))
{
std
::
string
next_server_txt
=
getString
(
class_def_cfg
,
"next-server"
);
try
{
next_server
=
IOAddress
(
next_server_txt
);
}
catch
(
const
IOError
&
ex
)
{
isc_throw
(
DhcpConfigError
,
"Invalid next-server value specified: '"
<<
next_server_txt
);
isc_throw
(
DhcpConfigError
,
"Invalid next-server value specified: '"
<<
next_server_txt
<<
"' ("
<<
getPosition
(
"next-server"
,
class_def_cfg
)
<<
")"
);
}
if
(
next_server
.
getFamily
()
!=
AF_INET
)
{
isc_throw
(
DhcpConfigError
,
"Invalid next-server value: '"
<<
next_server_txt
<<
"', must be IPv4 address"
);
<<
next_server_txt
<<
"', must be IPv4 address ("
<<
getPosition
(
"next-server"
,
class_def_cfg
)
<<
")"
);
}
if
(
next_server
.
isV4Bcast
())
{
isc_throw
(
DhcpConfigError
,
"Invalid next-server value: '"
<<
next_server_txt
<<
"', must not be a broadcast"
);
<<
next_server_txt
<<
"', must not be a broadcast ("
<<
getPosition
(
"next-server"
,
class_def_cfg
)
<<
")"
);
}
}
// Let's try to parse server-hostname
std
::
string
sname
;
if
(
class_def_cfg
->
contains
(
"server-hostname"
))
{
sname
=
getString
(
class_def_cfg
,
"server-hostname"
);
// Let's try to parse server-hostname
if
(
sname
.
length
()
>=
Pkt4
::
MAX_SNAME_LEN
)
{
isc_throw
(
DhcpConfigError
,
"server-hostname must be at most "
<<
Pkt4
::
MAX_SNAME_LEN
-
1
<<
" bytes long, it is "
<<
sname
.
length
());
<<
sname
.
length
()
<<
" ("
<<
getPosition
(
"server-hostname"
,
class_def_cfg
)
<<
")"
);
}
}
// Let's try to parse boot-file-name
std
::
string
filename
;
if
(
class_def_cfg
->
contains
(
"boot-file-name"
))
{
filename
=
getString
(
class_def_cfg
,
"boot-file-name"
);
// Let's try to parse boot-file-name
if
(
filename
.
length
()
>
Pkt4
::
MAX_FILE_LEN
)
{
isc_throw
(
DhcpConfigError
,
"boot-file-name must be at most "
<<
Pkt4
::
MAX_FILE_LEN
-
1
<<
" bytes long, it is "
<<
filename
.
length
());
<<
filename
.
length
()
<<
" ("
<<
getPosition
(
"boot-file-name"
,
class_def_cfg
)
<<
")"
);
}
// Add the client class definition
}
// Add the client class definition
try
{
class_dictionary
->
addClass
(
name
,
match_expr
,
options
,
next_server
,
sname
,
filename
);
}
catch
(
const
std
::
exception
&
ex
)
{
...
...
src/lib/dhcpsrv/parsers/dbaccess_parser.h
View file @
7eef7d97
...
...
@@ -43,7 +43,7 @@ public:
/// @brief Constructor
///
/// @param db_type Specifies database type (lease or hosts)
DbAccessParser
(
DBType
db_type
);
explicit
DbAccessParser
(
DBType
db_type
);
/// The destructor.
virtual
~
DbAccessParser
()
...
...
src/lib/dhcpsrv/parsers/dhcp_parsers.cc
View file @
7eef7d97
...
...
@@ -295,10 +295,7 @@ OptionDataParser::extractSpace(ConstElementPtr parent) const {
}
}
catch
(
std
::
exception
&
ex
)
{
// Append position of the option space parameter. Note, that in the case
// when 'space' was not specified a default value will be used and we
// should never get here. Therefore, it is ok to call getPosition for
// the space parameter here as this parameter will always be specified.
// Append position of the option space parameter.
isc_throw
(
DhcpConfigError
,
ex
.
what
()
<<
" ("
<<
getPosition
(
"space"
,
parent
)
<<
")"
);
}
...
...
@@ -600,57 +597,31 @@ RelayInfoParser::RelayInfoParser(const Option::Universe& family)
:
family_
(
family
)
{
};
// Can't use a constructor as a function
namespace
{
IOAddress
buildIOAddress
(
const
std
::
string
&
str
)
{
return
(
IOAddress
(
str
));
}
};
IOAddress
RelayInfoParser
::
getIOAddress
(
ConstElementPtr
scope
,
const
std
::
string
&
name
)
{
return
(
getAndConvert
<
IOAddress
,
buildIOAddress
>
(
scope
,
name
,
"address"
));
}
void
RelayInfoParser
::
parse
(
const
isc
::
dhcp
::
Subnet
::
RelayInfoPtr
&
cfg
,
ConstElementPtr
relay_info
)
{
// Let's start with some sanity checks.
if
(
!
relay_info
||
!
cfg
)
{
isc_throw
(
DhcpConfigError
,
"Logic error: RelayInfoParser::parse() called "
"with at least one NULL parameter."
);
}
if
(
relay_info
->
getType
()
!=
Element
::
map
)
{
isc_throw
(
DhcpConfigError
,
"Configuration error: RelayInfoParser::parse() "
"called with non-map parameter"
);
}
// Now create the default value.
isc
::
asiolink
::
IOAddress
ip
(
family_
==
Option
::
V4
?
IOAddress
::
IPV4_ZERO_ADDRESS
()
:
IOAddress
::
IPV6_ZERO_ADDRESS
());
// Now iterate over all parameters. Currently there's only one supported
// parameter, so it should be an easy thing to check.
bool
ip_address_specified
=
false
;
BOOST_FOREACH
(
ConfigPair
param
,
relay_info
->
mapValue
())
{
if
(
param
.
first
==
"ip-address"
)
{
ip_address_specified
=
true
;
try
{
ip
=
asiolink
::
IOAddress
(
param
.
second
->
stringValue
());
}
catch
(...)
{
isc_throw
(
DhcpConfigError
,
"Failed to parse ip-address "
"value: "
<<
param
.
second
<<
" ("
<<
param
.
second
->
getPosition
()
<<
")"
);
}
// Check if the address family matches.
if
(
(
ip
.
isV4
()
&&
family_
!=
Option
::
V4
)
||
(
ip
.
isV6
()
&&
family_
!=
Option
::
V6
)
)
{
isc_throw
(
DhcpConfigError
,
"ip-address field "
<<
ip
.
toText
()
<<
" does not have IP address of expected family type: "
<<
(
family_
==
Option
::
V4
?
"IPv4"
:
"IPv6"
)
<<
" ("
<<
param
.
second
->
getPosition
()
<<
")"
);
}
}
else
{
isc_throw
(
NotImplemented
,
"parser error: RelayInfoParser parameter not supported: "
<<
param
.
second
);
}
}
if
(
!
ip_address_specified
)
{
isc_throw
(
DhcpConfigError
,
"'relay' specified, but mandatory 'ip-address' "
"paramter in it is missing"
);
// There is only one parameter which is mandatory