Kea 2.6.2
d2_cfg_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2024 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 <d2srv/d2_log.h>
10#include <d2srv/d2_cfg_mgr.h>
14#include <util/encode/encode.h>
15#include <boost/range/adaptor/reversed.hpp>
16
17using namespace isc::asiolink;
18using namespace isc::config;
19using namespace isc::data;
20using namespace isc::process;
21
22namespace isc {
23namespace d2 {
24
25namespace {
26
27typedef std::vector<uint8_t> ByteAddress;
28
29} // end of unnamed namespace
30
31// *********************** D2CfgContext *************************
32
34 : d2_params_(new D2Params()),
35 forward_mgr_(new DdnsDomainListMgr("forward-ddns")),
36 reverse_mgr_(new DdnsDomainListMgr("reverse-ddns")),
37 keys_(new TSIGKeyInfoMap()),
38 control_socket_(ConstElementPtr()) {
39}
40
42 d2_params_ = rhs.d2_params_;
43 if (rhs.forward_mgr_) {
44 forward_mgr_.reset(new DdnsDomainListMgr(rhs.forward_mgr_->getName()));
45 forward_mgr_->setDomains(rhs.forward_mgr_->getDomains());
46 }
47
48 if (rhs.reverse_mgr_) {
49 reverse_mgr_.reset(new DdnsDomainListMgr(rhs.reverse_mgr_->getName()));
50 reverse_mgr_->setDomains(rhs.reverse_mgr_->getDomains());
51 }
52
53 keys_ = rhs.keys_;
54
55 control_socket_ = rhs.control_socket_;
56
57 hooks_config_ = rhs.hooks_config_;
58}
59
62
66 // Set user-context
68 // Set ip-address
69 const IOAddress& ip_address = d2_params_->getIpAddress();
70 d2->set("ip-address", Element::create(ip_address.toText()));
71 // Set port
72 size_t port = d2_params_->getPort();
73 d2->set("port", Element::create(static_cast<int64_t>(port)));
74 // Set dns-server-timeout
75 size_t dns_server_timeout = d2_params_->getDnsServerTimeout();
76 d2->set("dns-server-timeout",
77 Element::create(static_cast<int64_t>(dns_server_timeout)));
78 // Set ncr-protocol
79 const dhcp_ddns::NameChangeProtocol& ncr_protocol =
80 d2_params_->getNcrProtocol();
81 d2->set("ncr-protocol",
83 // Set ncr-format
84 const dhcp_ddns::NameChangeFormat& ncr_format = d2_params_->getNcrFormat();
85 d2->set("ncr-format",
87 // Set forward-ddns
88 ElementPtr forward_ddns = Element::createMap();
89 forward_ddns->set("ddns-domains", forward_mgr_->toElement());
90 d2->set("forward-ddns", forward_ddns);
91 // Set reverse-ddns
92 ElementPtr reverse_ddns = Element::createMap();
93 reverse_ddns->set("ddns-domains", reverse_mgr_->toElement());
94 d2->set("reverse-ddns", reverse_ddns);
95 // Set tsig-keys
96 ElementPtr tsig_keys = Element::createList();
97 for (auto const& key : *keys_) {
98 tsig_keys->add(key.second->toElement());
99 }
100 d2->set("tsig-keys", tsig_keys);
101 // Set control-socket (skip if null as empty is not legal)
102 if (!isNull(control_socket_)) {
103 d2->set("control-socket", UserContext::toElement(control_socket_));
104 }
105 // Set hooks-libraries
106 d2->set("hooks-libraries", hooks_config_.toElement());
107 // Set DhcpDdns
109 result->set("DhcpDdns", d2);
110
111 return (result);
112}
113
114// *********************** D2CfgMgr *************************
115
116const char* D2CfgMgr::IPV4_REV_ZONE_SUFFIX = "in-addr.arpa.";
117
118const char* D2CfgMgr::IPV6_REV_ZONE_SUFFIX = "ip6.arpa.";
119
122
125
130
131bool
133 // Forward updates are not enabled if no forward servers are defined.
134 return (getD2CfgContext()->getForwardMgr()->size() > 0);
135}
136
137bool
139 // Reverse updates are not enabled if no reverse servers are defined.
140 return (getD2CfgContext()->getReverseMgr()->size() > 0);
141}
142
143bool
144D2CfgMgr::matchForward(const std::string& fqdn, DdnsDomainPtr& domain) {
145 if (fqdn.empty()) {
146 // This is a programmatic error and should not happen.
147 isc_throw(D2CfgError, "matchForward passed an empty fqdn");
148 }
149
150 // Fetch the forward manager from the D2 context.
151 DdnsDomainListMgrPtr mgr = getD2CfgContext()->getForwardMgr();
152
153 // Call the manager's match method and return the result.
154 return (mgr->matchDomain(fqdn, domain));
155}
156
157bool
158D2CfgMgr::matchReverse(const std::string& ip_address, DdnsDomainPtr& domain) {
159 // Note, reverseIpAddress will throw if the ip_address is invalid.
160 std::string reverse_address = reverseIpAddress(ip_address);
161
162 // Fetch the reverse manager from the D2 context.
163 DdnsDomainListMgrPtr mgr = getD2CfgContext()->getReverseMgr();
164
165 return (mgr->matchDomain(reverse_address, domain));
166}
167
168std::string
169D2CfgMgr::reverseIpAddress(const std::string& address) {
170 try {
171 // Convert string address into an IOAddress and invoke the
172 // appropriate reverse method.
173 isc::asiolink::IOAddress ioaddr(address);
174 if (ioaddr.isV4()) {
175 return (reverseV4Address(ioaddr));
176 }
177
178 return (reverseV6Address(ioaddr));
179
180 } catch (const isc::Exception& ex) {
181 isc_throw(D2CfgError, "D2CfgMgr cannot reverse address: "
182 << address << " : " << ex.what());
183 }
184}
185
186std::string
188 if (!ioaddr.isV4()) {
189 isc_throw(D2CfgError, "D2CfgMgr address is not IPv4 address :"
190 << ioaddr);
191 }
192
193 // Get the address in byte vector form.
194 const ByteAddress bytes = ioaddr.toBytes();
195
196 // Walk backwards through vector outputting each octet and a dot.
197 std::ostringstream stream;
198
199 for (auto const& rit : boost::adaptors::reverse(bytes)) {
200 stream << static_cast<unsigned int>(rit) << ".";
201 }
202
203 // Tack on the suffix and we're done.
204 stream << IPV4_REV_ZONE_SUFFIX;
205 return(stream.str());
206}
207
208std::string
210 if (!ioaddr.isV6()) {
211 isc_throw(D2CfgError, "D2Cfg address is not IPv6 address: " << ioaddr);
212 }
213
214 // Turn the address into a string of digits.
215 const ByteAddress bytes = ioaddr.toBytes();
216 const std::string digits = isc::util::encode::encodeHex(bytes);
217
218 // Walk backwards through string outputting each digits and a dot.
219 std::ostringstream stream;
220
221 for (auto const& rit : boost::adaptors::reverse(digits)) {
222 stream << static_cast<char>(rit) << ".";
223 }
224
225 // Tack on the suffix and we're done.
226 stream << IPV6_REV_ZONE_SUFFIX;
227 return(stream.str());
228}
229
230const D2ParamsPtr&
234
239
240std::string
242 return (getD2Params()->getConfigSummary());
243}
244
245void
247 D2SimpleParser::setAllDefaults(mutable_config);
248}
249
251D2CfgMgr::parse(isc::data::ConstElementPtr config_set, bool check_only) {
252 // Do a sanity check first.
253 if (!config_set) {
254 isc_throw(D2CfgError, "Mandatory config parameter not provided");
255 }
256
258
259 // Set the defaults
260 ElementPtr cfg = boost::const_pointer_cast<Element>(config_set);
262
263 // And parse the configuration.
265 std::string excuse;
266 try {
267 // Do the actual parsing
268 D2SimpleParser parser;
269 parser.parse(ctx, cfg, check_only);
270 } catch (const isc::Exception& ex) {
271 excuse = ex.what();
273 } catch (...) {
274 excuse = "undefined configuration parsing error";
276 }
277
278 // At this stage the answer was created only in case of exception.
279 if (answer) {
280 if (check_only) {
282 } else {
284 }
285 return (answer);
286 }
287
288 if (check_only) {
290 "Configuration check successful");
291 } else {
292
293 // Calculate hash of the configuration that was just set.
294 ConstElementPtr config = getContext()->toElement();
295 std::string hash = BaseCommandMgr::getHash(config);
297 params->set("hash", Element::create(hash));
298
300 "Configuration applied successfully.", params);
301 }
302
303 return (answer);
304}
305
306std::list<std::list<std::string>>
308 static std::list<std::list<std::string>> const list({
309 {"tsig-keys", "[]"},
310 {"hooks-libraries", "[]", "parameters", "*"},
311 });
312 return list;
313}
314
315} // namespace d2
316} // namespace isc
if(!(yy_init))
when the call the UDPServer carries on at the same position As a result
Definition asiodns.dox:16
it forwards queries to a single upstream resolver and passes the answers back to the client It is constructed with the address of the forward server Queries are initiated with the question to ask the forward a buffer into which to write the answer
Definition asiodns.dox:60
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:299
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static std::string getHash(const isc::data::ConstElementPtr &config)
returns a hash of a given Element structure
DHCP-DDNS Configuration Context.
Definition d2_cfg_mgr.h:34
virtual ~D2CfgContext()
Destructor.
Definition d2_cfg_mgr.cc:60
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition d2_cfg_mgr.cc:64
D2CfgContext()
Constructor.
Definition d2_cfg_mgr.cc:33
Exception thrown when the error during configuration handling occurs.
Definition d2_config.h:134
virtual ~D2CfgMgr()
Destructor.
bool matchForward(const std::string &fqdn, DdnsDomainPtr &domain)
Matches a given FQDN to a forward domain.
virtual process::ConfigPtr createNewContext() override
Creates an new, blank D2CfgContext context.
static std::string reverseIpAddress(const std::string &address)
Generate a reverse order string for the given IP address.
D2CfgContextPtr getD2CfgContext()
Convenience method that returns the D2 configuration context.
Definition d2_cfg_mgr.h:180
bool reverseUpdatesEnabled()
Returns whether or not reverse updates are enabled.
virtual void setCfgDefaults(isc::data::ElementPtr mutable_config) override
Adds default values to the given config.
std::list< std::list< std::string > > jsonPathsToRedact() const final override
Return a list of all paths that contain passwords or secrets.
D2CfgMgr()
Constructor.
static const char * IPV6_REV_ZONE_SUFFIX
Reverse zone suffix added to IPv6 addresses for reverse lookups.
Definition d2_cfg_mgr.h:169
static std::string reverseV4Address(const isc::asiolink::IOAddress &ioaddr)
Generate a reverse order string for the given IP address.
bool forwardUpdatesEnabled()
Returns whether or not forward updates are enabled.
bool matchReverse(const std::string &ip_address, DdnsDomainPtr &domain)
Matches a given IP address to a reverse domain.
virtual std::string getConfigSummary(const uint32_t selection) override
Returns configuration summary in the textual format.
static std::string reverseV6Address(const isc::asiolink::IOAddress &ioaddr)
Generate a reverse order string for the given IP address.
const D2ParamsPtr & getD2Params()
Convenience method fetches the D2Params from context.
const isc::data::ConstElementPtr getControlSocketInfo()
Convenience method fetches information about control socket from context.
virtual isc::data::ConstElementPtr parse(isc::data::ConstElementPtr config, bool check_only) override
Parses configuration of the D2.
static const char * IPV4_REV_ZONE_SUFFIX
Reverse zone suffix added to IPv4 addresses for reverse lookups.
Definition d2_cfg_mgr.h:165
Acts as a storage vault for D2 global scalar parameters.
Definition d2_config.h:141
void parse(const D2CfgContextPtr &ctx, const isc::data::ConstElementPtr &config, bool check_only)
Parses the whole D2 configuration.
static size_t setAllDefaults(data::ElementPtr global)
Sets all defaults for D2 configuration.
Provides storage for and management of a list of DNS domains.
Definition d2_config.h:644
Base class for all configurations.
Definition config_base.h:33
virtual isc::data::ElementPtr toElement() const
Converts to Element representation.
DCfgMgrBase(ConfigPtr context)
Constructor.
Definition d_cfg_mgr.cc:37
ConfigPtr & getContext()
Fetches the configuration context.
Definition d_cfg_mgr.h:151
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< DdnsDomainListMgr > DdnsDomainListMgrPtr
Defines a pointer for DdnsDomain instances.
Definition d2_cfg_mgr.h:153
boost::shared_ptr< DdnsDomain > DdnsDomainPtr
Defines a pointer for DdnsDomain instances.
Definition d2_config.h:622
const isc::log::MessageID DHCP_DDNS_CONFIG_CHECK_FAIL
Definition d2_messages.h:19
std::map< std::string, TSIGKeyInfoPtr > TSIGKeyInfoMap
Defines a map of TSIGKeyInfos, keyed by the name.
Definition d2_config.h:417
boost::shared_ptr< D2CfgContext > D2CfgContextPtr
Pointer to a configuration context.
Definition d2_cfg_mgr.h:25
isc::log::Logger d2_logger("dhcpddns")
Defines the logger used within D2.
Definition d2_log.h:18
boost::shared_ptr< D2Params > D2ParamsPtr
Defines a pointer for D2Params instances.
Definition d2_config.h:255
const isc::log::MessageID DHCP_DDNS_CONFIG_FAIL
Definition d2_messages.h:20
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a NULL pointer.
Definition data.cc:1148
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
NameChangeFormat
Defines the list of data wire formats supported.
Definition ncr_msg.h:59
NameChangeProtocol
Defines the list of socket protocols supported.
Definition ncr_io.h:69
std::string ncrProtocolToString(NameChangeProtocol protocol)
Function which converts NameChangeProtocol enums to text labels.
Definition ncr_io.cc:36
std::string ncrFormatToString(NameChangeFormat format)
Function which converts NameChangeFormat enums to text labels.
Definition ncr_msg.cc:35
boost::shared_ptr< ConfigBase > ConfigPtr
Non-const pointer to the ConfigBase.
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
Definition encode.cc:361
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
static data::ElementPtr toElement(data::ConstElementPtr map)
Copy an Element map.