1 // Copyright (C) 2014-2021 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 #ifndef D2_CFG_MGR_H 8 #define D2_CFG_MGR_H 9 10 #include <asiolink/io_service.h> 11 #include <cc/data.h> 12 #include <exceptions/exceptions.h> 13 #include <d2srv/d2_config.h> 14 #include <hooks/hooks_config.h> 15 #include <process/d_cfg_mgr.h> 16 17 #include <stdint.h> 18 #include <string> 19 20 namespace isc { 21 namespace d2 { 22 23 class D2CfgContext; 24 /// @brief Pointer to a configuration context. 25 typedef boost::shared_ptr<D2CfgContext> D2CfgContextPtr; 26 27 /// @brief DHCP-DDNS Configuration Context 28 /// 29 /// Implements the storage container for configuration context. 30 /// It provides a single enclosure for the storage of configuration parameters 31 /// and any other DHCP-DDNS specific information that needs to be accessible 32 /// during configuration parsing as well as to the application as a whole. 33 /// It is derived from the context base class, ConfigBase. 34 class D2CfgContext : public process::ConfigBase { 35 public: 36 /// @brief Constructor 37 D2CfgContext(); 38 39 /// @brief Destructor 40 virtual ~D2CfgContext(); 41 42 /// @brief Creates a clone of this context object. 43 /// 44 /// @return returns a pointer to the new clone. clone()45 virtual process::ConfigPtr clone() { 46 return (process::ConfigPtr(new D2CfgContext(*this))); 47 } 48 49 /// @brief Fetches a reference to the D2Params getD2Params()50 D2ParamsPtr& getD2Params() { 51 return (d2_params_); 52 } 53 54 /// @brief Fetches the forward DNS domain list manager. 55 /// 56 /// @return returns a pointer to the forward manager. getForwardMgr()57 DdnsDomainListMgrPtr getForwardMgr() { 58 return (forward_mgr_); 59 } 60 61 /// @brief Sets the forward domain list manager 62 /// @param forward_mgr pointer to the new forward manager setForwardMgr(DdnsDomainListMgrPtr forward_mgr)63 void setForwardMgr(DdnsDomainListMgrPtr forward_mgr) { 64 forward_mgr_ = forward_mgr; 65 } 66 67 /// @brief Fetches the reverse DNS domain list manager. 68 /// 69 /// @return returns a pointer to the reverse manager. getReverseMgr()70 DdnsDomainListMgrPtr getReverseMgr() { 71 return (reverse_mgr_); 72 } 73 74 /// @brief Sets the reverse domain list manager 75 /// @param reverse_mgr pointer to the new reverse manager setReverseMgr(DdnsDomainListMgrPtr reverse_mgr)76 void setReverseMgr(DdnsDomainListMgrPtr reverse_mgr) { 77 reverse_mgr_ = reverse_mgr; 78 } 79 80 /// @brief Fetches the map of TSIG keys. 81 /// 82 /// @return returns a pointer to the key map. getKeys()83 TSIGKeyInfoMapPtr getKeys() { 84 return (keys_); 85 } 86 87 /// @brief Sets the map of TSIG keys 88 /// 89 /// @param keys pointer to the new TSIG key map setKeys(const TSIGKeyInfoMapPtr & keys)90 void setKeys(const TSIGKeyInfoMapPtr& keys) { 91 keys_ = keys; 92 } 93 94 /// @brief Returns information about control socket 95 /// @return pointer to the Element that holds control-socket map getControlSocketInfo()96 const isc::data::ConstElementPtr getControlSocketInfo() const { 97 return (control_socket_); 98 } 99 100 /// @brief Sets information about the control socket 101 /// @param control_socket Element that holds control-socket map setControlSocketInfo(const isc::data::ConstElementPtr & control_socket)102 void setControlSocketInfo(const isc::data::ConstElementPtr& control_socket) { 103 control_socket_ = control_socket; 104 } 105 106 /// @brief Returns non-const reference to configured hooks libraries. 107 /// 108 /// @return non-const reference to configured hooks libraries. getHooksConfig()109 isc::hooks::HooksConfig& getHooksConfig() { 110 return (hooks_config_); 111 } 112 113 /// @brief Returns const reference to configured hooks libraries. 114 /// 115 /// @return const reference to configured hooks libraries. getHooksConfig()116 const isc::hooks::HooksConfig& getHooksConfig() const { 117 return (hooks_config_); 118 } 119 120 /// @brief Unparse a configuration object 121 /// 122 /// @return a pointer to a configuration 123 virtual isc::data::ElementPtr toElement() const; 124 125 protected: 126 /// @brief Copy constructor for use by derivations in clone(). 127 D2CfgContext(const D2CfgContext& rhs); 128 129 private: 130 /// @brief Private assignment operator to avoid potential for slicing. 131 D2CfgContext& operator=(const D2CfgContext& rhs); 132 133 /// @brief Global level parameter storage 134 D2ParamsPtr d2_params_; 135 136 /// @brief Forward domain list manager. 137 DdnsDomainListMgrPtr forward_mgr_; 138 139 /// @brief Reverse domain list manager. 140 DdnsDomainListMgrPtr reverse_mgr_; 141 142 /// @brief Storage for the map of TSIGKeyInfos. 143 TSIGKeyInfoMapPtr keys_; 144 145 /// @brief Pointer to the control-socket information. 146 isc::data::ConstElementPtr control_socket_; 147 148 /// @brief Configured hooks libraries. 149 isc::hooks::HooksConfig hooks_config_; 150 }; 151 152 /// @brief Defines a pointer for DdnsDomain instances. 153 typedef boost::shared_ptr<DdnsDomainListMgr> DdnsDomainListMgrPtr; 154 155 /// @brief DHCP-DDNS Configuration Manager 156 /// 157 /// Provides the mechanisms for managing the DHCP-DDNS application's 158 /// configuration. This includes services for parsing sets of configuration 159 /// values, storing the parsed information in its converted form, 160 /// and retrieving the information on demand. 161 class D2CfgMgr : public process::DCfgMgrBase { 162 public: 163 /// @brief Reverse zone suffix added to IPv4 addresses for reverse lookups 164 /// @todo This should be configurable. 165 static const char* IPV4_REV_ZONE_SUFFIX; 166 167 /// @brief Reverse zone suffix added to IPv6 addresses for reverse lookups 168 /// @todo This should be configurable. 169 static const char* IPV6_REV_ZONE_SUFFIX; 170 171 /// @brief Constructor 172 D2CfgMgr(); 173 174 /// @brief Destructor 175 virtual ~D2CfgMgr(); 176 177 /// @brief Convenience method that returns the D2 configuration context. 178 /// 179 /// @return returns a pointer to the configuration context. getD2CfgContext()180 D2CfgContextPtr getD2CfgContext() { 181 return (boost::dynamic_pointer_cast<D2CfgContext>(getContext())); 182 } 183 184 /// @brief Returns whether or not forward updates are enabled. 185 /// 186 /// This method currently uses the presence or absence of Forward DDNS 187 /// Domains to determine if forward updates are enabled or disabled. 188 /// @todo This could be expanded to include the check of a configurable 189 /// boolean value. 190 /// 191 /// @return true if forward updates are enabled, false otherwise. 192 bool forwardUpdatesEnabled(); 193 194 /// @brief Returns whether or not reverse updates are enabled. 195 /// 196 /// This method currently uses the presence or absence of Reverse DDNS 197 /// Domains to determine if reverse updates are enabled or disabled. 198 /// @todo This could be expanded to include the check of a configurable 199 /// boolean value. 200 /// 201 /// @return true if reverse updates are enabled, false otherwise. 202 bool reverseUpdatesEnabled(); 203 204 /// @brief Matches a given FQDN to a forward domain. 205 /// 206 /// This calls the matchDomain method of the forward domain manager to 207 /// match the given FQDN to a forward domain. 208 /// 209 /// @param fqdn is the name for which to look. 210 /// @param domain receives the matching domain. Note that it will be reset 211 /// upon entry and only set if a match is subsequently found. 212 /// 213 /// @return returns true if a match is found, false otherwise. 214 /// @throw throws D2CfgError if given an invalid fqdn. 215 bool matchForward(const std::string& fqdn, DdnsDomainPtr& domain); 216 217 /// @brief Matches a given IP address to a reverse domain. 218 /// 219 /// This calls the matchDomain method of the reverse domain manager to 220 /// match the given IPv4 or IPv6 address to a reverse domain. 221 /// 222 /// @param ip_address is the name for which to look. 223 /// @param domain receives the matching domain. Note that it will be reset 224 /// upon entry and only set if a match is subsequently found. 225 /// 226 /// @return returns true if a match is found, false otherwise. 227 /// @throw throws D2CfgError if given an invalid fqdn. 228 bool matchReverse(const std::string& ip_address, DdnsDomainPtr& domain); 229 230 /// @brief Generate a reverse order string for the given IP address 231 /// 232 /// This method creates a string containing the given IP address 233 /// contents in reverse order. This format is used for matching 234 /// against reverse DDNS domains in DHCP_DDNS configuration. 235 /// After reversing the syllables of the address, it appends the 236 /// appropriate suffix. 237 /// 238 /// @param address string containing a valid IPv4 or IPv6 address. 239 /// 240 /// @return a std::string containing the reverse order address. 241 /// 242 /// @throw D2CfgError if given an invalid address. 243 static std::string reverseIpAddress(const std::string& address); 244 245 /// @brief Generate a reverse order string for the given IP address 246 /// 247 /// This method creates a string containing the given IP address 248 /// contents in reverse order. This format is used for matching 249 /// against reverse DDNS domains in DHCP_DDNS configuration. 250 /// After reversing the syllables of the address, it appends the 251 /// appropriate suffix. 252 /// 253 /// Example: 254 /// input: 192.168.1.15 255 /// output: 15.1.168.192.in-addr.arpa. 256 /// 257 /// @param ioaddr is the IPv4 IOaddress to convert 258 /// 259 /// @return a std::string containing the reverse order address. 260 /// 261 /// @throw D2CfgError if not given an IPv4 address. 262 static std::string reverseV4Address(const isc::asiolink::IOAddress& ioaddr); 263 264 /// @brief Generate a reverse order string for the given IP address 265 /// 266 /// This method creates a string containing the given IPv6 address 267 /// contents in reverse order. This format is used for matching 268 /// against reverse DDNS domains in DHCP_DDNS configuration. 269 /// After reversing the syllables of the address, it appends the 270 /// appropriate suffix. 271 /// 272 /// IPv6 example: 273 /// input: 2001:db8:302:99:: 274 /// output: 275 ///0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.9.0.0.2.0.3.0.8.B.D.0.1.0.0.2.ip6.arpa. 276 /// 277 /// @param ioaddr string containing a valid IPv6 address. 278 /// 279 /// @return a std::string containing the reverse order address. 280 /// 281 /// @throw D2CfgError if not given an IPv6 address. 282 static std::string reverseV6Address(const isc::asiolink::IOAddress& ioaddr); 283 284 /// @brief Convenience method fetches the D2Params from context 285 /// @return reference to const D2ParamsPtr 286 const D2ParamsPtr& getD2Params(); 287 288 /// @brief Convenience method fetches information about control socket 289 /// from context 290 /// @return pointer to the Element that holds control-socket map 291 const isc::data::ConstElementPtr getControlSocketInfo(); 292 293 /// @brief Returns configuration summary in the textual format. 294 /// 295 /// @param selection Bitfield which describes the parts of the configuration 296 /// to be returned. This parameter is ignored for the D2. 297 /// 298 /// @return Summary of the configuration in the textual format. 299 virtual std::string getConfigSummary(const uint32_t selection) override; 300 301 std::list<std::list<std::string>> jsonPathsToRedact() const final override; 302 303 protected: 304 /// @brief Parses configuration of the D2. 305 /// 306 /// @param config Pointer to a configuration specified for D2. 307 /// @param check_only Boolean flag indicating if this method should 308 /// only verify correctness of the provided configuration. 309 /// @return Pointer to a result of configuration parsing. 310 virtual isc::data::ConstElementPtr 311 parse(isc::data::ConstElementPtr config, bool check_only) override; 312 313 /// @brief Adds default values to the given config 314 /// 315 /// Adds the D2 default values to the configuration Element map. This 316 /// method is invoked by @c DCfgMgrBase::parseConfig(). 317 /// 318 /// @param mutable_config - configuration to which defaults should be added 319 virtual void setCfgDefaults(isc::data::ElementPtr mutable_config) override; 320 321 /// @brief Creates an new, blank D2CfgContext context 322 /// 323 /// This method is used at the beginning of configuration process to 324 /// create a fresh, empty copy of a D2CfgContext. This new context will 325 /// be populated during the configuration process and will replace the 326 /// existing context provided the configuration process completes without 327 /// error. 328 /// 329 /// @return Returns a ConfigPtr to the new context instance. 330 virtual process::ConfigPtr createNewContext() override; 331 }; 332 333 /// @brief Defines a shared pointer to D2CfgMgr. 334 typedef boost::shared_ptr<D2CfgMgr> D2CfgMgrPtr; 335 336 } // end of isc::d2 namespace 337 } // end of isc namespace 338 339 #endif // D2_CFG_MGR_H 340