diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 78533d76ce..31e9343a5d 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -1926,7 +1926,6 @@ - diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 9e6a6a3a20..062fa9e7f3 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -1706,9 +1706,6 @@ [2] Old Ripple\ripple_app\peers - - [2] Old Ripple\ripple_core\functional - [2] Old Ripple\ripple_app\main diff --git a/src/BeastConfig.h b/src/BeastConfig.h index ca84a48060..2b97cb4e33 100644 --- a/src/BeastConfig.h +++ b/src/BeastConfig.h @@ -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 diff --git a/src/ripple/resource/api/Charge.h b/src/ripple/resource/api/Charge.h index 053c6b39ca..c6a7b3e042 100644 --- a/src/ripple/resource/api/Charge.h +++ b/src/ripple/resource/api/Charge.h @@ -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; diff --git a/src/ripple/resource/api/Manager.h b/src/ripple/resource/api/Manager.h index afdcf771dc..beb1400865 100644 --- a/src/ripple/resource/api/Manager.h +++ b/src/ripple/resource/api/Manager.h @@ -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. */ diff --git a/src/ripple/resource/impl/Charge.cpp b/src/ripple/resource/impl/Charge.cpp index c792a71a81..8f33b33bcc 100644 --- a/src/ripple/resource/impl/Charge.cpp +++ b/src/ripple/resource/impl/Charge.cpp @@ -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; +} + } } diff --git a/src/ripple/resource/impl/Consumer.cpp b/src/ripple/resource/impl/Consumer.cpp index 62729efea8..0a44d1e16d 100644 --- a/src/ripple/resource/impl/Consumer.cpp +++ b/src/ripple/resource/impl/Consumer.cpp @@ -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; } diff --git a/src/ripple/resource/impl/Logic.h b/src/ripple/resource/impl/Logic.h index 4bca32ad8d..3a91bfaef7 100644 --- a/src/ripple/resource/impl/Logic.h +++ b/src/ripple/resource/impl/Logic.h @@ -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 ::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 ::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 ::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; } } diff --git a/src/ripple/resource/impl/Manager.cpp b/src/ripple/resource/impl/Manager.cpp index 5c3261622f..509122e655 100644 --- a/src/ripple/resource/impl/Manager.cpp +++ b/src/ripple/resource/impl/Manager.cpp @@ -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); diff --git a/src/ripple/resource/ripple_resource.h b/src/ripple/resource/ripple_resource.h index fd36c58c9c..a7da1f695a 100644 --- a/src/ripple/resource/ripple_resource.h +++ b/src/ripple/resource/ripple_resource.h @@ -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" diff --git a/src/ripple_app/ledger/InboundLedgers.cpp b/src/ripple_app/ledger/InboundLedgers.cpp index e0caa175dd..6b21dd994f 100644 --- a/src/ripple_app/ledger/InboundLedgers.cpp +++ b/src/ripple_app/ledger/InboundLedgers.cpp @@ -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 () diff --git a/src/ripple_app/main/Application.cpp b/src/ripple_app/main/Application.cpp index 093698b412..813223b655 100644 --- a/src/ripple_app/main/Application.cpp +++ b/src/ripple_app/main/Application.cpp @@ -110,10 +110,10 @@ public: , m_deprecatedUNL (UniqueNodeList::New (*m_jobQueue)) , m_rpcHTTPServer (RPCHTTPServer::New (*m_networkOPs, - LogJournal::get (), *m_jobQueue, *m_networkOPs)) + LogJournal::get (), *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 m_rpcDoor; ScopedPointer m_wsPublicDoor; ScopedPointer m_wsPrivateDoor; + ScopedPointer m_wsProxyDoor; WaitableEvent m_stop; }; diff --git a/src/ripple_app/main/Application.h b/src/ripple_app/main/Application.h index 78f27809f3..12e5e11618 100644 --- a/src/ripple_app/main/Application.h +++ b/src/ripple_app/main/Application.h @@ -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; diff --git a/src/ripple_app/main/LoadManager.cpp b/src/ripple_app/main/LoadManager.cpp index a3f4202f59..8ab9c5cc41 100644 --- a/src/ripple_app/main/LoadManager.cpp +++ b/src/ripple_app/main/LoadManager.cpp @@ -74,13 +74,6 @@ public: typedef LockType::ScopedLockType ScopedLockType; LockType mLock; - BlackList 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 (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::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 (t)].getCost (); - } - void resetDeadlockDetector () { ScopedLockType sl (mLock, __FILE__, __LINE__); @@ -337,11 +159,6 @@ public: #endif } - void addCost (const Cost& c) - { - mCosts [static_cast (c.getLoadType ())] = c; - } - // VFALCO NOTE Where's the thread object? It's not a data member... // void run () diff --git a/src/ripple_app/main/LoadManager.h b/src/ripple_app/main/LoadManager.h index 43d5347ed0..bf713ffa40 100644 --- a/src/ripple_app/main/LoadManager.h +++ b/src/ripple_app/main/LoadManager.h @@ -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::mCreditLimit / 2)) = 0; }; #endif diff --git a/src/ripple_app/main/RPCHTTPServer.cpp b/src/ripple_app/main/RPCHTTPServer.cpp index af3a749cf0..805de65322 100644 --- a/src/ripple_app/main/RPCHTTPServer.cpp +++ b/src/ripple_app/main/RPCHTTPServer.cpp @@ -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); } diff --git a/src/ripple_app/main/RPCHTTPServer.h b/src/ripple_app/main/RPCHTTPServer.h index 10dbb32b88..914032bfa3 100644 --- a/src/ripple_app/main/RPCHTTPServer.h +++ b/src/ripple_app/main/RPCHTTPServer.h @@ -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 () { } diff --git a/src/ripple_app/main/RippleMain.cpp b/src/ripple_app/main/RippleMain.cpp index 62a702a7b4..66ed1b19b7 100644 --- a/src/ripple_app/main/RippleMain.cpp +++ b/src/ripple_app/main/RippleMain.cpp @@ -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; diff --git a/src/ripple_app/misc/NetworkOPs.cpp b/src/ripple_app/misc/NetworkOPs.cpp index f95b28c09e..0b2f569cac 100644 --- a/src/ripple_app/misc/NetworkOPs.cpp +++ b/src/ripple_app/misc/NetworkOPs.cpp @@ -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(cluster, protocol::mtCLUSTER); getApp().getPeers().relayMessageCluster (NULL, message); diff --git a/src/ripple_app/peers/Peer.cpp b/src/ripple_app/peers/Peer.cpp index 91300eccb6..e55220f9d7 100644 --- a/src/ripple_app/peers/Peer.cpp +++ b/src/ripple_app/peers/Peer.cpp @@ -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(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 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& packe if (san.isInvalid ()) { charge (Resource::feeUnwantedData); - applyLoadCharge (LT_UnwantedData); } return; @@ -2443,7 +2430,6 @@ void PeerImp::recvLedger (const boost::shared_ptr& 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, ProofOfWork::pointer pow) { if (peer.expired ()) @@ -2658,7 +2617,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr& { 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& { 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& { 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& { 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, Resource::Charge const& fee) if (p != nullptr) p->charge (fee); } - -void Peer::applyLoadCharge (boost::weak_ptr & peerToPunish, - LoadType loadThatWasImposed) -{ - Peer::pointer p = peerToPunish.lock (); - - if (p != nullptr) - { - p->applyLoadCharge (loadThatWasImposed); - } -} - diff --git a/src/ripple_app/peers/Peer.h b/src/ripple_app/peers/Peer.h index f494b9624b..79db345646 100644 --- a/src/ripple_app/peers/Peer.h +++ b/src/ripple_app/peers/Peer.h @@ -76,8 +76,6 @@ public: */ virtual void charge (Resource::Charge const& fee) = 0; static void charge (boost::weak_ptr & peer, Resource::Charge const& fee); - virtual void applyLoadCharge (LoadType) = 0; - static void applyLoadCharge (boost::weak_ptr & peerTOCharge, LoadType loadThatWasImposed); virtual Json::Value getJson () = 0; diff --git a/src/ripple_app/peers/Peers.cpp b/src/ripple_app/peers/Peers.cpp index bd826c6bb3..cb6ff94060 100644 --- a/src/ripple_app/peers/Peers.cpp +++ b/src/ripple_app/peers/Peers.cpp @@ -208,7 +208,6 @@ public: PeerFinder::PeerID (peer->getNodePublic()) == id) { peer->charge (Resource::feeUnwantedData); - peer->applyLoadCharge (LT_UnwantedData); break; } } diff --git a/src/ripple_app/rpc/RPCHandler.cpp b/src/ripple_app/rpc/RPCHandler.cpp index 568a04d5af..94f4953f05 100644 --- a/src/ripple_app/rpc/RPCHandler.cpp +++ b/src/ripple_app/rpc/RPCHandler.cpp @@ -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_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: // } // 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: // } -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: // } -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: // value: // } -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' : // 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: // optional // 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: // } -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: // optional // 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_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_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: // } -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 (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 (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: , // 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: , // 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: // } -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: // } -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' | | , // 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: // } -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_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: // } -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: // } -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: , // password: // } -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: // 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: |, // 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: | // } -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 : // } // 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 : // ... // } -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_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 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); } diff --git a/src/ripple_app/rpc/RPCHandler.h b/src/ripple_app/rpc/RPCHandler.h index 33f5229762..388e300be4 100644 --- a/src/ripple_app/rpc/RPCHandler.h +++ b/src/ripple_app/rpc/RPCHandler.h @@ -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: diff --git a/src/ripple_app/rpc/RPCServerHandler.cpp b/src/ripple_app/rpc/RPCServerHandler.cpp index 2c28f381ac..492e4cd8fd 100644 --- a/src/ripple_app/rpc/RPCServerHandler.cpp +++ b/src/ripple_app/rpc/RPCServerHandler.cpp @@ -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; diff --git a/src/ripple_app/rpc/RPCServerHandler.h b/src/ripple_app/rpc/RPCServerHandler.h index ff928ef854..ffbf4453bb 100644 --- a/src/ripple_app/rpc/RPCServerHandler.h +++ b/src/ripple_app/rpc/RPCServerHandler.h @@ -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 diff --git a/src/ripple_app/websocket/WSConnection.cpp b/src/ripple_app/websocket/WSConnection.cpp index 1c85eb5d44..9a5144493f 100644 --- a/src/ripple_app/websocket/WSConnection.cpp +++ b/src/ripple_app/websocket/WSConnection.cpp @@ -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 (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 diff --git a/src/ripple_app/websocket/WSConnection.h b/src/ripple_app/websocket/WSConnection.h index 535249f6cf..b56a7e604a 100644 --- a/src/ripple_app/websocket/WSConnection.h +++ b/src/ripple_app/websocket/WSConnection.h @@ -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 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) diff --git a/src/ripple_app/websocket/WSDoor.cpp b/src/ripple_app/websocket/WSDoor.cpp index ba9a2bd150..a6f137dfce 100644 --- a/src/ripple_app/websocket/WSDoor.cpp +++ b/src/ripple_app/websocket/WSDoor.cpp @@ -41,7 +41,7 @@ class WSDoorImp : public WSDoor, protected Thread, LeakChecked 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 ( - m_resourceManager, m_source, m_ssl_context, mPublic)); + websocketpp::server_multitls::handler::ptr handler ( + new WSServerHandler ( + 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 m_endpoint; + ScopedPointer 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 door; try { door = new WSDoorImp (resourceManager, - source, strIp, iPort, bPublic, ssl_context); + source, strIp, iPort, bPublic, bProxy, ssl_context); } catch (...) { diff --git a/src/ripple_app/websocket/WSDoor.h b/src/ripple_app/websocket/WSDoor.h index 886f894843..172ab78f4b 100644 --- a/src/ripple_app/websocket/WSDoor.h +++ b/src/ripple_app/websocket/WSDoor.h @@ -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 diff --git a/src/ripple_app/websocket/WSServerHandler.h b/src/ripple_app/websocket/WSServerHandler.h index 6043c8ab82..7966beb182 100644 --- a/src/ripple_app/websocket/WSServerHandler.h +++ b/src/ripple_app/websocket/WSServerHandler.h @@ -72,15 +72,17 @@ protected: boost::unordered_map > > 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 (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) diff --git a/src/ripple_core/functional/Config.cpp b/src/ripple_core/functional/Config.cpp index 7a4d73f403..b98ba1dee5 100644 --- a/src/ripple_core/functional/Config.cpp +++ b/src/ripple_core/functional/Config.cpp @@ -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 (strTemp); + (void) SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_IP, WEBSOCKET_PROXY_IP); + + if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_PORT, strTemp)) + WEBSOCKET_PROXY_PORT = lexicalCastThrow (strTemp); + if (SectionSingleB (secConfig, SECTION_WEBSOCKET_SECURE, strTemp)) WEBSOCKET_SECURE = lexicalCastThrow (strTemp); if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PUBLIC_SECURE, strTemp)) WEBSOCKET_PUBLIC_SECURE = lexicalCastThrow (strTemp); + if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_SECURE, strTemp)) + WEBSOCKET_PROXY_SECURE = lexicalCastThrow (strTemp); + if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PING_FREQ, strTemp)) WEBSOCKET_PING_FREQ = lexicalCastThrow (strTemp); diff --git a/src/ripple_core/functional/Config.h b/src/ripple_core/functional/Config.h index 7fb3691e57..047cb67f7f 100644 --- a/src/ripple_core/functional/Config.h +++ b/src/ripple_core/functional/Config.h @@ -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; diff --git a/src/ripple_core/functional/ConfigSections.h b/src/ripple_core/functional/ConfigSections.h index 11a795cdf8..e1b0698a70 100644 --- a/src/ripple_core/functional/ConfigSections.h +++ b/src/ripple_core/functional/ConfigSections.h @@ -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" diff --git a/src/ripple_core/functional/LoadSource.h b/src/ripple_core/functional/LoadSource.h deleted file mode 100644 index 4188b6580c..0000000000 --- a/src/ripple_core/functional/LoadSource.h +++ /dev/null @@ -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 diff --git a/src/ripple_core/ripple_core.h b/src/ripple_core/ripple_core.h index 56f4ea54f6..c59246ed27 100644 --- a/src/ripple_core/ripple_core.h +++ b/src/ripple_core/ripple_core.h @@ -41,7 +41,6 @@ namespace ripple # include "functional/LoadMonitor.h" # include "functional/Job.h" #include "functional/JobQueue.h" -#include "functional/LoadSource.h" } diff --git a/src/ripple_data/protocol/ripple.proto b/src/ripple_data/protocol/ripple.proto index 92e86669a6..979eab9285 100644 --- a/src/ripple_data/protocol/ripple.proto +++ b/src/ripple_data/protocol/ripple.proto @@ -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; } diff --git a/src/ripple_net/ripple_net.h b/src/ripple_net/ripple_net.h index 3e00044414..7cfe69b003 100644 --- a/src/ripple_net/ripple_net.h +++ b/src/ripple_net/ripple_net.h @@ -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" diff --git a/src/ripple_net/rpc/InfoSub.cpp b/src/ripple_net/rpc/InfoSub.cpp index 50cb5ce6f9..4c49a18423 100644 --- a/src/ripple_net/rpc/InfoSub.cpp +++ b/src/ripple_net/rpc/InfoSub.cpp @@ -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 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); diff --git a/src/ripple_net/rpc/InfoSub.h b/src/ripple_net/rpc/InfoSub.h index e4b476c52f..6c84cd6dfc 100644 --- a/src/ripple_net/rpc/InfoSub.h +++ b/src/ripple_net/rpc/InfoSub.h @@ -40,6 +40,8 @@ public: typedef const boost::shared_ptr& 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 mSubAccountInfo; boost::unordered_set mSubAccountTransaction; diff --git a/src/ripple_net/rpc/RPCSub.cpp b/src/ripple_net/rpc/RPCSub.cpp index f735771bff..cd63c56aaa 100644 --- a/src/ripple_net/rpc/RPCSub.cpp +++ b/src/ripple_net/rpc/RPCSub.cpp @@ -195,7 +195,7 @@ private: //------------------------------------------------------------------------------ RPCSub::RPCSub (InfoSub::Source& source) - : InfoSub (source) + : InfoSub (source, Consumer()) { } diff --git a/src/ripple_net/rpc/RPCSub.h b/src/ripple_net/rpc/RPCSub.h index a9c6d5b1cb..6cfe49c14c 100644 --- a/src/ripple_net/rpc/RPCSub.h +++ b/src/ripple_net/rpc/RPCSub.h @@ -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: diff --git a/src/ripple_websocket/ripple_websocket.h b/src/ripple_websocket/ripple_websocket.h index 656e77ccda..94eeedec5a 100644 --- a/src/ripple_websocket/ripple_websocket.h +++ b/src/ripple_websocket/ripple_websocket.h @@ -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 @@ -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" diff --git a/src/websocket/src/connection.hpp b/src/websocket/src/connection.hpp index 52863efdf8..9d2ff11e24 100644 --- a/src/websocket/src/connection.hpp +++ b/src/websocket/src/connection.hpp @@ -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, diff --git a/src/websocket/src/endpoint.hpp b/src/websocket/src/endpoint.hpp index 862243c1c2..c457ef5d78 100644 --- a/src/websocket/src/endpoint.hpp +++ b/src/websocket/src/endpoint.hpp @@ -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 @@ -74,7 +74,7 @@ protected: */ template < template class role, - template class socket = socket::autotls, + template class socket = socket::multitls, template class logger = log::logger> class endpoint : public endpoint_base, diff --git a/src/websocket/src/roles/server.hpp b/src/websocket/src/roles/server.hpp index 6f5396d1cf..cc701e2b29 100644 --- a/src/websocket/src/roles/server.hpp +++ b/src/websocket/src/roles/server.hpp @@ -410,7 +410,7 @@ void server::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 void server::handle_accept(connection_ptr con, const boost::system::error_code& error) { - bool delay = false; + bool delay = false; boost::lock_guard lock(m_endpoint.m_lock); @@ -554,18 +554,19 @@ void server::connection::async_init() { static boost::arg<1> pl1; static boost::arg<2> pl2; - boost::shared_ptr stringPtr = boost::make_shared(); - 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 stringPtr = boost::make_shared(); + 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::connection::handle_read_request( std::string reply = "" "(m_connection.get_raw_socket().local_endpoint().port()); - reply += "\"/>"; - reply.append("\0", 1); + reply += beast::lexicalCastThrow (m_connection.get_native_socket().local_endpoint().port()); + reply += "\"/>"; + 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::connection::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::connection::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; diff --git a/src/websocket/src/sockets/multitls.hpp b/src/websocket/src/sockets/multitls.hpp new file mode 100644 index 0000000000..4c69f638ab --- /dev/null +++ b/src/websocket/src/sockets/multitls.hpp @@ -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 +class multitls { +public: + typedef multitls type; + typedef ripple::MultiSocket multitls_socket; + typedef boost::asio::ip::tcp::socket native_socket_t; + typedef boost::shared_ptr 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 + class connection { + public: + + multitls_socket& get_socket() { + return *m_socket_ptr; + } + + native_socket_t& get_native_socket() { + return m_socket_ptr->next_layer (); + } + + bool is_secure() { + return m_socket_ptr->ssl_handle() != NULL; + } + protected: + connection(multitls& 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 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::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::handle_shutdown, + m_socket_ptr, + boost::asio::placeholders::error + ) + ); + + if (ignored_ec) { + return false; + } else { + return true; + } + } + private: + boost::shared_ptr m_context_ptr; + multitls_socket_ptr m_socket_ptr; + multitls& 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 diff --git a/src/websocket/src/websocketpp.hpp b/src/websocket/src/websocketpp.hpp index c6692a9ba3..8ae9e804af 100644 --- a/src/websocket/src/websocketpp.hpp +++ b/src/websocket/src/websocketpp.hpp @@ -41,9 +41,9 @@ namespace websocketpp { typedef websocketpp::endpoint server_tls; #endif - #ifdef WEBSOCKETPP_SOCKET_AUTOTLS_HPP + #ifdef WEBSOCKETPP_SOCKET_MULTITLS_HPP typedef websocketpp::endpoint server_autotls; + websocketpp::socket::multitls> server_multitls; #endif #endif