Tie in blacklist code.

This commit is contained in:
JoelKatz
2013-09-24 13:00:11 -07:00
parent f61caaae09
commit 5d63086b69
9 changed files with 99 additions and 20 deletions

View File

@@ -146,7 +146,7 @@ private:
} }
} }
bool shouldWarn (LoadSource& source) const bool shouldWarn (LoadSource& source)
{ {
{ {
ScopedLockType sl (mLock, __FILE__, __LINE__); ScopedLockType sl (mLock, __FILE__, __LINE__);
@@ -159,12 +159,14 @@ private:
source.mLastWarning = now; source.mLastWarning = now;
} }
mBlackList.doWarning(source.getCostName ());
logWarning (source.getName ()); logWarning (source.getName ());
return true; return true;
} }
bool shouldCutoff (LoadSource& source) const bool shouldCutoff (LoadSource& source)
{ {
bool bLogged;
{ {
ScopedLockType sl (mLock, __FILE__, __LINE__); ScopedLockType sl (mLock, __FILE__, __LINE__);
int now = UptimeTimer::getInstance ().getElapsedSeconds (); int now = UptimeTimer::getInstance ().getElapsedSeconds ();
@@ -173,15 +175,22 @@ private:
if (source.isPrivileged () || (source.mBalance > mDebitLimit)) if (source.isPrivileged () || (source.mBalance > mDebitLimit))
return false; return false;
if (source.mLogged) bLogged = source.mLogged;
return true;
source.mLogged = true; source.mLogged = true;
} }
mBlackList.doDisconnect (source.getName ());
if (!bLogged)
logDisconnect (source.getName ()); logDisconnect (source.getName ());
return true; return true;
} }
bool shouldAllow (LoadSource& source)
{
return mBlackList.isAllowed (source.getCostName ());
}
bool applyLoadCharge (LoadSource& source, LoadType loadType) const bool applyLoadCharge (LoadSource& source, LoadType loadType) const
{ {
// FIXME: Scale by category // FIXME: Scale by category
@@ -230,6 +239,17 @@ private:
WriteLog (lsWARNING, LoadManager) << "Disconnect for: " << source; WriteLog (lsWARNING, LoadManager) << "Disconnect for: " << source;
} }
Json::Value getBlackList (int threshold)
{
Json::Value ret(Json::objectValue);
BOOST_FOREACH(const BlackList<UptimeTimerAdapter>::BlackListEntry& entry, mBlackList.getBlackList(threshold))
{
ret[entry.first] = entry.second;
}
return ret;
}
// VFALCO TODO Implement this and stop accessing the vector directly // VFALCO TODO Implement this and stop accessing the vector directly
//Cost const& getCost (LoadType loadType) const; //Cost const& getCost (LoadType loadType) const;
int getCost (LoadType t) const int getCost (LoadType t) const
@@ -415,6 +435,8 @@ private:
beast::ThreadWithCallQueue m_logThread; beast::ThreadWithCallQueue m_logThread;
BlackList<UptimeTimerAdapter> mBlackList;
int mCreditRate; // credits gained/lost per second int mCreditRate; // credits gained/lost per second
int mCreditLimit; // the most credits a source can have int mCreditLimit; // the most credits a source can have
int mDebitWarn; // when a source drops below this, we warn int mDebitWarn; // when a source drops below this, we warn

View File

@@ -80,8 +80,10 @@ public:
// VFALCO TODO Eliminate these two functions and just make applyLoadCharge() // VFALCO TODO Eliminate these two functions and just make applyLoadCharge()
// return a LoadSource::Disposition // return a LoadSource::Disposition
// //
virtual bool shouldWarn (LoadSource&) const = 0; virtual bool shouldWarn (LoadSource&) = 0;
virtual bool shouldCutoff (LoadSource&) const = 0; virtual bool shouldCutoff (LoadSource&) = 0;
virtual Json::Value getBlackList(int threshold = (BlackList<UptimeTimerAdapter>::mCreditLimit / 2)) = 0;
}; };
#endif #endif

View File

