Merge branch 'websocket'

This commit is contained in:
Arthur Britto
2012-06-22 00:31:18 -07:00
9 changed files with 165 additions and 16 deletions

View File

@@ -1,11 +1,4 @@
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "../database/SqliteDatabase.h"
#include "Application.h"
#include "Config.h"
#include "PeerDoor.h"
@@ -14,9 +7,16 @@
#include "key.h"
#include "utils.h"
#include "TaggedCache.h"
#include "boost/filesystem.hpp"
#include "Log.h"
#include "../database/SqliteDatabase.h"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
Application* theApp = NULL;
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)
@@ -52,7 +52,7 @@ void Application::stop()
{
mIOService.stop();
std::cerr << "Stopped: " << mIOService.stopped() << std::endl;
Log(lsINFO) << "Stopped: " << mIOService.stopped();
}
static void InitDB(DatabaseCon** dbCon, const char *fileName, const char *dbInit[], int dbCount)
@@ -111,6 +111,8 @@ void Application::run()
std::cerr << "RPC interface: disabled" << std::endl;
}
mWSDoor = WSDoor::createWSDoor();
//
// Begin connecting to network.
//
@@ -122,8 +124,8 @@ void Application::run()
NewcoinAddress rootAddress = NewcoinAddress::createAccountPublic(rootGeneratorMaster, 0);
// Print enough information to be able to claim root account.
std::cerr << "Root master seed: " << rootSeedMaster.humanSeed() << std::endl;
std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl;
Log(lsINFO) << "Root master seed: " << rootSeedMaster.humanSeed();
Log(lsINFO) << "Root account: " << rootAddress.humanAccountID();
Ledger::pointer firstLedger = boost::make_shared<Ledger>(rootAddress, SYSTEM_CURRENCY_START);
assert(!!firstLedger->getAccountState(rootAddress));
@@ -141,6 +143,8 @@ void Application::run()
mIOService.run(); // This blocks
mWSDoor->stop();
std::cout << "Done." << std::endl;
}

View File

@@ -12,6 +12,7 @@
#include "Wallet.h"
#include "Peer.h"
#include "NetworkOPs.h"
#include "WSDoor.h"
#include "TaggedCache.h"
#include "ValidationCollection.h"
#include "Suppression.h"
@@ -54,6 +55,7 @@ class Application
ConnectionPool mConnectionPool;
PeerDoor* mPeerDoor;
RPCDoor* mRPCDoor;
WSDoor* mWSDoor;
uint256 mNonce256;
std::size_t mNonceST;

View File

@@ -118,6 +118,7 @@ void Config::setup(const std::string& strConf)
PEER_PORT = SYSTEM_PEER_PORT;
RPC_PORT = 5001;
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
NUMBER_CONNECTIONS = 30;
// a new ledger every minute

View File

@@ -22,7 +22,9 @@
#define DEFAULT_VALIDATORS_SITE "redstem.com"
#define VALIDATORS_FILE_NAME "validators.txt"
const int SYSTEM_PEER_PORT = 6561;
const int SYSTEM_PEER_PORT = 6561;
const int SYSTEM_WEBSOCKET_PORT = 6562;
// Allow anonymous DH.
#define DEFAULT_PEER_SSL_CIPHER_LIST "ALL:!LOW:!EXP:!MD5:@STRENGTH"
@@ -76,7 +78,7 @@ public:
int PEER_START_MAX;
int PEER_CONNECT_LOW_WATER;
// Client networking parameters
// Websocket networking parameters
std::string WEBSOCKET_IP;
int WEBSOCKET_PORT;
@@ -96,7 +98,7 @@ public:
uint64 FEE_NICKNAME_CREATE; // Fee to create a nickname.
// Client behavior
int ACCOUNT_PROBE_MAX; // How far to scan for accounts.
int ACCOUNT_PROBE_MAX; // How far to scan for accounts.
void setup(const std::string& strConf);
void load();

View File

@@ -169,7 +169,6 @@ void HttpsClient::handleConnect(const boost::system::error_code& ecResult)
{
// std::cerr << "Connected." << std::endl;
mSocketSsl.lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true));
mSocketSsl.set_verify_mode(boost::asio::ssl::verify_peer);
// XXX Verify semantics of RFC 2818 are what we want.

View File

