Kea 2.7.6
ncr_generator.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2023 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
10#include <dhcpsrv/cfgmgr.h>
11#include <dhcpsrv/dhcpsrv_log.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 NetworkPtr subnet) {
43 // Check if there is a need for update.
44 if (lease->hostname_.empty() || (!lease->fqdn_fwd_ && !lease->fqdn_rev_)
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;
57 util::Optional<uint32_t> ddns_ttl_min;
58 util::Optional<uint32_t> ddns_ttl_max;
59 if (subnet) {
60 auto mode = subnet->getDdnsConflictResolutionMode();
61 if (!mode.empty()) {
62 conflict_resolution_mode = StringToConflictResolutionMode(mode);
63 }
64
65 ddns_ttl_percent = subnet->getDdnsTtlPercent();
66 ddns_ttl = subnet->getDdnsTtl();
67 ddns_ttl_min = subnet->getDdnsTtlMin();
68 ddns_ttl_max = subnet->getDdnsTtlMax();
69 }
70
71 try {
72 // Create DHCID
73 std::vector<uint8_t> hostname_wire;
74 OptionDataTypeUtil::writeFqdn(lease->hostname_, hostname_wire, true);
75 D2Dhcid dhcid = D2Dhcid(identifier, hostname_wire);
76
77 // Calculate the TTL based on lease life time.
78 uint32_t ttl = calculateDdnsTtl(lease->valid_lft_,
79 ddns_ttl_percent, ddns_ttl,
80 ddns_ttl_min, ddns_ttl_max);
81
82 // Create name change request.
84 (new NameChangeRequest(chg_type, lease->fqdn_fwd_, lease->fqdn_rev_,
85 lease->hostname_, lease->addr_.toText(),
86 dhcid, lease->cltt_ + ttl,
87 ttl, conflict_resolution_mode));
88
90 .arg(label)
91 .arg(chg_type == CHG_ADD ? "add" : "remove")
92 .arg(ncr->toText());
93
94 // Send name change request.
96
97 } catch (const std::exception& ex) {
99 .arg(label)
100 .arg(chg_type == CHG_ADD ? "add" : "remove")
101 .arg(lease->addr_.toText())
102 .arg(ex.what());
103 }
104}
105
106} // end of anonymous namespace
107
108namespace isc {
109namespace dhcp {
110
111void queueNCR(const NameChangeType& chg_type, const Lease4Ptr& lease) {
112 if (lease) {
113 // Figure out from the lease's subnet if we should use conflict resolution.
114 // If there's no subnet, something hinky is going on so we'll set it true.
116 ->getCfgSubnets4()->getSubnet(lease->subnet_id_);
117
118 // Client id takes precedence over HW address.
119 if (lease->client_id_) {
120 queueNCRCommon(chg_type, lease, lease->client_id_->getClientId(),
121 Pkt4::makeLabel(lease->hwaddr_, lease->client_id_), subnet);
122 } else {
123 // Client id is not specified for the lease. Use HW address
124 // instead.
125 queueNCRCommon(chg_type, lease, lease->hwaddr_,
126 Pkt4::makeLabel(lease->hwaddr_, lease->client_id_), subnet);
127 }
128 }
129}
130
131void queueNCR(const NameChangeType& chg_type, const Lease6Ptr& lease) {
132 // DUID is required to generate NCR.
133 if (lease && (lease->type_ != Lease::TYPE_PD) && lease->duid_) {
134 // Figure out from the lease's subnet if we should use conflict resolution.
135 // If there's no subnet, something hinky is going on so we'll set it true.
137 ->getCfgSubnets6()->getSubnet(lease->subnet_id_);
138 queueNCRCommon(chg_type, lease, *(lease->duid_),
139 Pkt6::makeLabel(lease->duid_, lease->hwaddr_), subnet);
140 }
141}
142
143uint32_t calculateDdnsTtl(uint32_t lease_lft,
144 const util::Optional<double>& ddns_ttl_percent,
145 const util::Optional<uint32_t>& ddns_ttl,
146 const util::Optional<uint32_t>& ddns_ttl_min,
147 const util::Optional<uint32_t>& ddns_ttl_max) {
148 // If we have an explicit value use it.
149 if (!ddns_ttl.unspecified() && ddns_ttl.get() > 0) {
150 return (ddns_ttl.get());
151 }
152
153 // Use specified percentage (if one) or 1/3 as called for in RFC 4702.
154 double ttl_percent = (ddns_ttl_percent.get() > 0.0 ?
155 ddns_ttl_percent.get() : 0.33333);
156
157 // Calculate the ttl.
158 uint32_t ttl = static_cast<uint32_t>(round(ttl_percent * lease_lft));
159
160 // Adjust for minimum and maximum.
161 // If we have a custom minimum enforce it, otherwise per RFC 4702 it
162 // should not less than 600.
163 uint32_t ttl_min = (ddns_ttl_min.get() > 0) ? ddns_ttl_min.get() : 600;
164 if (ttl < ttl_min) {
167 .arg(util::str::dumpDouble(ttl_percent))
168 .arg(lease_lft)
169 .arg(ttl)
170 .arg(ttl_min);
171 return (ttl_min);
172 }
173
174 // If we have a maximum enforce it.
175 uint32_t ttl_max = ddns_ttl_max.get();
176 if (ttl_max && ttl > ttl_max) {
179 .arg(util::str::dumpDouble(ttl_percent))
180 .arg(lease_lft)
181 .arg(ttl)
182 .arg(ttl_max);
183 return (ttl_max);
184 }
185
186 return (ttl);
187}
188
189}
190}
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
Definition cfgmgr.cc:68
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:28
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:115
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
static void writeFqdn(const std::string &fqdn, std::vector< uint8_t > &buf, const bool downcase=false)
Append FQDN into a buffer.
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:397
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:691
Container class for handling the DHCID value within a NameChangeRequest.
Definition ncr_msg.h:113
Represents a DHCP-DDNS client request.
Definition ncr_msg.h:254
A template representing an optional value.
Definition optional.h:36
T get() const
Retrieves the encapsulated value.
Definition optional.h:114
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition optional.h:136
Defines the D2ClientMgr class.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
ConflictResolutionMode StringToConflictResolutionMode(const std::string &mode_str)
Function which converts string to ConflictResolutionMode enum values.
Definition ncr_msg.cc:45
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
Definition ncr_msg.h:241
NameChangeType
Defines the types of DNS updates that can be requested.
Definition ncr_msg.h:45
const int DHCPSRV_DBG_TRACE_DETAIL_DATA
Additional information.
Definition dhcpsrv_log.h:43
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
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.
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
Definition subnet.h:461
const isc::log::MessageID DHCPSRV_QUEUE_NCR
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:508
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
Definition subnet.h:626
const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_LARGE
const isc::log::MessageID DHCPSRV_QUEUE_NCR_FAILED
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition dhcpsrv_log.h:38
const isc::log::MessageID DHCPSRV_QUEUE_NCR_SKIP
const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_SMALL
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
Definition network.h:73
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:295
string dumpDouble(double val, size_t precision)
Converts a double to a string with given precision.
Definition str.cc:344
Defines the logger used by the top-level component of kea-lfc.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition lease.h:49