New ResourceManager for managing server load.

* Track abusive endpoints
* Gossip across cluster.
* Use resource manager's gossip support to share load reporting across a cluster
* Swtich from legacy fees to new Resource::Charge fees.
* Connect RPC to the new resource manager.
* Set load levels where needed in RPC/websocket commands.
* Disconnect abusive peer endpoints.
* Don't start conversations with abusive peer endpoints.
* Move Resource::Consumer to InfoSub and remove LoadSource
* Remove port from inbound Consumer keys
* Add details in getJson
* Fix doAccountCurrencies for the new resource manager.
This commit is contained in:
David Schwartz
2013-10-29 17:35:47 -07:00
committed by Vinnie Falco
parent a05f33f6a7
commit 58f07a573f
48 changed files with 665 additions and 759 deletions

View File

@@ -1926,7 +1926,6 @@
<ClInclude Include="..\..\src\ripple_basics\utility\ThreadName.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\Time.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\UptimeTimer.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h" />
<ClInclude Include="..\..\src\ripple_core\functional\Config.h" />
<ClInclude Include="..\..\src\ripple_core\functional\ConfigSections.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h" />

View File

@@ -1706,9 +1706,6 @@
<ClInclude Include="..\..\src\ripple_app\peers\Peers.h">
<Filter>[2] Old Ripple\ripple_app\peers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_app\main\LoadManager.h">
<Filter>[2] Old Ripple\ripple_app\main</Filter>
</ClInclude>

View File

@@ -197,11 +197,4 @@
#define RIPPLE_USE_RPC_SERVICE_MANAGER 0
#endif
// Here temporarily
// Controls whether or not the new Resource manager replaces the BlackList
// and LoadManager for measuring and controlling access to the server
#ifndef RIPPLE_USE_RESOURCE_MANAGER
#define RIPPLE_USE_RESOURCE_MANAGER 0
#endif
#endif

View File

@@ -47,6 +47,9 @@ public:
/** Converts this charge into a human readable string. */
std::string to_string () const;
bool operator== (Charge const&) const;
bool operator!= (Charge const&) const;
private:
value_type m_cost;
std::string m_label;

View File

@@ -46,6 +46,10 @@ public:
/** Extract packaged consumer information for export. */
virtual Gossip exportConsumers () = 0;
/** Extract consumer information for reporting. */
virtual Json::Value getJson () = 0;
virtual Json::Value getJson (int threshold) = 0;
/** Import packaged consumer information.
@param origin An identifier that unique labels the origin.
*/

View File

@@ -56,5 +56,15 @@ std::ostream& operator<< (std::ostream& os, Charge const& v)
return os;
}
bool Charge::operator== (Charge const& c) const
{
return c.m_cost == m_cost;
}
bool Charge::operator!= (Charge const& c) const
{
return c.m_cost != m_cost;
}
}
}

View File

@@ -87,11 +87,15 @@ std::string Consumer::to_string () const
bool Consumer::admin () const
{
return m_entry->admin();
if (m_entry != nullptr)
return m_entry->admin();
return false;
}
void Consumer::elevate (std::string const& name)
{
bassert (m_entry != nullptr);
m_entry = &m_logic->elevateToAdminEndpoint (*m_entry, name);
}
@@ -102,26 +106,31 @@ Disposition Consumer::disposition() const
Disposition Consumer::charge (Charge const& what)
{
bassert (m_entry != nullptr);
return m_logic->charge (*m_entry, what);
}
bool Consumer::warn ()
{
bassert (m_entry != nullptr);
return m_logic->warn (*m_entry);
}
bool Consumer::disconnect ()
{
bassert (m_entry != nullptr);
return m_logic->disconnect (*m_entry);
}
int Consumer::balance()
{
bassert (m_entry != nullptr);
return m_logic->balance (*m_entry);
}
Entry& Consumer::entry()
{
bassert (m_entry != nullptr);
return *m_entry;
}

View File

@@ -83,7 +83,7 @@ public:
Key key;
key.kind = kindInbound;
key.address = address;
key.address = address.withPort (0);
Entry* entry (nullptr);
@@ -202,6 +202,61 @@ public:
return *entry;
}
Json::Value getJson ()
{
return getJson (warningThreshold);
}
Json::Value getJson (int threshold)
{
DiscreteTime const now (m_clock());
Json::Value ret (Json::objectValue);
SharedState::Access state (m_state);
for (List <Entry>::iterator iter (state->inbound.begin());
iter != state->inbound.end(); ++iter)
{
int localBalance = iter->local_balance.value (now);
if ((localBalance + iter->remote_balance) >= threshold)
{
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
entry["local"] = localBalance;
entry["remote"] = iter->remote_balance;
entry["type"] = "outbound";
}
}
for (List <Entry>::iterator iter (state->outbound.begin());
iter != state->outbound.end(); ++iter)
{
int localBalance = iter->local_balance.value (now);
if ((localBalance + iter->remote_balance) >= threshold)
{
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
entry["local"] = localBalance;
entry["remote"] = iter->remote_balance;
entry["type"] = "outbound";
}
}
for (List <Entry>::iterator iter (state->admin.begin());
iter != state->admin.end(); ++iter)
{
int localBalance = iter->local_balance.value (now);
if ((localBalance + iter->remote_balance) >= threshold)
{
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
entry["local"] = localBalance;
entry["remote"] = iter->remote_balance;
entry["type"] = "admin";
}
}
return ret;
}
Gossip exportConsumers ()
{
DiscreteTime const now (m_clock());
@@ -318,8 +373,8 @@ public:
}
}
for (Imports::iterator iter (state->import_table.begin());
iter != state->import_table.end(); ++iter)
Imports::iterator iter (state->import_table.begin());
while (iter != state->import_table.end())
{
Import& import (iter->second);
if (iter->second.whenExpires <= now)
@@ -332,6 +387,8 @@ public:
iter = state->import_table.erase (iter);
}
else
++iter;
}
}

View File

