cfg_iface.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 IFACE_CFG_H
  15. #define IFACE_CFG_H
  16. #include <asiolink/io_address.h>
  17. #include <map>
  18. #include <set>
  19. namespace isc {
  20. namespace dhcp {
  21. /// @brief Exception thrown when duplicated interface names specified.
  22. class DuplicateIfaceName : public Exception {
  23. public:
  24. DuplicateIfaceName(const char* file, size_t line, const char* what) :
  25. isc::Exception(file, line, what) { };
  26. };
  27. /// @brief Exception thrown when specified interface name is invalid.
  28. class InvalidIfaceName : public Exception {
  29. public:
  30. InvalidIfaceName(const char* file, size_t line, const char* what) :
  31. isc::Exception(file, line, what) { };
  32. };
  33. /// @brief Exception thrown when specified interface doesn't exist in a system.
  34. class NoSuchIface : public Exception {
  35. public:
  36. NoSuchIface(const char* file, size_t line, const char* what) :
  37. isc::Exception(file, line, what) { };
  38. };
  39. /// @brief Exception thrown when specified unicast address is not assigned
  40. /// to the interface specified.
  41. class NoSuchAddress : public Exception {
  42. public:
  43. NoSuchAddress(const char* file, size_t line, const char* what) :
  44. isc::Exception(file, line, what) { };
  45. };
  46. /// @brief Represents selection of interfaces for DHCP server.
  47. ///
  48. /// This class manages selection of interfaces on which the DHCP server is
  49. /// listening to queries. The interfaces are selected in the server
  50. /// configuration by their names or by the pairs of interface names and unicast
  51. /// addresses (e.g. eth0/2001:db8:1::1). The latter format is only accepted when
  52. /// IPv6 configuration is in use.
  53. ///
  54. /// This class also accepts "wildcard" interface name which, if specified,
  55. /// instructs the server to listen on all available interfaces.
  56. ///
  57. /// Once interfaces have been specified the sockets (either IPv4 or IPv6)
  58. /// can be opened by calling @c CfgIface::openSockets function.
  59. class CfgIface {
  60. public:
  61. /// @brief Keyword used to enable all interfaces.
  62. ///
  63. /// This keyword can be used instead of the interface name to specify
  64. /// that DHCP server should listen on all interfaces.
  65. static const char* ALL_IFACES_KEYWORD;
  66. /// @brief Protocol family: IPv4 or IPv6.
  67. ///
  68. /// Depending on the family specified, the IPv4 or IPv6 sockets are
  69. /// opened.
  70. enum Family {
  71. V4, V6
  72. };
  73. /// @brief Constructor.
  74. CfgIface();
  75. /// @brief Convenience function which closes all open sockets.
  76. void closeSockets() const;
  77. /// @brief Compares two @c CfgIface objects for equality.
  78. ///
  79. /// @param other An object to be compared with this object.
  80. ///
  81. /// @return true if objects are equal, false otherwise.
  82. bool equals(const CfgIface& other) const;
  83. /// @brief Tries to open sockets on selected interfaces.
  84. ///
  85. /// This function opens sockets bound to link-local address as well as
  86. /// sockets bound to unicast address. See @c CfgIface::use function
  87. /// documentation for details how to specify interfaces and unicast
  88. /// addresses to bind the sockets to.
  89. ///
  90. /// @param family Address family (v4 or v6).
  91. /// @param port Port number to be used to bind sockets to.
  92. /// @param use_bcast A boolean flag which indicates if the broadcast
  93. /// traffic should be received through the socket. This parameter is
  94. /// ignored for IPv6.
  95. void openSockets(const Family& family, const uint16_t port,
  96. const bool use_bcast = true) const;
  97. /// @brief Puts the interface configuration into default state.
  98. ///
  99. /// This function removes interface names from the set.
  100. void reset();
  101. /// @brief Select interface to be used to receive DHCP traffic.
  102. ///
  103. /// This function controls the selection of the interface on which the
  104. /// DHCP queries should be received by the server. The interface name
  105. /// passed as the argument of this function may appear in one of the following
  106. /// formats:
  107. /// - interface-name, e.g. eth0
  108. /// - interface-name/unicast-address, e.g. eth0/2001:db8:1::1 (V6 only)
  109. ///
  110. /// Extraneous spaces surrounding the interface name and/or unicast address
  111. /// are accepted. For example: eth0 / 2001:db8:1::1 will be accepted.
  112. ///
  113. /// When only interface name is specified (without an address) it is allowed
  114. /// to use the "wildcard" interface name (*) which indicates that the server
  115. /// should open sockets on all interfaces. When IPv6 is in use, the sockets
  116. /// will be bound to the link local addresses. Wildcard interface names are
  117. /// not allowed when specifying a unicast address. For example:
  118. /// */2001:db8:1::1 is not allowed.
  119. ///
  120. /// @param family Address family (v4 or v6).
  121. /// @param iface_name Explicit interface name, a wildcard name (*) of
  122. /// the interface(s) or the pair of iterface/unicast-address to be used
  123. /// to receive DHCP traffic.
  124. ///
  125. /// @throw InvalidIfaceName If the interface name is incorrect, e.g. empty.
  126. /// @throw NoSuchIface If the specified interface is not present.
  127. /// @throw NoSuchAddress If the specified unicast address is not assigned
  128. /// to the interface.
  129. /// @throw DuplicateIfaceName If the interface is already selected, i.e.
  130. /// @throw IOError when specified unicast address is invalid.
  131. /// @c CfgIface::use has been already called for this interface.
  132. void use(const Family& family, const std::string& iface_name);
  133. /// @brief Equality operator.
  134. ///
  135. /// @param other Object to be compared with this object.
  136. ///
  137. /// @return true if objects are equal, false otherwise.
  138. bool operator==(const CfgIface& other) const {
  139. return (equals(other));
  140. }
  141. /// @brief Inequality operator.
  142. ///
  143. /// @param other Object to be compared with this object.
  144. ///
  145. /// @return true if objects are not equal, false otherwise.
  146. bool operator!=(const CfgIface& other) const {
  147. return (!equals(other));
  148. }
  149. private:
  150. /// @brief Selects or deselects interfaces.
  151. ///
  152. /// This function selects all interfaces to receive DHCP traffic or
  153. /// deselects all interfaces so as none of them receives a DHCP traffic.
  154. ///
  155. /// @param family Address family (v4 or v6).
  156. /// @param inactive A boolean value which indicates if all interfaces
  157. /// (except loopback) should be selected or deselected.
  158. /// @param loopback_inactive A boolean value which indicates if loopback
  159. /// interface should be selected or deselected.
  160. /// should be deselected/inactive (true) or selected/active (false).
  161. void setState(const Family& family, const bool inactive,
  162. const bool loopback_inactive) const;
  163. /// @brief Error handler for executed when opening a socket fail.
  164. ///
  165. /// A pointer to this function is passed to the @c IfaceMgr::openSockets4
  166. /// or @c IfaceMgr::openSockets6. These functions call this handler when
  167. /// they fail to open a socket. The handler logs an error passed in the
  168. /// parameter.
  169. ///
  170. /// @param errmsg Error message being logged by the function.
  171. static void socketOpenErrorHandler(const std::string& errmsg);
  172. /// @brief Represents a set of interface names.
  173. typedef std::set<std::string> IfaceSet;
  174. /// @brief A set of interface names specified by the user.
  175. IfaceSet iface_set_;
  176. /// @brief A map of interfaces and unicast addresses.
  177. typedef std::map<std::string, asiolink::IOAddress> UnicastMap;
  178. /// @brief A map which holds the pairs of interface names and unicast
  179. /// addresses for which the unicast sockets should be opened.
  180. ///
  181. /// This is only used for V6 family.
  182. UnicastMap unicast_map_;
  183. /// @brief A booolean value which indicates that the wildcard interface name
  184. /// has been specified (*).
  185. bool wildcard_used_;
  186. };
  187. }
  188. }
  189. #endif // IFACE_CFG_H