mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Initial scaning support
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "ConnectionPool.h"
|
||||
#include "Config.h"
|
||||
#include "Peer.h"
|
||||
#include "Application.h"
|
||||
#include "utils.h"
|
||||
|
||||
// XXX On Windows make sure OpenSSL PRNG is seeded: EGADS
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
ConnectionPool::ConnectionPool() :
|
||||
iConnecting(0),
|
||||
mCtx(boost::asio::ssl::context::sslv23)
|
||||
ConnectionPool::ConnectionPool(boost::asio::io_service& io_service) :
|
||||
mCtx(boost::asio::ssl::context::sslv23),
|
||||
bScanning(false),
|
||||
mScanTimer(io_service)
|
||||
{
|
||||
mCtx.set_options(
|
||||
boost::asio::ssl::context::default_workarounds
|
||||
@@ -26,6 +27,9 @@ ConnectionPool::ConnectionPool() :
|
||||
void ConnectionPool::start()
|
||||
{
|
||||
// XXX Start running policy.
|
||||
|
||||
// Start scanning.
|
||||
scanRefresh();
|
||||
}
|
||||
|
||||
// XXX Broken: also don't send a message to a peer if we got it from the peer.
|
||||
@@ -75,6 +79,7 @@ bool ConnectionPool::peerRegister(Peer::pointer peer, const std::string& strIp,
|
||||
|
||||
bool ConnectionPool::connectTo(const std::string& strIp, int iPort)
|
||||
{
|
||||
bool bConnecting;
|
||||
ipPort ip = make_pair(strIp, iPort);
|
||||
|
||||
boost::unordered_map<ipPort, Peer::pointer>::iterator it;
|
||||
@@ -94,15 +99,19 @@ bool ConnectionPool::connectTo(const std::string& strIp, int iPort)
|
||||
mIpMap[ip] = peer;
|
||||
|
||||
peer->connect(strIp, iPort);
|
||||
|
||||
bConnecting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found it. Already connected.
|
||||
std::cerr << "ConnectionPool::connectTo: Already connected: "
|
||||
<< strIp << " " << iPort << std::endl;
|
||||
|
||||
bConnecting = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return bConnecting;
|
||||
}
|
||||
|
||||
Json::Value ConnectionPool::getPeersJson()
|
||||
@@ -129,7 +138,7 @@ bool ConnectionPool::peerConnected(Peer::pointer peer, const NewcoinAddress& na)
|
||||
if (na == theApp->getWallet().getNodePublic())
|
||||
{
|
||||
std::cerr << "ConnectionPool::peerConnected: To self." << std::endl;
|
||||
bSuccess = false;
|
||||
bSuccess = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -183,6 +192,143 @@ void ConnectionPool::peerDisconnected(Peer::pointer peer, const ipPort& ipPeer,
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionPool::peerFailed(const std::string& strIp, int iPort)
|
||||
{
|
||||
if (bScanning && !mScanIp.compare(strIp), mScanPort == iPort)
|
||||
{
|
||||
bScanning = false;
|
||||
scanRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionPool::peerVerified(const std::string& strIp, int iPort)
|
||||
{
|
||||
if (bScanning && !mScanIp.compare(strIp), mScanPort == iPort)
|
||||
{
|
||||
// Scan completed successfully.
|
||||
{
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
Database *db=theApp->getWalletDB()->getDB();
|
||||
|
||||
db->executeSQL(str(boost::format("UPDATE PeerIps SET ScanNext=NULL,ScanInterval=0 WHERE IP=%s AND Port=%d;")
|
||||
% db->escape(strIp)
|
||||
% iPort));
|
||||
// XXX Check error.
|
||||
}
|
||||
|
||||
bScanning = false;
|
||||
scanRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionPool::scanHandler(const boost::system::error_code& ecResult)
|
||||
{
|
||||
if (ecResult == boost::asio::error::operation_aborted)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
else if (!ecResult)
|
||||
{
|
||||
scanRefresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Internal error: unexpected deadline error.");
|
||||
}
|
||||
}
|
||||
|
||||
// Scan ips as per db entries.
|
||||
void ConnectionPool::scanRefresh()
|
||||
{
|
||||
if (bScanning)
|
||||
{
|
||||
// Currently scanning, will scan again after completion.
|
||||
std::cerr << "scanRefresh: already scanning" << std::endl;
|
||||
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Discover if there are entries that need scanning.
|
||||
boost::posix_time::ptime tpNext;
|
||||
boost::posix_time::ptime tpNow;
|
||||
std::string strIp;
|
||||
int iPort;
|
||||
int iInterval;
|
||||
|
||||
{
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
Database *db=theApp->getWalletDB()->getDB();
|
||||
|
||||
if (db->executeSQL("SELECT * FROM PeerIps INDEXED BY PeerScanIndex WHERE ScanNext NOT NULL ORDER BY ScanNext LIMIT 1;")
|
||||
&& db->startIterRows())
|
||||
{
|
||||
// Have an entry to scan.
|
||||
int iNext = db->getInt("ScanNext");
|
||||
|
||||
tpNext = ptFromSeconds(iNext);
|
||||
tpNow = boost::posix_time::second_clock::universal_time();
|
||||
|
||||
db->getStr("IP", strIp);
|
||||
iPort = db->getInt("Port");
|
||||
iInterval = db->getInt("ScanInterval");
|
||||
}
|
||||
else
|
||||
{
|
||||
// No entries to scan.
|
||||
tpNow = boost::posix_time::ptime(boost::posix_time::not_a_date_time);
|
||||
}
|
||||
}
|
||||
|
||||
if (tpNow.is_not_a_date_time())
|
||||
{
|
||||
std::cerr << "scanRefresh: no scan needed." << std::endl;
|
||||
|
||||
(void) mScanTimer.cancel();
|
||||
}
|
||||
else if (tpNext <= tpNow)
|
||||
{
|
||||
// Scan it.
|
||||
(void) mScanTimer.cancel();
|
||||
|
||||
std::cerr << "scanRefresh: scanning: " << strIp << " " << iPort << std::endl;
|
||||
bScanning = true;
|
||||
mScanIp = strIp;
|
||||
mScanPort = iPort;
|
||||
|
||||
iInterval *= 2;
|
||||
iInterval = MAX(iInterval, theConfig.PEER_SCAN_INTERVAL_MIN);
|
||||
|
||||
tpNext = tpNow + boost::posix_time::seconds(iInterval);
|
||||
|
||||
{
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
Database *db=theApp->getWalletDB()->getDB();
|
||||
|
||||
db->executeSQL(str(boost::format("UPDATE PeerIps SET ScanNext=%d,ScanInterval=%d WHERE IP=%s AND Port=%d;")
|
||||
% iToSeconds(tpNext)
|
||||
% iInterval
|
||||
% db->escape(strIp)
|
||||
% iPort));
|
||||
// XXX Check error.
|
||||
}
|
||||
|
||||
if (!connectTo(mScanIp, mScanPort))
|
||||
{
|
||||
// Already connected. Try again.
|
||||
scanRefresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "scanRefresh: next due: " << tpNow << std::endl;
|
||||
|
||||
mScanTimer.expires_at(tpNext);
|
||||
mScanTimer.async_wait(boost::bind(&ConnectionPool::scanHandler, this, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool ConnectionPool::isMessageKnown(PackedMessage::pointer msg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user