address_v6.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. //
  2. // ip/address_v6.hpp
  3. // ~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_IP_ADDRESS_V6_HPP
  11. #define ASIO_IP_ADDRESS_V6_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include <functional>
  17. #include <string>
  18. #include "asio/detail/array.hpp"
  19. #include "asio/detail/cstdint.hpp"
  20. #include "asio/detail/socket_types.hpp"
  21. #include "asio/detail/string_view.hpp"
  22. #include "asio/detail/winsock_init.hpp"
  23. #include "asio/error_code.hpp"
  24. #include "asio/ip/address_v4.hpp"
  25. #if !defined(ASIO_NO_IOSTREAM)
  26. # include <iosfwd>
  27. #endif // !defined(ASIO_NO_IOSTREAM)
  28. #include "asio/detail/push_options.hpp"
  29. namespace asio {
  30. namespace ip {
  31. template <typename> class basic_address_iterator;
  32. /// Type used for storing IPv6 scope IDs.
  33. typedef uint_least32_t scope_id_type;
  34. /// Implements IP version 6 style addresses.
  35. /**
  36. * The asio::ip::address_v6 class provides the ability to use and
  37. * manipulate IP version 6 addresses.
  38. *
  39. * @par Thread Safety
  40. * @e Distinct @e objects: Safe.@n
  41. * @e Shared @e objects: Unsafe.
  42. */
  43. class address_v6
  44. {
  45. public:
  46. /// The type used to represent an address as an array of bytes.
  47. /**
  48. * @note This type is defined in terms of the C++0x template @c std::array
  49. * when it is available. Otherwise, it uses @c boost:array.
  50. */
  51. #if defined(GENERATING_DOCUMENTATION)
  52. typedef array<unsigned char, 16> bytes_type;
  53. #else
  54. typedef asio::detail::array<unsigned char, 16> bytes_type;
  55. #endif
  56. /// Default constructor.
  57. /**
  58. * Initialises the @c address_v6 object such that:
  59. * @li <tt>to_bytes()</tt> yields <tt>{0, 0, ..., 0}</tt>; and
  60. * @li <tt>scope_id() == 0</tt>.
  61. */
  62. ASIO_DECL address_v6() noexcept;
  63. /// Construct an address from raw bytes and scope ID.
  64. /**
  65. * Initialises the @c address_v6 object such that:
  66. * @li <tt>to_bytes() == bytes</tt>; and
  67. * @li <tt>this->scope_id() == scope_id</tt>.
  68. *
  69. * @throws out_of_range Thrown if any element in @c bytes is not in the range
  70. * <tt>0 - 0xFF</tt>. Note that no range checking is required for platforms
  71. * where <tt>std::numeric_limits<unsigned char>::max()</tt> is <tt>0xFF</tt>.
  72. */
  73. ASIO_DECL explicit address_v6(const bytes_type& bytes,
  74. scope_id_type scope_id = 0);
  75. /// Copy constructor.
  76. ASIO_DECL address_v6(const address_v6& other) noexcept;
  77. /// Move constructor.
  78. ASIO_DECL address_v6(address_v6&& other) noexcept;
  79. /// Assign from another address.
  80. ASIO_DECL address_v6& operator=(
  81. const address_v6& other) noexcept;
  82. /// Move-assign from another address.
  83. ASIO_DECL address_v6& operator=(address_v6&& other) noexcept;
  84. /// The scope ID of the address.
  85. /**
  86. * Returns the scope ID associated with the IPv6 address.
  87. */
  88. scope_id_type scope_id() const noexcept
  89. {
  90. return scope_id_;
  91. }
  92. /// The scope ID of the address.
  93. /**
  94. * Modifies the scope ID associated with the IPv6 address.
  95. *
  96. * @param id The new scope ID.
  97. */
  98. void scope_id(scope_id_type id) noexcept
  99. {
  100. scope_id_ = id;
  101. }
  102. /// Get the address in bytes, in network byte order.
  103. ASIO_DECL bytes_type to_bytes() const noexcept;
  104. /// Get the address as a string.
  105. ASIO_DECL std::string to_string() const;
  106. #if !defined(ASIO_NO_DEPRECATED)
  107. /// (Deprecated: Use other overload.) Get the address as a string.
  108. ASIO_DECL std::string to_string(asio::error_code& ec) const;
  109. /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
  110. /// address string.
  111. static address_v6 from_string(const char* str);
  112. /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
  113. /// address string.
  114. static address_v6 from_string(
  115. const char* str, asio::error_code& ec);
  116. /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
  117. /// address string.
  118. static address_v6 from_string(const std::string& str);
  119. /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
  120. /// address string.
  121. static address_v6 from_string(
  122. const std::string& str, asio::error_code& ec);
  123. /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or
  124. /// IPv4-compatible address to an IPv4 address.
  125. ASIO_DECL address_v4 to_v4() const;
  126. #endif // !defined(ASIO_NO_DEPRECATED)
  127. /// Determine whether the address is a loopback address.
  128. /**
  129. * This function tests whether the address is the loopback address
  130. * <tt>::1</tt>.
  131. */
  132. ASIO_DECL bool is_loopback() const noexcept;
  133. /// Determine whether the address is unspecified.
  134. /**
  135. * This function tests whether the address is the loopback address
  136. * <tt>::</tt>.
  137. */
  138. ASIO_DECL bool is_unspecified() const noexcept;
  139. /// Determine whether the address is link local.
  140. ASIO_DECL bool is_link_local() const noexcept;
  141. /// Determine whether the address is site local.
  142. ASIO_DECL bool is_site_local() const noexcept;
  143. /// Determine whether the address is a mapped IPv4 address.
  144. ASIO_DECL bool is_v4_mapped() const noexcept;
  145. #if !defined(ASIO_NO_DEPRECATED)
  146. /// (Deprecated: No replacement.) Determine whether the address is an
  147. /// IPv4-compatible address.
  148. ASIO_DECL bool is_v4_compatible() const;
  149. #endif // !defined(ASIO_NO_DEPRECATED)
  150. /// Determine whether the address is a multicast address.
  151. ASIO_DECL bool is_multicast() const noexcept;
  152. /// Determine whether the address is a global multicast address.
  153. ASIO_DECL bool is_multicast_global() const noexcept;
  154. /// Determine whether the address is a link-local multicast address.
  155. ASIO_DECL bool is_multicast_link_local() const noexcept;
  156. /// Determine whether the address is a node-local multicast address.
  157. ASIO_DECL bool is_multicast_node_local() const noexcept;
  158. /// Determine whether the address is a org-local multicast address.
  159. ASIO_DECL bool is_multicast_org_local() const noexcept;
  160. /// Determine whether the address is a site-local multicast address.
  161. ASIO_DECL bool is_multicast_site_local() const noexcept;
  162. /// Compare two addresses for equality.
  163. ASIO_DECL friend bool operator==(const address_v6& a1,
  164. const address_v6& a2) noexcept;
  165. /// Compare two addresses for inequality.
  166. friend bool operator!=(const address_v6& a1,
  167. const address_v6& a2) noexcept
  168. {
  169. return !(a1 == a2);
  170. }
  171. /// Compare addresses for ordering.
  172. ASIO_DECL friend bool operator<(const address_v6& a1,
  173. const address_v6& a2) noexcept;
  174. /// Compare addresses for ordering.
  175. friend bool operator>(const address_v6& a1,
  176. const address_v6& a2) noexcept
  177. {
  178. return a2 < a1;
  179. }
  180. /// Compare addresses for ordering.
  181. friend bool operator<=(const address_v6& a1,
  182. const address_v6& a2) noexcept
  183. {
  184. return !(a2 < a1);
  185. }
  186. /// Compare addresses for ordering.
  187. friend bool operator>=(const address_v6& a1,
  188. const address_v6& a2) noexcept
  189. {
  190. return !(a1 < a2);
  191. }
  192. /// Obtain an address object that represents any address.
  193. /**
  194. * This functions returns an address that represents the "any" address
  195. * <tt>::</tt>.
  196. *
  197. * @returns A default-constructed @c address_v6 object.
  198. */
  199. static address_v6 any() noexcept
  200. {
  201. return address_v6();
  202. }
  203. /// Obtain an address object that represents the loopback address.
  204. /**
  205. * This function returns an address that represents the well-known loopback
  206. * address <tt>::1</tt>.
  207. */
  208. ASIO_DECL static address_v6 loopback() noexcept;
  209. #if !defined(ASIO_NO_DEPRECATED)
  210. /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address.
  211. ASIO_DECL static address_v6 v4_mapped(const address_v4& addr);
  212. /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address.
  213. ASIO_DECL static address_v6 v4_compatible(const address_v4& addr);
  214. #endif // !defined(ASIO_NO_DEPRECATED)
  215. private:
  216. friend class basic_address_iterator<address_v6>;
  217. // The underlying IPv6 address.
  218. asio::detail::in6_addr_type addr_;
  219. // The scope ID associated with the address.
  220. scope_id_type scope_id_;
  221. };
  222. /// Create an IPv6 address from raw bytes and scope ID.
  223. /**
  224. * @relates address_v6
  225. */
  226. inline address_v6 make_address_v6(const address_v6::bytes_type& bytes,
  227. scope_id_type scope_id = 0)
  228. {
  229. return address_v6(bytes, scope_id);
  230. }
  231. /// Create an IPv6 address from an IP address string.
  232. /**
  233. * @relates address_v6
  234. */
  235. ASIO_DECL address_v6 make_address_v6(const char* str);
  236. /// Create an IPv6 address from an IP address string.
  237. /**
  238. * @relates address_v6
  239. */
  240. ASIO_DECL address_v6 make_address_v6(const char* str,
  241. asio::error_code& ec) noexcept;
  242. /// Createan IPv6 address from an IP address string.
  243. /**
  244. * @relates address_v6
  245. */
  246. ASIO_DECL address_v6 make_address_v6(const std::string& str);
  247. /// Create an IPv6 address from an IP address string.
  248. /**
  249. * @relates address_v6
  250. */
  251. ASIO_DECL address_v6 make_address_v6(const std::string& str,
  252. asio::error_code& ec) noexcept;
  253. #if defined(ASIO_HAS_STRING_VIEW) \
  254. || defined(GENERATING_DOCUMENTATION)
  255. /// Create an IPv6 address from an IP address string.
  256. /**
  257. * @relates address_v6
  258. */
  259. ASIO_DECL address_v6 make_address_v6(string_view str);
  260. /// Create an IPv6 address from an IP address string.
  261. /**
  262. * @relates address_v6
  263. */
  264. ASIO_DECL address_v6 make_address_v6(string_view str,
  265. asio::error_code& ec) noexcept;
  266. #endif // defined(ASIO_HAS_STRING_VIEW)
  267. // || defined(GENERATING_DOCUMENTATION)
  268. /// Tag type used for distinguishing overloads that deal in IPv4-mapped IPv6
  269. /// addresses.
  270. enum v4_mapped_t { v4_mapped };
  271. /// Create an IPv4 address from a IPv4-mapped IPv6 address.
  272. /**
  273. * @relates address_v4
  274. */
  275. ASIO_DECL address_v4 make_address_v4(
  276. v4_mapped_t, const address_v6& v6_addr);
  277. /// Create an IPv4-mapped IPv6 address from an IPv4 address.
  278. /**
  279. * @relates address_v6
  280. */
  281. ASIO_DECL address_v6 make_address_v6(
  282. v4_mapped_t, const address_v4& v4_addr);
  283. #if !defined(ASIO_NO_IOSTREAM)
  284. /// Output an address as a string.
  285. /**
  286. * Used to output a human-readable string for a specified address.
  287. *
  288. * @param os The output stream to which the string will be written.
  289. *
  290. * @param addr The address to be written.
  291. *
  292. * @return The output stream.
  293. *
  294. * @relates asio::ip::address_v6
  295. */
  296. template <typename Elem, typename Traits>
  297. std::basic_ostream<Elem, Traits>& operator<<(
  298. std::basic_ostream<Elem, Traits>& os, const address_v6& addr);
  299. #endif // !defined(ASIO_NO_IOSTREAM)
  300. } // namespace ip
  301. } // namespace asio
  302. namespace std {
  303. template <>
  304. struct hash<asio::ip::address_v6>
  305. {
  306. std::size_t operator()(const asio::ip::address_v6& addr)
  307. const noexcept
  308. {
  309. const asio::ip::address_v6::bytes_type bytes = addr.to_bytes();
  310. std::size_t result = static_cast<std::size_t>(addr.scope_id());
  311. combine_4_bytes(result, &bytes[0]);
  312. combine_4_bytes(result, &bytes[4]);
  313. combine_4_bytes(result, &bytes[8]);
  314. combine_4_bytes(result, &bytes[12]);
  315. return result;
  316. }
  317. private:
  318. static void combine_4_bytes(std::size_t& seed, const unsigned char* bytes)
  319. {
  320. const std::size_t bytes_hash =
  321. (static_cast<std::size_t>(bytes[0]) << 24) |
  322. (static_cast<std::size_t>(bytes[1]) << 16) |
  323. (static_cast<std::size_t>(bytes[2]) << 8) |
  324. (static_cast<std::size_t>(bytes[3]));
  325. seed ^= bytes_hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  326. }
  327. };
  328. } // namespace std
  329. #include "asio/detail/pop_options.hpp"
  330. #include "asio/ip/impl/address_v6.hpp"
  331. #if defined(ASIO_HEADER_ONLY)
  332. # include "asio/ip/impl/address_v6.ipp"
  333. #endif // defined(ASIO_HEADER_ONLY)
  334. #endif // ASIO_IP_ADDRESS_V6_HPP