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

This commit is contained in:
Arthur Britto
2013-01-25 03:23:22 -08:00
23 changed files with 833 additions and 764 deletions

View File

@@ -20,6 +20,7 @@
SETUP_LOG();
LogPartition TaggedCachePartition("TaggedCache");
LogPartition AutoSocketPartition("AutoSocket");
Application* theApp = NULL;
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)

View File

@@ -1,32 +0,0 @@
#include "AutoSocket.h"
#include <boost/bind.hpp>
void AutoSocket::handle_autodetect(const error_code& ec)
{
if (ec)
{
if (mCallback)
mCallback(ec);
return;
}
if ((mBuffer[0] < 127) && (mBuffer[0] > 31) &&
(mBuffer[1] < 127) && (mBuffer[1] > 31) &&
(mBuffer[2] < 127) && (mBuffer[2] > 31) &&
(mBuffer[3] < 127) && (mBuffer[3] > 31))
{ // non-SSL
mSecure = false;
if (mCallback)
mCallback(ec);
}
else
{ // ssl
mSecure = true;
SSLSocket().async_handshake(ssl_socket::server, mCallback);
mCallback = callback();
}
}
// vim:ts=4

View File

@@ -5,9 +5,14 @@
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include "Log.h"
extern LogPartition AutoSocketPartition;
// Socket wrapper that supports both SSL and non-SSL connections.
// Generally, handle it as you would an SSL connection.
// To force a non-SSL connection, just don't call async_handshake.
@@ -20,78 +25,140 @@ class AutoSocket
{
public:
typedef bassl::stream<basio::ip::tcp::socket> ssl_socket;
typedef boost::shared_ptr<ssl_socket> socket_ptr;
typedef ssl_socket::next_layer_type plain_socket;
typedef ssl_socket::lowest_layer_type lowest_layer_type;
typedef ssl_socket::handshake_type handshake_type;
typedef boost::system::error_code error_code;
typedef boost::function<void(error_code)> callback;
typedef boost::function<void(error_code)> callback;
protected:
ssl_socket mSocket;
socket_ptr mSocket;
bool mSecure;
callback mCallback;
std::vector<char> mBuffer;
public:
AutoSocket(basio::io_service& s, bassl::context& c) : mSocket(s, c), mSecure(false), mBuffer(4) { ; }
AutoSocket(basio::io_service& s, bassl::context& c) : mSecure(false), mBuffer(4)
{
mSocket = boost::make_shared<ssl_socket>(boost::ref(s), boost::ref(c));
}
AutoSocket(basio::io_service& s, bassl::context& c, bool secureOnly, bool plainOnly)
: mSecure(secureOnly), mBuffer((plainOnly || secureOnly) ? 0 : 4)
{
mSocket = boost::make_shared<ssl_socket>(boost::ref(s), boost::ref(c));
}
bool isSecure() { return mSecure; }
ssl_socket& SSLSocket() { return mSocket; }
plain_socket& PlainSocket() { return mSocket.next_layer(); }
ssl_socket& SSLSocket() { return *mSocket; }
plain_socket& PlainSocket() { return mSocket->next_layer(); }
void setSSLOnly() { mSecure = true;}
void setPlainOnly() { mBuffer.clear(); }
void setSSLOnly() { mBuffer.clear(); }
lowest_layer_type& lowest_layer() { return mSocket->lowest_layer(); }
void async_handshake(ssl_socket::handshake_type type, callback cbFunc)
void swap(AutoSocket& s)
{
mSecure = true;
if ((type == ssl_socket::client) || (mBuffer.empty()))
SSLSocket().async_handshake(type, cbFunc);
mBuffer.swap(s.mBuffer);
mSocket.swap(s.mSocket);
std::swap(mSecure, s.mSecure);
}
void async_handshake(handshake_type type, callback cbFunc)
{
if ((type == ssl_socket::client) || (mSecure))
{ // must be ssl
mSecure = true;
mSocket->async_handshake(type, cbFunc);
}
else if (mBuffer.empty())
{ // must be plain
mSecure = false;
mSocket->get_io_service().post(boost::bind(cbFunc, error_code()));
}
else
{
mCallback = cbFunc;
PlainSocket().async_receive(basio::buffer(mBuffer), basio::socket_base::message_peek,
boost::bind(&AutoSocket::handle_autodetect, this, basio::placeholders::error));
{ // autodetect
mSocket->next_layer().async_receive(basio::buffer(mBuffer), basio::socket_base::message_peek,
boost::bind(&AutoSocket::handle_autodetect, this, cbFunc, basio::placeholders::error));
}
}
template <typename StreamType> StreamType& getSocket()
{
if (isSecure())
return SSLSocket();
if (!isSecure())
return PlainSocket();
}
template <typename ShutdownHandler> void async_shutdown(ShutdownHandler handler)
{
if (isSecure())
SSLSocket().async_shutdown(handler);
mSocket->async_shutdown(handler);
else
{
PlainSocket().shutdown(plain_socket::shutdown_both);
if (handler)
mSocket.get_io_service().post(handler);
lowest_layer().shutdown(plain_socket::shutdown_both);
mSocket->get_io_service().post(boost::bind(handler, error_code()));
}
}
template <typename Seq, typename Handler> void async_read_some(const Seq& buffers, Handler handler)
{
if (isSecure())
SSLSocket().async_read_some(buffers, handler);
mSocket->async_read_some(buffers, handler);
else
PlainSocket().async_read_some(buffers, handler);
}
template <typename Buf, typename Handler> void async_write(const Buf& buffers, Handler handler)
{
if (isSecure())
boost::asio::async_write(*mSocket, buffers, handler);
else
boost::asio::async_write(PlainSocket(), buffers, handler);
}
template <typename Buf, typename Condition, typename Handler>
void async_read(const Buf& buffers, Condition cond, Handler handler)
{
if (isSecure())
boost::asio::async_read(*mSocket, buffers, cond, handler);
else
boost::asio::async_read(PlainSocket(), buffers, cond, handler);
}
template <typename Buf, typename Handler> void async_read(const Buf& buffers, Handler handler)
{
if (isSecure())
boost::asio::async_read(*mSocket, buffers, handler);
else
boost::asio::async_read(PlainSocket(), buffers, handler);
}
template <typename Seq, typename Handler> void async_write_some(const Seq& buffers, Handler handler)
{
if (isSecure())
SSLSocket().async_write_some(buffers, handler);
mSocket->async_write_some(buffers, handler);
else
PlainSocket().async_write_some(buffers, handler);
}
protected:
void handle_autodetect(const error_code&);
void handle_autodetect(callback cbFunc, const error_code& ec)
{
if (ec)
{
Log(lsWARNING, AutoSocketPartition) << "Handle autodetect error: " << ec;
cbFunc(ec);
}
else if ((mBuffer[0] < 127) && (mBuffer[0] > 31) &&
(mBuffer[1] < 127) && (mBuffer[1] > 31) &&
(mBuffer[2] < 127) && (mBuffer[2] > 31) &&
(mBuffer[3] < 127) && (mBuffer[3] > 31))
{ // not ssl
mSecure = false;
cbFunc(ec);
}
else
{ // ssl
mSecure = true;
mSocket->async_handshake(ssl_socket::server, cbFunc);
}
}
};
#endif

View File

@@ -178,8 +178,8 @@ Config::Config()
RPC_PORT = 5001;
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT;
WEBSOCKET_PUBLIC_SECURE = true;
WEBSOCKET_SECURE = false;
WEBSOCKET_PUBLIC_SECURE = 1;
WEBSOCKET_SECURE = 0;
NUMBER_CONNECTIONS = 30;
// a new ledger every minute
@@ -340,10 +340,10 @@ void Config::load()
WEBSOCKET_PUBLIC_PORT = boost::lexical_cast<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_SECURE, strTemp))
WEBSOCKET_SECURE = boost::lexical_cast<bool>(strTemp);
WEBSOCKET_SECURE = boost::lexical_cast<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_PUBLIC_SECURE, strTemp))
WEBSOCKET_PUBLIC_SECURE = boost::lexical_cast<bool>(strTemp);
WEBSOCKET_PUBLIC_SECURE = boost::lexical_cast<int>(strTemp);
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CERT, WEBSOCKET_SSL_CERT);
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CHAIN, WEBSOCKET_SSL_CHAIN);

