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

This commit is contained in:
JoelKatz
2012-04-28 17:29:56 -07:00
11 changed files with 206 additions and 122 deletions

View File

@@ -11,6 +11,7 @@
#include "RPCDoor.h" #include "RPCDoor.h"
#include "BitcoinUtil.h" #include "BitcoinUtil.h"
#include "key.h" #include "key.h"
#include "utils.h"
Application* theApp=NULL; Application* theApp=NULL;
@@ -45,7 +46,7 @@ Application::Application() :
mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
mPeerDoor(NULL), mRPCDoor(NULL) mPeerDoor(NULL), mRPCDoor(NULL)
{ {
theConfig.load(); nothing();
} }
extern const char *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[]; extern const char *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[];

View File

@@ -6,35 +6,38 @@
#include <fstream> #include <fstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg #define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg
#define SECTION_PEER_IP "peer_ip" #define SECTION_PEER_IP "peer_ip"
#define SECTION_PEER_PORT "peer_port" #define SECTION_PEER_PORT "peer_port"
#define SECTION_RPC_IP "rpc_ip" #define SECTION_RPC_IP "rpc_ip"
#define SECTION_RPC_PORT "rpc_port" #define SECTION_RPC_PORT "rpc_port"
#define SECTION_VALIDATION_PASSWORD "validation_password" #define SECTION_VALIDATION_PASSWORD "validation_password"
#define SECTION_VALIDATION_KEY "validation_key" #define SECTION_VALIDATION_KEY "validation_key"
#define SECTION_PEER_SSL_CIPHER_LIST "peer_ssl_cipher_list"
Config theConfig; Config theConfig;
Config::Config() Config::Config()
{ {
VERSION=1; VERSION = 1;
NETWORK_START_TIME=1319844908; NETWORK_START_TIME = 1319844908;
PEER_PORT=SYSTEM_PEER_PORT; PEER_PORT = SYSTEM_PEER_PORT;
RPC_PORT=5001; RPC_PORT = 5001;
NUMBER_CONNECTIONS=30; NUMBER_CONNECTIONS = 30;
// a new ledger every 30 min // a new ledger every 30 min
LEDGER_SECONDS=(60*30); LEDGER_SECONDS = (60*30);
RPC_USER="admin"; RPC_USER = "admin";
RPC_PASSWORD="pass"; RPC_PASSWORD = "pass";
DATA_DIR="db/"; DATA_DIR = "db/";
TRANSACTION_FEE_BASE=1000; PEER_SSL_CIPHER_LIST = DEFAULT_PEER_SSL_CIPHER_LIST;
TRANSACTION_FEE_BASE = 1000;
} }
void Config::load() void Config::load()
@@ -73,6 +76,8 @@ void Config::load()
(void) sectionSingleB(secConfig, SECTION_VALIDATION_PASSWORD, VALIDATION_PASSWORD); (void) sectionSingleB(secConfig, SECTION_VALIDATION_PASSWORD, VALIDATION_PASSWORD);
(void) sectionSingleB(secConfig, SECTION_VALIDATION_KEY, VALIDATION_KEY); (void) sectionSingleB(secConfig, SECTION_VALIDATION_KEY, VALIDATION_KEY);
(void) sectionSingleB(secConfig, SECTION_PEER_SSL_CIPHER_LIST, PEER_SSL_CIPHER_LIST);
} }
} }

View File

