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__);
@@ -159,12 +159,14 @@ private:
source.mLastWarning = now;
}
mBlackList.doWarning(source.getCostName ());
logWarning (source.getName ());
return true;
}
bool shouldCutoff (LoadSource& source) const
bool shouldCutoff (LoadSource& source)
{
bool bLogged;
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
@@ -173,15 +175,22 @@ private:
if (source.isPrivileged () || (source.mBalance > mDebitLimit))
return false;
if (source.mLogged)
return true;
bLogged = source.mLogged;
source.mLogged = true;
}
logDisconnect (source.getName ());
mBlackList.doDisconnect (source.getName ());
if (!bLogged)
logDisconnect (source.getName ());
return true;
}
bool shouldAllow (LoadSource& source)
{
return mBlackList.isAllowed (source.getCostName ());
}
bool applyLoadCharge (LoadSource& source, LoadType loadType) const
{
// FIXME: Scale by category
@@ -230,6 +239,17 @@ private:
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
//Cost const& getCost (LoadType loadType) const;
int getCost (LoadType t) const
@@ -415,6 +435,8 @@ private:
beast::ThreadWithCallQueue m_logThread;
BlackList<UptimeTimerAdapter> mBlackList;
int mCreditRate; // credits gained/lost per second
int mCreditLimit; // the most credits a source can have
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()
// return a LoadSource::Disposition
//
virtual bool shouldWarn (LoadSource&) const = 0;
virtual bool shouldCutoff (LoadSource&) const = 0;
virtual bool shouldWarn (LoadSource&) = 0;
virtual bool shouldCutoff (LoadSource&) = 0;
virtual Json::Value getBlackList(int threshold = (BlackList<UptimeTimerAdapter>::mCreditLimit / 2)) = 0;
};
#endif

View File

@@ -71,7 +71,7 @@ public:
, mCluster (false)
, mPeerId (peerID)
, mPrivate (false)
, mLoad (std::string())
, mLoad (std::string(), std::string())
, mMinLedger (0)
, mMaxLedger (0)
, 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)
{
mIpPort = make_pair (strIP, iPort);
mLoad.rename (strIP);
mLoad.rename (strIP + lexicalCast<std::string>(iPort), strIP);
WriteLog (lsDEBUG, Peer) << "Peer: Set: "
<< addressToString (this) << "> "
@@ -1085,7 +1085,7 @@ void PeerImp::recvHello (protocol::TMHello& packet)
mCluster = true;
mLoad.setPrivileged ();
if (!mNodeName.empty())
mLoad.rename (mNodeName);
mLoad.rename (mNodeName, mNodeName);
WriteLog (lsINFO, Peer) << "Cluster connection to \"" << (mNodeName.empty () ? getIP () : mNodeName)
<< "\" established";
}

View File

@@ -608,6 +608,15 @@ Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, A
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>,
// port: <number>
@@ -3774,6 +3783,7 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{ "account_lines", &RPCHandler::doAccountLines, false, optCurrent },
{ "account_offers", &RPCHandler::doAccountOffers, false, optCurrent },
{ "account_tx", &RPCHandler::doAccountTxSwitch, false, optNetwork },
{ "blacklist", &RPCHandler::doBlackList, true, optNone },
{ "book_offers", &RPCHandler::doBookOffers, false, optCurrent },
{ "connect", &RPCHandler::doConnect, 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 doAccountTxOld (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 doConsensusInfo (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")
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,
@@ -15,7 +21,7 @@ WSConnection::WSConnection (InfoSub::Source& source, bool isPublic,
, m_remoteIP (remoteIP)
, m_receiveQueueMutex (this, "WSConnection", __FILE__, __LINE__)
, m_netOPs (getApp ().getOPs ())
, m_loadSource (m_remoteIP)
, m_loadSource (m_remoteIP, trimIP(m_remoteIP))
, m_pingTimer (io_service)
, m_sentPing (false)
, m_receiveQueueRunning (false)

View File

@@ -10,8 +10,11 @@ class BlackList
int mBalance; // Exponentially-decaying "cost" balance
int mLastUpdate; // The uptime when the balance was last decayed
iBlackList(int now) : mBalance(0), mLastUpdate(now) { ; }
iBlackList() : mBalance(0), mLastUpdate(0) { ; }
iBlackList(int now) : mBalance(0), mLastUpdate(now)
{ ; }
iBlackList() : mBalance(0), mLastUpdate(0)
{ ; }
};
public:
@@ -21,7 +24,11 @@ public:
typedef std::vector<BlackListEntry> BlackListEntryList;
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
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 mDiscCost = 100; // The cost of being disconnected for abuse
static const int mRejectCost = 1; // The cost of having a connection disconnected
@@ -119,8 +147,9 @@ private:
typedef std::map<std::string, iBlackList> BlackListTable;
BlackListTable mList;
boost::mutex mMutex;
BlackListTable mList;
std::vector<std::string> mWhiteList;
boost::mutex mMutex;
bool chargeEntry(const std::string& source, int charge)
{

View File

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

View File

@@ -63,8 +63,9 @@ public:
/** Construct a load source with a given name.
The endpoint is considered non-privileged.
*/
explicit LoadSource (std::string const& name)
explicit LoadSource (std::string const& name, std::string const& costName)
: mName (name)
, mCostName (costName)
, mBalance (0)
, mFlags (0)
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
@@ -81,9 +82,10 @@ public:
// VFALCO TODO Figure out a way to construct the LoadSource object with
// 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;
mCostName = costName;
}
/** Retrieve the name of this endpoint.
@@ -93,6 +95,11 @@ public:
return mName;
}
std::string const& getCostName () const noexcept
{
return mCostName;
}
/** Determine if this endpoint is privileged.
*/
bool isPrivileged () const noexcept
@@ -154,7 +161,8 @@ private:
static const int lsfOutbound = 2;
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 mFlags;
int mLastUpdate;