Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2012-12-06 20:16:19 -08:00
23 changed files with 319 additions and 189 deletions

View File

@@ -143,6 +143,7 @@
<ClCompile Include="src\cpp\ripple\Peer.cpp" />
<ClCompile Include="src\cpp\ripple\PeerDoor.cpp" />
<ClCompile Include="src\cpp\ripple\PlatRand.cpp" />
<ClCompile Include="src\cpp\ripple\ProofOfWork.cpp" />
<ClCompile Include="src\cpp\ripple\PubKeyCache.cpp" />
<ClCompile Include="src\cpp\ripple\RangeSet.cpp" />
<ClCompile Include="src\cpp\ripple\RegularKeySetTransactor.cpp" />
@@ -184,6 +185,7 @@
<ClCompile Include="src\cpp\ripple\WalletAddTransactor.cpp" />
<ClCompile Include="src\cpp\ripple\WSConnection.cpp" />
<ClCompile Include="src\cpp\ripple\WSDoor.cpp" />
<ClCompile Include="src\cpp\ripple\WSHandler.cpp" />
<ClCompile Include="src\cpp\websocketpp\src\base64\base64.cpp" />
<ClCompile Include="src\cpp\websocketpp\src\md5\md5.c" />
<ClCompile Include="src\cpp\websocketpp\src\messages\data.cpp" />
@@ -295,6 +297,17 @@
<ClInclude Include="src\cpp\ripple\WSConnection.h" />
<ClInclude Include="src\cpp\ripple\WSDoor.h" />
<ClInclude Include="src\cpp\ripple\WSHandler.h" />
<ClInclude Include="src\cpp\websocketpp\src\common.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\connection.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\endpoint.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\network_utilities.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\shared_const_buffer.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\sockets\plain.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\sockets\socket_base.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\sockets\tls.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\uri.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\websocketpp.hpp" />
<ClInclude Include="src\cpp\websocketpp\src\websocket_frame.hpp" />
<ClInclude Include="util\pugiconfig.hpp" />
<ClInclude Include="util\pugixml.hpp" />
</ItemGroup>

View File

@@ -31,6 +31,9 @@
<Filter Include="Source Files\websocketpp">
<UniqueIdentifier>{92775c5f-dc9f-4a97-a9a6-6d4bd4e424b4}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\websocket">
<UniqueIdentifier>{cd4c41c0-3ee6-49f8-8322-d11422b892f9}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\cpp\database\database.cpp">
@@ -351,6 +354,12 @@
<ClCompile Include="src\cpp\ripple\AccountItems.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\cpp\ripple\ProofOfWork.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\cpp\ripple\WSHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="util\pugiconfig.hpp">
@@ -656,6 +665,39 @@
<ClInclude Include="src\cpp\ripple\AccountItems.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\common.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\connection.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\endpoint.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\network_utilities.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\shared_const_buffer.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\uri.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\websocket_frame.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\websocketpp.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\sockets\plain.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\sockets\socket_base.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
<ClInclude Include="src\cpp\websocketpp\src\sockets\tls.hpp">
<Filter>Header Files\websocket</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="wallet.xml" />

View File