@@ -68,6 +68,18 @@ public:
//--------------------------------------------------------------------------
Json::Value getJson ()
{
return m_logic.getJson ();
}
Json::Value getJson (int threshold)
{
return m_logic.getJson (threshold);
}
//--------------------------------------------------------------------------
void onWrite (PropertyStream::Map& map)
{
m_logic.onWrite (map);

View File

@@ -26,6 +26,8 @@ namespace ripple {
using namespace beast;
}
#include "../json/ripple_json.h"
# include "api/Types.h"
# include "api/Disposition.h"
# include "api/Charge.h"

View File

@@ -130,7 +130,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
if (peer)
{
peer->charge (Resource::feeInvalidRequest);
peer->applyLoadCharge (LT_InvalidRequest);
}
return;
@@ -147,7 +146,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
{
WriteLog (lsWARNING, InboundLedger) << "Got empty base data";
peer->charge (Resource::feeInvalidRequest);
peer->applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -155,7 +153,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
{
WriteLog (lsWARNING, InboundLedger) << "Got invalid base data";
peer->charge (Resource::feeInvalidRequest);
peer->applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -191,7 +188,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
{
WriteLog (lsINFO, InboundLedger) << "Got response with no nodes";
peer->charge (Resource::feeInvalidRequest);
peer->applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -203,7 +199,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
{
WriteLog (lsWARNING, InboundLedger) << "Got bad node";
peer->charge (Resource::feeInvalidRequest);
peer->applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -231,7 +226,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
WriteLog (lsWARNING, InboundLedger) << "Not sure what ledger data we got";
peer->charge (Resource::feeInvalidRequest);
peer->applyLoadCharge (LT_InvalidRequest);
}
void InboundLedgers::sweep ()

View File

@@ -110,10 +110,10 @@ public:
, m_deprecatedUNL (UniqueNodeList::New (*m_jobQueue))
, m_rpcHTTPServer (RPCHTTPServer::New (*m_networkOPs,
LogJournal::get <HTTPServerLog> (), *m_jobQueue, *m_networkOPs))
LogJournal::get <HTTPServerLog> (), *m_jobQueue, *m_networkOPs, *m_resourceManager))
#if ! RIPPLE_USE_RPC_SERVICE_MANAGER
, m_rpcServerHandler (*m_networkOPs) // passive object, not a Service
, m_rpcServerHandler (*m_networkOPs, *m_resourceManager) // passive object, not a Service
#endif
, m_nodeStoreScheduler (*m_jobQueue, *m_jobQueue)
@@ -228,6 +228,11 @@ public:
return *m_loadManager;
}
Resource::Manager& getResourceManager ()
{
return *m_resourceManager;
}
TxQueue& getTxQueue ()
{
return *m_txQueue;
@@ -537,7 +542,7 @@ public:
{
m_wsPrivateDoor = WSDoor::New (*m_resourceManager,
getOPs(), getConfig ().WEBSOCKET_IP,
getConfig ().WEBSOCKET_PORT, false,
getConfig ().WEBSOCKET_PORT, false, false,
m_wsSSLContext->get ());
if (m_wsPrivateDoor == nullptr)
@@ -557,7 +562,7 @@ public:
{
m_wsPublicDoor = WSDoor::New (*m_resourceManager,
getOPs(), getConfig ().WEBSOCKET_PUBLIC_IP,
getConfig ().WEBSOCKET_PUBLIC_PORT, true,
getConfig ().WEBSOCKET_PUBLIC_PORT, true, false,
m_wsSSLContext->get ());
if (m_wsPublicDoor == nullptr)
@@ -570,6 +575,19 @@ public:
{
m_journal.info << "WebSocket public interface: disabled";
}
if (!getConfig ().WEBSOCKET_PROXY_IP.empty () && getConfig ().WEBSOCKET_PROXY_PORT)
{
m_wsProxyDoor = WSDoor::New (*m_resourceManager,
getOPs(), getConfig ().WEBSOCKET_PROXY_IP,
getConfig ().WEBSOCKET_PROXY_PORT, true, true,
m_wsSSLContext->get ());
if (m_wsProxyDoor == nullptr)
{
FatalError ("Could not open the WebSocket public interface.",
__FILE__, __LINE__);
}
}
//
//
@@ -744,6 +762,7 @@ public:
// once the WSDoor cancels its pending I/O correctly
//m_wsPublicDoor = nullptr;
//m_wsPrivateDoor = nullptr;
//m_wsProxyDoor = nullptr;
// VFALCO TODO Try to not have to do this early, by using observers to
// eliminate LoadManager's dependency inversions.
@@ -898,6 +917,7 @@ private:
ScopedPointer <RPCDoor> m_rpcDoor;
ScopedPointer <WSDoor> m_wsPublicDoor;
ScopedPointer <WSDoor> m_wsPrivateDoor;
ScopedPointer <WSDoor> m_wsProxyDoor;
WaitableEvent m_stop;
};

View File

@@ -102,6 +102,7 @@ public:
virtual TransactionMaster& getMasterTransaction () = 0;
virtual TxQueue& getTxQueue () = 0;
virtual LocalCredentials& getLocalCredentials () = 0;
virtual Resource::Manager& getResourceManager () = 0;
virtual DatabaseCon* getRpcDB () = 0;
virtual DatabaseCon* getTxnDB () = 0;

View File

@@ -74,13 +74,6 @@ public:
typedef LockType::ScopedLockType ScopedLockType;
LockType mLock;
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
int mDebitLimit; // when a source drops below this, we cut it off (should be negative)
bool mArmed;
int mDeadLock; // Detect server deadlocks
@@ -94,52 +87,10 @@ public:
, Thread ("loadmgr")
, m_journal (journal)
, mLock (this, "LoadManagerImp", __FILE__, __LINE__)
, mCreditRate (100)
, mCreditLimit (500)
, mDebitWarn (-500)
, mDebitLimit (-1000)
, mArmed (false)
, mDeadLock (0)
, mCosts (LT_MAX)
{
/** Flags indicating the type of load.
Utilization may include any combination of:
- CPU
- Storage space
- Network transfer
*/
// VFALCO NOTE These flags are not used...
enum
{
flagDisk = 1,
flagCpu = 2,
flagNet = 4
};
// VFALCO TODO Replace this with a function that uses a simple switch statement...
//
addCost (Cost (LT_InvalidRequest, -10, flagCpu | flagNet));
addCost (Cost (LT_RequestNoReply, -1, flagCpu | flagDisk));
addCost (Cost (LT_InvalidSignature, -100, flagCpu));
addCost (Cost (LT_UnwantedData, -5, flagCpu | flagNet));
addCost (Cost (LT_BadData, -20, flagCpu));
addCost (Cost (LT_RPCInvalid, -10, flagCpu | flagNet));
addCost (Cost (LT_RPCReference, -10, flagCpu | flagNet));
addCost (Cost (LT_RPCException, -20, flagCpu | flagNet));
addCost (Cost (LT_RPCBurden, -50, flagCpu | flagNet));
// VFALCO NOTE Why do these supposedly "good" load types still have a negative cost?
//
addCost (Cost (LT_NewTrusted, -10, 0));
addCost (Cost (LT_NewTransaction, -2, 0));
addCost (Cost (LT_NeededData, -10, 0));
addCost (Cost (LT_RequestData, -5, flagDisk | flagNet));
addCost (Cost (LT_CheapQuery, -1, flagCpu));
UptimeTimer::getInstance ().beginManualUpdates ();
}
@@ -154,6 +105,7 @@ public:
//
// Stoppable
//
//--------------------------------------------------------------------------
void onPrepare ()
{
@@ -180,136 +132,6 @@ public:
//--------------------------------------------------------------------------
void canonicalize (LoadSource& source, int now) const
{
if (source.mLastUpdate != now)
{
if (source.mLastUpdate < now)
{
source.mBalance += mCreditRate * (now - source.mLastUpdate);
if (source.mBalance > mCreditLimit)
{
source.mBalance = mCreditLimit;
source.mLogged = false;
}
}
source.mLastUpdate = now;
}
}
bool shouldWarn (LoadSource& source)
{
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
canonicalize (source, now);
if (source.isPrivileged () || (source.mBalance > mDebitWarn) || (source.mLastWarning == now))
return false;
source.mLastWarning = now;
}
mBlackList.doWarning(source.getCostName ());
logWarning (source.getName ());
return true;
}
bool shouldCutoff (LoadSource& source)
{
bool bLogged;
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
canonicalize (source, now);
if (source.isPrivileged () || (source.mBalance > mDebitLimit))
return false;
bLogged = source.mLogged;
source.mLogged = true;
}
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
Cost cost = mCosts[static_cast<int> (loadType)];
return adjust (source, cost.m_cost);
}
bool adjust (LoadSource& source, int credits) const
{
// return: true = need to warn/cutoff
// We do it this way in case we want to add exponential decay later
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
ScopedLockType sl (mLock, __FILE__, __LINE__);
canonicalize (source, now);
source.mBalance += credits;
if (source.mBalance > mCreditLimit)
source.mBalance = mCreditLimit;
if (source.isPrivileged ()) // privileged sources never warn/cutoff
return false;
if ( (source.mBalance >= mDebitWarn) ||
((source.mBalance >= mDebitLimit) && (source.mLastWarning == now)))
return false;
return true;
}
void logWarning (const std::string& source) const
{
if (source.empty ())
m_journal.debug << "Load warning from empty source";
else
m_journal.info << "Load warning: " << source;
}
void logDisconnect (const std::string& source) const
{
if (source.empty ())
m_journal.info << "Disconnect for empty source";
else
m_journal.warning << "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
{
return mCosts [static_cast <int> (t)].getCost ();
}
void resetDeadlockDetector ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
@@ -337,11 +159,6 @@ public:
#endif
}
void addCost (const Cost& c)
{
mCosts [static_cast <int> (c.getLoadType ())] = c;
}
// VFALCO NOTE Where's the thread object? It's not a data member...
//
void run ()

View File

@@ -72,23 +72,6 @@ public:
time passes it will produce log warnings.
*/
virtual void resetDeadlockDetector () = 0;
/** Update an endpoint to reflect an imposed load.
The balance of the endpoint is adjusted based on the heuristic cost
of the indicated load.
@return `true` if the endpoint should be warned or punished.
*/
virtual bool applyLoadCharge (LoadSource& sourceToAdjust, LoadType loadToImpose) const = 0;
// VFALCO TODO Eliminate these two functions and just make applyLoadCharge()
// return a LoadSource::Disposition
//
virtual bool shouldWarn (LoadSource&) = 0;
virtual bool shouldCutoff (LoadSource&) = 0;
virtual Json::Value getBlackList(int threshold = (BlackList<UptimeTimerAdapter>::mCreditLimit / 2)) = 0;
};
#endif

View File

@@ -24,6 +24,7 @@ class RPCHTTPServerImp
, public HTTP::Handler
{
public:
Resource::Manager& m_resourceManager;
Journal m_journal;
JobQueue& m_jobQueue;
NetworkOPs& m_networkOPs;
@@ -34,12 +35,14 @@ public:
RPCHTTPServerImp (Stoppable& parent,
Journal journal,
JobQueue& jobQueue,
NetworkOPs& networkOPs)
NetworkOPs& networkOPs,
Resource::Manager& resourceManager)
: RPCHTTPServer (parent)
, m_resourceManager (resourceManager)
, m_journal (journal)
, m_jobQueue (jobQueue)
, m_networkOPs (networkOPs)
, m_deprecatedHandler (networkOPs)
, m_deprecatedHandler (networkOPs, resourceManager)
, m_server (*this, journal)
{
if (getConfig ().RPC_SECURE == 0)
@@ -186,6 +189,16 @@ public:
Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));
Resource::Consumer usage;
if (role == Config::ADMIN)
usage = m_resourceManager.newAdminEndpoint(remoteAddress);
else
usage = m_resourceManager.newInboundEndpoint(IPAddress::from_string(remoteAddress));
if (usage.disconnect ())
return createResponse (503, "Server is overloaded");
// Parse id now so errors from here on will have the id
//
// VFALCO NOTE Except that "id" isn't included in the following errors...
@@ -241,11 +254,12 @@ public:
RPCHandler rpcHandler (&m_networkOPs);
LoadType loadType = LT_RPCReference;
Resource::Charge loadType = Resource::feeReferenceRPC;
Json::Value const result (rpcHandler.doRpcCommand (
strMethod, params, role, &loadType));
// VFALCO NOTE We discard loadType since there is no endpoint to punish
strMethod, params, role, loadType));
usage.charge (loadType);
m_journal.debug << "Reply: " << result;
@@ -267,8 +281,9 @@ RPCHTTPServer::RPCHTTPServer (Stoppable& parent)
RPCHTTPServer* RPCHTTPServer::New (Stoppable& parent,
Journal journal,
JobQueue& jobQueue,
NetworkOPs& networkOPs)
NetworkOPs& networkOPs,
Resource::Manager& resourceManager)
{
return new RPCHTTPServerImp (parent, journal, jobQueue, networkOPs);
return new RPCHTTPServerImp (parent, journal, jobQueue, networkOPs, resourceManager);
}

View File

@@ -27,7 +27,7 @@ protected:
public:
static RPCHTTPServer* New (Stoppable& parent,
Journal journal, JobQueue& jobQueue, NetworkOPs& networkOPs);
Journal journal, JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager);
virtual ~RPCHTTPServer () { }

View File

@@ -60,9 +60,8 @@ void startServer ()
RPCHandler rhHandler (&getApp().getOPs ());
// VFALCO TODO Clean up this magic number
LoadType loadType = LT_RPCReference;
Json::Value jvResult = rhHandler.doCommand (jvCommand, Config::ADMIN, &loadType);
Resource::Charge loadType = Resource::feeReferenceRPC;
Json::Value jvResult = rhHandler.doCommand (jvCommand, Config::ADMIN, loadType);
if (!getConfig ().QUIET)
Log::out() << "Result: " << jvResult;

View File

@@ -567,6 +567,14 @@ void NetworkOPsImp::processClusterTimer ()
node.set_nodename(it->second.getName());
}
Resource::Gossip gossip = getApp().getResourceManager().exportConsumers();
BOOST_FOREACH (Resource::Gossip::Item const& item, gossip.items)
{
protocol::TMLoadSource& node = *cluster.add_loadsources();
node.set_name (item.address);
node.set_cost (item.balance);
}
PackedMessage::pointer message = boost::make_shared<PackedMessage>(cluster, protocol::mtCLUSTER);
getApp().getPeers().relayMessageCluster (NULL, message);

View File

