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
Sebastian Schrader
Kea
Commits
75b75c89
Commit
75b75c89
authored
Apr 17, 2015
by
Marcin Siodelski
Browse files
[master] Merge branch 'trac3699'
parents
18590933
18d3ee41
Changes
12
Hide whitespace changes
Inline
Side-by-side
doc/guide/logging.xml
View file @
75b75c89
...
...
@@ -170,6 +170,12 @@
during DHCPv4 hooks operation, i.e. anything related to user
libraries will be logged using this logger.
</simpara>
</listitem>
<listitem>
<simpara><command>
kea-dhcp4.hosts
</command>
- this logger is used
within the libdhcpsrv and it logs messages related to the management
of the DHCPv4 host reservations, i.e. retrieval of the resevations
and adding new reservations.
</simpara>
</listitem>
<listitem>
<simpara><command>
kea-dhcp6
</command>
- this is the root logger for
the DHCPv6 server. All components used by the DHCPv6 server inherit
...
...
@@ -192,6 +198,12 @@
during DHCPv6 hooks operation, i.e. anything related to user
libraries will be logged using this logger.
</simpara>
</listitem>
<listitem>
<simpara><command>
kea-dhcp6.hosts
</command>
- this logger is used
within the libdhcpsrv and it logs messages related to the management
of the DHCPv6 host reservations, i.e. retrieval of the resevations
and adding new reservations.
</simpara>
</listitem>
<listitem>
<simpara><command>
kea-dhcp-ddns
</command>
- this is the root logger for
the kea-dhcp-ddns deamon. All components used by this deamon inherit
...
...
src/lib/dhcpsrv/.gitignore
View file @
75b75c89
/dhcpsrv_messages.cc
/dhcpsrv_messages.h
/hosts_messages.cc
/hosts_messages.h
/s-messages
src/lib/dhcpsrv/Makefile.am
View file @
75b75c89
...
...
@@ -35,19 +35,22 @@ EXTRA_DIST += parsers/host_reservation_parser.h
EXTRA_DIST
+=
parsers/host_reservations_list_parser.h
# Define rule to build logging source files from message file
dhcpsrv_messages.h dhcpsrv_messages.cc
:
s-messages
dhcpsrv_messages.h dhcpsrv_messages.cc
hosts_messages.h hosts_messages.cc
:
s-messages
s-messages
:
dhcpsrv_messages.mes
s-messages
:
dhcpsrv_messages.mes
hosts_messages.mes
$(top_builddir)
/src/lib/log/compiler/message
$(top_srcdir)
/src/lib/dhcpsrv/dhcpsrv_messages.mes
touch
$@
$(top_builddir)
/src/lib/log/compiler/message
$(top_srcdir)
/src/lib/dhcpsrv/hosts_messages.mes
touch
$@
# Tell Automake that the dhcpsrv_messages.{cc,h} source files are created
in the
# build process, so it must create these before doing anything else.
Although
# they are a dependency of the library (so will be created from the message
file
# anyway), there is no guarantee as to exactly _when_ in the build they will be
# Tell Automake that the
{
dhcpsrv
,hosts}
_messages.{cc,h} source files are created
#
in the
build process, so it must create these before doing anything else.
#
Although
they are a dependency of the library (so will be created from the message
#
file
anyway), there is no guarantee as to exactly _when_ in the build they will be
# created. As the .h file is included in other sources file (so must be
# present when they are compiled), the safest option is to create it first.
BUILT_SOURCES
=
dhcpsrv_messages.h dhcpsrv_messages.cc
BUILT_SOURCES
+=
hosts_messages.h hosts_messages.cc
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
...
...
@@ -56,7 +59,8 @@ BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
AM_CXXFLAGS
+=
$(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
# Make sure the generated files are deleted in a "clean" operation
CLEANFILES
=
*
.gcno
*
.gcda dhcpsrv_messages.h dhcpsrv_messages.cc s-messages
CLEANFILES
=
*
.gcno
*
.gcda dhcpsrv_messages.h dhcpsrv_messages.cc
CLEANFILES
+=
hosts_messages.h hosts_messages.cc s-messages
# Remove CSV files created by the CSVLeaseFile6 and CSVLeaseFile4 unit tests.
CLEANFILES
+=
*
.csv
...
...
@@ -84,6 +88,7 @@ libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES
+=
host.cc host.h
libkea_dhcpsrv_la_SOURCES
+=
host_container.h
libkea_dhcpsrv_la_SOURCES
+=
host_mgr.cc host_mgr.h
libkea_dhcpsrv_la_SOURCES
+=
hosts_log.cc hosts_log.h
libkea_dhcpsrv_la_SOURCES
+=
key_from_key.h
libkea_dhcpsrv_la_SOURCES
+=
lease.cc lease.h
libkea_dhcpsrv_la_SOURCES
+=
lease_file_loader.h
...
...
@@ -125,6 +130,7 @@ libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.h
nodist_libkea_dhcpsrv_la_SOURCES
=
dhcpsrv_messages.h dhcpsrv_messages.cc
nodist_libkea_dhcpsrv_la_SOURCES
+=
hosts_messages.h hosts_messages.cc
libkea_dhcpsrv_la_CXXFLAGS
=
$(AM_CXXFLAGS)
libkea_dhcpsrv_la_CPPFLAGS
=
$(AM_CPPFLAGS)
$(LOG4CPLUS_INCLUDES)
...
...
@@ -154,6 +160,7 @@ endif
# The message file should be in the distribution
EXTRA_DIST
+=
dhcpsrv_messages.mes
EXTRA_DIST
+=
hosts_messages.mes
# Distribute backend documentation
# Database schema creation script moved to src/bin/admin
...
...
src/lib/dhcpsrv/cfg_hosts.cc
View file @
75b75c89
...
...
@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/cfg_hosts.h>
#include <dhcpsrv/hosts_log.h>
#include <exceptions/exceptions.h>
#include <ostream>
...
...
@@ -23,6 +24,8 @@ namespace dhcp {
ConstHostCollection
CfgHosts
::
getAll
(
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
)
const
{
// Do not issue logging message here because it will be logged by
// the getAllInternal method.
ConstHostCollection
collection
;
getAllInternal
<
ConstHostCollection
>
(
hwaddr
,
duid
,
collection
);
return
(
collection
);
...
...
@@ -30,6 +33,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
HostCollection
CfgHosts
::
getAll
(
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
)
{
// Do not issue logging message here because it will be logged by
// the getAllInternal method.
HostCollection
collection
;
getAllInternal
<
HostCollection
>
(
hwaddr
,
duid
,
collection
);
return
(
collection
);
...
...
@@ -37,6 +42,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) {
ConstHostCollection
CfgHosts
::
getAll4
(
const
IOAddress
&
address
)
const
{
// Do not issue logging message here because it will be logged by
// the getAllInternal4 method.
ConstHostCollection
collection
;
getAllInternal4
<
ConstHostCollection
>
(
address
,
collection
);
return
(
collection
);
...
...
@@ -44,6 +51,8 @@ CfgHosts::getAll4(const IOAddress& address) const {
HostCollection
CfgHosts
::
getAll4
(
const
IOAddress
&
address
)
{
// Do not issue logging message here because it will be logged by
// the getAllInternal4 method.
HostCollection
collection
;
getAllInternal4
<
HostCollection
>
(
address
,
collection
);
return
(
collection
);
...
...
@@ -51,6 +60,8 @@ CfgHosts::getAll4(const IOAddress& address) {
ConstHostCollection
CfgHosts
::
getAll6
(
const
IOAddress
&
address
)
const
{
// Do not issue logging message here because it will be logged by
// the getAllInternal6 method.
ConstHostCollection
collection
;
getAllInternal6
<
ConstHostCollection
>
(
address
,
collection
);
return
(
collection
);
...
...
@@ -58,6 +69,8 @@ CfgHosts::getAll6(const IOAddress& address) const {
HostCollection
CfgHosts
::
getAll6
(
const
IOAddress
&
address
)
{
// Do not issue logging message here because it will be logged by
// the getAllInternal6 method.
HostCollection
collection
;
getAllInternal6
<
HostCollection
>
(
address
,
collection
);
return
(
collection
);
...
...
@@ -68,6 +81,35 @@ void
CfgHosts
::
getAllInternal
(
const
std
::
vector
<
uint8_t
>&
identifier
,
const
Host
::
IdentifierType
&
identifier_type
,
Storage
&
storage
)
const
{
// We will need to transform the identifier into the textual format.
// Until we do it, we mark it as invalid.
std
::
string
identifier_text
=
"(invalid)"
;
if
(
!
identifier
.
empty
())
{
try
{
// Use Host object to find the textual form of the identifier.
// This may throw exception if the identifier is invalid.
Host
host
(
&
identifier
[
0
],
identifier
.
size
(),
identifier_type
,
SubnetID
(
0
),
SubnetID
(
0
),
IOAddress
::
IPV4_ZERO_ADDRESS
());
identifier_text
=
host
.
getIdentifierAsText
();
}
catch
(...)
{
// Suppress exception and keep using (invalid) as an
// identifier. We will log that the identifier is
// invalid and return.
}
}
// This will log that we're invoking this function with the specified
// identifier. The identifier may also be marked as (invalid) if it
// had 0 length or its type is unsupported.
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ALL_IDENTIFIER
)
.
arg
(
identifier_text
);
// Do nothing if the identifier specified is invalid.
if
(
identifier_text
==
"(invalid)"
)
{
return
;
}
// Use the identifier and identifier type as a composite key.
const
HostContainerIndex0
&
idx
=
hosts_
.
get
<
0
>
();
boost
::
tuple
<
const
std
::
vector
<
uint8_t
>
,
const
Host
::
IdentifierType
>
t
=
...
...
@@ -76,14 +118,27 @@ CfgHosts::getAllInternal(const std::vector<uint8_t>& identifier,
// Append each Host object to the storage.
for
(
HostContainerIndex0
::
iterator
host
=
idx
.
lower_bound
(
t
);
host
!=
idx
.
upper_bound
(
t
);
++
host
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE_DETAIL_DATA
,
HOSTS_CFG_GET_ALL_IDENTIFIER_HOST
)
.
arg
(
identifier_text
)
.
arg
((
*
host
)
->
toText
());
storage
.
push_back
(
*
host
);
}
// Log how many hosts have been found.
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ALL_IDENTIFIER_COUNT
)
.
arg
(
identifier_text
)
.
arg
(
storage
.
size
());
}
template
<
typename
Storage
>
void
CfgHosts
::
getAllInternal
(
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
,
Storage
&
storage
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ALL_HWADDR_DUID
)
.
arg
(
hwaddr
?
hwaddr
->
toText
()
:
"(no-hwaddr)"
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
);
// Get hosts using HW address.
if
(
hwaddr
)
{
getAllInternal
<
Storage
>
(
hwaddr
->
hwaddr_
,
Host
::
IDENT_HWADDR
,
storage
);
...
...
@@ -97,6 +152,9 @@ CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
template
<
typename
Storage
>
void
CfgHosts
::
getAllInternal4
(
const
IOAddress
&
address
,
Storage
&
storage
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ALL_ADDRESS4
)
.
arg
(
address
.
toText
());
// Must not specify address other than IPv4.
if
(
!
address
.
isV4
())
{
isc_throw
(
BadHostAddress
,
"must specify an IPv4 address when searching"
...
...
@@ -108,13 +166,24 @@ CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
// Append each Host object to the storage.
for
(
HostContainerIndex1
::
iterator
host
=
r
.
first
;
host
!=
r
.
second
;
++
host
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE_DETAIL_DATA
,
HOSTS_CFG_GET_ALL_ADDRESS4_HOST
)
.
arg
(
address
.
toText
())
.
arg
((
*
host
)
->
toText
());
storage
.
push_back
(
*
host
);
}
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ALL_ADDRESS4_COUNT
)
.
arg
(
address
.
toText
())
.
arg
(
storage
.
size
());
}
template
<
typename
Storage
>
void
CfgHosts
::
getAllInternal6
(
const
IOAddress
&
address
,
Storage
&
storage
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ALL_ADDRESS6
)
.
arg
(
address
.
toText
());
// Must not specify address other than IPv6.
if
(
!
address
.
isV6
())
{
isc_throw
(
BadHostAddress
,
"must specify an IPv6 address when searching"
...
...
@@ -126,14 +195,23 @@ CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const {
// Append each Host object to the storage.
for
(
HostContainerIndex1
::
iterator
host
=
r
.
first
;
host
!=
r
.
second
;
++
host
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE_DETAIL_DATA
,
HOSTS_CFG_GET_ALL_ADDRESS6_HOST
)
.
arg
(
address
.
toText
())
.
arg
((
*
host
)
->
toText
());
storage
.
push_back
(
*
host
);
}
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ALL_ADDRESS6_COUNT
)
.
arg
(
address
.
toText
())
.
arg
(
storage
.
size
());
}
ConstHostPtr
CfgHosts
::
get4
(
const
SubnetID
&
subnet_id
,
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
)
const
{
// Do not log here because getHostInternal logs.
// The false value indicates that it is an IPv4 subnet.
return
(
getHostInternal
(
subnet_id
,
false
,
hwaddr
,
duid
));
}
...
...
@@ -141,19 +219,31 @@ CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
HostPtr
CfgHosts
::
get4
(
const
SubnetID
&
subnet_id
,
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
)
{
// Do not log here because getHostInternal logs.
// The false value indicates that it is an IPv4 subnet.
return
(
getHostInternal
(
subnet_id
,
false
,
hwaddr
,
duid
));
}
ConstHostPtr
CfgHosts
::
get4
(
const
SubnetID
&
subnet_id
,
const
IOAddress
&
address
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4
)
.
arg
(
subnet_id
).
arg
(
address
.
toText
());
ConstHostCollection
hosts
=
getAll4
(
address
);
for
(
ConstHostCollection
::
const_iterator
host
=
hosts
.
begin
();
host
!=
hosts
.
end
();
++
host
)
{
if
((
*
host
)
->
getIPv4SubnetID
()
==
subnet_id
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4_HOST
)
.
arg
(
subnet_id
)
.
arg
(
address
.
toText
())
.
arg
((
*
host
)
->
toText
());
return
(
*
host
);
}
}
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4_NULL
)
.
arg
(
subnet_id
).
arg
(
address
.
toText
());
return
(
ConstHostPtr
());
}
...
...
@@ -161,6 +251,7 @@ CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
ConstHostPtr
CfgHosts
::
get6
(
const
SubnetID
&
subnet_id
,
const
DuidPtr
&
duid
,
const
HWAddrPtr
&
hwaddr
)
const
{
// Do not log here because getHostInternal logs.
// The true value indicates that it is an IPv6 subnet.
return
(
getHostInternal
(
subnet_id
,
true
,
hwaddr
,
duid
));
}
...
...
@@ -168,6 +259,7 @@ CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
HostPtr
CfgHosts
::
get6
(
const
SubnetID
&
subnet_id
,
const
DuidPtr
&
duid
,
const
HWAddrPtr
&
hwaddr
)
{
// Do not log here because getHostInternal logs.
// The true value indicates that it is an IPv6 subnet.
return
(
getHostInternal
(
subnet_id
,
true
,
hwaddr
,
duid
));
}
...
...
@@ -186,20 +278,49 @@ CfgHosts::get6(const IOAddress&, const uint8_t) {
ConstHostPtr
CfgHosts
::
get6
(
const
SubnetID
&
subnet_id
,
const
asiolink
::
IOAddress
&
address
)
const
{
ConstHostCollection
storage
;
getAllInternal6
(
subnet_id
,
address
,
storage
);
// Do not log here because getHostInternal6 logs.
return
(
getHostInternal6
<
ConstHostPtr
,
ConstHostCollection
>
(
subnet_id
,
address
));
}
HostPtr
CfgHosts
::
get6
(
const
SubnetID
&
subnet_id
,
const
asiolink
::
IOAddress
&
address
)
{
// Do not log here because getHostInternal6 logs.
return
(
getHostInternal6
<
HostPtr
,
HostCollection
>
(
subnet_id
,
address
));
}
template
<
typename
ReturnType
,
typename
Storage
>
ReturnType
CfgHosts
::
getHostInternal6
(
const
SubnetID
&
subnet_id
,
const
asiolink
::
IOAddress
&
address
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6
)
.
arg
(
subnet_id
).
arg
(
address
.
toText
());
Storage
storage
;
getAllInternal6
<
Storage
>
(
subnet_id
,
address
,
storage
);
switch
(
storage
.
size
())
{
case
0
:
return
(
ConstHostPtr
());
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6_NULL
)
.
arg
(
subnet_id
)
.
arg
(
address
.
toText
());
return
(
HostPtr
());
case
1
:
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6_HOST
)
.
arg
(
subnet_id
)
.
arg
(
address
.
toText
())
.
arg
((
*
storage
.
begin
())
->
toText
());
return
(
*
storage
.
begin
());
default:
isc_throw
(
DuplicateHost
,
"more than one reservation found"
" for the host belonging to the subnet with id '"
<<
subnet_id
<<
"' and using the address '"
<<
address
.
toText
()
<<
"'"
);
}
}
template
<
typename
Storage
>
...
...
@@ -207,6 +328,9 @@ void
CfgHosts
::
getAllInternal6
(
const
SubnetID
&
subnet_id
,
const
asiolink
::
IOAddress
&
address
,
Storage
&
storage
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6
)
.
arg
(
subnet_id
).
arg
(
address
.
toText
());
// Must not specify address other than IPv6.
if
(
!
address
.
isV6
())
{
isc_throw
(
BadHostAddress
,
"must specify an IPv6 address when searching"
...
...
@@ -223,30 +347,30 @@ CfgHosts::getAllInternal6(const SubnetID& subnet_id,
// multiple addresses reserved, but for each (address, subnet_id) there should
// be at most one host reserving it).
for
(
HostContainer6Index1
::
iterator
resrv
=
r
.
first
;
resrv
!=
r
.
second
;
++
resrv
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE_DETAIL_DATA
,
HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6_HOST
)
.
arg
(
subnet_id
)
.
arg
(
address
.
toText
())
.
arg
(
resrv
->
host_
);
storage
.
push_back
(
resrv
->
host_
);
}
}
HostPtr
CfgHosts
::
get6
(
const
SubnetID
&
subnet_id
,
const
asiolink
::
IOAddress
&
address
)
{
HostCollection
storage
;
getAllInternal6
<
HostCollection
>
(
subnet_id
,
address
,
storage
);
switch
(
storage
.
size
())
{
case
0
:
return
(
HostPtr
());
case
1
:
return
(
*
storage
.
begin
());
default:
isc_throw
(
DuplicateHost
,
"more than one reservation found"
" for the host belonging to the subnet with id '"
<<
subnet_id
<<
"' and using the address '"
<<
address
.
toText
()
<<
"'"
);
}
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6_COUNT
)
.
arg
(
subnet_id
)
.
arg
(
address
.
toText
())
.
arg
(
storage
.
size
());
}
HostPtr
CfgHosts
::
getHostInternal
(
const
SubnetID
&
subnet_id
,
const
bool
subnet6
,
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
)
const
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID
)
.
arg
(
subnet6
?
"IPv6"
:
"IPv4"
)
.
arg
(
subnet_id
)
.
arg
(
hwaddr
?
hwaddr
->
toText
()
:
"(no-hwaddr)"
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
);
// Get all hosts for the HW address and DUID. This may return multiple hosts
// for different subnets, but the number of hosts returned should be low
// because one host presumably doesn't show up in many subnets.
...
...
@@ -284,17 +408,38 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
}
}
}
if
(
host
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID
)
.
arg
(
subnet_id
)
.
arg
(
hwaddr
?
hwaddr
->
toText
()
:
"(no-hwaddr)"
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
)
.
arg
(
host
->
toText
());
}
else
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_RESULTS
,
HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID_NULL
)
.
arg
(
subnet_id
)
.
arg
(
hwaddr
?
hwaddr
->
toText
()
:
"(no-hwaddr)"
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
);
}
return
(
host
);
}
void
CfgHosts
::
add
(
const
HostPtr
&
host
)
{
LOG_DEBUG
(
hosts_logger
,
HOSTS_DBG_TRACE
,
HOSTS_CFG_ADD_HOST
)
.
arg
(
host
?
host
->
toText
()
:
"(no-host)"
);
// Sanity check that the host is non-null.
if
(
!
host
)
{
isc_throw
(
BadValue
,
"specified host object must not be NULL when it"
" is added to the configuration"
);
}
// At least one subnet ID must be non-zero
if
(
host
->
getIPv4SubnetID
()
==
0
&&
host
->
getIPv6SubnetID
()
==
0
)
{
isc_throw
(
BadValue
,
"must not use both IPv4 and IPv6 subnet ids of"
...
...
@@ -308,7 +453,6 @@ CfgHosts::add(const HostPtr& host) {
void
CfgHosts
::
add4
(
const
HostPtr
&
host
)
{
/// @todo This may need further sanity checks.
HWAddrPtr
hwaddr
=
host
->
getHWAddress
();
DuidPtr
duid
=
host
->
getDuid
();
...
...
@@ -316,7 +460,7 @@ CfgHosts::add4(const HostPtr& host) {
// There should be at least one resource reserved: hostname, IPv4
// address, IPv6 address or prefix.
if
(
host
->
getHostname
().
empty
()
&&
(
host
->
getIPv4Reservation
()
==
IOAddress
(
"0.0.0.0"
))
&&
(
host
->
getIPv4Reservation
()
.
isV4Zero
(
))
&&
(
!
host
->
hasIPv6Reservation
()))
{
std
::
ostringstream
s
;
if
(
hwaddr
)
{
...
...
@@ -357,7 +501,6 @@ CfgHosts::add4(const HostPtr& host) {
void
CfgHosts
::
add6
(
const
HostPtr
&
host
)
{
/// @todo This may need further sanity checks.
HWAddrPtr
hwaddr
=
host
->
getHWAddress
();
DuidPtr
duid
=
host
->
getDuid
();
...
...
src/lib/dhcpsrv/cfg_hosts.h
View file @
75b75c89
...
...
@@ -339,6 +339,23 @@ private:
const
HWAddrPtr
&
hwaddr
,
const
DuidPtr
&
duid
)
const
;
/// @brief Returns the @c Host object holding reservation for the IPv6
/// address and connected to the specific subnet.
///
/// This private method is called by the public @c get6 method variants.
///
/// @param subnet_id IPv6 subnet identifier.
/// @param address IPv6 address.
/// @tparam ReturnType One of @c HostPtr or @c ConstHostPtr
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
///
/// @return Pointer to the found host, or NULL if no host found.
/// @throw isc::dhcp::DuplicateHost if method found more than one matching
/// @c Host object.
template
<
typename
ReturnType
,
typename
Storage
>
ReturnType
getHostInternal6
(
const
SubnetID
&
subnet_id
,
const
asiolink
::
IOAddress
&
adddress
)
const
;
/// @brief Adds a new host to the v4 collection.
///
/// This is an internal method called by public @ref add.
...
...
src/lib/dhcpsrv/host.cc
View file @
75b75c89
...
...
@@ -138,6 +138,24 @@ Host::getIdentifierType() const {
return
(
IDENT_DUID
);
}
std
::
string
Host
::
getIdentifierAsText
()
const
{
std
::
string
txt
;
if
(
hw_address_
)
{
txt
=
"hwaddr="
+
hw_address_
->
toText
(
false
);
}
else
{
txt
=
"duid="
;
if
(
duid_
)
{
txt
+=
duid_
->
toText
();
}
else
{
txt
+=
"(none)"
;
}
}
return
(
txt
);
}
void
Host
::
setIdentifier
(
const
uint8_t
*
identifier
,
const
size_t
len
,
const
IdentifierType
&
type
)
{
...
...
@@ -252,20 +270,59 @@ Host::addClientClassInternal(ClientClasses& classes,
}
std
::
string
Host
::
getIdentifierAsText
()
const
{
std
::
string
txt
;
if
(
hw_address_
)
{
txt
=
"hwaddr="
+
hw_address_
->
toText
(
false
);
Host
::
toText
()
const
{
std
::
ostringstream
s
;
// Add HW address or DUID.
s
<<
getIdentifierAsText
();
// Add IPv4 subnet id if exists (non-zero).
if
(
ipv4_subnet_id_
)
{
s
<<
" ipv4_subnet_id="
<<
ipv4_subnet_id_
;
}
// Add IPv6 subnet id if exists (non-zero).
if
(
ipv6_subnet_id_
)
{
s
<<
" ipv6_subnet_id="
<<
ipv6_subnet_id_
;
}
// Add hostname.
s
<<
" hostname="
<<
(
hostname_
.
empty
()
?
"(empty)"
:
hostname_
);
// Add IPv4 reservation.
s
<<
" ipv4_reservation="
<<
(
ipv4_reservation_
.
isV4Zero
()
?
"(no)"
:
ipv4_reservation_
.
toText
());
if
(
ipv6_reservations_
.
empty
())
{
s
<<
" ipv6_reservations=(none)"
;
}
else
{
txt
=
"duid="
;
if
(
duid_
)
{
txt
+=
duid_
->
toText
();
}
else
{
txt
+=
"(none)"
;
// Add all IPv6 reservations.
for
(
IPv6ResrvIterator
resrv
=
ipv6_reservations_
.
begin
();
resrv
!=
ipv6_reservations_
.
end
();
++
resrv
)
{
s
<<
" ipv6_reservation"
<<
std
::
distance
(
ipv6_reservations_
.
begin
(),
resrv
)
<<
"="
<<
resrv
->
second
.
toText
();
}
}
return
(
txt
);
// Add DHCPv4 client classes.
for
(
ClientClasses
::
const_iterator
cclass
=
dhcp4_client_classes_
.
begin
();
cclass
!=
dhcp4_client_classes_
.
end
();
++
cclass
)
{
s
<<
" dhcp4_class"
<<
std
::
distance
(
dhcp4_client_classes_
.
begin
(),
cclass
)
<<
"="
<<
*
cclass
;
}
// Add DHCPv6 client classes.
for
(
ClientClasses
::
const_iterator
cclass
=
dhcp6_client_classes_
.
begin
();
cclass
!=
dhcp6_client_classes_
.
end
();
++
cclass
)
{
s
<<
" dhcp6_class"
<<
std
::
distance
(
dhcp6_client_classes_
.
begin
(),
cclass
)
<<
"="
<<
*
cclass
;
}
return
(
s
.
str
());
}
}
// end of namespace isc::dhcp
...
...
src/lib/dhcpsrv/host.h
View file @
75b75c89
...
...
@@ -417,6 +417,9 @@ public:
return
(
dhcp6_client_classes_
);
}
/// @brief Returns information about the host in the textual format.
std
::
string
toText
()
const
;
private:
/// @brief Adds new client class for DHCPv4 or DHCPv6.
...
...
src/lib/dhcpsrv/host_mgr.cc
View file @
75b75c89
...
...
@@ -15,6 +15,7 @@
#include <dhcpsrv/cfg_hosts.h>