mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-22 03:55:53 +00:00
HTTP handshake in peer protocol (RIPD-351):
* New I/O paths for client and server role * New handshake_analyzer detects the peer protocol * New basic_message class for parsing and storing HTTP messages * Conditional compilation for selective feature enabling. * Server supports both current handshake and HTTP handshake
This commit is contained in:
@@ -3105,6 +3105,8 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClInclude Include="..\..\src\ripple\overlay\impl\PeerImp.h">
|
<ClInclude Include="..\..\src\ripple\overlay\impl\PeerImp.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\overlay\impl\peer_info.h">
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\overlay\impl\peer_protocol_detector.h">
|
<ClInclude Include="..\..\src\ripple\overlay\impl\peer_protocol_detector.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\overlay\impl\Tuning.h">
|
<ClInclude Include="..\..\src\ripple\overlay\impl\Tuning.h">
|
||||||
@@ -3121,6 +3123,9 @@
|
|||||||
</ClInclude>
|
</ClInclude>
|
||||||
<None Include="..\..\src\ripple\overlay\README.md">
|
<None Include="..\..\src\ripple\overlay\README.md">
|
||||||
</None>
|
</None>
|
||||||
|
<ClCompile Include="..\..\src\ripple\overlay\tests\peer_info.test.cpp">
|
||||||
|
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClInclude Include="..\..\src\ripple\peerfinder\api\Callback.h">
|
<ClInclude Include="..\..\src\ripple\peerfinder\api\Callback.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\peerfinder\api\Config.h">
|
<ClInclude Include="..\..\src\ripple\peerfinder\api\Config.h">
|
||||||
|
|||||||
@@ -463,6 +463,9 @@
|
|||||||
<Filter Include="ripple\overlay\impl">
|
<Filter Include="ripple\overlay\impl">
|
||||||
<UniqueIdentifier>{07E4BC73-2B68-D0D1-D922-FEBBB573F503}</UniqueIdentifier>
|
<UniqueIdentifier>{07E4BC73-2B68-D0D1-D922-FEBBB573F503}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="ripple\overlay\tests">
|
||||||
|
<UniqueIdentifier>{630E81FA-2122-38EA-81BD-636140BF270C}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
<Filter Include="ripple\peerfinder">
|
<Filter Include="ripple\peerfinder">
|
||||||
<UniqueIdentifier>{186385AD-A056-FA3A-7E0E-759EB55E9EAB}</UniqueIdentifier>
|
<UniqueIdentifier>{186385AD-A056-FA3A-7E0E-759EB55E9EAB}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
@@ -4281,6 +4284,9 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\overlay\impl\PeerImp.h">
|
<ClInclude Include="..\..\src\ripple\overlay\impl\PeerImp.h">
|
||||||
<Filter>ripple\overlay\impl</Filter>
|
<Filter>ripple\overlay\impl</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\overlay\impl\peer_info.h">
|
||||||
|
<Filter>ripple\overlay\impl</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\overlay\impl\peer_protocol_detector.h">
|
<ClInclude Include="..\..\src\ripple\overlay\impl\peer_protocol_detector.h">
|
||||||
<Filter>ripple\overlay\impl</Filter>
|
<Filter>ripple\overlay\impl</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -4305,6 +4311,9 @@
|
|||||||
<None Include="..\..\src\ripple\overlay\README.md">
|
<None Include="..\..\src\ripple\overlay\README.md">
|
||||||
<Filter>ripple\overlay</Filter>
|
<Filter>ripple\overlay</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<ClCompile Include="..\..\src\ripple\overlay\tests\peer_info.test.cpp">
|
||||||
|
<Filter>ripple\overlay\tests</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClInclude Include="..\..\src\ripple\peerfinder\api\Callback.h">
|
<ClInclude Include="..\..\src\ripple\peerfinder\api\Callback.h">
|
||||||
<Filter>ripple\peerfinder\api</Filter>
|
<Filter>ripple\peerfinder\api</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -220,11 +220,17 @@
|
|||||||
#define RIPPLE_SINGLE_IO_SERVICE_THREAD 0
|
#define RIPPLE_SINGLE_IO_SERVICE_THREAD 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Config: RIPPLE_STRUCTURED_OVERLAY
|
/** Config: RIPPLE_STRUCTURED_OVERLAY_CLIENT
|
||||||
Enables Structured Overlay support (unfinished)
|
RIPPLE_STRUCTURED_OVERLAY_SERVER
|
||||||
|
Enables Structured Overlay support for the client or server roles.
|
||||||
|
This feature is currently in development:
|
||||||
|
https://ripplelabs.atlassian.net/browse/RIPD-157
|
||||||
*/
|
*/
|
||||||
#ifndef RIPPLE_STRUCTURED_OVERLAY
|
#ifndef RIPPLE_STRUCTURED_OVERLAY_CLIENT
|
||||||
#define RIPPLE_STRUCTURED_OVERLAY 0
|
#define RIPPLE_STRUCTURED_OVERLAY_CLIENT 0
|
||||||
|
#endif
|
||||||
|
#ifndef RIPPLE_STRUCTURED_OVERLAY_SERVER
|
||||||
|
#define RIPPLE_STRUCTURED_OVERLAY_SERVER 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Config: RIPPLE_ASYNC_RPC_HANDLER
|
/** Config: RIPPLE_ASYNC_RPC_HANDLER
|
||||||
|
|||||||
@@ -21,6 +21,39 @@ establishes, receives, and maintains connections to peers. Protocol
|
|||||||
messages are exchanged between peers and serialized using
|
messages are exchanged between peers and serialized using
|
||||||
[_Google Protocol Buffers_][protocol_buffers].
|
[_Google Protocol Buffers_][protocol_buffers].
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
Each connection between peers is identified by its connection type, which
|
||||||
|
affects the behavior of message routing:
|
||||||
|
|
||||||
|
* Leaf
|
||||||
|
|
||||||
|
* Peer
|
||||||
|
|
||||||
|
## Roles
|
||||||
|
|
||||||
|
Depending on the type of connection desired, the peers will modify their
|
||||||
|
behavior according to certain roles:
|
||||||
|
|
||||||
|
### Leaf or Superpeer
|
||||||
|
|
||||||
|
A peer in the leaf role does not route messages. In the superpeer role, a
|
||||||
|
peer accepts incoming connections from other leaves and superpeers up to the
|
||||||
|
configured slot limit. It also routes messages. For a particular connection,
|
||||||
|
the choice of leaf or superpeer is mutually exclusive. However, a peer can
|
||||||
|
operate in both the leaf and superpeer role for different connections. One of
|
||||||
|
the requirements
|
||||||
|
|
||||||
|
### Client Handler
|
||||||
|
|
||||||
|
While not part of the responsibilities of the Overlay module, a peer
|
||||||
|
operating in the Client Handler role accepts incoming connections from clients
|
||||||
|
and services them through the JSON-RPC interface. A peer can operate in either
|
||||||
|
the leaf or superpeer roles while also operating as a client handler.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Handshake
|
## Handshake
|
||||||
|
|
||||||
To establish a protocol connection, a peer makes an outgoing TLS encrypted
|
To establish a protocol connection, a peer makes an outgoing TLS encrypted
|
||||||
@@ -128,6 +161,13 @@ Protocol-Session-Cookie: 71ED064155FFADFA38782C5E0158CB26
|
|||||||
|
|
||||||
This field must be present (TODO)
|
This field must be present (TODO)
|
||||||
|
|
||||||
|
* _User Defined_
|
||||||
|
|
||||||
|
The rippled operator may specify additional, optional fields and values
|
||||||
|
through the configuration. These headers will be transmitted in the
|
||||||
|
corresponding request or response messages.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[overlay_network]: http://en.wikipedia.org/wiki/Overlay_network
|
[overlay_network]: http://en.wikipedia.org/wiki/Overlay_network
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ OverlayImpl::disconnect (PeerFinder::Slot::ptr const& slot, bool graceful)
|
|||||||
{
|
{
|
||||||
if (m_journal.trace) m_journal.trace <<
|
if (m_journal.trace) m_journal.trace <<
|
||||||
"Disconnect " << slot->remote_endpoint () <<
|
"Disconnect " << slot->remote_endpoint () <<
|
||||||
(graceful ? "gracefully" : "");
|
(graceful ? " gracefully" : "");
|
||||||
|
|
||||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,6 @@
|
|||||||
#include <ripple/common/MultiSocket.h>
|
#include <ripple/common/MultiSocket.h>
|
||||||
#include <ripple/nodestore/Database.h>
|
#include <ripple/nodestore/Database.h>
|
||||||
#include <ripple/overlay/predicates.h>
|
#include <ripple/overlay/predicates.h>
|
||||||
#include <ripple/overlay/impl/basic_message.h>
|
|
||||||
#include <ripple/overlay/impl/message_name.h>
|
#include <ripple/overlay/impl/message_name.h>
|
||||||
#include <ripple/overlay/impl/message_stream.h>
|
#include <ripple/overlay/impl/message_stream.h>
|
||||||
#include <ripple/overlay/impl/OverlayImpl.h>
|
#include <ripple/overlay/impl/OverlayImpl.h>
|
||||||
@@ -40,7 +39,7 @@
|
|||||||
|
|
||||||
#include <beast/asio/IPAddressConversion.h>
|
#include <beast/asio/IPAddressConversion.h>
|
||||||
#include <beast/asio/placeholders.h>
|
#include <beast/asio/placeholders.h>
|
||||||
#include <beast/http/message_parser.h>
|
#include <beast/http/basic_message.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@@ -80,58 +79,6 @@ private:
|
|||||||
/** The length of the smallest valid finished message */
|
/** The length of the smallest valid finished message */
|
||||||
static const size_t sslMinimumFinishedLength = 12;
|
static const size_t sslMinimumFinishedLength = 12;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
/** We have accepted an inbound connection.
|
|
||||||
|
|
||||||
The connection state transitions from `stateConnect` to `stateConnected`
|
|
||||||
as `stateConnect`.
|
|
||||||
*/
|
|
||||||
void accept ()
|
|
||||||
{
|
|
||||||
m_journal.info << "Accepted " << m_remoteAddress;
|
|
||||||
|
|
||||||
m_socket->set_verify_mode (boost::asio::ssl::verify_none);
|
|
||||||
m_socket->async_handshake (
|
|
||||||
boost::asio::ssl::stream_base::server,
|
|
||||||
m_strand.wrap (std::bind (
|
|
||||||
&PeerImp::handleStart,
|
|
||||||
std::static_pointer_cast <PeerImp> (shared_from_this ()),
|
|
||||||
beast::asio::placeholders::error)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Attempt an outbound connection.
|
|
||||||
|
|
||||||
The connection may fail (for a number of reasons) and we do not know
|
|
||||||
what will happen at this point.
|
|
||||||
|
|
||||||
The connection state does not transition with this function and remains
|
|
||||||
as `stateConnecting`.
|
|
||||||
*/
|
|
||||||
void connect ()
|
|
||||||
{
|
|
||||||
m_journal.info << "Connecting to " << m_remoteAddress;
|
|
||||||
|
|
||||||
boost::system::error_code err;
|
|
||||||
|
|
||||||
m_timer.expires_from_now (nodeVerifySeconds, err);
|
|
||||||
|
|
||||||
m_timer.async_wait (m_strand.wrap (std::bind (
|
|
||||||
&PeerImp::handleVerifyTimer,
|
|
||||||
shared_from_this (), beast::asio::placeholders::error)));
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
m_journal.error << "Failed to set verify timer.";
|
|
||||||
detach ("c2");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_socket->next_layer <NativeSocketType>().async_connect (
|
|
||||||
beast::IPAddressConversion::to_asio_endpoint (m_remoteAddress),
|
|
||||||
m_strand.wrap (std::bind (&PeerImp::onConnect,
|
|
||||||
shared_from_this (), beast::asio::placeholders::error)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Current state */
|
/** Current state */
|
||||||
enum State
|
enum State
|
||||||
@@ -201,7 +148,7 @@ public:
|
|||||||
std::list<uint256> m_recentTxSets;
|
std::list<uint256> m_recentTxSets;
|
||||||
mutable std::mutex m_recentLock;
|
mutable std::mutex m_recentLock;
|
||||||
|
|
||||||
boost::asio::deadline_timer m_timer;
|
boost::asio::deadline_timer timer_;
|
||||||
|
|
||||||
std::vector<uint8_t> m_readBuffer;
|
std::vector<uint8_t> m_readBuffer;
|
||||||
std::list<Message::pointer> mSendQ;
|
std::list<Message::pointer> mSendQ;
|
||||||
@@ -217,13 +164,20 @@ public:
|
|||||||
// True if close was called
|
// True if close was called
|
||||||
bool m_was_canceled;
|
bool m_was_canceled;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
boost::asio::streambuf read_buffer_;
|
boost::asio::streambuf read_buffer_;
|
||||||
boost::optional <basic_message> http_message_;
|
boost::optional <beast::http::basic_message> http_message_;
|
||||||
boost::optional <basic_message::parser> http_parser_;
|
boost::optional <beast::http::basic_message::parser> http_parser_;
|
||||||
message_stream message_stream_;
|
message_stream message_stream_;
|
||||||
|
|
||||||
|
boost::asio::streambuf write_buffer_;
|
||||||
|
bool write_pending_;
|
||||||
|
|
||||||
std::unique_ptr <LoadEvent> load_event_;
|
std::unique_ptr <LoadEvent> load_event_;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
/** New incoming peer from the specified socket */
|
/** New incoming peer from the specified socket */
|
||||||
PeerImp (
|
PeerImp (
|
||||||
NativeSocketType&& socket,
|
NativeSocketType&& socket,
|
||||||
@@ -250,10 +204,11 @@ public:
|
|||||||
, m_clusterNode (false)
|
, m_clusterNode (false)
|
||||||
, m_minLedger (0)
|
, m_minLedger (0)
|
||||||
, m_maxLedger (0)
|
, m_maxLedger (0)
|
||||||
, m_timer (m_owned_socket.get_io_service())
|
, timer_ (m_owned_socket.get_io_service())
|
||||||
, m_slot (slot)
|
, m_slot (slot)
|
||||||
, m_was_canceled (false)
|
, m_was_canceled (false)
|
||||||
, message_stream_(*this)
|
, message_stream_(*this)
|
||||||
|
, write_pending_ (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,10 +243,11 @@ public:
|
|||||||
, m_clusterNode (false)
|
, m_clusterNode (false)
|
||||||
, m_minLedger (0)
|
, m_minLedger (0)
|
||||||
, m_maxLedger (0)
|
, m_maxLedger (0)
|
||||||
, m_timer (io_service)
|
, timer_ (io_service)
|
||||||
, m_slot (slot)
|
, m_slot (slot)
|
||||||
, m_was_canceled (false)
|
, m_was_canceled (false)
|
||||||
, message_stream_(*this)
|
, message_stream_(*this)
|
||||||
|
, write_pending_ (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,22 +269,66 @@ public:
|
|||||||
|
|
||||||
void getLedger (protocol::TMGetLedger& packet);
|
void getLedger (protocol::TMGetLedger& packet);
|
||||||
|
|
||||||
|
private:
|
||||||
//
|
//
|
||||||
// i/o
|
// client role
|
||||||
//
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
start_read();
|
do_connect();
|
||||||
|
|
||||||
void
|
void
|
||||||
on_read_detect (error_code ec, std::size_t bytes_transferred);
|
on_connect (error_code ec);
|
||||||
|
|
||||||
|
beast::http::basic_message
|
||||||
|
make_request();
|
||||||
|
|
||||||
void
|
void
|
||||||
on_read_http (error_code ec, std::size_t bytes_transferred);
|
on_connect_ssl (error_code ec);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_write_http_request (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_read_http_response (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
//
|
||||||
|
// server role
|
||||||
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
do_accept();
|
||||||
|
|
||||||
|
void
|
||||||
|
on_accept_ssl (error_code ec);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_read_http_detect (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_read_http_request (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
beast::http::basic_message
|
||||||
|
make_response (beast::http::basic_message const& req);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_write_http_response (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
//
|
||||||
|
// protocol
|
||||||
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
do_protocol_start();
|
||||||
|
|
||||||
void
|
void
|
||||||
on_read_protocol (error_code ec, std::size_t bytes_transferred);
|
on_read_protocol (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
void
|
||||||
|
on_write_protocol (error_code ec, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// abstract_protocol_handler
|
// abstract_protocol_handler
|
||||||
@@ -354,6 +354,7 @@ public:
|
|||||||
on_message_end (std::uint16_t type,
|
on_message_end (std::uint16_t type,
|
||||||
std::shared_ptr <::google::protobuf::Message> const& m) override;
|
std::shared_ptr <::google::protobuf::Message> const& m) override;
|
||||||
|
|
||||||
|
// message handlers
|
||||||
error_code on_message (std::shared_ptr <protocol::TMHello> const& m) override;
|
error_code on_message (std::shared_ptr <protocol::TMHello> const& m) override;
|
||||||
error_code on_message (std::shared_ptr <protocol::TMPing> const& m) override;
|
error_code on_message (std::shared_ptr <protocol::TMPing> const& m) override;
|
||||||
error_code on_message (std::shared_ptr <protocol::TMProofWork> const& m) override;
|
error_code on_message (std::shared_ptr <protocol::TMProofWork> const& m) override;
|
||||||
@@ -372,6 +373,7 @@ public:
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public:
|
||||||
State state() const
|
State state() const
|
||||||
{
|
{
|
||||||
return m_state;
|
return m_state;
|
||||||
@@ -422,7 +424,7 @@ public:
|
|||||||
|
|
||||||
mSendQ.clear ();
|
mSendQ.clear ();
|
||||||
|
|
||||||
(void) m_timer.cancel ();
|
(void) timer_.cancel ();
|
||||||
|
|
||||||
if (graceful)
|
if (graceful)
|
||||||
{
|
{
|
||||||
@@ -450,55 +452,6 @@ public:
|
|||||||
detach ("stop", graceful);
|
detach ("stop", graceful);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Outbound connection attempt has completed (not necessarily successfully)
|
|
||||||
|
|
||||||
The connection may fail for a number of reasons. Perhaps we do not have
|
|
||||||
a route to the remote endpoint, or there is no server listening at that
|
|
||||||
address.
|
|
||||||
|
|
||||||
If the connection succeeded, we transition to the `stateConnected` state
|
|
||||||
and move on.
|
|
||||||
|
|
||||||
If the connection failed, we simply disconnect.
|
|
||||||
|
|
||||||
@param ec indicates success or an error code.
|
|
||||||
*/
|
|
||||||
void onConnect (boost::system::error_code ec)
|
|
||||||
{
|
|
||||||
if (m_detaching)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NativeSocketType::endpoint_type local_endpoint;
|
|
||||||
|
|
||||||
if (! ec)
|
|
||||||
local_endpoint = m_socket->this_layer <
|
|
||||||
NativeSocketType> ().local_endpoint (ec);
|
|
||||||
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
// VFALCO NOTE This log statement looks like ass
|
|
||||||
m_journal.info <<
|
|
||||||
"Connect to " << m_remoteAddress <<
|
|
||||||
" failed: " << ec.message();
|
|
||||||
// This should end up calling onPeerClosed()
|
|
||||||
detach ("hc");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bassert (m_state == stateConnecting);
|
|
||||||
m_state = stateConnected;
|
|
||||||
|
|
||||||
m_peerFinder.on_connected (m_slot,
|
|
||||||
beast::IPAddressConversion::from_asio (local_endpoint));
|
|
||||||
|
|
||||||
m_socket->set_verify_mode (boost::asio::ssl::verify_none);
|
|
||||||
m_socket->async_handshake (
|
|
||||||
boost::asio::ssl::stream_base::client,
|
|
||||||
m_strand.wrap (std::bind (&PeerImp::handleStart,
|
|
||||||
std::static_pointer_cast <PeerImp> (shared_from_this ()),
|
|
||||||
beast::asio::placeholders::error)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Indicates that the peer must be activated.
|
/** Indicates that the peer must be activated.
|
||||||
A peer is activated after the handshake is completed and if it is not
|
A peer is activated after the handshake is completed and if it is not
|
||||||
a second connection from a peer that we already have. Once activated
|
a second connection from a peer that we already have. Once activated
|
||||||
@@ -516,9 +469,9 @@ public:
|
|||||||
void start ()
|
void start ()
|
||||||
{
|
{
|
||||||
if (m_inbound)
|
if (m_inbound)
|
||||||
accept ();
|
do_accept ();
|
||||||
else
|
else
|
||||||
connect ();
|
do_connect ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@@ -773,47 +726,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have an encrypted connection to the peer.
|
|
||||||
// Have it say who it is so we know to avoid redundant connections.
|
|
||||||
// Establish that it really who we are talking to by having it sign a
|
|
||||||
// connection detail. Also need to establish no man in the middle attack
|
|
||||||
// is in progress.
|
|
||||||
void handleStart (boost::system::error_code const& ec)
|
|
||||||
{
|
|
||||||
if (m_detaching)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ec == boost::asio::error::operation_aborted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
m_journal.info << "Handshake: " << ec.message ();
|
|
||||||
detach ("hs");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_inbound)
|
|
||||||
m_usage = m_resourceManager.newInboundEndpoint (m_remoteAddress);
|
|
||||||
else
|
|
||||||
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
|
|
||||||
|
|
||||||
if (m_usage.disconnect ())
|
|
||||||
{
|
|
||||||
detach ("resource");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!sendHello ())
|
|
||||||
{
|
|
||||||
m_journal.error << "Unable to send HELLO to " << m_remoteAddress;
|
|
||||||
detach ("hello");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
start_read();
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleVerifyTimer (boost::system::error_code const& ec)
|
void handleVerifyTimer (boost::system::error_code const& ec)
|
||||||
{
|
{
|
||||||
if (m_detaching)
|
if (m_detaching)
|
||||||
|
|||||||
1318
src/ripple/overlay/impl/handshake_analyzer.h
Normal file
1318
src/ripple/overlay/impl/handshake_analyzer.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#ifndef RIPPLE_OVERLAY_MESSAGE_NAME_H_INCLUDED
|
|
||||||
#define RIPPLE_OVERLAY_MESSAGE_NAME_H_INCLUDED
|
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
char const*
|
char const*
|
||||||
@@ -49,5 +46,3 @@ protocol_message_name (int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
36
src/ripple/overlay/impl/peer_info.h
Normal file
36
src/ripple/overlay/impl/peer_info.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_OVERLAY_PEER_INFO_H_INCLUDED
|
||||||
|
#define RIPPLE_OVERLAY_PEER_INFO_H_INCLUDED
|
||||||
|
|
||||||
|
#include <beast/http/basic_message.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
struct parsed_request
|
||||||
|
{
|
||||||
|
int version_major;
|
||||||
|
int version_minor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -39,30 +39,35 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <class ConstBufferSequence>
|
template <class ConstBufferSequence>
|
||||||
boost::tribool
|
boost::tribool
|
||||||
operator() (ConstBufferSequence const& buffers)
|
operator() (ConstBufferSequence const& buffers);
|
||||||
{
|
|
||||||
std::array <std::uint8_t, 6> data;
|
|
||||||
auto const n (boost::asio::buffer_copy (
|
|
||||||
boost::asio::buffer(data), buffers));
|
|
||||||
/*
|
|
||||||
Protocol messages are framed by a 6 byte header which includes
|
|
||||||
a big-endian 4-byte length followed by a big-endian 2-byte type.
|
|
||||||
The type for 'hello' is 1.
|
|
||||||
*/
|
|
||||||
if (n>=1 && data[0] != 0)
|
|
||||||
return false;
|
|
||||||
if (n>=2 && data[1] != 0)
|
|
||||||
return false;
|
|
||||||
if (n>=5 && data[4] != 0)
|
|
||||||
return false;
|
|
||||||
if (n>=6 && data[5] != 1)
|
|
||||||
return false;
|
|
||||||
if (n>=6)
|
|
||||||
return true;
|
|
||||||
return boost::indeterminate;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class ConstBufferSequence>
|
||||||
|
boost::tribool
|
||||||
|
peer_protocol_detector::operator() (
|
||||||
|
ConstBufferSequence const& buffers)
|
||||||
|
{
|
||||||
|
std::array <std::uint8_t, 6> data;
|
||||||
|
auto const n (boost::asio::buffer_copy (
|
||||||
|
boost::asio::buffer(data), buffers));
|
||||||
|
/*
|
||||||
|
Protocol messages are framed by a 6 byte header which includes
|
||||||
|
a big-endian 4-byte length followed by a big-endian 2-byte type.
|
||||||
|
The type for 'hello' is 1.
|
||||||
|
*/
|
||||||
|
if (n>=1 && data[0] != 0)
|
||||||
|
return false;
|
||||||
|
if (n>=2 && data[1] != 0)
|
||||||
|
return false;
|
||||||
|
if (n>=5 && data[4] != 0)
|
||||||
|
return false;
|
||||||
|
if (n>=6 && data[5] != 1)
|
||||||
|
return false;
|
||||||
|
if (n>=6)
|
||||||
|
return true;
|
||||||
|
return boost::indeterminate;
|
||||||
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
68
src/ripple/overlay/tests/peer_info.test.cpp
Normal file
68
src/ripple/overlay/tests/peer_info.test.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <ripple/overlay/impl/peer_info.h>
|
||||||
|
#include <beast/unit_test/suite.h>
|
||||||
|
#include <beast/http/rfc2616.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
class peer_info_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Parse a comma delimited list of strings
|
||||||
|
// Leading and trailing whitespace is removed from each element
|
||||||
|
static
|
||||||
|
std::vector <std::string>
|
||||||
|
parse_list (std::string const& value)
|
||||||
|
{
|
||||||
|
std::vector <std::string> list;
|
||||||
|
auto first (value.begin());
|
||||||
|
auto last (value.end());
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
auto const found (std::find (first, last, ','));
|
||||||
|
if (found != first)
|
||||||
|
{
|
||||||
|
auto p0 (first);
|
||||||
|
auto p1 (found - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (found == last)
|
||||||
|
break;
|
||||||
|
first = found + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
run()
|
||||||
|
{
|
||||||
|
expect (beast::http::rfc2616::trim("x") == "x");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(peer_info,overlay,ripple);
|
||||||
|
|
||||||
|
} // ripple
|
||||||
|
|
||||||
@@ -25,3 +25,5 @@
|
|||||||
#include <ripple/overlay/impl/PeerImp.cpp>
|
#include <ripple/overlay/impl/PeerImp.cpp>
|
||||||
#include <ripple/overlay/impl/PeerDoor.cpp>
|
#include <ripple/overlay/impl/PeerDoor.cpp>
|
||||||
|
|
||||||
|
#include <ripple/overlay/tests/peer_info.test.cpp>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user