@@ -76,7 +76,6 @@ public:
, mCluster (false)
, mPeerId (peerID)
, mPrivate (false)
, mLoad (std::string(), std::string())
, mMinLedger (0)
, mMaxLedger (0)
, mActivityTimer (io_service)
@@ -99,7 +98,6 @@ private:
uint256 mCookieHash;
uint64 mPeerId;
bool mPrivate; // Keep peer IP private.
LoadSource mLoad;
uint32 mMinLedger, mMaxLedger;
uint256 mClosedLedgerHash;
@@ -165,11 +163,10 @@ public:
void charge (Resource::Charge const& fee)
{
m_usage.charge (fee);
if ((m_usage.charge (fee) == Resource::drop) && m_usage.disconnect ())
detach ("resource", false);
}
void applyLoadCharge (LoadType);
Json::Value getJson ();
bool isConnected () const
{
@@ -308,6 +305,7 @@ private:
}
else
{
bool valid = false;
if (m_socket->getFlags ().set (MultiSocket::Flag::proxy) && m_isInbound)
{
@@ -332,11 +330,7 @@ private:
else
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
getApp ().getPeers ().peerConnected(m_remoteAddress, m_isInbound);
// Must compute mCookieHash before receiving a hello.
sendHello ();
startReadHeader ();
valid = true;
WriteLog (lsINFO, Peer) << "Peer: PROXY handshake from " << mIpPort.first;
}
@@ -380,12 +374,25 @@ private:
else
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
getApp ().getPeers ().peerConnected(m_remoteAddress, m_isInbound);
// Must compute mCookieHash before receiving a hello.
sendHello ();
startReadHeader ();
valid = true;
}
if (valid)
{
if (m_usage.disconnect ())
{
detach ("resource", true);
}
else
{
getApp ().getPeers ().peerConnected(m_remoteAddress, m_isInbound);
// Must compute mCookieHash before receiving a hello.
sendHello ();
startReadHeader ();
}
}
}
}
@@ -469,7 +476,6 @@ 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 + lexicalCast<std::string>(iPort), strIP);
WriteLog (lsDEBUG, Peer) << "Peer: Set: "
<< addressToString (this) << "> "
@@ -1163,16 +1169,10 @@ void PeerImp::recvHello (protocol::TMHello& packet)
if (getApp().getUNL ().nodeInCluster (mNodePublic, mNodeName))
{
mCluster = true;
mLoad.setPrivileged ();
if (!mNodeName.empty())
mLoad.rename (mNodeName, mNodeName);
WriteLog (lsINFO, Peer) << "Cluster connection to \"" << (mNodeName.empty () ? getIP () : mNodeName)
<< "\" established";
}
if (isOutbound ())
mLoad.setOutbound ();
if (mClientConnect)
{
// If we connected due to scan, no longer need to scan.
@@ -1268,7 +1268,6 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
{
getApp().getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD);
Peer::charge (peer, Resource::feeInvalidSignature);
Peer::applyLoadCharge (peer, LT_InvalidSignature);
return;
}
else
@@ -1282,7 +1281,6 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
{
getApp().getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD);
Peer::charge (peer, Resource::feeInvalidRequest);
Peer::applyLoadCharge (peer, LT_InvalidRequest);
}
#endif
@@ -1310,7 +1308,6 @@ void PeerImp::recvTransaction (protocol::TMTransaction& packet, Application::Sco
if (isSetBit (flags, SF_BAD))
{
charge (Resource::feeInvalidSignature);
applyLoadCharge (LT_InvalidSignature);
return;
}
@@ -1375,7 +1372,6 @@ static void checkPropose (Job& job, boost::shared_ptr<protocol::TMProposeSet> pa
WriteLog (lsWARNING, Peer) << "proposal with previous ledger fails signature check: " <<
(p ? p->getIP () : std::string ("???"));
Peer::charge (peer, Resource::feeInvalidSignature);
Peer::applyLoadCharge (peer, LT_InvalidSignature);
return;
}
else
@@ -1420,7 +1416,6 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
{
WriteLog (lsWARNING, Peer) << "Received proposal is malformed";
charge (Resource::feeInvalidSignature);
applyLoadCharge (LT_InvalidSignature);
return;
}
@@ -1428,7 +1423,6 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
{
WriteLog (lsWARNING, Peer) << "Received proposal is malformed";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -1490,7 +1484,6 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
if (packet.hash ().size () != (256 / 8))
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -1507,7 +1500,6 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
if (!getApp().getOPs ().hasTXSet (shared_from_this (), hash, packet.status ()))
{
charge (Resource::feeUnwantedData);
applyLoadCharge (LT_UnwantedData);
}
}
@@ -1524,7 +1516,6 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
{
WriteLog (lsWARNING, Peer) << "Validation is invalid";
Peer::charge (peer, Resource::feeInvalidRequest);
Peer::applyLoadCharge (peer, LT_InvalidRequest);
return;
}
@@ -1563,7 +1554,6 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
{
WriteLog (lsWARNING, Peer) << "Exception processing validation";
Peer::charge (peer, Resource::feeInvalidRequest);
Peer::applyLoadCharge (peer, LT_InvalidRequest);
}
#endif
@@ -1578,7 +1568,6 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
{
WriteLog (lsWARNING, Peer) << "Too small validation from peer";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -1595,7 +1584,6 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
{
WriteLog (lsTRACE, Peer) << "Validation is more than two minutes old";
charge (Resource::feeUnwantedData);
applyLoadCharge (LT_UnwantedData);
return;
}
@@ -1619,7 +1607,6 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
{
WriteLog (lsWARNING, Peer) << "Exception processing validation";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
}
#endif
@@ -1630,7 +1617,6 @@ void PeerImp::recvCluster (protocol::TMCluster& packet)
if (!mCluster)
{
charge (Resource::feeUnwantedData);
applyLoadCharge(LT_UnwantedData);
return;
}
@@ -1649,6 +1635,23 @@ void PeerImp::recvCluster (protocol::TMCluster& packet)
getApp().getUNL().nodeUpdate(nodePub, s);
}
int loadSources = packet.loadsources().size();
if (loadSources != 0)
{
Resource::Gossip gossip;
gossip.items.reserve (loadSources);
for (int i = 0; i < packet.loadsources().size(); ++i)
{
protocol::TMLoadSource const& node = packet.loadsources (i);
Resource::Gossip::Item item;
item.address = IPAddress::from_string (node.name());
item.balance = node.cost();
if (item.address != IPAddress())
gossip.items.push_back(item);
}
m_resourceManager.importConsumers (mNodeName, gossip);
}
getApp().getFeeTrack().setClusterFee(getApp().getUNL().getClusterFee());
}
@@ -1926,7 +1929,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
if (packet.response ().size () != (256 / 8))
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -1946,7 +1948,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
if (r != powTOOEASY)
{
charge (Resource::feeBadProofOfWork);
applyLoadCharge (LT_BadPoW);
}
return;
@@ -1968,7 +1969,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
if ((packet.challenge ().size () != (256 / 8)) || (packet.target ().size () != (256 / 8)))
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -1980,7 +1980,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
if (!pow->isValid ())
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2078,7 +2077,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
if ((!packet.has_ledgerhash () || packet.ledgerhash ().size () != 32))
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
WriteLog (lsWARNING, Peer) << "invalid request for TX candidate set data";
return;
}
@@ -2115,7 +2113,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
WriteLog (lsERROR, Peer) << "We do not have the map our peer wants " << getIP ();
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2144,7 +2141,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
if (packet.ledgerhash ().size () != 32)
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
WriteLog (lsWARNING, Peer) << "Invalid request";
return;
}
@@ -2201,7 +2197,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
else
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
WriteLog (lsWARNING, Peer) << "Can't figure out what ledger they want";
return;
}
@@ -2209,7 +2204,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
if ((!ledger) || (packet.has_ledgerseq () && (packet.ledgerseq () != ledger->getLedgerSeq ())))
{
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
if (ShouldLog (lsWARNING, Peer))
{
@@ -2290,7 +2284,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
{
WriteLog (lsWARNING, Peer) << "Can't find map or empty request";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2304,7 +2297,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
{
WriteLog (lsWARNING, Peer) << "Request for invalid node: " << logMe;
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2366,7 +2358,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
{
WriteLog (lsWARNING, Peer) << "Ledger/TXset data with no nodes";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2383,7 +2374,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
{
WriteLog (lsINFO, Peer) << "Unable to route TX/ledger data reply";
charge (Resource::feeUnwantedData);
applyLoadCharge (LT_UnwantedData);
}
return;
@@ -2395,7 +2385,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
{
WriteLog (lsWARNING, Peer) << "TX candidate reply with invalid hash size";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2415,7 +2404,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
{
WriteLog (lsWARNING, Peer) << "LedgerData request with invalid node ID";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2428,7 +2416,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
if (san.isInvalid ())
{
charge (Resource::feeUnwantedData);
applyLoadCharge (LT_UnwantedData);
}
return;
@@ -2443,7 +2430,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
else
{
charge (Resource::feeUnwantedData);
applyLoadCharge (LT_UnwantedData);
}
}
@@ -2589,33 +2575,6 @@ void PeerImp::sendGetPeers ()
sendPacket (packet, true);
}
void PeerImp::applyLoadCharge (LoadType loadType)
{
// IMPLEMENTATION IS INCOMPLETE
// VFALCO TODO This needs to completed before open sourcing.
if (getApp().getLoadManager ().applyLoadCharge (mLoad, loadType))
{
if (mCluster)
{
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " load from cluster";
}
else if (getApp().getLoadManager ().shouldCutoff(mLoad))
{
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " should cutoff";
}
else if (getApp().getLoadManager ().shouldWarn (mLoad))
{
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " load warning";
}
else
{
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " cannot figure out";
}
}
}
void PeerImp::doProofOfWork (Job&, boost::weak_ptr <Peer> peer, ProofOfWork::pointer pow)
{
if (peer.expired ())
@@ -2658,7 +2617,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
{
WriteLog (lsWARNING, Peer) << "FetchPack hash size malformed";
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2671,7 +2629,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
{
WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger we don't have: " << hash;
charge (Resource::feeRequestNoReply);
applyLoadCharge (LT_RequestNoReply);
return;
}
@@ -2679,7 +2636,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
{
WriteLog (lsWARNING, Peer) << "Peer requests fetch pack from open ledger: " << hash;
charge (Resource::feeInvalidRequest);
applyLoadCharge (LT_InvalidRequest);
return;
}
@@ -2689,7 +2645,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
{
WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger whose predecessor we don't have: " << hash;
charge (Resource::feeRequestNoReply);
applyLoadCharge (LT_RequestNoReply);
return;
}
@@ -2818,15 +2773,3 @@ void Peer::charge (boost::weak_ptr <Peer>& peer, Resource::Charge const& fee)
if (p != nullptr)
p->charge (fee);
}
void Peer::applyLoadCharge (boost::weak_ptr <Peer>& peerToPunish,
LoadType loadThatWasImposed)
{
Peer::pointer p = peerToPunish.lock ();
if (p != nullptr)
{
p->applyLoadCharge (loadThatWasImposed);
}
}

View File

@@ -76,8 +76,6 @@ public:
*/
virtual void charge (Resource::Charge const& fee) = 0;
static void charge (boost::weak_ptr <Peer>& peer, Resource::Charge const& fee);
virtual void applyLoadCharge (LoadType) = 0;
static void applyLoadCharge (boost::weak_ptr <Peer>& peerTOCharge, LoadType loadThatWasImposed);
virtual Json::Value getJson () = 0;

View File

@@ -208,7 +208,6 @@ public:
PeerFinder::PeerID (peer->getNodePublic()) == id)
{
peer->charge (Resource::feeUnwantedData);
peer->applyLoadCharge (LT_UnwantedData);
break;
}
}

View File

@@ -575,7 +575,7 @@ Json::Value RPCHandler::accountFromString (Ledger::ref lrLedger, RippleAddress&
return Json::Value (Json::objectValue);
}
Json::Value RPCHandler::doAccountCurrencies (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -641,7 +641,7 @@ Json::Value RPCHandler::doAccountCurrencies (Json::Value params, LoadType* loadT
// ledger_hash : <ledger>
// ledger_index : <ledger_index>
// }
Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -682,13 +682,13 @@ Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, A
return jvResult;
}
Json::Value RPCHandler::doBlackList (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doBlackList (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock();
if (params.isMember("threshold"))
return getApp().getLoadManager().getBlackList(params["threshold"].asInt());
return getApp().getResourceManager().getJson(params["threshold"].asInt());
else
return getApp().getLoadManager().getBlackList();
return getApp().getResourceManager().getJson();
}
// {
@@ -696,7 +696,7 @@ Json::Value RPCHandler::doBlackList (Json::Value params, LoadType* loadType, App
// port: <number>
// }
// XXX Might allow domain for manual connections.
Json::Value RPCHandler::doConnect (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doConnect (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (getConfig ().RUN_STANDALONE)
return "cannot connect in standalone mode";
@@ -717,7 +717,7 @@ Json::Value RPCHandler::doConnect (Json::Value params, LoadType* loadType, Appli
// {
// key: <string>
// }
Json::Value RPCHandler::doDataDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doDataDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("key"))
return rpcError (rpcINVALID_PARAMS);
@@ -743,7 +743,7 @@ Json::Value RPCHandler::doDataDelete (Json::Value params, LoadType* loadType, Ap
// {
// key: <string>
// }
Json::Value RPCHandler::doDataFetch (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doDataFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("key"))
return rpcError (rpcINVALID_PARAMS);
@@ -767,7 +767,7 @@ Json::Value RPCHandler::doDataFetch (Json::Value params, LoadType* loadType, App
// key: <string>
// value: <string>
// }
Json::Value RPCHandler::doDataStore (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doDataStore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("key")
|| !params.isMember ("value"))
@@ -828,7 +828,7 @@ Json::Value RPCHandler::doNicknameInfo (Json::Value params)
// 'account_index' : <index> // optional
// }
// XXX This would be better if it took the ledger.
Json::Value RPCHandler::doOwnerInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doOwnerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("account") && !params.isMember ("ident"))
return rpcError (rpcINVALID_PARAMS);
@@ -853,7 +853,7 @@ Json::Value RPCHandler::doOwnerInfo (Json::Value params, LoadType* loadType, App
return ret;
}
Json::Value RPCHandler::doPeers (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doPeers (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value jvResult (Json::objectValue);
@@ -864,12 +864,12 @@ Json::Value RPCHandler::doPeers (Json::Value, LoadType* loadType, Application::S
return jvResult;
}
Json::Value RPCHandler::doPing (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doPing (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
return Json::Value (Json::objectValue);
}
Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doPrint (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
@@ -887,7 +887,7 @@ Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Applica
// issuer is the offering account
// --> submit: 'submit|true|false': defaults to false
// Prior to running allow each to have a credit line of what they will be getting from the other account.
Json::Value RPCHandler::doProfile (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doProfile (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
/* need to fix now that sharedOfferCreate is gone
int iArgs = params.size();
@@ -979,7 +979,7 @@ Json::Value RPCHandler::doProfile (Json::Value params, LoadType* loadType, Appli
// difficulty: <number> // optional
// secret: <secret> // optional
// }
Json::Value RPCHandler::doProofCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doProofCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
// XXX: Add ability to create proof with arbitrary time
@@ -1024,7 +1024,7 @@ Json::Value RPCHandler::doProofCreate (Json::Value params, LoadType* loadType, A
// {
// token: <token>
// }
Json::Value RPCHandler::doProofSolve (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doProofSolve (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
@@ -1054,7 +1054,7 @@ Json::Value RPCHandler::doProofSolve (Json::Value params, LoadType* loadType, Ap
// difficulty: <number> // optional
// secret: <secret> // optional
// }
Json::Value RPCHandler::doProofVerify (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doProofVerify (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
// XXX Add ability to check proof against arbitrary time
@@ -1124,7 +1124,7 @@ Json::Value RPCHandler::doProofVerify (Json::Value params, LoadType* loadType, A
// ledger_hash : <ledger>
// ledger_index : <ledger_index>
// }
Json::Value RPCHandler::doAccountLines (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountLines (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -1215,6 +1215,7 @@ Json::Value RPCHandler::doAccountLines (Json::Value params, LoadType* loadType,
}
}
loadType = Resource::feeMediumBurdenRPC;
}
else
{
@@ -1242,7 +1243,7 @@ static void offerAdder (Json::Value& jvLines, SLE::ref offer)
// ledger_hash : <ledger>
// ledger_index : <ledger_index>
// }
Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -1287,6 +1288,7 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType,
if (!bUnlocked)
masterLockHolder.unlock ();
loadType = Resource::feeMediumBurdenRPC;
return jvResult;
}
@@ -1301,7 +1303,7 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType,
// "limit" : integer, // Optional.
// "proof" : boolean // Defaults to false.
// }
Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200)
{
@@ -1394,6 +1396,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, Ap
const Json::Value jvMarker = params.isMember ("marker") ? params["marker"] : Json::Value (Json::nullValue);
mNetOps->getBookPage (lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID (), bProof, iLimit, jvMarker, jvResult);
loadType = Resource::feeMediumBurdenRPC;
return jvResult;
}
@@ -1402,7 +1405,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, Ap
// {
// random: <uint256>
// }
Json::Value RPCHandler::doRandom (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doRandom (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
uint256 uRandom;
@@ -1423,7 +1426,7 @@ Json::Value RPCHandler::doRandom (Json::Value params, LoadType* loadType, Applic
}
}
Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doPathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger = mNetOps->getClosedLedger();
masterLockHolder.unlock();
@@ -1438,6 +1441,7 @@ Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, Appl
if (sSubCommand == "create")
{
loadType = Resource::feeHighBurdenRPC;
mInfoSub->clearPathRequest ();
PathRequest::pointer request = boost::make_shared<PathRequest> (mInfoSub);
Json::Value result = request->doCreate (lpLedger, params);
@@ -1481,7 +1485,7 @@ Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, Appl
// - Allows clients to verify path exists.
// - Return canonicalized path.
// - From a trusted server, allows clients to use path without manipulation.
Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
int jc = getApp().getJobQueue ().getJobCountGE (jtCLIENT);
@@ -1490,6 +1494,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
WriteLog (lsDEBUG, RPCHandler) << "Too busy for RPF: " << jc;
return rpcError (rpcTOO_BUSY);
}
loadType = Resource::feeHighBurdenRPC;
RippleAddress raSrc;
RippleAddress raDst;
@@ -1562,7 +1567,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
}
}
*loadType = LT_RPCBurden;
loadType = Resource::feeHighBurdenRPC;
Ledger::pointer lSnapShot = boost::make_shared<Ledger> (boost::ref (*lpLedger), false);
masterLockHolder.unlock (); // As long as we have a locked copy of the ledger, we can unlock.
@@ -1730,9 +1735,9 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
// tx_json: <object>,
// secret: <secret>
// }
Json::Value RPCHandler::doSign (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doSign (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
*loadType = LT_RPCBurden;
loadType = Resource::feeHighBurdenRPC;
bool bFailHard = params.isMember ("fail_hard") && params["fail_hard"].asBool ();
return transactionSign (params, false, bFailHard, masterLockHolder);
}
@@ -1741,8 +1746,10 @@ Json::Value RPCHandler::doSign (Json::Value params, LoadType* loadType, Applicat
// tx_json: <object>,
// secret: <secret>
// }
Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doSubmit (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
loadType = Resource::feeMediumBurdenRPC;
if (!params.isMember ("tx_blob"))
{
bool bFailHard = params.isMember ("fail_hard") && params["fail_hard"].asBool ();
@@ -1758,7 +1765,6 @@ Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Applic
return rpcError (rpcINVALID_PARAMS);
}
*loadType = LT_RPCBurden;
Serializer sTrans (vucBlob);
SerializerIterator sitTrans (sTrans);
@@ -1834,7 +1840,7 @@ Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Applic
}
}
Json::Value RPCHandler::doConsensusInfo (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doConsensusInfo (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value ret (Json::objectValue);
@@ -1843,7 +1849,7 @@ Json::Value RPCHandler::doConsensusInfo (Json::Value, LoadType* loadType, Applic
return ret;
}
Json::Value RPCHandler::doFetchInfo (Json::Value jvParams, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doFetchInfo (Json::Value jvParams, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
@@ -1860,7 +1866,7 @@ Json::Value RPCHandler::doFetchInfo (Json::Value jvParams, LoadType* loadType, A
return ret;
}
Json::Value RPCHandler::doServerInfo (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doServerInfo (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value ret (Json::objectValue);
@@ -1869,7 +1875,7 @@ Json::Value RPCHandler::doServerInfo (Json::Value, LoadType* loadType, Applicati
return ret;
}
Json::Value RPCHandler::doServerState (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doServerState (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value ret (Json::objectValue);
@@ -1881,8 +1887,9 @@ Json::Value RPCHandler::doServerState (Json::Value, LoadType* loadType, Applicat
// {
// start: <index>
// }
Json::Value RPCHandler::doTxHistory (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doTxHistory (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
loadType = Resource::feeMediumBurdenRPC;
masterLockHolder.unlock ();
if (!params.isMember ("start"))
@@ -1922,7 +1929,7 @@ Json::Value RPCHandler::doTxHistory (Json::Value params, LoadType* loadType, App
// {
// transaction: <hex>
// }
Json::Value RPCHandler::doTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
@@ -1990,7 +1997,7 @@ Json::Value RPCHandler::doTx (Json::Value params, LoadType* loadType, Applicatio
return rpcError (rpcNOT_IMPL);
}
Json::Value RPCHandler::doLedgerClosed (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLedgerClosed (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value jvResult;
@@ -2003,7 +2010,7 @@ Json::Value RPCHandler::doLedgerClosed (Json::Value, LoadType* loadType, Applica
return jvResult;
}
Json::Value RPCHandler::doLedgerCurrent (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLedgerCurrent (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value jvResult;
@@ -2017,7 +2024,7 @@ Json::Value RPCHandler::doLedgerCurrent (Json::Value, LoadType* loadType, Applic
// ledger: 'current' | 'closed' | <uint256> | <number>, // optional
// full: true | false // optional, defaults to false.
// }
Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLedger (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("ledger") && !params.isMember ("ledger_hash") && !params.isMember ("ledger_index"))
{
@@ -2050,10 +2057,14 @@ Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Applic
| (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0)
| (bAccounts ? LEDGER_JSON_DUMP_STATE : 0);
if ((bFull || bAccounts) && getApp().getFeeTrack().isLoadedLocal() && (mRole != Config::ADMIN))
if (bFull || bAccounts)
{
WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger";
return rpcError(rpcTOO_BUSY);
if (getApp().getFeeTrack().isLoadedLocal() && (mRole != Config::ADMIN))
{
WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger";
return rpcError(rpcTOO_BUSY);
}
loadType = Resource::feeHighBurdenRPC;
}
@@ -2064,7 +2075,7 @@ Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Applic
}
// Temporary switching code until the old account_tx is removed
Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (params.isMember("offset") || params.isMember("count") || params.isMember("descending") ||
params.isMember("ledger_max") || params.isMember("ledger_min"))
@@ -2082,7 +2093,7 @@ Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, LoadType* loadTyp
// offset: integer, // optional, defaults to 0
// limit: integer // optional
// }
Json::Value RPCHandler::doAccountTxOld (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountTxOld (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
RippleAddress raAccount;
uint32 offset = params.isMember ("offset") ? params["offset"].asUInt () : 0;
@@ -2102,6 +2113,8 @@ Json::Value RPCHandler::doAccountTxOld (Json::Value params, LoadType* loadType,
if (!raAccount.setAccountID (params["account"].asString ()))
return rpcError (rpcACT_MALFORMED);
loadType = Resource::feeHighBurdenRPC;
// DEPRECATED
if (params.isMember ("ledger_min"))
{
@@ -2231,7 +2244,7 @@ Json::Value RPCHandler::doAccountTxOld (Json::Value params, LoadType* loadType,
// limit: integer, // optional
// marker: opaque // optional, resume previous query
// }
Json::Value RPCHandler::doAccountTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doAccountTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
RippleAddress raAccount;
int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1;
@@ -2255,6 +2268,8 @@ Json::Value RPCHandler::doAccountTx (Json::Value params, LoadType* loadType, App
if (!raAccount.setAccountID (params["account"].asString ()))
return rpcError (rpcACT_MALFORMED);
loadType = Resource::feeMediumBurdenRPC;
if (params.isMember ("ledger_index_min") || params.isMember ("ledger_index_max"))
{
int64 iLedgerMin = params.isMember ("ledger_index_min") ? params["ledger_index_min"].asInt () : -1;
@@ -2364,7 +2379,7 @@ Json::Value RPCHandler::doAccountTx (Json::Value params, LoadType* loadType, App
// }
//
// This command requires Config::ADMIN access because it makes no sense to ask an untrusted server for this.
Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doValidationCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
RippleAddress raSeed;
Json::Value obj (Json::objectValue);
@@ -2390,7 +2405,7 @@ Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadTy
// {
// secret: <string>
// }
Json::Value RPCHandler::doValidationSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doValidationSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value obj (Json::objectValue);
@@ -2461,7 +2476,7 @@ Json::Value RPCHandler::accounts (Ledger::ref lrLedger, const RippleAddress& naM
// ledger_hash : <ledger>
// ledger_index : <ledger_index>
// }
Json::Value RPCHandler::doWalletAccounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doWalletAccounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -2504,7 +2519,7 @@ Json::Value RPCHandler::doWalletAccounts (Json::Value params, LoadType* loadType
}
}
Json::Value RPCHandler::doLogRotate (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLogRotate (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
return LogSink::get()->rotateLog ();
}
@@ -2512,7 +2527,7 @@ Json::Value RPCHandler::doLogRotate (Json::Value, LoadType* loadType, Applicatio
// {
// passphrase: <string>
// }
Json::Value RPCHandler::doWalletPropose (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doWalletPropose (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
@@ -2544,7 +2559,7 @@ Json::Value RPCHandler::doWalletPropose (Json::Value params, LoadType* loadType,
// {
// secret: <string>
// }
Json::Value RPCHandler::doWalletSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doWalletSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
RippleAddress raSeed;
bool bSecret = params.isMember ("secret");
@@ -2583,7 +2598,7 @@ Json::Value RPCHandler::doWalletSeed (Json::Value params, LoadType* loadType, Ap
// username: <string>,
// password: <string>
// }
Json::Value RPCHandler::doLogin (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLogin (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("username")
|| !params.isMember ("password"))
@@ -2621,7 +2636,7 @@ static void textTime (std::string& text, int& seconds, const char* unitName, int
text += "s";
}
Json::Value RPCHandler::doFeature (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh)
Json::Value RPCHandler::doFeature (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh)
{
if (!params.isMember ("feature"))
{
@@ -2650,7 +2665,7 @@ Json::Value RPCHandler::doFeature (Json::Value params, LoadType* loadType, Appli
// {
// min_count: <number> // optional, defaults to 10
// }
Json::Value RPCHandler::doGetCounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doGetCounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
int minCount = 10;
@@ -2702,7 +2717,7 @@ Json::Value RPCHandler::doGetCounts (Json::Value params, LoadType* loadType, App
return ret;
}
Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLogLevel (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
// log_level
if (!params.isMember ("severity"))
@@ -2755,7 +2770,7 @@ Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Appl
// node: <domain>|<node_public>,
// comment: <comment> // optional
// }
Json::Value RPCHandler::doUnlAdd (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlAdd (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
std::string strNode = params.isMember ("node") ? params["node"].asString () : "";
std::string strComment = params.isMember ("comment") ? params["comment"].asString () : "";
@@ -2779,7 +2794,7 @@ Json::Value RPCHandler::doUnlAdd (Json::Value params, LoadType* loadType, Applic
// {
// node: <domain>|<public_key>
// }
Json::Value RPCHandler::doUnlDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("node"))
return rpcError (rpcINVALID_PARAMS);
@@ -2802,7 +2817,7 @@ Json::Value RPCHandler::doUnlDelete (Json::Value params, LoadType* loadType, App
}
}
Json::Value RPCHandler::doUnlList (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlList (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value obj (Json::objectValue);
@@ -2812,7 +2827,7 @@ Json::Value RPCHandler::doUnlList (Json::Value, LoadType* loadType, Application:
}
// Populate the UNL from a local validators.txt file.
Json::Value RPCHandler::doUnlLoad (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlLoad (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (getConfig ().VALIDATORS_FILE.empty () || !getApp().getUNL ().nodeLoad (getConfig ().VALIDATORS_FILE))
{
@@ -2824,7 +2839,7 @@ Json::Value RPCHandler::doUnlLoad (Json::Value, LoadType* loadType, Application:
// Populate the UNL from ripple.com's validators.txt file.
Json::Value RPCHandler::doUnlNetwork (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlNetwork (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
getApp().getUNL ().nodeNetwork ();
@@ -2832,7 +2847,7 @@ Json::Value RPCHandler::doUnlNetwork (Json::Value params, LoadType* loadType, Ap
}
// unl_reset
Json::Value RPCHandler::doUnlReset (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlReset (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
getApp().getUNL ().nodeReset ();
@@ -2840,14 +2855,14 @@ Json::Value RPCHandler::doUnlReset (Json::Value params, LoadType* loadType, Appl
}
// unl_score
Json::Value RPCHandler::doUnlScore (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnlScore (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
getApp().getUNL ().nodeScore ();
return "scoring requested";
}
Json::Value RPCHandler::doSMS (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doSMS (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
if (!params.isMember ("text"))
return rpcError (rpcINVALID_PARAMS);
@@ -2856,14 +2871,14 @@ Json::Value RPCHandler::doSMS (Json::Value params, LoadType* loadType, Applicati
return "sms dispatched";
}
Json::Value RPCHandler::doStop (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doStop (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
getApp().signalStop ();
return SYSTEM_NAME " server stopping";
}
Json::Value RPCHandler::doLedgerAccept (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLedgerAccept (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Json::Value jvResult;
@@ -2886,7 +2901,7 @@ Json::Value RPCHandler::doLedgerAccept (Json::Value, LoadType* loadType, Applica
// ledger_index : <ledger_index>
// }
// XXX In this case, not specify either ledger does not mean ledger current. It means any ledger.
Json::Value RPCHandler::doTransactionEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doTransactionEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -3059,7 +3074,7 @@ Json::Value RPCHandler::lookupLedger (Json::Value params, Ledger::pointer& lpLed
// ledger_index : <ledger_index>
// ...
// }
Json::Value RPCHandler::doLedgerEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLedgerEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -3275,7 +3290,7 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value params, LoadType* loadType, A
// ledger_hash : <ledger>
// ledger_index : <ledger_index>
// }
Json::Value RPCHandler::doLedgerHeader (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doLedgerHeader (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -3317,7 +3332,7 @@ boost::unordered_set<RippleAddress> RPCHandler::parseAccountIds (const Json::Val
return usnaResult;
}
Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
InfoSub::pointer ispSub;
Json::Value jvResult (Json::objectValue);
@@ -3583,6 +3598,7 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, App
if (bSnapshot)
{
loadType = Resource::feeMediumBurdenRPC;
Ledger::pointer lpLedger = getApp().getLedgerMaster ().getPublishedLedger ();
if (lpLedger)
{
@@ -3614,7 +3630,7 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, App
}
// FIXME: This leaks RPCSub objects for JSON-RPC. Shouldn't matter for anyone sane.
Json::Value RPCHandler::doUnsubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doUnsubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
InfoSub::pointer ispSub;
Json::Value jvResult (Json::objectValue);
@@ -3804,7 +3820,7 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value params, LoadType* loadType, A
//
// JSON-RPC provides a method and an array of params. JSON-RPC is used as a transport for a command and a request object. The
// command is the method. The request object is supplied as the first element of the params.
Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value const& jvParams, int iRole, LoadType* loadType)
Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value const& jvParams, int iRole, Resource::Charge& loadType)
{
WriteLog (lsTRACE, RPCHandler) << "doRpcCommand:" << strMethod << ":" << jvParams;
@@ -3845,7 +3861,7 @@ Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value
return jvResult;
}
Json::Value RPCHandler::doInternal (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
Json::Value RPCHandler::doInternal (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{
// Used for debug or special-purpose RPC commands
if (!params.isMember ("internal_command"))
@@ -3854,7 +3870,7 @@ Json::Value RPCHandler::doInternal (Json::Value params, LoadType* loadType, Appl
return RPCInternalHandler::runHandler (params["internal_command"].asString (), params["params"]);
}
Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadType* loadType)
Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, Resource::Charge& loadType)
{
if (iRole != Config::ADMIN)
{
@@ -4016,8 +4032,8 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{
WriteLog (lsINFO, RPCHandler) << "Caught throw: " << e.what ();
if (*loadType == LT_RPCReference)
*loadType = LT_RPCException;
if (loadType == Resource::feeReferenceRPC)
loadType = Resource::feeExceptionRPC;
return rpcError (rpcINTERNAL);
}

View File

@@ -37,14 +37,14 @@ public:
RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub);
Json::Value doCommand (const Json::Value& jvRequest, int role, LoadType* loadType);
Json::Value doCommand (const Json::Value& jvRequest, int role, Resource::Charge& loadType);
Json::Value doRpcCommand (const std::string& strCommand, Json::Value const& jvParams, int iRole, LoadType* loadType);
Json::Value doRpcCommand (const std::string& strCommand, Json::Value const& jvParams, int iRole, Resource::Charge& loadType);
private:
typedef Json::Value (RPCHandler::*doFuncPtr) (
Json::Value params,
LoadType* loadType,
Resource::Charge& loadType,
Application::ScopedLockType& MasterLockHolder);
// VFALCO TODO Document these and give the enumeration a label.
@@ -94,76 +94,76 @@ private:
const int iIndex,
const bool bStrict);
Json::Value doAccountCurrencies (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doAccountInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doAccountLines (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doAccountOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doAccountTx (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 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);
Json::Value doFetchInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doGetCounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doInternal (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLedger (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerAccept (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerClosed (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerCurrent (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerHeader (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLogLevel (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLogRotate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doNicknameInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doOwnerInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPeers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPing (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProfile (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProofCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProofSolve (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProofVerify (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doRandom (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doRipplePathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doSMS (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doServerInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); // for humans
Json::Value doServerState (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); // for machines
Json::Value doSessionClose (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doSessionOpen (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doSign (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doStop (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doSubmit (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doSubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doTransactionEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doTxHistory (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlAdd (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlFetch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlList (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlLoad (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlNetwork (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlReset (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnlScore (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doUnsubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doValidationCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doValidationSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doWalletAccounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doWalletLock (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doWalletPropose (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doWalletSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doWalletUnlock (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doWalletVerify (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doAccountInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doAccountLines (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doAccountOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doAccountTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doAccountTxSwitch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doAccountTxOld (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doBookOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doBlackList (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doConnect (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doConsensusInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doFeature (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doFetchInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doGetCounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doInternal (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLedger (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerAccept (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerClosed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerCurrent (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLedgerHeader (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLogLevel (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLogRotate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doNicknameInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doOwnerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doPathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doPeers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doPing (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doPrint (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doProfile (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doProofCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doProofSolve (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doProofVerify (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doRandom (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doRipplePathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doSMS (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doServerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh); // for humans
Json::Value doServerState (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh); // for machines
Json::Value doSessionClose (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doSessionOpen (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doSign (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doStop (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doSubmit (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doSubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doTransactionEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doTxHistory (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlAdd (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlList (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlLoad (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlNetwork (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlReset (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnlScore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doUnsubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doValidationCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doValidationSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doWalletAccounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doWalletLock (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doWalletPropose (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doWalletSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doWalletUnlock (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doWalletVerify (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
#if ENABLE_INSECURE
Json::Value doDataDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doDataFetch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doDataStore (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doLogin (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doDataDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doDataFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doDataStore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
Json::Value doLogin (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
#endif
private:

View File

@@ -18,8 +18,9 @@
//==============================================================================
RPCServerHandler::RPCServerHandler (NetworkOPs& networkOPs)
RPCServerHandler::RPCServerHandler (NetworkOPs& networkOPs, Resource::Manager& resourceManager)
: m_networkOPs (networkOPs)
, m_resourceManager (resourceManager)
{
}
@@ -52,6 +53,16 @@ std::string RPCServerHandler::processRequest (std::string const& request, std::s
Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));
Resource::Consumer usage;
if (role == Config::ADMIN)
usage = m_resourceManager.newAdminEndpoint (remoteAddress);
else
usage = m_resourceManager.newInboundEndpoint (IPAddress::from_string (remoteAddress));
if (usage.disconnect ())
return createResponse (503, "Server is overloaded");
// Parse id now so errors from here on will have the id
//
// VFALCO NOTE Except that "id" isn't included in the following errors...
@@ -107,10 +118,11 @@ std::string RPCServerHandler::processRequest (std::string const& request, std::s
RPCHandler rpcHandler (&m_networkOPs);
LoadType loadType = LT_RPCReference;
Resource::Charge loadType = Resource::feeReferenceRPC;
Json::Value const result = rpcHandler.doRpcCommand (strMethod, params, role, &loadType);
// VFALCO NOTE We discard loadType since there is no endpoint to punish
Json::Value const result = rpcHandler.doRpcCommand (strMethod, params, role, loadType);
usage.charge (loadType);
WriteLog (lsDEBUG, RPCServer) << "Reply: " << result;

View File

@@ -27,7 +27,7 @@ class NetworkOPs;
class RPCServerHandler : public RPCServer::Handler
{
public:
explicit RPCServerHandler (NetworkOPs& networkOPs);
explicit RPCServerHandler (NetworkOPs& networkOPs, Resource::Manager& resourceManager);
std::string createResponse (int statusCode, std::string const& description);
@@ -37,6 +37,7 @@ public:
private:
NetworkOPs& m_networkOPs;
Resource::Manager& m_resourceManager;
};
#endif

View File

@@ -17,35 +17,27 @@
*/
//==============================================================================
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 (Resource::Manager& resourceManager,
Resource::Consumer usage, InfoSub::Source& source, bool isPublic,
std::string const& remoteIP, boost::asio::io_service& io_service)
: InfoSub (source)
IPAddress const& remoteAddress, boost::asio::io_service& io_service)
: InfoSub (source, usage)
, m_resourceManager (resourceManager)
, m_usage (usage)
, m_isPublic (isPublic)
, m_remoteIP (remoteIP)
, m_remoteAddress (remoteAddress)
, m_receiveQueueMutex (this, "WSConnection", __FILE__, __LINE__)
, m_netOPs (getApp ().getOPs ())
, m_loadSource (m_remoteIP, trimIP(m_remoteIP))
, m_pingTimer (io_service)
, m_sentPing (false)
, m_receiveQueueRunning (false)
, m_isDead (false)
, m_io_service (io_service)
{
WriteLog (lsDEBUG, WSConnection) << "Websocket connection from " << m_remoteIP;
WriteLog (lsDEBUG, WSConnection) <<
"Websocket connection from " << remoteAddress;
}
WSConnection::~WSConnection ()
@@ -113,19 +105,11 @@ void WSConnection::returnMessage (message_ptr ptr)
Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
{
#if RIPPLE_USE_RESOURCE_MANAGER
if (m_usage.disconnect ())
if (getConsumer().disconnect ())
{
disconnect ();
return rpcError (rpcSLOW_DOWN);
}
#else
if (getApp().getLoadManager ().shouldCutoff (m_loadSource))
{
disconnect ();
return rpcError (rpcSLOW_DOWN);
}
#endif
// Requests without "command" are invalid.
//
@@ -143,22 +127,19 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
jvResult["id"] = jvRequest["id"];
}
#if RIPPLE_USE_RESOURCE_MANAGER
m_usage.charge (Resource::feeInvalidRPC);
#else
getApp().getLoadManager ().applyLoadCharge (m_loadSource, LT_RPCInvalid);
#endif
getConsumer().charge (Resource::feeInvalidRPC);
return jvResult;
}
LoadType loadType = LT_RPCReference;
Resource::Charge loadType = Resource::feeReferenceRPC;
RPCHandler mRPCHandler (&this->m_netOPs, boost::dynamic_pointer_cast<InfoSub> (this->shared_from_this ()));
Json::Value jvResult (Json::objectValue);
Config::Role const role = m_isPublic
? Config::GUEST // Don't check on the public interface.
: getConfig ().getAdminRole (jvRequest, m_remoteIP);
: getConfig ().getAdminRole (
jvRequest, m_remoteAddress.withPort(0).to_string());
if (Config::FORBID == role)
{
@@ -166,24 +147,14 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
}
else
{
jvResult["result"] = mRPCHandler.doCommand (jvRequest, role, &loadType);
jvResult["result"] = mRPCHandler.doCommand (jvRequest, role, loadType);
}
#if RIPPLE_USE_RESOURCE_MANAGER
m_usage.charge (Resource::legacyFee (loadType));
if (m_usage.warn ())
getConsumer().charge (loadType);
if (getConsumer().warn ())
{
jvResult["warning"] = "load";
}
#else
// Debit/credit the load and see if we should include a warning.
//
if (getApp().getLoadManager ().applyLoadCharge (m_loadSource, loadType) &&
getApp().getLoadManager ().shouldWarn (m_loadSource))
{
jvResult["warning"] = "load";
}
#endif
// Currently we will simply unwrap errors returned by the RPC
// API, in the future maybe we can make the responses

View File

@@ -39,7 +39,7 @@ protected:
WSConnection (Resource::Manager& resourceManager,
Resource::Consumer usage, InfoSub::Source& source, bool isPublic,
std::string const& remoteIP, boost::asio::io_service& io_service);
IPAddress const& remoteAddress, boost::asio::io_service& io_service);
virtual ~WSConnection ();
@@ -57,11 +57,10 @@ protected:
Resource::Manager& m_resourceManager;
Resource::Consumer m_usage;
bool const m_isPublic;
std::string const m_remoteIP;
IPAddress const m_remoteAddress;
LockType m_receiveQueueMutex;
std::deque <message_ptr> m_receiveQueue;
NetworkOPs& m_netOPs;
LoadSource m_loadSource;
boost::asio::deadline_timer m_pingTimer;
bool m_sentPing;
bool m_receiveQueueRunning;
@@ -96,11 +95,10 @@ public:
connection_ptr const& cpConnection)
: WSConnection (
resourceManager,
resourceManager.newInboundEndpoint (IPAddressConversion::from_asio (
cpConnection->get_socket ().lowest_layer ().remote_endpoint ().address ())),
resourceManager.newInboundEndpoint (cpConnection->get_socket ().remote_endpoint ()),
source,
serverHandler.getPublic (),
cpConnection->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string (),
cpConnection->get_socket ().remote_endpoint (),
cpConnection->get_io_service ())
, m_serverHandler (serverHandler)
, m_connection (cpConnection)

View File

@@ -41,7 +41,7 @@ class WSDoorImp : public WSDoor, protected Thread, LeakChecked <WSDoorImp>
public:
WSDoorImp (Resource::Manager& resourceManager,
InfoSub::Source& source, std::string const& strIp,
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
int iPort, bool bPublic, bool bProxy, boost::asio::ssl::context& ssl_context)
: WSDoor (source)
, Thread ("websocket")
, m_resourceManager (resourceManager)
@@ -49,6 +49,7 @@ public:
, m_ssl_context (ssl_context)
, m_endpointLock (this, "WSDoor", __FILE__, __LINE__)
, mPublic (bPublic)
, mProxy (bProxy)
, mIp (strIp)
, mPort (iPort)
{
@@ -67,14 +68,14 @@ private:
boost::format ("Websocket: %s: Listening: %s %d ") %
(mPublic ? "Public" : "Private") % mIp % mPort);
websocketpp::server_autotls::handler::ptr handler (
new WSServerHandler <websocketpp::server_autotls> (
m_resourceManager, m_source, m_ssl_context, mPublic));
websocketpp::server_multitls::handler::ptr handler (
new WSServerHandler <websocketpp::server_multitls> (
m_resourceManager, m_source, m_ssl_context, mPublic, mProxy));
{
ScopedLockType lock (m_endpointLock, __FILE__, __LINE__);
m_endpoint = new websocketpp::server_autotls (handler);
m_endpoint = new websocketpp::server_multitls (handler);
}
// Call the main-event-loop of the websocket server.
@@ -137,8 +138,9 @@ private:
boost::asio::ssl::context& m_ssl_context;
LockType m_endpointLock;
ScopedPointer <websocketpp::server_autotls> m_endpoint;
ScopedPointer <websocketpp::server_multitls> m_endpoint;
bool mPublic;
bool mProxy;
std::string mIp;
int mPort;
};
@@ -154,14 +156,14 @@ WSDoor::WSDoor (Stoppable& parent)
WSDoor* WSDoor::New (Resource::Manager& resourceManager,
InfoSub::Source& source, std::string const& strIp,
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
int iPort, bool bPublic, bool bProxy, boost::asio::ssl::context& ssl_context)
{
ScopedPointer <WSDoor> door;
try
{
door = new WSDoorImp (resourceManager,
source, strIp, iPort, bPublic, ssl_context);
source, strIp, iPort, bPublic, bProxy, ssl_context);
}
catch (...)
{

View File

@@ -31,7 +31,7 @@ public:
static WSDoor* New (Resource::Manager& resourceManager,
InfoSub::Source& source, std::string const& strIp,
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context);
int iPort, bool bPublic, bool bProxy, boost::asio::ssl::context& ssl_context);
};
#endif

View File

@@ -72,15 +72,17 @@ protected:
boost::unordered_map <connection_ptr,
boost::shared_ptr <WSConnectionType <endpoint_type> > > mMap;
bool const mPublic;
bool const mProxy;
public:
WSServerHandler (Resource::Manager& resourceManager,
InfoSub::Source& source, boost::asio::ssl::context& ssl_context, bool bPublic)
InfoSub::Source& source, boost::asio::ssl::context& ssl_context, bool bPublic, bool bProxy)
: m_resourceManager (resourceManager)
, m_source (source)
, mLock (static_cast <WSServerHandlerBase*> (this), "WSServerHandler", __FILE__, __LINE__)
, m_ssl_context (ssl_context)
, mPublic (bPublic)
, mProxy (bProxy)
{
}
@@ -249,7 +251,7 @@ public:
try
{
WriteLog (lsDEBUG, WSServerHandlerLog) << "Ws:: Rejected("
<< cpClient->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string ()
<< cpClient->get_socket ().remote_endpoint ().to_string ()
<< ") '" << mpMessage->get_payload () << "'";
}
catch (...)
@@ -301,7 +303,7 @@ public:
try
{
WriteLog (lsDEBUG, WSServerHandlerLog) << "Ws:: Receiving("
<< cpClient->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string ()
<< cpClient->get_socket ().remote_endpoint ().to_string ()
<< ") '" << mpMessage->get_payload () << "'";
}
catch (...)
@@ -345,6 +347,10 @@ public:
{
return m_ssl_context;
}
bool get_proxy ()
{
return mProxy;
}
// Respond to http requests.
bool http (connection_ptr cpClient)

View File

@@ -60,6 +60,8 @@ Config::Config ()
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT;
WEBSOCKET_PUBLIC_SECURE = 1;
WEBSOCKET_PROXY_PORT = 0;
WEBSOCKET_PROXY_SECURE = 1;
WEBSOCKET_SECURE = 0;
WEBSOCKET_PING_FREQ = (5 * 60);
NUMBER_CONNECTIONS = 30;
@@ -408,12 +410,20 @@ void Config::load ()
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PUBLIC_PORT, strTemp))
WEBSOCKET_PUBLIC_PORT = lexicalCastThrow <int> (strTemp);
(void) SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_IP, WEBSOCKET_PROXY_IP);
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_PORT, strTemp))
WEBSOCKET_PROXY_PORT = lexicalCastThrow <int> (strTemp);
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_SECURE, strTemp))
WEBSOCKET_SECURE = lexicalCastThrow <int> (strTemp);
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PUBLIC_SECURE, strTemp))
WEBSOCKET_PUBLIC_SECURE = lexicalCastThrow <int> (strTemp);
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_SECURE, strTemp))
WEBSOCKET_PROXY_SECURE = lexicalCastThrow <int> (strTemp);
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PING_FREQ, strTemp))
WEBSOCKET_PING_FREQ = lexicalCastThrow <int> (strTemp);

