cfg_iface.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. ///
  60. /// @warning This class makes use of the AF_INET and AF_INET6 family literals,
  61. /// but it doesn't verify that the address family value passed as @c uint16_t
  62. /// parameter is equal to one of them. It is a callers responsibility to
  63. /// guarantee that the address family value is correct.
  64. class CfgIface {
  65. public:
  66. /// @brief Keyword used to enable all interfaces.
  67. ///
  68. /// This keyword can be used instead of the interface name to specify
  69. /// that DHCP server should listen on all interfaces.
  70. static const char* ALL_IFACES_KEYWORD;
  71. /// @brief Constructor.
  72. CfgIface();
  73. /// @brief Convenience function which closes all open sockets.
  74. void closeSockets() const;
  75. /// @brief Compares two @c CfgIface objects for equality.
  76. ///
  77. /// @param other An object to be compared with this object.
  78. ///
  79. /// @return true if objects are equal, false otherwise.
  80. bool equals(const CfgIface& other) const;
  81. /// @brief Tries to open sockets on selected interfaces.
  82. ///
  83. /// This function opens sockets bound to link-local address as well as
  84. /// sockets bound to unicast address. See @c CfgIface::use function
  85. /// documentation for details how to specify interfaces and unicast
  86. /// addresses to bind the sockets to.
  87. ///
  88. /// @param family Address family (AF_INET or AF_INET6).
  89. /// @param port Port number to be used to bind sockets to.
  90. /// @param use_bcast A boolean flag which indicates if the broadcast
  91. /// traffic should be received through the socket. This parameter is
  92. /// ignored for IPv6.
  93. void openSockets(const uint16_t family, const uint16_t port,
  94. const bool use_bcast = true) const;
  95. /// @brief Puts the interface configuration into default state.
  96. ///
  97. /// This function removes interface names from the set.
  98. void reset();
  99. /// @brief Select interface to be used to receive DHCP traffic.
  100. ///
  101. /// This function controls the selection of the interface on which the
  102. /// DHCP queries should be received by the server. The interface name
  103. /// passed as the argument of this function may appear in one of the following
  104. /// formats:
  105. /// - interface-name, e.g. eth0
  106. /// - interface-name/unicast-address, e.g. eth0/2001:db8:1::1 (V6 only)
  107. ///
  108. /// Extraneous spaces surrounding the interface name and/or unicast address
  109. /// are accepted. For example: eth0 / 2001:db8:1::1 will be accepted.
  110. ///
  111. /// When only interface name is specified (without an address) it is allowed
  112. /// to use the "wildcard" interface name (*) which indicates that the server
  113. /// should open sockets on all interfaces. When IPv6 is in use, the sockets
  114. /// will be bound to the link local addresses. Wildcard interface names are
  115. /// not allowed when specifying a unicast address. For example:
  116. /// */2001:db8:1::1 is not allowed.
  117. ///
  118. /// @param family Address family (AF_INET or AF_INET6).
  119. /// @param iface_name Explicit interface name, a wildcard name (*) of
  120. /// the interface(s) or the pair of iterface/unicast-address to be used
  121. /// to receive DHCP traffic.
  122. ///
  123. /// @throw InvalidIfaceName If the interface name is incorrect, e.g. empty.
  124. /// @throw NoSuchIface If the specified interface is not present.
  125. /// @throw NoSuchAddress If the specified unicast address is not assigned
  126. /// to the interface.
  127. /// @throw DuplicateIfaceName If the interface is already selected, i.e.
  128. /// @throw IOError when specified unicast address is invalid.
  129. /// @c CfgIface::use has been already called for this interface.
  130. void use(const uint16_t family, const std::string& iface_name);
  131. /// @brief Equality operator.
  132. ///
  133. /// @param other Object to be compared with this object.
  134. ///
  135. /// @return true if objects are equal, false otherwise.
  136. bool operator==(const CfgIface& other) const {
  137. return (equals(other));
  138. }
  139. /// @brief Inequality operator.
  140. ///
  141. /// @param other Object to be compared with this object.
  142. ///
  143. /// @return true if objects are not equal, false otherwise.
  144. bool operator!=(const CfgIface& other) const {
  145. return (!equals(other));
  146. }
  147. private:
  148. /// @brief Selects or deselects interfaces.
  149. ///
  150. /// This function selects all interfaces to receive DHCP traffic or
  151. /// deselects all interfaces so as none of them receives a DHCP traffic.
  152. ///
  153. /// @param family Address family (AF_INET or AF_INET6).
  154. /// @param inactive A boolean value which indicates if all interfaces
  155. /// (except loopback) should be selected or deselected.
  156. /// @param loopback_inactive A boolean value which indicates if loopback
  157. /// interface should be selected or deselected.
  158. /// should be deselected/inactive (true) or selected/active (false).
  159. void setState(const uint16_t family, const bool inactive,
  160. const bool loopback_inactive) const;
  161. /// @brief Error handler for executed when opening a socket fail.
  162. ///
  163. /// A pointer to this function is passed to the @c IfaceMgr::openSockets4
  164. /// or @c IfaceMgr::openSockets6. These functions call this handler when
  165. /// they fail to open a socket. The handler logs an error passed in the
  166. /// parameter.
  167. ///
  168. /// @param errmsg Error message being logged by the function.
  169. static void socketOpenErrorHandler(const std::string& errmsg);
  170. /// @brief Represents a set of interface names.
  171. typedef std::set<std::string> IfaceSet;
  172. /// @brief A set of interface names specified by the user.
  173. IfaceSet iface_set_;
  174. /// @brief A map of interfaces and addresses to which the server
  175. /// should bind sockets.
  176. typedef std::map<std::string, asiolink::IOAddress> ExplicitAddressMap;
  177. /// @brief A map which holds the pairs of interface names and addresses
  178. /// for which the sockets should be opened.
  179. ExplicitAddressMap address_map_;
  180. /// @brief A booolean value which indicates that the wildcard interface name
  181. /// has been specified (*).
  182. bool wildcard_used_;
  183. };
  184. }
  185. }
  186. #endif // IFACE_CFG_H