mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add MultiSocket and RippleTlsContext
This commit is contained in:
@@ -690,6 +690,12 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\ripple_asio\ripple_asio.cpp" />
|
<ClCompile Include="..\..\modules\ripple_asio\ripple_asio.cpp" />
|
||||||
|
<ClCompile Include="..\..\modules\ripple_asio\sockets\ripple_RippleTlsContext.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\ripple_asio\tests\ripple_AsioTests.cpp">
|
<ClCompile Include="..\..\modules\ripple_asio\tests\ripple_AsioTests.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
@@ -1491,6 +1497,9 @@
|
|||||||
<ClInclude Include="..\..\modules\ripple_asio\ripple_asio.h" />
|
<ClInclude Include="..\..\modules\ripple_asio\ripple_asio.h" />
|
||||||
<ClInclude Include="..\..\modules\ripple_asio\ripple_asio_fwdecl.h" />
|
<ClInclude Include="..\..\modules\ripple_asio\ripple_asio_fwdecl.h" />
|
||||||
<ClInclude Include="..\..\modules\ripple_asio\ripple_asio_impl.h" />
|
<ClInclude Include="..\..\modules\ripple_asio\ripple_asio_impl.h" />
|
||||||
|
<ClInclude Include="..\..\modules\ripple_asio\sockets\ripple_MultiSocket.cpp" />
|
||||||
|
<ClInclude Include="..\..\modules\ripple_asio\sockets\ripple_MultiSocket.h" />
|
||||||
|
<ClInclude Include="..\..\modules\ripple_asio\sockets\ripple_RippleTlsContext.h" />
|
||||||
<ClInclude Include="..\..\modules\ripple_basics\containers\ripple_KeyCache.h" />
|
<ClInclude Include="..\..\modules\ripple_basics\containers\ripple_KeyCache.h" />
|
||||||
<ClInclude Include="..\..\modules\ripple_basics\containers\ripple_RangeSet.h" />
|
<ClInclude Include="..\..\modules\ripple_basics\containers\ripple_RangeSet.h" />
|
||||||
<ClInclude Include="..\..\modules\ripple_basics\containers\ripple_SecureAllocator.h" />
|
<ClInclude Include="..\..\modules\ripple_basics\containers\ripple_SecureAllocator.h" />
|
||||||
|
|||||||
@@ -163,6 +163,9 @@
|
|||||||
<Filter Include="[1] Ripple\ripple_asio\tests">
|
<Filter Include="[1] Ripple\ripple_asio\tests">
|
||||||
<UniqueIdentifier>{2fdf2a12-4f97-45f6-a63d-7e99e97835dd}</UniqueIdentifier>
|
<UniqueIdentifier>{2fdf2a12-4f97-45f6-a63d-7e99e97835dd}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="[1] Ripple\ripple_asio\sockets">
|
||||||
|
<UniqueIdentifier>{625992a9-7333-4782-8ee3-6ed072d02fe5}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\Subtrees\sqlite\sqlite3.c">
|
<ClCompile Include="..\..\Subtrees\sqlite\sqlite3.c">
|
||||||
@@ -894,6 +897,9 @@
|
|||||||
<ClCompile Include="..\..\modules\ripple_asio\boost\ripple_IoService.cpp">
|
<ClCompile Include="..\..\modules\ripple_asio\boost\ripple_IoService.cpp">
|
||||||
<Filter>[1] Ripple\ripple_asio\boost</Filter>
|
<Filter>[1] Ripple\ripple_asio\boost</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\modules\ripple_asio\sockets\ripple_RippleTlsContext.cpp">
|
||||||
|
<Filter>[1] Ripple\ripple_asio\sockets</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\Subtrees\sqlite\sqlite3.h">
|
<ClInclude Include="..\..\Subtrees\sqlite\sqlite3.h">
|
||||||
@@ -1688,6 +1694,15 @@
|
|||||||
<ClInclude Include="..\..\modules\ripple_asio\boost\ripple_IoService.h">
|
<ClInclude Include="..\..\modules\ripple_asio\boost\ripple_IoService.h">
|
||||||
<Filter>[1] Ripple\ripple_asio\boost</Filter>
|
<Filter>[1] Ripple\ripple_asio\boost</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\modules\ripple_asio\sockets\ripple_MultiSocket.h">
|
||||||
|
<Filter>[1] Ripple\ripple_asio\sockets</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\modules\ripple_asio\sockets\ripple_RippleTlsContext.h">
|
||||||
|
<Filter>[1] Ripple\ripple_asio\sockets</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\modules\ripple_asio\sockets\ripple_MultiSocket.cpp">
|
||||||
|
<Filter>[1] Ripple\ripple_asio\sockets</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="..\..\modules\ripple_data\protocol\ripple.proto">
|
<CustomBuild Include="..\..\modules\ripple_data\protocol\ripple.proto">
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include "BeastConfig.h"
|
#include "BeastConfig.h"
|
||||||
|
|
||||||
#include "beast/modules/beast_basics/beast_basics.h"
|
#include "beast/modules/beast_basics/beast_basics.h"
|
||||||
#include "beast/modules/beast_asio/beast_asio.h"
|
|
||||||
|
|
||||||
#include "ripple_asio.h"
|
#include "ripple_asio.h"
|
||||||
|
|
||||||
@@ -27,6 +26,10 @@ namespace ripple
|
|||||||
#include "boost/ripple_IoService.cpp"
|
#include "boost/ripple_IoService.cpp"
|
||||||
#include "boost/ripple_SslContext.cpp"
|
#include "boost/ripple_SslContext.cpp"
|
||||||
|
|
||||||
|
#include "sockets/ripple_RippleTlsContext.h" // private
|
||||||
|
#include "sockets/ripple_RippleTlsContext.cpp"
|
||||||
|
#include "sockets/ripple_MultiSocket.cpp"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning (push)
|
#pragma warning (push)
|
||||||
#pragma warning (disable: 4100)
|
#pragma warning (disable: 4100)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#define RIPPLE_ASIO_H_INCLUDED
|
#define RIPPLE_ASIO_H_INCLUDED
|
||||||
|
|
||||||
#include "beast/modules/beast_core/beast_core.h"
|
#include "beast/modules/beast_core/beast_core.h"
|
||||||
|
#include "beast/modules/beast_asio/beast_asio.h"
|
||||||
|
|
||||||
// Must be outside the namespace
|
// Must be outside the namespace
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ using namespace beast;
|
|||||||
#include "boost/ripple_IoService.h"
|
#include "boost/ripple_IoService.h"
|
||||||
#include "boost/ripple_SslContext.h"
|
#include "boost/ripple_SslContext.h"
|
||||||
|
|
||||||
|
#include "sockets/ripple_MultiSocket.h"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#ifndef RIPPLE_ASIO_IMPL_H_INCLUDED
|
#ifndef RIPPLE_ASIO_IMPL_H_INCLUDED
|
||||||
#define RIPPLE_ASIO_IMPL_H_INCLUDED
|
#define RIPPLE_ASIO_IMPL_H_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
// Once everything is converted, these can be moved to ripple_asio.cpp
|
// Once everything is converted, these can be moved to ripple_asio.cpp
|
||||||
#include <boost/asio/io_service.hpp>
|
#include <boost/asio/io_service.hpp>
|
||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
|
|||||||
686
modules/ripple_asio/sockets/ripple_MultiSocket.cpp
Normal file
686
modules/ripple_asio/sockets/ripple_MultiSocket.cpp
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
RippleMultiSocket::Options::Options (Flags flags)
|
||||||
|
: useClientSsl (false)
|
||||||
|
, enableServerSsl (false)
|
||||||
|
, requireServerSsl (false)
|
||||||
|
, requireServerProxy (false)
|
||||||
|
{
|
||||||
|
setFromFlags (flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RippleMultiSocket::Options::setFromFlags (Flags flags)
|
||||||
|
{
|
||||||
|
useClientSsl = (flags & client_ssl) != 0;
|
||||||
|
enableServerSsl = (flags & (server_ssl | server_ssl_required)) != 0;
|
||||||
|
requireServerSsl = (flags & server_ssl_required) != 0;
|
||||||
|
requireServerProxy = (flags & server_proxy) !=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <class Stream>
|
||||||
|
class RippleMultiSocketType : public RippleMultiSocket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// This shouldn't be needed
|
||||||
|
/*
|
||||||
|
struct SocketInterfaces
|
||||||
|
: SocketInterface::Socket
|
||||||
|
, SocketInterface::Stream
|
||||||
|
, SocketInterface::Handshake
|
||||||
|
{};
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef typename boost::remove_reference <Stream>::type next_layer_type;
|
||||||
|
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||||
|
|
||||||
|
typedef typename boost::add_reference <next_layer_type>::type next_layer_type_ref;
|
||||||
|
typedef typename boost::asio::ssl::stream <next_layer_type_ref> SslStreamType;
|
||||||
|
|
||||||
|
typedef RippleMultiSocketType <Stream> ThisType;
|
||||||
|
|
||||||
|
enum Status
|
||||||
|
{
|
||||||
|
needMore,
|
||||||
|
proxy,
|
||||||
|
plain,
|
||||||
|
ssl
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Arg>
|
||||||
|
explicit RippleMultiSocketType (Arg& arg, Options options = Options())
|
||||||
|
: m_options (options)
|
||||||
|
, m_context (RippleTlsContext::New ())
|
||||||
|
, m_next_layer (arg)
|
||||||
|
, m_io_service (m_next_layer.get_io_service ())
|
||||||
|
, m_strand (m_io_service)
|
||||||
|
, m_status (needMore)
|
||||||
|
, m_role (Socket::client)
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool is_handshaked ()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* native_object_raw ()
|
||||||
|
{
|
||||||
|
return &m_next_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::io_service& get_io_service () noexcept
|
||||||
|
{
|
||||||
|
return m_io_service;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_layer_type& next_layer () noexcept
|
||||||
|
{
|
||||||
|
return m_next_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_layer_type const& next_layer () const noexcept
|
||||||
|
{
|
||||||
|
return m_next_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
lowest_layer_type& lowest_layer () noexcept
|
||||||
|
{
|
||||||
|
return m_next_layer.lowest_layer ();
|
||||||
|
}
|
||||||
|
|
||||||
|
lowest_layer_type const& lowest_layer () const noexcept
|
||||||
|
{
|
||||||
|
return m_next_layer.lowest_layer ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Socket& stream () const noexcept
|
||||||
|
{
|
||||||
|
fatal_assert (m_stream != nullptr);
|
||||||
|
return *m_stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// SocketInterface
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
boost::system::error_code cancel (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return lowest_layer ().cancel (ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::system::error_code close (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return lowest_layer ().close (ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::system::error_code shutdown (Socket::shutdown_type what, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return lowest_layer ().shutdown (what, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// StreamInterface
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
std::size_t read_some (MutableBuffers const& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
if (m_buffer.size () > 0)
|
||||||
|
{
|
||||||
|
ec = boost::system::error_code ();
|
||||||
|
std::size_t const amount = boost::asio::buffer_copy (buffers, m_buffer.data ());
|
||||||
|
m_buffer.consume (amount);
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
return stream ().read_some (buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t write_some (ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return stream ().write_some (buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||||
|
async_read_some (MutableBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||||
|
{
|
||||||
|
if (m_buffer.size () > 0)
|
||||||
|
{
|
||||||
|
// Return the leftover bytes from the handshake
|
||||||
|
std::size_t const amount = boost::asio::buffer_copy (buffers, m_buffer.data ());
|
||||||
|
m_buffer.consume (amount);
|
||||||
|
return m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler), boost::system::error_code (), amount)));
|
||||||
|
}
|
||||||
|
return stream ().async_read_some (buffers, m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler), boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred)));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||||
|
async_write_some (ConstBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||||
|
{
|
||||||
|
return stream ().async_write_some (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
boost::system::error_code handshake (Socket::handshake_type role, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
Action action = calcAction (role);
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
handshakePlain (ec);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case actionSsl:
|
||||||
|
handshakeSsl (ec);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case actionDetect:
|
||||||
|
detectHandshake (ec);
|
||||||
|
if (! ec)
|
||||||
|
{
|
||||||
|
action = calcDetectAction (ec);
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
handshakePlain (ec);
|
||||||
|
break;
|
||||||
|
case actionSsl:
|
||||||
|
handshakeSsl (ec);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||||
|
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||||
|
{
|
||||||
|
Action const action = calcAction (type);
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
return handshakePlainAsync (BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case actionSsl:
|
||||||
|
return handshakeSslAsync (BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case actionDetect:
|
||||||
|
return detectHandshakeAsync (BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
|
boost::system::error_code handshake (handshake_type type,
|
||||||
|
ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
Action action = calcAction (type);
|
||||||
|
ec = boost::system::error_code ();
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
handshakePlain (buffers, ec);
|
||||||
|
break;
|
||||||
|
case actionSsl:
|
||||||
|
handshakeSsl (buffers, ec);
|
||||||
|
break;
|
||||||
|
case actionDetect:
|
||||||
|
detectHandshake (buffers, ec);
|
||||||
|
if (! ec)
|
||||||
|
{
|
||||||
|
action = calcDetectAction (ec);
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
handshakePlain (buffers, ec);
|
||||||
|
break;
|
||||||
|
case actionSsl:
|
||||||
|
handshakeSsl (buffers, ec);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||||
|
async_handshake (handshake_type type, ConstBuffers const& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||||
|
{
|
||||||
|
Action const action = calcAction (type);
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
return handshakePlainAsync (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case actionSsl:
|
||||||
|
return handshakeSslAsync (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case actionDetect:
|
||||||
|
return detectHandshakeAsync (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
boost::system::error_code shutdown (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
if (m_status == ssl)
|
||||||
|
{
|
||||||
|
return m_ssl_stream->shutdown (ec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we need to close the lwest layer
|
||||||
|
return m_next_layer.shutdown (next_layer_type::shutdown_both, ec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||||
|
async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||||
|
{
|
||||||
|
if (m_status == ssl)
|
||||||
|
{
|
||||||
|
m_ssl_stream->async_shutdown (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||||
|
boost::asio::placeholders::error)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
m_next_layer.shutdown (next_layer_type::shutdown_both, ec);
|
||||||
|
m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), ec)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum Action
|
||||||
|
{
|
||||||
|
actionDetect,
|
||||||
|
actionPlain,
|
||||||
|
actionSsl,
|
||||||
|
actionFail
|
||||||
|
};
|
||||||
|
|
||||||
|
// Determines what action to take based on
|
||||||
|
// the stream options and the desired role.
|
||||||
|
//
|
||||||
|
Action calcAction (Socket::handshake_type role)
|
||||||
|
{
|
||||||
|
m_role = role;
|
||||||
|
|
||||||
|
if (role == Socket::server)
|
||||||
|
{
|
||||||
|
if (! m_options.enableServerSsl &&
|
||||||
|
! m_options.requireServerSsl &&
|
||||||
|
! m_options.requireServerProxy)
|
||||||
|
{
|
||||||
|
return actionPlain;
|
||||||
|
}
|
||||||
|
else if (m_options.requireServerSsl && ! m_options.requireServerProxy)
|
||||||
|
{
|
||||||
|
return actionSsl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return actionDetect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_role == Socket::client)
|
||||||
|
{
|
||||||
|
if (m_options.useClientSsl)
|
||||||
|
{
|
||||||
|
return actionSsl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return actionPlain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actionPlain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines what action to take based on the auto-detected
|
||||||
|
// handshake, the stream options, and desired role.
|
||||||
|
//
|
||||||
|
Action calcDetectAction (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
ec = boost::system::error_code ();
|
||||||
|
|
||||||
|
if (m_status == plain)
|
||||||
|
{
|
||||||
|
if (! m_options.requireServerProxy && ! m_options.requireServerSsl)
|
||||||
|
{
|
||||||
|
return actionPlain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
failedHandshake (ec);
|
||||||
|
return actionFail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_status == ssl)
|
||||||
|
{
|
||||||
|
if (! m_options.requireServerProxy)
|
||||||
|
{
|
||||||
|
if (m_options.enableServerSsl || m_options.requireServerSsl)
|
||||||
|
{
|
||||||
|
return actionSsl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
failedHandshake (ec);
|
||||||
|
return actionFail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
failedHandshake (ec);
|
||||||
|
return actionFail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_status == proxy)
|
||||||
|
{
|
||||||
|
if (m_options.requireServerProxy)
|
||||||
|
{
|
||||||
|
// read the rest of the proxy string
|
||||||
|
// then transition to SSL handshake mode
|
||||||
|
failedHandshake (ec);
|
||||||
|
return actionFail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Can we make PROXY optional?
|
||||||
|
failedHandshake (ec);
|
||||||
|
return actionFail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
failedHandshake (ec);
|
||||||
|
return actionFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// called when options disallow handshake
|
||||||
|
void failedHandshake (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
// VFALCO TODO maybe use a ripple error category?
|
||||||
|
// set this to something custom that we can recognize later?
|
||||||
|
ec = boost::asio::error::invalid_argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createPlainStream ()
|
||||||
|
{
|
||||||
|
m_status = plain;
|
||||||
|
m_stream = new SocketWrapper <next_layer_type> (m_next_layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handshakePlain (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
ec = boost::system::error_code ();
|
||||||
|
createPlainStream ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handshakePlain (ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
fatal_assert (boost::asio::buffer_size (buffers) == 0 );
|
||||||
|
ec = boost::system::error_code ();
|
||||||
|
createPlainStream ();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE(ErrorCall, void (boost::system::error_code))
|
||||||
|
handshakePlainAsync (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||||
|
{
|
||||||
|
createPlainStream ();
|
||||||
|
return m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), boost::system::error_code())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void createSslStream ()
|
||||||
|
{
|
||||||
|
m_status = ssl;
|
||||||
|
m_ssl_stream = new SslStreamType (m_next_layer, m_context->getBoostContext ());
|
||||||
|
m_stream = new SocketWrapper <SslStreamType> (*m_ssl_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handshakeSsl (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
createSslStream ();
|
||||||
|
m_ssl_stream->handshake (m_role, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE(ErrorCall, void (boost::system::error_code))
|
||||||
|
handshakeSslAsync (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||||
|
{
|
||||||
|
createSslStream ();
|
||||||
|
return m_ssl_stream->async_handshake (m_role,
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE(TransferCall, void (boost::system::error_code, std::size_t))
|
||||||
|
handshakePlainAsync (ConstBuffers const& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG (TransferCall) handler)
|
||||||
|
{
|
||||||
|
fatal_assert (boost::asio::buffer_size (buffers) == 0);
|
||||||
|
createPlainStream ();
|
||||||
|
return m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||||
|
boost::system::error_code(), 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void handshakeSsl (ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
createSslStream ();
|
||||||
|
m_ssl_stream->handshake (m_role, buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE (TransferCall, void (boost::system::error_code, std::size_t))
|
||||||
|
handshakeSslAsync (ConstBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||||
|
{
|
||||||
|
createSslStream ();
|
||||||
|
return m_ssl_stream->async_handshake (m_role, buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
autoDetectBytes = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
void detectHandshake (boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
// Top up our buffer
|
||||||
|
bassert (m_buffer.size () == 0);
|
||||||
|
std::size_t const needed = autoDetectBytes;
|
||||||
|
std::size_t const amount = m_next_layer.receive (
|
||||||
|
m_buffer.prepare (needed), boost::asio::socket_base::message_peek, ec);
|
||||||
|
m_buffer.commit (amount);
|
||||||
|
if (! ec)
|
||||||
|
{
|
||||||
|
analyzeHandshake (m_buffer.data ());
|
||||||
|
m_buffer.consume (amount);
|
||||||
|
if (m_status == needMore)
|
||||||
|
ec = boost::asio::error::invalid_argument; // should never happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
|
void detectHandshake (ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
m_buffer.commit (boost::asio::buffer_copy (
|
||||||
|
m_buffer.prepare (boost::asio::buffer_size (buffers)), buffers));
|
||||||
|
detectHandshake (ec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void onDetectRead (BOOST_ASIO_MOVE_ARG(ErrorCall) handler,
|
||||||
|
boost::system::error_code const& ec, std::size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
m_buffer.commit (bytes_transferred);
|
||||||
|
|
||||||
|
if (! ec)
|
||||||
|
{
|
||||||
|
analyzeHandshake (m_buffer.data ());
|
||||||
|
|
||||||
|
boost::system::error_code ec;
|
||||||
|
|
||||||
|
if (m_status != needMore)
|
||||||
|
{
|
||||||
|
m_buffer.consume (bytes_transferred);
|
||||||
|
|
||||||
|
Action action = calcDetectAction (ec);
|
||||||
|
if (! ec)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case actionPlain:
|
||||||
|
handshakePlainAsync (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||||
|
break;
|
||||||
|
case actionSsl:
|
||||||
|
handshakeSslAsync (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ec = boost::asio::error::invalid_argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), ec)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE(ErrorCall, void (boost::system::error_code))
|
||||||
|
detectHandshakeAsync (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||||
|
{
|
||||||
|
bassert (m_buffer.size () == 0);
|
||||||
|
return m_next_layer.async_receive (
|
||||||
|
m_buffer.prepare (autoDetectBytes), boost::asio::socket_base::message_peek,
|
||||||
|
m_strand.wrap (boost::bind (&ThisType::onDetectRead, this,
|
||||||
|
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||||
|
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
|
BOOST_ASIO_INITFN_RESULT_TYPE(TransferCall, void (boost::system::error_code, std::size_t))
|
||||||
|
detectHandshakeAsync (ConstBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||||
|
{
|
||||||
|
fatal_error ("unimplemented");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static inline bool isPrintable (unsigned char c)
|
||||||
|
{
|
||||||
|
return (c < 127) && (c > 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ConstBufferSequence>
|
||||||
|
void analyzeHandshake (ConstBufferSequence const& buffers)
|
||||||
|
{
|
||||||
|
m_status = needMore;
|
||||||
|
|
||||||
|
unsigned char data [5];
|
||||||
|
|
||||||
|
std::size_t const bytes = boost::asio::buffer_copy (boost::asio::buffer (data), buffers);
|
||||||
|
|
||||||
|
if (bytes > 0)
|
||||||
|
{
|
||||||
|
if ( isPrintable (data [0]) &&
|
||||||
|
((bytes < 2) || isPrintable (data [1])) &&
|
||||||
|
((bytes < 3) || isPrintable (data [2])) &&
|
||||||
|
((bytes < 4) || isPrintable (data [3])) &&
|
||||||
|
((bytes < 5) || isPrintable (data [4])))
|
||||||
|
{
|
||||||
|
if (bytes < 5 || memcmp (data, "PROXY", 5) != 0)
|
||||||
|
{
|
||||||
|
m_status = plain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_status = proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_status = ssl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Options m_options;
|
||||||
|
ScopedPointer <RippleTlsContext> m_context;
|
||||||
|
Stream m_next_layer;
|
||||||
|
boost::asio::io_service& m_io_service;
|
||||||
|
boost::asio::io_service::strand m_strand;
|
||||||
|
Status m_status;
|
||||||
|
Socket::handshake_type m_role;
|
||||||
|
ScopedPointer <Socket> m_stream;
|
||||||
|
ScopedPointer <SslStreamType> m_ssl_stream;
|
||||||
|
boost::asio::streambuf m_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RippleMultiSocket* RippleMultiSocket::New (boost::asio::io_service& io_service,
|
||||||
|
Options const& options)
|
||||||
|
{
|
||||||
|
return new RippleMultiSocketType <boost::asio::ip::tcp::socket> (io_service, options);
|
||||||
|
}
|
||||||
|
|
||||||
49
modules/ripple_asio/sockets/ripple_MultiSocket.h
Normal file
49
modules/ripple_asio/sockets/ripple_MultiSocket.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_MULTISOCKET_H_INCLUDED
|
||||||
|
#define RIPPLE_MULTISOCKET_H_INCLUDED
|
||||||
|
|
||||||
|
/** A Socket that can handshake with multiple protocols.
|
||||||
|
*/
|
||||||
|
class RippleMultiSocket : public Socket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Flags
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
client_ssl = 1,
|
||||||
|
server_ssl = 2,
|
||||||
|
server_ssl_required = 4,
|
||||||
|
server_proxy = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Options
|
||||||
|
{
|
||||||
|
Options (Flags flags = none);
|
||||||
|
|
||||||
|
// Always perform SSL handshake as client role
|
||||||
|
bool useClientSsl;
|
||||||
|
|
||||||
|
// Enable optional SSL capability as server role
|
||||||
|
bool enableServerSsl;
|
||||||
|
|
||||||
|
// Require SSL as server role.
|
||||||
|
// Does not require that enableServerSsl is set
|
||||||
|
bool requireServerSsl;
|
||||||
|
|
||||||
|
// Require PROXY protocol handshake as server role
|
||||||
|
bool requireServerProxy;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setFromFlags (Flags flags);
|
||||||
|
};
|
||||||
|
|
||||||
|
static RippleMultiSocket* New (boost::asio::io_service& io_service,
|
||||||
|
Options const& options = none);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
151
modules/ripple_asio/sockets/ripple_RippleTlsContext.cpp
Normal file
151
modules/ripple_asio/sockets/ripple_RippleTlsContext.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class RippleTlsContextImp : public RippleTlsContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RippleTlsContextImp ()
|
||||||
|
: m_context (boost::asio::ssl::context::sslv23)
|
||||||
|
{
|
||||||
|
initBoostContext (m_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
~RippleTlsContextImp ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BoostContextType& getBoostContext () noexcept
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::asio::ssl::context m_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RippleTlsContext::initBoostContext (BoostContextType& context)
|
||||||
|
{
|
||||||
|
struct Helpers
|
||||||
|
{
|
||||||
|
typedef boost::array <unsigned char, 72> RawDHParams;
|
||||||
|
|
||||||
|
// A simple RAII container for a DH
|
||||||
|
struct ScopedDHPointer
|
||||||
|
{
|
||||||
|
explicit ScopedDHPointer (DH* dh)
|
||||||
|
: m_dh (dh)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopedDHPointer ()
|
||||||
|
{
|
||||||
|
if (m_dh != nullptr)
|
||||||
|
DH_free (m_dh);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator DH* () const
|
||||||
|
{
|
||||||
|
return get ();
|
||||||
|
}
|
||||||
|
|
||||||
|
DH* get () const
|
||||||
|
{
|
||||||
|
return m_dh;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned char const* m_p;
|
||||||
|
DH* m_dh;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// These are the DH parameters that OpenCoin has chosen for Ripple
|
||||||
|
//
|
||||||
|
static RawDHParams const& getRaw512Params () noexcept
|
||||||
|
{
|
||||||
|
static RawDHParams params =
|
||||||
|
{ {
|
||||||
|
0x30, 0x46, 0x02, 0x41, 0x00, 0x98, 0x15, 0xd2, 0xd0, 0x08, 0x32, 0xda,
|
||||||
|
0xaa, 0xac, 0xc4, 0x71, 0xa3, 0x1b, 0x11, 0xf0, 0x6c, 0x62, 0xb2, 0x35,
|
||||||
|
0x8a, 0x10, 0x92, 0xc6, 0x0a, 0xa3, 0x84, 0x7e, 0xaf, 0x17, 0x29, 0x0b,
|
||||||
|
0x70, 0xef, 0x07, 0x4f, 0xfc, 0x9d, 0x6d, 0x87, 0x99, 0x19, 0x09, 0x5b,
|
||||||
|
0x6e, 0xdb, 0x57, 0x72, 0x4a, 0x7e, 0xcd, 0xaf, 0xbd, 0x3a, 0x97, 0x55,
|
||||||
|
0x51, 0x77, 0x5a, 0x34, 0x7c, 0xe8, 0xc5, 0x71, 0x63, 0x02, 0x01, 0x02
|
||||||
|
} };
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DH* createDH (RawDHParams const& rawParams)
|
||||||
|
{
|
||||||
|
RawDHParams::const_iterator iter = rawParams.begin ();
|
||||||
|
return d2i_DHparams (nullptr, &iter, rawParams.size ());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
static DH* getDhParameters (int keyLength)
|
||||||
|
{
|
||||||
|
if (keyLength == 512 || keyLength == 1024)
|
||||||
|
{
|
||||||
|
static ScopedDHPointer dh512 (createDH (getRaw512Params ()));
|
||||||
|
return dh512.get ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalError ("unsupported key length", __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DH* tmp_dh_handler (SSL*, int, int key_length)
|
||||||
|
{
|
||||||
|
return DHparams_dup (getDhParameters (key_length));
|
||||||
|
}
|
||||||
|
|
||||||
|
static char const* getCipherList ()
|
||||||
|
{
|
||||||
|
static char const* ciphers = "ALL:!LOW:!EXP:!MD5:@STRENGTH";
|
||||||
|
|
||||||
|
return ciphers;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
context.set_options (
|
||||||
|
boost::asio::ssl::context::default_workarounds |
|
||||||
|
boost::asio::ssl::context::no_sslv2 |
|
||||||
|
boost::asio::ssl::context::single_dh_use);
|
||||||
|
|
||||||
|
context.set_verify_mode (boost::asio::ssl::verify_none);
|
||||||
|
|
||||||
|
SSL_CTX_set_tmp_dh_callback (
|
||||||
|
context.native_handle (),
|
||||||
|
Helpers::tmp_dh_handler);
|
||||||
|
|
||||||
|
int const result = SSL_CTX_set_cipher_list (
|
||||||
|
context.native_handle (),
|
||||||
|
Helpers::getCipherList ());
|
||||||
|
|
||||||
|
if (result != 1)
|
||||||
|
FatalError ("invalid cipher list", __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RippleTlsContext* RippleTlsContext::New ()
|
||||||
|
{
|
||||||
|
return new RippleTlsContextImp ();
|
||||||
|
}
|
||||||
32
modules/ripple_asio/sockets/ripple_RippleTlsContext.h
Normal file
32
modules/ripple_asio/sockets/ripple_RippleTlsContext.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_RIPPLETLSCONTEXT_H_INCLUDED
|
||||||
|
#define RIPPLE_RIPPLETLSCONTEXT_H_INCLUDED
|
||||||
|
|
||||||
|
/** A boost SSL context which is set to Generic SSL/TLS (sslv23).
|
||||||
|
|
||||||
|
This is what Ripple uses for its secure connections. The
|
||||||
|
curve parameters are predefined and verified to be secure.
|
||||||
|
|
||||||
|
The context is set to sslv23, Transport Layer Security / General.
|
||||||
|
This is primarily used for peer to peer servers that don't care
|
||||||
|
about certificates or identity verification.
|
||||||
|
|
||||||
|
Usually you don't instantiate this directly, you will need to derive
|
||||||
|
a class and initialize the context in your constructor.
|
||||||
|
|
||||||
|
@see SslContext
|
||||||
|
*/
|
||||||
|
class RippleTlsContext : public SslContextBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static RippleTlsContext* New ();
|
||||||
|
|
||||||
|
static void initBoostContext (BoostContextType& context);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -13,119 +13,6 @@ namespace AsioUnitTestsNamespace
|
|||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
class SslContext : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SslContext ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~SslContext () { }
|
|
||||||
|
|
||||||
virtual asio::ssl::context& get_object () = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class RippleSslContext : public SslContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RippleSslContext ()
|
|
||||||
: m_context (asio::ssl::context::sslv23)
|
|
||||||
{
|
|
||||||
init_ssl_context (m_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
asio::ssl::context& get_object ()
|
|
||||||
{
|
|
||||||
return m_context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static char const* get_ciphers ()
|
|
||||||
{
|
|
||||||
static char const* ciphers = "ALL:!LOW:!EXP:!MD5:@STRENGTH";
|
|
||||||
|
|
||||||
return ciphers;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DH* get_dh_params (int /*key_length*/)
|
|
||||||
{
|
|
||||||
static const unsigned char raw512DHParams [] =
|
|
||||||
{
|
|
||||||
0x30, 0x46, 0x02, 0x41, 0x00, 0x98, 0x15, 0xd2, 0xd0, 0x08, 0x32, 0xda,
|
|
||||||
0xaa, 0xac, 0xc4, 0x71, 0xa3, 0x1b, 0x11, 0xf0, 0x6c, 0x62, 0xb2, 0x35,
|
|
||||||
0x8a, 0x10, 0x92, 0xc6, 0x0a, 0xa3, 0x84, 0x7e, 0xaf, 0x17, 0x29, 0x0b,
|
|
||||||
0x70, 0xef, 0x07, 0x4f, 0xfc, 0x9d, 0x6d, 0x87, 0x99, 0x19, 0x09, 0x5b,
|
|
||||||
0x6e, 0xdb, 0x57, 0x72, 0x4a, 0x7e, 0xcd, 0xaf, 0xbd, 0x3a, 0x97, 0x55,
|
|
||||||
0x51, 0x77, 0x5a, 0x34, 0x7c, 0xe8, 0xc5, 0x71, 0x63, 0x02, 0x01, 0x02
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScopedDH
|
|
||||||
{
|
|
||||||
explicit ScopedDH (DH* dh)
|
|
||||||
: m_dh (dh)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit ScopedDH (unsigned char const* rawData, std::size_t bytes)
|
|
||||||
: m_dh (d2i_DHparams (nullptr, &rawData, bytes))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedDH ()
|
|
||||||
{
|
|
||||||
if (m_dh != nullptr)
|
|
||||||
DH_free (m_dh);
|
|
||||||
}
|
|
||||||
|
|
||||||
DH* get () const
|
|
||||||
{
|
|
||||||
return m_dh;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator DH* () const
|
|
||||||
{
|
|
||||||
return get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DH* m_dh;
|
|
||||||
};
|
|
||||||
|
|
||||||
static ScopedDH dh512 (raw512DHParams, sizeof (raw512DHParams));
|
|
||||||
|
|
||||||
return dh512;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DH* tmp_dh_handler (SSL* /*ssl*/, int /*is_export*/, int key_length)
|
|
||||||
{
|
|
||||||
return DHparams_dup (get_dh_params (key_length));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_ssl_context (asio::ssl::context& context)
|
|
||||||
{
|
|
||||||
context.set_options (
|
|
||||||
asio::ssl::context::default_workarounds |
|
|
||||||
asio::ssl::context::no_sslv2 |
|
|
||||||
asio::ssl::context::single_dh_use);
|
|
||||||
|
|
||||||
context.set_verify_mode (asio::ssl::verify_none);
|
|
||||||
|
|
||||||
SSL_CTX_set_tmp_dh_callback (context.native_handle (), tmp_dh_handler);
|
|
||||||
|
|
||||||
int const result = SSL_CTX_set_cipher_list (context.native_handle (), get_ciphers ());
|
|
||||||
|
|
||||||
if (result != 1)
|
|
||||||
FatalError ("invalid cipher list", __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
asio::ssl::context m_context;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// A handshaking stream that can distinguish multiple protocols
|
// A handshaking stream that can distinguish multiple protocols
|
||||||
@@ -193,6 +80,7 @@ public:
|
|||||||
template <class Arg>
|
template <class Arg>
|
||||||
explicit RippleHandshakeStreamType (Arg& arg, Options options = Options ())
|
explicit RippleHandshakeStreamType (Arg& arg, Options options = Options ())
|
||||||
: m_options (options)
|
: m_options (options)
|
||||||
|
, m_context (RippleTlsContext::New ())
|
||||||
, m_next_layer (arg)
|
, m_next_layer (arg)
|
||||||
, m_io_service (m_next_layer.get_io_service ())
|
, m_io_service (m_next_layer.get_io_service ())
|
||||||
, m_strand (m_io_service)
|
, m_strand (m_io_service)
|
||||||
@@ -293,16 +181,19 @@ public:
|
|||||||
std::size_t const amount = asio::buffer_copy (buffers, m_buffer.data ());
|
std::size_t const amount = asio::buffer_copy (buffers, m_buffer.data ());
|
||||||
m_buffer.consume (amount);
|
m_buffer.consume (amount);
|
||||||
return m_io_service.post (m_strand.wrap (boost::bind (
|
return m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
handler, system::error_code (), amount)));
|
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler), system::error_code (), amount)));
|
||||||
}
|
}
|
||||||
return stream ().async_read_some (buffers, m_strand.wrap (handler));
|
return stream ().async_read_some (buffers, m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler), boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConstBufferSequence, typename WriteHandler>
|
template <typename ConstBufferSequence, typename WriteHandler>
|
||||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void (boost::system::error_code, std::size_t))
|
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void (boost::system::error_code, std::size_t))
|
||||||
async_write_some (ConstBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
async_write_some (ConstBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||||
{
|
{
|
||||||
return stream ().async_write_some (buffers, handler);
|
return stream ().async_write_some (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@@ -344,7 +235,7 @@ public:
|
|||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <typename ConstBufferSequence>
|
template <typename ConstBufferSequence>
|
||||||
boost::system::error_code handshake (handshake_type type,
|
boost::system::error_code handshake (handshake_type type,
|
||||||
ConstBufferSequence const& buffers, boost::system::error_code& ec)
|
ConstBufferSequence const& buffers, boost::system::error_code& ec)
|
||||||
@@ -391,39 +282,42 @@ public:
|
|||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case actionPlain:
|
case actionPlain:
|
||||||
return handshakePlainAsync (handler);
|
return handshakePlainAsync (BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case actionSsl:
|
case actionSsl:
|
||||||
return handshakeSslAsync (handler);
|
return handshakeSslAsync (BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case actionDetect:
|
case actionDetect:
|
||||||
return detectHandshakeAsync (handler);
|
return detectHandshakeAsync (BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
||||||
async_handshake (handshake_type type, const ConstBufferSequence& buffers,
|
async_handshake (handshake_type type, const ConstBufferSequence& buffers,
|
||||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||||
{
|
{
|
||||||
Action const action = calcAction (type);
|
Action const action = calcAction (type);
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case actionPlain:
|
case actionPlain:
|
||||||
return handshakePlainAsync (buffers, handler);
|
return handshakePlainAsync (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case actionSsl:
|
case actionSsl:
|
||||||
return handshakeSslAsync (buffers, handler);
|
return handshakeSslAsync (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case actionDetect:
|
case actionDetect:
|
||||||
return detectHandshakeAsync (buffers, handler);
|
return detectHandshakeAsync (buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,13 +342,16 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_status == ssl)
|
if (m_status == ssl)
|
||||||
{
|
{
|
||||||
m_ssl_stream->async_shutdown (m_strand.wrap (handler));
|
m_ssl_stream->async_shutdown (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler),
|
||||||
|
boost::asio::placeholders::error)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
system::error_code ec;
|
system::error_code ec;
|
||||||
m_next_layer.shutdown (next_layer_type::shutdown_both, ec);
|
m_next_layer.shutdown (next_layer_type::shutdown_both, ec);
|
||||||
m_io_service.post (m_strand.wrap (boost::bind (handler, ec)));
|
m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler), ec)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,10 +499,11 @@ public:
|
|||||||
handshakePlainAsync (BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
handshakePlainAsync (BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||||
{
|
{
|
||||||
createPlainStream ();
|
createPlainStream ();
|
||||||
return m_io_service.post (m_strand.wrap (boost::bind (handler, system::error_code())));
|
return m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler), system::error_code())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
||||||
handshakePlainAsync (ConstBufferSequence const& buffers,
|
handshakePlainAsync (ConstBufferSequence const& buffers,
|
||||||
@@ -613,14 +511,16 @@ public:
|
|||||||
{
|
{
|
||||||
fatal_assert (asio::buffer_size (buffers) == 0);
|
fatal_assert (asio::buffer_size (buffers) == 0);
|
||||||
createPlainStream ();
|
createPlainStream ();
|
||||||
return m_io_service.post (m_strand.wrap (boost::bind (handler, system::error_code(), 0)));
|
return m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler),
|
||||||
|
system::error_code(), 0)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void createSslStream ()
|
void createSslStream ()
|
||||||
{
|
{
|
||||||
m_status = ssl;
|
m_status = ssl;
|
||||||
m_ssl_stream = new SslStreamType (m_next_layer, m_context.get_object ());
|
m_ssl_stream = new SslStreamType (m_next_layer, m_context->getBoostContext ());
|
||||||
m_stream = new SocketWrapper <SslStreamType> (*m_ssl_stream);
|
m_stream = new SocketWrapper <SslStreamType> (*m_ssl_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,7 +530,7 @@ public:
|
|||||||
m_ssl_stream->handshake (m_role, ec);
|
m_ssl_stream->handshake (m_role, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <typename ConstBufferSequence>
|
template <typename ConstBufferSequence>
|
||||||
void handshakeSsl (ConstBufferSequence const& buffers, system::error_code& ec)
|
void handshakeSsl (ConstBufferSequence const& buffers, system::error_code& ec)
|
||||||
{
|
{
|
||||||
@@ -644,17 +544,19 @@ public:
|
|||||||
handshakeSslAsync (BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
handshakeSslAsync (BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||||
{
|
{
|
||||||
createSslStream ();
|
createSslStream ();
|
||||||
return m_ssl_stream->async_handshake (m_role, handler);
|
return m_ssl_stream->async_handshake (m_role,
|
||||||
|
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||||
BOOST_ASIO_INITFN_RESULT_TYPE (BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
BOOST_ASIO_INITFN_RESULT_TYPE (BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
||||||
handshakeSslAsync (ConstBufferSequence const& buffers,
|
handshakeSslAsync (ConstBufferSequence const& buffers,
|
||||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||||
{
|
{
|
||||||
createSslStream ();
|
createSslStream ();
|
||||||
return m_ssl_stream->async_handshake (m_role, buffers, handler);
|
return m_ssl_stream->async_handshake (m_role, buffers,
|
||||||
|
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -682,7 +584,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <class ConstBufferSequence>
|
template <class ConstBufferSequence>
|
||||||
void detectHandshake (ConstBufferSequence const& buffers, system::error_code& ec)
|
void detectHandshake (ConstBufferSequence const& buffers, system::error_code& ec)
|
||||||
{
|
{
|
||||||
@@ -695,7 +597,7 @@ public:
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
template <typename HandshakeHandler>
|
template <typename HandshakeHandler>
|
||||||
void onDetectRead (HandshakeHandler handler,
|
void onDetectRead (BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
|
||||||
system::error_code const& ec, std::size_t bytes_transferred)
|
system::error_code const& ec, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
m_buffer.commit (bytes_transferred);
|
m_buffer.commit (bytes_transferred);
|
||||||
@@ -717,10 +619,12 @@ public:
|
|||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case actionPlain:
|
case actionPlain:
|
||||||
handshakePlainAsync (handler);
|
handshakePlainAsync (
|
||||||
|
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
case actionSsl:
|
case actionSsl:
|
||||||
handshakeSslAsync (handler);
|
handshakeSslAsync (
|
||||||
|
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -732,7 +636,8 @@ public:
|
|||||||
|
|
||||||
if (ec)
|
if (ec)
|
||||||
{
|
{
|
||||||
m_io_service.post (m_strand.wrap (boost::bind (handler, ec)));
|
m_io_service.post (m_strand.wrap (boost::bind (
|
||||||
|
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler), ec)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,14 +649,16 @@ public:
|
|||||||
bassert (m_buffer.size () == 0);
|
bassert (m_buffer.size () == 0);
|
||||||
return m_next_layer.async_receive (
|
return m_next_layer.async_receive (
|
||||||
m_buffer.prepare (autoDetectBytes), asio::socket_base::message_peek,
|
m_buffer.prepare (autoDetectBytes), asio::socket_base::message_peek,
|
||||||
m_strand.wrap (boost::bind (&ThisType::onDetectRead <HandshakeHandler>, this, handler,
|
m_strand.wrap (boost::bind (&ThisType::onDetectRead <HandshakeHandler>, this,
|
||||||
|
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler),
|
||||||
asio::placeholders::error, asio::placeholders::bytes_transferred)));
|
asio::placeholders::error, asio::placeholders::bytes_transferred)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BOOST_VERSION / 100) >= 1054
|
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
||||||
detectHandshakeAsync (ConstBufferSequence const& buffers, BufferedHandshakeHandler handler)
|
detectHandshakeAsync (ConstBufferSequence const& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||||
{
|
{
|
||||||
fatal_error ("unimplemented");
|
fatal_error ("unimplemented");
|
||||||
}
|
}
|
||||||
@@ -799,7 +706,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Options m_options;
|
Options m_options;
|
||||||
RippleSslContext m_context;
|
//RippleSslContext m_context;
|
||||||
|
ScopedPointer <RippleTlsContext> m_context;
|
||||||
Stream m_next_layer;
|
Stream m_next_layer;
|
||||||
asio::io_service& m_io_service;
|
asio::io_service& m_io_service;
|
||||||
asio::io_service::strand m_strand;
|
asio::io_service::strand m_strand;
|
||||||
@@ -2180,3 +2088,14 @@ public:
|
|||||||
static AsioUnitTests asioUnitTests;
|
static AsioUnitTests asioUnitTests;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
What we want is a MultiSocket
|
||||||
|
Derived from beast::Socket so it can be used generically
|
||||||
|
|
||||||
|
BUT, conforms to
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user