View File

@@ -401,6 +401,10 @@ public:
int WEBSOCKET_PUBLIC_PORT;
int WEBSOCKET_PUBLIC_SECURE;
std::string WEBSOCKET_PROXY_IP; // XXX Going away. Merge with the inbound peer connction.
int WEBSOCKET_PROXY_PORT;
int WEBSOCKET_PROXY_SECURE;
std::string WEBSOCKET_IP;
int WEBSOCKET_PORT;
int WEBSOCKET_SECURE;

View File

@@ -92,6 +92,9 @@ struct ConfigSection
#define SECTION_WEBSOCKET_PUBLIC_IP "websocket_public_ip"
#define SECTION_WEBSOCKET_PUBLIC_PORT "websocket_public_port"
#define SECTION_WEBSOCKET_PUBLIC_SECURE "websocket_public_secure"
#define SECTION_WEBSOCKET_PROXY_IP "websocket_proxy_ip"
#define SECTION_WEBSOCKET_PROXY_PORT "websocket_proxy_port"
#define SECTION_WEBSOCKET_PROXY_SECURE "websocket_proxy_secure"
#define SECTION_WEBSOCKET_PING_FREQ "websocket_ping_frequency"
#define SECTION_WEBSOCKET_IP "websocket_ip"
#define SECTION_WEBSOCKET_PORT "websocket_port"

