Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 52.14.184.10
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
usr /
include /
c++ /
9 /
experimental /
[ HOME SHELL ]
Name
Size
Permission
Action
bits
[ DIR ]
drwxr-xr-x
algorithm
3.57
KB
-rw-r--r--
any
15.58
KB
-rw-r--r--
array
3.16
KB
-rw-r--r--
buffer
28.03
KB
-rw-r--r--
chrono
1.89
KB
-rw-r--r--
deque
2.22
KB
-rw-r--r--
executor
52.77
KB
-rw-r--r--
filesystem
1.53
KB
-rw-r--r--
forward_list
2.29
KB
-rw-r--r--
functional
12
KB
-rw-r--r--
internet
64.03
KB
-rw-r--r--
io_context
20.81
KB
-rw-r--r--
iterator
3.43
KB
-rw-r--r--
list
2.19
KB
-rw-r--r--
map
2.51
KB
-rw-r--r--
memory
5.89
KB
-rw-r--r--
memory_resource
16.03
KB
-rw-r--r--
net
1.48
KB
-rw-r--r--
netfwd
3.52
KB
-rw-r--r--
numeric
3.12
KB
-rw-r--r--
optional
28.2
KB
-rw-r--r--
propagate_const
14.95
KB
-rw-r--r--
random
2.49
KB
-rw-r--r--
ratio
2.36
KB
-rw-r--r--
regex
2.05
KB
-rw-r--r--
set
2.39
KB
-rw-r--r--
socket
74.42
KB
-rw-r--r--
source_location
2.69
KB
-rw-r--r--
string
2.83
KB
-rw-r--r--
string_view
21.5
KB
-rw-r--r--
system_error
1.97
KB
-rw-r--r--
timer
5.63
KB
-rw-r--r--
tuple
2.39
KB
-rw-r--r--
type_traits
10.69
KB
-rw-r--r--
unordered_map
2.75
KB
-rw-r--r--
unordered_set
2.64
KB
-rw-r--r--
utility
1.67
KB
-rw-r--r--
vector
2.28
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : internet
// <experimental/internet> -*- C++ -*- // Copyright (C) 2015-2019 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file experimental/internet * This is a TS C++ Library header. */ #ifndef _GLIBCXX_EXPERIMENTAL_INTERNET #define _GLIBCXX_EXPERIMENTAL_INTERNET #pragma GCC system_header #if __cplusplus >= 201402L #include <experimental/netfwd> #include <experimental/io_context> #include <experimental/bits/net.h> #include <array> #include <forward_list> #include <sstream> #include <cstdint> #include <experimental/string_view> #ifdef _GLIBCXX_HAVE_UNISTD_H # include <unistd.h> #endif #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H # include <sys/socket.h> // AF_INET, AF_INET6, SOCK_DGRAM, SOCK_STREAM #endif #ifdef _GLIBCXX_HAVE_ARPA_INET_H # include <arpa/inet.h> // inet_ntop #endif #ifdef _GLIBCXX_HAVE_NETINET_IN_H # include <netinet/in.h> // IPPROTO_IP #endif #ifdef _GLIBCXX_HAVE_NETINET_TCP_H # include <netinet/tcp.h> // TCP_NODELAY #endif #ifdef _GLIBCXX_HAVE_NETDB_H # include <netdb.h> // getaddrinfo etc. #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace experimental { namespace net { inline namespace v1 { namespace ip { /** * @ingroup networking * @{ */ #ifdef _GLIBCXX_HAVE_NETDB_H /** Error codes for resolver errors. * @{ */ enum class resolver_errc : int { host_not_found = EAI_NONAME, host_not_found_try_again = EAI_AGAIN, service_not_found = EAI_SERVICE }; /// Error category for resolver errors. inline const error_category& resolver_category() noexcept // TODO non-inline { struct __cat : error_category { const char* name() const noexcept { return "resolver"; } std::string message(int __e) const { return ::gai_strerror(__e); } virtual void __message(int) { } // TODO dual ABI XXX }; static __cat __c; return __c; } inline error_code make_error_code(resolver_errc __e) noexcept { return error_code(static_cast<int>(__e), resolver_category()); } inline error_condition make_error_condition(resolver_errc __e) noexcept { return error_condition(static_cast<int>(__e), resolver_category()); } /// @} #endif typedef uint_least16_t port_type; ///< Type used for port numbers. typedef uint_least32_t scope_id_type; ///< Type used for IPv6 scope IDs. /// Convenience alias for constraining allocators for strings. template<typename _Alloc> using __string_with = enable_if_t<std::is_same<typename _Alloc::value_type, char>::value, std::basic_string<char, std::char_traits<char>, _Alloc>>; /** Tag indicating conversion between IPv4 and IPv4-mapped IPv6 addresses. * @{ */ struct v4_mapped_t {}; constexpr v4_mapped_t v4_mapped; /// @} /// An IPv4 address. class address_v4 { public: // types: typedef uint_least32_t uint_type; struct bytes_type : array<unsigned char, 4> { template<typename... _Tp> explicit constexpr bytes_type(_Tp... __tp) : array<unsigned char, 4>{{static_cast<unsigned char>(__tp)...}} { #if UCHAR_MAX > 0xFF for (auto __b : *this) if (__b > 0xFF) __throw_out_of_range("invalid address_v4::bytes_type value"); #endif } }; // constructors: constexpr address_v4() noexcept : _M_addr(0) { } constexpr address_v4(const address_v4& a) noexcept = default; constexpr address_v4(const bytes_type& __b) : _M_addr((__b[0] << 24) | (__b[1] << 16) | (__b[2] << 8) | __b[3]) { } explicit constexpr address_v4(uint_type __val) : _M_addr(_S_hton_32(__val)) { #if UINT_LEAST32_MAX > 0xFFFFFFFF if (__val > 0xFFFFFFFF) __throw_out_of_range("invalid address_v4::uint_type value"); #endif } // assignment: address_v4& operator=(const address_v4& a) noexcept = default; // members: constexpr bool is_unspecified() const noexcept { return to_uint() == 0; } constexpr bool is_loopback() const noexcept { return (to_uint() & 0xFF000000) == 0x7F000000; } constexpr bool is_multicast() const noexcept { return (to_uint() & 0xF0000000) == 0xE0000000; } constexpr bytes_type to_bytes() const noexcept { return bytes_type{ (_M_addr >> 24) & 0xFF, (_M_addr >> 16) & 0xFF, (_M_addr >> 8) & 0xFF, _M_addr & 0xFF }; } constexpr uint_type to_uint() const noexcept { return _S_ntoh_32(_M_addr); } #ifdef _GLIBCXX_HAVE_ARPA_INET_H template<typename _Allocator = allocator<char>> __string_with<_Allocator> to_string(const _Allocator& __a = _Allocator()) const { __string_with<_Allocator> __str(__a); __str.resize(INET6_ADDRSTRLEN); if (inet_ntop(AF_INET, &_M_addr, &__str.front(), __str.size())) __str.erase(__str.find('\0')); else __str.resize(0); return __str; } #endif // static members: static constexpr address_v4 any() noexcept { return address_v4{}; } static constexpr address_v4 loopback() noexcept { return address_v4{0x7F000001}; } static constexpr address_v4 broadcast() noexcept { return address_v4{0xFFFFFFFF}; } private: template<typename _InternetProtocol> friend class basic_endpoint; friend address_v4 make_address_v4(const char*, error_code&) noexcept; #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ static constexpr uint16_t _S_hton_16(uint16_t __h) { return __h; } static constexpr uint16_t _S_ntoh_16(uint16_t __n) { return __n; } static constexpr uint32_t _S_hton_32(uint32_t __h) { return __h; } static constexpr uint32_t _S_ntoh_32(uint32_t __n) { return __n; } #else static constexpr uint16_t _S_hton_16(uint16_t __h) { return __builtin_bswap16(__h); } static constexpr uint16_t _S_ntoh_16(uint16_t __n) { return __builtin_bswap16(__n); } static constexpr uint32_t _S_hton_32(uint32_t __h) { return __builtin_bswap32(__h); } static constexpr uint32_t _S_ntoh_32(uint32_t __n) { return __builtin_bswap32(__n); } #endif in_addr_t _M_addr; // network byte order }; /// An IPv6 address. class address_v6 { public: // types: struct bytes_type : array<unsigned char, 16> { template<typename... _Tp> explicit constexpr bytes_type(_Tp... __t) : array<unsigned char, 16>{{static_cast<unsigned char>(__t)...}} { } }; // constructors: constexpr address_v6() noexcept : _M_bytes(), _M_scope_id() { } constexpr address_v6(const address_v6& __a) noexcept = default; constexpr address_v6(const bytes_type& __bytes, scope_id_type __scope = 0) : _M_bytes(__bytes), _M_scope_id(__scope) { } // assignment: address_v6& operator=(const address_v6& __a) noexcept = default; // members: void scope_id(scope_id_type __id) noexcept { _M_scope_id = __id; } constexpr scope_id_type scope_id() const noexcept { return _M_scope_id; } constexpr bool is_unspecified() const noexcept { for (int __i = 0; __i < 16; ++__i) if (_M_bytes[__i] != 0x00) return false; return _M_scope_id == 0; } constexpr bool is_loopback() const noexcept { for (int __i = 0; __i < 15; ++__i) if (_M_bytes[__i] != 0x00) return false; return _M_bytes[15] == 0x01 && _M_scope_id == 0; } constexpr bool is_multicast() const noexcept { return _M_bytes[0] == 0xFF; } constexpr bool is_link_local() const noexcept { return _M_bytes[0] == 0xFE && (_M_bytes[1] & 0xC0) == 0x80; } constexpr bool is_site_local() const noexcept { return _M_bytes[0] == 0xFE && (_M_bytes[1] & 0xC0) == 0xC0; } constexpr bool is_v4_mapped() const noexcept { const bytes_type& __b = _M_bytes; return __b[0] == 0 && __b[1] == 0 && __b[ 2] == 0 && __b[ 3] == 0 && __b[4] == 0 && __b[5] == 0 && __b[ 6] == 0 && __b[ 7] == 0 && __b[8] == 0 && __b[9] == 0 && __b[10] == 0xFF && __b[11] == 0xFF; } constexpr bool is_multicast_node_local() const noexcept { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x01; } constexpr bool is_multicast_link_local() const noexcept { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x02; } constexpr bool is_multicast_site_local() const noexcept { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x05; } constexpr bool is_multicast_org_local() const noexcept { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x08; } constexpr bool is_multicast_global() const noexcept { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x0b; } constexpr bytes_type to_bytes() const noexcept { return _M_bytes; } #ifdef _GLIBCXX_HAVE_ARPA_INET_H template<typename _Allocator = allocator<char>> __string_with<_Allocator> to_string(const _Allocator& __a = _Allocator()) const { __string_with<_Allocator> __str(__a); __str.resize(INET6_ADDRSTRLEN + (_M_scope_id ? 11 : 0)); char* const __p = &__str.front(); if (inet_ntop(AF_INET6, &_M_bytes, __p, __str.size())) { auto __end = __str.find('\0'); if (unsigned long __scope = _M_scope_id) { __end += #if _GLIBCXX_USE_C99_STDIO __builtin_snprintf(__p + __end, __str.size() - __end, "%%%lu", __scope); #else __builtin_sprintf(__p + __end, "%%%lu", __scope); #endif } __str.erase(__end); } else __str.resize(0); return __str; } #endif // static members: static constexpr address_v6 any() noexcept { return {}; } static constexpr address_v6 loopback() noexcept { return {bytes_type{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}; } private: template<typename _InternetProtocol> friend class basic_endpoint; friend constexpr bool operator==(const address_v6&, const address_v6&) noexcept; friend constexpr bool operator< (const address_v6&, const address_v6&) noexcept; bytes_type _M_bytes; scope_id_type _M_scope_id; }; /// Exception type thrown on misuse of IPv4 addresses as IPv6 or vice versa. class bad_address_cast : public bad_cast { public: bad_address_cast() { } const char* what() const noexcept { return "bad address cast"; } }; /// An IPv4 or IPv6 address. class address { public: // constructors: constexpr address() noexcept : _M_v4(), _M_is_v4(true) { } constexpr address(const address& __a) noexcept : _M_uninit(), _M_is_v4(__a._M_is_v4) { if (_M_is_v4) ::new (std::addressof(_M_v4)) address_v4(__a.to_v4()); else ::new (std::addressof(_M_v6)) address_v6(__a.to_v6()); } constexpr address(const address_v4& __a) noexcept : _M_v4(__a), _M_is_v4(true) { } constexpr address(const address_v6& __a) noexcept : _M_v6(__a), _M_is_v4(false) { } // assignment: address& operator=(const address& __a) noexcept { if (__a._M_is_v4) *this = __a.to_v4(); else *this = __a.to_v6(); return *this; } address& operator=(const address_v4& __a) noexcept { ::new (std::addressof(_M_v4)) address_v4(__a); _M_is_v4 = true; return *this; } address& operator=(const address_v6& __a) noexcept { ::new (std::addressof(_M_v6)) address_v6(__a); _M_is_v4 = false; return *this; } // members: constexpr bool is_v4() const noexcept { return _M_is_v4; } constexpr bool is_v6() const noexcept { return !_M_is_v4; } constexpr address_v4 to_v4() const { if (!is_v4()) _GLIBCXX_THROW_OR_ABORT(bad_address_cast()); return _M_v4; } constexpr address_v6 to_v6() const { if (!is_v6()) _GLIBCXX_THROW_OR_ABORT(bad_address_cast()); return _M_v6; } constexpr bool is_unspecified() const noexcept { return _M_is_v4 ? _M_v4.is_unspecified() : _M_v6.is_unspecified(); } constexpr bool is_loopback() const noexcept { return _M_is_v4 ? _M_v4.is_loopback() : _M_v6.is_loopback(); } constexpr bool is_multicast() const noexcept { return _M_is_v4 ? _M_v4.is_multicast() : _M_v6.is_multicast(); } template<typename _Allocator = allocator<char>> __string_with<_Allocator> to_string(const _Allocator& __a = _Allocator()) const { if (_M_is_v4) return to_v4().to_string(__a); return to_v6().to_string(__a); } private: template<typename _InternetProtocol> friend class basic_endpoint; friend constexpr bool operator==(const address&, const address&) noexcept; friend constexpr bool operator<(const address&, const address&) noexcept; union { address_v4 _M_v4; address_v6 _M_v6; bool _M_uninit; }; bool _M_is_v4; }; /** ip::address_v4 comparisons * @{ */ constexpr bool operator==(const address_v4& __a, const address_v4& __b) noexcept { return __a.to_uint() == __b.to_uint(); } constexpr bool operator!=(const address_v4& __a, const address_v4& __b) noexcept { return !(__a == __b); } constexpr bool operator< (const address_v4& __a, const address_v4& __b) noexcept { return __a.to_uint() < __b.to_uint(); } constexpr bool operator> (const address_v4& __a, const address_v4& __b) noexcept { return __b < __a; } constexpr bool operator<=(const address_v4& __a, const address_v4& __b) noexcept { return !(__b < __a); } constexpr bool operator>=(const address_v4& __a, const address_v4& __b) noexcept { return !(__a < __b); } /// @} /** ip::address_v6 comparisons * @{ */ constexpr bool operator==(const address_v6& __a, const address_v6& __b) noexcept { const auto& __aa = __a._M_bytes; const auto& __bb = __b._M_bytes; int __i = 0; for (; __i < 16 && __aa[__i] == __bb[__i]; ++__i) ; return __i == 16 ? __a.scope_id() == __b.scope_id() : false; } constexpr bool operator!=(const address_v6& __a, const address_v6& __b) noexcept { return !(__a == __b); } constexpr bool operator< (const address_v6& __a, const address_v6& __b) noexcept { const auto& __aa = __a._M_bytes; const auto& __bb = __b._M_bytes; int __i = 0; for (; __i < 16 && __aa[__i] == __bb[__i]; ++__i) ; return __i == 16 ? __a.scope_id() < __b.scope_id() : __aa[__i] < __bb[__i]; } constexpr bool operator> (const address_v6& __a, const address_v6& __b) noexcept { return __b < __a; } constexpr bool operator<=(const address_v6& __a, const address_v6& __b) noexcept { return !(__b < __a); } constexpr bool operator>=(const address_v6& __a, const address_v6& __b) noexcept { return !(__a < __b); } /// @} /** ip::address comparisons * @{ */ constexpr bool operator==(const address& __a, const address& __b) noexcept { if (__a.is_v4()) return __b.is_v4() ? __a._M_v4 == __b._M_v4 : false; return __b.is_v4() ? false : __a._M_v6 == __b._M_v6; } constexpr bool operator!=(const address& __a, const address& __b) noexcept { return !(__a == __b); } constexpr bool operator< (const address& __a, const address& __b) noexcept { if (__a.is_v4()) return __b.is_v4() ? __a._M_v4 < __b._M_v4 : true; return __b.is_v4() ? false : __a._M_v6 < __b._M_v6; } constexpr bool operator> (const address& __a, const address& __b) noexcept { return __b < __a; } constexpr bool operator<=(const address& __a, const address& __b) noexcept { return !(__b < __a); } constexpr bool operator>=(const address& __a, const address& __b) noexcept { return !(__a < __b); } /// @} /** ip::address_v4 creation * @{ */ constexpr address_v4 make_address_v4(const address_v4::bytes_type& __b) { return address_v4{__b}; } constexpr address_v4 make_address_v4(address_v4::uint_type __val) { return address_v4{__val}; } constexpr address_v4 make_address_v4(v4_mapped_t, const address_v6& __a) { if (!__a.is_v4_mapped()) _GLIBCXX_THROW_OR_ABORT(bad_address_cast()); const auto __v6b = __a.to_bytes(); return address_v4::bytes_type(__v6b[12], __v6b[13], __v6b[14], __v6b[15]); } inline address_v4 make_address_v4(const char* __str, error_code& __ec) noexcept { address_v4 __a; const int __res = ::inet_pton(AF_INET, __str, &__a._M_addr); if (__res == 1) { __ec.clear(); return __a; } if (__res == 0) __ec = std::make_error_code(std::errc::invalid_argument); else __ec.assign(errno, generic_category()); return {}; } inline address_v4 make_address_v4(const char* __str) { return make_address_v4(__str, __throw_on_error{"make_address_v4"}); } inline address_v4 make_address_v4(const string& __str, error_code& __ec) noexcept { return make_address_v4(__str.c_str(), __ec); } inline address_v4 make_address_v4(const string& __str) { return make_address_v4(__str.c_str()); } inline address_v4 make_address_v4(string_view __str, error_code& __ec) noexcept { char __buf[INET_ADDRSTRLEN]; auto __len = __str.copy(__buf, sizeof(__buf)); if (__len == sizeof(__buf)) { __ec = std::make_error_code(std::errc::invalid_argument); return {}; } __ec.clear(); __buf[__len] = '\0'; return make_address_v4(__buf, __ec); } inline address_v4 make_address_v4(string_view __str) { return make_address_v4(__str, __throw_on_error{"make_address_v4"}); } /// @} /** ip::address_v6 creation * @{ */ constexpr address_v6 make_address_v6(const address_v6::bytes_type& __b, scope_id_type __scope = 0) { return address_v6{__b, __scope}; } constexpr address_v6 make_address_v6(v4_mapped_t, const address_v4& __a) noexcept { const address_v4::bytes_type __v4b = __a.to_bytes(); address_v6::bytes_type __v6b(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, __v4b[0], __v4b[1], __v4b[2], __v4b[3]); return address_v6(__v6b); } inline address_v6 __make_address_v6(const char* __addr, const char* __scope, error_code& __ec) { address_v6::bytes_type __b; int __res = ::inet_pton(AF_INET6, __addr, __b.data()); if (__res == 1) { __ec.clear(); if (!__scope) { return { __b }; } char* __eptr; unsigned long __val = std::strtoul(__scope, &__eptr, 10); if (__eptr != __scope && !*__eptr && __val <= numeric_limits<scope_id_type>::max()) { return { __b, static_cast<scope_id_type>(__val) }; } __ec = std::make_error_code(std::errc::invalid_argument); } else if (__res == 0) __ec = std::make_error_code(std::errc::invalid_argument); else __ec.assign(errno, generic_category()); return {}; } inline address_v6 make_address_v6(const char* __str, error_code& __ec) noexcept { auto __p = __builtin_strchr(__str, '%'); if (__p == nullptr) return __make_address_v6(__str, nullptr, __ec); char __buf[64]; char* __out = __buf; bool __skip_leading_zero = true; while (__str < __p && __out < std::end(__buf)) { if (!__skip_leading_zero || *__str != '0') { if (*__str == ':' || *__str == '.') __skip_leading_zero = true; else __skip_leading_zero = false; *__out = *__str; } __str++; } if (__out == std::end(__buf)) { __ec = std::make_error_code(std::errc::invalid_argument); return {}; } else { *__out = '\0'; return __make_address_v6(__buf, __p + 1, __ec); } } inline address_v6 make_address_v6(const char* __str) { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); } inline address_v6 make_address_v6(const string& __str, error_code& __ec) noexcept { auto __pos = __str.find('%'); if (__pos == string::npos) return __make_address_v6(__str.c_str(), nullptr, __ec); char __buf[64]; char* __out = __buf; bool __skip_leading_zero = true; size_t __n = 0; while (__n < __pos && __out < std::end(__buf)) { if (!__skip_leading_zero || __str[__n] != '0') { if (__str[__n] == ':' || __str[__n] == '.') __skip_leading_zero = true; else __skip_leading_zero = false; *__out = __str[__n]; } __n++; } if (__out == std::end(__buf)) { __ec = std::make_error_code(std::errc::invalid_argument); return {}; } else { *__out = '\0'; return __make_address_v6(__buf, __str.c_str() + __pos + 1, __ec); } } inline address_v6 make_address_v6(const string& __str) { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); } inline address_v6 make_address_v6(string_view __str, error_code& __ec) noexcept { char __buf[64]; char* __out = __buf; char* __scope = nullptr; bool __skip_leading_zero = true; size_t __n = 0; while (__n < __str.length() && __out < std::end(__buf)) { if (__str[__n] == '%') { if (__scope) __out = std::end(__buf); else { *__out = '\0'; __scope = ++__out; __skip_leading_zero = true; } } else if (!__skip_leading_zero || __str[__n] != '0') { if (__str[__n] == ':' || __str[__n] == '.') __skip_leading_zero = true; else __skip_leading_zero = false; *__out = __str[__n]; __out++; } __n++; } if (__out == std::end(__buf)) { __ec = std::make_error_code(std::errc::invalid_argument); return {}; } else { *__out = '\0'; return __make_address_v6(__buf, __scope, __ec); } } inline address_v6 make_address_v6(string_view __str) { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); } /// @} /** ip::address creation * @{ */ inline address make_address(const char* __str, error_code& __ec) noexcept { address __a; address_v6 __v6a = make_address_v6(__str, __ec); if (!__ec) __a = __v6a; else { address_v4 __v4a = make_address_v4(__str, __ec); if (!__ec) __a = __v4a; } return __a; } inline address make_address(const char* __str) { return make_address(__str, __throw_on_error{"make_address"}); } inline address make_address(const string& __str, error_code& __ec) noexcept; // TODO inline address make_address(const string& __str) { return make_address(__str, __throw_on_error{"make_address"}); } inline address make_address(string_view __str, error_code& __ec) noexcept { if (__str.rfind('\0') != string_view::npos) return make_address(__str.data(), __ec); return make_address(__str.to_string(), __ec); // TODO don't allocate } inline address make_address(string_view __str) { return make_address(__str, __throw_on_error{"make_address"}); } /// @} /// ip::address I/O template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const address& __a) { return __os << __a.to_string(); } /// ip::address_v4 I/O template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const address_v4& __a) { return __os << __a.to_string(); } /// ip::address_v6 I/O template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const address_v6& __a) { return __os << __a.to_string(); } template<typename> class basic_address_iterator; // not defined template<> class basic_address_iterator<address_v4> { public: // types: typedef address_v4 value_type; typedef ptrdiff_t difference_type; typedef const address_v4* pointer; typedef const address_v4& reference; typedef input_iterator_tag iterator_category; // constructors: basic_address_iterator(const address_v4& __a) noexcept : _M_address(__a) { } // members: reference operator*() const noexcept { return _M_address; } pointer operator->() const noexcept { return &_M_address; } basic_address_iterator& operator++() noexcept { _M_address = value_type(_M_address.to_uint() + 1); return *this; } basic_address_iterator operator++(int) noexcept { auto __tmp = *this; ++*this; return __tmp; } basic_address_iterator& operator--() noexcept { _M_address = value_type(_M_address.to_uint() - 1); return *this; } basic_address_iterator operator--(int) noexcept { auto __tmp = *this; --*this; return __tmp; } bool operator==(const basic_address_iterator& __rhs) const noexcept { return _M_address == __rhs._M_address; } bool operator!=(const basic_address_iterator& __rhs) const noexcept { return _M_address != __rhs._M_address; } private: address_v4 _M_address; }; typedef basic_address_iterator<address_v4> address_v4_iterator; template<> class basic_address_iterator<address_v6> { public: // types: typedef address_v6 value_type; typedef ptrdiff_t difference_type; typedef const address_v6* pointer; typedef const address_v6& reference; typedef input_iterator_tag iterator_category; // constructors: basic_address_iterator(const address_v6& __a) noexcept : _M_address(__a) { } // members: reference operator*() const noexcept { return _M_address; } pointer operator->() const noexcept { return &_M_address; } basic_address_iterator& operator++() noexcept; // TODO basic_address_iterator operator++(int) noexcept { auto __tmp = *this; ++*this; return __tmp; } basic_address_iterator& operator--() noexcept; // TODO basic_address_iterator operator--(int) noexcept { auto __tmp = *this; --*this; return __tmp; } bool operator==(const basic_address_iterator& __rhs) const noexcept { return _M_address == __rhs._M_address; } bool operator!=(const basic_address_iterator& __rhs) const noexcept { return _M_address != __rhs._M_address; } private: address_v6 _M_address; }; typedef basic_address_iterator<address_v6> address_v6_iterator; template<typename> class basic_address_range; // not defined /** An IPv6 address range. * @{ */ template<> class basic_address_range<address_v4> { public: // types: typedef basic_address_iterator<address_v4> iterator; // constructors: basic_address_range() noexcept : _M_begin({}), _M_end({}) { } basic_address_range(const address_v4& __first, const address_v4& __last) noexcept : _M_begin(__first), _M_end(__last) { } // members: iterator begin() const noexcept { return _M_begin; } iterator end() const noexcept { return _M_end; } _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; } size_t size() const noexcept { return _M_end->to_uint() - _M_begin->to_uint(); } iterator find(const address_v4& __addr) const noexcept { if (*_M_begin <= __addr && __addr < *_M_end) return iterator{__addr}; return end(); } private: iterator _M_begin; iterator _M_end; }; typedef basic_address_range<address_v4> address_v4_range; /// @} /** An IPv6 address range. * @{ */ template<> class basic_address_range<address_v6> { public: // types: typedef basic_address_iterator<address_v6> iterator; // constructors: basic_address_range() noexcept : _M_begin({}), _M_end({}) { } basic_address_range(const address_v6& __first, const address_v6& __last) noexcept : _M_begin(__first), _M_end(__last) { } // members: iterator begin() const noexcept { return _M_begin; } iterator end() const noexcept { return _M_end; } _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; } iterator find(const address_v6& __addr) const noexcept { if (*_M_begin <= __addr && __addr < *_M_end) return iterator{__addr}; return end(); } private: iterator _M_begin; iterator _M_end; }; typedef basic_address_range<address_v6> address_v6_range; bool operator==(const network_v4& __a, const network_v4& __b) noexcept; bool operator==(const network_v6& __a, const network_v6& __b) noexcept; /// @} /// An IPv4 network address. class network_v4 { public: // constructors: constexpr network_v4() noexcept : _M_addr(), _M_prefix_len(0) { } constexpr network_v4(const address_v4& __addr, int __prefix_len) : _M_addr(__addr), _M_prefix_len(__prefix_len) { if (_M_prefix_len < 0 || _M_prefix_len > 32) __throw_out_of_range("network_v4: invalid prefix length"); } constexpr network_v4(const address_v4& __addr, const address_v4& __mask) : _M_addr(__addr), _M_prefix_len(__builtin_popcount(__mask.to_uint())) { if (_M_prefix_len != 0) { address_v4::uint_type __mask_uint = __mask.to_uint(); if (__builtin_ctz(__mask_uint) != (32 - _M_prefix_len)) __throw_invalid_argument("network_v4: invalid mask"); if ((__mask_uint & 0x80000000) == 0) __throw_invalid_argument("network_v4: invalid mask"); } } // members: constexpr address_v4 address() const noexcept { return _M_addr; } constexpr int prefix_length() const noexcept { return _M_prefix_len; } constexpr address_v4 netmask() const noexcept { address_v4::uint_type __val = address_v4::broadcast().to_uint(); __val >>= (32 - _M_prefix_len); __val <<= (32 - _M_prefix_len); return address_v4{__val}; } constexpr address_v4 network() const noexcept { return address_v4{_M_addr.to_uint() & netmask().to_uint()}; } constexpr address_v4 broadcast() const noexcept { return address_v4{_M_addr.to_uint() | ~netmask().to_uint()}; } address_v4_range hosts() const noexcept { if (is_host()) return { address(), *++address_v4_iterator(address()) }; return { network(), broadcast() }; } constexpr network_v4 canonical() const noexcept { return network_v4(network(), prefix_length()); } constexpr bool is_host() const noexcept { return _M_prefix_len == 32; } constexpr bool is_subnet_of(const network_v4& __other) const noexcept { if (__other.prefix_length() < prefix_length()) { network_v4 __net(address(), __other.prefix_length()); return __net.canonical() == __other.canonical(); } return false; } template<typename _Allocator = allocator<char>> __string_with<_Allocator> to_string(const _Allocator& __a = _Allocator()) const { return address().to_string(__a) + '/' + std::to_string(prefix_length()); } private: address_v4 _M_addr; int _M_prefix_len; }; /// An IPv6 network address. class network_v6 { public: // constructors: constexpr network_v6() noexcept : _M_addr(), _M_prefix_len(0) { } constexpr network_v6(const address_v6& __addr, int __prefix_len) : _M_addr(__addr), _M_prefix_len(__prefix_len) { if (_M_prefix_len < 0 || _M_prefix_len > 128) __throw_out_of_range("network_v6: invalid prefix length"); } // members: constexpr address_v6 address() const noexcept { return _M_addr; } constexpr int prefix_length() const noexcept { return _M_prefix_len; } constexpr address_v6 network() const noexcept; // TODO address_v6_range hosts() const noexcept { if (is_host()) return { address(), *++address_v6_iterator(address()) }; return {}; // { network(), XXX broadcast() XXX }; // TODO } constexpr network_v6 canonical() const noexcept { return network_v6{network(), prefix_length()}; } constexpr bool is_host() const noexcept { return _M_prefix_len == 128; } constexpr bool is_subnet_of(const network_v6& __other) const noexcept { if (__other.prefix_length() < prefix_length()) { network_v6 __net(address(), __other.prefix_length()); return __net.canonical() == __other.canonical(); } return false; } template<typename _Allocator = allocator<char>> __string_with<_Allocator> to_string(const _Allocator& __a = _Allocator()) const { return address().to_string(__a) + '/' + std::to_string(prefix_length()); } private: address_v6 _M_addr; int _M_prefix_len; }; /** ip::network_v4 comparisons * @{ */ inline bool operator==(const network_v4& __a, const network_v4& __b) noexcept { return __a.address() == __b.address() && __a.prefix_length() == __b.prefix_length(); } inline bool operator!=(const network_v4& __a, const network_v4& __b) noexcept { return !(__a == __b); } /// @} /** ip::network_v6 comparisons * @{ */ inline bool operator==(const network_v6& __a, const network_v6& __b) noexcept { return __a.address() == __b.address() && __a.prefix_length() == __b.prefix_length(); } inline bool operator!=(const network_v6& __a, const network_v6& __b) noexcept { return !(__a == __b); } /// @} /** ip::network_v4 creation * @{ */ inline network_v4 make_network_v4(const address_v4& __a, int __prefix_len) { return network_v4{__a, __prefix_len}; } inline network_v4 make_network_v4(const address_v4& __a, const address_v4& __mask) { return network_v4{ __a, __mask }; } network_v4 make_network_v4(const char*, error_code&) noexcept; // TODO inline network_v4 make_network_v4(const char* __str) { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); } network_v4 make_network_v4(const string&, error_code&) noexcept; // TODO inline network_v4 make_network_v4(const string& __str) { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); } network_v4 make_network_v4(string_view, error_code&) noexcept; // TODO inline network_v4 make_network_v4(string_view __str) { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); } /// @} /** ip::network_v6 creation * @{ */ inline network_v6 make_network_v6(const address_v6& __a, int __prefix_len) { return network_v6{__a, __prefix_len}; } network_v6 make_network_v6(const char*, error_code&) noexcept; // TODO inline network_v6 make_network_v6(const char* __str) { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); } network_v6 make_network_v6(const string&, error_code&) noexcept; // TODO inline network_v6 make_network_v6(const string& __str) { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); } network_v6 make_network_v6(string_view, error_code&) noexcept; // TODO inline network_v6 make_network_v6(string_view __str) { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); } /// @} /// ip::network_v4 I/O template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v4& __net) { return __os << __net.to_string(); } /// ip::network_v6 I/O template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v6& __net) { return __os << __net.to_string(); } /// An IP endpoint. template<typename _InternetProtocol> class basic_endpoint { public: // types: typedef _InternetProtocol protocol_type; // constructors: constexpr basic_endpoint() noexcept : _M_data() { _M_data._M_v4.sin_family = protocol_type::v4().family(); } constexpr basic_endpoint(const protocol_type& __proto, port_type __port_num) noexcept : _M_data() { __glibcxx_assert(__proto == protocol_type::v4() || __proto == protocol_type::v6()); _M_data._M_v4.sin_family = __proto.family(); _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); } constexpr basic_endpoint(const ip::address& __addr, port_type __port_num) noexcept : _M_data() { if (__addr.is_v4()) { _M_data._M_v4.sin_family = protocol_type::v4().family(); _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr; } else { _M_data._M_v6 = {}; _M_data._M_v6.sin6_family = protocol_type::v6().family(); _M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num); __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr, __addr._M_v6._M_bytes.data(), 16); _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id; } } // members: constexpr protocol_type protocol() const noexcept { return _M_data._M_v4.sin_family == AF_INET6 ? protocol_type::v6() : protocol_type::v4(); } constexpr ip::address address() const noexcept { ip::address __addr; if (protocol().family() == AF_INET6) { __builtin_memcpy(&__addr._M_v6._M_bytes, _M_data._M_v6.sin6_addr.s6_addr, 16); __addr._M_is_v4 = false; } else { __builtin_memcpy(&__addr._M_v4._M_addr, &_M_data._M_v4.sin_addr.s_addr, 4); } return __addr; } void address(const ip::address& __addr) noexcept { if (__addr.is_v6()) { _M_data._M_v6 = {}; _M_data._M_v6.sin6_family = protocol_type::v6().family(); __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr, __addr._M_v6._M_bytes.data(), 16); _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id; } else { _M_data._M_v4.sin_family = protocol_type::v4().family(); _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr; } } constexpr port_type port() const noexcept { return address_v4::_S_ntoh_16(_M_data._M_v4.sin_port); } void port(port_type __port_num) noexcept { _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); } void* data() noexcept { return &_M_data; } const void* data() const noexcept { return &_M_data; } constexpr size_t size() const noexcept { return protocol().family() == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); } void resize(size_t __s) { if ((protocol().family() == AF_INET6 && __s != sizeof(sockaddr_in6)) || (protocol().family() == AF_INET && __s != sizeof(sockaddr_in))) __throw_length_error("net::ip::basic_endpoint::resize"); } constexpr size_t capacity() const noexcept { return sizeof(_M_data); } private: union { sockaddr_in _M_v4; sockaddr_in6 _M_v6; } _M_data; }; /** basic_endpoint comparisons * @{ */ template<typename _InternetProtocol> inline bool operator==(const basic_endpoint<_InternetProtocol>& __a, const basic_endpoint<_InternetProtocol>& __b) { return __a.address() == __b.address() && __a.port() == __b.port(); } template<typename _InternetProtocol> inline bool operator!=(const basic_endpoint<_InternetProtocol>& __a, const basic_endpoint<_InternetProtocol>& __b) { return !(__a == __b); } template<typename _InternetProtocol> inline bool operator< (const basic_endpoint<_InternetProtocol>& __a, const basic_endpoint<_InternetProtocol>& __b) { return __a.address() < __b.address() || (!(__b.address() < __a.address()) && __a.port() < __b.port()); } template<typename _InternetProtocol> inline bool operator> (const basic_endpoint<_InternetProtocol>& __a, const basic_endpoint<_InternetProtocol>& __b) { return __b < __a; } template<typename _InternetProtocol> inline bool operator<=(const basic_endpoint<_InternetProtocol>& __a, const basic_endpoint<_InternetProtocol>& __b) { return !(__b < __a); } template<typename _InternetProtocol> inline bool operator>=(const basic_endpoint<_InternetProtocol>& __a, const basic_endpoint<_InternetProtocol>& __b) { return !(__a < __b); } /// @} /// basic_endpoint I/O template<typename _CharT, typename _Traits, typename _InternetProtocol> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_endpoint<_InternetProtocol>& __ep) { basic_ostringstream<_CharT, _Traits> __ss; if (__ep.protocol() == basic_endpoint<_InternetProtocol>::protocol_type::v6()) __ss << '[' << __ep.address() << ']'; else __ss << __ep.address(); __ss << ':' << __ep.port(); __os << __ss.str(); return __os; } /** Type representing a single result of name/address resolution. * @{ */ template<typename _InternetProtocol> class basic_resolver_entry { public: // types: typedef _InternetProtocol protocol_type; typedef typename _InternetProtocol::endpoint endpoint_type; // constructors: basic_resolver_entry() { } basic_resolver_entry(const endpoint_type& __ep, string_view __h, string_view __s) : _M_ep(__ep), _M_host(__h), _M_svc(__s) { } // members: endpoint_type endpoint() const { return _M_ep; } operator endpoint_type() const { return _M_ep; } template<typename _Allocator = allocator<char>> __string_with<_Allocator> host_name(const _Allocator& __a = _Allocator()) const { return { _M_host, __a }; } template<typename _Allocator = allocator<char>> __string_with<_Allocator> service_name(const _Allocator& __a = _Allocator()) const { return { _M_svc, __a }; } private: basic_endpoint<_InternetProtocol> _M_ep; string _M_host; string _M_svc; }; template<typename _InternetProtocol> inline bool operator==(const basic_resolver_entry<_InternetProtocol>& __a, const basic_resolver_entry<_InternetProtocol>& __b) { return __a.endpoint() == __b.endpoint() && __a.host_name() == __b.host_name() && __a.service_name() == __b.service_name(); } template<typename _InternetProtocol> inline bool operator!=(const basic_resolver_entry<_InternetProtocol>& __a, const basic_resolver_entry<_InternetProtocol>& __b) { return !(__a == __b); } /// @} /** Base class defining flags for name/address resolution. * @{ */ class resolver_base { public: enum flags : int { __flags_passive = AI_PASSIVE, __flags_canonical_name = AI_CANONNAME, __flags_numeric_host = AI_NUMERICHOST, #ifdef AI_NUMERICSERV __flags_numeric_service = AI_NUMERICSERV, #endif __flags_v4_mapped = AI_V4MAPPED, __flags_all_matching = AI_ALL, __flags_address_configured = AI_ADDRCONFIG }; static constexpr flags passive = __flags_passive; static constexpr flags canonical_name = __flags_canonical_name; static constexpr flags numeric_host = __flags_numeric_host; #ifdef AI_NUMERICSERV static constexpr flags numeric_service = __flags_numeric_service; #endif static constexpr flags v4_mapped = __flags_v4_mapped; static constexpr flags all_matching = __flags_all_matching; static constexpr flags address_configured = __flags_address_configured; protected: resolver_base() = default; ~resolver_base() = default; }; constexpr resolver_base::flags operator&(resolver_base::flags __f1, resolver_base::flags __f2) { return resolver_base::flags( int(__f1) & int(__f2) ); } constexpr resolver_base::flags operator|(resolver_base::flags __f1, resolver_base::flags __f2) { return resolver_base::flags( int(__f1) | int(__f2) ); } constexpr resolver_base::flags operator^(resolver_base::flags __f1, resolver_base::flags __f2) { return resolver_base::flags( int(__f1) ^ int(__f2) ); } constexpr resolver_base::flags operator~(resolver_base::flags __f) { return resolver_base::flags( ~int(__f) ); } inline resolver_base::flags& operator&=(resolver_base::flags& __f1, resolver_base::flags __f2) { return __f1 = (__f1 & __f2); } inline resolver_base::flags& operator|=(resolver_base::flags& __f1, resolver_base::flags __f2) { return __f1 = (__f1 | __f2); } inline resolver_base::flags& operator^=(resolver_base::flags& __f1, resolver_base::flags __f2) { return __f1 = (__f1 ^ __f2); } // TODO define resolver_base::flags static constants for C++14 mode /// @} /** Container for results of name/address resolution. * @{ */ template<typename _InternetProtocol> class basic_resolver_results { public: // types: typedef _InternetProtocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; typedef basic_resolver_entry<protocol_type> value_type; typedef const value_type& const_reference; typedef value_type& reference; typedef typename forward_list<value_type>::const_iterator const_iterator; typedef const_iterator iterator; typedef ptrdiff_t difference_type; typedef size_t size_type; // construct / copy / destroy: basic_resolver_results() = default; basic_resolver_results(const basic_resolver_results&) = default; basic_resolver_results(basic_resolver_results&&) noexcept = default; basic_resolver_results& operator=(const basic_resolver_results&) = default; basic_resolver_results& operator=(basic_resolver_results&&) = default; ~basic_resolver_results() = default; // size: size_type size() const noexcept { return _M_size; } size_type max_size() const noexcept { return _M_results.max_size(); } _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_results.empty(); } // element access: const_iterator begin() const { return _M_results.begin(); } const_iterator end() const { return _M_results.end(); } const_iterator cbegin() const { return _M_results.begin(); } const_iterator cend() const { return _M_results.end(); } // swap: void swap(basic_resolver_results& __that) noexcept { _M_results.swap(__that._M_results); } private: friend class basic_resolver<protocol_type>; basic_resolver_results(string_view, string_view, resolver_base::flags, error_code&, protocol_type* = nullptr); basic_resolver_results(const endpoint_type&, error_code&); forward_list<value_type> _M_results; size_t _M_size = 0; }; template<typename _InternetProtocol> inline bool operator==(const basic_resolver_results<_InternetProtocol>& __a, const basic_resolver_results<_InternetProtocol>& __b) { return __a.size() == __b.size() && std::equal(__a.begin(), __a.end(), __b.begin()); } template<typename _InternetProtocol> inline bool operator!=(const basic_resolver_results<_InternetProtocol>& __a, const basic_resolver_results<_InternetProtocol>& __b) { return !(__a == __b); } /// @} /// Perform name/address resolution. template<typename _InternetProtocol> class basic_resolver : public resolver_base { public: // types: typedef io_context::executor_type executor_type; typedef _InternetProtocol protocol_type; typedef typename _InternetProtocol::endpoint endpoint_type; typedef basic_resolver_results<_InternetProtocol> results_type; // construct / copy / destroy: explicit basic_resolver(io_context& __ctx) : _M_ctx(&__ctx) { } basic_resolver(const basic_resolver&) = delete; basic_resolver(basic_resolver&& __rhs) noexcept : _M_ctx(__rhs._M_ctx) { } // TODO move state/tasks etc. ~basic_resolver() { cancel(); } basic_resolver& operator=(const basic_resolver&) = delete; basic_resolver& operator=(basic_resolver&& __rhs) { cancel(); _M_ctx = __rhs._M_ctx; // TODO move state/tasks etc. return *this; } // basic_resolver operations: executor_type get_executor() noexcept { return _M_ctx->get_executor(); } void cancel() { } // TODO results_type resolve(string_view __host_name, string_view __service_name) { return resolve(__host_name, __service_name, resolver_base::flags(), __throw_on_error{"basic_resolver::resolve"}); } results_type resolve(string_view __host_name, string_view __service_name, error_code& __ec) { return resolve(__host_name, __service_name, resolver_base::flags(), __ec); } results_type resolve(string_view __host_name, string_view __service_name, flags __f) { return resolve(__host_name, __service_name, __f, __throw_on_error{"basic_resolver::resolve"}); } results_type resolve(string_view __host_name, string_view __service_name, flags __f, error_code& __ec) { return {__host_name, __service_name, __f, __ec}; } template<typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, results_type)> async_resolve(string_view __host_name, string_view __service_name, _CompletionToken&& __token) { return async_resolve(__host_name, __service_name, resolver_base::flags(), forward<_CompletionToken>(__token)); } template<typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, results_type)> async_resolve(string_view __host_name, string_view __service_name, flags __f, _CompletionToken&& __token); // TODO results_type resolve(const protocol_type& __protocol, string_view __host_name, string_view __service_name) { return resolve(__protocol, __host_name, __service_name, resolver_base::flags(), __throw_on_error{"basic_resolver::resolve"}); } results_type resolve(const protocol_type& __protocol, string_view __host_name, string_view __service_name, error_code& __ec) { return resolve(__protocol, __host_name, __service_name, resolver_base::flags(), __ec); } results_type resolve(const protocol_type& __protocol, string_view __host_name, string_view __service_name, flags __f) { return resolve(__protocol, __host_name, __service_name, __f, __throw_on_error{"basic_resolver::resolve"}); } results_type resolve(const protocol_type& __protocol, string_view __host_name, string_view __service_name, flags __f, error_code& __ec) { return {__host_name, __service_name, __f, __ec, &__protocol}; } template<typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, results_type)> async_resolve(const protocol_type& __protocol, string_view __host_name, string_view __service_name, _CompletionToken&& __token) { return async_resolve(__protocol, __host_name, __service_name, resolver_base::flags(), forward<_CompletionToken>(__token)); } template<typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, results_type)> async_resolve(const protocol_type& __protocol, string_view __host_name, string_view __service_name, flags __f, _CompletionToken&& __token); // TODO results_type resolve(const endpoint_type& __ep) { return resolve(__ep, __throw_on_error{"basic_resolver::resolve"}); } results_type resolve(const endpoint_type& __ep, error_code& __ec) { return { __ep, __ec }; } template<typename _CompletionToken> // TODO __deduced_t<_CompletionToken, void(error_code, results_type)> async_resolve(const endpoint_type& __ep, _CompletionToken&& __token); private: io_context* _M_ctx; }; /// Private constructor to synchronously resolve host and service names. template<typename _InternetProtocol> basic_resolver_results<_InternetProtocol>:: basic_resolver_results(string_view __host_name, string_view __service_name, resolver_base::flags __f, error_code& __ec, protocol_type* __protocol) { #ifdef _GLIBCXX_HAVE_NETDB_H string __host; const char* __h = __host_name.data() ? (__host = __host_name.to_string()).c_str() : nullptr; string __svc; const char* __s = __service_name.data() ? (__svc = __service_name.to_string()).c_str() : nullptr; ::addrinfo __hints{ }; __hints.ai_flags = static_cast<int>(__f); if (__protocol) { __hints.ai_family = __protocol->family(); __hints.ai_socktype = __protocol->type(); __hints.ai_protocol = __protocol->protocol(); } else { auto __p = endpoint_type{}.protocol(); __hints.ai_family = AF_UNSPEC; __hints.ai_socktype = __p.type(); __hints.ai_protocol = __p.protocol(); } struct __scoped_addrinfo { ~__scoped_addrinfo() { if (_M_p) ::freeaddrinfo(_M_p); } ::addrinfo* _M_p = nullptr; } __sai; if (int __err = ::getaddrinfo(__h, __s, &__hints, &__sai._M_p)) { __ec.assign(__err, resolver_category()); return; } __ec.clear(); endpoint_type __ep; auto __tail = _M_results.before_begin(); for (auto __ai = __sai._M_p; __ai != nullptr; __ai = __ai->ai_next) { if (__ai->ai_family == AF_INET || __ai->ai_family == AF_INET6) { if (__ai->ai_addrlen <= __ep.capacity()) __builtin_memcpy(__ep.data(), __ai->ai_addr, __ai->ai_addrlen); __ep.resize(__ai->ai_addrlen); __tail = _M_results.emplace_after(__tail, __ep, __host, __svc); _M_size++; } } #else __ec = std::make_error_code(errc::operation_not_supported); #endif } /// Private constructor to synchronously resolve an endpoint. template<typename _InternetProtocol> basic_resolver_results<_InternetProtocol>:: basic_resolver_results(const endpoint_type& __ep, error_code& __ec) { #ifdef _GLIBCXX_HAVE_NETDB_H char __host_name[256]; char __service_name[128]; int __flags = 0; if (__ep.protocol().type() == SOCK_DGRAM) __flags |= NI_DGRAM; auto __sa = static_cast<const sockaddr*>(__ep.data()); int __err = ::getnameinfo(__sa, __ep.size(), __host_name, sizeof(__host_name), __service_name, sizeof(__service_name), __flags); if (__err) { __flags |= NI_NUMERICSERV; __err = ::getnameinfo(__sa, __ep.size(), __host_name, sizeof(__host_name), __service_name, sizeof(__service_name), __flags); } if (__err) __ec.assign(__err, resolver_category()); else { __ec.clear(); _M_results.emplace_front(__ep, __host_name, __service_name); _M_size = 1; } #else __ec = std::make_error_code(errc::operation_not_supported); #endif } /** The name of the local host. * @{ */ template<typename _Allocator> __string_with<_Allocator> host_name(const _Allocator& __a, error_code& __ec) { #ifdef HOST_NAME_MAX constexpr size_t __maxlen = HOST_NAME_MAX; #else constexpr size_t __maxlen = 256; #endif char __buf[__maxlen + 1]; if (::gethostname(__buf, __maxlen) == -1) __ec.assign(errno, generic_category()); __buf[__maxlen] = '\0'; return { __buf, __a }; } template<typename _Allocator> inline __string_with<_Allocator> host_name(const _Allocator& __a) { return host_name(__a, __throw_on_error{"host_name"}); } inline string host_name(error_code& __ec) { return host_name(std::allocator<char>{}, __ec); } inline string host_name() { return host_name(std::allocator<char>{}, __throw_on_error{"host_name"}); } /// @} /// The TCP byte-stream protocol. class tcp { public: // types: typedef basic_endpoint<tcp> endpoint; ///< A TCP endpoint. typedef basic_resolver<tcp> resolver; ///< A TCP resolver. typedef basic_stream_socket<tcp> socket; ///< A TCP socket. typedef basic_socket_acceptor<tcp> acceptor; ///< A TCP acceptor. typedef basic_socket_iostream<tcp> iostream; /// A TCP iostream. #ifdef _GLIBCXX_HAVE_NETINET_TCP_H /// Disable coalescing of small segments (i.e. the Nagle algorithm). struct no_delay : __sockopt_crtp<no_delay, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = IPPROTO_TCP; static const int _S_name = TCP_NODELAY; }; #endif // static members: /// A protocol object representing IPv4 TCP. static constexpr tcp v4() noexcept { return tcp(AF_INET); } /// A protocol object representing IPv6 TCP. static constexpr tcp v6() noexcept { return tcp(AF_INET6); } tcp() = delete; constexpr int family() const noexcept { return _M_family; } constexpr int type() const noexcept { return SOCK_STREAM; } constexpr int protocol() const noexcept { return IPPROTO_TCP; } private: constexpr explicit tcp(int __family) : _M_family(__family) { } int _M_family; }; /** tcp comparisons * @{ */ inline bool operator==(const tcp& __a, const tcp& __b) { return __a.family() == __b.family(); } inline bool operator!=(const tcp& __a, const tcp& __b) { return !(__a == __b); } /// @} /// The UDP datagram protocol. class udp { public: // types: typedef basic_endpoint<udp> endpoint; typedef basic_resolver<udp> resolver; typedef basic_datagram_socket<udp> socket; // static members: static constexpr udp v4() noexcept { return udp(AF_INET); } static constexpr udp v6() noexcept { return udp(AF_INET6); } udp() = delete; constexpr int family() const noexcept { return _M_family; } constexpr int type() const noexcept { return SOCK_DGRAM; } constexpr int protocol() const noexcept { return IPPROTO_UDP; } private: constexpr explicit udp(int __family) : _M_family(__family) { } int _M_family; }; /** udp comparisons * @{ */ inline bool operator==(const udp& __a, const udp& __b) { return __a.family() == __b.family(); } inline bool operator!=(const udp& __a, const udp& __b) { return !(__a == __b); } /// @} /// Restrict a socket created for an IPv6 protocol to IPv6 only. struct v6_only : __sockopt_crtp<v6_only, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = IPPROTO_IPV6; static const int _S_name = IPV6_V6ONLY; }; namespace unicast { /// Set the default number of hops (TTL) for outbound datagrams. struct hops : __sockopt_crtp<hops> { using __sockopt_crtp::__sockopt_crtp; template<typename _Protocol> int level(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; } template<typename _Protocol> int name(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPV6_UNICAST_HOPS : IP_TTL; } }; } // namespace unicast namespace multicast { /// Request that a socket joins a multicast group. struct join_group { explicit join_group(const address&); explicit join_group(const address_v4&, const address_v4& = address_v4::any()); explicit join_group(const address_v6&, unsigned int = 0); template<typename _Protocol> int level(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; } template<typename _Protocol> int name(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPV6_JOIN_GROUP : IP_ADD_MEMBERSHIP; } template<typename _Protocol> void* data(const _Protocol&) noexcept { return std::addressof(_M_value); } template<typename _Protocol> const void* data(const _Protocol&) const noexcept { return std::addressof(_M_value); } template<typename _Protocol> size_t size(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4); } template<typename _Protocol> void resize(const _Protocol& __p, size_t __s) { if (__s != size(__p)) __throw_length_error("invalid value for socket option resize"); } protected: union { ipv6_mreq _M_v6; ip_mreq _M_v4; } _M_value; }; /// Request that a socket leaves a multicast group. struct leave_group { explicit leave_group(const address&); explicit leave_group(const address_v4&, const address_v4& = address_v4::any()); explicit leave_group(const address_v6&, unsigned int = 0); template<typename _Protocol> int level(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; } template<typename _Protocol> int name(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPV6_LEAVE_GROUP : IP_DROP_MEMBERSHIP; } template<typename _Protocol> void* data(const _Protocol&) noexcept { return std::addressof(_M_value); } template<typename _Protocol> const void* data(const _Protocol&) const noexcept { return std::addressof(_M_value); } template<typename _Protocol> size_t size(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4); } template<typename _Protocol> void resize(const _Protocol& __p, size_t __s) { if (__s != size(__p)) __throw_length_error("invalid value for socket option resize"); } protected: union { ipv6_mreq _M_v6; ip_mreq _M_v4; } _M_value; }; /// Specify the network interface for outgoing multicast datagrams. class outbound_interface { explicit outbound_interface(const address_v4&); explicit outbound_interface(unsigned int); template<typename _Protocol> int level(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; } template<typename _Protocol> int name(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPV6_MULTICAST_IF : IP_MULTICAST_IF; } template<typename _Protocol> const void* data(const _Protocol&) const noexcept { return std::addressof(_M_value); } template<typename _Protocol> size_t size(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4); } protected: union { unsigned _M_v6; in_addr _M_v4; } _M_value; }; /// Set the default number of hops (TTL) for outbound datagrams. struct hops : __sockopt_crtp<hops> { using __sockopt_crtp::__sockopt_crtp; template<typename _Protocol> int level(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; } template<typename _Protocol> int name(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL; } }; /// Set whether datagrams are delivered back to the local application. struct enable_loopback : __sockopt_crtp<enable_loopback> { using __sockopt_crtp::__sockopt_crtp; template<typename _Protocol> int level(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; } template<typename _Protocol> int name(const _Protocol& __p) const noexcept { return __p.family() == AF_INET6 ? IPV6_MULTICAST_LOOP : IP_MULTICAST_LOOP; } }; } // namespace multicast /// @} } // namespace ip } // namespace v1 } // namespace net } // namespace experimental template<> struct is_error_condition_enum<experimental::net::v1::ip::resolver_errc> : public true_type {}; // hash support template<typename _Tp> struct hash; template<> struct hash<experimental::net::v1::ip::address> : __hash_base<size_t, experimental::net::v1::ip::address> { size_t operator()(const argument_type& __a) const { if (__a.is_v4()) return _Hash_impl::hash(__a.to_v4()); else return _Hash_impl::hash(__a.to_v6()); } }; template<> struct hash<experimental::net::v1::ip::address_v4> : __hash_base<size_t, experimental::net::v1::ip::address_v4> { size_t operator()(const argument_type& __a) const { return _Hash_impl::hash(__a.to_bytes()); } }; template<> struct hash<experimental::net::v1::ip::address_v6> : __hash_base<size_t, experimental::net::v1::ip::address_v6> { size_t operator()(const argument_type& __a) const { return _Hash_impl::hash(__a.to_bytes()); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++14 #endif // _GLIBCXX_EXPERIMENTAL_INTERNET
Close