From bb5afa144af4c554846b4eeb63f98f64616ab1d5 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 28 Apr 2012 18:08:10 -0700 Subject: [PATCH] Add verification timer to peer connecting. --- src/ConnectionPool.cpp | 2 +- src/Peer.cpp | 53 +++++++++++++++++++++++++++++++++++++++--- src/Peer.h | 11 +++++---- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/ConnectionPool.cpp b/src/ConnectionPool.cpp index 1b87e15ea..22c154f3e 100644 --- a/src/ConnectionPool.cpp +++ b/src/ConnectionPool.cpp @@ -142,7 +142,7 @@ bool ConnectionPool::peerConnected(Peer::pointer peer, const NewcoinAddress& na) void ConnectionPool::peerDisconnected(Peer::pointer peer, const ipPort& ipPeer, const NewcoinAddress& naPeer) { - std::cerr << "ConnectionPool::peerDisconnected: " << peer->mIpPort.first << " " << peer->mIpPort.second << std::endl; + std::cerr << "ConnectionPool::peerDisconnected: " << ipPeer.first << " " << ipPeer.second << std::endl; boost::mutex::scoped_lock sl(mPeerLock); diff --git a/src/Peer.cpp b/src/Peer.cpp index c248dd41b..6112db77d 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -16,8 +16,12 @@ #include "SerializedTransaction.h" #include "utils.h" +// Node has this long to verify its identity from connection accepted or connection attempt. +#define NODE_VERIFY_SECONDS 15 + Peer::Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx) - : mSocketSsl(io_service, ctx) + : mSocketSsl(io_service, ctx), + mVerifyTimer(io_service) { } @@ -51,6 +55,10 @@ void Peer::handle_write(const boost::system::error_code& error, size_t bytes_tra void Peer::detach() { + boost::system::error_code ecCancel; + + (void) mVerifyTimer.cancel(); + mSendQ.clear(); // mSocketSsl.close(); @@ -60,12 +68,36 @@ void Peer::detach() } } +void Peer::handleVerifyTimer(const boost::system::error_code& ecResult) +{ + if (ecResult == boost::asio::error::operation_aborted) + { + // Timer canceled because deadline no longer needed. + // std::cerr << "Deadline cancelled." << std::endl; + + nothing(); // Aborter is done. + } + else if (ecResult) + { + std::cerr << "Peer verify timer error: " << std::endl; + + // Can't do anything sound. + abort(); + } + else + { + std::cerr << "Peer failed to verify in time." << std::endl; + detach(); + } +} + // Begin trying to connect. We are not connected till we know and accept peer's public key. // Only takes IP addresses (not domains). void Peer::connect(const std::string strIp, int iPort) { int iPortAct = iPort < 0 ? SYSTEM_PEER_PORT : iPort; + // XXX Should not print IP if not known sane. std::cerr << "Peer::connect: " << strIp << " " << iPort << std::endl; mIpPort = make_pair(strIp, iPort); @@ -78,10 +110,21 @@ void Peer::connect(const std::string strIp, int iPort) if (err || itrEndpoint == boost::asio::ip::tcp::resolver::iterator()) { std::cerr << "Peer::connect: Bad IP" << std::endl; - // Failed to resolve ip. detach(); } else + { + mVerifyTimer.expires_from_now(boost::posix_time::seconds(NODE_VERIFY_SECONDS), err); + mVerifyTimer.async_wait(boost::bind(&Peer::handleVerifyTimer, shared_from_this(), boost::asio::placeholders::error)); + + if (err) + { + std::cerr << "Peer::connect: Failed to set timer." << std::endl; + detach(); + } + } + + if (!err) { std::cerr << "Peer::connect: Connectting: " << mIpPort.first << " " << mIpPort.second << std::endl; @@ -461,8 +504,12 @@ void Peer::recvHello(newcoin::TMHello& packet) else { // Successful connection. - // XXX Kill hello timer. // XXX Set timer: connection is in grace period to be useful. + // XXX Set timer: connection idle (idle may vary depending on connection type.) + + // XXX Only kill if verified no man-in-the-middle. + (void) mVerifyTimer.cancel(); + bDetach = false; } diff --git a/src/Peer.h b/src/Peer.h index 7e943e286..963bd8971 100644 --- a/src/Peer.h +++ b/src/Peer.h @@ -28,15 +28,18 @@ public: static const int psbGotHello=0, psbSentHello=1, psbInMap=2, psbTrusted=3; static const int psbNoLedgers=4, psbNoTransactions=5, psbDownLevel=6; - NewcoinAddress mNodePublic; // Node public key of peer. - ipPort mIpPort; - void handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it); private: + NewcoinAddress mNodePublic; // Node public key of peer. + ipPort mIpPort; + boost::asio::ssl::stream mSocketSsl; - void handleStart(const boost::system::error_code& error); + boost::asio::deadline_timer mVerifyTimer; + + void handleStart(const boost::system::error_code& ecResult); + void handleVerifyTimer(const boost::system::error_code& ecResult); protected: