d2_config.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. // Copyright (C) 2013-2017 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. #ifndef D2_CONFIG_H
  7. #define D2_CONFIG_H
  8. #include <asiolink/io_service.h>
  9. #include <cc/data.h>
  10. #include <cc/simple_parser.h>
  11. #include <dhcpsrv/parsers/dhcp_parsers.h>
  12. #include <dns/tsig.h>
  13. #include <exceptions/exceptions.h>
  14. #include <process/d_cfg_mgr.h>
  15. #include <boost/foreach.hpp>
  16. #include <stdint.h>
  17. #include <string>
  18. namespace isc {
  19. namespace d2 {
  20. /// @file d2_config.h
  21. /// @brief A collection of classes for housing and parsing the application
  22. /// configuration necessary for the DHCP-DDNS application (aka D2).
  23. ///
  24. /// This file contains the class declarations for the class hierarchy created
  25. /// from the D2 configuration and the parser classes used to create it.
  26. /// The application configuration consists of a set of scalar parameters,
  27. /// a list of TSIG keys, and two managed lists of domains: one list for
  28. /// forward domains and one list for reverse domains.
  29. ///
  30. /// The key list consists of one or more TSIG keys, each entry described by
  31. /// a name, the algorithm method name, optionally the minimum truncated
  32. /// length, and its secret key component.
  33. ///
  34. /// Each managed domain list consists of a list one or more domains and is
  35. /// represented by the class DdnsDomainListMgr.
  36. ///
  37. /// Each domain consists of a set of scalars parameters and a list of DNS
  38. /// servers which support that domain. Among its scalars, is key_name, which
  39. /// is the name of the TSIG Key to use for with this domain. This value should
  40. /// map to one of the TSIG Keys in the key list. Domains are represented by
  41. /// the class, DdnsDomain.
  42. ///
  43. /// Each server consists of a set of scalars used to describe the server such
  44. /// that the application can carry out DNS update exchanges with it. Servers
  45. /// are represented by the class, DnsServerInfo.
  46. ///
  47. /// The configuration specification for use with Kea is detailed in the file
  48. /// dhcp-ddns.spec.
  49. ///
  50. /// The parsing class hierarchy reflects this same scheme. Working top down:
  51. ///
  52. /// A DdnsDomainListMgrParser parses a managed domain list entry. It handles
  53. /// any scalars which belong to the manager as well as creating and invoking a
  54. /// DdnsDomainListParser to parse its list of domain entries.
  55. ///
  56. /// A DdnsDomainListParser creates and invokes a DdnsDomainParser for each
  57. /// domain entry in its list.
  58. ///
  59. /// A DdnsDomainParser handles the scalars which belong to the domain as well as
  60. /// creating and invoking a DnsSeverInfoListParser to parse its list of server
  61. /// entries.
  62. ///
  63. /// A DnsServerInfoListParser creates and invokes a DnsServerInfoParser for
  64. /// each server entry in its list.
  65. ///
  66. /// A DdnsServerInfoParser handles the scalars which belong to the server.
  67. /// The following is sample configuration in JSON form with extra spacing
  68. /// for clarity:
  69. ///
  70. /// @code
  71. /// {
  72. /// "interface" : "eth1" ,
  73. /// "ip-address" : "192.168.1.33" ,
  74. /// "port" : 88 ,
  75. /// "tsig-keys":
  76. //// [
  77. /// {
  78. /// "name": "d2_key.tmark.org" ,
  79. /// "algorithm": "md5" ,
  80. /// "secret": "0123456989"
  81. /// }
  82. /// ],
  83. /// "forward-ddns" :
  84. /// {
  85. /// "ddns-domains":
  86. /// [
  87. /// {
  88. /// "name": "tmark.org." ,
  89. /// "key-name": "d2_key.tmark.org" ,
  90. /// "dns-servers" :
  91. /// [
  92. /// { "hostname": "fserver.tmark.org" },
  93. /// { "hostname": "f2server.tmark.org" }
  94. /// ]
  95. /// },
  96. /// {
  97. /// "name": "pub.tmark.org." ,
  98. /// "key-name": "d2_key.tmark.org" ,
  99. /// "dns-servers" :
  100. /// [
  101. /// { "hostname": "f3server.tmark.org" }
  102. /// ]
  103. /// }
  104. /// ]
  105. /// },
  106. /// "reverse-ddns" :
  107. /// {
  108. /// "ddns-domains":
  109. /// [
  110. /// {
  111. /// "name": " 0.168.192.in.addr.arpa." ,
  112. /// "key-name": "d2_key.tmark.org" ,
  113. /// "dns-servers" :
  114. /// [
  115. /// { "ip-address": "127.0.0.101" , "port": 100 }
  116. /// ]
  117. /// }
  118. /// ]
  119. /// }
  120. /// }
  121. /// @endcode
  122. /// @brief Exception thrown when the error during configuration handling
  123. /// occurs.
  124. class D2CfgError : public isc::Exception {
  125. public:
  126. D2CfgError(const char* file, size_t line, const char* what) :
  127. isc::Exception(file, line, what) { };
  128. };
  129. /// @brief Acts as a storage vault for D2 global scalar parameters
  130. class D2Params {
  131. public:
  132. /// @brief Default configuration constants.
  133. //@{
  134. static const char* DFT_IP_ADDRESS;
  135. static const uint32_t DFT_PORT;
  136. static const char* DFT_PORT_STR;
  137. static const uint32_t DFT_DNS_SERVER_TIMEOUT;
  138. static const char* DFT_DNS_SERVER_TIMEOUT_STR;
  139. static const char* DFT_NCR_PROTOCOL;
  140. static const char* DFT_NCR_FORMAT;
  141. //@}
  142. /// @brief Constructor
  143. ///
  144. /// @param ip_address IP address at which D2 should listen for NCRs
  145. /// @param port port on which D2 should listen NCRs
  146. /// @param dns_server_timeout maximum amount of time in milliseconds to
  147. /// wait for a response to a single DNS update request.
  148. /// @param ncr_protocol socket protocol D2 should use to receive NCRS
  149. /// @param ncr_format packet format of the inbound NCRs
  150. ///
  151. /// @throw D2CfgError if:
  152. /// -# ip_address is 0.0.0.0 or ::
  153. /// -# port is 0
  154. /// -# dns_server_timeout is < 1
  155. /// -# ncr_protocol is invalid, currently only NCR_UDP is supported
  156. /// -# ncr_format is invalid, currently only FMT_JSON is supported
  157. D2Params(const isc::asiolink::IOAddress& ip_address,
  158. const size_t port,
  159. const size_t dns_server_timeout,
  160. const dhcp_ddns::NameChangeProtocol& ncr_protocol,
  161. const dhcp_ddns::NameChangeFormat& ncr_format);
  162. /// @brief Default constructor
  163. /// The default constructor creates an instance that has updates disabled.
  164. D2Params();
  165. /// @brief Destructor
  166. virtual ~D2Params();
  167. /// @brief Return the IP address D2 listens on.
  168. const isc::asiolink::IOAddress& getIpAddress() const {
  169. return(ip_address_);
  170. }
  171. /// @brief Return the TCP/UPD port D2 listens on.
  172. size_t getPort() const {
  173. return(port_);
  174. }
  175. /// @brief Return the DNS server timeout value.
  176. size_t getDnsServerTimeout() const {
  177. return(dns_server_timeout_);
  178. }
  179. /// @brief Return the socket protocol in use.
  180. const dhcp_ddns::NameChangeProtocol& getNcrProtocol() const {
  181. return(ncr_protocol_);
  182. }
  183. /// @brief Return the expected format of inbound requests (NCRs).
  184. const dhcp_ddns::NameChangeFormat& getNcrFormat() const {
  185. return(ncr_format_);
  186. }
  187. /// @brief Return summary of the configuration used by D2.
  188. ///
  189. /// The returned summary of the configuration is meant to be appended to
  190. /// the log message informing about the successful completion of the
  191. /// D2 configuration.
  192. ///
  193. /// @return Configuration summary in the textual format.
  194. std::string getConfigSummary() const;
  195. /// @brief Compares two D2Params's for equality
  196. bool operator == (const D2Params& other) const;
  197. /// @brief Compares two D2Params's for inequality
  198. bool operator != (const D2Params& other) const;
  199. /// @brief Generates a string representation of the class contents.
  200. std::string toText() const;
  201. protected:
  202. /// @brief Validates member values.
  203. ///
  204. /// Method is used by the constructor to validate member contents.
  205. /// Currently checks:
  206. /// -# ip_address is not 0.0.0.0 or ::
  207. /// -# port is not 0
  208. /// -# dns_server_timeout is 0
  209. /// -# ncr_protocol is UDP
  210. /// -# ncr_format is JSON
  211. ///
  212. /// @throw D2CfgError if contents are invalid
  213. virtual void validateContents();
  214. private:
  215. /// @brief IP address D2 listens on.
  216. isc::asiolink::IOAddress ip_address_;
  217. /// @brief IP port D2 listens on.
  218. size_t port_;
  219. /// @brief Timeout for a single DNS packet exchange in milliseconds.
  220. size_t dns_server_timeout_;
  221. /// @brief The socket protocol to use.
  222. /// Currently only UDP is supported.
  223. dhcp_ddns::NameChangeProtocol ncr_protocol_;
  224. /// @brief Format of the inbound requests (NCRs).
  225. /// Currently only JSON format is supported.
  226. dhcp_ddns::NameChangeFormat ncr_format_;
  227. };
  228. /// @brief Dumps the contents of a D2Params as text to an output stream
  229. ///
  230. /// @param os output stream to which text should be sent
  231. /// @param config D2Param instance to dump
  232. std::ostream&
  233. operator<<(std::ostream& os, const D2Params& config);
  234. /// @brief Defines a pointer for D2Params instances.
  235. typedef boost::shared_ptr<D2Params> D2ParamsPtr;
  236. /// @brief Represents a TSIG Key.
  237. ///
  238. /// Acts as both a storage class containing the basic attributes which
  239. /// describe a TSIG Key, as well as owning and providing access to an
  240. /// instance of the actual key (@ref isc::dns::TSIGKey) that can be used
  241. /// by the IO layer for signing and verifying messages.
  242. ///
  243. class TSIGKeyInfo {
  244. public:
  245. /// @brief Defines string values for the supported TSIG algorithms
  246. //@{
  247. static const char* HMAC_MD5_STR;
  248. static const char* HMAC_SHA1_STR;
  249. static const char* HMAC_SHA256_STR;
  250. static const char* HMAC_SHA224_STR;
  251. static const char* HMAC_SHA384_STR;
  252. static const char* HMAC_SHA512_STR;
  253. //}@
  254. /// @brief Constructor
  255. ///
  256. /// @param name the unique label used to identify this key
  257. /// @param algorithm the id of the encryption algorithm this key uses.
  258. /// Currently supported values are (case insensitive):
  259. /// -# "HMAC-MD5"
  260. /// -# "HMAC-SHA1"
  261. /// -# "HMAC-SHA224"
  262. /// -# "HMAC-SHA256"
  263. /// -# "HMAC-SHA384"
  264. /// -# "HMAC-SHA512"
  265. ///
  266. /// @param secret The base-64 encoded secret component for this key.
  267. /// (A suitable string for use here could be obtained by running the
  268. /// BIND 9 dnssec-keygen program; the contents of resulting key file
  269. /// will look similar to:
  270. /// @code
  271. /// Private-key-format: v1.3
  272. /// Algorithm: 157 (HMAC_MD5)
  273. /// Key: LSWXnfkKZjdPJI5QxlpnfQ==
  274. /// Bits: AAA=
  275. /// Created: 20140515143700
  276. /// Publish: 20140515143700
  277. /// Activate: 20140515143700
  278. /// @endcode
  279. /// where the value the "Key:" entry is the secret component of the key.)
  280. /// @param digestbits the minimum truncated length in bits
  281. ///
  282. /// @throw D2CfgError if values supplied are invalid:
  283. /// name cannot be blank, algorithm must be a supported value,
  284. /// secret must be a non-blank, base64 encoded string.
  285. TSIGKeyInfo(const std::string& name, const std::string& algorithm,
  286. const std::string& secret, uint32_t digestbits = 0);
  287. /// @brief Destructor
  288. virtual ~TSIGKeyInfo();
  289. /// @brief Getter which returns the key's name.
  290. ///
  291. /// @return returns the name as a std::string.
  292. const std::string getName() const {
  293. return (name_);
  294. }
  295. /// @brief Getter which returns the key's algorithm string ID
  296. ///
  297. /// @return returns the algorithm as a std::string.
  298. const std::string getAlgorithm() const {
  299. return (algorithm_);
  300. }
  301. /// @brief Getter which returns the key's minimum truncated length
  302. ///
  303. /// @return returns the minimum truncated length or 0 as an uint32_t
  304. uint32_t getDigestbits() const {
  305. return (digestbits_);
  306. }
  307. /// @brief Getter which returns the key's secret.
  308. ///
  309. /// @return returns the secret as a std::string.
  310. const std::string getSecret() const {
  311. return (secret_);
  312. }
  313. /// @brief Getter which returns the TSIG key used to sign and verify
  314. /// messages
  315. ///
  316. /// @return const pointer reference to dns::TSIGKey.
  317. const dns::TSIGKeyPtr& getTSIGKey() const {
  318. return (tsig_key_);
  319. }
  320. /// @brief Converts algorithm id to dns::TSIGKey algorithm dns::Name
  321. ///
  322. /// @param algorithm_id string value to translate into an algorithm name.
  323. /// Currently supported values are (case insensitive):
  324. /// -# "HMAC-MD5"
  325. /// -# "HMAC-SHA1"
  326. /// -# "HMAC-SHA224"
  327. /// -# "HMAC-SHA256"
  328. /// -# "HMAC-SHA384"
  329. /// -# "HMAC-SHA512"
  330. ///
  331. /// @return const reference to a dns::Name containing the algorithm name
  332. /// @throw BadValue if ID isn't recognized.
  333. static const dns::Name& stringToAlgorithmName(const std::string&
  334. algorithm_id);
  335. private:
  336. /// @brief Creates the actual TSIG key instance member
  337. ///
  338. /// Replaces this tsig_key member with a key newly created using the key
  339. /// name, algorithm id, digest bits, and secret.
  340. /// This method is currently only called by the constructor, however it
  341. /// could be called post-construction should keys ever support expiration.
  342. ///
  343. /// @throw D2CfgError with an explanation if the key could not be created.
  344. void remakeKey();
  345. /// @brief The name of the key.
  346. ///
  347. /// This value is the unique identifier that domains use to
  348. /// to specify which TSIG key they need.
  349. std::string name_;
  350. /// @brief The string ID of the algorithm that should be used for this key.
  351. std::string algorithm_;
  352. /// @brief The base64 encoded string secret value component of this key.
  353. std::string secret_;
  354. /// @brief The minimum truncated length in bits
  355. /// (0 means no truncation is allowed and is the default)
  356. uint32_t digestbits_;
  357. /// @brief The actual TSIG key.
  358. dns::TSIGKeyPtr tsig_key_;
  359. };
  360. /// @brief Defines a pointer for TSIGKeyInfo instances.
  361. typedef boost::shared_ptr<TSIGKeyInfo> TSIGKeyInfoPtr;
  362. /// @brief Defines a map of TSIGKeyInfos, keyed by the name.
  363. typedef std::map<std::string, TSIGKeyInfoPtr> TSIGKeyInfoMap;
  364. /// @brief Defines a iterator pairing of name and TSIGKeyInfo
  365. typedef std::pair<std::string, TSIGKeyInfoPtr> TSIGKeyInfoMapPair;
  366. /// @brief Defines a pointer to map of TSIGkeyInfos
  367. typedef boost::shared_ptr<TSIGKeyInfoMap> TSIGKeyInfoMapPtr;
  368. /// @brief Represents a specific DNS Server.
  369. /// It provides information about the server's network identity and typically
  370. /// belongs to a list of servers supporting DNS for a given domain. It will
  371. /// be used to establish communications with the server to carry out DNS
  372. /// updates.
  373. class DnsServerInfo {
  374. public:
  375. /// @brief defines DNS standard port value
  376. static const uint32_t STANDARD_DNS_PORT = 53;
  377. static const char* STANDARD_DNS_PORT_STR;
  378. /// @brief defines an "empty" string version of an ip address.
  379. static const char* EMPTY_IP_STR;
  380. /// @brief Constructor
  381. ///
  382. /// @param hostname is the resolvable name of the server. If not blank,
  383. /// then the server address should be resolved at runtime.
  384. /// @param ip_address is the static IP address of the server. If hostname
  385. /// is blank, then this address should be used to connect to the server.
  386. /// @param port is the port number on which the server listens.
  387. /// primarily meant for testing purposes. Normally, DNS traffic is on
  388. /// is port 53. (NOTE the constructing code is responsible for setting
  389. /// the default.)
  390. /// @param enabled is a flag that indicates whether this server is
  391. /// enabled for use. It defaults to true.
  392. DnsServerInfo(const std::string& hostname,
  393. isc::asiolink::IOAddress ip_address,
  394. uint32_t port = STANDARD_DNS_PORT,
  395. bool enabled=true);
  396. /// @brief Destructor
  397. virtual ~DnsServerInfo();
  398. /// @brief Getter which returns the server's hostname.
  399. ///
  400. /// @return returns the hostname as as std::string.
  401. const std::string getHostname() const {
  402. return (hostname_);
  403. }
  404. /// @brief Getter which returns the server's port number.
  405. ///
  406. /// @return returns the port number as a unsigned integer.
  407. uint32_t getPort() const {
  408. return (port_);
  409. }
  410. /// @brief Getter which returns the server's ip_address.
  411. ///
  412. /// @return returns the address as an IOAddress reference.
  413. const isc::asiolink::IOAddress& getIpAddress() const {
  414. return (ip_address_);
  415. }
  416. /// @brief Convenience method which returns whether or not the
  417. /// server is enabled.
  418. ///
  419. /// @return returns true if the server is enabled, false otherwise.
  420. bool isEnabled() const {
  421. return (enabled_);
  422. }
  423. /// @brief Sets the server's enabled flag to true.
  424. void enable() {
  425. enabled_ = true;
  426. }
  427. /// @brief Sets the server's enabled flag to false.
  428. void disable() {
  429. enabled_ = false;
  430. }
  431. /// @brief Returns a text representation for the server.
  432. std::string toText() const;
  433. private:
  434. /// @brief The resolvable name of the server. If not blank, then the
  435. /// server's IP address should be dynamically resolved at runtime.
  436. std::string hostname_;
  437. /// @brief The static IP address of the server. When hostname is blank,
  438. /// then this address should be used to connect to the server.
  439. isc::asiolink::IOAddress ip_address_;
  440. /// @brief The port number on which the server listens for DNS traffic.
  441. uint32_t port_;
  442. /// @param enabled is a flag that indicates whether this server is
  443. /// enabled for use. It defaults to true.
  444. bool enabled_;
  445. };
  446. std::ostream&
  447. operator<<(std::ostream& os, const DnsServerInfo& server);
  448. /// @brief Defines a pointer for DnsServerInfo instances.
  449. typedef boost::shared_ptr<DnsServerInfo> DnsServerInfoPtr;
  450. /// @brief Defines a storage container for DnsServerInfo pointers.
  451. typedef std::vector<DnsServerInfoPtr> DnsServerInfoStorage;
  452. /// @brief Defines a pointer to DnsServerInfo storage containers.
  453. typedef boost::shared_ptr<DnsServerInfoStorage> DnsServerInfoStoragePtr;
  454. /// @brief Represents a DNS domain that is may be updated dynamically.
  455. /// This class specifies a DNS domain and the list of DNS servers that support
  456. /// it. It's primary use is to map a domain to the DNS server(s) responsible
  457. /// for it.
  458. /// @todo Currently the name entry for a domain is just an std::string. It
  459. /// may be worthwhile to change this to a dns::Name for purposes of better
  460. /// validation and matching capabilities.
  461. class DdnsDomain {
  462. public:
  463. /// @brief Constructor
  464. ///
  465. /// @param name is the domain name of the domain.
  466. /// @param servers is the list of server(s) supporting this domain.
  467. /// @param tsig_key_info pointer to the TSIGKeyInfo for the domain's key
  468. /// It defaults to an empty pointer, signifying the domain has no key.
  469. DdnsDomain(const std::string& name,
  470. DnsServerInfoStoragePtr servers,
  471. const TSIGKeyInfoPtr& tsig_key_info = TSIGKeyInfoPtr());
  472. /// @brief Destructor
  473. virtual ~DdnsDomain();
  474. /// @brief Getter which returns the domain's name.
  475. ///
  476. /// @return returns the name in an std::string.
  477. const std::string getName() const {
  478. return (name_);
  479. }
  480. /// @brief Convenience method which returns the domain's TSIG key name.
  481. ///
  482. /// @return returns the key name in an std::string. If domain has no
  483. /// TSIG key, the string will empty.
  484. const std::string getKeyName() const;
  485. /// @brief Getter which returns the domain's list of servers.
  486. ///
  487. /// @return returns the pointer to the server storage.
  488. const DnsServerInfoStoragePtr& getServers() {
  489. return (servers_);
  490. }
  491. /// @brief Getter which returns the domain's TSIGKey info
  492. ///
  493. /// @return returns the pointer to the server storage. If the domain
  494. /// is not configured to use TSIG the pointer will be empty.
  495. const TSIGKeyInfoPtr& getTSIGKeyInfo() {
  496. return (tsig_key_info_);
  497. }
  498. private:
  499. /// @brief The domain name of the domain.
  500. std::string name_;
  501. /// @brief The list of server(s) supporting this domain.
  502. DnsServerInfoStoragePtr servers_;
  503. /// @brief Pointer to domain's the TSIGKeyInfo.
  504. /// Value is empty if the domain is not configured for TSIG.
  505. TSIGKeyInfoPtr tsig_key_info_;
  506. };
  507. /// @brief Defines a pointer for DdnsDomain instances.
  508. typedef boost::shared_ptr<DdnsDomain> DdnsDomainPtr;
  509. /// @brief Defines a map of DdnsDomains, keyed by the domain name.
  510. typedef std::map<std::string, DdnsDomainPtr> DdnsDomainMap;
  511. /// @brief Defines a iterator pairing domain name and DdnsDomain
  512. typedef std::pair<std::string, DdnsDomainPtr> DdnsDomainMapPair;
  513. /// @brief Defines a pointer to DdnsDomain storage containers.
  514. typedef boost::shared_ptr<DdnsDomainMap> DdnsDomainMapPtr;
  515. /// @brief Provides storage for and management of a list of DNS domains.
  516. /// In addition to housing the domain list storage, it provides domain matching
  517. /// services. These services are used to match a FQDN to a domain. Currently
  518. /// it supports a single matching service, which will return the matching
  519. /// domain or a wild card domain if one is specified. The wild card domain is
  520. /// specified as a domain whose name is "*". The wild card domain will match
  521. /// any entry and is provided for flexibility in FQDNs If for instance, all
  522. /// forward requests are handled by the same servers, the configuration could
  523. /// specify the wild card domain as the only forward domain. All forward DNS
  524. /// updates would be sent to that one list of servers, regardless of the FQDN.
  525. /// As matching capabilities evolve this class is expected to expand.
  526. class DdnsDomainListMgr {
  527. public:
  528. /// @brief defines the domain name for denoting the wildcard domain.
  529. static const char* wildcard_domain_name_;
  530. /// @brief Constructor
  531. ///
  532. /// @param name is an arbitrary label assigned to this manager.
  533. DdnsDomainListMgr(const std::string& name);
  534. /// @brief Destructor
  535. virtual ~DdnsDomainListMgr ();
  536. /// @brief Matches a given name to a domain based on a longest match
  537. /// scheme.
  538. ///
  539. /// Given a FQDN, search the list of domains, successively removing a
  540. /// sub-domain from the FQDN until a match is found. If no match is found
  541. /// and the wild card domain is present in the list, then return it as the
  542. /// match. If the wild card domain is the only domain in the list, then
  543. /// it will be returned immediately for any FQDN.
  544. ///
  545. /// @param fqdn is the name for which to look.
  546. /// @param domain receives the matching domain. If no match is found its
  547. /// contents will be unchanged.
  548. ///
  549. /// @return returns true if a match is found, false otherwise.
  550. /// @todo This is a very basic match method, which expects valid FQDNs
  551. /// both as input and for the DdnsDomain::getName(). Currently both are
  552. /// simple strings and there is no normalization (i.e. added trailing dots
  553. /// if missing).
  554. virtual bool matchDomain(const std::string& fqdn, DdnsDomainPtr& domain);
  555. /// @brief Fetches the manager's name.
  556. ///
  557. /// @return returns a std::string containing the name of the manager.
  558. const std::string getName() const {
  559. return (name_);
  560. }
  561. /// @brief Returns the number of domains in the domain list.
  562. ///
  563. /// @brief returns an unsigned int containing the domain count.
  564. uint32_t size() const {
  565. return (domains_->size());
  566. }
  567. /// @brief Fetches the wild card domain.
  568. ///
  569. /// @return returns a pointer reference to the domain. The pointer will
  570. /// empty if the wild card domain is not present.
  571. const DdnsDomainPtr& getWildcardDomain() {
  572. return (wildcard_domain_);
  573. }
  574. /// @brief Fetches the domain list.
  575. ///
  576. /// @return returns a pointer reference to the list of domains.
  577. const DdnsDomainMapPtr &getDomains() {
  578. return (domains_);
  579. }
  580. /// @brief Sets the manger's domain list to the given list of domains.
  581. /// This method will scan the inbound list for the wild card domain and
  582. /// set the internal wild card domain pointer accordingly.
  583. void setDomains(DdnsDomainMapPtr domains);
  584. private:
  585. /// @brief An arbitrary label assigned to this manager.
  586. std::string name_;
  587. /// @brief Map of the domains, keyed by name.
  588. DdnsDomainMapPtr domains_;
  589. /// @brief Pointer to the wild card domain.
  590. DdnsDomainPtr wildcard_domain_;
  591. };
  592. /// @brief Defines a pointer for DdnsDomain instances.
  593. typedef boost::shared_ptr<DdnsDomainListMgr> DdnsDomainListMgrPtr;
  594. /// @brief Storage container for scalar configuration parameters.
  595. ///
  596. /// This class is useful for implementing parsers for more complex configuration
  597. /// elements (e.g. those of item type "map"). It provides a convenient way to
  598. /// add storage to the parser for an arbitrary number and variety of scalar
  599. /// configuration items (e.g. ints, bools, strings...) without explicitly adding
  600. /// storage for each individual type needed by the parser.
  601. ///
  602. /// This class implements a concrete version of the base class by supplying a
  603. /// "clone" method.
  604. class DScalarContext : public process::DCfgContextBase {
  605. public:
  606. /// @brief Constructor
  607. DScalarContext() {
  608. };
  609. /// @brief Destructor
  610. virtual ~DScalarContext() {
  611. }
  612. /// @brief Creates a clone of a DStubContext.
  613. ///
  614. /// @return returns a pointer to the new clone.
  615. virtual process::DCfgContextBasePtr clone() {
  616. return (process::DCfgContextBasePtr(new DScalarContext(*this)));
  617. }
  618. protected:
  619. /// @brief Copy constructor
  620. DScalarContext(const DScalarContext& rhs) : DCfgContextBase(rhs) {
  621. }
  622. private:
  623. /// @brief Private assignment operator, not implemented.
  624. DScalarContext& operator=(const DScalarContext& rhs);
  625. };
  626. /// @brief Defines a pointer for DScalarContext instances.
  627. typedef boost::shared_ptr<DScalarContext> DScalarContextPtr;
  628. /// @brief Parser for TSIGKeyInfo
  629. ///
  630. /// This class parses the configuration element "tsig-key" defined in
  631. /// src/bin/d2/dhcp-ddns.spec and creates an instance of a TSIGKeyInfo.
  632. class TSIGKeyInfoParser : public data::SimpleParser {
  633. public:
  634. /// @brief Constructor
  635. TSIGKeyInfoParser(){};
  636. /// @brief Destructor
  637. virtual ~TSIGKeyInfoParser(){};
  638. /// @brief Performs the actual parsing of the given "tsig-key" element.
  639. ///
  640. /// Parses a configuration for the elements needed to instantiate a
  641. /// TSIGKeyInfo, validates those entries, creates a TSIGKeyInfo instance
  642. ///
  643. /// @param key_config is the "tsig-key" configuration to parse
  644. ///
  645. /// @return pointer to the new TSIGKeyInfo instance
  646. TSIGKeyInfoPtr parse(data::ConstElementPtr key_config);
  647. private:
  648. };
  649. /// @brief Parser for a list of TSIGKeyInfos
  650. ///
  651. /// This class parses a list of "tsig-key" configuration elements.
  652. /// (see src/bin/d2/dhcp-ddns.spec). The TSIGKeyInfo instances are added
  653. /// to the given storage upon commit.
  654. class TSIGKeyInfoListParser : public data::SimpleParser {
  655. public:
  656. /// @brief Constructor
  657. TSIGKeyInfoListParser(){};
  658. /// @brief Destructor
  659. virtual ~TSIGKeyInfoListParser(){};
  660. /// @brief Performs the parsing of the given list "tsig-key" elements.
  661. ///
  662. /// Creates an emtpy TSIGKeyInfoMap
  663. ///
  664. /// It iterates over each key entry in the list:
  665. /// 1. Instantiate a TSIGKeyInfoParser for the entry
  666. /// 2. Pass the element configuration to the parser's parse method
  667. /// 3. Add the new TSIGKeyInfo instance to the key map
  668. ///
  669. /// @param key_list_config is the list of "tsig_key" elements to parse.
  670. ///
  671. /// @return a map containing the TSIGKeyInfo instances
  672. TSIGKeyInfoMapPtr parse(data::ConstElementPtr key_list_config);
  673. };
  674. /// @brief Parser for DnsServerInfo
  675. ///
  676. /// This class parses the configuration element "dns-server" defined in
  677. /// src/bin/d2/dhcp-ddns.spec and creates an instance of a DnsServerInfo.
  678. class DnsServerInfoParser : public data::SimpleParser {
  679. public:
  680. /// @brief Constructor
  681. DnsServerInfoParser(){};
  682. /// @brief Destructor
  683. virtual ~DnsServerInfoParser(){};
  684. /// @brief Performs the actual parsing of the given "dns-server" element.
  685. ///
  686. /// Parses a configuration for the elements needed to instantiate a
  687. /// DnsServerInfo, validates those entries, creates a DnsServerInfo instance
  688. /// and returns it.
  689. ///
  690. /// @param server_config is the "dns-server" configuration to parse
  691. ///
  692. /// @return a pointer to the newly created server instance
  693. ///
  694. /// @throw D2CfgError if:
  695. /// -# hostname is not blank, hostname is not yet supported
  696. /// -# ip_address is invalid
  697. /// -# port is 0
  698. DnsServerInfoPtr parse(data::ConstElementPtr server_config);
  699. };
  700. /// @brief Parser for a list of DnsServerInfos
  701. ///
  702. /// This class parses a list of "dns-server" configuration elements.
  703. /// (see src/bin/d2/dhcp-ddns.spec). The DnsServerInfo instances are added
  704. /// to the given storage upon commit.
  705. class DnsServerInfoListParser : public data::SimpleParser{
  706. public:
  707. /// @brief Constructor
  708. DnsServerInfoListParser(){};
  709. /// @brief Destructor
  710. virtual ~DnsServerInfoListParser(){};
  711. /// @brief Performs the actual parsing of the given list "dns-server"
  712. /// elements.
  713. ///
  714. /// Creates an empty server list
  715. /// It iterates over each server entry in the list:
  716. /// 1. Creates a server instance by passing the entry to @c
  717. /// DnsSeverInfoParser::parse()
  718. /// 2. Adds the server to the server list
  719. ///
  720. /// @param server_list_config is the list of "dns-server" elements to parse.
  721. /// @return A pointer to the new, populated server list
  722. DnsServerInfoStoragePtr parse(data::ConstElementPtr server_list_config);
  723. };
  724. /// @brief Parser for DdnsDomain
  725. ///
  726. /// This class parses the configuration element "ddns-domain" defined in
  727. /// src/bin/d2/dhcp-ddns.spec and creates an instance of a DdnsDomain.
  728. class DdnsDomainParser : public data::SimpleParser {
  729. public:
  730. /// @brief Constructor
  731. DdnsDomainParser(){};
  732. /// @brief Destructor
  733. virtual ~DdnsDomainParser(){};
  734. /// @brief Performs the actual parsing of the given "ddns-domain" element.
  735. ///
  736. /// Parses a configuration for the elements needed to instantiate a
  737. /// DdnsDomain, validates those entries, and creates a DdnsDomain instance.
  738. ///
  739. /// @param domain_config is the "ddns-domain" configuration to parse
  740. /// @param keys map of defined TSIG keys
  741. ///
  742. /// @return a pointer to the new domain instance
  743. DdnsDomainPtr parse(data::ConstElementPtr domain_config,
  744. const TSIGKeyInfoMapPtr keys);
  745. };
  746. /// @brief Parser for a list of DdnsDomains
  747. ///
  748. /// This class parses a list of "ddns-domain" configuration elements.
  749. /// (see src/bin/d2/dhcp-ddns.spec) into a map of DdnsDomains.
  750. class DdnsDomainListParser : public data::SimpleParser {
  751. public:
  752. /// @brief Constructor
  753. DdnsDomainListParser(){};
  754. /// @brief Destructor
  755. virtual ~DdnsDomainListParser(){};
  756. /// @brief Performs the actual parsing of the given list "ddns-domain"
  757. /// elements.
  758. /// Creates a new DdnsDomain map
  759. /// It iterates over each domain entry in the list:
  760. /// 1. Creates a DdnsDomain instance by passing the entry into @c
  761. /// DdnsDomainParser::parser()
  762. /// 2. Adds the DdnsDomain instance to the domain map
  763. ///
  764. /// @param domain_list_config is the list of "ddns-domain" elements to
  765. /// parse.
  766. /// @param keys map of defined TSIG keys
  767. /// @return a pointer to the newly populated domain map
  768. DdnsDomainMapPtr parse(data::ConstElementPtr domain_list_config,
  769. const TSIGKeyInfoMapPtr keys);
  770. };
  771. /// @brief Parser for DdnsDomainListMgr
  772. ///
  773. /// This class parses the configuration elements "forward-ddns" and
  774. /// "reverse-ddns" as defined in src/bin/d2/dhcp-ddns.spec. It populates the
  775. /// given DdnsDomainListMgr with parsed information.
  776. class DdnsDomainListMgrParser : public data::SimpleParser {
  777. public:
  778. /// @brief Constructor
  779. DdnsDomainListMgrParser(){};
  780. /// @brief Destructor
  781. virtual ~DdnsDomainListMgrParser(){};
  782. /// @brief Performs the actual parsing of the given manager element.
  783. ///
  784. /// Parses a configuration for the elements needed to instantiate a
  785. /// DdnsDomainListMgr, validates those entries, then creates a
  786. /// DdnsDomainListMgr.
  787. ///
  788. /// @param mgr_config manager configuration to parse
  789. /// @param mgr_name convenience label for the manager instance
  790. /// @param keys map of defined TSIG keys
  791. ///
  792. /// @return a pointer to the new manager instance
  793. DdnsDomainListMgrPtr parse(data::ConstElementPtr mgr_config,
  794. const std::string& mgr_name,
  795. const TSIGKeyInfoMapPtr keys);
  796. };
  797. }; // end of isc::d2 namespace
  798. }; // end of isc namespace
  799. #endif // D2_CONFIG_H