cfg_subnets4.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (C) 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 CFG_SUBNETS4_H
  15. #define CFG_SUBNETS4_H
  16. #include <asiolink/io_address.h>
  17. #include <dhcpsrv/subnet.h>
  18. #include <dhcpsrv/subnet_selector.h>
  19. #include <boost/shared_ptr.hpp>
  20. namespace isc {
  21. namespace dhcp {
  22. /// @brief Holds subnets configured for the DHCPv4 server.
  23. ///
  24. /// This class holds a collection of subnets configured for the DHCPv4 server.
  25. /// It allows for retrieving a subnet for the particular client using various
  26. /// parameters extracted from the DHCPv4 message. These parameters must be
  27. /// assigned to the appropriate members of the @c CfgSubnets4::Selector
  28. /// structure.
  29. ///
  30. /// See @c CfgSubnets4::selectSubnet documentation for more details on how the
  31. /// subnet is selected for the client.
  32. class CfgSubnets4 {
  33. public:
  34. /// @brief Adds new subnet to the configuration.
  35. ///
  36. /// @param subnet Pointer to the subnet being added.
  37. ///
  38. /// @throw isc::DuplicateSubnetID If the subnet id for the new subnet
  39. /// duplicates id of an existing subnet.
  40. void add(const Subnet4Ptr& subnet);
  41. /// @brief Returns pointer to the collection of all IPv4 subnets.
  42. ///
  43. /// This is used in a hook (subnet4_select), where the hook is able
  44. /// to choose a different subnet. Server code has to offer a list
  45. /// of possible choices (i.e. all subnets).
  46. ///
  47. /// @return A pointer to const Subnet4 collection
  48. const Subnet4Collection* getAll() const {
  49. return (&subnets_);
  50. }
  51. /// @brief Returns pointer to the selected subnet.
  52. ///
  53. /// This method tries to retrieve the subnet for the client using various
  54. /// parameters extracted from the client's message using the following
  55. /// logic.
  56. ///
  57. /// If the giaddr value is set in the selector it means that the client's
  58. /// message was relayed. The subnet configuration allows for setting the
  59. /// relay address for each subnet to indicate that the subnet must be
  60. /// assigned when the packet was transmitted over the particular relay.
  61. /// This method first tries to match the giaddr with the relay addresses
  62. /// specified for all subnets. If the relay address for the subnet is equal
  63. /// to the address of the relay through which the message was transmitted,
  64. /// the particular subnet is returned.
  65. ///
  66. /// If the giaddr is not matched with any of the relay addresses in any
  67. /// subnet or the message was not relayed, the method will need to try to
  68. /// match one of the addresses in the client's message with the prefixes
  69. /// of the existing subnets. Depending whether it is a relayed message,
  70. /// message from the renewing client or a new allocation, the server will
  71. /// pick one of the following addresses for this matching:
  72. /// - giaddr - for relayed message
  73. /// - ciaddr - for renewing or rebinding client
  74. /// - source address - for the renewing client which didn't provide ciaddr
  75. /// - address on the local server's interface if this is a new allocation
  76. /// requested by the directly connected client
  77. ///
  78. /// If the address matches with a subnet, the subnet is returned.
  79. ///
  80. /// @todo This method requires performance improvement! It currently
  81. /// iterates over all existing subnets (possibly a couple of times)
  82. /// to find the one which fulfils the search criteria. The subnet storage
  83. /// is implemented as a simple STL vector which precludes fast searches
  84. /// using specific keys. Hence, full scan is required. To improve the
  85. /// search performance a different container type is required, e.g.
  86. /// multi-index container, or something of a similar functionality.
  87. ///
  88. /// @param selector Const reference to the selector structure which holds
  89. /// various information extracted from the client's packet which are used
  90. /// to find appropriate subnet.
  91. ///
  92. /// @return Pointer to the selected subnet or NULL if no subnet found.
  93. /// @throw isc::BadValue if the values in the subnet selector are invalid
  94. /// or they are insufficient to select a subnet.
  95. Subnet4Ptr selectSubnet(const SubnetSelector& selector) const;
  96. /// @brief Returns pointer to a subnet if provided address is in its range.
  97. ///
  98. /// This method returns a pointer to the subnet if the address passed in
  99. /// parameter is in range with this subnet. This is mainly used for unit
  100. /// testing. This method is also called by the
  101. /// @c selectSubnet(SubnetSelector).
  102. ///
  103. /// @todo This method requires performance improvement! It currently
  104. /// iterates over all existing subnets to find the one which fulfils
  105. /// the search criteria. The subnet storage is implemented as a simple
  106. /// STL vector which precludes fast searches using specific keys.
  107. /// Hence, full scan is required. To improve the search performance a
  108. /// different container type is required, e.g. multi-index container,
  109. /// or something of a similar functionality.
  110. ///
  111. /// @param address Address for which the subnet is searched.
  112. /// @param client_classes Optional parameter specifying the classes that
  113. /// the client belongs to.
  114. ///
  115. /// @return Pointer to the selected subnet or NULL if no subnet found.
  116. Subnet4Ptr selectSubnet(const asiolink::IOAddress& address,
  117. const ClientClasses& client_classes
  118. = ClientClasses()) const;
  119. private:
  120. /// @brief Checks that the IPv4 subnet with the given id already exists.
  121. ///
  122. /// @param subnet Subnet for which this function will check if the other
  123. /// subnet with equal id already exists.
  124. ///
  125. /// @return true if the duplicate subnet exists.
  126. bool isDuplicate(const Subnet4& subnet) const;
  127. /// @brief A container for IPv4 subnets.
  128. Subnet4Collection subnets_;
  129. };
  130. /// @name Pointer to the @c CfgSubnets4 objects.
  131. //@{
  132. /// @brief Non-const pointer.
  133. typedef boost::shared_ptr<CfgSubnets4> CfgSubnets4Ptr;
  134. /// @brief Const pointer.
  135. typedef boost::shared_ptr<const CfgSubnets4> ConstCfgSubnets4Ptr;
  136. //@}
  137. }
  138. }
  139. #endif // CFG_SUBNETS4_H