Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

2428 rindas
64KB

  1. // <experimental/internet> -*- C++ -*-
  2. // Copyright (C) 2015-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file experimental/internet
  21. * This is a TS C++ Library header.
  22. * @ingroup networking-ts
  23. */
  24. #ifndef _GLIBCXX_EXPERIMENTAL_INTERNET
  25. #define _GLIBCXX_EXPERIMENTAL_INTERNET
  26. #pragma GCC system_header
  27. #if __cplusplus >= 201402L
  28. #include <experimental/netfwd>
  29. #include <experimental/io_context>
  30. #include <experimental/bits/net.h>
  31. #include <array>
  32. #include <forward_list>
  33. #include <sstream>
  34. #include <cstdint>
  35. #include <experimental/string_view>
  36. #ifdef _GLIBCXX_HAVE_UNISTD_H
  37. # include <unistd.h>
  38. #endif
  39. #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
  40. # include <sys/socket.h> // AF_INET, AF_INET6, SOCK_DGRAM, SOCK_STREAM
  41. #endif
  42. #ifdef _GLIBCXX_HAVE_ARPA_INET_H
  43. # include <arpa/inet.h> // inet_ntop
  44. #endif
  45. #ifdef _GLIBCXX_HAVE_NETINET_IN_H
  46. # include <netinet/in.h> // IPPROTO_IP
  47. #endif
  48. #ifdef _GLIBCXX_HAVE_NETINET_TCP_H
  49. # include <netinet/tcp.h> // TCP_NODELAY
  50. #endif
  51. #ifdef _GLIBCXX_HAVE_NETDB_H
  52. # include <netdb.h> // getaddrinfo etc.
  53. #endif
  54. namespace std _GLIBCXX_VISIBILITY(default)
  55. {
  56. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  57. namespace experimental
  58. {
  59. namespace net
  60. {
  61. inline namespace v1
  62. {
  63. namespace ip
  64. {
  65. /** @addtogroup networking-ts
  66. * @{
  67. */
  68. #ifdef _GLIBCXX_HAVE_NETDB_H
  69. /** Error codes for resolver errors.
  70. * @{
  71. */
  72. enum class resolver_errc : int {
  73. host_not_found = EAI_NONAME,
  74. host_not_found_try_again = EAI_AGAIN,
  75. service_not_found = EAI_SERVICE
  76. };
  77. /// Error category for resolver errors.
  78. inline const error_category& resolver_category() noexcept // TODO non-inline
  79. {
  80. struct __cat : error_category
  81. {
  82. const char* name() const noexcept { return "resolver"; }
  83. std::string message(int __e) const { return ::gai_strerror(__e); }
  84. virtual void __message(int) { } // TODO dual ABI XXX
  85. };
  86. static __cat __c;
  87. return __c;
  88. }
  89. error_code make_error_code(resolver_errc __e) noexcept
  90. { return error_code(static_cast<int>(__e), resolver_category()); }
  91. error_condition make_error_condition(resolver_errc __e) noexcept
  92. { return error_condition(static_cast<int>(__e), resolver_category()); }
  93. /// @}
  94. #endif
  95. typedef uint_least16_t port_type; ///< Type used for port numbers.
  96. typedef uint_least32_t scope_id_type; ///< Type used for IPv6 scope IDs.
  97. /// Convenience alias for constraining allocators for strings.
  98. template<typename _Alloc>
  99. using __string_with
  100. = enable_if_t<std::is_same<typename _Alloc::value_type, char>::value,
  101. std::basic_string<char, std::char_traits<char>, _Alloc>>;
  102. /** Tag indicating conversion between IPv4 and IPv4-mapped IPv6 addresses.
  103. * @{
  104. */
  105. struct v4_mapped_t {};
  106. constexpr v4_mapped_t v4_mapped;
  107. // @}
  108. /// An IPv4 address.
  109. class address_v4
  110. {
  111. public:
  112. // types:
  113. typedef uint_least32_t uint_type;
  114. struct bytes_type : array<unsigned char, 4>
  115. {
  116. template<typename... _Tp>
  117. explicit constexpr
  118. bytes_type(_Tp... __tp)
  119. : array<unsigned char, 4>{{static_cast<unsigned char>(__tp)...}}
  120. {
  121. #if UCHAR_MAX > 0xFF
  122. for (auto __b : *this)
  123. if (__b > 0xFF)
  124. __throw_out_of_range("invalid address_v4::bytes_type value");
  125. #endif
  126. }
  127. };
  128. // constructors:
  129. constexpr address_v4() noexcept : _M_addr(0) { }
  130. constexpr address_v4(const address_v4& a) noexcept = default;
  131. constexpr
  132. address_v4(const bytes_type& __b)
  133. : _M_addr((__b[0] << 24) | (__b[1] << 16) | (__b[2] << 8) | __b[3])
  134. { }
  135. explicit constexpr
  136. address_v4(uint_type __val) : _M_addr(_S_hton_32(__val))
  137. {
  138. #if UINT_LEAST32_MAX > 0xFFFFFFFF
  139. if (__val > 0xFFFFFFFF)
  140. __throw_out_of_range("invalid address_v4::uint_type value");
  141. #endif
  142. }
  143. // assignment:
  144. address_v4& operator=(const address_v4& a) noexcept = default;
  145. // members:
  146. constexpr bool is_unspecified() const noexcept { return to_uint() == 0; }
  147. constexpr bool
  148. is_loopback() const noexcept
  149. { return (to_uint() & 0xFF000000) == 0x7F000000; }
  150. constexpr bool
  151. is_multicast() const noexcept
  152. { return (to_uint() & 0xF0000000) == 0xE0000000; }
  153. constexpr bytes_type
  154. to_bytes() const noexcept
  155. {
  156. return bytes_type{
  157. (_M_addr >> 24) & 0xFF,
  158. (_M_addr >> 16) & 0xFF,
  159. (_M_addr >> 8) & 0xFF,
  160. _M_addr & 0xFF
  161. };
  162. }
  163. constexpr uint_type
  164. to_uint() const noexcept { return _S_ntoh_32(_M_addr); }
  165. #ifdef _GLIBCXX_HAVE_ARPA_INET_H
  166. template<typename _Allocator = allocator<char>>
  167. __string_with<_Allocator>
  168. to_string(const _Allocator& __a = _Allocator()) const
  169. {
  170. __string_with<_Allocator> __str(__a);
  171. __str.resize(INET6_ADDRSTRLEN);
  172. if (inet_ntop(AF_INET, &_M_addr, &__str.front(), __str.size()))
  173. __str.erase(__str.find('\0'));
  174. else
  175. __str.resize(0);
  176. return __str;
  177. }
  178. #endif
  179. // static members:
  180. static constexpr address_v4 any() noexcept { return address_v4{}; }
  181. static constexpr
  182. address_v4 loopback() noexcept { return address_v4{0x7F000001}; }
  183. static constexpr
  184. address_v4 broadcast() noexcept { return address_v4{0xFFFFFFFF}; }
  185. private:
  186. template<typename _InternetProtocol>
  187. friend class basic_endpoint;
  188. friend address_v4 make_address_v4(const char*, error_code&) noexcept;
  189. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  190. static constexpr uint16_t _S_hton_16(uint16_t __h) { return __h; }
  191. static constexpr uint16_t _S_ntoh_16(uint16_t __n) { return __n; }
  192. static constexpr uint32_t _S_hton_32(uint32_t __h) { return __h; }
  193. static constexpr uint32_t _S_ntoh_32(uint32_t __n) { return __n; }
  194. #else
  195. static constexpr uint16_t
  196. _S_hton_16(uint16_t __h) { return __builtin_bswap16(__h); }
  197. static constexpr uint16_t
  198. _S_ntoh_16(uint16_t __n) { return __builtin_bswap16(__n); }
  199. static constexpr uint32_t
  200. _S_hton_32(uint32_t __h) { return __builtin_bswap32(__h); }
  201. static constexpr uint32_t
  202. _S_ntoh_32(uint32_t __n) { return __builtin_bswap32(__n); }
  203. #endif
  204. in_addr_t _M_addr; // network byte order
  205. };
  206. /// An IPv6 address.
  207. class address_v6
  208. {
  209. public:
  210. // types:
  211. struct bytes_type : array<unsigned char, 16>
  212. {
  213. template<typename... _Tp> explicit constexpr bytes_type(_Tp... __t)
  214. : array<unsigned char, 16>{{static_cast<unsigned char>(__t)...}} { }
  215. };
  216. // constructors:
  217. constexpr address_v6() noexcept : _M_bytes(), _M_scope_id() { }
  218. constexpr address_v6(const address_v6& __a) noexcept = default;
  219. constexpr
  220. address_v6(const bytes_type& __bytes, scope_id_type __scope = 0)
  221. : _M_bytes(__bytes), _M_scope_id(__scope)
  222. { }
  223. // assignment:
  224. address_v6& operator=(const address_v6& __a) noexcept = default;
  225. // members:
  226. void scope_id(scope_id_type __id) noexcept { _M_scope_id = __id; }
  227. constexpr scope_id_type scope_id() const noexcept { return _M_scope_id; }
  228. constexpr bool
  229. is_unspecified() const noexcept
  230. {
  231. for (int __i = 0; __i < 16; ++__i)
  232. if (_M_bytes[__i] != 0x00)
  233. return false;
  234. return _M_scope_id == 0;
  235. }
  236. constexpr bool
  237. is_loopback() const noexcept
  238. {
  239. for (int __i = 0; __i < 15; ++__i)
  240. if (_M_bytes[__i] != 0x00)
  241. return false;
  242. return _M_bytes[15] == 0x01 && _M_scope_id == 0;
  243. }
  244. constexpr bool
  245. is_multicast() const noexcept { return _M_bytes[0] == 0xFF; }
  246. constexpr bool
  247. is_link_local() const noexcept
  248. { return _M_bytes[0] == 0xFE && (_M_bytes[1] & 0xC0) == 0x80; }
  249. constexpr bool
  250. is_site_local() const noexcept
  251. { return _M_bytes[0] == 0xFE && (_M_bytes[1] & 0xC0) == 0xC0; }
  252. constexpr bool
  253. is_v4_mapped() const noexcept
  254. {
  255. const bytes_type& __b = _M_bytes;
  256. return __b[0] == 0 && __b[1] == 0 && __b[ 2] == 0 && __b[ 3] == 0
  257. && __b[4] == 0 && __b[5] == 0 && __b[ 6] == 0 && __b[ 7] == 0
  258. && __b[8] == 0 && __b[9] == 0 && __b[10] == 0xFF && __b[11] == 0xFF;
  259. }
  260. constexpr bool
  261. is_multicast_node_local() const noexcept
  262. { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x01; }
  263. constexpr bool
  264. is_multicast_link_local() const noexcept
  265. { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x02; }
  266. constexpr bool
  267. is_multicast_site_local() const noexcept
  268. { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x05; }
  269. constexpr bool
  270. is_multicast_org_local() const noexcept
  271. { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x08; }
  272. constexpr bool
  273. is_multicast_global() const noexcept
  274. { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x0b; }
  275. constexpr bytes_type to_bytes() const noexcept { return _M_bytes; }
  276. #ifdef _GLIBCXX_HAVE_ARPA_INET_H
  277. template<typename _Allocator = allocator<char>>
  278. __string_with<_Allocator>
  279. to_string(const _Allocator& __a = _Allocator()) const
  280. {
  281. __string_with<_Allocator> __str(__a);
  282. __str.resize(INET6_ADDRSTRLEN);
  283. if (inet_ntop(AF_INET6, &_M_bytes, &__str.front(), __str.size()))
  284. __str.erase(__str.find('\0'));
  285. else
  286. __str.resize(0);
  287. return __str;
  288. }
  289. #endif
  290. // static members:
  291. static constexpr address_v6
  292. any() noexcept
  293. {
  294. address_v6 __addr;
  295. __builtin_memcpy(&__addr._M_bytes, in6addr_any.s6_addr, 16);
  296. return __addr;
  297. }
  298. static constexpr address_v6
  299. loopback() noexcept
  300. {
  301. address_v6 __addr;
  302. __builtin_memcpy(&__addr._M_bytes, in6addr_loopback.s6_addr, 16);
  303. return __addr;
  304. }
  305. private:
  306. template<typename _InternetProtocol>
  307. friend class basic_endpoint;
  308. friend constexpr bool
  309. operator==(const address_v6&, const address_v6&) noexcept;
  310. friend constexpr bool
  311. operator< (const address_v6&, const address_v6&) noexcept;
  312. bytes_type _M_bytes;
  313. scope_id_type _M_scope_id;
  314. };
  315. /// Exception type thrown on misuse of IPv4 addresses as IPv6 or vice versa.
  316. class bad_address_cast : public bad_cast
  317. {
  318. public:
  319. bad_address_cast() { }
  320. const char* what() const noexcept { return "bad address cast"; }
  321. };
  322. /// An IPv4 or IPv6 address.
  323. class address
  324. {
  325. public:
  326. // constructors:
  327. constexpr address() noexcept : _M_v4(), _M_is_v4(true) { }
  328. constexpr
  329. address(const address& __a) noexcept : _M_uninit(), _M_is_v4(__a._M_is_v4)
  330. {
  331. if (_M_is_v4)
  332. ::new (std::addressof(_M_v4)) address_v4(__a.to_v4());
  333. else
  334. ::new (std::addressof(_M_v6)) address_v6(__a.to_v6());
  335. }
  336. constexpr
  337. address(const address_v4& __a) noexcept : _M_v4(__a), _M_is_v4(true) { }
  338. constexpr
  339. address(const address_v6& __a) noexcept : _M_v6(__a), _M_is_v4(false) { }
  340. // assignment:
  341. address&
  342. operator=(const address& __a) noexcept
  343. {
  344. if (__a._M_is_v4)
  345. *this = __a.to_v4();
  346. else
  347. *this = __a.to_v6();
  348. return *this;
  349. }
  350. address&
  351. operator=(const address_v4& __a) noexcept
  352. {
  353. ::new (std::addressof(_M_v4)) address_v4(__a);
  354. _M_is_v4 = true;
  355. return *this;
  356. }
  357. address&
  358. operator=(const address_v6& __a) noexcept
  359. {
  360. ::new (std::addressof(_M_v6)) address_v6(__a);
  361. _M_is_v4 = false;
  362. return *this;
  363. }
  364. // members:
  365. constexpr bool is_v4() const noexcept { return _M_is_v4; }
  366. constexpr bool is_v6() const noexcept { return !_M_is_v4; }
  367. constexpr address_v4
  368. to_v4() const
  369. {
  370. if (!is_v4())
  371. _GLIBCXX_THROW_OR_ABORT(bad_address_cast());
  372. return _M_v4;
  373. }
  374. constexpr address_v6
  375. to_v6() const
  376. {
  377. if (!is_v6())
  378. _GLIBCXX_THROW_OR_ABORT(bad_address_cast());
  379. return _M_v6;
  380. }
  381. constexpr bool
  382. is_unspecified() const noexcept
  383. { return _M_is_v4 ? _M_v4.is_unspecified() : _M_v6.is_unspecified(); }
  384. constexpr bool
  385. is_loopback() const noexcept
  386. { return _M_is_v4 ? _M_v4.is_loopback() : _M_v6.is_loopback(); }
  387. constexpr bool
  388. is_multicast() const noexcept
  389. { return _M_is_v4 ? _M_v4.is_multicast() : _M_v6.is_multicast(); }
  390. template<typename _Allocator = allocator<char>>
  391. __string_with<_Allocator>
  392. to_string(const _Allocator& __a = _Allocator()) const
  393. {
  394. if (_M_is_v4)
  395. return to_v4().to_string(__a);
  396. return to_v6().to_string(__a);
  397. }
  398. private:
  399. template<typename _InternetProtocol>
  400. friend class basic_endpoint;
  401. friend constexpr bool
  402. operator==(const address&, const address&) noexcept;
  403. friend constexpr bool
  404. operator<(const address&, const address&) noexcept;
  405. union {
  406. address_v4 _M_v4;
  407. address_v6 _M_v6;
  408. bool _M_uninit;
  409. };
  410. bool _M_is_v4;
  411. };
  412. /** ip::address_v4 comparisons
  413. * @{
  414. */
  415. constexpr bool
  416. operator==(const address_v4& __a, const address_v4& __b) noexcept
  417. { return __a.to_uint() == __b.to_uint(); }
  418. constexpr bool
  419. operator!=(const address_v4& __a, const address_v4& __b) noexcept
  420. { return !(__a == __b); }
  421. constexpr bool
  422. operator< (const address_v4& __a, const address_v4& __b) noexcept
  423. { return __a.to_uint() < __b.to_uint(); }
  424. constexpr bool
  425. operator> (const address_v4& __a, const address_v4& __b) noexcept
  426. { return __b < __a; }
  427. constexpr bool
  428. operator<=(const address_v4& __a, const address_v4& __b) noexcept
  429. { return !(__b < __a); }
  430. constexpr bool
  431. operator>=(const address_v4& __a, const address_v4& __b) noexcept
  432. { return !(__a < __b); }
  433. // @}
  434. /** ip::address_v6 comparisons
  435. * @{
  436. */
  437. constexpr bool
  438. operator==(const address_v6& __a, const address_v6& __b) noexcept
  439. {
  440. const auto& __aa = __a._M_bytes;
  441. const auto& __bb = __b._M_bytes;
  442. int __i = 0;
  443. for (; __i < 16 && __aa[__i] == __bb[__i]; ++__i)
  444. ;
  445. return __i == 16 ? __a.scope_id() == __b.scope_id() : false;
  446. }
  447. constexpr bool
  448. operator!=(const address_v6& __a, const address_v6& __b) noexcept
  449. { return !(__a == __b); }
  450. constexpr bool
  451. operator< (const address_v6& __a, const address_v6& __b) noexcept
  452. {
  453. const auto& __aa = __a._M_bytes;
  454. const auto& __bb = __b._M_bytes;
  455. int __i = 0;
  456. for (; __i < 16 && __aa[__i] == __bb[__i]; ++__i)
  457. ;
  458. return __i == 16 ? __a.scope_id() < __b.scope_id() : __aa[__i] < __bb[__i];
  459. }
  460. constexpr bool
  461. operator> (const address_v6& __a, const address_v6& __b) noexcept
  462. { return __b < __a; }
  463. constexpr bool
  464. operator<=(const address_v6& __a, const address_v6& __b) noexcept
  465. { return !(__b < __a); }
  466. constexpr bool
  467. operator>=(const address_v6& __a, const address_v6& __b) noexcept
  468. { return !(__a < __b); }
  469. // @}
  470. /** ip::address comparisons
  471. * @{
  472. */
  473. constexpr bool
  474. operator==(const address& __a, const address& __b) noexcept
  475. {
  476. if (__a.is_v4())
  477. return __b.is_v4() ? __a._M_v4 == __b._M_v4 : false;
  478. return __b.is_v4() ? false : __a._M_v6 == __b._M_v6;
  479. }
  480. constexpr bool
  481. operator!=(const address& __a, const address& __b) noexcept
  482. { return !(__a == __b); }
  483. constexpr bool
  484. operator< (const address& __a, const address& __b) noexcept
  485. {
  486. if (__a.is_v4())
  487. return __b.is_v4() ? __a._M_v4 < __b._M_v4 : true;
  488. return __b.is_v4() ? false : __a._M_v6 < __b._M_v6;
  489. }
  490. constexpr bool
  491. operator> (const address& __a, const address& __b) noexcept
  492. { return __b < __a; }
  493. constexpr bool
  494. operator<=(const address& __a, const address& __b) noexcept
  495. { return !(__b < __a); }
  496. constexpr bool
  497. operator>=(const address& __a, const address& __b) noexcept
  498. { return !(__a < __b); }
  499. // @}
  500. /** ip::address_v4 creation
  501. * @{
  502. */
  503. constexpr address_v4
  504. make_address_v4(const address_v4::bytes_type& __b)
  505. { return address_v4{__b}; }
  506. constexpr address_v4
  507. make_address_v4(address_v4::uint_type __val)
  508. { return address_v4{__val}; }
  509. constexpr address_v4
  510. make_address_v4(v4_mapped_t, const address_v6& __a)
  511. {
  512. if (!__a.is_v4_mapped())
  513. _GLIBCXX_THROW_OR_ABORT(bad_address_cast());
  514. const auto __v6b = __a.to_bytes();
  515. return address_v4::bytes_type(__v6b[12], __v6b[13], __v6b[14], __v6b[15]);
  516. }
  517. inline address_v4
  518. make_address_v4(const char* __str, error_code& __ec) noexcept
  519. {
  520. address_v4 __a;
  521. const int __res = ::inet_pton(AF_INET, __str, &__a._M_addr);
  522. if (__res == 1)
  523. {
  524. __ec.clear();
  525. return __a;
  526. }
  527. if (__res == 0)
  528. __ec = std::make_error_code(std::errc::invalid_argument);
  529. else
  530. __ec.assign(errno, generic_category());
  531. return {};
  532. }
  533. inline address_v4
  534. make_address_v4(const char* __str)
  535. { return make_address_v4(__str, __throw_on_error{"make_address_v4"}); }
  536. inline address_v4
  537. make_address_v4(const string& __str, error_code& __ec) noexcept
  538. { return make_address_v4(__str.c_str(), __ec); }
  539. inline address_v4
  540. make_address_v4(const string& __str)
  541. { return make_address_v4(__str.c_str()); }
  542. inline address_v4
  543. make_address_v4(string_view __str, error_code& __ec) noexcept
  544. {
  545. char __buf[INET_ADDRSTRLEN];
  546. auto __len = __str.copy(__buf, sizeof(__buf));
  547. if (__len == sizeof(__buf))
  548. {
  549. __ec = std::make_error_code(std::errc::invalid_argument);
  550. return {};
  551. }
  552. __ec.clear();
  553. __buf[__len] = '\0';
  554. return make_address_v4(__buf, __ec);
  555. }
  556. inline address_v4
  557. make_address_v4(string_view __str)
  558. { return make_address_v4(__str, __throw_on_error{"make_address_v4"}); }
  559. // @}
  560. /** ip::address_v6 creation
  561. * @{
  562. */
  563. constexpr address_v6
  564. make_address_v6(const address_v6::bytes_type& __b, scope_id_type __scope = 0)
  565. { return address_v6{__b, __scope}; }
  566. constexpr address_v6
  567. make_address_v6(v4_mapped_t, const address_v4& __a) noexcept
  568. {
  569. const address_v4::bytes_type __v4b = __a.to_bytes();
  570. address_v6::bytes_type __v6b(0, 0, 0, 0, 0, 0, 0, 0,
  571. 0, 0, 0xFF, 0xFF,
  572. __v4b[0], __v4b[1], __v4b[2], __v4b[3]);
  573. return address_v6(__v6b);
  574. }
  575. inline address_v6
  576. __make_address_v6(const char* __addr, const char* __scope, error_code& __ec)
  577. {
  578. address_v6::bytes_type __b;
  579. int __res = ::inet_pton(AF_INET6, __addr, __b.data());
  580. if (__res == 1)
  581. {
  582. __ec.clear();
  583. if (!__scope)
  584. {
  585. return { __b };
  586. }
  587. char* __eptr;
  588. unsigned long __val = std::strtoul(__scope, &__eptr, 10);
  589. if (__eptr != __scope && !*__eptr
  590. && __val <= numeric_limits<scope_id_type>::max())
  591. {
  592. return { __b, static_cast<scope_id_type>(__val) };
  593. }
  594. __ec = std::make_error_code(std::errc::invalid_argument);
  595. }
  596. else if (__res == 0)
  597. __ec = std::make_error_code(std::errc::invalid_argument);
  598. else
  599. __ec.assign(errno, generic_category());
  600. return {};
  601. }
  602. inline address_v6
  603. make_address_v6(const char* __str, error_code& __ec) noexcept
  604. {
  605. auto __p = __builtin_strchr(__str, '%');
  606. if (__p == nullptr)
  607. return __make_address_v6(__str, nullptr, __ec);
  608. char __buf[64];
  609. char* __out = __buf;
  610. bool __skip_leading_zero = true;
  611. while (__str < __p && __out < std::end(__buf))
  612. {
  613. if (!__skip_leading_zero || *__str != '0')
  614. {
  615. if (*__str == ':' || *__str == '.')
  616. __skip_leading_zero = true;
  617. else
  618. __skip_leading_zero = false;
  619. *__out = *__str;
  620. }
  621. __str++;
  622. }
  623. if (__out == std::end(__buf))
  624. __ec = std::make_error_code(std::errc::invalid_argument);
  625. else
  626. {
  627. *__out = '\0';
  628. return __make_address_v6(__buf, __p + 1, __ec);
  629. }
  630. }
  631. inline address_v6
  632. make_address_v6(const char* __str)
  633. { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); }
  634. inline address_v6
  635. make_address_v6(const string& __str, error_code& __ec) noexcept
  636. {
  637. auto __pos = __str.find('%');
  638. if (__pos == string::npos)
  639. return __make_address_v6(__str.c_str(), nullptr, __ec);
  640. char __buf[64];
  641. char* __out = __buf;
  642. bool __skip_leading_zero = true;
  643. size_t __n = 0;
  644. while (__n < __pos && __out < std::end(__buf))
  645. {
  646. if (!__skip_leading_zero || __str[__n] != '0')
  647. {
  648. if (__str[__n] == ':' || __str[__n] == '.')
  649. __skip_leading_zero = true;
  650. else
  651. __skip_leading_zero = false;
  652. *__out = __str[__n];
  653. }
  654. __n++;
  655. }
  656. if (__out == std::end(__buf))
  657. __ec = std::make_error_code(std::errc::invalid_argument);
  658. else
  659. {
  660. *__out = '\0';
  661. return __make_address_v6(__buf, __str.c_str() + __pos + 1, __ec);
  662. }
  663. }
  664. inline address_v6
  665. make_address_v6(const string& __str)
  666. { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); }
  667. inline address_v6
  668. make_address_v6(string_view __str, error_code& __ec) noexcept
  669. {
  670. char __buf[64];
  671. char* __out = __buf;
  672. char* __scope = nullptr;
  673. bool __skip_leading_zero = true;
  674. size_t __n = 0;
  675. while (__n < __str.length() && __out < std::end(__buf))
  676. {
  677. if (__str[__n] == '%')
  678. {
  679. if (__scope)
  680. __out = std::end(__buf);
  681. else
  682. {
  683. *__out = '\0';
  684. __scope = ++__out;
  685. __skip_leading_zero = true;
  686. }
  687. }
  688. else if (!__skip_leading_zero || __str[__n] != '0')
  689. {
  690. if (__str[__n] == ':' || __str[__n] == '.')
  691. __skip_leading_zero = true;
  692. else
  693. __skip_leading_zero = false;
  694. *__out = __str[__n];
  695. __out++;
  696. }
  697. __n++;
  698. }
  699. if (__out == std::end(__buf))
  700. __ec = std::make_error_code(std::errc::invalid_argument);
  701. else
  702. {
  703. *__out = '\0';
  704. return __make_address_v6(__buf, __scope, __ec);
  705. }
  706. }
  707. inline address_v6
  708. make_address_v6(string_view __str)
  709. { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); }
  710. // @}
  711. /** ip::address creation
  712. * @{
  713. */
  714. inline address
  715. make_address(const char* __str, error_code& __ec) noexcept
  716. {
  717. address __a;
  718. address_v6 __v6a = make_address_v6(__str, __ec);
  719. if (!__ec)
  720. __a = __v6a;
  721. else
  722. {
  723. address_v4 __v4a = make_address_v4(__str, __ec);
  724. if (!__ec)
  725. __a = __v4a;
  726. }
  727. return __a;
  728. }
  729. inline address
  730. make_address(const char* __str)
  731. { return make_address(__str, __throw_on_error{"make_address"}); }
  732. inline address
  733. make_address(const string& __str, error_code& __ec) noexcept; // TODO
  734. inline address
  735. make_address(const string& __str)
  736. { return make_address(__str, __throw_on_error{"make_address"}); }
  737. inline address
  738. make_address(string_view __str, error_code& __ec) noexcept
  739. {
  740. if (__str.rfind('\0') != string_view::npos)
  741. return make_address(__str.data(), __ec);
  742. return make_address(__str.to_string(), __ec); // TODO don't allocate
  743. }
  744. inline address
  745. make_address(string_view __str)
  746. { return make_address(__str, __throw_on_error{"make_address"}); }
  747. // @}
  748. /// ip::address I/O
  749. template<typename _CharT, typename _Traits>
  750. inline basic_ostream<_CharT, _Traits>&
  751. operator<<(basic_ostream<_CharT, _Traits>& __os, const address& __a)
  752. { return __os << __a.to_string(); }
  753. /// ip::address_v4 I/O
  754. template<typename _CharT, typename _Traits>
  755. inline basic_ostream<_CharT, _Traits>&
  756. operator<<(basic_ostream<_CharT, _Traits>& __os, const address_v4& __a)
  757. { return __os << __a.to_string(); }
  758. /// ip::address_v6 I/O
  759. template<typename _CharT, typename _Traits>
  760. inline basic_ostream<_CharT, _Traits>&
  761. operator<<(basic_ostream<_CharT, _Traits>& __os, const address_v6& __a)
  762. { return __os << __a.to_string(); }
  763. template<typename> class basic_address_iterator; // not defined
  764. template<> class basic_address_iterator<address_v4>
  765. {
  766. public:
  767. // types:
  768. typedef address_v4 value_type;
  769. typedef ptrdiff_t difference_type;
  770. typedef const address_v4* pointer;
  771. typedef const address_v4& reference;
  772. typedef input_iterator_tag iterator_category;
  773. // constructors:
  774. basic_address_iterator(const address_v4& __a) noexcept
  775. : _M_address(__a) { }
  776. // members:
  777. reference operator*() const noexcept { return _M_address; }
  778. pointer operator->() const noexcept { return &_M_address; }
  779. basic_address_iterator&
  780. operator++() noexcept
  781. {
  782. _M_address = value_type(_M_address.to_uint() + 1);
  783. return *this;
  784. }
  785. basic_address_iterator operator++(int) noexcept
  786. {
  787. auto __tmp = *this;
  788. ++*this;
  789. return __tmp;
  790. }
  791. basic_address_iterator& operator--() noexcept
  792. {
  793. _M_address = value_type(_M_address.to_uint() - 1);
  794. return *this;
  795. }
  796. basic_address_iterator
  797. operator--(int) noexcept
  798. {
  799. auto __tmp = *this;
  800. --*this;
  801. return __tmp;
  802. }
  803. bool
  804. operator==(const basic_address_iterator& __rhs) const noexcept
  805. { return _M_address == __rhs._M_address; }
  806. bool
  807. operator!=(const basic_address_iterator& __rhs) const noexcept
  808. { return _M_address != __rhs._M_address; }
  809. private:
  810. address_v4 _M_address;
  811. };
  812. typedef basic_address_iterator<address_v4> address_v4_iterator;
  813. template<> class basic_address_iterator<address_v6>
  814. {
  815. public:
  816. // types:
  817. typedef address_v6 value_type;
  818. typedef ptrdiff_t difference_type;
  819. typedef const address_v6* pointer;
  820. typedef const address_v6& reference;
  821. typedef input_iterator_tag iterator_category;
  822. // constructors:
  823. basic_address_iterator(const address_v6& __a) noexcept
  824. : _M_address(__a) { }
  825. // members:
  826. reference operator*() const noexcept { return _M_address; }
  827. pointer operator->() const noexcept { return &_M_address; }
  828. basic_address_iterator&
  829. operator++() noexcept; // TODO
  830. basic_address_iterator
  831. operator++(int) noexcept
  832. {
  833. auto __tmp = *this;
  834. ++*this;
  835. return __tmp;
  836. }
  837. basic_address_iterator&
  838. operator--() noexcept; // TODO
  839. basic_address_iterator
  840. operator--(int) noexcept
  841. {
  842. auto __tmp = *this;
  843. --*this;
  844. return __tmp;
  845. }
  846. bool
  847. operator==(const basic_address_iterator& __rhs) const noexcept
  848. { return _M_address == __rhs._M_address; }
  849. bool
  850. operator!=(const basic_address_iterator& __rhs) const noexcept
  851. { return _M_address != __rhs._M_address; }
  852. private:
  853. address_v6 _M_address;
  854. };
  855. typedef basic_address_iterator<address_v6> address_v6_iterator;
  856. template<typename> class basic_address_range; // not defined
  857. /** An IPv6 address range.
  858. * @{
  859. */
  860. template<> class basic_address_range<address_v4>
  861. {
  862. public:
  863. // types:
  864. typedef basic_address_iterator<address_v4> iterator;
  865. // constructors:
  866. basic_address_range() noexcept : _M_begin({}), _M_end({}) { }
  867. basic_address_range(const address_v4& __first,
  868. const address_v4& __last) noexcept
  869. : _M_begin(__first), _M_end(__last) { }
  870. // members:
  871. iterator begin() const noexcept { return _M_begin; }
  872. iterator end() const noexcept { return _M_end; }
  873. _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; }
  874. size_t
  875. size() const noexcept { return _M_end->to_uint() - _M_begin->to_uint(); }
  876. iterator
  877. find(const address_v4& __addr) const noexcept
  878. {
  879. if (*_M_begin <= __addr && __addr < *_M_end)
  880. return iterator{__addr};
  881. return end();
  882. }
  883. private:
  884. iterator _M_begin;
  885. iterator _M_end;
  886. };
  887. typedef basic_address_range<address_v4> address_v4_range;
  888. // @}
  889. /** An IPv6 address range.
  890. * @{
  891. */
  892. template<> class basic_address_range<address_v6>
  893. {
  894. public:
  895. // types:
  896. typedef basic_address_iterator<address_v6> iterator;
  897. // constructors:
  898. basic_address_range() noexcept : _M_begin({}), _M_end({}) { }
  899. basic_address_range(const address_v6& __first,
  900. const address_v6& __last) noexcept
  901. : _M_begin(__first), _M_end(__last) { }
  902. // members:
  903. iterator begin() const noexcept { return _M_begin; }
  904. iterator end() const noexcept { return _M_end; }
  905. _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; }
  906. iterator
  907. find(const address_v6& __addr) const noexcept
  908. {
  909. if (*_M_begin <= __addr && __addr < *_M_end)
  910. return iterator{__addr};
  911. return end();
  912. }
  913. private:
  914. iterator _M_begin;
  915. iterator _M_end;
  916. };
  917. typedef basic_address_range<address_v6> address_v6_range;
  918. // @}
  919. bool
  920. operator==(const network_v4& __a, const network_v4& __b) noexcept;
  921. bool
  922. operator==(const network_v6& __a, const network_v6& __b) noexcept;
  923. /// An IPv4 network address.
  924. class network_v4
  925. {
  926. public:
  927. // constructors:
  928. constexpr network_v4() noexcept : _M_addr(), _M_prefix_len(0) { }
  929. constexpr
  930. network_v4(const address_v4& __addr, int __prefix_len)
  931. : _M_addr(__addr), _M_prefix_len(__prefix_len)
  932. {
  933. if (_M_prefix_len < 0 || _M_prefix_len > 32)
  934. __throw_out_of_range("network_v4: invalid prefix length");
  935. }
  936. constexpr
  937. network_v4(const address_v4& __addr, const address_v4& __mask)
  938. : _M_addr(__addr), _M_prefix_len(__builtin_popcount(__mask.to_uint()))
  939. {
  940. if (_M_prefix_len != 0)
  941. {
  942. address_v4::uint_type __mask_uint = __mask.to_uint();
  943. if (__builtin_ctz(__mask_uint) != (32 - _M_prefix_len))
  944. __throw_invalid_argument("network_v4: invalid mask");
  945. if ((__mask_uint & 0x80000000) == 0)
  946. __throw_invalid_argument("network_v4: invalid mask");
  947. }
  948. }
  949. // members:
  950. constexpr address_v4 address() const noexcept { return _M_addr; }
  951. constexpr int prefix_length() const noexcept { return _M_prefix_len; }
  952. constexpr address_v4
  953. netmask() const noexcept
  954. {
  955. address_v4::uint_type __val = address_v4::broadcast().to_uint();
  956. __val >>= (32 - _M_prefix_len);
  957. __val <<= (32 - _M_prefix_len);
  958. return address_v4{__val};
  959. }
  960. constexpr address_v4
  961. network() const noexcept
  962. { return address_v4{_M_addr.to_uint() & netmask().to_uint()}; }
  963. constexpr address_v4
  964. broadcast() const noexcept
  965. { return address_v4{_M_addr.to_uint() | ~netmask().to_uint()}; }
  966. address_v4_range
  967. hosts() const noexcept
  968. {
  969. if (is_host())
  970. return { address(), *++address_v4_iterator(address()) };
  971. return { network(), broadcast() };
  972. }
  973. constexpr network_v4
  974. canonical() const noexcept
  975. { return network_v4(network(), prefix_length()); }
  976. constexpr bool is_host() const noexcept { return _M_prefix_len == 32; }
  977. constexpr bool
  978. is_subnet_of(const network_v4& __other) const noexcept
  979. {
  980. if (__other.prefix_length() < prefix_length())
  981. {
  982. network_v4 __net(address(), __other.prefix_length());
  983. return __net.canonical() == __other.canonical();
  984. }
  985. return false;
  986. }
  987. template<typename _Allocator = allocator<char>>
  988. __string_with<_Allocator>
  989. to_string(const _Allocator& __a = _Allocator()) const
  990. {
  991. return address().to_string(__a) + '/'
  992. + std::to_string(prefix_length());
  993. }
  994. private:
  995. address_v4 _M_addr;
  996. int _M_prefix_len;
  997. };
  998. /// An IPv6 network address.
  999. class network_v6
  1000. {
  1001. public:
  1002. // constructors:
  1003. constexpr network_v6() noexcept : _M_addr(), _M_prefix_len(0) { }
  1004. constexpr
  1005. network_v6(const address_v6& __addr, int __prefix_len)
  1006. : _M_addr(__addr), _M_prefix_len(__prefix_len)
  1007. {
  1008. if (_M_prefix_len < 0 || _M_prefix_len > 128)
  1009. __throw_out_of_range("network_v6: invalid prefix length");
  1010. }
  1011. // members:
  1012. constexpr address_v6 address() const noexcept { return _M_addr; }
  1013. constexpr int prefix_length() const noexcept { return _M_prefix_len; }
  1014. constexpr address_v6 network() const noexcept; // TODO
  1015. address_v6_range
  1016. hosts() const noexcept
  1017. {
  1018. if (is_host())
  1019. return { address(), *++address_v6_iterator(address()) };
  1020. return {}; // { network(), XXX broadcast() XXX }; // TODO
  1021. }
  1022. constexpr network_v6
  1023. canonical() const noexcept
  1024. { return network_v6{network(), prefix_length()}; }
  1025. constexpr bool is_host() const noexcept { return _M_prefix_len == 128; }
  1026. constexpr bool
  1027. is_subnet_of(const network_v6& __other) const noexcept
  1028. {
  1029. if (__other.prefix_length() < prefix_length())
  1030. {
  1031. network_v6 __net(address(), __other.prefix_length());
  1032. return __net.canonical() == __other.canonical();
  1033. }
  1034. return false;
  1035. }
  1036. template<typename _Allocator = allocator<char>>
  1037. __string_with<_Allocator>
  1038. to_string(const _Allocator& __a = _Allocator()) const
  1039. {
  1040. return address().to_string(__a) + '/'
  1041. + std::to_string(prefix_length());
  1042. }
  1043. private:
  1044. address_v6 _M_addr;
  1045. int _M_prefix_len;
  1046. };
  1047. /** ip::network_v4 comparisons
  1048. * @{
  1049. */
  1050. inline bool
  1051. operator==(const network_v4& __a, const network_v4& __b) noexcept
  1052. {
  1053. return __a.address() == __b.address()
  1054. && __a.prefix_length() == __b.prefix_length();
  1055. }
  1056. inline bool
  1057. operator!=(const network_v4& __a, const network_v4& __b) noexcept
  1058. { return !(__a == __b); }
  1059. // @}
  1060. /** ip::network_v6 comparisons
  1061. * @{
  1062. */
  1063. inline bool
  1064. operator==(const network_v6& __a, const network_v6& __b) noexcept
  1065. {
  1066. return __a.address() == __b.address()
  1067. && __a.prefix_length() == __b.prefix_length();
  1068. }
  1069. inline bool
  1070. operator!=(const network_v6& __a, const network_v6& __b) noexcept
  1071. { return !(__a == __b); }
  1072. // @}
  1073. /** ip::network_v4 creation
  1074. * @{
  1075. */
  1076. inline network_v4
  1077. make_network_v4(const address_v4& __a, int __prefix_len)
  1078. { return network_v4{__a, __prefix_len}; }
  1079. network_v4
  1080. make_network_v4(const address_v4& __a, const address_v4& __mask)
  1081. { return network_v4{ __a, __mask }; }
  1082. network_v4 make_network_v4(const char*, error_code&) noexcept; // TODO
  1083. inline network_v4
  1084. make_network_v4(const char* __str)
  1085. { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); }
  1086. network_v4 make_network_v4(const string&, error_code&) noexcept; // TODO
  1087. inline network_v4
  1088. make_network_v4(const string& __str)
  1089. { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); }
  1090. network_v4 make_network_v4(string_view, error_code&) noexcept; // TODO
  1091. inline network_v4
  1092. make_network_v4(string_view __str)
  1093. { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); }
  1094. // @}
  1095. /** ip::network_v6 creation
  1096. * @{
  1097. */
  1098. inline network_v6
  1099. make_network_v6(const address_v6& __a, int __prefix_len)
  1100. { return network_v6{__a, __prefix_len}; }
  1101. network_v6 make_network_v6(const char*, error_code&) noexcept; // TODO
  1102. inline network_v6
  1103. make_network_v6(const char* __str)
  1104. { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); }
  1105. network_v6 make_network_v6(const string&, error_code&) noexcept; // TODO
  1106. inline network_v6
  1107. make_network_v6(const string& __str)
  1108. { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); }
  1109. network_v6 make_network_v6(string_view, error_code&) noexcept; // TODO
  1110. inline network_v6
  1111. make_network_v6(string_view __str)
  1112. { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); }
  1113. // @}
  1114. /// ip::network_v4 I/O
  1115. template<typename _CharT, typename _Traits>
  1116. inline basic_ostream<_CharT, _Traits>&
  1117. operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v4& __net)
  1118. { return __os << __net.to_string(); }
  1119. /// ip::network_v6 I/O
  1120. template<typename _CharT, typename _Traits>
  1121. inline basic_ostream<_CharT, _Traits>&
  1122. operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v6& __net)
  1123. { return __os << __net.to_string(); }
  1124. /// An IP endpoint.
  1125. template<typename _InternetProtocol>
  1126. class basic_endpoint
  1127. {
  1128. public:
  1129. // types:
  1130. typedef _InternetProtocol protocol_type;
  1131. // constructors:
  1132. constexpr
  1133. basic_endpoint() noexcept : _M_data()
  1134. { _M_data._M_v4.sin_family = protocol_type::v4().family(); }
  1135. constexpr
  1136. basic_endpoint(const protocol_type& __proto,
  1137. port_type __port_num) noexcept
  1138. : _M_data()
  1139. {
  1140. __glibcxx_assert(__proto == protocol_type::v4()
  1141. || __proto == protocol_type::v6());
  1142. _M_data._M_v4.sin_family = __proto.family();
  1143. _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num);
  1144. }
  1145. constexpr
  1146. basic_endpoint(const ip::address& __addr,
  1147. port_type __port_num) noexcept
  1148. : _M_data()
  1149. {
  1150. if (__addr.is_v4())
  1151. {
  1152. _M_data._M_v4.sin_family = protocol_type::v4().family();
  1153. _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num);
  1154. _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr;
  1155. }
  1156. else
  1157. {
  1158. _M_data._M_v6 = {};
  1159. _M_data._M_v6.sin6_family = protocol_type::v6().family();
  1160. _M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num);
  1161. __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr,
  1162. __addr._M_v6._M_bytes.data(), 16);
  1163. _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id;
  1164. }
  1165. }
  1166. // members:
  1167. constexpr protocol_type protocol() const noexcept
  1168. {
  1169. return _M_data._M_v4.sin_family == AF_INET6
  1170. ? protocol_type::v6() : protocol_type::v4();
  1171. }
  1172. constexpr ip::address
  1173. address() const noexcept
  1174. {
  1175. ip::address __addr;
  1176. if (protocol().family() == AF_INET6)
  1177. {
  1178. __builtin_memcpy(&__addr._M_v6._M_bytes,
  1179. _M_data._M_v6.sin6_addr.s6_addr, 16);
  1180. __addr._M_is_v4 = false;
  1181. }
  1182. else
  1183. {
  1184. __builtin_memcpy(&__addr._M_v4._M_addr,
  1185. &_M_data._M_v4.sin_addr.s_addr, 4);
  1186. }
  1187. return __addr;
  1188. }
  1189. void
  1190. address(const ip::address& __addr) noexcept
  1191. {
  1192. if (__addr.is_v6())
  1193. {
  1194. _M_data._M_v6 = {};
  1195. _M_data._M_v6.sin6_family = protocol_type::v6().family();
  1196. __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr,
  1197. __addr._M_v6._M_bytes.data(), 16);
  1198. _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id;
  1199. }
  1200. else
  1201. {
  1202. _M_data._M_v4.sin_family = protocol_type::v4().family();
  1203. _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr;
  1204. }
  1205. }
  1206. constexpr port_type
  1207. port() const noexcept
  1208. { return address_v4::_S_ntoh_16(_M_data._M_v4.sin_port); }
  1209. void
  1210. port(port_type __port_num) noexcept
  1211. { _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); }
  1212. void* data() noexcept { return &_M_data; }
  1213. const void* data() const noexcept { return &_M_data; }
  1214. constexpr size_t size() const noexcept
  1215. {
  1216. return protocol().family() == AF_INET6
  1217. ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
  1218. }
  1219. void
  1220. resize(size_t __s)
  1221. {
  1222. if ((protocol().family() == AF_INET6 && __s != sizeof(sockaddr_in6))
  1223. || (protocol().family() == AF_INET && __s != sizeof(sockaddr_in)))
  1224. __throw_length_error("net::ip::basic_endpoint::resize");
  1225. }
  1226. constexpr size_t capacity() const noexcept { return sizeof(_M_data); }
  1227. private:
  1228. union
  1229. {
  1230. sockaddr_in _M_v4;
  1231. sockaddr_in6 _M_v6;
  1232. } _M_data;
  1233. };
  1234. /** basic_endpoint comparisons
  1235. * @{
  1236. */
  1237. template<typename _InternetProtocol>
  1238. inline bool
  1239. operator==(const basic_endpoint<_InternetProtocol>& __a,
  1240. const basic_endpoint<_InternetProtocol>& __b)
  1241. { return __a.address() == __b.address() && __a.port() == __b.port(); }
  1242. template<typename _InternetProtocol>
  1243. inline bool
  1244. operator!=(const basic_endpoint<_InternetProtocol>& __a,
  1245. const basic_endpoint<_InternetProtocol>& __b)
  1246. { return !(__a == __b); }
  1247. template<typename _InternetProtocol>
  1248. inline bool
  1249. operator< (const basic_endpoint<_InternetProtocol>& __a,
  1250. const basic_endpoint<_InternetProtocol>& __b)
  1251. {
  1252. return __a.address() < __b.address()
  1253. || (!(__b.address() < __a.address()) && __a.port() < __b.port());
  1254. }
  1255. template<typename _InternetProtocol>
  1256. inline bool
  1257. operator> (const basic_endpoint<_InternetProtocol>& __a,
  1258. const basic_endpoint<_InternetProtocol>& __b)
  1259. { return __b < __a; }
  1260. template<typename _InternetProtocol>
  1261. inline bool
  1262. operator<=(const basic_endpoint<_InternetProtocol>& __a,
  1263. const basic_endpoint<_InternetProtocol>& __b)
  1264. { return !(__b < __a); }
  1265. template<typename _InternetProtocol>
  1266. inline bool
  1267. operator>=(const basic_endpoint<_InternetProtocol>& __a,
  1268. const basic_endpoint<_InternetProtocol>& __b)
  1269. { return !(__a < __b); }
  1270. // @}
  1271. /// basic_endpoint I/O
  1272. template<typename _CharT, typename _Traits, typename _InternetProtocol>
  1273. inline basic_ostream<_CharT, _Traits>&
  1274. operator<<(basic_ostream<_CharT, _Traits>& __os,
  1275. const basic_endpoint<_InternetProtocol>& __ep)
  1276. {
  1277. basic_ostringstream<_CharT, _Traits> __ss;
  1278. if (__ep.protocol()
  1279. == basic_endpoint<_InternetProtocol>::protocol_type::v6())
  1280. __ss << '[' << __ep.address() << ']';
  1281. else
  1282. __ss << __ep.address();
  1283. __ss << ':' << __ep.port();
  1284. __os << __ss.str();
  1285. return __os;
  1286. }
  1287. /** Type representing a single result of name/address resolution.
  1288. * @{
  1289. */
  1290. template<typename _InternetProtocol>
  1291. class basic_resolver_entry
  1292. {
  1293. public:
  1294. // types:
  1295. typedef _InternetProtocol protocol_type;
  1296. typedef typename _InternetProtocol::endpoint endpoint_type;
  1297. // constructors:
  1298. basic_resolver_entry() { }
  1299. basic_resolver_entry(const endpoint_type& __ep,
  1300. string_view __h, string_view __s)
  1301. : _M_ep(__ep), _M_host(__h), _M_svc(__s) { }
  1302. // members:
  1303. endpoint_type endpoint() const { return _M_ep; }
  1304. operator endpoint_type() const { return _M_ep; }
  1305. template<typename _Allocator = allocator<char>>
  1306. __string_with<_Allocator>
  1307. host_name(const _Allocator& __a = _Allocator()) const
  1308. { return { _M_host, __a }; }
  1309. template<typename _Allocator = allocator<char>>
  1310. __string_with<_Allocator>
  1311. service_name(const _Allocator& __a = _Allocator()) const
  1312. { return { _M_svc, __a }; }
  1313. private:
  1314. basic_endpoint<_InternetProtocol> _M_ep;
  1315. string _M_host;
  1316. string _M_svc;
  1317. };
  1318. template<typename _InternetProtocol>
  1319. inline bool
  1320. operator==(const basic_resolver_entry<_InternetProtocol>& __a,
  1321. const basic_resolver_entry<_InternetProtocol>& __b)
  1322. {
  1323. return __a.endpoint() == __b.endpoint()
  1324. && __a.host_name() == __b.host_name()
  1325. && __a.service_name() == __b.service_name();
  1326. }
  1327. template<typename _InternetProtocol>
  1328. inline bool
  1329. operator!=(const basic_resolver_entry<_InternetProtocol>& __a,
  1330. const basic_resolver_entry<_InternetProtocol>& __b)
  1331. { return !(__a == __b); }
  1332. // @}
  1333. /** Base class defining flags for name/address resolution.
  1334. * @{
  1335. */
  1336. class resolver_base
  1337. {
  1338. public:
  1339. enum flags : int
  1340. {
  1341. __flags_passive = AI_PASSIVE,
  1342. __flags_canonical_name = AI_CANONNAME,
  1343. __flags_numeric_host = AI_NUMERICHOST,
  1344. #ifdef AI_NUMERICSERV
  1345. __flags_numeric_service = AI_NUMERICSERV,
  1346. #endif
  1347. __flags_v4_mapped = AI_V4MAPPED,
  1348. __flags_all_matching = AI_ALL,
  1349. __flags_address_configured = AI_ADDRCONFIG
  1350. };
  1351. static constexpr flags passive = __flags_passive;
  1352. static constexpr flags canonical_name = __flags_canonical_name;
  1353. static constexpr flags numeric_host = __flags_numeric_host;
  1354. #ifdef AI_NUMERICSERV
  1355. static constexpr flags numeric_service = __flags_numeric_service;
  1356. #endif
  1357. static constexpr flags v4_mapped = __flags_v4_mapped;
  1358. static constexpr flags all_matching = __flags_all_matching;
  1359. static constexpr flags address_configured = __flags_address_configured;
  1360. protected:
  1361. resolver_base() = default;
  1362. ~resolver_base() = default;
  1363. };
  1364. constexpr resolver_base::flags
  1365. operator&(resolver_base::flags __f1, resolver_base::flags __f2)
  1366. { return resolver_base::flags( int(__f1) & int(__f2) ); }
  1367. constexpr resolver_base::flags
  1368. operator|(resolver_base::flags __f1, resolver_base::flags __f2)
  1369. { return resolver_base::flags( int(__f1) | int(__f2) ); }
  1370. constexpr resolver_base::flags
  1371. operator^(resolver_base::flags __f1, resolver_base::flags __f2)
  1372. { return resolver_base::flags( int(__f1) ^ int(__f2) ); }
  1373. constexpr resolver_base::flags
  1374. operator~(resolver_base::flags __f)
  1375. { return resolver_base::flags( ~int(__f) ); }
  1376. inline resolver_base::flags&
  1377. operator&=(resolver_base::flags& __f1, resolver_base::flags __f2)
  1378. { return __f1 = (__f1 & __f2); }
  1379. inline resolver_base::flags&
  1380. operator|=(resolver_base::flags& __f1, resolver_base::flags __f2)
  1381. { return __f1 = (__f1 | __f2); }
  1382. inline resolver_base::flags&
  1383. operator^=(resolver_base::flags& __f1, resolver_base::flags __f2)
  1384. { return __f1 = (__f1 ^ __f2); }
  1385. // TODO define resolver_base::flags static constants for C++14 mode
  1386. // @}
  1387. /** Container for results of name/address resolution.
  1388. * @{
  1389. */
  1390. template<typename _InternetProtocol>
  1391. class basic_resolver_results
  1392. {
  1393. public:
  1394. // types:
  1395. typedef _InternetProtocol protocol_type;
  1396. typedef typename protocol_type::endpoint endpoint_type;
  1397. typedef basic_resolver_entry<protocol_type> value_type;
  1398. typedef const value_type& const_reference;
  1399. typedef value_type& reference;
  1400. typedef typename forward_list<value_type>::const_iterator const_iterator;
  1401. typedef const_iterator iterator;
  1402. typedef ptrdiff_t difference_type;
  1403. typedef size_t size_type;
  1404. // construct / copy / destroy:
  1405. basic_resolver_results() = default;
  1406. basic_resolver_results(const basic_resolver_results&) = default;
  1407. basic_resolver_results(basic_resolver_results&&) noexcept = default;
  1408. basic_resolver_results&
  1409. operator=(const basic_resolver_results&) = default;
  1410. basic_resolver_results&
  1411. operator=(basic_resolver_results&&) = default;
  1412. ~basic_resolver_results() = default;
  1413. // size:
  1414. size_type size() const noexcept { return _M_size; }
  1415. size_type max_size() const noexcept { return _M_results.max_size(); }
  1416. _GLIBCXX_NODISCARD bool
  1417. empty() const noexcept { return _M_results.empty(); }
  1418. // element access:
  1419. const_iterator begin() const { return _M_results.begin(); }
  1420. const_iterator end() const { return _M_results.end(); }
  1421. const_iterator cbegin() const { return _M_results.begin(); }
  1422. const_iterator cend() const { return _M_results.end(); }
  1423. // swap:
  1424. void
  1425. swap(basic_resolver_results& __that) noexcept
  1426. { _M_results.swap(__that._M_results); }
  1427. private:
  1428. friend class basic_resolver<protocol_type>;
  1429. basic_resolver_results(string_view, string_view, resolver_base::flags,
  1430. error_code&, protocol_type* = nullptr);
  1431. basic_resolver_results(const endpoint_type&, error_code&);
  1432. forward_list<value_type> _M_results;
  1433. size_t _M_size = 0;
  1434. };
  1435. template<typename _InternetProtocol>
  1436. inline bool
  1437. operator==(const basic_resolver_results<_InternetProtocol>& __a,
  1438. const basic_resolver_results<_InternetProtocol>& __b)
  1439. {
  1440. return __a.size() == __b.size()
  1441. && std::equal(__a.begin(), __a.end(), __b.begin());
  1442. }
  1443. template<typename _InternetProtocol>
  1444. inline bool
  1445. operator!=(const basic_resolver_results<_InternetProtocol>& __a,
  1446. const basic_resolver_results<_InternetProtocol>& __b)
  1447. { return !(__a == __b); }
  1448. // @}
  1449. /// Perform name/address resolution.
  1450. template<typename _InternetProtocol>
  1451. class basic_resolver : public resolver_base
  1452. {
  1453. public:
  1454. // types:
  1455. typedef io_context::executor_type executor_type;
  1456. typedef _InternetProtocol protocol_type;
  1457. typedef typename _InternetProtocol::endpoint endpoint_type;
  1458. typedef basic_resolver_results<_InternetProtocol> results_type;
  1459. // construct / copy / destroy:
  1460. explicit basic_resolver(io_context& __ctx) : _M_ctx(&__ctx) { }
  1461. basic_resolver(const basic_resolver&) = delete;
  1462. basic_resolver(basic_resolver&& __rhs) noexcept
  1463. : _M_ctx(__rhs._M_ctx)
  1464. { } // TODO move state/tasks etc.
  1465. ~basic_resolver() { cancel(); }
  1466. basic_resolver& operator=(const basic_resolver&) = delete;
  1467. basic_resolver& operator=(basic_resolver&& __rhs)
  1468. {
  1469. cancel();
  1470. _M_ctx = __rhs._M_ctx;
  1471. // TODO move state/tasks etc.
  1472. return *this;
  1473. }
  1474. // basic_resolver operations:
  1475. executor_type get_executor() noexcept { return _M_ctx->get_executor(); }
  1476. void cancel() { } // TODO
  1477. results_type
  1478. resolve(string_view __host_name, string_view __service_name)
  1479. {
  1480. return resolve(__host_name, __service_name, resolver_base::flags(),
  1481. __throw_on_error{"basic_resolver::resolve"});
  1482. }
  1483. results_type
  1484. resolve(string_view __host_name, string_view __service_name,
  1485. error_code& __ec)
  1486. {
  1487. return resolve(__host_name, __service_name, resolver_base::flags(),
  1488. __ec);
  1489. }
  1490. results_type
  1491. resolve(string_view __host_name, string_view __service_name, flags __f)
  1492. {
  1493. return resolve(__host_name, __service_name, __f,
  1494. __throw_on_error{"basic_resolver::resolve"});
  1495. }
  1496. results_type
  1497. resolve(string_view __host_name, string_view __service_name, flags __f,
  1498. error_code& __ec)
  1499. { return {__host_name, __service_name, __f, __ec}; }
  1500. template<typename _CompletionToken>
  1501. __deduced_t<_CompletionToken, void(error_code, results_type)>
  1502. async_resolve(string_view __host_name, string_view __service_name,
  1503. _CompletionToken&& __token)
  1504. {
  1505. return async_resolve(__host_name, __service_name,
  1506. resolver_base::flags(),
  1507. forward<_CompletionToken>(__token));
  1508. }
  1509. template<typename _CompletionToken>
  1510. __deduced_t<_CompletionToken, void(error_code, results_type)>
  1511. async_resolve(string_view __host_name, string_view __service_name,
  1512. flags __f, _CompletionToken&& __token); // TODO
  1513. results_type
  1514. resolve(const protocol_type& __protocol,
  1515. string_view __host_name, string_view __service_name)
  1516. {
  1517. return resolve(__protocol, __host_name, __service_name,
  1518. resolver_base::flags(),
  1519. __throw_on_error{"basic_resolver::resolve"});
  1520. }
  1521. results_type
  1522. resolve(const protocol_type& __protocol,
  1523. string_view __host_name, string_view __service_name,
  1524. error_code& __ec)
  1525. {
  1526. return resolve(__protocol, __host_name, __service_name,
  1527. resolver_base::flags(), __ec);
  1528. }
  1529. results_type
  1530. resolve(const protocol_type& __protocol,
  1531. string_view __host_name, string_view __service_name, flags __f)
  1532. {
  1533. return resolve(__protocol, __host_name, __service_name, __f,
  1534. __throw_on_error{"basic_resolver::resolve"});
  1535. }
  1536. results_type
  1537. resolve(const protocol_type& __protocol,
  1538. string_view __host_name, string_view __service_name,
  1539. flags __f, error_code& __ec)
  1540. { return {__host_name, __service_name, __f, __ec, &__protocol}; }
  1541. template<typename _CompletionToken>
  1542. __deduced_t<_CompletionToken, void(error_code, results_type)>
  1543. async_resolve(const protocol_type& __protocol,
  1544. string_view __host_name, string_view __service_name,
  1545. _CompletionToken&& __token)
  1546. {
  1547. return async_resolve(__protocol, __host_name, __service_name,
  1548. resolver_base::flags(),
  1549. forward<_CompletionToken>(__token));
  1550. }
  1551. template<typename _CompletionToken>
  1552. __deduced_t<_CompletionToken, void(error_code, results_type)>
  1553. async_resolve(const protocol_type& __protocol,
  1554. string_view __host_name, string_view __service_name,
  1555. flags __f, _CompletionToken&& __token); // TODO
  1556. results_type
  1557. resolve(const endpoint_type& __ep)
  1558. { return resolve(__ep, __throw_on_error{"basic_resolver::resolve"}); }
  1559. results_type
  1560. resolve(const endpoint_type& __ep, error_code& __ec)
  1561. { return { __ep, __ec }; }
  1562. template<typename _CompletionToken> // TODO
  1563. __deduced_t<_CompletionToken, void(error_code, results_type)>
  1564. async_resolve(const endpoint_type& __ep, _CompletionToken&& __token);
  1565. private:
  1566. io_context* _M_ctx;
  1567. };
  1568. /// Private constructor to synchronously resolve host and service names.
  1569. template<typename _InternetProtocol>
  1570. basic_resolver_results<_InternetProtocol>::
  1571. basic_resolver_results(string_view __host_name, string_view __service_name,
  1572. resolver_base::flags __f, error_code& __ec,
  1573. protocol_type* __protocol)
  1574. {
  1575. #ifdef _GLIBCXX_HAVE_NETDB_H
  1576. string __host;
  1577. const char* __h = __host_name.data()
  1578. ? (__host = __host_name.to_string()).c_str()
  1579. : nullptr;
  1580. string __svc;
  1581. const char* __s = __service_name.data()
  1582. ? (__svc = __service_name.to_string()).c_str()
  1583. : nullptr;
  1584. ::addrinfo __hints{ };
  1585. __hints.ai_flags = static_cast<int>(__f);
  1586. if (__protocol)
  1587. {
  1588. __hints.ai_family = __protocol->family();
  1589. __hints.ai_socktype = __protocol->type();
  1590. __hints.ai_protocol = __protocol->protocol();
  1591. }
  1592. else
  1593. {
  1594. auto __p = endpoint_type{}.protocol();
  1595. __hints.ai_family = AF_UNSPEC;
  1596. __hints.ai_socktype = __p.type();
  1597. __hints.ai_protocol = __p.protocol();
  1598. }
  1599. struct __scoped_addrinfo
  1600. {
  1601. ~__scoped_addrinfo() { if (_M_p) ::freeaddrinfo(_M_p); }
  1602. ::addrinfo* _M_p = nullptr;
  1603. } __sai;
  1604. if (int __err = ::getaddrinfo(__h, __s, &__hints, &__sai._M_p))
  1605. {
  1606. __ec.assign(__err, resolver_category());
  1607. return;
  1608. }
  1609. __ec.clear();
  1610. endpoint_type __ep;
  1611. auto __tail = _M_results.before_begin();
  1612. for (auto __ai = __sai._M_p; __ai != nullptr; __ai = __ai->ai_next)
  1613. {
  1614. if (__ai->ai_family == AF_INET || __ai->ai_family == AF_INET6)
  1615. {
  1616. if (__ai->ai_addrlen <= __ep.capacity())
  1617. __builtin_memcpy(__ep.data(), __ai->ai_addr, __ai->ai_addrlen);
  1618. __ep.resize(__ai->ai_addrlen);
  1619. __tail = _M_results.emplace_after(__tail, __ep, __host, __svc);
  1620. _M_size++;
  1621. }
  1622. }
  1623. #else
  1624. __ec = std::make_error_code(errc::operation_not_supported);
  1625. #endif
  1626. }
  1627. /// Private constructor to synchronously resolve an endpoint.
  1628. template<typename _InternetProtocol>
  1629. basic_resolver_results<_InternetProtocol>::
  1630. basic_resolver_results(const endpoint_type& __ep, error_code& __ec)
  1631. {
  1632. #ifdef _GLIBCXX_HAVE_NETDB_H
  1633. char __host_name[256];
  1634. char __service_name[128];
  1635. int __flags = 0;
  1636. if (__ep.protocol().type() == SOCK_DGRAM)
  1637. __flags |= NI_DGRAM;
  1638. auto __sa = static_cast<const sockaddr*>(__ep.data());
  1639. int __err = ::getnameinfo(__sa, __ep.size(),
  1640. __host_name, sizeof(__host_name),
  1641. __service_name, sizeof(__service_name),
  1642. __flags);
  1643. if (__err)
  1644. {
  1645. __flags |= NI_NUMERICSERV;
  1646. __err = ::getnameinfo(__sa, __ep.size(),
  1647. __host_name, sizeof(__host_name),
  1648. __service_name, sizeof(__service_name),
  1649. __flags);
  1650. }
  1651. if (__err)
  1652. __ec.assign(__err, resolver_category());
  1653. else
  1654. {
  1655. __ec.clear();
  1656. _M_results.emplace_front(__ep, __host_name, __service_name);
  1657. _M_size = 1;
  1658. }
  1659. #else
  1660. __ec = std::make_error_code(errc::operation_not_supported);
  1661. #endif
  1662. }
  1663. /** The name of the local host.
  1664. * @{
  1665. */
  1666. template<typename _Allocator>
  1667. __string_with<_Allocator>
  1668. host_name(const _Allocator& __a, error_code& __ec)
  1669. {
  1670. #ifdef HOST_NAME_MAX
  1671. constexpr size_t __maxlen = HOST_NAME_MAX;
  1672. #else
  1673. constexpr size_t __maxlen = 256;
  1674. #endif
  1675. char __buf[__maxlen + 1];
  1676. if (::gethostname(__buf, __maxlen) == -1)
  1677. __ec.assign(errno, generic_category());
  1678. __buf[__maxlen] = '\0';
  1679. return { __buf, __a };
  1680. }
  1681. template<typename _Allocator>
  1682. inline __string_with<_Allocator>
  1683. host_name(const _Allocator& __a)
  1684. { return host_name(__a, __throw_on_error{"host_name"}); }
  1685. inline string
  1686. host_name(error_code& __ec)
  1687. { return host_name(std::allocator<char>{}, __ec); }
  1688. inline string
  1689. host_name()
  1690. { return host_name(std::allocator<char>{}, __throw_on_error{"host_name"}); }
  1691. // @}
  1692. /// The TCP byte-stream protocol.
  1693. class tcp
  1694. {
  1695. public:
  1696. // types:
  1697. typedef basic_endpoint<tcp> endpoint; ///< A TCP endpoint.
  1698. typedef basic_resolver<tcp> resolver; ///< A TCP resolver.
  1699. typedef basic_stream_socket<tcp> socket; ///< A TCP socket.
  1700. typedef basic_socket_acceptor<tcp> acceptor; ///< A TCP acceptor.
  1701. typedef basic_socket_iostream<tcp> iostream; /// A TCP iostream.
  1702. #ifdef _GLIBCXX_HAVE_NETINET_TCP_H
  1703. /// Disable coalescing of small segments (i.e. the Nagle algorithm).
  1704. struct no_delay : __sockopt_crtp<no_delay, bool>
  1705. {
  1706. using __sockopt_crtp::__sockopt_crtp;
  1707. static const int _S_level = IPPROTO_TCP;
  1708. static const int _S_name = TCP_NODELAY;
  1709. };
  1710. #endif
  1711. // static members:
  1712. /// A protocol object representing IPv4 TCP.
  1713. static constexpr tcp v4() noexcept { return tcp(AF_INET); }
  1714. /// A protocol object representing IPv6 TCP.
  1715. static constexpr tcp v6() noexcept { return tcp(AF_INET6); }
  1716. tcp() = delete;
  1717. constexpr int family() const noexcept { return _M_family; }
  1718. constexpr int type() const noexcept { return SOCK_STREAM; }
  1719. constexpr int protocol() const noexcept { return IPPROTO_TCP; }
  1720. private:
  1721. constexpr explicit tcp(int __family) : _M_family(__family) { }
  1722. int _M_family;
  1723. };
  1724. /** tcp comparisons
  1725. * @{
  1726. */
  1727. inline bool
  1728. operator==(const tcp& __a, const tcp& __b)
  1729. { return __a.family() == __b.family(); }
  1730. inline bool
  1731. operator!=(const tcp& __a, const tcp& __b)
  1732. { return !(__a == __b); }
  1733. // @}
  1734. /// The UDP datagram protocol.
  1735. class udp
  1736. {
  1737. public:
  1738. // types:
  1739. typedef basic_endpoint<udp> endpoint;
  1740. typedef basic_resolver<udp> resolver;
  1741. typedef basic_datagram_socket<udp> socket;
  1742. // static members:
  1743. static constexpr udp v4() noexcept { return udp(AF_INET); }
  1744. static constexpr udp v6() noexcept { return udp(AF_INET6); }
  1745. udp() = delete;
  1746. constexpr int family() const noexcept { return _M_family; }
  1747. constexpr int type() const noexcept { return SOCK_DGRAM; }
  1748. constexpr int protocol() const noexcept { return IPPROTO_UDP; }
  1749. private:
  1750. constexpr explicit udp(int __family) : _M_family(__family) { }
  1751. int _M_family;
  1752. };
  1753. /** udp comparisons
  1754. * @{
  1755. */
  1756. bool
  1757. operator==(const udp& __a, const udp& __b)
  1758. { return __a.family() == __b.family(); }
  1759. inline bool
  1760. operator!=(const udp& __a, const udp& __b)
  1761. { return !(__a == __b); }
  1762. // @}
  1763. /// Restrict a socket created for an IPv6 protocol to IPv6 only.
  1764. struct v6_only : __sockopt_crtp<v6_only, bool>
  1765. {
  1766. using __sockopt_crtp::__sockopt_crtp;
  1767. static const int _S_level = IPPROTO_IPV6;
  1768. static const int _S_name = IPV6_V6ONLY;
  1769. };
  1770. namespace unicast
  1771. {
  1772. /// Set the default number of hops (TTL) for outbound datagrams.
  1773. struct hops : __sockopt_crtp<hops>
  1774. {
  1775. using __sockopt_crtp::__sockopt_crtp;
  1776. template<typename _Protocol>
  1777. int
  1778. level(const _Protocol& __p) const noexcept
  1779. { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }
  1780. template<typename _Protocol>
  1781. int
  1782. name(const _Protocol& __p) const noexcept
  1783. { return __p.family() == AF_INET6 ? IPV6_UNICAST_HOPS : IP_TTL; }
  1784. };
  1785. } // namespace unicast
  1786. namespace multicast
  1787. {
  1788. /// Request that a socket joins a multicast group.
  1789. struct join_group
  1790. {
  1791. explicit
  1792. join_group(const address&);
  1793. explicit
  1794. join_group(const address_v4&, const address_v4& = address_v4::any());
  1795. explicit
  1796. join_group(const address_v6&, unsigned int = 0);
  1797. template<typename _Protocol>
  1798. int
  1799. level(const _Protocol& __p) const noexcept
  1800. { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }
  1801. template<typename _Protocol>
  1802. int
  1803. name(const _Protocol& __p) const noexcept
  1804. {
  1805. return __p.family() == AF_INET6
  1806. ? IPV6_JOIN_GROUP : IP_ADD_MEMBERSHIP;
  1807. }
  1808. template<typename _Protocol>
  1809. void*
  1810. data(const _Protocol&) noexcept
  1811. { return std::addressof(_M_value); }
  1812. template<typename _Protocol>
  1813. const void*
  1814. data(const _Protocol&) const noexcept
  1815. { return std::addressof(_M_value); }
  1816. template<typename _Protocol>
  1817. size_t
  1818. size(const _Protocol& __p) const noexcept
  1819. {
  1820. return __p.family() == AF_INET6
  1821. ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4);
  1822. }
  1823. template<typename _Protocol>
  1824. void
  1825. resize(const _Protocol& __p, size_t __s)
  1826. {
  1827. if (__s != size(__p))
  1828. __throw_length_error("invalid value for socket option resize");
  1829. }
  1830. protected:
  1831. union
  1832. {
  1833. ipv6_mreq _M_v6;
  1834. ip_mreq _M_v4;
  1835. } _M_value;
  1836. };
  1837. /// Request that a socket leaves a multicast group.
  1838. struct leave_group
  1839. {
  1840. explicit
  1841. leave_group(const address&);
  1842. explicit
  1843. leave_group(const address_v4&, const address_v4& = address_v4::any());
  1844. explicit
  1845. leave_group(const address_v6&, unsigned int = 0);
  1846. template<typename _Protocol>
  1847. int
  1848. level(const _Protocol& __p) const noexcept
  1849. { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }
  1850. template<typename _Protocol>
  1851. int
  1852. name(const _Protocol& __p) const noexcept
  1853. {
  1854. return __p.family() == AF_INET6
  1855. ? IPV6_LEAVE_GROUP : IP_DROP_MEMBERSHIP;
  1856. }
  1857. template<typename _Protocol>
  1858. void*
  1859. data(const _Protocol&) noexcept
  1860. { return std::addressof(_M_value); }
  1861. template<typename _Protocol>
  1862. const void*
  1863. data(const _Protocol&) const noexcept
  1864. { return std::addressof(_M_value); }
  1865. template<typename _Protocol>
  1866. size_t
  1867. size(const _Protocol& __p) const noexcept
  1868. {
  1869. return __p.family() == AF_INET6
  1870. ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4);
  1871. }
  1872. template<typename _Protocol>
  1873. void
  1874. resize(const _Protocol& __p, size_t __s)
  1875. {
  1876. if (__s != size(__p))
  1877. __throw_length_error("invalid value for socket option resize");
  1878. }
  1879. protected:
  1880. union
  1881. {
  1882. ipv6_mreq _M_v6;
  1883. ip_mreq _M_v4;
  1884. } _M_value;
  1885. };
  1886. /// Specify the network interface for outgoing multicast datagrams.
  1887. class outbound_interface
  1888. {
  1889. explicit
  1890. outbound_interface(const address_v4&);
  1891. explicit
  1892. outbound_interface(unsigned int);
  1893. template<typename _Protocol>
  1894. int
  1895. level(const _Protocol& __p) const noexcept
  1896. { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }
  1897. template<typename _Protocol>
  1898. int
  1899. name(const _Protocol& __p) const noexcept
  1900. {
  1901. return __p.family() == AF_INET6
  1902. ? IPV6_MULTICAST_IF : IP_MULTICAST_IF;
  1903. }
  1904. template<typename _Protocol>
  1905. const void*
  1906. data(const _Protocol&) const noexcept
  1907. { return std::addressof(_M_value); }
  1908. template<typename _Protocol>
  1909. size_t
  1910. size(const _Protocol& __p) const noexcept
  1911. {
  1912. return __p.family() == AF_INET6
  1913. ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4);
  1914. }
  1915. protected:
  1916. union {
  1917. unsigned _M_v6;
  1918. in_addr _M_v4;
  1919. } _M_value;
  1920. };
  1921. /// Set the default number of hops (TTL) for outbound datagrams.
  1922. struct hops : __sockopt_crtp<hops>
  1923. {
  1924. using __sockopt_crtp::__sockopt_crtp;
  1925. template<typename _Protocol>
  1926. int
  1927. level(const _Protocol& __p) const noexcept
  1928. { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }
  1929. template<typename _Protocol>
  1930. int
  1931. name(const _Protocol& __p) const noexcept
  1932. {
  1933. return __p.family() == AF_INET6
  1934. ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL;
  1935. }
  1936. };
  1937. /// Set whether datagrams are delivered back to the local application.
  1938. struct enable_loopback : __sockopt_crtp<enable_loopback>
  1939. {
  1940. using __sockopt_crtp::__sockopt_crtp;
  1941. template<typename _Protocol>
  1942. int
  1943. level(const _Protocol& __p) const noexcept
  1944. { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }
  1945. template<typename _Protocol>
  1946. int
  1947. name(const _Protocol& __p) const noexcept
  1948. {
  1949. return __p.family() == AF_INET6
  1950. ? IPV6_MULTICAST_LOOP : IP_MULTICAST_LOOP;
  1951. }
  1952. };
  1953. } // namespace multicast
  1954. // @}
  1955. } // namespace ip
  1956. } // namespace v1
  1957. } // namespace net
  1958. } // namespace experimental
  1959. template<>
  1960. struct is_error_condition_enum<experimental::net::v1::ip::resolver_errc>
  1961. : public true_type {};
  1962. // hash support
  1963. template<typename _Tp> struct hash;
  1964. template<>
  1965. struct hash<experimental::net::v1::ip::address>
  1966. : __hash_base<size_t, experimental::net::v1::ip::address>
  1967. {
  1968. size_t
  1969. operator()(const argument_type& __a) const
  1970. {
  1971. if (__a.is_v4())
  1972. return _Hash_impl::hash(__a.to_v4());
  1973. else
  1974. return _Hash_impl::hash(__a.to_v6());
  1975. }
  1976. };
  1977. template<>
  1978. struct hash<experimental::net::v1::ip::address_v4>
  1979. : __hash_base<size_t, experimental::net::v1::ip::address_v4>
  1980. {
  1981. size_t
  1982. operator()(const argument_type& __a) const
  1983. { return _Hash_impl::hash(__a.to_bytes()); }
  1984. };
  1985. template<> struct hash<experimental::net::v1::ip::address_v6>
  1986. : __hash_base<size_t, experimental::net::v1::ip::address_v6>
  1987. {
  1988. size_t
  1989. operator()(const argument_type& __a) const
  1990. { return _Hash_impl::hash(__a.to_bytes()); }
  1991. };
  1992. _GLIBCXX_END_NAMESPACE_VERSION
  1993. } // namespace std
  1994. #endif // C++14
  1995. #endif // _GLIBCXX_EXPERIMENTAL_INTERNET