host_mgr.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // Copyright (C) 2014-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 HOST_MGR_H
  7. #define HOST_MGR_H
  8. #include <dhcp/duid.h>
  9. #include <dhcp/hwaddr.h>
  10. #include <dhcpsrv/base_host_data_source.h>
  11. #include <dhcpsrv/host.h>
  12. #include <dhcpsrv/subnet_id.h>
  13. #include <boost/noncopyable.hpp>
  14. #include <boost/scoped_ptr.hpp>
  15. #include <string>
  16. namespace isc {
  17. namespace dhcp {
  18. /// @brief Host Manager.
  19. ///
  20. /// This is a singleton class which provides access to multiple sources of
  21. /// information about static host reservations. These sources are also referred
  22. /// to as host data sources. Each source derives (directly or indirectly) from
  23. /// the @c BaseHostDataSource.
  24. ///
  25. /// The @c HostMgr is a central point for providing information about the host
  26. /// reservations. Internally, it relays the queries (calls to the appropriate
  27. /// methods declared in the @c BaseHostDataSource) to the data sources it is
  28. /// connected to. The @c HostMgr is always connected to the server's
  29. /// configuration, accessible through the @c CfgHosts object in the @c CfgMgr.
  30. /// The @c CfgHosts object holds all reservations specified in the DHCP server
  31. /// configuration file. If a particular reservation is not found in the
  32. /// @c CfgHosts object, the @c HostMgr will try to find it using the alternate
  33. /// host data storage. The alternate host data storage is usually a database
  34. /// (e.g. SQL database), accessible through a dedicated host data source
  35. /// object (a.k.a. database backend). This datasource is responsible for
  36. /// managing the connection with the database and forming appropriate queries
  37. /// to retrieve (or update) the information about the reservations.
  38. ///
  39. /// The use of the alternate host data source is optional and usually requires
  40. /// additional configuration to be specified by the server administrator.
  41. /// For example, for the SQL database the user's credentials, database address,
  42. /// and database name are required. The @c HostMgr passes these parameters
  43. /// to an appropriate datasource which is responsible for opening a connection
  44. /// and maintaining it.
  45. ///
  46. /// It is possible to switch to a different alternate data source or disable
  47. /// the use of the alternate datasource, e.g. as a result of server's
  48. /// reconfiguration. However, the use of the primary host data source (i.e.
  49. /// reservations specified in the configuration file) can't be disabled.
  50. ///
  51. /// @todo Implement alternate host data sources: MySQL, PostgreSQL, etc.
  52. class HostMgr : public boost::noncopyable, public BaseHostDataSource {
  53. public:
  54. /// @brief Creates new instance of the @c HostMgr.
  55. ///
  56. /// If an instance of the @c HostMgr already exists, it will be replaced
  57. /// by the new instance. Thus, any instances of the alternate host data
  58. /// sources will be dropped.
  59. ///
  60. /// @param access Host data source access parameters for the alternate
  61. /// host data source. It holds "keyword=value" pairs, separated by spaces.
  62. /// The supported values are specific to the alternate data source in use.
  63. /// However, the "type" parameter will be common and it will specify which
  64. /// data source is to be used. Currently, no parameters are supported
  65. /// and the parameter is ignored.
  66. static void create(const std::string& access = "");
  67. /// @brief Returns a sole instance of the @c HostMgr.
  68. ///
  69. /// This method should be used to retrieve an instance of the @c HostMgr
  70. /// to be used to gather/manage host reservations. It returns an instance
  71. /// of the @c HostMgr created by the @c create method. If such instance
  72. /// doesn't exist yet, it is created using the @c create method with the
  73. /// default value of the data access string, which configures the host
  74. /// manager to not use the alternate host data source.
  75. static HostMgr& instance();
  76. /// @brief Returns all hosts for the specified HW address or DUID.
  77. ///
  78. /// This method returns all @c Host objects representing reservations for
  79. /// the specified HW address or/and DUID as documented in the
  80. /// @c BaseHostDataSource::getAll.
  81. ///
  82. /// It retrieves reservations from both primary and alternate host data
  83. /// source as a single collection of @c Host objects, i.e. if matching
  84. /// reservations are in both sources, all of them are returned. The
  85. /// reservations from the primary data source are placed before the
  86. /// reservations from the alternate source.
  87. ///
  88. /// Note that returned collection may contain duplicates. It is the
  89. /// caller's responsibility to check for duplicates.
  90. ///
  91. /// @param hwaddr HW address of the client or NULL if no HW address
  92. /// available.
  93. /// @param duid client id or NULL of not available.
  94. ///
  95. /// @return Collection of const @c Host objects.
  96. virtual ConstHostCollection
  97. getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const;
  98. /// @brief Return all hosts connected to any subnet for which reservations
  99. /// have been made using a specified identifier.
  100. ///
  101. /// This method returns all @c Host objects representing reservations for
  102. /// a specified identifier as documented in the
  103. /// @c BaseHostDataSource::getAll.
  104. ///
  105. /// It retrieves reservations from both primary and alternate host data
  106. /// source as a single collection of @c Host objects, i.e. if matching
  107. /// reservations are in both sources, all of them are returned. The
  108. /// reservations from the primary data source are placed before the
  109. /// reservations from the alternate source.
  110. ///
  111. /// @param identifier_type Identifier type.
  112. /// @param identifier_begin Pointer to a beginning of a buffer containing
  113. /// an identifier.
  114. /// @param identifier_len Identifier length.
  115. ///
  116. /// @return Collection of const @c Host objects.
  117. virtual ConstHostCollection
  118. getAll(const Host::IdentifierType& identifier_type,
  119. const uint8_t* identifier_begin,
  120. const size_t identifier_len) const;
  121. /// @brief Returns a collection of hosts using the specified IPv4 address.
  122. ///
  123. /// This method may return multiple @c Host objects if they are connected to
  124. /// different subnets.
  125. ///
  126. /// If matching reservations are both in the primary and the alternate
  127. /// data source, all of them are returned. The reservations from the
  128. /// primary data source are placed before the reservations from the
  129. /// alternate source.
  130. ///
  131. /// @param address IPv4 address for which the @c Host object is searched.
  132. ///
  133. /// @return Collection of const @c Host objects.
  134. virtual ConstHostCollection
  135. getAll4(const asiolink::IOAddress& address) const;
  136. /// @brief Returns a host connected to the IPv4 subnet.
  137. ///
  138. /// This method returns a single reservation for the particular host
  139. /// (identified by the HW address or DUID) as documented in the
  140. /// @c BaseHostDataSource::get4.
  141. ///
  142. /// @param subnet_id Subnet identifier.
  143. /// @param hwaddr HW address of the client or NULL if no HW address
  144. /// available.
  145. /// @param duid client id or NULL if not available.
  146. ///
  147. /// @return Const @c Host object using a specified HW address or DUID.
  148. virtual ConstHostPtr
  149. get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
  150. const DuidPtr& duid = DuidPtr()) const;
  151. /// @brief Returns a host connected to the IPv4 subnet.
  152. ///
  153. /// This method returns a single reservation for a particular host as
  154. /// documented in the @c BaseHostDataSource::get4.
  155. ///
  156. /// @param subnet_id Subnet identifier.
  157. /// @param identifier_type Identifier type.
  158. /// @param identifier_begin Pointer to a beginning of a buffer containing
  159. /// an identifier.
  160. /// @param identifier_len Identifier length.
  161. ///
  162. /// @return Const @c Host object for which reservation has been made using
  163. /// the specified identifier.
  164. virtual ConstHostPtr
  165. get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  166. const uint8_t* identifier_begin, const size_t identifier_len) const;
  167. /// @brief Returns a host connected to the IPv4 subnet and having
  168. /// a reservation for a specified IPv4 address.
  169. ///
  170. /// This method returns a single reservation for the particular host
  171. /// (identified by the HW address or DUID) as documented in the
  172. /// @c BaseHostDataSource::get4.
  173. ///
  174. /// @param subnet_id Subnet identifier.
  175. /// @param address reserved IPv4 address.
  176. ///
  177. /// @return Const @c Host object using a specified IPv4 address.
  178. virtual ConstHostPtr
  179. get4(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
  180. /// @brief Returns a host connected to the IPv6 subnet.
  181. ///
  182. /// This method returns a host connected to the IPv6 subnet and identified
  183. /// by the HW address or DUID, as described in the
  184. /// @c BaseHostDataSource::get6.
  185. ///
  186. /// @param subnet_id Subnet identifier.
  187. /// @param hwaddr HW address of the client or NULL if no HW address
  188. /// available.
  189. /// @param duid DUID or NULL if not available.
  190. ///
  191. /// @return Const @c Host object using a specified HW address or DUID.
  192. virtual ConstHostPtr
  193. get6(const SubnetID& subnet_id, const DuidPtr& duid,
  194. const HWAddrPtr& hwaddr = HWAddrPtr()) const;
  195. /// @brief Returns a host connected to the IPv6 subnet.
  196. ///
  197. /// This method returns a host connected to the IPv6 subnet as described
  198. /// in the @c BaseHostDataSource::get6.
  199. ///
  200. /// @param subnet_id Subnet identifier.
  201. /// @param identifier_type Identifier type.
  202. /// @param identifier_begin Pointer to a beginning of a buffer containing
  203. /// an identifier.
  204. /// @param identifier_len Identifier length.
  205. ///
  206. /// @return Const @c Host object for which reservation has been made using
  207. /// the specified identifier.
  208. virtual ConstHostPtr
  209. get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  210. const uint8_t* identifier_begin, const size_t identifier_len) const;
  211. /// @brief Returns a host using the specified IPv6 prefix.
  212. ///
  213. /// This method returns a host using specified IPv6 prefix, as described
  214. /// in the @c BaseHostDataSource::get6.
  215. ///
  216. /// @param prefix IPv6 prefix for which the @c Host object is searched.
  217. /// @param prefix_len IPv6 prefix length.
  218. ///
  219. /// @return Const @c Host object using a specified HW address or DUID.
  220. virtual ConstHostPtr
  221. get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
  222. /// @brief Returns a host from specific subnet and reserved address.
  223. ///
  224. /// @param subnet_id subnet identifier.
  225. /// @param addr specified address.
  226. ///
  227. /// @return Const @c host object that has a reservation for specified address.
  228. virtual ConstHostPtr
  229. get6(const SubnetID& subnet_id, const asiolink::IOAddress& addr) const;
  230. /// @brief Adds a new host to the alternate data source.
  231. ///
  232. /// This method will throw an exception if no alternate data source is
  233. /// in use.
  234. ///
  235. /// @param host Pointer to the new @c Host object being added.
  236. virtual void add(const HostPtr& host);
  237. /// @brief Return backend type
  238. ///
  239. /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
  240. ///
  241. /// @return Type of the backend.
  242. virtual std::string getType() const {
  243. return (std::string("host_mgr"));
  244. }
  245. /// @brief Returns pointer to the host data source
  246. ///
  247. /// May return NULL
  248. /// @return pointer to the host data source (or NULL)
  249. HostDataSourcePtr getHostDataSource() const {
  250. return (alternate_source_);
  251. }
  252. /// @brief Sets the alternate host data source.
  253. ///
  254. /// Note: This should be used only for testing. Do not use
  255. /// in production. Normal control flow assumes that
  256. /// HostMgr::create(...) is called and it instantiates
  257. /// appropriate host data source. However, some tests
  258. /// (e.g. host_cmds) implement their own very simple
  259. /// data source. It's not production ready by any means,
  260. /// so it does not belong in host_data_source_factory.cc.
  261. /// The testing nature of this method is reflected in its name.
  262. ///
  263. /// @param source new source to be set (may be NULL)
  264. void setTestHostDataSource(const HostDataSourcePtr& source) {
  265. alternate_source_ = source;
  266. }
  267. /// @brief Attempts to delete a host by address.
  268. ///
  269. /// This method supports both v4 and v6.
  270. ///
  271. /// @param subnet_id subnet identifier.
  272. /// @param addr specified address.
  273. /// @return true if deletion was successful, false otherwise.
  274. virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
  275. /// @brief Attempts to delete a host by (subnet4-id, identifier, identifier-type)
  276. ///
  277. /// This method supports v4 only.
  278. ///
  279. /// @param subnet_id IPv4 Subnet identifier.
  280. /// @param identifier_type Identifier type.
  281. /// @param identifier_begin Pointer to a beginning of a buffer containing
  282. /// an identifier.
  283. /// @param identifier_len Identifier length.
  284. /// @return true if deletion was successful, false otherwise.
  285. virtual bool
  286. del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  287. const uint8_t* identifier_begin, const size_t identifier_len);
  288. /// @brief Attempts to delete a host by (subnet6-id, identifier, identifier-type)
  289. ///
  290. /// This method supports v6 only.
  291. ///
  292. /// @param subnet_id IPv6 Subnet identifier.
  293. /// @param identifier_type Identifier type.
  294. /// @param identifier_begin Pointer to a beginning of a buffer containing
  295. /// an identifier.
  296. /// @param identifier_len Identifier length.
  297. /// @return true if deletion was successful, false otherwise.
  298. virtual bool
  299. del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  300. const uint8_t* identifier_begin, const size_t identifier_len);
  301. private:
  302. /// @brief Private default constructor.
  303. HostMgr() { }
  304. /// @brief Pointer to an alternate host data source.
  305. ///
  306. /// If this pointer is NULL, the source is not in use.
  307. HostDataSourcePtr alternate_source_;
  308. /// @brief Returns a pointer to the currently used instance of the
  309. /// @c HostMgr.
  310. static boost::scoped_ptr<HostMgr>& getHostMgrPtr();
  311. };
  312. }
  313. }
  314. #endif // HOST_MGR_H