@@ -7,6 +7,9 @@
const int SYSTEM_PEER_PORT=6561; const int SYSTEM_PEER_PORT=6561;
// Allow anonymous DH.
#define DEFAULT_PEER_SSL_CIPHER_LIST "ALL:!LOW:!EXP:!MD5:@STRENGTH"
class Config class Config
{ {
public: public:
@@ -42,6 +45,8 @@ public:
std::string VALIDATION_PASSWORD; std::string VALIDATION_PASSWORD;
std::string VALIDATION_KEY; std::string VALIDATION_KEY;
std::string PEER_SSL_CIPHER_LIST;
// configuration parameters // configuration parameters
std::string DATA_DIR; std::string DATA_DIR;

View File

@@ -8,18 +8,27 @@
#include "Application.h" #include "Application.h"
#include "utils.h" #include "utils.h"
// XXX On Windows make sure OpenSSL PRNG is seeded: EGADS
ConnectionPool::ConnectionPool() : ConnectionPool::ConnectionPool() :
iConnecting(0) iConnecting(0),
{ ; } mCtx(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);
if (1 != SSL_CTX_set_cipher_list(mCtx.native_handle(), theConfig.PEER_SSL_CIPHER_LIST.c_str()))
std::runtime_error("Error setting cipher list (no valid ciphers).");
}
void ConnectionPool::start() void ConnectionPool::start()
{ {
// XXX Start running policy. // XXX Start running policy.
} }
// XXX Broken don't send a message to a peer if we got it from the peer. // XXX Broken: also don't send a message to a peer if we got it from the peer.
void ConnectionPool::relayMessage(Peer* fromPeer, PackedMessage::pointer msg) void ConnectionPool::relayMessage(Peer* fromPeer, PackedMessage::pointer msg)
{ {
BOOST_FOREACH(naPeer pair, mConnectedMap) BOOST_FOREACH(naPeer pair, mConnectedMap)
@@ -80,7 +89,7 @@ bool ConnectionPool::connectTo(const std::string& strIp, int iPort)
std::cerr << "ConnectionPool::connectTo: Connectting: " std::cerr << "ConnectionPool::connectTo: Connectting: "
<< strIp << " " << iPort << std::endl; << strIp << " " << iPort << std::endl;
Peer::pointer peer(Peer::create(theApp->getIOService())); Peer::pointer peer(Peer::create(theApp->getIOService(), mCtx));
mIpMap[ip] = peer; mIpMap[ip] = peer;
@@ -131,18 +140,17 @@ bool ConnectionPool::peerConnected(Peer::pointer peer, const NewcoinAddress& na)
return bSuccess; return bSuccess;
} }
void ConnectionPool::peerDisconnected(Peer::pointer peer) void ConnectionPool::peerDisconnected(Peer::pointer peer, const ipPort& ipPeer, const NewcoinAddress& naPeer)
{ {
std::cerr << "ConnectionPool::peerDisconnected: " << peer->mIpPort.first << " " << peer->mIpPort.second << std::endl; std::cerr << "ConnectionPool::peerDisconnected: " << peer->mIpPort.first << " " << peer->mIpPort.second << std::endl;
boost::mutex::scoped_lock sl(mPeerLock); boost::mutex::scoped_lock sl(mPeerLock);
// XXX Don't access member variable directly. if (naPeer.isValid())
if (peer->mPublicKey.isValid())
{ {
boost::unordered_map<NewcoinAddress, Peer::pointer>::iterator itCm; boost::unordered_map<NewcoinAddress, Peer::pointer>::iterator itCm;
itCm = mConnectedMap.find(peer->mPublicKey); itCm = mConnectedMap.find(naPeer);
if (itCm == mConnectedMap.end()) if (itCm == mConnectedMap.end())
{ {
@@ -157,16 +165,15 @@ void ConnectionPool::peerDisconnected(Peer::pointer peer)
} }
} }
// XXX Don't access member variable directly.
boost::unordered_map<ipPort, Peer::pointer>::iterator itIp; boost::unordered_map<ipPort, Peer::pointer>::iterator itIp;
itIp = mIpMap.find(peer->mIpPort); itIp = mIpMap.find(ipPeer);
if (itIp == mIpMap.end()) if (itIp == mIpMap.end())
{ {
// Did not find it. Not already connecting or connected. // Did not find it. Not already connecting or connected.
std::cerr << "Internal Error: peer wasn't connected: " std::cerr << "Internal Error: peer wasn't connected: "
<< peer->mIpPort.first << " " << peer->mIpPort.second << std::endl; << ipPeer.first << " " << ipPeer.second << std::endl;
// XXX Bad error. // XXX Bad error.
} }
else else

View File

@@ -1,6 +1,7 @@
#ifndef __CONNECTION_POOL__ #ifndef __CONNECTION_POOL__
#define __CONNECTION_POOL__ #define __CONNECTION_POOL__
#include <boost/asio/ssl.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include "Peer.h" #include "Peer.h"
@@ -27,6 +28,8 @@ private:
// Non-thin peers which we are connected to. // Non-thin peers which we are connected to.
boost::unordered_map<NewcoinAddress, Peer::pointer> mConnectedMap; boost::unordered_map<NewcoinAddress, Peer::pointer> mConnectedMap;
boost::asio::ssl::context mCtx;
public: public:
ConnectionPool(); ConnectionPool();
@@ -51,7 +54,7 @@ public:
bool peerConnected(Peer::pointer peer, const NewcoinAddress& na); bool peerConnected(Peer::pointer peer, const NewcoinAddress& na);
// No longer connected. // No longer connected.
void peerDisconnected(Peer::pointer peer); void peerDisconnected(Peer::pointer peer, const ipPort& ipPeer, const NewcoinAddress& naPeer);
Json::Value getPeersJson(); Json::Value getPeersJson();

View File

@@ -16,10 +16,8 @@
#include "SerializedTransaction.h" #include "SerializedTransaction.h"
#include "utils.h" #include "utils.h"
Peer::Peer(boost::asio::io_service& io_service) Peer::Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx)
: mSocket(io_service), : mSocketSsl(io_service, ctx)
mCtx(boost::asio::ssl::context::sslv23),
mSocketSsl(io_service, mCtx)
{ {
} }
@@ -27,9 +25,9 @@ void Peer::handle_write(const boost::system::error_code& error, size_t bytes_tra
{ {
#ifdef DEBUG #ifdef DEBUG
if(error) if(error)
std::cout << "Peer::handle_write Error: " << error << " bytes: " << bytes_transferred << std::endl; std::cerr << "Peer::handle_write Error: " << error << " bytes: " << bytes_transferred << std::endl;
else else
std::cout << "Peer::handle_write bytes: "<< bytes_transferred << std::endl; std::cerr << "Peer::handle_write bytes: "<< bytes_transferred << std::endl;
#endif #endif
mSendingPacket=PackedMessage::pointer(); mSendingPacket=PackedMessage::pointer();
@@ -54,10 +52,10 @@ void Peer::handle_write(const boost::system::error_code& error, size_t bytes_tra
void Peer::detach() void Peer::detach()
{ {
mSendQ.clear(); mSendQ.clear();
mSocket.close(); // mSocketSsl.close();
if (!mIpPort.first.empty()) { if (!mIpPort.first.empty()) {
theApp->getConnectionPool().peerDisconnected(shared_from_this()); theApp->getConnectionPool().peerDisconnected(shared_from_this(), mIpPort, mNodePublic);
mIpPort.first.clear(); mIpPort.first.clear();
} }
} }
@@ -68,7 +66,7 @@ void Peer::connect(const std::string strIp, int iPort)
{ {
int iPortAct = iPort < 0 ? SYSTEM_PEER_PORT : iPort; int iPortAct = iPort < 0 ? SYSTEM_PEER_PORT : iPort;
std::cout << "Peer::connect: " << strIp << " " << iPort << std::endl; std::cerr << "Peer::connect: " << strIp << " " << iPort << std::endl;
mIpPort = make_pair(strIp, iPort); mIpPort = make_pair(strIp, iPort);
boost::asio::ip::tcp::resolver::query query(strIp, boost::lexical_cast<std::string>(iPortAct), boost::asio::ip::tcp::resolver::query query(strIp, boost::lexical_cast<std::string>(iPortAct),
@@ -86,87 +84,104 @@ void Peer::connect(const std::string strIp, int iPort)
else else
{ {
std::cerr << "Peer::connect: Connectting: " << mIpPort.first << " " << mIpPort.second << std::endl; std::cerr << "Peer::connect: Connectting: " << mIpPort.first << " " << mIpPort.second << std::endl;
#if 1
boost::asio::async_connect(
mSocket,
itrEndpoint,
boost::bind(
&Peer::handleConnect,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::iterator));
#else
// Connect via ssl.
// XXX Why doesn't handler need an iterator?
boost::asio::async_connect( boost::asio::async_connect(
mSocketSsl.lowest_layer(), mSocketSsl.lowest_layer(),
itrEndpoint, itrEndpoint,
boost::bind( boost::bind(
&Peer::handleConnect, &Peer::handleConnect,
shared_from_this(), shared_from_this(),
boost::asio::placeholders::error)); boost::asio::placeholders::error,
#endif boost::asio::placeholders::iterator));
} }
} }
// SSL connection. // We have an ecrypted connection to the peer.
void Peer::handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it) // Have it say who it is so we know to avoid redundant connections.
// Establish that it really who we are talking to by having it sign a connection detail.
// XXX Also need to establish no man in the middle attack is in progress.
void Peer::handleStart(const boost::system::error_code& error)
{ {
if (error) if (error)
{ {
std::cout << "Socket Connect failed:" << error << std::endl; std::cerr << "Peer::handleStart: failed:" << error << std::endl;
detach(); detach();
} }
else else
{ {
std::cout << "Socket Connected." << std::endl;
start_read_header(); start_read_header();
sendHello(); sendHello();
} }
} }
// Peer connected via door. // Connect as client.
void Peer::handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it)
{
if (error)
{
std::cerr << "Socket Connect failed:" << error << std::endl;
detach();
}
else
{
std::cerr << "Socket Connected." << std::endl;
mSocketSsl.lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true));
mSocketSsl.set_verify_mode(boost::asio::ssl::verify_none);
mSocketSsl.async_handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::client,
boost::bind(&Peer::handleStart,
shared_from_this(),
boost::asio::placeholders::error));
}
}
// Connect as server.
void Peer::connected(const boost::system::error_code& error) void Peer::connected(const boost::system::error_code& error)
{ {
boost::asio::ip::tcp::endpoint ep = mSocket.remote_endpoint(); boost::asio::ip::tcp::endpoint ep = mSocketSsl.lowest_layer().remote_endpoint();
int iPort = ep.port(); int iPort = ep.port();
std::string strIp = ep.address().to_string(); std::string strIp = ep.address().to_string();
if (iPort == SYSTEM_PEER_PORT) if (iPort == SYSTEM_PEER_PORT)
iPort = -1; iPort = -1;
std::cout << "Remote peer: accept: " << strIp << " " << iPort << std::endl; std::cerr << "Remote peer: accept: " << strIp << " " << iPort << std::endl;
if (error) if (error)
{ {
std::cout << "Remote peer: accept error: " << error << std::endl; std::cerr << "Remote peer: accept error: " << error << std::endl;
detach(); detach();
} }
else if (!theApp->getConnectionPool().peerRegister(shared_from_this(), strIp, iPort)) else if (!theApp->getConnectionPool().peerRegister(shared_from_this(), strIp, iPort))
{ {
std::cout << "Remote peer: rejecting." << std::endl; std::cerr << "Remote peer: rejecting." << std::endl;
// XXX Reject with a rejection message: already connected // XXX Reject with a rejection message: already connected
detach(); detach();
} }
else else
{ {
// Not redundant, add to connection list. // Not redundant ip and port, add to connection list.
std::cout << "Remote peer: accepted." << std::endl; std::cerr << "Remote peer: accepted." << std::endl;
//BOOST_LOG_TRIVIAL(info) << "Connected to Peer."; //BOOST_LOG_TRIVIAL(info) << "Connected to Peer.";
mIpPort = make_pair(strIp, iPort); mIpPort = make_pair(strIp, iPort);
start_read_header(); mSocketSsl.lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true));
sendHello(); mSocketSsl.set_verify_mode(boost::asio::ssl::verify_none);
mSocketSsl.async_handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::server,
boost::bind(&Peer::handleStart,
shared_from_this(),
boost::asio::placeholders::error));
} }
} }
void Peer::sendPacketForce(PackedMessage::pointer packet) void Peer::sendPacketForce(PackedMessage::pointer packet)
{ {
mSendingPacket=packet; mSendingPacket=packet;
boost::asio::async_write(mSocket, boost::asio::buffer(packet->getBuffer()), boost::asio::async_write(mSocketSsl, boost::asio::buffer(packet->getBuffer()),
boost::bind(&Peer::handle_write, shared_from_this(), boost::bind(&Peer::handle_write, shared_from_this(),
boost::asio::placeholders::error, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)); boost::asio::placeholders::bytes_transferred));
@@ -194,7 +209,7 @@ void Peer::start_read_header()
#endif #endif
mReadbuf.clear(); mReadbuf.clear();
mReadbuf.resize(HEADER_SIZE); mReadbuf.resize(HEADER_SIZE);
boost::asio::async_read(mSocket, boost::asio::buffer(mReadbuf), boost::asio::async_read(mSocketSsl, boost::asio::buffer(mReadbuf),
boost::bind(&Peer::handle_read_header, shared_from_this(), boost::asio::placeholders::error)); boost::bind(&Peer::handle_read_header, shared_from_this(), boost::asio::placeholders::error));
} }
@@ -205,13 +220,13 @@ void Peer::start_read_body(unsigned msg_len)
// read into the body. // read into the body.
// //
mReadbuf.resize(HEADER_SIZE + msg_len); mReadbuf.resize(HEADER_SIZE + msg_len);
boost::asio::async_read(mSocket, boost::asio::buffer(&mReadbuf[HEADER_SIZE], msg_len), boost::asio::async_read(mSocketSsl, boost::asio::buffer(&mReadbuf[HEADER_SIZE], msg_len),
boost::bind(&Peer::handle_read_body, shared_from_this(), boost::asio::placeholders::error)); boost::bind(&Peer::handle_read_body, shared_from_this(), boost::asio::placeholders::error));
} }
void Peer::handle_read_header(const boost::system::error_code& error) void Peer::handle_read_header(const boost::system::error_code& error)
{ {
if(!error) if (!error)
{ {
unsigned msg_len = PackedMessage::getLength(mReadbuf); unsigned msg_len = PackedMessage::getLength(mReadbuf);
// WRITEME: Compare to maximum message length, abort if too large // WRITEME: Compare to maximum message length, abort if too large
@@ -225,13 +240,13 @@ void Peer::handle_read_header(const boost::system::error_code& error)
else else
{ {
detach(); detach();
std::cout << "Peer::connected Error: " << error << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error; std::cerr << "Peer::handle_read_header: Error: " << error << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
} }
} }
void Peer::handle_read_body(const boost::system::error_code& error) void Peer::handle_read_body(const boost::system::error_code& error)
{ {
if(!error) if (!error)
{ {
processReadBuffer(); processReadBuffer();
start_read_header(); start_read_header();
@@ -239,7 +254,7 @@ void Peer::handle_read_body(const boost::system::error_code& error)
else else
{ {
detach(); detach();
std::cout << "Peer::connected Error: " << error << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error; std::cerr << "Peer::handle_read_body: Error: " << error << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
} }
} }
@@ -266,7 +281,7 @@ void Peer::processReadBuffer()
newcoin::TMHello msg; newcoin::TMHello msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvHello(msg); recvHello(msg);
else std::cout << "parse error: " << type << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error; else std::cerr << "parse error: " << type << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
} }
break; break;
@@ -275,7 +290,7 @@ void Peer::processReadBuffer()
newcoin::TMErrorMsg msg; newcoin::TMErrorMsg msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvErrorMessage(msg); recvErrorMessage(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -284,7 +299,7 @@ void Peer::processReadBuffer()
newcoin::TMPing msg; newcoin::TMPing msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvPing(msg); recvPing(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -293,7 +308,7 @@ void Peer::processReadBuffer()
newcoin::TMGetContacts msg; newcoin::TMGetContacts msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvGetContacts(msg); recvGetContacts(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -302,7 +317,7 @@ void Peer::processReadBuffer()
newcoin::TMContact msg; newcoin::TMContact msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvContact(msg); recvContact(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -311,7 +326,7 @@ void Peer::processReadBuffer()
newcoin::TMSearchTransaction msg; newcoin::TMSearchTransaction msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvSearchTransaction(msg); recvSearchTransaction(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -320,7 +335,7 @@ void Peer::processReadBuffer()
newcoin::TMGetAccount msg; newcoin::TMGetAccount msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvGetAccount(msg); recvGetAccount(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -329,7 +344,7 @@ void Peer::processReadBuffer()
newcoin::TMAccount msg; newcoin::TMAccount msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvAccount(msg); recvAccount(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -338,7 +353,7 @@ void Peer::processReadBuffer()
newcoin::TMTransaction msg; newcoin::TMTransaction msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvTransaction(msg); recvTransaction(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -347,7 +362,7 @@ void Peer::processReadBuffer()
newcoin::TMGetLedger msg; newcoin::TMGetLedger msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvGetLedger(msg); recvGetLedger(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -356,17 +371,17 @@ void Peer::processReadBuffer()
newcoin::TMLedgerData msg; newcoin::TMLedgerData msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvLedger(msg); recvLedger(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
#if 0 #if 0
case newcoin::mtPROPOSE_LEDGER: case newcoin::mtPROPOSE_LEDGER:
{ {
newcoin::TM msg; newcoin::TM msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recv(msg); recv(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -375,7 +390,7 @@ void Peer::processReadBuffer()
newcoin::TM msg; newcoin::TM msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recv(msg); recv(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -384,7 +399,7 @@ void Peer::processReadBuffer()
newcoin::TM msg; newcoin::TM msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recv(msg); recv(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -393,18 +408,16 @@ void Peer::processReadBuffer()
newcoin::TM msg; newcoin::TM msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recv(msg); recv(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
#endif
#endif
case newcoin::mtGET_OBJECT: case newcoin::mtGET_OBJECT:
{ {
newcoin::TMGetObjectByHash msg; newcoin::TMGetObjectByHash msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvGetObjectByHash(msg); recvGetObjectByHash(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
@@ -413,12 +426,12 @@ void Peer::processReadBuffer()
newcoin::TMObjectByHash msg; newcoin::TMObjectByHash msg;
if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) if(msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
recvObjectByHash(msg); recvObjectByHash(msg);
else std::cout << "pars error: " << type << std::endl; else std::cerr << "parse error: " << type << std::endl;
} }
break; break;
default: default:
std::cout << "Unknown Msg: " << type << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error; std::cerr << "Unknown Msg: " << type << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
} }
} }
} }
@@ -432,15 +445,15 @@ void Peer::recvHello(newcoin::TMHello& packet)
#endif #endif
bool bDetach = true; bool bDetach = true;
if (mPublicKey.isValid()) if (mNodePublic.isValid())
{ {
std::cerr << "Recv(Hello): Disconnect: Extraneous node public key." << std::endl; std::cerr << "Recv(Hello): Disconnect: Extraneous node public key." << std::endl;
} }
else if (!mPublicKey.setNodePublic(packet.nodepublic())) else if (!mNodePublic.setNodePublic(packet.nodepublic()))
{ {
std::cerr << "Recv(Hello): Disconnect: Bad node public key." << std::endl; std::cerr << "Recv(Hello): Disconnect: Bad node public key." << std::endl;
} }
else if (!theApp->getConnectionPool().peerConnected(shared_from_this(), mPublicKey)) else if (!theApp->getConnectionPool().peerConnected(shared_from_this(), mNodePublic))
{ {
// Already connected, self, or some other reason. // Already connected, self, or some other reason.
std::cerr << "Recv(Hello): Disconnect: Extraneous connection." << std::endl; std::cerr << "Recv(Hello): Disconnect: Extraneous connection." << std::endl;
@@ -455,7 +468,7 @@ void Peer::recvHello(newcoin::TMHello& packet)
if (bDetach) if (bDetach)
{ {
mPublicKey.clear(); mNodePublic.clear();
detach(); detach();
} }
} }
@@ -685,7 +698,7 @@ Json::Value Peer::getJson() {
ret["ip"] = mIpPort.first; ret["ip"] = mIpPort.first;
ret["port"] = mIpPort.second; ret["port"] = mIpPort.second;
ret["public_key"] = mPublicKey.ToString(); ret["public_key"] = mNodePublic.ToString();
return ret; return ret;
} }
@@ -810,7 +823,7 @@ void Peer::receiveTransaction(TransactionPtr trans)
} }
else else
{ {
std::cout << "Invalid transaction: " << trans->from() << std::endl; std::cerr << "Invalid transaction: " << trans->from() << std::endl;
} }
} }

View File

@@ -28,18 +28,16 @@ public:
static const int psbGotHello=0, psbSentHello=1, psbInMap=2, psbTrusted=3; static const int psbGotHello=0, psbSentHello=1, psbInMap=2, psbTrusted=3;
static const int psbNoLedgers=4, psbNoTransactions=5, psbDownLevel=6; static const int psbNoLedgers=4, psbNoTransactions=5, psbDownLevel=6;
NewcoinAddress mPublicKey; // Node public key of peer. NewcoinAddress mNodePublic; // Node public key of peer.
ipPort mIpPort; ipPort mIpPort;
void handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it); void handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it);
private: private:
bool bRegistered;
boost::asio::ip::tcp::socket mSocket;
boost::asio::ssl::context mCtx;
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> mSocketSsl; boost::asio::ssl::stream<boost::asio::ip::tcp::socket> mSocketSsl;
void handleStart(const boost::system::error_code& error);
protected: protected:
std::vector<uint8_t> mReadbuf; std::vector<uint8_t> mReadbuf;
@@ -47,7 +45,7 @@ protected:
PackedMessage::pointer mSendingPacket; PackedMessage::pointer mSendingPacket;
std::bitset<32> mPeerBits; std::bitset<32> mPeerBits;
Peer(boost::asio::io_service& io_service); Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx);
void handle_write(const boost::system::error_code& error, size_t bytes_transferred); void handle_write(const boost::system::error_code& error, size_t bytes_transferred);
//void handle_read(const boost::system::error_code& error, size_t bytes_transferred); //void handle_read(const boost::system::error_code& error, size_t bytes_transferred);
@@ -85,14 +83,14 @@ public:
//bool operator == (const Peer& other); //bool operator == (const Peer& other);
static pointer create(boost::asio::io_service& io_service) static pointer create(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx)
{ {
return pointer(new Peer(io_service)); return pointer(new Peer(io_service, ctx));
} }
boost::asio::ip::tcp::socket& getSocket() boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::lowest_layer_type& getSocket()
{ {
return mSocket; return mSocketSsl.lowest_layer();
} }
void connect(const std::string strIp, int iPort); void connect(const std::string strIp, int iPort);

View File

@@ -4,23 +4,68 @@
#include <iostream> #include <iostream>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
//#include <boost/log/trivial.hpp> //#include <boost/log/trivial.hpp>
#include <openssl/dh.h>
#include "Config.h" #include "Config.h"
using namespace std; using namespace std;
using namespace boost::asio::ip; using namespace boost::asio::ip;
PeerDoor::PeerDoor(boost::asio::io_service& io_service) : // Generate DH for SSL connection.
mAcceptor(io_service, tcp::endpoint(address().from_string(theConfig.PEER_IP), theConfig.PEER_PORT)) static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength)
{ {
cout << "Opening peer door on port: " << theConfig.PEER_PORT << endl; // We don't care if for export.
static DH* sdh512 = 0;
static DH* sdh1024 = 0;
if (!sdh512 && 512 == iKeyLength)
{
int iCodes;
do {
sdh512 = DH_generate_parameters(512, DH_GENERATOR_5, NULL, NULL);
iCodes = 0;
DH_check(sdh512, &iCodes);
} while (iCodes & (DH_CHECK_P_NOT_PRIME|DH_CHECK_P_NOT_SAFE_PRIME|DH_UNABLE_TO_CHECK_GENERATOR|DH_NOT_SUITABLE_GENERATOR));
}
if (!sdh1024 && 512 != iKeyLength)
{
int iCodes;
do {
sdh1024 = DH_generate_parameters(1024, DH_GENERATOR_5, NULL, NULL);
iCodes = 0;
DH_check(sdh1024, &iCodes);
} while (iCodes & (DH_CHECK_P_NOT_PRIME|DH_CHECK_P_NOT_SAFE_PRIME|DH_UNABLE_TO_CHECK_GENERATOR|DH_NOT_SUITABLE_GENERATOR));
}
return 512 == iKeyLength ? sdh512 : sdh1024;
}
PeerDoor::PeerDoor(boost::asio::io_service& io_service) :
mAcceptor(io_service, tcp::endpoint(address().from_string(theConfig.PEER_IP), theConfig.PEER_PORT)),
mCtx(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);
if (1 != SSL_CTX_set_cipher_list(mCtx.native_handle(), theConfig.PEER_SSL_CIPHER_LIST.c_str()))
std::runtime_error("Error setting cipher list (no valid ciphers).");
cerr << "Peer port: " << theConfig.PEER_IP << " " << theConfig.PEER_PORT << endl;
startListening(); startListening();
} }
void PeerDoor::startListening() void PeerDoor::startListening()
{ {
Peer::pointer new_connection = Peer::create(mAcceptor.get_io_service()); Peer::pointer new_connection = Peer::create(mAcceptor.get_io_service(), mCtx);
mAcceptor.async_accept(new_connection->getSocket(), mAcceptor.async_accept(new_connection->getSocket(),
boost::bind(&PeerDoor::handleConnect, this, new_connection, boost::bind(&PeerDoor::handleConnect, this, new_connection,

View File

@@ -2,6 +2,7 @@
#include <set> #include <set>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include "Peer.h" #include "Peer.h"
@@ -11,10 +12,12 @@ Handles incoming connections from other Peers
class PeerDoor class PeerDoor
{ {
boost::asio::ip::tcp::acceptor mAcceptor; private:
void startListening(); boost::asio::ip::tcp::acceptor mAcceptor;
void handleConnect(Peer::pointer new_connection, boost::asio::ssl::context mCtx;
const boost::system::error_code& error);
void startListening();
void handleConnect(Peer::pointer new_connection, const boost::system::error_code& error);
public: public:
PeerDoor(boost::asio::io_service& io_service); PeerDoor(boost::asio::io_service& io_service);

View File

@@ -10,7 +10,7 @@ using namespace boost::asio::ip;
RPCDoor::RPCDoor(boost::asio::io_service& io_service) : RPCDoor::RPCDoor(boost::asio::io_service& io_service) :
mAcceptor(io_service, tcp::endpoint(address::from_string(theConfig.RPC_IP), theConfig.RPC_PORT)) mAcceptor(io_service, tcp::endpoint(address::from_string(theConfig.RPC_IP), theConfig.RPC_PORT))
{ {
cout << "Opening rpc door on port: " << theConfig.RPC_PORT << endl; cerr << "RPC port: " << theConfig.RPC_IP << " " << theConfig.RPC_PORT << endl;
startListening(); startListening();
} }
@@ -47,3 +47,4 @@ void RPCDoor::handleConnect(RPCServer::pointer new_connection,
startListening(); startListening();
} }
// vim:ts=4

View File

@@ -47,14 +47,17 @@ void printHelp()
int parseCommandline(int argc, char* argv[]) int parseCommandline(int argc, char* argv[])
{ {
int ret=0; int ret=0;
theConfig.load();
if(argc>1) if(argc>1)
{ {
theConfig.load();
ret=commandLineRPC(argc, argv); ret=commandLineRPC(argc, argv);
if(ret) if(ret)
printHelp(); printHelp();
} }
else startApp(); else startApp();
return ret; return ret;
} }