mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
Updates asio socket components to new styles
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2013, 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:
|
||||
@@ -25,8 +25,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_TRANSPORT_SECURITY_BASE_HPP
|
||||
#define WEBSOCKETPP_TRANSPORT_SECURITY_BASE_HPP
|
||||
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
|
||||
#define WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
|
||||
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
@@ -41,10 +41,11 @@
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
namespace security {
|
||||
namespace asio {
|
||||
namespace socket {
|
||||
|
||||
/**
|
||||
* The transport::security::* classes are a set of security/socket related
|
||||
* The transport::asio::socket::* classes are a set of security/socket related
|
||||
* policies and support code for the ASIO transport types.
|
||||
*/
|
||||
|
||||
@@ -53,7 +54,11 @@ namespace error {
|
||||
/// Catch-all error for security policy errors that don't fit in other
|
||||
/// categories
|
||||
security = 1,
|
||||
|
||||
|
||||
/// Catch-all error for socket component errors that don't fit in other
|
||||
/// categories
|
||||
socket,
|
||||
|
||||
/// A function was called in a state that it was illegal to do so.
|
||||
invalid_state,
|
||||
|
||||
@@ -65,20 +70,25 @@ namespace error {
|
||||
tls_handshake_timeout,
|
||||
|
||||
/// pass_through from underlying library
|
||||
pass_through
|
||||
pass_through,
|
||||
|
||||
/// Required tls_init handler not present
|
||||
missing_tls_init_handler
|
||||
};
|
||||
} // namespace error
|
||||
|
||||
class security_category : public lib::error_category {
|
||||
class socket_category : public lib::error_category {
|
||||
public:
|
||||
const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
|
||||
return "websocketpp.transport.asio.security";
|
||||
return "websocketpp.transport.asio.socket";
|
||||
}
|
||||
|
||||
std::string message(int value) const {
|
||||
switch(value) {
|
||||
case error::security:
|
||||
return "Security policy error";
|
||||
case error::socket:
|
||||
return "Socket component error";
|
||||
case error::invalid_state:
|
||||
return "Invalid state";
|
||||
case error::invalid_tls_context:
|
||||
@@ -87,27 +97,28 @@ public:
|
||||
return "TLS handshake timed out";
|
||||
case error::pass_through:
|
||||
return "Pass through from underlying library";
|
||||
case error::missing_tls_init_handler:
|
||||
return "Required tls_init handler not present.";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const lib::error_category& get_security_category() {
|
||||
static security_category instance;
|
||||
const lib::error_category& get_socket_category() {
|
||||
static socket_category instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
//static const security_category error_category;
|
||||
|
||||
lib::error_code make_error(error::value e) {
|
||||
return lib::error_code(static_cast<int>(e), get_security_category());
|
||||
return lib::error_code(static_cast<int>(e), get_socket_category());
|
||||
}
|
||||
|
||||
typedef lib::function<void(const lib::error_code&)> init_handler;
|
||||
|
||||
} // namespace security
|
||||
} // namespace socket
|
||||
} // namespace asio
|
||||
} // namespace transport
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_TRANSPORT_SECURITY_BASE_HPP
|
||||
#endif // WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2013, 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:
|
||||
@@ -37,13 +37,30 @@
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
namespace security {
|
||||
namespace asio {
|
||||
namespace basic_socket {
|
||||
|
||||
class none {
|
||||
typedef lib::function<void(connection_hdl,boost::asio::ip::tcp::socket&)>
|
||||
socket_init_handler;
|
||||
|
||||
/// Basic Boost ASIO connection socket component
|
||||
/**
|
||||
* transport::asio::basic_socket::connection impliments a connection socket
|
||||
* component using Boost ASIO ip::tcp::socket.
|
||||
*/
|
||||
class connection {
|
||||
public:
|
||||
typedef lib::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
|
||||
/// Type of this connection socket component
|
||||
typedef connection type;
|
||||
/// Type of a shared pointer to this connection socket component
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
|
||||
/// Type of a pointer to the ASIO io_service being used
|
||||
typedef boost::asio::io_service* io_service_ptr;
|
||||
/// Type of a shared pointer to the socket being used.
|
||||
typedef lib::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
|
||||
|
||||
// TODO: clean up these types
|
||||
class handler_interface {
|
||||
public:
|
||||
virtual void on_socket_init(boost::asio::ip::tcp::socket& socket) {};
|
||||
@@ -51,15 +68,31 @@ public:
|
||||
|
||||
typedef lib::shared_ptr<handler_interface> handler_ptr;
|
||||
|
||||
explicit none() : m_state(UNINITIALIZED)
|
||||
{
|
||||
std::cout << "transport::security::none constructor" << std::endl;
|
||||
explicit connection() : m_state(UNINITIALIZED) {
|
||||
std::cout << "transport::asio::basic_socket::connection constructor"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/// Check whether or not this connection is secure
|
||||
/**
|
||||
* @return Wether or not this connection is secure
|
||||
*/
|
||||
bool is_secure() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Set the socket initialization handler
|
||||
/**
|
||||
* The socket initialization handler is called after the socket object is
|
||||
* created but before it is used. This gives the application a chance to
|
||||
* set any ASIO socket options it needs.
|
||||
*
|
||||
* @param h The new socket_init_handler
|
||||
*/
|
||||
void set_socket_init_handler(socket_init_handler h) {
|
||||
m_socket_init_handler = h;
|
||||
}
|
||||
|
||||
/// Retrieve a pointer to the underlying socket
|
||||
/**
|
||||
* This is used internally. It can also be used to set socket options, etc
|
||||
@@ -87,7 +120,7 @@ protected:
|
||||
*/
|
||||
lib::error_code init_asio (io_service_ptr service, bool is_server) {
|
||||
if (m_state != UNINITIALIZED) {
|
||||
return make_error(error::invalid_state);
|
||||
return socket::make_error(socket::error::invalid_state);
|
||||
}
|
||||
|
||||
m_socket.reset(new boost::asio::ip::tcp::socket(*service));
|
||||
@@ -100,11 +133,13 @@ protected:
|
||||
/// Initialize security policy for reading
|
||||
void init(init_handler callback) {
|
||||
if (m_state != READY) {
|
||||
callback(make_error(error::invalid_state));
|
||||
callback(socket::make_error(socket::error::invalid_state));
|
||||
return;
|
||||
}
|
||||
|
||||
m_handler->on_socket_init(*m_socket);
|
||||
if (m_socket_init_handler) {
|
||||
m_socket_init_handler(m_hdl,*m_socket);
|
||||
}
|
||||
|
||||
m_state = READING;
|
||||
|
||||
@@ -114,6 +149,17 @@ protected:
|
||||
void set_handler(handler_ptr new_handler) {
|
||||
m_handler = new_handler;
|
||||
}
|
||||
|
||||
/// Sets the connection handle
|
||||
/**
|
||||
* The connection handle is passed to any handlers to identify the
|
||||
* connection
|
||||
*
|
||||
* @param hdl The new handle
|
||||
*/
|
||||
void set_handle(connection_hdl hdl) {
|
||||
m_hdl = hdl;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
boost::system::error_code ec;
|
||||
@@ -128,12 +174,70 @@ private:
|
||||
READING = 2
|
||||
};
|
||||
|
||||
socket_ptr m_socket;
|
||||
state m_state;
|
||||
handler_ptr m_handler;
|
||||
socket_ptr m_socket;
|
||||
state m_state;
|
||||
handler_ptr m_handler;
|
||||
|
||||
connection_hdl m_hdl;
|
||||
socket_init_handler m_socket_init_handler;
|
||||
};
|
||||
|
||||
} // namespace security
|
||||
/// Basic ASIO endpoint socket component
|
||||
/**
|
||||
* transport::asio::basic_socket::endpoint impliments an endpoint socket
|
||||
* component that uses Boost ASIO's ip::tcp::socket.
|
||||
*/
|
||||
class endpoint {
|
||||
public:
|
||||
/// The type of this endpoint socket component
|
||||
typedef endpoint type;
|
||||
|
||||
/// The type of the corresponding connection socket component
|
||||
typedef connection socket_con_type;
|
||||
/// The type of a shared pointer to the corresponding connection socket
|
||||
/// component.
|
||||
typedef typename socket_con_type::ptr socket_con_ptr;
|
||||
|
||||
explicit endpoint() {
|
||||
std::cout << "transport::asio::basic_socket::endpoint constructor"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/// Checks whether the endpoint creates secure connections
|
||||
/**
|
||||
* @return Wether or not the endpoint creates secure connections
|
||||
*/
|
||||
bool is_secure() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Set socket init handler
|
||||
/**
|
||||
* The socket init handler is called after a connection's socket is created
|
||||
* but before it is used. This gives the end application an opportunity to
|
||||
* set asio socket specific parameters.
|
||||
*
|
||||
* @param h The new socket_init_handler
|
||||
*/
|
||||
void set_socket_init_handler(socket_init_handler h) {
|
||||
m_socket_init_handler = h;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Initialize a connection
|
||||
/**
|
||||
* Called by the transport after a new connection is created to initialize
|
||||
* the socket component of the connection.
|
||||
*/
|
||||
void init(socket_con_ptr scon) {
|
||||
scon->set_socket_init_handler(m_socket_init_handler);
|
||||
}
|
||||
private:
|
||||
socket_init_handler m_socket_init_handler;
|
||||
};
|
||||
|
||||
} // namespace basic_socket
|
||||
} // namespace asio
|
||||
} // namespace transport
|
||||
} // namespace websocketpp
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#define WEBSOCKETPP_TRANSPORT_SECURITY_TLS_HPP
|
||||
|
||||
#include <websocketpp/transport/asio/security/base.hpp>
|
||||
#include <websocketpp/common/connection_hdl.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
@@ -39,16 +42,35 @@
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
namespace security {
|
||||
namespace asio {
|
||||
namespace tls_socket {
|
||||
|
||||
class tls {
|
||||
typedef lib::function<void(connection_hdl,boost::asio::ssl::stream<
|
||||
boost::asio::ip::tcp::socket>::lowest_layer_type&)> socket_init_handler;
|
||||
typedef lib::function<lib::shared_ptr<boost::asio::ssl::context>(connection_hdl)>
|
||||
tls_init_handler;
|
||||
|
||||
/// TLS enabled Boost ASIO connection socket component
|
||||
/**
|
||||
* transport::asio::tls_socket::connection impliments a secure connection socket
|
||||
* component that uses Boost ASIO's ssl::stream to wrap an ip::tcp::socket.
|
||||
*/
|
||||
class connection {
|
||||
public:
|
||||
typedef tls type;
|
||||
|
||||
/// Type of this connection socket component
|
||||
typedef connection type;
|
||||
/// Type of a shared pointer to this connection socket component
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
|
||||
/// Type of the ASIO socket being used
|
||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_type;
|
||||
typedef boost::asio::io_service* io_service_ptr;
|
||||
/// Type of a shared pointer to the ASIO socket being used
|
||||
typedef lib::shared_ptr<socket_type> socket_ptr;
|
||||
/// Type of a pointer to the ASIO io_service being used
|
||||
typedef boost::asio::io_service* io_service_ptr;
|
||||
/// Type of a shared pointer to the ASIO TLS context being used
|
||||
typedef lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
/// Type of a shared pointer to the ASIO timer being used
|
||||
typedef lib::shared_ptr<boost::asio::deadline_timer> timer_ptr;
|
||||
|
||||
typedef boost::system::error_code boost_error;
|
||||
@@ -62,11 +84,15 @@ public:
|
||||
typedef lib::shared_ptr<handler_interface> handler_ptr;
|
||||
|
||||
|
||||
explicit tls()
|
||||
{
|
||||
std::cout << "transport::security::tls constructor" << std::endl;
|
||||
explicit connection() {
|
||||
std::cout << "transport::asio::tls_socket::connection constructor"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/// Check whether or not this connection is secure
|
||||
/**
|
||||
* @return Wether or not this connection is secure
|
||||
*/
|
||||
bool is_secure() const {
|
||||
return true;
|
||||
}
|
||||
@@ -86,6 +112,31 @@ public:
|
||||
socket_type& get_socket() {
|
||||
return *m_socket;
|
||||
}
|
||||
|
||||
/// Set the socket initialization handler
|
||||
/**
|
||||
* The socket initialization handler is called after the socket object is
|
||||
* created but before it is used. This gives the application a chance to
|
||||
* set any ASIO socket options it needs.
|
||||
*
|
||||
* @param h The new socket_init_handler
|
||||
*/
|
||||
void set_socket_init_handler(socket_init_handler h) {
|
||||
m_socket_init_handler = h;
|
||||
}
|
||||
|
||||
/// Set TLS init handler
|
||||
/**
|
||||
* The tls init handler is called when needed to request a TLS context for
|
||||
* the library to use. A TLS init handler must be set and it must return a
|
||||
* valid TLS context in order for this endpoint to be able to initialize
|
||||
* TLS connections
|
||||
*
|
||||
* @param h The new tls_init_handler
|
||||
*/
|
||||
void set_tls_init_handler(tls_init_handler h) {
|
||||
m_tls_init_handler = h;
|
||||
}
|
||||
protected:
|
||||
/// Perform one time initializations
|
||||
/**
|
||||
@@ -97,10 +148,13 @@ protected:
|
||||
* @param is_server Whether or not the endpoint is a server or not.
|
||||
*/
|
||||
lib::error_code init_asio (io_service_ptr service, bool is_server) {
|
||||
m_context = m_handler->on_tls_init();
|
||||
if (!m_tls_init_handler) {
|
||||
return socket::make_error(socket::error::missing_tls_init_handler);
|
||||
}
|
||||
m_context = m_tls_init_handler(m_hdl);
|
||||
|
||||
if (!m_context) {
|
||||
return make_error(error::invalid_tls_context);
|
||||
return socket::make_error(socket::error::invalid_tls_context);
|
||||
}
|
||||
|
||||
m_socket.reset(new socket_type(*service,*m_context));
|
||||
@@ -118,8 +172,10 @@ protected:
|
||||
|
||||
/// Initialize security policy for reading
|
||||
void init(init_handler callback) {
|
||||
m_handler->on_socket_init(get_raw_socket());
|
||||
|
||||
if (m_socket_init_handler) {
|
||||
m_socket_init_handler(m_hdl,get_raw_socket());
|
||||
}
|
||||
|
||||
// register timeout
|
||||
m_timer->expires_from_now(boost::posix_time::milliseconds(5000));
|
||||
// TEMP
|
||||
@@ -144,6 +200,17 @@ protected:
|
||||
);
|
||||
}
|
||||
|
||||
/// Sets the connection handle
|
||||
/**
|
||||
* The connection handle is passed to any handlers to identify the
|
||||
* connection
|
||||
*
|
||||
* @param hdl The new handle
|
||||
*/
|
||||
void set_handle(connection_hdl hdl) {
|
||||
m_hdl = hdl;
|
||||
}
|
||||
|
||||
void handle_timeout(init_handler callback, const
|
||||
boost::system::error_code& error)
|
||||
{
|
||||
@@ -155,11 +222,11 @@ protected:
|
||||
|
||||
// Some other ASIO error, pass it through
|
||||
// TODO: make this error pass through better
|
||||
callback(make_error(error::pass_through));
|
||||
callback(socket::make_error(socket::error::pass_through));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(make_error(error::tls_handshake_timeout));
|
||||
callback(socket::make_error(socket::error::tls_handshake_timeout));
|
||||
}
|
||||
|
||||
void handle_init(init_handler callback, const
|
||||
@@ -170,7 +237,7 @@ protected:
|
||||
|
||||
if (error) {
|
||||
// TODO: make this error pass through better
|
||||
callback(make_error(error::pass_through));
|
||||
callback(socket::make_error(socket::error::pass_through));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -196,15 +263,89 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
io_service_ptr m_io_service;
|
||||
context_ptr m_context;
|
||||
socket_ptr m_socket;
|
||||
timer_ptr m_timer;
|
||||
bool m_is_server;
|
||||
handler_ptr m_handler;
|
||||
io_service_ptr m_io_service;
|
||||
context_ptr m_context;
|
||||
socket_ptr m_socket;
|
||||
timer_ptr m_timer;
|
||||
bool m_is_server;
|
||||
handler_ptr m_handler;
|
||||
|
||||
connection_hdl m_hdl;
|
||||
socket_init_handler m_socket_init_handler;
|
||||
tls_init_handler m_tls_init_handler;
|
||||
};
|
||||
|
||||
} // namespace security
|
||||
/// TLS enabled Boost ASIO endpoint socket component
|
||||
/**
|
||||
* transport::asio::tls_socket::endpoint impliments a secure endpoint socket
|
||||
* component that uses Boost ASIO's ssl::stream to wrap an ip::tcp::socket.
|
||||
*/
|
||||
class endpoint {
|
||||
public:
|
||||
/// The type of this endpoint socket component
|
||||
typedef endpoint type;
|
||||
|
||||
/// The type of the corresponding connection socket component
|
||||
typedef connection socket_con_type;
|
||||
/// The type of a shared pointer to the corresponding connection socket
|
||||
/// component.
|
||||
typedef typename socket_con_type::ptr socket_con_ptr;
|
||||
|
||||
explicit endpoint() {
|
||||
std::cout << "transport::asio::tls_socket::endpoint constructor"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/// Checks whether the endpoint creates secure connections
|
||||
/**
|
||||
* @return Wether or not the endpoint creates secure connections
|
||||
*/
|
||||
bool is_secure() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Set socket init handler
|
||||
/**
|
||||
* The socket init handler is called after a connection's socket is created
|
||||
* but before it is used. This gives the end application an opportunity to
|
||||
* set asio socket specific parameters.
|
||||
*
|
||||
* @param h The new socket_init_handler
|
||||
*/
|
||||
void set_socket_init_handler(socket_init_handler h) {
|
||||
m_socket_init_handler = h;
|
||||
}
|
||||
|
||||
/// Set TLS init handler
|
||||
/**
|
||||
* The tls init handler is called when needed to request a TLS context for
|
||||
* the library to use. A TLS init handler must be set and it must return a
|
||||
* valid TLS context in order for this endpoint to be able to initialize
|
||||
* TLS connections
|
||||
*
|
||||
* @param h The new tls_init_handler
|
||||
*/
|
||||
void set_tls_init_handler(tls_init_handler h) {
|
||||
m_tls_init_handler = h;
|
||||
}
|
||||
protected:
|
||||
/// Initialize a connection
|
||||
/**
|
||||
* Called by the transport after a new connection is created to initialize
|
||||
* the socket component of the connection.
|
||||
*/
|
||||
void init(socket_con_ptr scon) {
|
||||
scon->set_socket_init_handler(m_socket_init_handler);
|
||||
scon->set_tls_init_handler(m_tls_init_handler);
|
||||
}
|
||||
|
||||
private:
|
||||
socket_init_handler m_socket_init_handler;
|
||||
tls_init_handler m_tls_init_handler;
|
||||
};
|
||||
|
||||
} // namespace tls_socket
|
||||
} // namespace asio
|
||||
} // namespace transport
|
||||
} // namespace websocketpp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user