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 : socket
// <experimental/socket> -*- 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/socket * This is a TS C++ Library header. */ #ifndef _GLIBCXX_EXPERIMENTAL_SOCKET #define _GLIBCXX_EXPERIMENTAL_SOCKET #pragma GCC system_header #if __cplusplus >= 201402L #include <experimental/netfwd> #include <experimental/buffer> #include <experimental/io_context> #include <experimental/bits/net.h> #include <streambuf> #include <istream> #include <bits/unique_ptr.h> #if _GLIBCXX_HAVE_UNISTD_H # include <unistd.h> # ifdef _GLIBCXX_HAVE_SYS_SOCKET_H # include <sys/socket.h> // socket etc # endif # ifdef _GLIBCXX_HAVE_SYS_IOCTL_H # include <sys/ioctl.h> // ioctl # endif # ifdef _GLIBCXX_HAVE_SYS_UIO_H # include <sys/uio.h> // iovec # endif # ifdef _GLIBCXX_HAVE_POLL_H # include <poll.h> // poll, pollfd, POLLIN, POLLOUT, POLLERR # endif # ifdef _GLIBCXX_HAVE_FCNTL_H # include <fcntl.h> // fcntl, F_GETFL, F_SETFL # endif #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace experimental { namespace net { inline namespace v1 { /** * @ingroup networking * @{ */ enum class socket_errc { // TODO decide values already_open = 3, not_found = 4 }; } // namespace v1 } // namespace net } // namespace experimental template<> struct is_error_code_enum<experimental::net::v1::socket_errc> : public true_type {}; namespace experimental { namespace net { inline namespace v1 { const error_category& socket_category() noexcept { struct __cat : error_category { const char* name() const noexcept { return "socket"; } std::string message(int __e) const { if (__e == (int)socket_errc::already_open) return "already open"; else if (__e == (int)socket_errc::not_found) return "endpoint not found"; return "socket error"; } virtual void __message(int) { } // TODO dual ABI XXX }; static __cat __c; return __c; } inline error_code make_error_code(socket_errc __e) noexcept { return error_code(static_cast<int>(__e), socket_category()); } inline error_condition make_error_condition(socket_errc __e) noexcept { return error_condition(static_cast<int>(__e), socket_category()); } template<typename _Tp, typename = __void_t<>> struct __is_endpoint_impl : false_type { }; // Check Endpoint requirements. template<typename _Tp> auto __endpoint_reqs(const _Tp* __a = 0) -> enable_if_t<__and_< is_default_constructible<_Tp>, __is_value_constructible<_Tp>, is_same<decltype(__a->__protocol()), typename _Tp::protocol_type> >::value, __void_t< typename _Tp::protocol_type::endpoint >>; template<typename _Tp> struct __is_endpoint_impl<_Tp, decltype(__endpoint_reqs<_Tp>())> : true_type { }; template<typename _Tp> struct __is_endpoint : __is_endpoint_impl<_Tp> { }; // TODO Endpoint reqs for extensible implementations // TODO _Protocol reqs // TODO AcceptableProtocol reqs // TODO GettableSocket reqs // TODO SettableSocket reqs // TODO BooleanSocketOption reqs // TODO IntegerSocketOption reqs // TODO _IoControlCommand reqs // TODO _ConnectCondition reqs /** @brief Sockets * @{ */ class socket_base { public: #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H struct broadcast : __sockopt_crtp<broadcast, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_BROADCAST; }; struct debug : __sockopt_crtp<debug, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_DEBUG; }; struct do_not_route : __sockopt_crtp<do_not_route, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_DONTROUTE; }; struct keep_alive : __sockopt_crtp<keep_alive, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_KEEPALIVE; }; struct linger : __sockopt_crtp<linger, ::linger> { using __sockopt_crtp::__sockopt_crtp; linger() noexcept = default; linger(bool __e, chrono::seconds __t) noexcept { enabled(__e); timeout(__t); } bool enabled() const noexcept { return _M_value.l_onoff != 0; } void enabled(bool __e) noexcept { _M_value.l_onoff = int(__e); } chrono::seconds timeout() const noexcept { return chrono::seconds(_M_value.l_linger); } void timeout(chrono::seconds __t) noexcept { _M_value.l_linger = __t.count(); } static const int _S_level = SOL_SOCKET; static const int _S_name = SO_LINGER; }; struct out_of_band_inline : __sockopt_crtp<out_of_band_inline, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_OOBINLINE; }; struct receive_buffer_size : __sockopt_crtp<receive_buffer_size> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_RCVBUF; }; struct receive_low_watermark : __sockopt_crtp<receive_low_watermark> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_RCVLOWAT; }; struct reuse_address : __sockopt_crtp<reuse_address, bool> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_REUSEADDR; }; struct send_buffer_size : __sockopt_crtp<send_buffer_size> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_SNDBUF; }; struct send_low_watermark : __sockopt_crtp<send_low_watermark> { using __sockopt_crtp::__sockopt_crtp; static const int _S_level = SOL_SOCKET; static const int _S_name = SO_SNDLOWAT; }; enum shutdown_type : int { __shutdown_receive = SHUT_RD, __shutdown_send = SHUT_WR, __shutdown_both = SHUT_RDWR }; static constexpr shutdown_type shutdown_receive = __shutdown_receive; static constexpr shutdown_type shutdown_send = __shutdown_send; static constexpr shutdown_type shutdown_both = __shutdown_both; #ifdef _GLIBCXX_HAVE_POLL_H enum wait_type : int { __wait_read = POLLIN, __wait_write = POLLOUT, __wait_error = POLLERR }; static constexpr wait_type wait_read = __wait_read; static constexpr wait_type wait_write = __wait_write; static constexpr wait_type wait_error = __wait_error; #endif enum message_flags : int { __message_peek = MSG_PEEK, __message_oob = MSG_OOB, __message_dontroute = MSG_DONTROUTE }; static constexpr message_flags message_peek = __message_peek; static constexpr message_flags message_out_of_band = __message_oob; static constexpr message_flags message_do_not_route = __message_dontroute; static const int max_listen_connections = SOMAXCONN; #endif protected: socket_base() = default; ~socket_base() = default; #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H struct __msg_hdr : ::msghdr { #ifdef IOV_MAX using __iovec_array = array<::iovec, IOV_MAX>; #elif _GLIBCXX_HAVE_UNISTD_H struct __iovec_array { __iovec_array() : _M_ptr(new ::iovec[size()]) { } ::iovec& operator[](size_t __n) noexcept { return _M_ptr[__n]; } ::iovec* data() noexcept { return _M_ptr.get(); } static size_t size() { static const size_t __iov_max = ::sysconf(_SC_IOV_MAX); return __iov_max; } private: unique_ptr<::iovec[]> _M_ptr; }; #else using __iovec_array = array<::iovec, 16>; #endif __iovec_array _M_iov; template<typename _BufferSequence> explicit __msg_hdr(const _BufferSequence& __buffers) : msghdr() { auto __buf = net::buffer_sequence_begin(__buffers); const auto __bufend = net::buffer_sequence_end(__buffers); size_t __len = 0; while (__buf != __bufend && __len != _M_iov.size()) { _M_iov[__len].iov_base = (void*)__buf->data(); _M_iov[__len].iov_len = __buf->size(); ++__buf; ++__len; } this->msg_iovlen = __len; this->msg_iov = _M_iov.data(); } template<typename _BufferSequence, typename _Endpoint> __msg_hdr(const _BufferSequence& __buffers, const _Endpoint& __ep) : __msg_hdr(__buffers) { this->msg_name = __ep.data(); this->msg_namelen = __ep.size(); } }; #endif }; constexpr socket_base::message_flags operator&(socket_base::message_flags __f1, socket_base::message_flags __f2) { return socket_base::message_flags( int(__f1) & int(__f2) ); } constexpr socket_base::message_flags operator|(socket_base::message_flags __f1, socket_base::message_flags __f2) { return socket_base::message_flags( int(__f1) | int(__f2) ); } constexpr socket_base::message_flags operator^(socket_base::message_flags __f1, socket_base::message_flags __f2) { return socket_base::message_flags( int(__f1) ^ int(__f2) ); } constexpr socket_base::message_flags operator~(socket_base::message_flags __f) { return socket_base::message_flags( ~int(__f) ); } inline socket_base::message_flags& operator&=(socket_base::message_flags& __f1, socket_base::message_flags __f2) { return __f1 = (__f1 & __f2); } inline socket_base::message_flags& operator|=(socket_base::message_flags& __f1, socket_base::message_flags __f2) { return __f1 = (__f1 | __f2); } inline socket_base::message_flags& operator^=(socket_base::message_flags& __f1, socket_base::message_flags __f2) { return __f1 = (__f1 ^ __f2); } #if _GLIBCXX_HAVE_UNISTD_H class __socket_impl { protected: using executor_type = io_context::executor_type; using native_handle_type = int; explicit __socket_impl(io_context& __ctx) : _M_ctx(std::addressof(__ctx)) { } __socket_impl(__socket_impl&& __rhs) : _M_ctx(__rhs._M_ctx), _M_sockfd(std::exchange(__rhs._M_sockfd, -1)), _M_bits(std::exchange(__rhs._M_bits, {})) { } __socket_impl& operator=(__socket_impl&& __rhs) { _M_ctx = __rhs._M_ctx; _M_sockfd = std::exchange(__rhs._M_sockfd, -1); _M_bits = std::exchange(__rhs._M_bits, {}); return *this; } ~__socket_impl() = default; __socket_impl(const __socket_impl&) = delete; __socket_impl& operator=(const __socket_impl&) = delete; executor_type get_executor() noexcept { return _M_ctx->get_executor(); } native_handle_type native_handle() noexcept { return _M_sockfd; } bool is_open() const noexcept { return _M_sockfd != -1; } void close(error_code& __ec) { if (is_open()) { cancel(__ec); if (!__ec) { if (::close(_M_sockfd) == -1) __ec.assign(errno, generic_category()); else { get_executor().context()._M_remove_fd(_M_sockfd); _M_sockfd = -1; } } } } void cancel(error_code& __ec) { _M_ctx->cancel(_M_sockfd, __ec); } void non_blocking(bool __mode, error_code&) { _M_bits.non_blocking = __mode; } bool non_blocking() const { return _M_bits.non_blocking; } void native_non_blocking(bool __mode, error_code& __ec) { #ifdef _GLIBCXX_HAVE_FCNTL_H int __flags = ::fcntl(_M_sockfd, F_GETFL, 0); if (__flags >= 0) { if (__mode) __flags |= O_NONBLOCK; else __flags &= ~O_NONBLOCK; __flags = ::fcntl(_M_sockfd, F_SETFL, __flags); } if (__flags == -1) __ec.assign(errno, generic_category()); else { __ec.clear(); _M_bits.native_non_blocking = __mode; } #else __ec = std::make_error_code(std::errc::not_supported); #endif } bool native_non_blocking() const { #ifdef _GLIBCXX_HAVE_FCNTL_H if (_M_bits.native_non_blocking == -1) { const int __flags = ::fcntl(_M_sockfd, F_GETFL, 0); if (__flags == -1) return 0; _M_bits.native_non_blocking = __flags & O_NONBLOCK; } return _M_bits.native_non_blocking; #else return false; #endif } io_context* _M_ctx; int _M_sockfd{-1}; struct { unsigned non_blocking : 1; mutable signed native_non_blocking : 2; unsigned enable_connection_aborted : 1; } _M_bits{}; }; template<typename _Protocol> class __basic_socket_impl : public __socket_impl { using __base = __socket_impl; protected: using protocol_type = _Protocol; using endpoint_type = typename protocol_type::endpoint; explicit __basic_socket_impl(io_context& __ctx) : __base(__ctx) { } __basic_socket_impl(__basic_socket_impl&&) = default; template<typename _OtherProtocol> __basic_socket_impl(__basic_socket_impl<_OtherProtocol>&& __rhs) : __base(std::move(__rhs)), _M_protocol(std::move(__rhs._M_protocol)) { } __basic_socket_impl& operator=(__basic_socket_impl&& __rhs) { if (this == std::addressof(__rhs)) return *this; _M_close(); __base::operator=(std::move(__rhs)); return *this; } ~__basic_socket_impl() { _M_close(); } __basic_socket_impl(const __basic_socket_impl&) = delete; __basic_socket_impl& operator=(const __basic_socket_impl&) = delete; void open(const protocol_type& __protocol, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (is_open()) __ec = socket_errc::already_open; else { _M_protocol = __protocol; _M_sockfd = ::socket(__protocol.family(), __protocol.type(), __protocol.protocol()); if (is_open()) { get_executor().context()._M_add_fd(_M_sockfd); __ec.clear(); } else __ec.assign(errno, std::generic_category()); } #else __ec = std::make_error_code(errc::operation_not_supported); #endif } void assign(const protocol_type& __protocol, const native_handle_type& __native_socket, error_code& __ec) { if (is_open()) __ec = socket_errc::already_open; else { _M_protocol = __protocol; _M_bits.native_non_blocking = -1; _M_sockfd = __native_socket; if (is_open()) { get_executor().context()._M_add_fd(_M_sockfd); __ec.clear(); } else __ec.assign(errno, std::generic_category()); } } template<typename _SettableSocketOption> void set_option(const _SettableSocketOption& __option, error_code& __ec) { int __result = ::setsockopt(_M_sockfd, __option.level(_M_protocol), __option.name(_M_protocol), __option.data(_M_protocol), __option.size(_M_protocol)); if (__result == -1) __ec.assign(errno, generic_category()); else __ec.clear(); } template<typename _GettableSocketOption> void get_option(_GettableSocketOption& __option, error_code& __ec) const { int __result = ::getsockopt(_M_sockfd, __option.level(_M_protocol), __option.name(_M_protocol), __option.data(_M_protocol), __option.size(_M_protocol)); if (__result == -1) __ec.assign(errno, generic_category()); else __ec.clear(); } template<typename _IoControlCommand> void io_control(_IoControlCommand& __command, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_IOCTL_H int __result = ::ioctl(_M_sockfd, __command.name(), __command.data()); if (__result == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(std::errc::not_supported); #endif } endpoint_type local_endpoint(error_code& __ec) const { endpoint_type __endpoint; #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socklen_t __endpoint_len = __endpoint.capacity(); if (::getsockname(_M_sockfd, (sockaddr*)__endpoint.data(), &__endpoint_len) == -1) { __ec.assign(errno, generic_category()); return endpoint_type{}; } __ec.clear(); __endpoint.resize(__endpoint_len); #else __ec = std::make_error_code(errc::operation_not_supported); #endif return __endpoint; } void bind(const endpoint_type& __endpoint, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (::bind(_M_sockfd, (sockaddr*)__endpoint.data(), __endpoint.size()) == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(errc::operation_not_supported); #endif } _Protocol _M_protocol{ endpoint_type{}.protocol() }; private: void _M_close() { if (is_open()) { error_code __ec; cancel(__ec); set_option(socket_base::linger{false, chrono::seconds{}}, __ec); ::close(_M_sockfd); } } }; template<typename _Protocol> class basic_socket : public socket_base, private __basic_socket_impl<_Protocol> { using __base = __basic_socket_impl<_Protocol>; public: // types: typedef io_context::executor_type executor_type; typedef int native_handle_type; typedef _Protocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; // basic_socket operations: executor_type get_executor() noexcept { return __base::get_executor(); } native_handle_type native_handle() noexcept { return __base::native_handle(); } void open(const protocol_type& __protocol = protocol_type()) { open(__protocol, __throw_on_error{"basic_socket::open"}); } void open(const protocol_type& __protocol, error_code& __ec) { __base::open(__protocol, __ec); } void assign(const protocol_type& __protocol, const native_handle_type& __native_socket) { assign(__protocol, __native_socket, __throw_on_error{"basic_socket::assign"}); } void assign(const protocol_type& __protocol, const native_handle_type& __native_socket, error_code& __ec) { __base::assign(__protocol, __native_socket, __ec); } bool is_open() const noexcept { return __base::is_open(); } void close() { close(__throw_on_error{"basic_socket::close"}); } void close(error_code& __ec) { __base::close(); } void cancel() { cancel(__throw_on_error{"basic_socket::cancel"}); } void cancel(error_code& __ec) { __base::cancel(__ec); } template<typename _SettableSocketOption> void set_option(const _SettableSocketOption& __option) { set_option(__option, __throw_on_error{"basic_socket::set_option"}); } template<typename _SettableSocketOption> void set_option(const _SettableSocketOption& __option, error_code& __ec) { __base::set_option(__option, __ec); } template<typename _GettableSocketOption> void get_option(_GettableSocketOption& __option) const { get_option(__option, __throw_on_error{"basic_socket::get_option"}); } template<typename _GettableSocketOption> void get_option(_GettableSocketOption& __option, error_code& __ec) const { __base::get_option(__option, __ec); } template<typename _IoControlCommand> void io_control(_IoControlCommand& __command) { io_control(__command, __throw_on_error{"basic_socket::io_control"}); } template<typename _IoControlCommand> void io_control(_IoControlCommand& __command, error_code& __ec) { __base::io_control(__command, __ec); } void non_blocking(bool __mode) { non_blocking(__mode, __throw_on_error{"basic_socket::non_blocking"}); } void non_blocking(bool __mode, error_code& __ec) { __base::non_blocking(__mode, __ec); } bool non_blocking() const { return __base::non_blocking(); } void native_non_blocking(bool __mode) { native_non_blocking(__mode, __throw_on_error{ "basic_socket::native_non_blocking"}); } void native_non_blocking(bool __mode, error_code& __ec) { __base::native_non_blocking(__mode, __ec); } bool native_non_blocking() const { return __base::native_non_blocking(); } bool at_mark() const { return at_mark(__throw_on_error{"basic_socket::at_mark"}); } bool at_mark(error_code& __ec) const { #ifdef _GLIBCXX_HAVE_SOCKATMARK const int __result = ::sockatmark(native_handle()); if (__result == -1) { __ec.assign(errno, generic_category()); return false; } __ec.clear(); return (bool)__result; #else __ec = std::make_error_code(errc::operation_not_supported); return false; #endif } size_t available() const { return available(__throw_on_error{"basic_socket::available"}); } size_t available(error_code& __ec) const { if (!is_open()) { __ec = std::make_error_code(errc::bad_file_descriptor); return 0; } #if defined _GLIBCXX_HAVE_SYS_IOCTL_H && defined FIONREAD int __avail = 0; if (::ioctl(this->_M_sockfd, FIONREAD, &__avail) == -1) { __ec.assign(errno, generic_category()); return 0; } __ec.clear(); return __avail; #else return 0; #endif } void bind(const endpoint_type& __endpoint) { return bind(__endpoint, __throw_on_error{"basic_socket::bind"}); } void bind(const endpoint_type& __endpoint, error_code& __ec) { __base::bind(__endpoint, __ec); } void shutdown(shutdown_type __what) { return shutdown(__what, __throw_on_error{"basic_socket::shutdown"}); } void shutdown(shutdown_type __what, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (::shutdown(native_handle(), static_cast<int>(__what)) == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(errc::operation_not_supported); #endif } endpoint_type local_endpoint() const { return local_endpoint( __throw_on_error{"basic_socket::local_endpoint"}); } endpoint_type local_endpoint(error_code& __ec) const { return __base::local_endpoint(__ec); } endpoint_type remote_endpoint() const { return remote_endpoint( __throw_on_error{"basic_socket::remote_endpoint"}); } endpoint_type remote_endpoint(error_code& __ec) const { endpoint_type __endpoint; #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socklen_t __endpoint_len = __endpoint.capacity(); if (::getpeername(this->_M_sockfd, (sockaddr*)__endpoint.data(), &__endpoint_len) == -1) { __ec.assign(errno, generic_category()); return endpoint_type{}; } __ec.clear(); __endpoint.resize(__endpoint_len); #else __ec = std::make_error_code(errc::operation_not_supported); #endif return __endpoint; } void connect(const endpoint_type& __endpoint) { return connect(__endpoint, __throw_on_error{"basic_socket::connect"}); } void connect(const endpoint_type& __endpoint, error_code& __ec) { if (!is_open()) { open(__endpoint.protocol(), __ec); if (__ec) return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (::connect(native_handle(), (const sockaddr*)__endpoint.data(), __endpoint.size()) == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(errc::operation_not_supported); #endif } template<typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code)> async_connect(const endpoint_type& __endpoint, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code)> __init{__token}; if (!is_open()) { error_code __ec; open(__endpoint.protocol(), __ec); if (__ec) { auto __ex = net::get_associated_executor( __init.completion_handler, get_executor()); auto __a = get_associated_allocator( __init.completion_handler, std::allocator<void>()); __ex.post( [__h=std::move(__init.completion_handler), __ec] () mutable { __h(__ec); }, __a); return __init.result.get(); } } get_executor().context().async_wait( native_handle(), socket_base::wait_read, [__h = std::move(__init.completion_handler), __ep = std::move(__endpoint), __fd = native_handle()] (error_code __ec) mutable { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (!__ec && ::connect(__fd, (const sockaddr*)__ep.data(), __ep.size()) == -1) __ec.assign(errno, generic_category()); #else __ec = std::make_error_code(errc::operation_not_supported); #endif __h(__ec); }); return __init.result.get(); } void wait(wait_type __w) { return wait(__w, __throw_on_error{"basic_socket::wait"}); } void wait(wait_type __w, error_code& __ec) { #ifdef _GLIBCXX_HAVE_POLL_H ::pollfd __fd; __fd.fd = native_handle(); __fd.events = static_cast<int>(__w); int __res = ::poll(&__fd, 1, -1); if (__res == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(errc::operation_not_supported); #endif } template<typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code)> async_wait(wait_type __w, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code)> __init{__token}; get_executor().context().async_wait( native_handle(), static_cast<int>(__w), [__h = std::move(__init.completion_handler)] (error_code __ec) mutable { __h(__ec); }); return __init.result.get(); } protected: // construct / copy / destroy: using __base::__base; explicit basic_socket(io_context& __ctx) : __base(__ctx) { } basic_socket(io_context& __ctx, const protocol_type& __protocol) : __base(__ctx) { open(__protocol); } basic_socket(io_context& __ctx, const endpoint_type& __endpoint) : basic_socket(std::addressof(__ctx), __endpoint.protocol()) { bind(__endpoint); } basic_socket(io_context& __ctx, const protocol_type& __protocol, const native_handle_type& __native_socket) : __base(__ctx) { assign(__protocol, __native_socket); } basic_socket(const basic_socket&) = delete; basic_socket(basic_socket&& __rhs) = default; template<typename _OtherProtocol, typename _Requires = _Require<is_convertible<_OtherProtocol, _Protocol>>> basic_socket(basic_socket<_OtherProtocol>&& __rhs) : __base(std::move(__rhs)) { } ~basic_socket() = default; basic_socket& operator=(const basic_socket&) = delete; basic_socket& operator=(basic_socket&& __rhs) = default; template<typename _OtherProtocol> enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value, basic_socket&> operator=(basic_socket<_OtherProtocol>&& __rhs) { return *this = basic_socket{std::move(__rhs)}; } }; template<typename _Protocol> class basic_datagram_socket : public basic_socket<_Protocol> { using __base = basic_socket<_Protocol>; public: // types: typedef int native_handle_type; typedef _Protocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; // construct / copy / destroy: explicit basic_datagram_socket(io_context& __ctx) : __base(__ctx) { } basic_datagram_socket(io_context& __ctx, const protocol_type& __protocol) : __base(__ctx, __protocol) { } basic_datagram_socket(io_context& __ctx, const endpoint_type& __endpoint) : __base(__ctx, __endpoint) { } basic_datagram_socket(io_context& __ctx, const protocol_type& __protocol, const native_handle_type& __native_socket) : __base(__ctx, __protocol, __native_socket) { } basic_datagram_socket(const basic_datagram_socket&) = delete; basic_datagram_socket(basic_datagram_socket&& __rhs) = default; template<typename _OtherProtocol, typename _Requires = _Require<is_convertible<_OtherProtocol, _Protocol>>> basic_datagram_socket(basic_datagram_socket<_OtherProtocol>&& __rhs) : __base(std::move(__rhs)) { } ~basic_datagram_socket() = default; basic_datagram_socket& operator=(const basic_datagram_socket&) = delete; basic_datagram_socket& operator=(basic_datagram_socket&& __rhs) = default; template<typename _OtherProtocol> enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value, basic_datagram_socket&> operator=(basic_datagram_socket<_OtherProtocol>&& __rhs) { __base::operator=(std::move(__rhs)); return *this; } // basic_datagram_socket operations: template<typename _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers) { return receive(__buffers, socket_base::message_flags(), __throw_on_error{"basic_datagram_socket::receive"}); } template<typename _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers, error_code& __ec) { return receive(__buffers, socket_base::message_flags(), __ec); } template<typename _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers, socket_base::message_flags __flags) { return receive(__buffers, __flags, __throw_on_error{"basic_datagram_socket::receive"}); } template<typename _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers, socket_base::message_flags __flags, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::recvmsg(this->native_handle(), &__msg, static_cast<int>(__flags)); if (__result == -1) { __ec.assign(errno, generic_category()); return 0; } __ec.clear(); return __result; #else __ec = std::make_error_code(errc::operation_not_supported); return 0; #endif } template<typename _MutableBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_receive(const _MutableBufferSequence& __buffers, _CompletionToken&& __token) { return async_receive(__buffers, socket_base::message_flags(), std::forward<_CompletionToken>(__token)); } template<typename _MutableBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_receive(const _MutableBufferSequence& __buffers, socket_base::message_flags __flags, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, size_t)> __init{__token}; this->get_executor().context().async_wait(this->native_handle(), socket_base::wait_read, [__h = std::move(__init.completion_handler), &__buffers, __flags = static_cast<int>(__flags), __fd = this->native_handle()] (error_code __ec) mutable { if (__ec) { __h(__ec); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::recvmsg(__fd, &__msg, __flags); if (__result == -1) { __ec.assign(errno, generic_category()); __result = 0; } else __ec.clear(); __h(__ec, __result); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } template<typename _MutableBufferSequence> size_t receive_from(const _MutableBufferSequence& __buffers, endpoint_type& __sender) { return receive_from(__buffers, __sender, socket_base::message_flags(), __throw_on_error{ "basic_datagram_socket::receive_from"}); } template<typename _MutableBufferSequence> size_t receive_from(const _MutableBufferSequence& __buffers, endpoint_type& __sender, error_code& __ec) { return receive_from(__buffers, __sender, socket_base::message_flags(), __ec); } template<typename _MutableBufferSequence> size_t receive_from(const _MutableBufferSequence& __buffers, endpoint_type& __sender, socket_base::message_flags __flags) { return receive_from(__buffers, __sender, __flags, __throw_on_error{ "basic_datagram_socket::receive_from"}); } template<typename _MutableBufferSequence> size_t receive_from(const _MutableBufferSequence& __buffers, endpoint_type& __sender, socket_base::message_flags __flags, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers, __sender); ssize_t __result = ::recvmsg(this->native_handle(), &__msg, static_cast<int>(__flags)); if (__result == -1) { __ec.assign(errno, generic_category()); return 0; } __ec.clear(); __sender.resize(__msg.msg_namelen); return __result; #else __ec = std::make_error_code(errc::operation_not_supported); return 0; #endif } template<typename _MutableBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_receive_from(const _MutableBufferSequence& __buffers, endpoint_type& __sender, _CompletionToken&& __token) { return async_receive_from(__buffers, __sender, socket_base::message_flags(), std::forward<_CompletionToken>(__token)); } template<typename _MutableBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_receive_from(const _MutableBufferSequence& __buffers, endpoint_type& __sender, socket_base::message_flags __flags, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, size_t)> __init{__token}; this->get_executor().context().async_wait( this->native_handle(), socket_base::wait_read, [__h = std::move(__init.completion_handler), &__buffers, __flags = static_cast<int>(__flags), __sender = std::move(__sender), __fd = this->native_handle()] (error_code __ec) mutable { if (__ec) { __h(__ec); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers, __sender); ssize_t __result = ::recvmsg(__fd, &__msg, __flags); if (__result == -1) { __ec.assign(errno, generic_category()); __result = 0; } else { __ec.clear(); __sender.resize(__msg.msg_namelen); } __h(__ec, __result); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } template<typename _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers) { return send(__buffers, socket_base::message_flags(), __throw_on_error{"basic_datagram_socket::send"}); } template<typename _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers, error_code& __ec) { return send(__buffers, socket_base::message_flags(), __ec); } template<typename _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers, socket_base::message_flags __flags) { return send(__buffers, __flags, __throw_on_error{"basic_datagram_socket::send"}); } template<typename _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers, socket_base::message_flags __flags, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::sendmsg(this->native_handle(), &__msg, static_cast<int>(__flags)); if (__result == -1) { __ec.assign(errno, generic_category()); return 0; } __ec.clear(); return __result; #else __ec = std::make_error_code(errc::operation_not_supported); return 0; #endif } template<typename _ConstBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_send(const _ConstBufferSequence& __buffers, _CompletionToken&& __token) { return async_send(__buffers, socket_base::message_flags(), std::forward<_CompletionToken>(__token)); } template<typename _ConstBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_send(const _ConstBufferSequence& __buffers, socket_base::message_flags __flags, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, size_t)> __init{__token}; this->get_executor().context().async_wait( this->native_handle(), socket_base::wait_write, [__h = std::move(__init.completion_handler), &__buffers, __flags = static_cast<int>(__flags), __fd = this->native_handle()] (error_code __ec) mutable { if (__ec) { __h(__ec); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::sendmsg(__fd, &__msg, __flags); if (__result == -1) { __ec.assign(errno, generic_category()); __result = 0; } else __ec.clear(); __h(__ec, __result); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } template<typename _ConstBufferSequence> size_t send_to(const _ConstBufferSequence& __buffers, const endpoint_type& __recipient) { return send_to(__buffers, __recipient, socket_base::message_flags(), __throw_on_error{"basic_datagram_socket::send_to"}); } template<typename _ConstBufferSequence> size_t send_to(const _ConstBufferSequence& __buffers, const endpoint_type& __recipient, error_code& __ec) { return send_to(__buffers, __recipient, socket_base::message_flags(), __ec); } template<typename _ConstBufferSequence> size_t send_to(const _ConstBufferSequence& __buffers, const endpoint_type& __recipient, socket_base::message_flags __flags) { return send_to(__buffers, __recipient, __flags, __throw_on_error{"basic_datagram_socket::send_to"}); } template<typename _ConstBufferSequence> size_t send_to(const _ConstBufferSequence& __buffers, const endpoint_type& __recipient, socket_base::message_flags __flags, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers, __recipient); ssize_t __result = ::sendmsg(this->native_handle(), &__msg, static_cast<int>(__flags)); if (__result == -1) { __ec.assign(errno, generic_category()); return 0; } __ec.clear(); __recipient.resize(__msg.msg_namelen); return __result; #else __ec = std::make_error_code(errc::operation_not_supported); return 0; #endif } template<typename _ConstBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_send_to(const _ConstBufferSequence& __buffers, const endpoint_type& __recipient, _CompletionToken&& __token) { return async_send_to(__buffers, __recipient, socket_base::message_flags(), std::forward<_CompletionToken>(__token)); } template<typename _ConstBufferSequence, typename _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_send_to(const _ConstBufferSequence& __buffers, const endpoint_type& __recipient, socket_base::message_flags __flags, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, size_t)> __init{__token}; this->get_executor().context().async_wait( this->native_handle(), socket_base::wait_write, [__h = std::move(__init.completion_handler), &__buffers, __flags = static_cast<int>(__flags), __recipient = std::move(__recipient), __fd = this->native_handle()] (error_code __ec) mutable { if (__ec) { __h(__ec); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers, __recipient); ssize_t __result = ::sendmsg(__fd, &__msg, __flags); if (__result == -1) { __ec.assign(errno, generic_category()); __result = 0; } else { __ec.clear(); __recipient.resize(__msg.msg_namelen); } __h(__ec, __result); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } }; template<typename _Protocol> class basic_stream_socket : public basic_socket<_Protocol> { using __base = basic_socket<_Protocol>; public: // types: typedef int native_handle_type; typedef _Protocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; // construct / copy / destroy: explicit basic_stream_socket(io_context& __ctx) : __base(__ctx) { } basic_stream_socket(io_context& __ctx, const protocol_type& __protocol) : __base(__ctx, __protocol) { } basic_stream_socket(io_context& __ctx, const endpoint_type& __endpoint) : __base(__ctx, __endpoint) { } basic_stream_socket(io_context& __ctx, const protocol_type& __protocol, const native_handle_type& __native_socket) : __base(__ctx, __protocol, __native_socket) { } basic_stream_socket(const basic_stream_socket&) = delete; basic_stream_socket(basic_stream_socket&& __rhs) = default; template<typename _OtherProtocol, typename _Requires = _Require<is_convertible<_OtherProtocol, _Protocol>>> basic_stream_socket(basic_stream_socket<_OtherProtocol>&& __rhs) : __base(std::move(__rhs)) { } ~basic_stream_socket() = default; basic_stream_socket& operator=(const basic_stream_socket&) = delete; basic_stream_socket& operator=(basic_stream_socket&& __rhs) = default; template<class _OtherProtocol> enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value, basic_stream_socket&> operator=(basic_stream_socket<_OtherProtocol>&& __rhs) { __base::operator=(std::move(__rhs)); return *this; } // basic_stream_socket operations: template<class _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers) { return receive(__buffers, socket_base::message_flags(), __throw_on_error{"basic_stream_socket::receive"}); } template<class _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers, error_code& __ec) { return receive(__buffers, socket_base::message_flags(), __ec); } template<class _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers, socket_base::message_flags __flags) { return receive(__buffers, __flags, __throw_on_error{"basic_stream_socket::receive"}); } template<class _MutableBufferSequence> size_t receive(const _MutableBufferSequence& __buffers, socket_base::message_flags __flags, error_code& __ec) { if (__buffer_empty(__buffers)) { __ec.clear(); return 0; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::recvmsg(this->native_handle(), &__msg, static_cast<int>(__flags)); if (__result >= 0) { __ec.clear(); return __result; } __ec.assign(errno, generic_category()); #else __ec = std::make_error_code(errc::operation_not_supported); #endif return 0; } template<class _MutableBufferSequence, class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_receive(const _MutableBufferSequence& __buffers, _CompletionToken&& __token) { return async_receive(__buffers, socket_base::message_flags(), std::forward<_CompletionToken>(__token)); } template<class _MutableBufferSequence, class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_receive(const _MutableBufferSequence& __buffers, socket_base::message_flags __flags, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, size_t)> __init{__token}; if (__buffer_empty(__buffers)) { auto __ex = net::get_associated_executor( __init.completion_handler, this->get_executor()); auto __a = get_associated_allocator( __init.completion_handler, std::allocator<void>()); __ex.post( [__h=std::move(__init.completion_handler)] () mutable { __h(error_code{}, 0); }, __a); return __init.result.get(); } this->get_executor().context().async_wait(this->native_handle(), socket_base::wait_read, [__h = std::move(__init.completion_handler), &__buffers, __flags = static_cast<int>(__flags), __fd = this->native_handle()] (error_code __ec) mutable { if (__ec) { __h(__ec); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::recvmsg(__fd, &__msg, __flags); if (__result == -1) { __ec.assign(errno, generic_category()); __result = 0; } else __ec.clear(); __h(__ec, __result); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } template<class _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers) { return send(__buffers, socket_base::message_flags(), __throw_on_error{"basic_stream_socket::send"}); } template<class _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers, error_code& __ec) { return send(__buffers, socket_base::message_flags(), __ec); } template<class _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers, socket_base::message_flags __flags) { return send(__buffers, socket_base::message_flags(), __throw_on_error{"basic_stream_socket::send"}); } template<class _ConstBufferSequence> size_t send(const _ConstBufferSequence& __buffers, socket_base::message_flags __flags, error_code& __ec) { if (__buffer_empty(__buffers)) { __ec.clear(); return 0; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::sendmsg(this->native_handle(), &__msg, static_cast<int>(__flags)); if (__result >= 0) { __ec.clear(); return __result; } __ec.assign(errno, generic_category()); #else __ec = std::make_error_code(errc::operation_not_supported); #endif return 0; } template<class _ConstBufferSequence, class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_send(const _ConstBufferSequence& __buffers, _CompletionToken&& __token) { return async_send(__buffers, socket_base::message_flags(), std::forward<_CompletionToken>(__token)); } template<class _ConstBufferSequence, class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_send(const _ConstBufferSequence& __buffers, socket_base::message_flags __flags, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, size_t)> __init{__token}; if (__buffer_empty(__buffers)) { auto __ex = net::get_associated_executor( __init.completion_handler, this->get_executor()); auto __a = get_associated_allocator( __init.completion_handler, std::allocator<void>()); __ex.post( [__h=std::move(__init.completion_handler)] () mutable { __h(error_code{}, 0); }, __a); return __init.result.get(); } this->get_executor().context().async_wait(this->native_handle(), socket_base::wait_write, [__h = std::move(__init.completion_handler), &__buffers, __flags = static_cast<int>(__flags), __fd = this->native_handle()] (error_code __ec) mutable { if (__ec) { __h(__ec); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socket_base::__msg_hdr __msg(__buffers); ssize_t __result = ::sendmsg(__fd, &__msg, __flags); if (__result == -1) { __ec.assign(errno, generic_category()); __result = 0; } else __ec.clear(); __h(__ec, __result); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } template<class _MutableBufferSequence> size_t read_some(const _MutableBufferSequence& __buffers) { return receive(__buffers, __throw_on_error{"basic_stream_socket::read_some"}); } template<class _MutableBufferSequence> size_t read_some(const _MutableBufferSequence& __buffers, error_code& __ec) { return receive(__buffers, __ec); } template<class _MutableBufferSequence, class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_read_some(const _MutableBufferSequence& __buffers, _CompletionToken&& __token) { return async_receive(__buffers, std::forward<_CompletionToken>(__token)); } template<class _ConstBufferSequence> size_t write_some(const _ConstBufferSequence& __buffers) { return send(__buffers, __throw_on_error{"basic_stream_socket:write_some"}); } template<class _ConstBufferSequence> size_t write_some(const _ConstBufferSequence& __buffers, error_code& __ec) { return send(__buffers, __ec); } template<class _ConstBufferSequence, class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, size_t)> async_write_some(const _ConstBufferSequence& __buffers, _CompletionToken&& __token) { return async_send(__buffers, std::forward<_CompletionToken>(__token)); } }; template<typename _AcceptableProtocol> class basic_socket_acceptor : public socket_base, private __basic_socket_impl<_AcceptableProtocol> { using __base = __basic_socket_impl<_AcceptableProtocol>; public: // types: typedef io_context::executor_type executor_type; typedef int native_handle_type; typedef _AcceptableProtocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; typedef typename protocol_type::socket socket_type; // construct / copy / destroy: explicit basic_socket_acceptor(io_context& __ctx) : __base(__ctx), _M_protocol(endpoint_type{}.protocol()) { } basic_socket_acceptor(io_context& __ctx, const protocol_type& __protocol) : __base(__ctx), _M_protocol(__protocol) { open(__protocol); } basic_socket_acceptor(io_context& __ctx, const endpoint_type& __endpoint, bool __reuse_addr = true) : basic_socket_acceptor(__ctx, __endpoint.protocol()) { if (__reuse_addr) set_option(reuse_address(true)); bind(__endpoint); listen(); } basic_socket_acceptor(io_context& __ctx, const protocol_type& __protocol, const native_handle_type& __native_acceptor) : basic_socket_acceptor(__ctx, __protocol) { assign(__protocol, __native_acceptor); } basic_socket_acceptor(const basic_socket_acceptor&) = delete; basic_socket_acceptor(basic_socket_acceptor&&) = default; template<typename _OtherProtocol, typename _Requires = _Require<is_convertible<_OtherProtocol, protocol_type>>> basic_socket_acceptor(basic_socket_acceptor<_OtherProtocol>&& __rhs) : __base(std::move(__rhs)) { } ~basic_socket_acceptor() = default; basic_socket_acceptor& operator=(const basic_socket_acceptor&) = delete; basic_socket_acceptor& operator=(basic_socket_acceptor&&) = default; template<class _OtherProtocol> enable_if_t<is_convertible<_OtherProtocol, protocol_type>::value, basic_socket_acceptor&> operator=(basic_socket_acceptor<_OtherProtocol>&& __rhs) { __base::operator=(std::move(__rhs)); return *this; } // basic_socket_acceptor operations: executor_type get_executor() noexcept { return __base::get_executor(); } native_handle_type native_handle() noexcept { return __base::native_handle(); } void open(const protocol_type& __protocol = protocol_type()) { open(__protocol, __throw_on_error{"basic_socket_acceptor::open"}); } void open(const protocol_type& __protocol, error_code& __ec) { __base::open(__protocol, __ec); } void assign(const protocol_type& __protocol, const native_handle_type& __native_acceptor) { assign(__protocol, __native_acceptor, __throw_on_error{"basic_socket_acceptor::assign"}); } void assign(const protocol_type& __protocol, const native_handle_type& __native_acceptor, error_code& __ec) { __base::assign(__protocol, __native_acceptor, __ec); } bool is_open() const noexcept { return __base::is_open(); } void close() { close(__throw_on_error{"basic_socket_acceptor::close"}); } void close(error_code& __ec) { __base::_close(__ec); } void cancel() { cancel(__throw_on_error{"basic_socket_acceptor::cancel"}); } void cancel(error_code& __ec) { __base::cancel(__ec); } template<typename _SettableSocketOption> void set_option(const _SettableSocketOption& __option) { set_option(__option, __throw_on_error{"basic_socket_acceptor::set_option"}); } template<typename _SettableSocketOption> void set_option(const _SettableSocketOption& __option, error_code& __ec) { __base::set_option(__option, __ec); } template<typename _GettableSocketOption> void get_option(_GettableSocketOption& __option) const { get_option(__option, __throw_on_error{"basic_socket_acceptor::get_option"}); } template<typename _GettableSocketOption> void get_option(_GettableSocketOption& __option, error_code& __ec) const { __base::get_option(__option, __ec); } template<typename _IoControlCommand> void io_control(_IoControlCommand& __command) { io_control(__command, __throw_on_error{"basic_socket_acceptor::io_control"}); } template<typename _IoControlCommand> void io_control(_IoControlCommand& __command, error_code& __ec) { __base::io_control(__command, __ec); } void non_blocking(bool __mode) { non_blocking(__mode, __throw_on_error{"basic_socket_acceptor::non_blocking"}); } void non_blocking(bool __mode, error_code& __ec) { __base::non_blocking(__mode, __ec); } bool non_blocking() const { return __base::non_blocking(); } void native_non_blocking(bool __mode) { native_non_blocking(__mode, __throw_on_error{ "basic_socket_acceptor::native_non_blocking"}); } void native_non_blocking(bool __mode, error_code& __ec) { __base::native_non_blocking(__mode, __ec); } bool native_non_blocking() const { return __base::native_non_blocking(); } void bind(const endpoint_type& __endpoint) { return bind(__endpoint, __throw_on_error{"basic_socket_acceptor::bind"}); } void bind(const endpoint_type& __endpoint, error_code& __ec) { __base::bind(__endpoint, __ec); } void listen(int __backlog = max_listen_connections) { return listen(__backlog, __throw_on_error{"basic_socket_acceptor::listen"}); } void listen(int __backlog, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (::listen(native_handle(), __backlog) == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(errc::operation_not_supported); #endif } endpoint_type local_endpoint() const { return local_endpoint( __throw_on_error{"basic_socket_acceptor::local_endpoint"}); } endpoint_type local_endpoint(error_code& __ec) const { return __base::local_endpoint(__ec); } void enable_connection_aborted(bool __mode) { __base::_M_bits.enable_connection_aborted = __mode; } bool enable_connection_aborted() const { return __base::_M_bits.enable_connection_aborted; } socket_type accept() { return accept(__throw_on_error{"basic_socket_acceptor::accept"}); } socket_type accept(error_code& __ec) { return accept(get_executor().context(), __ec); } socket_type accept(io_context& __ctx) { return accept(__ctx, __throw_on_error{"basic_socket_acceptor::accept"}); } socket_type accept(io_context& __ctx, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H do { int __h = ::accept(native_handle(), nullptr, 0); if (__h != -1) { __ec.clear(); return socket_type{__ctx, _M_protocol, __h}; } } while (errno == ECONNABORTED && enable_connection_aborted()); __ec.assign(errno, generic_category()); #else __ec = std::make_error_code(errc::operation_not_supported); #endif return socket_type{__ctx}; } template<class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, socket_type)> async_accept(_CompletionToken&& __token) { return async_accept(get_executor().context(), std::forward<_CompletionToken>(__token)); } template<class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, socket_type)> async_accept(io_context& __ctx, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, socket_type)> __init{__token}; __ctx.get_executor().context().async_wait(native_handle(), socket_base::wait_read, [__h = std::move(__init.completion_handler), __connabort = enable_connection_aborted(), __fd = native_handle(), __protocol = _M_protocol, &__ctx ] (error_code __ec) mutable { if (__ec) { __h(__ec, socket_type(__ctx)); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H do { int __newfd = ::accept(__fd, nullptr, 0); if (__newfd != -1) { __ec.clear(); __h(__ec, socket_type{__ctx, __protocol, __newfd}); return; } } while (errno == ECONNABORTED && __connabort); __ec.assign(errno, generic_category()); __h(__ec, socket_type(__ctx)); #else __h(std::make_error_code(errc::operation_not_supported), 0); #endif }); return __init.result.get(); } socket_type accept(endpoint_type& __endpoint) { return accept(get_executor().context(), __endpoint, __throw_on_error{"basic_socket_acceptor::accept"}); } socket_type accept(endpoint_type& __endpoint, error_code& __ec) { return accept(get_executor().context(), __endpoint, __ec); } socket_type accept(io_context& __ctx, endpoint_type& __endpoint) { return accept(__ctx, __endpoint, __throw_on_error{"basic_socket_acceptor::accept"}); } socket_type accept(io_context& __ctx, endpoint_type& __endpoint, error_code& __ec) { #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H do { socklen_t __len = __endpoint.capacity(); int __h = ::accept(native_handle(), (sockaddr*)__endpoint.data(), &__len); if (__h != -1) { __endpoint.resize(__len); return socket_type{__ctx, _M_protocol, __h}; } } while (errno == ECONNABORTED && enable_connection_aborted()); __ec.assign(errno, generic_category()); #else __ec = std::make_error_code(errc::operation_not_supported); #endif return socket_type{__ctx}; } template<class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, socket_type)> async_accept(endpoint_type& __endpoint, _CompletionToken&& __token) { return async_accept(get_executor().context(), __endpoint, std::forward<_CompletionToken>(__token)); } template<class _CompletionToken> __deduced_t<_CompletionToken, void(error_code, socket_type)> async_accept(io_context& __ctx, endpoint_type& __endpoint, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code, socket_type)> __init{__token}; __ctx.get_executor().context().async_wait(native_handle(), socket_base::wait_read, [__h = std::move(__init.completion_handler), __ep = std::move(__endpoint), __connabort = enable_connection_aborted(), __fd = native_handle(), &__ctx ] (error_code __ec) mutable { if (__ec) { __h(__ec, socket_type(__ctx)); return; } #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H do { socklen_t __len = __ep.capacity(); int __newfd = ::accept(__fd, __ep.data, &__len); if (__newfd != -1) { __ep.resize(__len); auto __protocol = __ep.protocol(); __ec.clear(); __h(__ec, socket_type{__ctx, __protocol, __newfd}); return; } } while (errno == ECONNABORTED && __connabort); __ec.assign(errno, generic_category()); #else __ec = std::make_error_code(errc::operation_not_supported); #endif __h(__ec, socket_type(__ctx)); }); return __init.result.get(); } void wait(wait_type __w) { wait(__w, __throw_on_error{"basic_socket_acceptor::wait"}); } void wait(wait_type __w, error_code& __ec) { #ifdef _GLIBCXX_HAVE_POLL_H ::pollfd __fds; __fds.fd = native_handle(); __fds.events = __w; // __w | POLLIN; if (::poll(&__fds, 1, -1) == -1) __ec.assign(errno, generic_category()); else __ec.clear(); #else __ec = std::make_error_code(errc::operation_not_supported); #endif } template<class _CompletionToken> __deduced_t<_CompletionToken, void(error_code)> async_wait(wait_type __w, _CompletionToken&& __token) { async_completion<_CompletionToken, void(error_code)> __init{__token}; get_executor().context().async_wait( native_handle(), static_cast<int>(__w), [__h = std::move(__init.completion_handler)] (error_code __ec) mutable { __h(__ec); }); return __init.result.get(); } private: protocol_type _M_protocol; }; /// @} /** @brief Socket streams * @{ */ template<typename _Protocol, typename _Clock, typename _WaitTraits> class basic_socket_streambuf : public basic_streambuf<char> { public: // types: typedef _Protocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; typedef _Clock clock_type; typedef typename clock_type::time_point time_point; typedef typename clock_type::duration duration; typedef _WaitTraits wait_traits_type; // construct / copy / destroy: basic_socket_streambuf() : _M_socket(_S_ctx()) { } explicit basic_socket_streambuf(basic_stream_socket<protocol_type> __s) : _M_socket(std::move(__s)) { } basic_socket_streambuf(const basic_socket_streambuf&) = delete; basic_socket_streambuf(basic_socket_streambuf&& __rhs); // TODO virtual ~basic_socket_streambuf(); // TODO basic_socket_streambuf& operator=(const basic_socket_streambuf&) = delete; basic_socket_streambuf& operator=(basic_socket_streambuf&& __rhs); // TODO // members: basic_socket_streambuf* connect(const endpoint_type& __e); // TODO template<typename... _Args> basic_socket_streambuf* connect(_Args&&... ); // TODO basic_socket_streambuf* close(); // TODO basic_socket<protocol_type>& socket() { return _M_socket; } error_code error() const { return _M_ec; } time_point expiry() const { return _M_expiry; } void expires_at(const time_point& __t) { _M_expiry = __t; } void expires_after(const duration& __d) { expires_at(clock_type::now() + __d); } protected: // overridden virtual functions: // TODO virtual int_type underflow() override; virtual int_type pbackfail(int_type __c = traits_type::eof()) override; virtual int_type overflow(int_type __c = traits_type::eof()) override; virtual int sync() override; virtual streambuf* setbuf(char_type* __s, streamsize __n) override; private: static io_context& _S_ctx() { static io_context __ctx; return __ctx; } basic_stream_socket<protocol_type> _M_socket; error_code _M_ec; time_point _M_expiry{ time_point::max() }; }; template<typename _Protocol, class _Clock, typename _WaitTraits> class basic_socket_iostream : public basic_iostream<char> { using __streambuf_type = basic_socket_streambuf<_Protocol, _Clock, _WaitTraits>; public: // types: typedef _Protocol protocol_type; typedef typename protocol_type::endpoint endpoint_type; typedef _Clock clock_type; typedef typename clock_type::time_point time_point; typedef typename clock_type::duration duration; typedef _WaitTraits wait_traits_type; // construct / copy / destroy: // TODO base-from-member ? basic_socket_iostream() : basic_iostream(nullptr), _M_sb() { this->init(std::addressof(_M_sb)); this->setf(std::ios::unitbuf); } explicit basic_socket_iostream(basic_stream_socket<protocol_type> __s) : basic_iostream(nullptr), _M_sb(std::move(__s)) { this->init(std::addressof(_M_sb)); this->setf(std::ios::unitbuf); } basic_socket_iostream(const basic_socket_iostream&) = delete; basic_socket_iostream(basic_socket_iostream&& __rhs) : basic_iostream(nullptr), _M_sb(std::move(__rhs._M_sb)) // XXX ??? ^^^^^^^ { // XXX ??? this->init(std::addressof(_M_sb)); this->set_rbduf(std::addressof(_M_sb)); } template<typename... _Args> explicit basic_socket_iostream(_Args&&... __args) : basic_iostream(nullptr), _M_sb() { this->init(std::addressof(_M_sb)); this->setf(std::ios::unitbuf); connect(forward<_Args>(__args)...); } basic_socket_iostream& operator=(const basic_socket_iostream&) = delete; basic_socket_iostream& operator=(basic_socket_iostream&& __rhs); // TODO // members: template<typename... _Args> void connect(_Args&&... __args) { if (rdbuf()->connect(forward<_Args>(__args)...) == nullptr) this->setstate(failbit); } void close() { if (rdbuf()->close() == nullptr) this->setstate(failbit); } basic_socket_streambuf<protocol_type, clock_type, wait_traits_type>* rdbuf() const { return const_cast<__streambuf_type*>(std::addressof(_M_sb)); } basic_socket<protocol_type>& socket() { return rdbuf()->socket(); } error_code error() const { return rdbuf()->error(); } time_point expiry() const { return rdbuf()->expiry(); } void expires_at(const time_point& __t) { rdbuf()->expires_at(__t); } void expires_after(const duration& __d) { rdbuf()->expires_after(__d); } private: __streambuf_type _M_sb; }; /// @} /** @brief synchronous connect operations * @{ */ template<typename _Protocol, typename _EndpointSequence, typename _ConnectCondition> inline typename _Protocol::endpoint connect(basic_socket<_Protocol>& __s, const _EndpointSequence& __endpoints, _ConnectCondition __c, error_code& __ec) { __ec.clear(); bool __found = false; for (auto& __ep : __endpoints) { if (__c(__ec, __ep)) { __found = true; __s.close(__ec); if (!__ec) __s.open(__ep.protocol(), __ec); if (!__ec) __s.connect(__ep, __ec); if (!__ec) return __ep; } } if (!__found) __ec = socket_errc::not_found; return typename _Protocol::endpoint{}; } template<typename _Protocol, typename _InputIterator, typename _ConnectCondition> inline _InputIterator connect(basic_socket<_Protocol>& __s, _InputIterator __first, _InputIterator __last, _ConnectCondition __c, error_code& __ec) { __ec.clear(); bool __found = false; for (auto __i = __first; __i != __last; ++__i) { if (__c(__ec, *__i)) { __found = true; __s.close(__ec); if (!__ec) __s.open(typename _Protocol::endpoint(*__i).protocol(), __ec); if (!__ec) __s.connect(*__i, __ec); if (!__ec) return __i; } } if (!__found) __ec = socket_errc::not_found; return __last; } template<typename _Protocol, typename _EndpointSequence, typename _ConnectCondition> inline typename _Protocol::endpoint connect(basic_socket<_Protocol>& __s, const _EndpointSequence& __endpoints, _ConnectCondition __c) { return net::connect(__s, __endpoints, __c, __throw_on_error{"connect"}); } template<typename _Protocol, typename _InputIterator, typename _ConnectCondition> inline _InputIterator connect(basic_socket<_Protocol>& __s, _InputIterator __first, _InputIterator __last, _ConnectCondition __c) { return net::connect(__s, __first, __last, __c, __throw_on_error{"connect"}); } template<typename _Protocol, typename _EndpointSequence> inline typename _Protocol::endpoint connect(basic_socket<_Protocol>& __s, const _EndpointSequence& __endpoints) { return net::connect(__s, __endpoints, [](auto, auto){ return true; }, __throw_on_error{"connect"}); } template<typename _Protocol, typename _EndpointSequence> inline typename _Protocol::endpoint connect(basic_socket<_Protocol>& __s, const _EndpointSequence& __endpoints, error_code& __ec) { return net::connect(__s, __endpoints, [](auto, auto){ return true; }, __ec); } template<typename _Protocol, typename _InputIterator> inline _InputIterator connect(basic_socket<_Protocol>& __s, _InputIterator __first, _InputIterator __last) { return net::connect(__s, __first, __last, [](auto, auto){ return true; }, __throw_on_error{"connect"}); } template<typename _Protocol, typename _InputIterator> inline _InputIterator connect(basic_socket<_Protocol>& __s, _InputIterator __first, _InputIterator __last, error_code& __ec) { return net::connect(__s, __first, __last, [](auto, auto){ return true; }, __ec); } /// @} /** @brief asynchronous connect operations * @{ */ template<typename _Protocol, typename _EndpointSequence, typename _ConnectCondition, typename _CompletionToken> inline __deduced_t<_CompletionToken, void(error_code, typename _Protocol::endpoint)> async_connect(basic_socket<_Protocol>& __s, const _EndpointSequence& __endpoints, _ConnectCondition __c, _CompletionToken&& __token); // TODO template<typename _Protocol, typename _EndpointSequence, typename _CompletionToken> inline __deduced_t<_CompletionToken, void(error_code, typename _Protocol::endpoint)> async_connect(basic_socket<_Protocol>& __s, const _EndpointSequence& __endpoints, _CompletionToken&& __token) { return net::async_connect(__s, __endpoints, [](auto, auto){ return true; }, forward<_CompletionToken>(__token)); } template<typename _Protocol, typename _InputIterator, typename _ConnectCondition, typename _CompletionToken> inline __deduced_t<_CompletionToken, void(error_code, _InputIterator)> async_connect(basic_socket<_Protocol>& __s, _InputIterator __first, _InputIterator __last, _ConnectCondition __c, _CompletionToken&& __token); // TODO template<typename _Protocol, typename _InputIterator, typename _CompletionToken> inline __deduced_t<_CompletionToken, void(error_code, _InputIterator)> async_connect(basic_socket<_Protocol>& __s, _InputIterator __first, _InputIterator __last, _CompletionToken&& __token) { return net::async_connect(__s, __first, __last, [](auto, auto){ return true; }, forward<_CompletionToken>(__token)); } /// @} #endif // _GLIBCXX_HAVE_UNISTD_H /// @} } // namespace v1 } // namespace net } // namespace experimental _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++14 #endif // _GLIBCXX_EXPERIMENTAL_SOCKET
Close