2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-22 01:49:48 +00:00

[#1934] Kea now supports v6 DUIDs in v4 Client IDs

Adds support for extracting v6 DUIDs from v4
client identfiers per RFC 4361. This allows DDNS
for dual-stack clients to function. Thanks to
John Dickinson for contributing the patch.

Updated AUTHORS
Added ChangeLog

doc/sphinx/arm/ddns.rst
doc/sphinx/arm/dhcp4-srv.rst
    Updated doc

src/lib/dhcp_ddns/ncr_msg.cc
    D2Dhcid::fromClientId() - can now extract DUIDs stored
    per RFC 4361

src/lib/dhcp_ddns/tests/ncr_unittests.cc
    TEST_F(DhcidTest, fromClientIdDUID) - new test
This commit is contained in:
Thomas Markwalder 2021-11-29 13:25:49 -05:00
parent c6f5220df8
commit 0a66a532a9
6 changed files with 92 additions and 9 deletions

View File

@ -235,3 +235,8 @@ We have received the following contributions:
- Brad Smith
2021-08: compilation fix for upcoming boost 1.77
- John Dickinson
2021-11: Patch that adds support for v6 DUIDs to be embedded in v4 client
identifiers per RFC 4361. This allows Kea to support DDNS for
dual-stack clients per RFC 4703.

View File

@ -1,3 +1,11 @@
1971. [func] tmark,jad
Added support for embedded DHCPv6 DUIDs within DHCPv4
Client Identifier options per RFC 4361. This allows
Kea to support DDNS in dual stack environments per
RFC 4703(Sec 5.2). Thanks to John Dickinson for
contributing the patch!
(Gitlab #1934)
Kea 2.1.1 (development) released on Nov 24, 2021
1970. [build] razvan

View File

@ -79,7 +79,7 @@ the configuration parameter ``ddns-use-conflict-resolution``, supported
by both ``kea-dhcp4`` and ``kea-dhcp6``. These servers use this parameter to
set a flag within each NameChangeRequest they send that tells D2
whether conflict resolution should be employed for that request.
By default, conflict resolution is enabled. For more details, please refer
By default, conflict resolution is enabled. For more details, please refer
to discussions of ``ddns-use-conflict-resolution`` in :ref:`dhcp4-ddns-config` and :ref:`dhcp6-ddns-config`.
When conflict resolution is disabled, D2 still adds DHCID RRs but does
@ -97,9 +97,9 @@ issues that may arise with dual-stack clients. These are clients that
wish to have both IPv4 and IPv6 mappings for the same FQDN.
To work properly, clients must embed their IPv6 DUID
within their IPv4 client identifier option, as described in `RFC
4703 <https://tools.ietf.org/html/rfc4361>`__. In this way, DNS updates
for both IPv4 and IPv6 can be managed under the same DHCID RR. Kea does not
currently support this feature.
4361 <https://tools.ietf.org/html/rfc4361>`__. In this way, DNS updates
for both IPv4 and IPv6 can be managed under the same DHCID RR. This feature
is supported by Kea beginning with release 2.1.2.
.. _dhcp-ddns-server-start-stop:

View File

@ -3666,7 +3666,10 @@ ones are:
information stored in DHCPv4 and DHCPv6 servers for a particular
host. Using common identification information by the DHCPv4 and
DHCPv6 clients allows the network administrator to achieve this
correlation and better administer the network.
correlation and better administer the network. Beginning with
release 2.1.2, Kea supports DHCPv6 DUIDs embedded within DHCPv4
Client Identifier options as described in
`RFC 4361 <https://tools.ietf.org/html/rfc4361>`__.
DHCPv4 uses two distinct identifiers which are placed by the client in
the queries sent to the server and copied by the server to its responses

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2013-2021 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
@ -99,7 +99,32 @@ D2Dhcid::toStr() const {
void
D2Dhcid::fromClientId(const std::vector<uint8_t>& clientid_data,
const std::vector<uint8_t>& wire_fqdn) {
createDigest(DHCID_ID_CLIENTID, clientid_data, wire_fqdn);
// IPv4 Client ID containing a DUID looks like this in RFC4361
// Type IAID DUID
// +-----+----+----+----+----+----+----+---
// | 255 | i1 | i2 | i3 | i4 | d1 | d2 |...
// +-----+----+----+----+----+----+----+---
if (!clientid_data.empty() && clientid_data[0] == 255) {
if (clientid_data.size() <= 5) {
isc_throw(isc::dhcp_ddns::DhcidRdataComputeError,
"unable to compute DHCID from client identifier, embedded DUID "
"length of: " << clientid_data.size() << ", is too short");
}
// RFC3315 states that the DUID is a type code of 2 octets followed
// by no more then 128 octets. So add the 5 from above and make sure
// the length is not too long.
if (clientid_data.size() > 135) {
isc_throw(isc::dhcp_ddns::DhcidRdataComputeError,
"unable to compute DHCID from client identifier, embedded DUID "
"length of: " << clientid_data.size() << ", is too long");
}
std::vector<uint8_t>::const_iterator start = clientid_data.begin() + 5;
std::vector<uint8_t>::const_iterator end = clientid_data.end();
std::vector<uint8_t> duid(start, end);
createDigest(DHCID_ID_DUID, duid, wire_fqdn);
} else {
createDigest(DHCID_ID_CLIENTID, clientid_data, wire_fqdn);
}
}
void
@ -346,7 +371,7 @@ NameChangeRequest::fromJSON(const std::string& json) {
// For backward compatibility use-conflict-resolution is optional
// and defaults to true.
auto found = element_map.find("use-conflict-resolution");
auto found = element_map.find("use-conflict-resolution");
if (found != element_map.end()) {
ncr->setConflictResolution(found->second);
} else {

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2013-2021 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
@ -455,6 +455,48 @@ TEST_F(DhcidTest, fromClientId) {
}
// This test verifies that DHCID is properly computed from a buffer holding
// client identifier data that contains a DUID.
TEST_F(DhcidTest, fromClientIdDUID) {
D2Dhcid dhcid;
// Create a buffer holding client id..
uint8_t clientid_data[] = { 0xff, 0x5d, 0xe2, 0x6c, 0x15, 0x00, 0x02,
0x00, 0x00, 0xab, 0x11, 0x9a, 0x57, 0x20, 0x95, 0x71, 0x61, 0xbd, 0xd0 };
std::vector<uint8_t> clientid(clientid_data,
clientid_data + sizeof(clientid_data));
// Create DHCID.
ASSERT_NO_THROW(dhcid.fromClientId(clientid, wire_fqdn_));
// The reference DHCID (represented as string of hexadecimal digits)
std::string dhcid_ref = "000201A250D060B9352AE68E5014B78D25"
"1C30EFB0D5F64E48303B2BC56E6938F129E7";
// Make sure that the DHCID is valid.
EXPECT_EQ(dhcid_ref, dhcid.toStr());
// Make sure that a too long client identifier is not accepted.
clientid.resize(136);
EXPECT_THROW_MSG(dhcid.fromClientId(clientid, wire_fqdn_),
isc::dhcp_ddns::DhcidRdataComputeError,
"unable to compute DHCID from client identifier,"
" embedded DUID length of: 136, is too long");
// Make sure that a too short client identifier is not accepted.
clientid.resize(5);
EXPECT_THROW_MSG(dhcid.fromClientId(clientid, wire_fqdn_),
isc::dhcp_ddns::DhcidRdataComputeError,
"unable to compute DHCID from client identifier,"
" embedded DUID length of: 5, is too short");
// Make sure an empty client identifier is not accepted.
clientid.clear();
EXPECT_THROW_MSG(dhcid.fromClientId(clientid, wire_fqdn_),
isc::dhcp_ddns::DhcidRdataComputeError,
"empty DUID used to create DHCID");
}
// This test verifies that DHCID is properly computed from a HW address.
TEST_F(DhcidTest, fromHWAddr) {
D2Dhcid dhcid;