@@ -71,7 +71,7 @@ public:
, mCluster (false) , mCluster (false)
, mPeerId (peerID) , mPeerId (peerID)
, mPrivate (false) , mPrivate (false)
, mLoad (std::string()) , mLoad (std::string(), std::string())
, mMinLedger (0) , mMinLedger (0)
, mMaxLedger (0) , mMaxLedger (0)
, mActivityTimer (io_service) , mActivityTimer (io_service)
@@ -406,7 +406,7 @@ void PeerImp::handleWrite (const boost::system::error_code& error, size_t bytes_
void PeerImp::setIpPort (const std::string& strIP, int iPort) void PeerImp::setIpPort (const std::string& strIP, int iPort)
{ {
mIpPort = make_pair (strIP, iPort); mIpPort = make_pair (strIP, iPort);
mLoad.rename (strIP); mLoad.rename (strIP + lexicalCast<std::string>(iPort), strIP);
WriteLog (lsDEBUG, Peer) << "Peer: Set: " WriteLog (lsDEBUG, Peer) << "Peer: Set: "
<< addressToString (this) << "> " << addressToString (this) << "> "
@@ -1085,7 +1085,7 @@ void PeerImp::recvHello (protocol::TMHello& packet)
mCluster = true; mCluster = true;
mLoad.setPrivileged (); mLoad.setPrivileged ();
if (!mNodeName.empty()) if (!mNodeName.empty())
mLoad.rename (mNodeName); mLoad.rename (mNodeName, mNodeName);
WriteLog (lsINFO, Peer) << "Cluster connection to \"" << (mNodeName.empty () ? getIP () : mNodeName) WriteLog (lsINFO, Peer) << "Cluster connection to \"" << (mNodeName.empty () ? getIP () : mNodeName)
<< "\" established"; << "\" established";
} }

View File

@@ -608,6 +608,15 @@ Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, A
return jvResult; return jvResult;
} }
Json::Value RPCHandler::doBlackList (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock();
if (params.isMember("threshold"))
return getApp().getLoadManager().getBlackList(params["threshold"].asInt());
else
return getApp().getLoadManager().getBlackList();
}
// { // {
// ip: <string>, // ip: <string>,
// port: <number> // port: <number>
@@ -3774,6 +3783,7 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{ "account_lines", &RPCHandler::doAccountLines, false, optCurrent }, { "account_lines", &RPCHandler::doAccountLines, false, optCurrent },
{ "account_offers", &RPCHandler::doAccountOffers, false, optCurrent }, { "account_offers", &RPCHandler::doAccountOffers, false, optCurrent },
{ "account_tx", &RPCHandler::doAccountTxSwitch, false, optNetwork }, { "account_tx", &RPCHandler::doAccountTxSwitch, false, optNetwork },
{ "blacklist", &RPCHandler::doBlackList, true, optNone },
{ "book_offers", &RPCHandler::doBookOffers, false, optCurrent }, { "book_offers", &RPCHandler::doBookOffers, false, optCurrent },
{ "connect", &RPCHandler::doConnect, true, optNone }, { "connect", &RPCHandler::doConnect, true, optNone },
{ "consensus_info", &RPCHandler::doConsensusInfo, true, optNone }, { "consensus_info", &RPCHandler::doConsensusInfo, true, optNone },

View File