View File

@@ -101,11 +101,12 @@ public:
// Websocket networking parameters
std::string WEBSOCKET_PUBLIC_IP; // XXX Going away. Merge with the inbound peer connction.
int WEBSOCKET_PUBLIC_PORT;
bool WEBSOCKET_PUBLIC_SECURE;
int WEBSOCKET_PUBLIC_SECURE;
std::string WEBSOCKET_IP;
int WEBSOCKET_PORT;
bool WEBSOCKET_SECURE;
int WEBSOCKET_SECURE;
std::string WEBSOCKET_SSL_CERT;
std::string WEBSOCKET_SSL_CHAIN;
std::string WEBSOCKET_SSL_KEY;

View File

@@ -100,9 +100,10 @@ std::vector<RippleAddress> SerializedTransaction::getMentionedAccounts() const
if (!found)
accounts.push_back(na);
}
if (it.getFName() == sfLimitAmount)
const STAmount* sam = dynamic_cast<const STAmount*>(&it);
if (sam)
{
uint160 issuer = dynamic_cast<const STAmount*>(&it)->getIssuer();
uint160 issuer = sam->getIssuer();
if (issuer.isNonZero())
{
RippleAddress na;

View File

@@ -127,28 +127,23 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
uint32 t_seq = txn.getSequence();
uint32 a_seq = txnAcct->getFieldU32(sfSequence);
if (t_seq != a_seq)
{
if (a_seq < t_seq)
terResult = terPRE_SEQ;
else
terResult = tefPAST_SEQ;
}
if (a_seq < t_seq)
terResult = terPRE_SEQ;
else if (a_seq > t_seq)
terResult = tefPAST_SEQ;
else
{
STAmount fee = txn.getTransactionFee();
STAmount balance = txnAcct->getFieldAmount(sfBalance);
if (balance < fee)
{
terResult = terINSUF_FEE_B;
}
else
{
txnAcct->setFieldAmount(sfBalance, balance - fee);
txnAcct->setFieldU32(sfSequence, t_seq + 1);
didApply = true;
entryModify(txnAcct);
didApply = true;
}
}
}

View File

@@ -81,7 +81,8 @@ std::vector<RippleAddress> TransactionMetaSet::getAffectedAccounts()
const STAccount* sa = dynamic_cast<const STAccount*>(&field);
if (sa)
addIfUnique(accounts, sa->getValueNCA());
else if ((field.getFName() == sfLowLimit) || (field.getFName() == sfHighLimit))
else if ((field.getFName() == sfLowLimit) || (field.getFName() == sfHighLimit) ||
(field.getFName() == sfTakerPays) || (field.getFName() == sfTakerGets))
{
const STAmount* lim = dynamic_cast<const STAmount*>(&field);
if (lim != NULL)

View File

@@ -1,5 +1,5 @@
#include "../websocketpp/src/sockets/tls.hpp"
#include "../websocketpp/src/sockets/autotls.hpp"
#include "../websocketpp/src/websocketpp.hpp"
#include "../json/value.h"

View File

@@ -2,7 +2,7 @@
#include "Log.h"
#define WSDOOR_CPP
#include "../websocketpp/src/sockets/tls.hpp"
#include "../websocketpp/src/sockets/autotls.hpp"
#include "../websocketpp/src/websocketpp.hpp"
SETUP_LOG();
@@ -59,80 +59,40 @@ void WSDoor::startListening()
SSL_CTX_set_tmp_dh_callback(mCtx->native_handle(), handleTmpDh);
if (mPublic ? theConfig.WEBSOCKET_PUBLIC_SECURE : theConfig.WEBSOCKET_SECURE)
// Construct a single handler for all requests.
websocketpp::server_autotls::handler::ptr handler(new WSServerHandler<websocketpp::server_autotls>(mCtx, mPublic));
// Construct a websocket server.
mSEndpoint = new websocketpp::server_autotls(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.
try
{
// Construct a single handler for all requests.
websocketpp::server_tls::handler::ptr handler(new WSServerHandler<websocketpp::server_tls>(mCtx, mPublic));
// Construct a websocket server.
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.
try
{
mSEndpoint->listen(
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address().from_string(mIp), mPort));
}
catch (websocketpp::exception& e)
{
cLog(lsWARNING) << "websocketpp exception: " << e.what();
while (1) // temporary workaround for websocketpp throwing exceptions on access/close races
{ // https://github.com/zaphoyd/websocketpp/issues/98
try
{
mSEndpoint->get_io_service().run();
break;
}
catch (websocketpp::exception& e)
{
cLog(lsWARNING) << "websocketpp exception: " << e.what();
}
mSEndpoint->listen(
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address().from_string(mIp), mPort));
}
catch (websocketpp::exception& e)
{
cLog(lsWARNING) << "websocketpp exception: " << e.what();
while (1) // temporary workaround for websocketpp throwing exceptions on access/close races
{ // https://github.com/zaphoyd/websocketpp/issues/98
try
{
mSEndpoint->get_io_service().run();
break;
}
catch (websocketpp::exception& e)
{
cLog(lsWARNING) << "websocketpp exception: " << e.what();
}
}
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);
// Call the main-event-loop of the websocket server.
try
{
mEndpoint->listen(
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address().from_string(mIp), mPort));
}
catch (websocketpp::exception& e)
{
cLog(lsWARNING) << "websocketpp exception: " << e.what();
while (1) // temporary workaround for websocketpp throwing exceptions on access/close races
{ // https://github.com/zaphoyd/websocketpp/issues/98
try
{
mEndpoint->get_io_service().run();
break;
}
catch (websocketpp::exception& e)
{
cLog(lsWARNING) << "websocketpp exception: " << e.what();
}
}
}
delete mEndpoint;
}
delete mSEndpoint;
}
WSDoor* WSDoor::createWSDoor(const std::string& strIp, const int iPort, bool bPublic)
@@ -154,8 +114,6 @@ void WSDoor::stop()
{
if (mThread)
{
if (mEndpoint)
mEndpoint->stop();
if (mSEndpoint)
mSEndpoint->stop();

View File

@@ -12,7 +12,7 @@
namespace websocketpp
{
class server;
class server_tls;
class server_autotls;
}
#endif
@@ -20,19 +20,18 @@ namespace websocketpp
class WSDoor
{
private:
websocketpp::server* mEndpoint;
websocketpp::server_tls* mSEndpoint;
websocketpp::server_autotls* mSEndpoint;
boost::thread* mThread;
bool mPublic;
std::string mIp;
int mPort;
boost::thread* mThread;
bool mPublic;
std::string mIp;
int mPort;
void startListening();
public:
WSDoor(const std::string& strIp, int iPort, bool bPublic) : mEndpoint(0), mSEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; }
WSDoor(const std::string& strIp, int iPort, bool bPublic) : mSEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; }
void stop();

View File

@@ -37,7 +37,7 @@ protected:
public:
WSServerHandler(boost::shared_ptr<boost::asio::ssl::context> spCtx, bool bPublic) : mCtx(spCtx), mPublic(bPublic)
{
if (theConfig.WEBSOCKET_SECURE)
if (theConfig.WEBSOCKET_SECURE != 0)
{
initSSLContext(*mCtx, theConfig.WEBSOCKET_SSL_KEY,
theConfig.WEBSOCKET_SSL_CERT, theConfig.WEBSOCKET_SSL_CHAIN);