From 44f91065563ede941b9f64fe406ba02a567a5c4b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 20 Feb 2013 21:42:27 -0800 Subject: [PATCH] Complete the peer ping/pong logic. Disconnect idle/broken peers. --- src/cpp/ripple/Peer.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/cpp/ripple/Peer.h | 3 ++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index 0d6068a47..37e9bcb21 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -24,11 +24,14 @@ DECLARE_INSTANCE(Peer); // Node has this long to verify its identity from connection accepted or connection attempt. #define NODE_VERIFY_SECONDS 15 +// Idle nodes are probed this often +#define NODE_IDLE_SECONDS 120 + Peer::Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx, uint64 peerID, bool inbound) : mInbound(inbound), mHelloed(false), mDetaching(false), - mActive(true), + mActive(2), mCluster(false), mPeerId(peerID), mSocketSsl(io_service, ctx), @@ -123,6 +126,33 @@ void Peer::detach(const char *rsn) } } +void Peer::handlePingTimer(const boost::system::error_code& ecResult) +{ + if (ecResult || mDetaching) + return; + + if (mActive == 1) + { // ping out + detach("pto"); + return; + } + + if (mActive == 0) + { // idle->pingsent + mActive = 1; + ripple::TMPing packet; + packet.set_type(ripple::TMPing::ptPING); + sendPacket(boost::make_shared(packet, ripple::mtPING)); + } + else // active->idle + mActive = 0; + + mActivityTimer.expires_from_now(boost::posix_time::seconds(NODE_IDLE_SECONDS)); + mActivityTimer.async_wait(boost::bind(&Peer::handlePingTimer, shared_from_this(), + boost::asio::placeholders::error)); +} + + void Peer::handleVerifyTimer(const boost::system::error_code& ecResult) { if (ecResult == boost::asio::error::operation_aborted) @@ -631,8 +661,10 @@ void Peer::recvHello(ripple::TMHello& packet) { bool bDetach = true; - // Cancel verification timeout. - FIXME Start ping/pong timer (void) mActivityTimer.cancel(); + mActivityTimer.expires_from_now(boost::posix_time::seconds(NODE_IDLE_SECONDS)); + mActivityTimer.async_wait(boost::bind(&Peer::handlePingTimer, shared_from_this(), + boost::asio::placeholders::error)); uint32 ourTime = theApp->getOPs().getNetworkTimeNC(); uint32 minTime = ourTime - 20; @@ -1197,7 +1229,7 @@ void Peer::recvPing(ripple::TMPing& packet) } else if (packet.type() == ripple::TMPing::ptPONG) { - mActive = true; + mActive = 2; } } diff --git a/src/cpp/ripple/Peer.h b/src/cpp/ripple/Peer.h index f21e96b30..06a07e5d9 100644 --- a/src/cpp/ripple/Peer.h +++ b/src/cpp/ripple/Peer.h @@ -37,7 +37,7 @@ private: bool mClientConnect; // In process of connecting as client. bool mHelloed; // True, if hello accepted. bool mDetaching; // True, if detaching. - bool mActive; + int mActive; // 0=idle, 1=pingsent, 2=active bool mCluster; // Node in our cluster RippleAddress mNodePublic; // Node public key of peer. std::string mNodeName; @@ -58,6 +58,7 @@ private: void handleStart(const boost::system::error_code& ecResult); void handleVerifyTimer(const boost::system::error_code& ecResult); + void handlePingTimer(const boost::system::error_code& ecResult); protected: