From ae854ca778dd80a9d565a090b8823d5ebb3cd538 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Tue, 29 Nov 2011 18:01:39 -0600 Subject: [PATCH] updates socket policies to expose handler interfaces, moves TLS context into connection --- src/sockets/plain.hpp | 5 ++++ src/sockets/ssl.hpp | 65 ++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/sockets/plain.hpp b/src/sockets/plain.hpp index 846db38185..6c0782c78b 100644 --- a/src/sockets/plain.hpp +++ b/src/sockets/plain.hpp @@ -49,6 +49,9 @@ public: return false; } + // plain sockets do not add anything to the handler interface + class handler_interface {}; + // Connection specific details template class connection { @@ -64,6 +67,8 @@ public: protected: connection(plain& e) : m_socket(e.get_io_service()) {} + void init() {} + void async_init(socket_init_callback callback) { // TODO: should this use post()? callback(boost::system::error_code()); diff --git a/src/sockets/ssl.hpp b/src/sockets/ssl.hpp index 8b69e4b007..700c93f862 100644 --- a/src/sockets/ssl.hpp +++ b/src/sockets/ssl.hpp @@ -44,21 +44,13 @@ class ssl { public: typedef ssl type; typedef boost::asio::ssl::stream ssl_socket; - - std::string get_password() const { - return "test"; - } + typedef boost::shared_ptr ssl_socket_ptr; // should be private friended boost::asio::io_service& get_io_service() { return m_io_service; } - // should be private friended - boost::asio::ssl::context& get_context() { - return m_context; - } - // should be private friended? ssl_socket::handshake_type get_handshake_type() { if (static_cast< endpoint_type* >(this)->is_server()) { @@ -72,23 +64,38 @@ public: return true; } + // TLS policy adds the on_tls_init method to the handler to allow the user + // to set up their asio TLS context. + class handler_interface { + public: + virtual boost::shared_ptr on_tls_init() = 0; + }; + // Connection specific details template class connection { public: // should these two be public or protected. If protected, how? ssl_socket::lowest_layer_type& get_raw_socket() { - return m_socket.lowest_layer(); + return m_socket_ptr->lowest_layer(); } ssl_socket& get_socket() { - return m_socket; + return *m_socket_ptr; } protected: - connection(ssl& e) : m_socket(e.get_io_service(),e.get_context()),m_endpoint(e) {} + connection(ssl& e) + : m_endpoint(e), + m_connection(static_cast< connection_type& >(*this)) {} - void async_init(boost::function callback) { - m_socket.async_handshake( + void init() { + m_context_ptr = m_connection.get_handler()->on_tls_init(); + m_socket_ptr = ssl_socket_ptr(new ssl_socket(m_endpoint.get_io_service(),*m_context_ptr)); + } + + void async_init(boost::function callback) + { + m_socket_ptr->async_handshake( m_endpoint.get_handshake_type(), boost::bind( &connection::handle_init, @@ -111,7 +118,13 @@ public: bool shutdown() { boost::system::error_code ignored_ec; - m_socket.shutdown(ignored_ec); + + // TODO: this call blocks, sometimes for a long period of time. + // need to figure out what is going on here and how to calculate + // if the socket was already closed by this point. + // Until this is fixed, dropped_by_me for TLS connections will be + // inaccurate. + //m_socket_ptr->shutdown(ignored_ec); if (ignored_ec) { return false; @@ -120,27 +133,15 @@ public: } } private: - ssl_socket m_socket; - ssl& m_endpoint; + boost::shared_ptr m_context_ptr; + ssl_socket_ptr m_socket_ptr; + ssl& m_endpoint; + connection_type& m_connection; }; protected: - ssl (boost::asio::io_service& m) : m_io_service(m),m_context(boost::asio::ssl::context::sslv23) { - try { - // this should all be in separate init functions - m_context.set_options(boost::asio::ssl::context::default_workarounds | - boost::asio::ssl::context::no_sslv2 | - boost::asio::ssl::context::single_dh_use); - m_context.set_password_callback(boost::bind(&type::get_password, this)); - m_context.use_certificate_chain_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem"); - m_context.use_private_key_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem); - m_context.use_tmp_dh_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/dh512.pem"); - } catch (std::exception& e) { - std::cout << e.what() << std::endl; - } - } + ssl (boost::asio::io_service& m) : m_io_service(m) {} private: boost::asio::io_service& m_io_service; - boost::asio::ssl::context m_context; ssl_socket::handshake_type m_handshake_type; };