View File

@@ -1,176 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_CORE_FUNCTIONAL_LOADSOURCE_H_INCLUDED
#define RIPPLE_CORE_FUNCTIONAL_LOADSOURCE_H_INCLUDED
/** Tracks the consumption of resources at an endpoint.
To prevent monopolization of server resources or attacks on servers,
resource consumption is monitored at each endpoint. When consumption
exceeds certain thresholds, costs are imposed. Costs include charging
additional XRP for transactions, requiring a proof of work to be
performed, or simply disconnecting the endpoint.
Currently, consumption endpoints include websocket connections used to
service clients, and peer connections used to create the peer to peer
overlay network implementing the Ripple protcool.
The current "balance" of a LoadSource represents resource consumption
debt or credit. Debt is accrued when bad loads are imposed. Credit is
granted when good loads are imposed. When the balance crosses heuristic
thresholds, costs are increased on the endpoint.
The balance is represented as a unitless relative quantity.
@note Although RPC connections consume resources, they are transient and
cannot be rate limited. It is advised not to expose RPC interfaces
to the general public.
*/
class LoadSource
{
public:
/** Construct a load source.
Sources with admin privileges have relaxed or no restrictions
on resource consumption.
@param admin `true` if the source should have admin privileges.
*/
// VFALCO TODO See who is constructing this with a parameter
explicit LoadSource (bool admin)
: mBalance (0)
, mFlags (admin ? lsfPrivileged : 0)
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
, mLastWarning (0)
, mLogged (false)
{
}
/** Construct a load source with a given name.
The endpoint is considered non-privileged.
*/
explicit LoadSource (std::string const& name, std::string const& costName)
: mName (name)
, mCostName (costName)
, mBalance (0)
, mFlags (0)
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
, mLastWarning (0)
, mLogged (false)
{
}
/** Change the name of the source.
An endpoint can be created before it's name is known. For example,
on an incoming connection before the IP and port have been determined.
*/
// 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, std::string const& costName) noexcept
{
mName = name;
mCostName = costName;
}
/** Retrieve the name of this endpoint.
*/
std::string const& getName () const noexcept
{
return mName;
}
std::string const& getCostName () const noexcept
{
return mCostName;
}
/** Determine if this endpoint is privileged.
*/
bool isPrivileged () const noexcept
{
return (mFlags & lsfPrivileged) != 0;
}
/** Grant the privileged attribute on this endpoint.
*/
void setPrivileged () noexcept
{
mFlags |= lsfPrivileged;
}
/** Retrieve the load debit or credit associated with the endpoint.
The balance is represented in a unitless relative quantity
indicating the heuristically weighted amount of resource consumption.
*/
int getBalance () const noexcept
{
return mBalance;
}
/** Returns true if the endpoint received a log warning.
*/
bool isLogged () const noexcept
{
return mLogged;
}
/** Reset the flag indicating the endpoint received a log warning.
*/
void clearLogged () noexcept
{
mLogged = false;
}
/** Indicate that this endpoint is an outgoing connection.
*/
void setOutbound () noexcept
{
mFlags |= lsfOutbound;
}
/** Returns true if this endpoint is an outgoing connection.
*/
bool isOutbound () const
{
return (mFlags & lsfOutbound) != 0;
}
private:
// VFALCO Make this not a friend
friend class LoadManagerImp;
// VFALCO TODO Rename these for clarity
static const int lsfPrivileged = 1;
static const int lsfOutbound = 2;
private:
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;
int mLastWarning;
bool mLogged;
};
#endif

