cfgmgr.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // Copyright (C) 2012 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 <string>
  17. #include <map>
  18. #include <vector>
  19. #include <boost/shared_ptr.hpp>
  20. #include <boost/noncopyable.hpp>
  21. #include <asiolink/io_address.h>
  22. #include <util/buffer.h>
  23. #include <dhcp/option.h>
  24. namespace isc {
  25. namespace dhcp {
  26. class Pool6;
  27. class Subnet6;
  28. /// @brief this template specifes a parameter value
  29. ///
  30. /// This template class is used to store configuration parameters, like lifetime or T1.
  31. /// It defines 3 parameters: min, default, and max value. There are 2 constructors:
  32. /// - simple (just one value that sets all parameters)
  33. /// - extended (that sets default value and two thresholds)
  34. /// It will be used with integer types. It provides necessary operators, so
  35. /// it can be assigned to a plain integer or integer assigned to a Triplet.
  36. /// See TripletTest.operator test for details on an easy Triplet usage.
  37. template <class T>
  38. class Triplet {
  39. public:
  40. /// @brief base type to Triple conversion
  41. ///
  42. /// Typically: uint32_t to Triplet assignment. It is very convenient
  43. /// to be able to simply write Triplet<uint32_t> x = 7;
  44. Triplet<T>& operator = (T base_type) {
  45. return Triplet<T>(base_type);
  46. }
  47. /// @brief triplet to base type conversion
  48. ///
  49. /// Typically: Triplet to uint32_t assignment. It is very convenient
  50. /// to be able to simply write uint32_t z = x; (where x is a Triplet)
  51. operator T () const {
  52. return (default_);
  53. }
  54. /// @brief sets a fixed value
  55. ///
  56. /// This constructor assigns a fixed (i.e. no range, just a single value)
  57. /// value.
  58. Triplet(T value)
  59. :min_(value), default_(value), max_(value) {
  60. }
  61. /// @brief sets the default value and thresholds
  62. ///
  63. /// @throw BadValue if min <= def <= max rule is violated
  64. Triplet(T min, T def, T max)
  65. :min_(min), default_(def), max_(max) {
  66. if ( (min_>def) || (def > max_) ) {
  67. isc_throw(BadValue, "Invalid triplet values.");
  68. }
  69. }
  70. /// @brief returns a minimum allowed value
  71. T getMin() const { return min_;}
  72. /// @brief returns the default value
  73. T get() const { return default_;}
  74. /// @brief returns value with a hint
  75. ///
  76. /// DHCP protocol treats any values sent by a client as hints.
  77. /// This is a method that implements that. We can assign any value
  78. /// from configured range that client asks.
  79. T get(T hint) const {
  80. if (hint <= min_) {
  81. return (min_);
  82. }
  83. if (hint >= max_) {
  84. return (max_);
  85. }
  86. return (hint);
  87. }
  88. /// @brief returns a maximum allowed value
  89. T getMax() const { return max_; }
  90. protected:
  91. /// @brief the minimum value
  92. T min_;
  93. /// @brief the default value
  94. T default_;
  95. /// @brief the maximum value
  96. T max_;
  97. };
  98. /// @brief base class for Pool4 and Pool6
  99. ///
  100. /// Stores information about pool of IPv4 or IPv6 addresses.
  101. /// That is a basic component of a configuration.
  102. class Pool {
  103. public:
  104. uint32_t getId() const {
  105. return (id_);
  106. }
  107. const isc::asiolink::IOAddress& getFirstAddress() const {
  108. return (first_);
  109. }
  110. const isc::asiolink::IOAddress& getLastAddress() const {
  111. return (last_);
  112. }
  113. /// @brief checks if specified address is in range
  114. bool inRange(const isc::asiolink::IOAddress& addr);
  115. protected:
  116. /// @brief protected constructor
  117. Pool(const isc::asiolink::IOAddress& first,
  118. const isc::asiolink::IOAddress& last);
  119. static uint32_t getNextID() {
  120. static uint32_t id = 0;
  121. return (id++);
  122. }
  123. /// @brief pool-id
  124. ///
  125. /// This ID is used to indentify this specific pool.
  126. uint32_t id_;
  127. isc::asiolink::IOAddress first_;
  128. isc::asiolink::IOAddress last_;
  129. std::string comments_;
  130. ///uint128_t available_leases_;
  131. ///uint128_t total_leases_;
  132. };
  133. class Pool6 : public Pool {
  134. public:
  135. typedef enum {
  136. TYPE_IA,
  137. TYPE_TA,
  138. TYPE_PD
  139. } Pool6Type;
  140. Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
  141. const isc::asiolink::IOAddress& last);
  142. Pool6(Pool6Type type, const isc::asiolink::IOAddress& addr,
  143. uint8_t prefix_len);
  144. Pool6Type getType() const {
  145. return (type_);
  146. }
  147. protected:
  148. Pool6Type type_;
  149. /// @brief prefix length
  150. /// used by TYPE_PD only (zeroed for other types)
  151. uint8_t prefix_len_;
  152. };
  153. typedef boost::shared_ptr<Pool> PoolPtr;
  154. typedef boost::shared_ptr<Pool6> Pool6Ptr;
  155. typedef std::vector<Pool6Ptr> Pool6Collection;
  156. class Subnet {
  157. public:
  158. /// @brief checks if specified address is in range
  159. bool inRange(const isc::asiolink::IOAddress& addr);
  160. Triplet<uint32_t> getValid() const {
  161. return (valid_);
  162. }
  163. Triplet<uint32_t> getT1() const {
  164. return (t1_);
  165. }
  166. Triplet<uint32_t> getT2() const {
  167. return (t2_);
  168. }
  169. protected:
  170. /// @brief protected constructor
  171. //
  172. /// By making the constructor protected, we make sure that noone will
  173. /// ever instantiate that class. Pool4 and Pool6 should be used instead.
  174. Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
  175. const Triplet<uint32_t>& t1,
  176. const Triplet<uint32_t>& t2,
  177. const Triplet<uint32_t>& valid_lifetime);
  178. static uint32_t getNextID() {
  179. static uint32_t id = 0;
  180. return (id++);
  181. }
  182. /// @brief subnet-id
  183. uint32_t id_;
  184. isc::asiolink::IOAddress prefix_;
  185. uint8_t prefix_len_;
  186. Pool6Collection pool_;
  187. Triplet<uint32_t> t1_;
  188. Triplet<uint32_t> t2_;
  189. Triplet<uint32_t> valid_;
  190. };
  191. class Subnet6 : public Subnet {
  192. public:
  193. Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
  194. const Triplet<uint32_t>& t1,
  195. const Triplet<uint32_t>& t2,
  196. const Triplet<uint32_t>& preferred_lifetime,
  197. const Triplet<uint32_t>& valid_lifetime);
  198. Triplet<uint32_t> getPreferred() const {
  199. return (preferred_);
  200. }
  201. Pool6Ptr getPool6(const isc::asiolink::IOAddress& hint =
  202. isc::asiolink::IOAddress("::"));
  203. void addPool6(const Pool6Ptr& pool);
  204. const Pool6Collection& getPools() const {
  205. return pools_;
  206. }
  207. protected:
  208. /// collection of pools in that list
  209. Pool6Collection pools_;
  210. Triplet<uint32_t> preferred_;
  211. };
  212. typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
  213. typedef std::vector<Subnet6Ptr> Subnet6Collection;
  214. /// @brief Configuration Manager
  215. ///
  216. /// This singleton class holds the whole configuration for DHCPv4 and DHCPv6
  217. /// servers. It currently holds information about zero or more subnets6.
  218. /// Each subnet may contain zero or more pools. Pool4 and Pool6 is the most
  219. /// basic "chunk" of configuration. It contains a range of assigneable
  220. /// addresses.
  221. ///
  222. /// The sketch of configuration inheritance (it is not implemented yet).
  223. /// Let's investigate the following configuration:
  224. ///
  225. /// valid-lifetime 1000;
  226. /// subnet6 2001:db8:1::/48 {
  227. /// pool6 2001::db8:1::1 - 2001::db8:1::ff;
  228. /// };
  229. /// subnet6 2001:db8:2::/48 {
  230. /// valid-lifetime 2000;
  231. /// pool6 2001::db8:2::1 - 2001::db8:2::ff;
  232. /// };
  233. /// Parameters defined in a global scope are considered valid until
  234. /// they are overwritten in a smaller scope, in this case subnet6.
  235. /// In the example above, the first subnet6
  236. ///
  237. /// @todo: Implement Subnet4 support (ticket #2237)
  238. /// @todo: Implement option definition support
  239. /// @todo: Implement inheritance.
  240. class CfgMgr : public boost::noncopyable {
  241. public:
  242. static CfgMgr& instance();
  243. /// @brief get subnet by address
  244. ///
  245. /// Finds a matching subnet, based on an address. This can be used
  246. /// in two cases: when trying to find an appropriate lease based on
  247. /// a) relay link address (that must be the address that is on link)
  248. /// b) our global address on the interface the message was received on
  249. /// (for directly connected clients)
  250. Subnet6Ptr getSubnet6(const isc::asiolink::IOAddress& hint);
  251. /// @brief get subnet by interface-id
  252. ///
  253. /// Another possibility is to find a subnet based on interface-id.
  254. /// @todo This method is not currently supported.
  255. Subnet6Ptr getSubnet6(OptionPtr interfaceId);
  256. void addSubnet6(const Subnet6Ptr& subnet);
  257. protected:
  258. /// @brief Protected constructor.
  259. CfgMgr();
  260. virtual ~CfgMgr();
  261. Subnet6Collection subnets6_;
  262. };
  263. } // namespace isc::dhcp
  264. } // namespace isc
  265. #endif