Kea: ncr_generator.cc Source File

| Kea 3.2.0-git

ncr_generator.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcp/option_data_types.h>
10#include <dhcpsrv/cfgmgr.h>
11#include <dhcpsrv/dhcpsrv_log.h>
12#include <dhcpsrv/d2_client_mgr.h>
13#include <dhcpsrv/ncr_generator.h>
14#include <stdint.h>
15#include <vector>
16#include <util/str.h>
17
18using namespace isc;
19using namespace isc::dhcp;
20using namespace isc::dhcp_ddns;
21
22namespace {
23
39template<typename LeasePtrType, typename IdentifierType>
40void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
41 const IdentifierType& identifier, const std::string& label,
42 const ConstSubnetPtr subnet) {
43 // Check if there is a need for update.
44 if (lease->hostname_.empty() || (!lease->fqdn_fwd_ && !lease->fqdn_rev_)
45 || !CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
46 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
47 DHCPSRV_QUEUE_NCR_SKIP)
48 .arg(label)
49 .arg(lease->addr_.toText());
50
51 return;
52 }
53
54 ConflictResolutionMode conflict_resolution_mode = CHECK_WITH_DHCID;
55 util::Optional<double> ddns_ttl_percent;
56 util::Optional<uint32_t> ddns_ttl;
57 util::Optional<uint32_t> ddns_ttl_min;
58 util::Optional<uint32_t> ddns_ttl_max;
59 if (subnet) {
60 // Create a DdnsParams so we have access to pool scope values.
61 DdnsParams ddns_params(subnet, true);
62 static_cast<void>(ddns_params.setPoolFromAddress(lease->addr_));
63
64 auto mode = ddns_params.getConflictResolutionMode();
65 if (!mode.empty()) {
66 conflict_resolution_mode = StringToConflictResolutionMode(mode);
67 }
68
69 ddns_ttl_percent = ddns_params.getTtlPercent();
70 ddns_ttl = ddns_params.getTtl();
71 ddns_ttl_min = ddns_params.getTtlMin();
72 ddns_ttl_max = ddns_params.getTtlMax();
73 }
74
75 try {
76 // Create DHCID
77 std::vector<uint8_t> hostname_wire;
78 OptionDataTypeUtil::writeFqdn(lease->hostname_, hostname_wire, true);
79 D2Dhcid dhcid = D2Dhcid(identifier, hostname_wire);
80
81 // Calculate the TTL based on lease life time.
82 uint32_t ttl = calculateDdnsTtl(lease->valid_lft_,
83 ddns_ttl_percent, ddns_ttl,
84 ddns_ttl_min, ddns_ttl_max);
85
86 // Create name change request.
87 NameChangeRequestPtr ncr
88 (new NameChangeRequest(chg_type, lease->fqdn_fwd_, lease->fqdn_rev_,
89 lease->hostname_, lease->addr_.toText(),
90 dhcid, ttl, conflict_resolution_mode));
91
92 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA, DHCPSRV_QUEUE_NCR)
93 .arg(label)
94 .arg(chg_type == CHG_ADD ? "add" : "remove")
95 .arg(ncr->toText());
96
97 // Send name change request.
98 CfgMgr::instance().getD2ClientMgr().sendRequest(ncr);
99
100 } catch (const std::exception& ex) {
101 LOG_ERROR(dhcpsrv_logger, DHCPSRV_QUEUE_NCR_FAILED)
102 .arg(label)
103 .arg(chg_type == CHG_ADD ? "add" : "remove")
104 .arg(lease->addr_.toText())
105 .arg(ex.what());
106 }
107}
108
109} // end of anonymous namespace
110
111namespace isc {
112namespace dhcp {
113
114 void queueNCR(const NameChangeType& chg_type, const Lease4Ptr& lease) {
115 if (lease) {
116 // Figure out from the lease's subnet if we should use conflict resolution.
117 // If there's no subnet, something hinky is going on so we'll set it true.
118 ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()
119 ->getCfgSubnets4()->getSubnet(lease->subnet_id_);
120
121 // Client id takes precedence over HW address.
122 if (lease->client_id_) {
123 queueNCRCommon(chg_type, lease, lease->client_id_->getClientId(),
124 Pkt4::makeLabel(lease->hwaddr_, lease->client_id_), subnet);
125 } else {
126 // Client id is not specified for the lease. Use HW address
127 // instead.
128 queueNCRCommon(chg_type, lease, lease->hwaddr_,
129 Pkt4::makeLabel(lease->hwaddr_, lease->client_id_), subnet);
130 }
131 }
132}
133
134 void queueNCR(const NameChangeType& chg_type, const Lease6Ptr& lease) {
135 // DUID is required to generate NCR.
136 if (lease && (lease->type_ != Lease::TYPE_PD) && lease->duid_) {
137 // Figure out from the lease's subnet if we should use conflict resolution.
138 // If there's no subnet, something hinky is going on so we'll set it true.
139 ConstSubnet6Ptr subnet = CfgMgr::instance().getCurrentCfg()
140 ->getCfgSubnets6()->getSubnet(lease->subnet_id_);
141 queueNCRCommon(chg_type, lease, *(lease->duid_),
142 Pkt6::makeLabel(lease->duid_, lease->hwaddr_), subnet);
143 }
144}
145
146uint32_t calculateDdnsTtl(uint32_t lease_lft,
147 const util::Optional<double>& ddns_ttl_percent,
148 const util::Optional<uint32_t>& ddns_ttl,
149 const util::Optional<uint32_t>& ddns_ttl_min,
150 const util::Optional<uint32_t>& ddns_ttl_max) {
151 // If we have an explicit value use it.
152 if (!ddns_ttl.unspecified() && ddns_ttl.get() > 0) {
153 return (ddns_ttl.get());
154 }
155
156 // Use specified percentage (if one) or 1/3 as called for in RFC 4702.
157 double ttl_percent = (ddns_ttl_percent.get() > 0.0 ?
158 ddns_ttl_percent.get() : 0.33333);
159
160 // Calculate the ttl.
161 uint32_t ttl = static_cast<uint32_t>(round(ttl_percent * lease_lft));
162
163 // Adjust for minimum and maximum.
164 // If we have a custom minimum enforce it, otherwise per RFC 4702 it
165 // should not less than 600.
166 uint32_t ttl_min = (ddns_ttl_min.get() > 0) ? ddns_ttl_min.get() : 600;
167 if (ttl < ttl_min) {
168 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA,
169 DHCPSRV_DDNS_TTL_TOO_SMALL)
170 .arg(util::str::dumpDouble(ttl_percent))
171 .arg(lease_lft)
172 .arg(ttl)
173 .arg(ttl_min);
174 return (ttl_min);
175 }
176
177 // If we have a maximum enforce it.
178 uint32_t ttl_max = ddns_ttl_max.get();
179 if (ttl_max && ttl > ttl_max) {
180 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA,
181 DHCPSRV_DDNS_TTL_TOO_LARGE)
182 .arg(util::str::dumpDouble(ttl_percent))
183 .arg(lease_lft)
184 .arg(ttl)
185 .arg(ttl_max);
186 return (ttl_max);
187 }
188
189 return (ttl);
190}
191
192}
193}
cfgmgr.h
isc::dhcp::CfgMgr::getD2ClientMgr
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
Definition cfgmgr.cc:69
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
isc::dhcp::CfgMgr::getCurrentCfg
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
isc::dhcp::D2ClientMgr::sendRequest
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
Definition d2_client_mgr.cc:326
isc::dhcp::DdnsParams
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
Definition ddns_params.h:23
isc::dhcp::IdentifierType
Definition duid.h:37
isc::dhcp::OptionDataTypeUtil::writeFqdn
static void writeFqdn(const std::string &fqdn, std::vector< uint8_t > &buf, const bool downcase=false)
Append FQDN into a buffer.
Definition option_data_types.cc:359
isc::dhcp::Pkt4::makeLabel
static std::string makeLabel(const HWAddrPtr &hwaddr, const ClientIdPtr &client_id, const uint32_t transid)
Returns text representation of the given packet identifiers.
Definition pkt4.cc:399
isc::dhcp::Pkt6::makeLabel
static std::string makeLabel(const DuidPtr duid, const uint32_t transid, const HWAddrPtr &hwaddr)
Returns text representation of the given packet identifiers.
Definition pkt6.cc:693
isc::dhcp_ddns::D2Dhcid
Container class for handling the DHCID value within a NameChangeRequest.
Definition ncr_msg.h:113
isc::dhcp_ddns::NameChangeRequest
Represents a DHCP-DDNS client request.
Definition ncr_msg.h:254
isc::util::Optional
A template representing an optional value.
Definition optional.h:37
isc::util::Optional::get
T get() const
Retrieves the encapsulated value.
Definition optional.h:123
isc::util::Optional::unspecified
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition optional.h:145
d2_client_mgr.h
Defines the D2ClientMgr class.
dhcpsrv_log.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
isc::dhcp_ddns
Definition dhcp_ddns_log.cc:14
isc::dhcp_ddns::ConflictResolutionMode
ConflictResolutionMode
Definition ncr_msg.h:64
isc::dhcp_ddns::CHECK_WITH_DHCID
@ CHECK_WITH_DHCID
Definition ncr_msg.h:65
isc::dhcp_ddns::StringToConflictResolutionMode
ConflictResolutionMode StringToConflictResolutionMode(const std::string &mode_str)
Function which converts string to ConflictResolutionMode enum values.
Definition ncr_msg.cc:42
isc::dhcp_ddns::NameChangeRequestPtr
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
Definition ncr_msg.h:241
isc::dhcp_ddns::NameChangeType
NameChangeType
Defines the types of DNS updates that can be requested.
Definition ncr_msg.h:45
isc::dhcp_ddns::CHG_ADD
@ CHG_ADD
Definition ncr_msg.h:46
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL_DATA
const int DHCPSRV_DBG_TRACE_DETAIL_DATA
Additional information.
Definition dhcpsrv_log.h:43
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
isc::dhcp::calculateDdnsTtl
uint32_t calculateDdnsTtl(uint32_t lease_lft, const util::Optional< double > &ddns_ttl_percent, const util::Optional< uint32_t > &ddns_ttl, const util::Optional< uint32_t > &ddns_ttl_min, const util::Optional< uint32_t > &ddns_ttl_max)
Calculates TTL for a DNS resource record based on lease life time.
Definition ncr_generator.cc:146
isc::dhcp::DHCPSRV_QUEUE_NCR
const isc::log::MessageID DHCPSRV_QUEUE_NCR
Definition dhcpsrv_messages.h:162
isc::dhcp::queueNCR
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
Definition ncr_generator.cc:114
isc::dhcp::ConstSubnet6Ptr
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition subnet.h:620
isc::dhcp::ConstSubnet4Ptr
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
Definition subnet.h:455
isc::dhcp::Lease6Ptr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:528
isc::dhcp::DHCPSRV_DDNS_TTL_TOO_LARGE
const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_LARGE
Definition dhcpsrv_messages.h:54
isc::dhcp::DHCPSRV_QUEUE_NCR_FAILED
const isc::log::MessageID DHCPSRV_QUEUE_NCR_FAILED
Definition dhcpsrv_messages.h:163
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition dhcpsrv_log.h:38
isc::dhcp::DHCPSRV_QUEUE_NCR_SKIP
const isc::log::MessageID DHCPSRV_QUEUE_NCR_SKIP
Definition dhcpsrv_messages.h:164
isc::dhcp::DHCPSRV_DDNS_TTL_TOO_SMALL
const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_SMALL
Definition dhcpsrv_messages.h:55
isc::dhcp::ConstSubnetPtr
boost::shared_ptr< const Subnet > ConstSubnetPtr
A generic pointer to either const Subnet4 or const Subnet6 object.
Definition subnet.h:449
isc::dhcp::Lease4Ptr
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
isc::util::str::dumpDouble
string dumpDouble(double val, size_t precision)
Converts a double to a string with given precision.
Definition str.cc:344
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18
ncr_generator.h
option_data_types.h
str.h
isc::dhcp::Lease::TYPE_PD
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition lease.h:49