cfgmgr.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. // Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef CFGMGR_H
  15. #define CFGMGR_H
  16. #include <asiolink/io_address.h>
  17. #include <dhcp/option.h>
  18. #include <dhcp/option_space.h>
  19. #include <dhcp/classify.h>
  20. #include <dhcpsrv/d2_client_mgr.h>
  21. #include <dhcpsrv/pool.h>
  22. #include <dhcpsrv/subnet.h>
  23. #include <dhcpsrv/srv_config.h>
  24. #include <util/buffer.h>
  25. #include <boost/shared_ptr.hpp>
  26. #include <boost/noncopyable.hpp>
  27. #include <map>
  28. #include <string>
  29. #include <vector>
  30. #include <list>
  31. namespace isc {
  32. namespace dhcp {
  33. /// @brief Exception thrown when the same interface has been specified twice.
  34. ///
  35. /// In particular, this exception is thrown when adding interface to the set
  36. /// of interfaces on which server is supposed to listen.
  37. class DuplicateListeningIface : public Exception {
  38. public:
  39. DuplicateListeningIface(const char* file, size_t line, const char* what) :
  40. isc::Exception(file, line, what) { };
  41. };
  42. /// @brief Configuration Manager
  43. ///
  44. /// This singleton class holds the whole configuration for DHCPv4 and DHCPv6
  45. /// servers. It currently holds information about zero or more subnets6.
  46. /// Each subnet may contain zero or more pools. Pool4 and Pool6 is the most
  47. /// basic "chunk" of configuration. It contains a range of assignable
  48. /// addresses.
  49. ///
  50. /// Below is a sketch of configuration inheritance (not implemented yet).
  51. /// Let's investigate the following configuration:
  52. ///
  53. /// @code
  54. /// preferred-lifetime 500;
  55. /// valid-lifetime 1000;
  56. /// subnet6 2001:db8:1::/48 {
  57. /// pool6 2001::db8:1::1 - 2001::db8:1::ff;
  58. /// };
  59. /// subnet6 2001:db8:2::/48 {
  60. /// valid-lifetime 2000;
  61. /// pool6 2001::db8:2::1 - 2001::db8:2::ff;
  62. /// };
  63. /// @endcode
  64. ///
  65. /// Parameters defined in a global scope are applicable to everything until
  66. /// they are overwritten in a smaller scope, in this case subnet6.
  67. /// In the example above, the first subnet6 has preferred lifetime of 500s
  68. /// and a valid lifetime of 1000s. The second subnet has preferred lifetime
  69. /// of 500s, but valid lifetime of 2000s.
  70. ///
  71. /// Parameter inheritance is likely to be implemented in configuration handling
  72. /// routines, so there is no storage capability in a global scope for
  73. /// subnet-specific parameters.
  74. ///
  75. /// @todo: Implement Subnet4 support (ticket #2237)
  76. /// @todo: Implement option definition support
  77. /// @todo: Implement parameter inheritance
  78. class CfgMgr : public boost::noncopyable {
  79. public:
  80. /// @brief A number of configurations held by @c CfgMgr.
  81. ///
  82. /// @todo Make it configurable.
  83. static const size_t CONFIG_LIST_SIZE;
  84. /// @brief returns a single instance of Configuration Manager
  85. ///
  86. /// CfgMgr is a singleton and this method is the only way of
  87. /// accessing it.
  88. static CfgMgr& instance();
  89. /// @brief Adds new DHCPv4 option space to the collection.
  90. ///
  91. /// @param space option space to be added.
  92. ///
  93. /// @throw isc::dhcp::InvalidOptionSpace invalid option space
  94. /// has been specified.
  95. void addOptionSpace4(const OptionSpacePtr& space);
  96. /// @brief Adds new DHCPv6 option space to the collection.
  97. ///
  98. /// @param space option space to be added.
  99. ///
  100. /// @throw isc::dhcp::InvalidOptionSpace invalid option space
  101. /// has been specified.
  102. void addOptionSpace6(const OptionSpacePtr& space);
  103. /// @brief Return option spaces for DHCPv4.
  104. ///
  105. /// @return A collection of option spaces.
  106. const OptionSpaceCollection& getOptionSpaces4() const {
  107. return (spaces4_);
  108. }
  109. /// @brief Return option spaces for DHCPv6.
  110. ///
  111. /// @return A collection of option spaces.
  112. const OptionSpaceCollection& getOptionSpaces6() const {
  113. return (spaces6_);
  114. }
  115. /// @brief returns path do the data directory
  116. ///
  117. /// This method returns a path to writeable directory that DHCP servers
  118. /// can store data in.
  119. /// @return data directory
  120. std::string getDataDir();
  121. /// @brief Sets whether server should send back client-id in DHCPv4
  122. ///
  123. /// This is a compatibility flag. The default (true) is compliant with
  124. /// RFC6842. False is for backward compatibility.
  125. ///
  126. /// @param echo should the client-id be sent or not
  127. void echoClientId(const bool echo) {
  128. echo_v4_client_id_ = echo;
  129. }
  130. /// @brief Returns whether server should send back client-id in DHCPv4.
  131. /// @return true if client-id should be returned, false otherwise.
  132. bool echoClientId() const {
  133. return (echo_v4_client_id_);
  134. }
  135. /// @brief Updates the DHCP-DDNS client configuration to the given value.
  136. ///
  137. /// @param new_config pointer to the new client configuration.
  138. ///
  139. /// @throw Underlying method(s) will throw D2ClientError if given an empty
  140. /// pointer.
  141. void setD2ClientConfig(D2ClientConfigPtr& new_config);
  142. /// @brief Convenience method for checking if DHCP-DDNS updates are enabled.
  143. ///
  144. /// @return True if the D2 configuration is enabled.
  145. bool ddnsEnabled();
  146. /// @brief Fetches the DHCP-DDNS configuration pointer.
  147. ///
  148. /// @return a reference to the current configuration pointer.
  149. const D2ClientConfigPtr& getD2ClientConfig() const;
  150. /// @brief Fetches the DHCP-DDNS manager.
  151. ///
  152. /// @return a reference to the DHCP-DDNS manager.
  153. D2ClientMgr& getD2ClientMgr();
  154. /// @name Methods managing the collection of configurations.
  155. ///
  156. /// The following methods manage the process of preparing a configuration
  157. /// without affecting a currently used configuration and then commiting
  158. /// the configuration to replace current configuration atomically.
  159. /// They also allow for keeping a history of previous configurations so
  160. /// as the @c CfgMgr can revert to the historical configuration when
  161. /// required.
  162. ///
  163. /// @todo Migrate all configuration parameters to use the model supported
  164. /// by these functions.
  165. ///
  166. /// @todo Make the size of the configurations history configurable.
  167. ///
  168. //@{
  169. /// @brief Removes current, staging and all previous configurations.
  170. ///
  171. /// This function removes all configurations, including current and
  172. /// staging configurations. It creates a new current configuration with
  173. /// default settings.
  174. ///
  175. /// This function is exception safe.
  176. void clear();
  177. /// @brief Commits the staging configuration.
  178. ///
  179. /// The staging configuration becomes current configuration when this
  180. /// function is called. It removes the oldest configuration held in the
  181. /// history so as the size of the list of configuration does not exceed
  182. /// the @c CONFIG_LIST_SIZE.
  183. ///
  184. /// This function is exception safe.
  185. void commit();
  186. /// @brief Removes staging configuration.
  187. ///
  188. /// This function should be called when there is a staging configuration
  189. /// (likely created in the previous configuration attempt) but the entirely
  190. /// new configuration should be created. It removes the existing staging
  191. /// configuration and the next call to @c CfgMgr::getStagingCfg will return a
  192. /// fresh (default) configuration.
  193. ///
  194. /// This function is exception safe.
  195. void rollback();
  196. /// @brief Reverts to one of the previous configurations.
  197. ///
  198. /// This function reverts to selected previous configuration. The previous
  199. /// configuration is entirely copied to a new @c SrvConfig instance. This
  200. /// new instance has a unique sequence id (sequence id is not copied). The
  201. /// previous configuration (being copied) is not modified by this operation.
  202. ///
  203. /// The configuration to be copied is identified by the index value which
  204. /// is the distance between the current (most recent) and desired
  205. /// configuration. If the index is out of range an exception is thrown.
  206. ///
  207. /// @warning Revert operation will rollback any changes to the staging
  208. /// configuration (if it exists).
  209. ///
  210. /// @warning This function requires that the entire previous configuration
  211. /// is copied to the new configuration object. This is not working for
  212. /// some of the complex configuration objects, e.g. subnets. Hence, the
  213. /// "revert" operation is not really usable at this point.
  214. ///
  215. /// @param index A distance from the current configuration to the
  216. /// past configuration to be reverted. The minimal value is 1 which points
  217. /// to the nearest configuration.
  218. ///
  219. /// @throw isc::OutOfRange if the specified index is out of range.
  220. void revert(const size_t index);
  221. /// @brief Returns a pointer to the current configuration.
  222. ///
  223. /// This function returns pointer to the current configuration. If the
  224. /// current configuration is not set it will create a default configuration
  225. /// and return it. Current configuration returned is read-only.
  226. ///
  227. /// @return Non-null const pointer to the current configuration.
  228. ConstSrvConfigPtr getCurrentCfg();
  229. /// @brief Returns a pointer to the staging configuration.
  230. ///
  231. /// The staging configuration is used by the configuration parsers to
  232. /// create new configuration. The staging configuration doesn't affect the
  233. /// server's operation until it is committed. The staging configuration
  234. /// is a non-const object which can be modified by the caller.
  235. ///
  236. /// Multiple consecutive calls to this function return the same object
  237. /// which can be modified from various places of the code (e.g. various
  238. /// configuration parsers).
  239. ///
  240. /// @return non-null pointer to the staging configuration.
  241. SrvConfigPtr getStagingCfg();
  242. //@}
  243. /// @name Methods setting/accessing global configuration for the process.
  244. ///
  245. //@{
  246. /// @brief Sets verbose mode.
  247. ///
  248. /// @param verbose A boolean value indicating if the process should run
  249. /// in verbose (true) or non-verbose mode.
  250. void setVerbose(const bool verbose) {
  251. verbose_mode_ = verbose;
  252. }
  253. /// @brief Checks if the process has been run in verbose mode.
  254. ///
  255. /// @return true if verbose mode enabled, false otherwise.
  256. bool isVerbose() const {
  257. return (verbose_mode_);
  258. }
  259. /// @brief Sets the default logger name.
  260. ///
  261. /// This name is used in cases when a user doesn't provide a configuration
  262. /// for logger in the Kea configuration file.
  263. void setDefaultLoggerName(const std::string& name) {
  264. default_logger_name_ = name;
  265. }
  266. /// @brief Returns default logger name.
  267. std::string getDefaultLoggerName() const {
  268. return (default_logger_name_);
  269. }
  270. //@}
  271. protected:
  272. /// @brief Protected constructor.
  273. ///
  274. /// This constructor is protected for 2 reasons. First, it forbids any
  275. /// instantiations of this class (CfgMgr is a singleton). Second, it
  276. /// allows derived class to instantiate it. That is useful for testing
  277. /// purposes.
  278. CfgMgr();
  279. /// @brief virtual destructor
  280. virtual ~CfgMgr();
  281. /// @brief a container for IPv6 subnets.
  282. ///
  283. /// That is a simple vector of pointers. It does not make much sense to
  284. /// optimize access time (e.g. using a map), because typical search
  285. /// pattern will use calling inRange() method on each subnet until
  286. /// a match is found.
  287. Subnet6Collection subnets6_;
  288. private:
  289. /// @brief Checks if current configuration is created and creates it if needed.
  290. ///
  291. /// This private method is called to ensure that the current configuration
  292. /// is created. If current configuration is not set, it creates the
  293. /// default current configuration.
  294. void ensureCurrentAllocated();
  295. /// @brief Checks that the IPv6 subnet with the given id already exists.
  296. ///
  297. /// @param subnet Subnet for which this function will check if the other
  298. /// subnet with equal id already exists.
  299. /// @return true if the duplicate subnet exists.
  300. bool isDuplicate(const Subnet6& subnet) const;
  301. /// @brief Updates statistics.
  302. ///
  303. /// This method updates statistics that are affected by the newly committed
  304. /// configuration. In particular, it updates the number of available addresses
  305. /// in each subnet. Other statistics may be added in the future. In general,
  306. /// these are statistics that are dependant only on configuration, so they are
  307. /// not expected to change until the next reconfiguration event.
  308. void updateStatistics();
  309. /// @brief Removes statistics.
  310. ///
  311. /// During commitment of a new configuration, we need to get rid of the old
  312. /// statistics for the old configuration. In particular, we need to remove
  313. /// anything related to subnets, as there may be fewer subnets in the new
  314. /// configuration and also subnet-ids may change.
  315. void removeStatistics();
  316. /// @brief Container for defined DHCPv6 option spaces.
  317. OptionSpaceCollection spaces6_;
  318. /// @brief Container for defined DHCPv4 option spaces.
  319. OptionSpaceCollection spaces4_;
  320. /// @brief directory where data files (e.g. server-id) are stored
  321. std::string datadir_;
  322. /// Indicates whether v4 server should send back client-id
  323. bool echo_v4_client_id_;
  324. /// @brief Manages the DHCP-DDNS client and its configuration.
  325. D2ClientMgr d2_client_mgr_;
  326. /// @brief Server configuration
  327. ///
  328. /// This is a structure that will hold all configuration.
  329. /// @todo: migrate all other parameters to that structure.
  330. SrvConfigPtr configuration_;
  331. /// @name Configuration List.
  332. ///
  333. //@{
  334. /// @brief Server configuration list type.
  335. typedef std::list<SrvConfigPtr> SrvConfigList;
  336. /// @brief Container holding all previous and current configurations.
  337. SrvConfigList configs_;
  338. //@}
  339. /// @brief Indicates if a process has been ran in the verbose mode.
  340. bool verbose_mode_;
  341. /// @brief Default logger name.
  342. std::string default_logger_name_;
  343. };
  344. } // namespace isc::dhcp
  345. } // namespace isc
  346. #endif // CFGMGR_H