@@ -49,7 +49,7 @@ void PeerDoor::startListening()
void PeerDoor::handleConnect(Peer::pointer new_connection,
const boost::system::error_code& error)
{
if(!error)
if (!error)
{
new_connection->connected(error);
}
@@ -57,4 +57,5 @@ void PeerDoor::handleConnect(Peer::pointer new_connection,
startListening();
}
// vim:ts=4

View File

@@ -1,3 +1,6 @@
#ifndef __PEERDOOR__
#define __PEERDOOR__
#include <map>
#include <set>
@@ -22,4 +25,7 @@ private:
public:
PeerDoor(boost::asio::io_service& io_service);
};
#endif
// vim:ts=4

102
src/WSDoor.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include "WSDoor.h"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include "Application.h"
#include "Config.h"
#include "Log.h"
#include "utils.h"
using namespace std;
using namespace boost::asio::ip;
// Generate DH for SSL connection.
static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength)
{
return 512 == iKeyLength ? theApp->getWallet().getDh512() : theApp->getWallet().getDh1024();
}
// A single instance of this object is made.
// This instance dispatches all events. There is no per connection persistency.
template <typename endpoint_type>
class WSServerHandler : public endpoint_type::handler {
private:
boost::shared_ptr<boost::asio::ssl::context> mCtx;
public:
typedef typename endpoint_type::handler::connection_ptr connection_ptr;
typedef typename endpoint_type::handler::message_ptr message_ptr;
WSServerHandler(boost::shared_ptr<boost::asio::ssl::context> spCtx) : mCtx(spCtx) {}
boost::shared_ptr<boost::asio::ssl::context> on_tls_init()
{
return mCtx;
}
void on_message(connection_ptr con, message_ptr msg) {
con->send(msg->get_payload(), msg->get_opcode());
}
void http(connection_ptr con) {
con->set_body("<!DOCTYPE html><html><head><title>WebSocket++ TLS certificate test</title></head><body><h1>WebSocket++ TLS certificate test</h1><p>This is an HTTP(S) page served by a WebSocket++ server for the purposes of confirming that certificates are working since browsers normally silently ignore certificate issues.</p></body></html>");
}
};
void WSDoor::startListening()
{
boost::shared_ptr<boost::asio::ssl::context> mCtx;
mCtx = boost::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);
mCtx->set_options(
boost::asio::ssl::context::default_workarounds
| boost::asio::ssl::context::no_sslv2
| boost::asio::ssl::context::single_dh_use);
SSL_CTX_set_tmp_dh_callback(mCtx->native_handle(), handleTmpDh);
websocketpp::server_tls::handler::ptr handler(new WSServerHandler<websocketpp::server_tls>(mCtx));
mEndpoint = new websocketpp::server_tls(handler);
Log(lsINFO) << "listening>";
mEndpoint->listen(boost::asio::ip::tcp::endpoint(address().from_string(theConfig.WEBSOCKET_IP), theConfig.WEBSOCKET_PORT));
free(mEndpoint);
Log(lsINFO) << "listening<";
}
WSDoor* WSDoor::createWSDoor()
{
WSDoor* wdpResult = new WSDoor();
if (!theConfig.WEBSOCKET_IP.empty() && theConfig.WEBSOCKET_PORT)
{
Log(lsINFO) << "Websocket: Listening: " << theConfig.WEBSOCKET_IP << " " << theConfig.WEBSOCKET_PORT;
wdpResult->mThread = new boost::thread(boost::bind(&WSDoor::startListening, wdpResult));
}
else
{
Log(lsINFO) << "Websocket: Disabled";
}
return wdpResult;
}
void WSDoor::stop()
{
if (mThread)
{
mEndpoint->stop(); // XXX Make this thread safe
mThread->join();
}
}
// vim:ts=4

32
src/WSDoor.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef __WSDOOR__
#define __WSDOOR__
#include "../websocketpp/src/sockets/tls.hpp"
#include "../websocketpp/src/websocketpp.hpp"
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
class WSDoor
{
private:
websocketpp::server_tls* mEndpoint;
boost::thread* mThread;
void startListening();
public:
WSDoor() : mEndpoint(0), mThread(0) { ; }
void stop();
static WSDoor* createWSDoor();
};
#endif
// vim:ts=4