From fd3767c4d17986eaa5f24cde53b8c9d0ca3f87ec Mon Sep 17 00:00:00 2001 From: Martin Hartmond Date: Fri, 28 May 2021 14:12:16 +0200 Subject: [PATCH] added asio unix-socket configuration --- websocketpp/config/asio_unix_no_tls.hpp | 73 ++++++++++++++++++++ websocketpp/transport/asio/endpoint.hpp | 56 +++++++++------ websocketpp/transport/asio/security/none.hpp | 72 ++++++++++++------- websocketpp/transport/asio/security/tls.hpp | 1 + 4 files changed, 155 insertions(+), 47 deletions(-) create mode 100644 websocketpp/config/asio_unix_no_tls.hpp diff --git a/websocketpp/config/asio_unix_no_tls.hpp b/websocketpp/config/asio_unix_no_tls.hpp new file mode 100644 index 000000000..1c7280eb3 --- /dev/null +++ b/websocketpp/config/asio_unix_no_tls.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_CONFIG_ASIO_UNIX_HPP +#define WEBSOCKETPP_CONFIG_ASIO_UNIX_HPP + +#include +#include + +namespace websocketpp { +namespace config { + +/// Server config with asio transport and TLS disabled +struct asio_unix : public core { + typedef asio_unix type; + typedef core base; + + typedef base::concurrency_type concurrency_type; + + typedef base::request_type request_type; + typedef base::response_type response_type; + + typedef base::message_type message_type; + typedef base::con_msg_manager_type con_msg_manager_type; + typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef base::alog_type alog_type; + typedef base::elog_type elog_type; + + typedef base::rng_type rng_type; + + struct transport_config : public base::transport_config { + typedef type::concurrency_type concurrency_type; + typedef type::alog_type alog_type; + typedef type::elog_type elog_type; + typedef type::request_type request_type; + typedef type::response_type response_type; + typedef websocketpp::transport::asio::basic_socket::generic::endpoint + socket_type; + }; + + typedef websocketpp::transport::asio::endpoint + transport_type; +}; + +} // namespace config +} // namespace websocketpp + +#endif // WEBSOCKETPP_CONFIG_ASIO_UNIX_HPP diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index 94509adb3..ae22c2829 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -79,8 +79,11 @@ class endpoint : public config::socket_type { /// Type of a pointer to the ASIO io_service being used typedef lib::asio::io_service * io_service_ptr; + + typedef typename config::socket_type::socket_con_type::socket_suite socket_suite; + /// Type of a shared pointer to the acceptor being used - typedef lib::shared_ptr acceptor_ptr; + typedef lib::shared_ptr acceptor_ptr; /// Type of a shared pointer to the resolver being used typedef lib::shared_ptr resolver_ptr; /// Type of timer handle @@ -161,7 +164,7 @@ class endpoint : public config::socket_type { rhs.m_acceptor = NULL; rhs.m_listen_backlog = lib::asio::socket_base::max_connections; rhs.m_state = UNINITIALIZED; - + // TODO: this needs to be updated } return *this; @@ -195,7 +198,7 @@ class endpoint : public config::socket_type { m_io_service = ptr; m_external_io_service = true; - m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service)); + m_acceptor.reset(new typename socket_suite::acceptor(*m_io_service)); m_state = READY; ec = lib::error_code(); @@ -225,7 +228,7 @@ class endpoint : public config::socket_type { * @param ec Set to indicate what error occurred, if any. */ void init_asio(lib::error_code & ec) { - // Use a smart pointer until the call is successful and ownership has + // Use a smart pointer until the call is successful and ownership has // successfully been taken. Use unique_ptr when available. // TODO: remove the use of auto_ptr when C++98/03 support is no longer // necessary. @@ -247,7 +250,7 @@ class endpoint : public config::socket_type { * @see init_asio(io_service_ptr ptr) */ void init_asio() { - // Use a smart pointer until the call is successful and ownership has + // Use a smart pointer until the call is successful and ownership has // successfully been taken. Use unique_ptr when available. // TODO: remove the use of auto_ptr when C++98/03 support is no longer // necessary. @@ -378,7 +381,7 @@ class endpoint : public config::socket_type { lib::asio::io_service & get_io_service() { return *m_io_service; } - + /// Get local TCP endpoint /** * Extracts the local endpoint from the acceptor. This represents the @@ -386,18 +389,18 @@ class endpoint : public config::socket_type { * * Sets a bad_descriptor error if the acceptor is not currently listening * or otherwise unavailable. - * + * * @since 0.7.0 * * @param ec Set to indicate what error occurred, if any. * @return The local endpoint */ - lib::asio::ip::tcp::endpoint get_local_endpoint(lib::asio::error_code & ec) { + typename socket_suite::endpoint get_local_endpoint(lib::asio::error_code & ec) { if (m_acceptor) { return m_acceptor->local_endpoint(ec); } else { ec = lib::asio::error::make_error_code(lib::asio::error::bad_descriptor); - return lib::asio::ip::tcp::endpoint(); + return socket_suite::endpoint(); } } @@ -409,7 +412,7 @@ class endpoint : public config::socket_type { * @param ep An endpoint to read settings from * @param ec Set to indicate what error occurred, if any. */ - void listen(lib::asio::ip::tcp::endpoint const & ep, lib::error_code & ec) + void listen(typename socket_suite::endpoint const & ep, lib::error_code & ec) { if (m_state != READY) { m_elog->write(log::elevel::library, @@ -425,10 +428,10 @@ class endpoint : public config::socket_type { m_acceptor->open(ep.protocol(),bec); if (bec) {ec = clean_up_listen_after_error(bec);return;} - + m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec); if (bec) {ec = clean_up_listen_after_error(bec);return;} - + // if a TCP pre-bind handler is present, run it if (m_tcp_pre_bind_handler) { ec = m_tcp_pre_bind_handler(m_acceptor); @@ -437,13 +440,13 @@ class endpoint : public config::socket_type { return; } } - + m_acceptor->bind(ep,bec); if (bec) {ec = clean_up_listen_after_error(bec);return;} - + m_acceptor->listen(m_listen_backlog,bec); if (bec) {ec = clean_up_listen_after_error(bec);return;} - + // Success m_state = LISTENING; ec = lib::error_code(); @@ -457,7 +460,7 @@ class endpoint : public config::socket_type { * * @param ep An endpoint to read settings from */ - void listen(lib::asio::ip::tcp::endpoint const & ep) { + void listen(typename socket_suite::endpoint const & ep) { lib::error_code ec; listen(ep,ec); if (ec) { throw exception(ec); } @@ -498,11 +501,20 @@ class endpoint : public config::socket_type { * @param internet_protocol The internet protocol to use. * @param port The port to listen on. */ - template - void listen(InternetProtocol const & internet_protocol, uint16_t port) - { - lib::asio::ip::tcp::endpoint ep(internet_protocol, port); + template + typename std::enable_if::value, void>::type + listen(InternetProtocol const &internet_protocol, uint16_t port) { + typename lib::asio::ip::tcp::endpoint ep(internet_protocol, port); + listen(ep); + } + + template + typename std::enable_if::value, void>::type + listen(const char* path) { + ::unlink(path); + lib::asio::local::stream_protocol::endpoint ep(path); listen(ep); + chmod(path, S_IRWXG ^ S_IRWXU ^ S_IRWXO); } /// Set up endpoint for listening on a port (exception free) @@ -553,7 +565,9 @@ class endpoint : public config::socket_type { * descriptive name or a numeric string corresponding to a port number. * @param ec Set to indicate what error occurred, if any. */ - void listen(std::string const & host, std::string const & service, + template + typename std::enable_if::value, void>::type + listen(std::string const & host, std::string const & service, lib::error_code & ec) { using lib::asio::ip::tcp; diff --git a/websocketpp/transport/asio/security/none.hpp b/websocketpp/transport/asio/security/none.hpp index 6c7d35241..17374a05b 100644 --- a/websocketpp/transport/asio/security/none.hpp +++ b/websocketpp/transport/asio/security/none.hpp @@ -46,19 +46,18 @@ namespace asio { /// socket namespace basic_socket { -/// The signature of the socket init handler for this socket policy -typedef lib::function - socket_init_handler; +namespace generic { /// Basic Asio connection socket component /** - * transport::asio::basic_socket::connection implements a connection socket - * component using Asio ip::tcp::socket. + * transport::asio::basic_socket::generic::connection implements a connection socket + * component using a specified Asio socket */ -class connection : public lib::enable_shared_from_this { +template +class connection : public lib::enable_shared_from_this> { public: /// Type of this connection socket component - typedef connection type; + typedef connection type; /// Type of a shared pointer to this connection socket component typedef lib::shared_ptr ptr; @@ -67,9 +66,12 @@ class connection : public lib::enable_shared_from_this { /// Type of a pointer to the Asio io_service strand being used typedef lib::shared_ptr strand_ptr; /// Type of the ASIO socket being used - typedef lib::asio::ip::tcp::socket socket_type; + typedef SocketSuite_T socket_suite; + typedef typename SocketSuite_T::socket socket_type; /// Type of a shared pointer to the socket being used. typedef lib::shared_ptr socket_ptr; + /// The signature of the socket init handler for this socket policy + typedef lib::function socket_init_handler; explicit connection() : m_state(UNINITIALIZED) { //std::cout << "transport::asio::basic_socket::connection constructor" @@ -78,7 +80,7 @@ class connection : public lib::enable_shared_from_this { /// Get a shared pointer to this component ptr get_shared() { - return shared_from_this(); + return lib::enable_shared_from_this>::shared_from_this(); } /// Check whether or not this connection is secure @@ -105,7 +107,7 @@ class connection : public lib::enable_shared_from_this { /** * This is used internally. It can also be used to set socket options, etc */ - lib::asio::ip::tcp::socket & get_socket() { + socket_type & get_socket() { return *m_socket; } @@ -113,7 +115,7 @@ class connection : public lib::enable_shared_from_this { /** * This is used internally. */ - lib::asio::ip::tcp::socket & get_next_layer() { + socket_type & get_next_layer() { return *m_socket; } @@ -121,7 +123,7 @@ class connection : public lib::enable_shared_from_this { /** * This is used internally. It can also be used to set socket options, etc */ - lib::asio::ip::tcp::socket & get_raw_socket() { + socket_type & get_raw_socket() { return *m_socket; } @@ -139,7 +141,7 @@ class connection : public lib::enable_shared_from_this { std::stringstream s; lib::asio::error_code aec; - lib::asio::ip::tcp::endpoint ep = m_socket->remote_endpoint(aec); + auto ep = m_socket->remote_endpoint(aec); if (aec) { ec = error::make_error_code(error::pass_through); @@ -168,7 +170,7 @@ class connection : public lib::enable_shared_from_this { return socket::make_error_code(socket::error::invalid_state); } - m_socket.reset(new lib::asio::ip::tcp::socket(*service)); + m_socket.reset(new socket_type(*service)); if (m_socket_init_handler) { m_socket_init_handler(m_hdl, *m_socket); @@ -252,7 +254,7 @@ class connection : public lib::enable_shared_from_this { void async_shutdown(socket::shutdown_handler h) { lib::asio::error_code ec; - m_socket->shutdown(lib::asio::ip::tcp::socket::shutdown_both, ec); + m_socket->shutdown(socket_type::shutdown_both, ec); h(ec); } @@ -263,14 +265,14 @@ class connection : public lib::enable_shared_from_this { public: /// Translate any security policy specific information about an error code /** - * Translate_ec takes an Asio error code and attempts to convert its value + * Translate_ec takes an Asio error code and attempts to convert its value * to an appropriate websocketpp error code. In the case that the Asio and * Websocketpp error types are the same (such as using boost::asio and * boost::system_error or using standalone asio and std::system_error the * code will be passed through natively. * * In the case of a mismatch (boost::asio with std::system_error) a - * translated code will be returned. The plain socket policy does not have + * translated code will be returned. The plain socket policy does not have * any additional information so all such errors will be reported as the * generic transport pass_through error. * @@ -287,7 +289,7 @@ class connection : public lib::enable_shared_from_this { } static - /// Overload of translate_ec to catch cases where lib::error_code is the + /// Overload of translate_ec to catch cases where lib::error_code is the /// same type as lib::asio::error_code lib::error_code translate_ec(lib::error_code ec) { // We don't know any more information about this error, but the error is @@ -310,20 +312,17 @@ class connection : public lib::enable_shared_from_this { }; /// Basic ASIO endpoint socket component -/** - * transport::asio::basic_socket::endpoint implements an endpoint socket - * component that uses Boost ASIO's ip::tcp::socket. - */ -class endpoint { +template class endpoint { public: /// The type of this endpoint socket component - typedef endpoint type; + typedef endpoint type; /// The type of the corresponding connection socket component - typedef connection socket_con_type; + typedef connection socket_con_type; /// The type of a shared pointer to the corresponding connection socket /// component. - typedef socket_con_type::ptr socket_con_ptr; + typedef typename socket_con_type::ptr socket_con_ptr; + typedef typename socket_con_type::socket_init_handler socket_init_handler; explicit endpoint() {} @@ -364,6 +363,27 @@ class endpoint { socket_init_handler m_socket_init_handler; }; +} // namespace generic + + +/** + * transport::asio::basic_socket::connection implements a connection socket + * component using Asio ip::tcp::socket. + * + * To use other socket suits specialize the template + * transport::asio::basic_socket::generic::connection + */ +class connection : public generic::connection {}; + +/** + * transport::asio::basic_socket::endpoint implements an endpoint socket + * component that uses Boost ASIO's ip::tcp::socket. + * + * To use other socket suits specialize the template + * transport::asio::basic_socket::generic::endpoint + */ +class endpoint : public generic::endpoint {}; + } // namespace basic_socket } // namespace asio } // namespace transport diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp index 04ac37903..d0f7d608b 100644 --- a/websocketpp/transport/asio/security/tls.hpp +++ b/websocketpp/transport/asio/security/tls.hpp @@ -69,6 +69,7 @@ class connection : public lib::enable_shared_from_this { /// Type of the ASIO socket being used typedef lib::asio::ssl::stream socket_type; + typedef lib::asio::ip::tcp socket_family; /// Type of a shared pointer to the ASIO socket being used typedef lib::shared_ptr socket_ptr; /// Type of a pointer to the ASIO io_service being used