View File

@@ -41,7 +41,6 @@ namespace ripple
# include "functional/LoadMonitor.h"
# include "functional/Job.h"
#include "functional/JobQueue.h"
#include "functional/LoadSource.h"
}

View File

@@ -90,10 +90,19 @@ message TMClusterNode
optional string address = 5;
}
// Sources that are placing load on the server
message TMLoadSource
{
required string name = 1;
required uint32 cost = 2;
optional uint32 count = 3; // number of connections
}
// The status of all nodes in the cluster
message TMCluster
{
repeated TMClusterNode clusterNodes = 1;
repeated TMLoadSource loadSources = 2;
}

View File

@@ -25,12 +25,14 @@
#include "beast/modules/beast_asio/beast_asio.h"
#include "../ripple/resource/ripple_resource.h"
#include "../ripple_basics/ripple_basics.h"
#include "../ripple_core/ripple_core.h"
#include "../ripple_data/ripple_data.h"
#include "../ripple_websocket/autosocket/AutoSocket.h"
namespace ripple
{
namespace ripple {
#include "basics/RippleSSLContext.h"
#include "basics/MultiSocket.h"

View File

@@ -38,8 +38,9 @@ InfoSub::Source::Source (char const* name, Stoppable& parent)
//------------------------------------------------------------------------------
InfoSub::InfoSub (Source& source)
InfoSub::InfoSub (Source& source, Consumer consumer)
: mLock (this, "InfoSub", __FILE__, __LINE__)
, m_consumer (consumer)
, m_source (source)
{
static Atomic <int> s_seq_id;
@@ -56,6 +57,11 @@ InfoSub::~InfoSub ()
m_source.unsubAccount (mSeq, mSubAccountInfo, false);
}
Resource::Consumer& InfoSub::getConsumer()
{
return m_consumer;
}
void InfoSub::send (const Json::Value& jvObj, const std::string& sObj, bool broadcast)
{
send (jvObj, broadcast);

View File

@@ -40,6 +40,8 @@ public:
typedef const boost::shared_ptr<InfoSub>& ref;
typedef Resource::Consumer Consumer;
public:
/** Abstracts the source of subscription data.
*/
@@ -95,10 +97,12 @@ public:
};
public:
explicit InfoSub (Source& source);
InfoSub (Source& source, Consumer consumer);
virtual ~InfoSub ();
Consumer& getConsumer();
virtual void send (const Json::Value & jvObj, bool broadcast) = 0;
// VFALCO NOTE Why is this virtual?
@@ -122,6 +126,7 @@ protected:
LockType mLock;
private:
Consumer m_consumer;
Source& m_source;
boost::unordered_set <RippleAddress> mSubAccountInfo;
boost::unordered_set <RippleAddress> mSubAccountTransaction;

View File

@@ -195,7 +195,7 @@ private:
//------------------------------------------------------------------------------
RPCSub::RPCSub (InfoSub::Source& source)
: InfoSub (source)
: InfoSub (source, Consumer())
{
}

View File

@@ -20,8 +20,7 @@
#ifndef RIPPLE_NET_RPC_RPCSUB_H_INCLUDED
#define RIPPLE_NET_RPC_RPCSUB_H_INCLUDED
/** Subscription object for JSON RPC.
*/
/** Subscription object for JSON RPC. */
class RPCSub : public InfoSub
{
public:

View File

@@ -25,7 +25,7 @@
#define __STDC_LIMIT_MACROS
#endif
#include "../ripple_basics/ripple_basics.h"
#include "../ripple_net/ripple_net.h"
#include "beast/modules/beast_core/system/BeforeBoost.h"
#include <boost/asio.hpp>
@@ -33,8 +33,7 @@
#include "websocket/src/common.hpp"
#include "websocket/src/sockets/socket_base.hpp"
#include "autosocket/AutoSocket.h" // must come before autotls.hpp
#include "websocket/src/sockets/autotls.hpp"
#include "websocket/src/sockets/multitls.hpp"
#include "websocket/src/websocketpp.hpp"
#include "websocket/src/logger/logger.hpp"

View File

@@ -900,7 +900,8 @@ public:
{
// TODO: read timeout timer?
socket_type::get_socket().async_read(
async_read(
socket_type::get_socket(),
m_buf,
boost::asio::transfer_at_least(std::min(
m_read_threshold,
@@ -1209,7 +1210,7 @@ public:
//m_endpoint.alog().at(log::alevel::DEVEL) << "write header: " << zsutil::to_hex(m_write_queue.front()->get_header()) << log::endl;
socket_type::get_socket().async_write(
async_write(socket_type::get_socket(),
m_write_buf,
m_strand.wrap(boost::bind(
&type::handle_write,

View File

@@ -29,7 +29,7 @@
#define WEBSOCKETPP_ENDPOINT_HPP
#include "connection.hpp"
#include "sockets/autotls.hpp" // should this be here?
#include "sockets/multitls.hpp" // should this be here?
#include "logger/logger.hpp"
#include <boost/asio.hpp>
@@ -74,7 +74,7 @@ protected:
*/
template <
template <class> class role,
template <class> class socket = socket::autotls,
template <class> class socket = socket::multitls,
template <class> class logger = log::logger>
class endpoint
: public endpoint_base,

View File

@@ -410,7 +410,7 @@ void server<endpoint>::start_accept() {
}
m_acceptor.async_accept(
con->get_raw_socket(),
con->get_native_socket (),
boost::bind(
&type::handle_accept,
this,
@@ -427,7 +427,7 @@ template <class endpoint>
void server<endpoint>::handle_accept(connection_ptr con,
const boost::system::error_code& error)
{
bool delay = false;
bool delay = false;
boost::lock_guard<boost::recursive_mutex> lock(m_endpoint.m_lock);
@@ -554,18 +554,19 @@ void server<endpoint>::connection<connection_type>::async_init() {
static boost::arg<1> pl1;
static boost::arg<2> pl2;
boost::shared_ptr<std::string> stringPtr = boost::make_shared<std::string>();
m_connection.get_socket().async_read_until(
m_connection.buffer(),
boost::bind(&match_header, stringPtr, pl1, pl2),
m_connection.get_strand().wrap(boost::bind(
&type::handle_read_request,
m_connection.shared_from_this(),
stringPtr,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
))
);
boost::shared_ptr<std::string> stringPtr = boost::make_shared<std::string>();
async_read_until(
m_connection.get_socket(),
m_connection.buffer(),
boost::bind(&match_header, stringPtr, pl1, pl2),
m_connection.get_strand().wrap(boost::bind(
&type::handle_read_request,
m_connection.shared_from_this(),
stringPtr,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
))
);
}
/// processes the response from an async read for an HTTP header
@@ -598,13 +599,14 @@ void server<endpoint>::connection<connection_type>::handle_read_request(
std::string reply =
"<?xml version=\"1.0\"?><cross-domain-policy>"
"<allow-access-from domain=\"*\" to-ports=\"";
reply += beast::lexicalCastThrow <std::string>(m_connection.get_raw_socket().local_endpoint().port());
reply += "\"/></cross-domain-policy>";
reply.append("\0", 1);
reply += beast::lexicalCastThrow <std::string>(m_connection.get_native_socket().local_endpoint().port());
reply += "\"/></cross-domain-policy>";
reply.append("\0", 1);
m_version = -1;
shared_const_buffer buffer(reply);
m_connection.get_socket().async_write(
async_write(
m_connection.get_socket(),
shared_const_buffer(reply),
boost::bind(
&type::handle_write_response,
@@ -862,7 +864,8 @@ void server<endpoint>::connection<connection_type>::write_response() {
m_endpoint.m_alog->at(log::alevel::DEBUG_HANDSHAKE) << raw << log::endl;
m_connection.get_socket().async_write(
async_write(
m_connection.get_socket(),
//boost::asio::buffer(raw),
buffer,
boost::bind(
@@ -928,8 +931,8 @@ void server<endpoint>::connection<connection_type>::log_open_result() {
version << "v" << m_version << " ";
std::string remote;
boost::system::error_code ec;
boost::asio::ip::tcp::endpoint ep = m_connection.get_raw_socket().remote_endpoint(ec);
boost::system::error_code ec; // FIXME: proxy
boost::asio::ip::tcp::endpoint ep = m_connection.get_native_socket().remote_endpoint(ec);
if (ec) {
m_endpoint.m_elog->at(log::elevel::WARN)
<< "Error getting remote endpoint. code: " << ec << log::endl;

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_SOCKET_MULTITLS_HPP
#define WEBSOCKETPP_SOCKET_MULTITLS_HPP
namespace websocketpp {
namespace socket {
template <typename endpoint_type>
class multitls {
public:
typedef multitls<endpoint_type> type;
typedef ripple::MultiSocket multitls_socket;
typedef boost::asio::ip::tcp::socket native_socket_t;
typedef boost::shared_ptr<multitls_socket> multitls_socket_ptr;
// should be private friended
boost::asio::io_service& get_io_service() {
return m_io_service;
}
static void handle_shutdown(multitls_socket_ptr, const boost::system::error_code&) {
}
void set_secure_only() {
m_secure_only = true;
}
void set_plain_only() {
m_plain_only = true;
}
// should be private friended?
multitls_socket::handshake_type get_handshake_type() {
if (static_cast< endpoint_type* >(this)->is_server()) {
return boost::asio::ssl::stream_base::server;
} else {
return boost::asio::ssl::stream_base::client;
}
}
class handler_interface {
public:
virtual ~handler_interface() {}
virtual void on_tcp_init() {};
virtual boost::asio::ssl::context& get_ssl_context () = 0;
virtual bool get_proxy() = 0;
};
// Connection specific details
template <typename connection_type>
class connection {
public:
multitls_socket& get_socket() {
return *m_socket_ptr;
}
native_socket_t& get_native_socket() {
return m_socket_ptr->next_layer<native_socket_t> ();
}
bool is_secure() {
return m_socket_ptr->ssl_handle() != NULL;
}
protected:
connection(multitls<endpoint_type>& e)
: m_endpoint(e)
, m_connection(static_cast< connection_type& >(*this)) {}
void init() {
boost::asio::ssl::context& ssl_context (
m_connection.get_handler()->get_ssl_context());
int flags = multitls_socket::Flag::server_role |
(m_endpoint.m_secure_only ? multitls_socket::Flag::ssl_required : 0) |
(m_endpoint.m_plain_only ? 0 : multitls_socket::Flag::ssl);
if (m_connection.get_handler()->get_proxy ())
flags |= multitls_socket::Flag::proxy;
m_socket_ptr = multitls_socket_ptr (multitls_socket::New (
m_endpoint.get_io_service(), ssl_context, flags ) );
}
void async_init(boost::function<void(const boost::system::error_code&)> callback)
{
m_connection.get_handler()->on_tcp_init();
// wait for TLS handshake
// TODO: configurable value
m_connection.register_timeout(5000,
fail::status::TIMEOUT_TLS,
"Timeout on TLS handshake");
m_socket_ptr->async_handshake(
m_endpoint.get_handshake_type(),
boost::bind(
&connection<connection_type>::handle_init,
this,
callback,
boost::asio::placeholders::error
)
);
}
void handle_init(socket_init_callback callback,const boost::system::error_code& error) {
m_connection.cancel_timeout();
callback(error);
}
// note, this function for some reason shouldn't/doesn't need to be
// called for plain HTTP connections. not sure why.
bool shutdown() {
boost::system::error_code ignored_ec;
m_socket_ptr->async_shutdown( // Don't block on connection shutdown DJS
boost::bind(
&multitls<endpoint_type>::handle_shutdown,
m_socket_ptr,
boost::asio::placeholders::error
)
);
if (ignored_ec) {
return false;
} else {
return true;
}
}
private:
boost::shared_ptr<boost::asio::ssl::context> m_context_ptr;
multitls_socket_ptr m_socket_ptr;
multitls<endpoint_type>& m_endpoint;
connection_type& m_connection;
};
protected:
multitls (boost::asio::io_service& m) : m_io_service(m), m_secure_only(false), m_plain_only(false) {}
private:
boost::asio::io_service& m_io_service;
bool m_secure_only;
bool m_plain_only;
};
} // namespace socket
} // namespace websocketpp
#endif // WEBSOCKETPP_SOCKET_MULTITLS_HPP

View File

@@ -41,9 +41,9 @@ namespace websocketpp {
typedef websocketpp::endpoint<websocketpp::role::server,
websocketpp::socket::tls> server_tls;
#endif
#ifdef WEBSOCKETPP_SOCKET_AUTOTLS_HPP
#ifdef WEBSOCKETPP_SOCKET_MULTITLS_HPP
typedef websocketpp::endpoint<websocketpp::role::server,
websocketpp::socket::autotls> server_autotls;
websocketpp::socket::multitls> server_multitls;
#endif
#endif