host_container.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright (C) 2014-2015 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 HOST_CONTAINER_H
  15. #define HOST_CONTAINER_H
  16. #include <dhcpsrv/host.h>
  17. #include <dhcpsrv/subnet_id.h>
  18. #include <boost/multi_index_container.hpp>
  19. #include <boost/multi_index/composite_key.hpp>
  20. #include <boost/multi_index/mem_fun.hpp>
  21. #include <boost/multi_index/member.hpp>
  22. #include <boost/multi_index/ordered_index.hpp>
  23. #include <boost/multi_index/hashed_index.hpp>
  24. namespace isc {
  25. namespace dhcp {
  26. /// @brief Multi-index container holding host reservations.
  27. ///
  28. /// This container holds a collection of @c Host objects which can be retrieved
  29. /// using various parameters. The typical use of this container is to search for
  30. /// all @c Host objects which are identified by a specified identifier, i.e.
  31. /// HW address or DUID.
  32. ///
  33. /// @todo This container will be extended to search for @c Host objects
  34. /// associated with a specific IPv4 address or IPv6 prefix/length.
  35. ///
  36. /// @see http://www.boost.org/doc/libs/1_56_0/libs/multi_index/doc/index.html
  37. typedef boost::multi_index_container<
  38. // This container stores pointers to Host objects.
  39. HostPtr,
  40. // Start specification of indexes here.
  41. boost::multi_index::indexed_by<
  42. // First index is used to search for the host using one of the
  43. // identifiers, i.e. HW address or DUID. The elements of this
  44. // index are non-unique because there may be multiple reservations
  45. // for the same host belonging to a different subnets.
  46. boost::multi_index::ordered_non_unique<
  47. // The index comprises actual identifier (HW address or DUID) in
  48. // a binary form and a type of the identifier which indicates
  49. // that it is HW address or DUID.
  50. boost::multi_index::composite_key<
  51. // Composite key uses members of the Host class.
  52. Host,
  53. // Binary identifier is retrieved from the Host class using
  54. // a getIdentifier method.
  55. boost::multi_index::const_mem_fun<
  56. Host, const std::vector<uint8_t>&,
  57. &Host::getIdentifier
  58. >,
  59. // Identifier type is retrieved from the Host class using
  60. // a getIdentifierType method.
  61. boost::multi_index::const_mem_fun<
  62. Host, Host::IdentifierType,
  63. &Host::getIdentifierType
  64. >
  65. >
  66. >,
  67. // Second index is used to search for the host using reserved IPv4
  68. // address.
  69. boost::multi_index::ordered_non_unique<
  70. // Index using values returned by the @c Host::getIPv4Resrvation.
  71. boost::multi_index::const_mem_fun<Host, const asiolink::IOAddress&,
  72. &Host::getIPv4Reservation>
  73. >
  74. >
  75. > HostContainer;
  76. /// @brief First index type in the @c HostContainer.
  77. ///
  78. /// This index allows for searching for @c Host objects using an
  79. /// identifier + identifier type tuple.
  80. typedef HostContainer::nth_index<0>::type HostContainerIndex0;
  81. /// @brief Results range returned using the @c HostContainerIndex0.
  82. typedef std::pair<HostContainerIndex0::iterator,
  83. HostContainerIndex0::iterator> HostContainerIndex0Range;
  84. /// @brief Second index type in the @c HostContainer.
  85. ///
  86. /// This index allows for searching for @c Host objects using a
  87. /// reserved IPv4 address.
  88. typedef HostContainer::nth_index<1>::type HostContainerIndex1;
  89. /// @brief Results range returned using the @c HostContainerIndex1.
  90. typedef std::pair<HostContainerIndex1::iterator,
  91. HostContainerIndex1::iterator> HostContainerIndex1Range;
  92. /// @brief Defines one entry for the Host Container for v6 hosts
  93. ///
  94. /// It's essentially a pair of (IPv6 reservation, Host pointer).
  95. /// This structure is used as an intermediate structure in HostContainer6.
  96. /// For a single host that has reservations for X addresses or prefixes, there
  97. /// will be X HostResrv6Tuple structures.
  98. struct HostResrv6Tuple {
  99. /// @brief Default constructor.
  100. ///
  101. /// @param resrv IPv6 address/prefix reservation
  102. /// @param host pointer to the host object
  103. HostResrv6Tuple(const IPv6Resrv& resrv, const HostPtr& host)
  104. :resrv_(resrv), host_(host), subnet_id_(host ? host->getIPv6SubnetID() : 0) {
  105. }
  106. /// @brief Address or prefix reservation.
  107. const IPv6Resrv resrv_;
  108. /// @brief Pointer to the host object.
  109. HostPtr host_;
  110. /// @brief Value of the IPv6 Subnet-id
  111. const SubnetID subnet_id_;
  112. /// @brief Key extractor (used in the second composite key)
  113. const asiolink::IOAddress& getKey() const {
  114. return (resrv_.getPrefix());
  115. }
  116. };
  117. /// @brief Multi-index container holding IPv6 reservations.
  118. ///
  119. /// This container holds HostResrv6Tuples, i.e. pairs of (IPv6Resrv, HostPtr)
  120. /// pieces of information. This is needed for efficiently finding a host
  121. /// for a given IPv6 address or prefix.
  122. typedef boost::multi_index_container<
  123. // This containers stores (IPv6Resrv, HostPtr) tuples
  124. HostResrv6Tuple,
  125. // Start specification of indexes here.
  126. boost::multi_index::indexed_by<
  127. // First index is used to search by an address.
  128. boost::multi_index::ordered_non_unique<
  129. // Address is extracted by calling IPv6Resrv::getPrefix()
  130. // and it will return an IOAddress object.
  131. boost::multi_index::const_mem_fun<
  132. HostResrv6Tuple, const asiolink::IOAddress&, &HostResrv6Tuple::getKey>
  133. >,
  134. // Second index is used to search by (subnet_id, address) pair.
  135. // This is
  136. boost::multi_index::ordered_unique<
  137. /// This is a composite key. It uses two keys: subnet-id and
  138. /// IPv6 address reservation.
  139. boost::multi_index::composite_key<
  140. // Composite key uses members of the HostResrv6Tuple class.
  141. HostResrv6Tuple,
  142. // First key extractor. Gets subnet-id as a member of the
  143. // HostResrv6Tuple structure.
  144. boost::multi_index::member<HostResrv6Tuple, const SubnetID,
  145. &HostResrv6Tuple::subnet_id_>,
  146. // Second key extractor. Address is extracted by calling
  147. // IPv6Resrv::getPrefix() and it will return an IOAddress object.
  148. boost::multi_index::const_mem_fun<
  149. HostResrv6Tuple, const asiolink::IOAddress&,
  150. &HostResrv6Tuple::getKey
  151. >
  152. >
  153. >
  154. >
  155. > HostContainer6;
  156. /// @brief First index type in the @c HostContainer6.
  157. ///
  158. /// This index allows for searching for @c Host objects using an
  159. /// address.
  160. typedef HostContainer6::nth_index<0>::type HostContainer6Index0;
  161. /// @brief Results range returned using the @c HostContainer6Index0.
  162. typedef std::pair<HostContainer6Index0::iterator,
  163. HostContainer6Index0::iterator> HostContainer6Index0Range;
  164. /// @brief Second index type in the @c HostContainer6.
  165. ///
  166. /// This index allows for searching for @c Host objects using a
  167. /// reserved (SubnetID, IPv6 address) tuple.
  168. typedef HostContainer6::nth_index<1>::type HostContainer6Index1;
  169. /// @brief Results range returned using the @c HostContainer6Index1.
  170. typedef std::pair<HostContainer6Index1::iterator,
  171. HostContainer6Index1::iterator> HostContainer6Index1Range;
  172. }; // end of isc::dhcp namespace
  173. }; // end of isc namespace
  174. #endif // HOST_CONTAINER_H