@@ -88,6 +88,7 @@ private:
Json::Value doAccountTxSwitch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doAccountTxSwitch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doAccountTxOld (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doAccountTxOld (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doBookOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doBookOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doBlackList (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doConnect (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doConnect (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doConsensusInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doConsensusInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doFeature (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doFeature (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);

View File

@@ -6,6 +6,12 @@
SETUP_LOGN (WSConnection, "WSConnection") SETUP_LOGN (WSConnection, "WSConnection")
static std::string trimIP(const std::string& ip)
{ // Make sure there's no port
size_t pos = ip.find(':');
return (pos == std::string::npos) ? ip : ip.substr(0, pos - 1);
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
WSConnection::WSConnection (InfoSub::Source& source, bool isPublic, WSConnection::WSConnection (InfoSub::Source& source, bool isPublic,
@@ -15,7 +21,7 @@ WSConnection::WSConnection (InfoSub::Source& source, bool isPublic,
, m_remoteIP (remoteIP) , m_remoteIP (remoteIP)
, m_receiveQueueMutex (this, "WSConnection", __FILE__, __LINE__) , m_receiveQueueMutex (this, "WSConnection", __FILE__, __LINE__)
, m_netOPs (getApp ().getOPs ()) , m_netOPs (getApp ().getOPs ())
, m_loadSource (m_remoteIP) , m_loadSource (m_remoteIP, trimIP(m_remoteIP))
, m_pingTimer (io_service) , m_pingTimer (io_service)
, m_sentPing (false) , m_sentPing (false)
, m_receiveQueueRunning (false) , m_receiveQueueRunning (false)

View File

@@ -10,8 +10,11 @@ class BlackList
int mBalance; // Exponentially-decaying "cost" balance int mBalance; // Exponentially-decaying "cost" balance
int mLastUpdate; // The uptime when the balance was last decayed int mLastUpdate; // The uptime when the balance was last decayed
iBlackList(int now) : mBalance(0), mLastUpdate(now) { ; } iBlackList(int now) : mBalance(0), mLastUpdate(now)
iBlackList() : mBalance(0), mLastUpdate(0) { ; } { ; }
iBlackList() : mBalance(0), mLastUpdate(0)
{ ; }
}; };
public: public:
@@ -21,7 +24,11 @@ public:
typedef std::vector<BlackListEntry> BlackListEntryList; typedef std::vector<BlackListEntry> BlackListEntryList;
BlackList() BlackList()
{ } {
mWhiteList.push_back("127.");
mWhiteList.push_back("10.");
mWhiteList.push_back("192.168.");
}
// We are issuing a warning to a source, update its entry // We are issuing a warning to a source, update its entry
bool doWarning(const std::string& source) bool doWarning(const std::string& source)
@@ -107,6 +114,27 @@ public:
} }
} }
void setWhiteList(std::vector<std::string> wl)
{
boost::mutex::scoped_lock sl(mMutex);
mWhiteList.swap(wl);
}
bool isWhiteList(const std::string& source)
{
{
boost::mutex::scoped_lock sl(mMutex);
BOOST_FOREACH(const std::string& entry, mWhiteList)
{ // Does this source start with the entry?
if ((source.size() >= entry.size()) && (entry.compare(0, entry.size(), source) == 0))
return true;
}
}
return false;
}
static const int mWarnCost = 10; // The cost of being warned static const int mWarnCost = 10; // The cost of being warned
static const int mDiscCost = 100; // The cost of being disconnected for abuse static const int mDiscCost = 100; // The cost of being disconnected for abuse
static const int mRejectCost = 1; // The cost of having a connection disconnected static const int mRejectCost = 1; // The cost of having a connection disconnected
@@ -120,6 +148,7 @@ private:
typedef std::map<std::string, iBlackList> BlackListTable; typedef std::map<std::string, iBlackList> BlackListTable;
BlackListTable mList; BlackListTable mList;
std::vector<std::string> mWhiteList;
boost::mutex mMutex; boost::mutex mMutex;
bool chargeEntry(const std::string& source, int charge) bool chargeEntry(const std::string& source, int charge)

View File

@@ -69,6 +69,7 @@ using namespace beast;
#include "containers/KeyCache.h" #include "containers/KeyCache.h"
#include "containers/RangeSet.h" #include "containers/RangeSet.h"
#include "containers/BlackList.h"
#include "containers/TaggedCache.h" #include "containers/TaggedCache.h"
} }

View File

@@ -63,8 +63,9 @@ public:
/** Construct a load source with a given name. /** Construct a load source with a given name.
The endpoint is considered non-privileged. The endpoint is considered non-privileged.
*/ */
explicit LoadSource (std::string const& name) explicit LoadSource (std::string const& name, std::string const& costName)
: mName (name) : mName (name)
, mCostName (costName)
, mBalance (0) , mBalance (0)
, mFlags (0) , mFlags (0)
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ()) , mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
@@ -81,9 +82,10 @@ public:
// VFALCO TODO Figure out a way to construct the LoadSource object with // VFALCO TODO Figure out a way to construct the LoadSource object with
// the proper name instead of renaming it later. // the proper name instead of renaming it later.
// //
void rename (std::string const& name) noexcept void rename (std::string const& name, std::string const& costName) noexcept
{ {
mName = name; mName = name;
mCostName = costName;
} }
/** Retrieve the name of this endpoint. /** Retrieve the name of this endpoint.
@@ -93,6 +95,11 @@ public:
return mName; return mName;
} }
std::string const& getCostName () const noexcept
{
return mCostName;
}
/** Determine if this endpoint is privileged. /** Determine if this endpoint is privileged.
*/ */
bool isPrivileged () const noexcept bool isPrivileged () const noexcept
@@ -154,7 +161,8 @@ private:
static const int lsfOutbound = 2; static const int lsfOutbound = 2;
private: private:
std::string mName; std::string mName; // Name of this particular load source, can include details like ports
std::string mCostName; // The name to "charge" for load from this connection
int mBalance; int mBalance;
int mFlags; int mFlags;
int mLastUpdate; int mLastUpdate;