@@ -45,8 +45,8 @@ Application::Application() :
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mWSPublicDoor(NULL), mWSPrivateDoor(NULL),
mSweepTimer(mAuxService)
{
RAND_bytes(mNonce256.begin(), mNonce256.size());
RAND_bytes(reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
getRand(mNonce256.begin(), mNonce256.size());
getRand(reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
mJobQueue.setThreadCount();
mSweepTimer.expires_from_now(boost::posix_time::seconds(60));
mSweepTimer.async_wait(boost::bind(&Application::sweep, this));

View File

@@ -39,6 +39,10 @@
#define SECTION_WEBSOCKET_PUBLIC_PORT "websocket_public_port"
#define SECTION_WEBSOCKET_IP "websocket_ip"
#define SECTION_WEBSOCKET_PORT "websocket_port"
#define SECTION_WEBSOCKET_SECURE "websocket_secure"
#define SECTION_WEBSOCKET_SSL_CERT "websocket_ssl_cert"
#define SECTION_WEBSOCKET_SSL_CHAIN "websocket_ssl_chain"
#define SECTION_WEBSOCKET_SSL_KEY "websocket_ssl_key"
#define SECTION_VALIDATORS "validators"
#define SECTION_VALIDATORS_SITE "validators_site"
@@ -134,6 +138,7 @@ void Config::setup(const std::string& strConf, bool bQuiet)
RPC_PORT = 5001;
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT;
WEBSOCKET_SECURE = false;
NUMBER_CONNECTIONS = 30;
// a new ledger every minute
@@ -256,6 +261,14 @@ void Config::load()
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_PUBLIC_PORT, strTemp))
WEBSOCKET_PUBLIC_PORT = boost::lexical_cast<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_SECURE, strTemp))
WEBSOCKET_SECURE = boost::lexical_cast<bool>(strTemp);
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CERT, WEBSOCKET_SSL_CERT);
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CHAIN, WEBSOCKET_SSL_CHAIN);
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_KEY, WEBSOCKET_SSL_KEY);
if (sectionSingleB(secConfig, SECTION_VALIDATION_SEED, strTemp))
{
VALIDATION_SEED.setSeedGeneric(strTemp);

View File

@@ -91,6 +91,10 @@ public:
std::string WEBSOCKET_IP;
int WEBSOCKET_PORT;
bool WEBSOCKET_SECURE;
std::string WEBSOCKET_SSL_CERT;
std::string WEBSOCKET_SSL_CHAIN;
std::string WEBSOCKET_SSL_KEY;
// RPC parameters
std::string RPC_IP;

View File

@@ -116,8 +116,7 @@ std::vector<unsigned char> CKey::encryptECIES(CKey& otherKey, const std::vector<
{
ECIES_ENC_IV_TYPE iv;
if (RAND_bytes(static_cast<unsigned char *>(iv.begin()), ECIES_ENC_BLK_SIZE) != 1)
throw std::runtime_error("insufficient entropy");
getRand(static_cast<unsigned char *>(iv.begin()), ECIES_ENC_BLK_SIZE);
ECIES_ENC_KEY_TYPE secret;
ECIES_HMAC_KEY_TYPE hmacKey;
@@ -280,8 +279,7 @@ bool checkECIES(void)
std::vector<unsigned char> message(4096);
int msglen = i%3000;
if (RAND_bytes(static_cast<unsigned char *>(&message.front()), msglen) != 1)
throw std::runtime_error("insufficient entropy");
getRand(static_cast<unsigned char *>(&message.front()), msglen);
message.resize(msglen);
// encrypt message with sender's private key and recipient's public key

View File

@@ -867,8 +867,10 @@ void NetworkOPs::consensusViewChange()
void NetworkOPs::setMode(OperatingMode om)
{
if (mMode == om) return;
if ((om >= omCONNECTED) && (mMode == omDISCONNECTED))
mConnectTime = boost::posix_time::second_clock::universal_time();
Log lg((om < mMode) ? lsWARNING : lsINFO);
if (om == omDISCONNECTED)
lg << "STATE->Disconnected";
@@ -878,6 +880,25 @@ void NetworkOPs::setMode(OperatingMode om)
lg << "STATE->Tracking";
else
lg << "STATE->Full";
if ((om == omDISCONNECTED) || (mMode == omDISCONNECTED))
{
boost::recursive_mutex::scoped_lock sl(mMonitorLock);
if (!mSubServer.empty())
{
Json::Value jvObj(Json::objectValue);
jvObj["type"] = "serverStatus";
jvObj["server_status"] = om >= omCONNECTED ? "ok" : "noNetwork";
BOOST_FOREACH(InfoSub* ispListener, mSubServer)
{
ispListener->send(jvObj);
}
}
}
mMode = om;
}
@@ -1311,19 +1332,8 @@ bool NetworkOPs::subServer(InfoSub* ispListener, Json::Value& jvResult)
jvResult["stand_alone"] = theConfig.RUN_STANDALONE;
switch (RAND_bytes(uRandom.begin(), uRandom.size()))
{
case 0:
case 1:
getRand(uRandom.begin(), uRandom.size());
jvResult["random"] = uRandom.ToString();
break;
case -1:
default:
// XXX Should probably stop running.
cLog(lsFATAL) << "Internal error: unable to generate secure random.";
break;
}
return mSubServer.insert(ispListener).second;
}

View File

@@ -61,7 +61,7 @@ uint256 ProofOfWork::solve(int maxIterations) const
throw std::runtime_error("invalid proof of work target/iteration");
uint256 nonce;
RAND_bytes(nonce.begin(), nonce.size());
getRand(nonce.begin(), nonce.size());
std::vector<uint256> buf2;
buf2.resize(mIterations);
@@ -112,7 +112,7 @@ bool ProofOfWork::checkSolution(const uint256& solution) const
ProofOfWorkGenerator::ProofOfWorkGenerator() : mValidTime(180)
{
setDifficulty(1);
RAND_bytes(mSecret.begin(), mSecret.size());
getRand(mSecret.begin(), mSecret.size());
}
ProofOfWork ProofOfWorkGenerator::getProof()
@@ -123,7 +123,7 @@ ProofOfWork ProofOfWorkGenerator::getProof()
int now = static_cast<int>(time(NULL) / 4);
uint256 challenge;
RAND_bytes(challenge.begin(), challenge.size());
getRand(challenge.begin(), challenge.size());
boost::mutex::scoped_lock sl(mLock);

View File

@@ -58,7 +58,6 @@ Json::Value rpcError(int iError, Json::Value jvResult)
{ rpcSRC_ACT_MISSING, "srcActMissing", "Source account does not exist." },
{ rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency/issuer is malformed." },
{ rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." },
{ rpcSUCCESS, "success", "Success." },
{ rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." },
{ rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." },
{ rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." },

View File

@@ -4,8 +4,7 @@
#include "../json/value.h"
enum {
rpcSUCCESS,
rpcSUCCESS = 0,
rpcBAD_SYNTAX, // Must be 1 to print usage to command line.
rpcJSON_RPC,

View File

@@ -664,23 +664,15 @@ Json::Value RPCHandler::doRandom(Json::Value jvRequest)
{
uint256 uRandom;
switch (RAND_bytes(uRandom.begin(), uRandom.size()))
{
case 0:
case 1:
try
{
getRand(uRandom.begin(), uRandom.size());
Json::Value jvResult;
jvResult["random"] = uRandom.ToString();
return jvResult;
}
break;
case -1:
return rpcError(rpcNOT_SUPPORTED);
default:
catch (...)
{
return rpcError(rpcINTERNAL);
}
}
@@ -1572,7 +1564,7 @@ Json::Value RPCHandler::doLogLevel(Json::Value jvRequest)
if (!jvRequest.isMember("partition"))
{ // set base log severity
Log::setMinSeverity(sv, true);
return rpcError(rpcSUCCESS);
return Json::objectValue;
}
// log_level partition severity base?
@@ -1584,7 +1576,7 @@ Json::Value RPCHandler::doLogLevel(Json::Value jvRequest)
else if (!LogPartition::setSeverity(partition, sv))
return rpcError(rpcINVALID_PARAMS);
return rpcError(rpcSUCCESS);
return Json::objectValue;
}
return rpcError(rpcINVALID_PARAMS);
@@ -2092,6 +2084,7 @@ Json::Value RPCHandler::doSubscribe(Json::Value jvRequest)
if(streamName=="server")
{
mNetOps->subServer(mInfoSub, jvResult);
jvResult["server_status"] = mNetOps->available() ? "ok" : "noNetwork";
}else if(streamName=="ledger")
{
mNetOps->subLedger(mInfoSub, jvResult);

View File

@@ -792,7 +792,7 @@ void RippleAddress::setSeedRandom()
// XXX Maybe we should call MakeNewKey
uint128 key;
RAND_bytes(key.begin(), key.size());
getRand(key.begin(), key.size());
RippleAddress::setSeed(key);
}

View File

@@ -78,7 +78,7 @@ void SNTPClient::resolveComplete(const boost::system::error_code& error, boost::
}
query.mReceivedReply = false;
query.mLocalTimeSent = now;
RAND_bytes(reinterpret_cast<unsigned char *>(&query.mQueryNonce), sizeof(query.mQueryNonce));
getRand(reinterpret_cast<unsigned char *>(&query.mQueryNonce), sizeof(query.mQueryNonce));
reinterpret_cast<uint32*>(SNTPQueryData)[NTP_OFF_XMITTS_INT] = time(NULL) + NTP_UNIX_OFFSET;
reinterpret_cast<uint32*>(SNTPQueryData)[NTP_OFF_XMITTS_FRAC] = query.mQueryNonce;
mSocket.async_send_to(boost::asio::buffer(SNTPQueryData, 48), *sel,

View File

@@ -1,102 +0,0 @@
//
// WSConnection
//
#include "Log.h"
SETUP_LOG();
#include "CallRPC.h" // XXX Remove this, don't provide support for RPC syntax.
#include "WSConnection.h"
#include "WSHandler.h"
#include "../json/reader.h"
#include "../json/writer.h"
WSConnection::~WSConnection()
{
mNetwork.unsubTransactions(this);
mNetwork.unsubRTTransactions(this);
mNetwork.unsubLedger(this);
mNetwork.unsubServer(this);
mNetwork.unsubAccount(this, mSubAccountInfo, true);
mNetwork.unsubAccount(this, mSubAccountInfo, false);
}
void WSConnection::send(const Json::Value& jvObj)
{
mHandler->send(mConnection, jvObj);
}
//
// Utilities
//
Json::Value WSConnection::invokeCommand(Json::Value& jvRequest)
{
if (!jvRequest.isMember("command"))
{
Json::Value jvResult(Json::objectValue);
jvResult["type"] = "response";
jvResult["result"] = "error";
jvResult["error"] = "missingCommand";
jvResult["command"] = jvRequest;
return jvResult;
}
RPCHandler mRPCHandler(&mNetwork, this);
Json::Value jvResult(Json::objectValue);
// XXX Temporarily support RPC style commands over websocket. Remove this.
if (jvRequest.isMember("params"))
{
RPCParser rpParser;
Json::Value jvRpcRequest = rpParser.parseCommand(jvRequest["command"].asString(), jvRequest["params"]);
if (jvRpcRequest.isMember("error"))
{
jvResult = jvRpcRequest;
}
else
{
jvResult["result"] = mRPCHandler.doCommand(
jvRpcRequest,
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
}
}
else
{
jvResult["result"] = mRPCHandler.doCommand(
jvRequest,
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
}
// Currently we will simply unwrap errors returned by the RPC
// API, in the future maybe we can make the responses
// consistent.
//
// Regularize result. This is duplicate code.
if (jvResult["result"].isMember("error"))
{
jvResult = jvResult["result"];
jvResult["status"] = "error";
jvResult["request"] = jvRequest;
} else {
jvResult["status"] = "success";
}
if (jvRequest.isMember("id"))
{
jvResult["id"] = jvRequest["id"];
}
jvResult["type"] = "response";
return jvResult;
}
// vim:ts=4

View File

@@ -1,10 +1,14 @@
#include "../websocketpp/src/sockets/tls.hpp"
#include "../websocketpp/src/websocketpp.hpp"
#include "../json/value.h"
#include "WSDoor.h"
#include "Application.h"
#include "Log.h"
#include "NetworkOPs.h"
#include "CallRPC.h"
template <typename endpoint_type>
class WSServerHandler;
@@ -12,16 +16,17 @@ class WSServerHandler;
// Storage for connection specific info
// - Subscriptions
//
template <typename endpoint_type>
class WSConnection : public InfoSub
{
public:
typedef websocketpp::WSDOOR_SERVER::handler::connection_ptr connection_ptr;
typedef websocketpp::WSDOOR_SERVER::handler::message_ptr message_ptr;
typedef typename endpoint_type::handler::connection_ptr connection_ptr;
typedef typename endpoint_type::handler::message_ptr message_ptr;
protected:
typedef void (WSConnection::*doFuncPtr)(Json::Value& jvResult, Json::Value &jvRequest);
WSServerHandler<websocketpp::WSDOOR_SERVER>* mHandler;
WSServerHandler<endpoint_type>* mHandler;
connection_ptr mConnection;
NetworkOPs& mNetwork;
@@ -30,17 +35,95 @@ public:
// : mHandler((WSServerHandler<websocketpp::WSDOOR_SERVER>*)(NULL)),
// mConnection(connection_ptr()) { ; }
WSConnection(WSServerHandler<websocketpp::WSDOOR_SERVER>* wshpHandler, connection_ptr cpConnection)
WSConnection(WSServerHandler<endpoint_type>* wshpHandler, connection_ptr cpConnection)
: mHandler(wshpHandler), mConnection(cpConnection), mNetwork(theApp->getOPs()) { ; }
virtual ~WSConnection();
virtual ~WSConnection()
{
mNetwork.unsubTransactions(this);
mNetwork.unsubRTTransactions(this);
mNetwork.unsubLedger(this);
mNetwork.unsubServer(this);
mNetwork.unsubAccount(this, mSubAccountInfo, true);
mNetwork.unsubAccount(this, mSubAccountInfo, false);
}
// Implement overridden functions from base class:
void send(const Json::Value& jvObj);
void send(const Json::Value& jvObj)
{
mHandler->send(mConnection, jvObj);
}
// Utilities
Json::Value invokeCommand(Json::Value& jvRequest);
Json::Value invokeCommand(Json::Value& jvRequest)
{
if (!jvRequest.isMember("command"))
{
Json::Value jvResult(Json::objectValue);
jvResult["type"] = "response";
jvResult["result"] = "error";
jvResult["error"] = "missingCommand";
jvResult["command"] = jvRequest;
return jvResult;
}
RPCHandler mRPCHandler(&mNetwork, this);
Json::Value jvResult(Json::objectValue);
// XXX Temporarily support RPC style commands over websocket. Remove this.
if (jvRequest.isMember("params"))
{
RPCParser rpParser;
Json::Value jvRpcRequest = rpParser.parseCommand(jvRequest["command"].asString(), jvRequest["params"]);
if (jvRpcRequest.isMember("error"))
{
jvResult = jvRpcRequest;
}
else
{
jvResult["result"] = mRPCHandler.doCommand(
jvRpcRequest,
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
}
}
else
{
jvResult["result"] = mRPCHandler.doCommand(
jvRequest,
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
}
// Currently we will simply unwrap errors returned by the RPC
// API, in the future maybe we can make the responses
// consistent.
//
// Regularize result. This is duplicate code.
if (jvResult["result"].isMember("error"))
{
jvResult = jvResult["result"];
jvResult["status"] = "error";
jvResult["request"] = jvRequest;
} else {
jvResult["status"] = "success";
}
if (jvRequest.isMember("id"))
{
jvResult["id"] = jvRequest["id"];
}
jvResult["type"] = "response";
return jvResult;
}
};
// vim:ts=4

View File

@@ -9,6 +9,7 @@ SETUP_LOG();
#include "utils.h"
#include "WSConnection.h"
#include "WSHandler.h"
#include "Config.h"
#include "WSDoor.h"
@@ -53,11 +54,30 @@ void WSDoor::startListening()
SSL_CTX_set_tmp_dh_callback(mCtx->native_handle(), handleTmpDh);
if(theConfig.WEBSOCKET_SECURE)
{
// Construct a single handler for all requests.
websocketpp::WSDOOR_SERVER::handler::ptr handler(new WSServerHandler<websocketpp::WSDOOR_SERVER>(mCtx, mPublic));
websocketpp::server_tls::handler::ptr handler(new WSServerHandler<websocketpp::server_tls>(mCtx, mPublic));
// Construct a websocket server.
mEndpoint = new websocketpp::WSDOOR_SERVER(handler);
mSEndpoint = new websocketpp::server_tls(handler);
// mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL);
// mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL);
// Call the main-event-loop of the websocket server.
mSEndpoint->listen(
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address().from_string(mIp), mPort));
delete mSEndpoint;
}else
{
// Construct a single handler for all requests.
websocketpp::server::handler::ptr handler(new WSServerHandler<websocketpp::server>(mCtx, mPublic));
// Construct a websocket server.
mEndpoint = new websocketpp::server(handler);
// mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL);
// mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL);
@@ -68,6 +88,8 @@ void WSDoor::startListening()
boost::asio::ip::address().from_string(mIp), mPort));
delete mEndpoint;
}
}
WSDoor* WSDoor::createWSDoor(const std::string& strIp, const int iPort, bool bPublic)
@@ -89,7 +111,11 @@ void WSDoor::stop()
{
if (mThread)
{
if (mEndpoint)
mEndpoint->stop();
if (mSEndpoint)
mSEndpoint->stop();
mThread->join();
}

View File

@@ -10,16 +10,12 @@
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#if 1
#define WSDOOR_SERVER server
#else
#define WSDOOR_SERVER server_tls
#endif
class WSDoor
{
private:
websocketpp::WSDOOR_SERVER* mEndpoint;
websocketpp::server* mEndpoint;
websocketpp::server_tls* mSEndpoint;
boost::thread* mThread;
bool mPublic;
std::string mIp;
@@ -29,7 +25,7 @@ private:
public:
WSDoor(const std::string& strIp, int iPort, bool bPublic) : mEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; }
WSDoor(const std::string& strIp, int iPort, bool bPublic) : mEndpoint(0), mSEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; }
void stop();

View File

@@ -2,7 +2,9 @@
#define __WSHANDLER__
#include "Application.h"
#include "Config.h"
template <typename endpoint_type>
class WSConnection;
// A single instance of this object is made.
@@ -25,7 +27,7 @@ private:
protected:
boost::mutex mMapLock;
// For each connection maintain an associated object to track subscriptions.
boost::unordered_map<connection_ptr, boost::shared_ptr<WSConnection> > mMap;
boost::unordered_map<connection_ptr, boost::shared_ptr< WSConnection<endpoint_type> > > mMap;
bool mPublic;
public:
@@ -33,10 +35,7 @@ public:
bool getPublic() { return mPublic; };
boost::shared_ptr<boost::asio::ssl::context> on_tls_init()
{
return mCtx;
}
void send(connection_ptr cpClient, message_ptr mpMessage)
{
@@ -77,7 +76,7 @@ public:
{
boost::mutex::scoped_lock sl(mMapLock);
mMap[cpClient] = boost::make_shared<WSConnection>(this, cpClient);
mMap[cpClient] = boost::make_shared< WSConnection<endpoint_type> >(this, cpClient);
}
void on_close(connection_ptr cpClient)
@@ -116,7 +115,7 @@ public:
}
else
{
boost::shared_ptr<WSConnection> conn;
boost::shared_ptr< WSConnection<endpoint_type> > conn;
{
boost::mutex::scoped_lock sl(mMapLock);
conn = mMap[cpClient];
@@ -127,6 +126,35 @@ public:
}
}
boost::shared_ptr<boost::asio::ssl::context> on_tls_init()
{
if(theConfig.WEBSOCKET_SECURE)
{
// create a tls context, init, and return.
boost::shared_ptr<boost::asio::ssl::context> context(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
try {
context->set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::single_dh_use);
// context->set_password_callback(boost::bind(&type::get_password, this));
if (!theConfig.WEBSOCKET_SSL_CERT.empty())
context->use_certificate_file(theConfig.WEBSOCKET_SSL_CERT, boost::asio::ssl::context::pem);
if (!theConfig.WEBSOCKET_SSL_KEY.empty())
context->use_private_key_file(theConfig.WEBSOCKET_SSL_KEY, boost::asio::ssl::context::pem);
if (!theConfig.WEBSOCKET_SSL_CHAIN.empty())
context->use_certificate_chain_file(theConfig.WEBSOCKET_SSL_CHAIN);
//context->use_tmp_dh_file("../../src/ssl/dh512.pem");
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
return context;
}else
{
return mCtx;
}
}
// Respond to http requests.
void http(connection_ptr cpClient)
{

View File

@@ -5,6 +5,17 @@
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
#include <openssl/rand.h>
void getRand(unsigned char *buf, int num)
{
if (RAND_bytes(buf, num) != 1)
{
assert(false);
throw std::runtime_error("Entropy pool not seeded");
}
}
//
// Time support
// We have our own epoch.

View File

@@ -189,6 +189,10 @@ bool parseQuality(const std::string& strSource, uint32& uQuality);
DH* DH_der_load(const std::string& strDer);
std::string DH_der_gen(int iKeyLength);
void getRand(unsigned char *buf, int num);
inline static void getRand(char *buf, int num) { return getRand(reinterpret_cast<unsigned char *>(buf), num); }
inline static void getRand(void *buf, int num) { return getRand(reinterpret_cast<unsigned char *>(buf), num); }
inline std::string strGetEnv(const std::string& strKey)
{
return getenv(strKey.c_str()) ? getenv(strKey.c_str()) : "";

View File

@@ -499,12 +499,16 @@ Amount.prototype.to_human = function (opts)
if ("undefined" === typeof opts.group_sep) opts.group_sep = true;
opts.group_width = opts.group_width || 3;
var denominator = this._is_native ?
consts.bi_xns_unit :
consts.bi_10.clone().pow(-this._offset);
var order = this._is_native ? consts.xns_precision : -this._offset;
var denominator = consts.bi_10.clone().pow(order);
var int_part = this._value.divide(denominator).toString(10);
var fraction_part = this._value.mod(denominator).toString(10);
// Add leading zeros to fraction
while (fraction_part.length < order) {
fraction_part = "0" + fraction_part;
}
int_part = int_part.replace(/^0*/, '');
fraction_part = fraction_part.replace(/0*$/, '');

View File

@@ -191,6 +191,7 @@ var Remote = function (opts, trace) {
this.trusted = opts.trusted;
this.websocket_ip = opts.websocket_ip;
this.websocket_port = opts.websocket_port;
this.websocket_ssl = opts.websocket_ssl;
this.local_sequence = opts.local_sequence; // Locally track sequence numbers
this.local_fee = opts.local_fee; // Locally set fees
this.id = 0;
@@ -384,7 +385,8 @@ Remote.prototype._connect_start = function () {
// with self-signed certs as the user must have pre-approved the self-signed certs.
var self = this;
var url = "ws://" + this.websocket_ip + ":" + this.websocket_port;
var url = (this.websocket_ssl ? "wss://" : "ws://") +
this.websocket_ip + ":" + this.websocket_port;
if (this.trace) console.log("remote: connect: %s", url);
@@ -412,8 +414,6 @@ Remote.prototype._connect_start = function () {
};
if (self.online_target) {
self._set_state('online');
// Note, we could get disconnected before this goes through.
self._server_subscribe(); // Automatically subscribe.
}
@@ -493,6 +493,10 @@ Remote.prototype._connect_message = function (ws, json) {
this.emit('ledger_closed', message);
break;
case 'serverStatus':
this._set_state(message.server_status === 'ok' ? 'online' : 'offline');
break;
// All other messages
default:
if (this.trace) utils.logObject("remote: "+message.type+": %s", message);
@@ -852,6 +856,10 @@ Remote.prototype._server_subscribe = function () {
self.emit('ledger_closed', message);
}
if (message.server_status === "ok") {
self._set_state('online');
}
self.emit('subscribed');
})
.request();

View File

@@ -23,6 +23,7 @@ exports.servers = {
'rpc_port' : 5005,
'websocket_ip' : "127.0.0.1",
'websocket_port' : 5006,
'websocket_ssl' : false,
'local_sequence' : true,
'local_fee' : true,
// 'validation_seed' : "shhDFVsmS2GSu5vUyZSPXYfj1r79h",