Merge remote branch 'refs/remotes/svn/trunk' into svn
This commit is contained in:
commit
cc8005b4e7
16
init.cpp
16
init.cpp
|
@ -170,13 +170,27 @@ bool AppInit2(int argc, char* argv[])
|
||||||
" -gen=0 \t " + _("Don't generate coins\n") +
|
" -gen=0 \t " + _("Don't generate coins\n") +
|
||||||
" -min \t " + _("Start minimized\n") +
|
" -min \t " + _("Start minimized\n") +
|
||||||
" -datadir=<dir> \t " + _("Specify data directory\n") +
|
" -datadir=<dir> \t " + _("Specify data directory\n") +
|
||||||
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
|
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
|
||||||
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
||||||
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
|
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
|
||||||
" -server \t " + _("Accept command line and JSON-RPC commands\n") +
|
" -server \t " + _("Accept command line and JSON-RPC commands\n") +
|
||||||
" -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
|
" -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
|
||||||
|
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
|
||||||
|
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
|
||||||
|
" -rpcport=<port> \t " + _("Listen for JSON-RPC connections on <port>\n") +
|
||||||
|
" -rpcallowip=<ip> \t " + _("Allow JSON-RPC connections from specified IP address\n") +
|
||||||
|
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip>\n") +
|
||||||
" -? \t " + _("This help message\n");
|
" -? \t " + _("This help message\n");
|
||||||
|
|
||||||
|
#ifdef USE_SSL
|
||||||
|
strUsage += string() +
|
||||||
|
_("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
|
||||||
|
" -rpcssl=1 \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
|
||||||
|
" -rpcsslcertificatchainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
|
||||||
|
" -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
|
||||||
|
" -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__WXMSW__) && defined(GUI)
|
#if defined(__WXMSW__) && defined(GUI)
|
||||||
// Tabs make the columns line up in the message box
|
// Tabs make the columns line up in the message box
|
||||||
wxMessageBox(strUsage, "Bitcoin", wxOK);
|
wxMessageBox(strUsage, "Bitcoin", wxOK);
|
||||||
|
|
15
main.cpp
15
main.cpp
|
@ -2433,15 +2433,20 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
{
|
{
|
||||||
// Nodes rebroadcast an addr every 24 hours
|
// Nodes rebroadcast an addr every 24 hours
|
||||||
pfrom->vAddrToSend.clear();
|
pfrom->vAddrToSend.clear();
|
||||||
int64 nSince = GetAdjustedTime() - 6 * 60 * 60; // in the last 6 hours
|
int64 nSince = GetAdjustedTime() - 3 * 60 * 60; // in the last 3 hours
|
||||||
CRITICAL_BLOCK(cs_mapAddresses)
|
CRITICAL_BLOCK(cs_mapAddresses)
|
||||||
{
|
{
|
||||||
|
unsigned int nCount = 0;
|
||||||
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
|
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
|
||||||
{
|
{
|
||||||
if (fShutdown)
|
|
||||||
return true;
|
|
||||||
const CAddress& addr = item.second;
|
const CAddress& addr = item.second;
|
||||||
if (addr.nTime > nSince)
|
if (addr.nTime > nSince)
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
|
||||||
|
{
|
||||||
|
const CAddress& addr = item.second;
|
||||||
|
if (addr.nTime > nSince && GetRand(nCount) < 2000)
|
||||||
pfrom->PushAddress(addr);
|
pfrom->PushAddress(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2780,7 +2785,7 @@ void ThreadBitcoinMiner(void* parg)
|
||||||
vnThreadsRunning[3]--;
|
vnThreadsRunning[3]--;
|
||||||
PrintException(NULL, "ThreadBitcoinMiner()");
|
PrintException(NULL, "ThreadBitcoinMiner()");
|
||||||
}
|
}
|
||||||
UIThreadCall(bind(CalledSetStatusBar, "", 0));
|
UIThreadCall(boost::bind(CalledSetStatusBar, "", 0));
|
||||||
nHPSTimerStart = 0;
|
nHPSTimerStart = 0;
|
||||||
if (vnThreadsRunning[3] == 0)
|
if (vnThreadsRunning[3] == 0)
|
||||||
dHashesPerSec = 0;
|
dHashesPerSec = 0;
|
||||||
|
@ -3143,7 +3148,7 @@ void BitcoinMiner()
|
||||||
nHPSTimerStart = GetTimeMillis();
|
nHPSTimerStart = GetTimeMillis();
|
||||||
nHashCounter = 0;
|
nHashCounter = 0;
|
||||||
string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
|
string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
|
||||||
UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
|
UIThreadCall(boost::bind(CalledSetStatusBar, strStatus, 0));
|
||||||
static int64 nLogTime;
|
static int64 nLogTime;
|
||||||
if (GetTime() - nLogTime > 30 * 60)
|
if (GetTime() - nLogTime > 30 * 60)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,9 +22,10 @@ LIBS= -dead_strip \
|
||||||
$(DEPSDIR)/lib/libboost_filesystem.a \
|
$(DEPSDIR)/lib/libboost_filesystem.a \
|
||||||
$(DEPSDIR)/lib/libboost_program_options.a \
|
$(DEPSDIR)/lib/libboost_program_options.a \
|
||||||
$(DEPSDIR)/lib/libboost_thread.a \
|
$(DEPSDIR)/lib/libboost_thread.a \
|
||||||
|
$(DEPSDIR)/lib/libssl.a \
|
||||||
$(DEPSDIR)/lib/libcrypto.a
|
$(DEPSDIR)/lib/libcrypto.a
|
||||||
|
|
||||||
DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0
|
DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0 -DUSE_SSL
|
||||||
|
|
||||||
DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0
|
DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0
|
||||||
# ppc doesn't work because we don't support big-endian
|
# ppc doesn't work because we don't support big-endian
|
||||||
|
|
|
@ -23,11 +23,12 @@ LIBS= \
|
||||||
-l boost_program_options \
|
-l boost_program_options \
|
||||||
-l boost_thread \
|
-l boost_thread \
|
||||||
-l db_cxx \
|
-l db_cxx \
|
||||||
|
-l ssl \
|
||||||
-l crypto \
|
-l crypto \
|
||||||
-Wl,-Bdynamic \
|
-Wl,-Bdynamic \
|
||||||
-l gthread-2.0
|
-l gthread-2.0
|
||||||
|
|
||||||
DEFS=-D__WXGTK__ -DNOPCH -DFOURWAYSSE2
|
DEFS=-D__WXGTK__ -DNOPCH -DFOURWAYSSE2 -DUSE_SSL
|
||||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||||
CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
||||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
|
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
|
||||||
|
|
131
rpc.cpp
131
rpc.cpp
|
@ -5,6 +5,12 @@
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
#undef printf
|
#undef printf
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/iostreams/concepts.hpp>
|
||||||
|
#include <boost/iostreams/stream.hpp>
|
||||||
|
#ifdef USE_SSL
|
||||||
|
#include <boost/asio/ssl.hpp>
|
||||||
|
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
|
||||||
|
#endif
|
||||||
#include "json/json_spirit_reader_template.h"
|
#include "json/json_spirit_reader_template.h"
|
||||||
#include "json/json_spirit_writer_template.h"
|
#include "json/json_spirit_writer_template.h"
|
||||||
#include "json/json_spirit_utils.h"
|
#include "json/json_spirit_utils.h"
|
||||||
|
@ -14,7 +20,7 @@
|
||||||
// a certain size around 145MB. If we need access to json_spirit outside this
|
// a certain size around 145MB. If we need access to json_spirit outside this
|
||||||
// file, we could use the compiled json_spirit option.
|
// file, we could use the compiled json_spirit option.
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
using namespace boost::asio;
|
||||||
using namespace json_spirit;
|
using namespace json_spirit;
|
||||||
|
|
||||||
void ThreadRPCServer2(void* parg);
|
void ThreadRPCServer2(void* parg);
|
||||||
|
@ -777,7 +783,7 @@ string HTTPReply(int nStatus, const string& strMsg)
|
||||||
strMsg.c_str());
|
strMsg.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadHTTPStatus(tcp::iostream& stream)
|
int ReadHTTPStatus(std::basic_istream<char>& stream)
|
||||||
{
|
{
|
||||||
string str;
|
string str;
|
||||||
getline(stream, str);
|
getline(stream, str);
|
||||||
|
@ -788,7 +794,7 @@ int ReadHTTPStatus(tcp::iostream& stream)
|
||||||
return atoi(vWords[1].c_str());
|
return atoi(vWords[1].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadHTTPHeader(tcp::iostream& stream, map<string, string>& mapHeadersRet)
|
int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
|
||||||
{
|
{
|
||||||
int nLen = 0;
|
int nLen = 0;
|
||||||
loop
|
loop
|
||||||
|
@ -812,7 +818,7 @@ int ReadHTTPHeader(tcp::iostream& stream, map<string, string>& mapHeadersRet)
|
||||||
return nLen;
|
return nLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadHTTP(tcp::iostream& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
|
int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
|
||||||
{
|
{
|
||||||
mapHeadersRet.clear();
|
mapHeadersRet.clear();
|
||||||
strMessageRet = "";
|
strMessageRet = "";
|
||||||
|
@ -930,8 +936,59 @@ bool ClientAllowed(const string& strAddress)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SSL
|
||||||
|
//
|
||||||
|
// IOStream device that speaks SSL but can also speak non-SSL
|
||||||
|
//
|
||||||
|
class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
|
||||||
|
public:
|
||||||
|
SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
|
||||||
|
{
|
||||||
|
fUseSSL = fUseSSLIn;
|
||||||
|
fNeedHandshake = fUseSSLIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handshake(ssl::stream_base::handshake_type role)
|
||||||
|
{
|
||||||
|
if (!fNeedHandshake) return;
|
||||||
|
fNeedHandshake = false;
|
||||||
|
stream.handshake(role);
|
||||||
|
}
|
||||||
|
std::streamsize read(char* s, std::streamsize n)
|
||||||
|
{
|
||||||
|
handshake(ssl::stream_base::server); // HTTPS servers read first
|
||||||
|
if (fUseSSL) return stream.read_some(asio::buffer(s, n));
|
||||||
|
return stream.next_layer().read_some(asio::buffer(s, n));
|
||||||
|
}
|
||||||
|
std::streamsize write(const char* s, std::streamsize n)
|
||||||
|
{
|
||||||
|
handshake(ssl::stream_base::client); // HTTPS clients write first
|
||||||
|
if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
|
||||||
|
return asio::write(stream.next_layer(), asio::buffer(s, n));
|
||||||
|
}
|
||||||
|
bool connect(const std::string& server, const std::string& port)
|
||||||
|
{
|
||||||
|
ip::tcp::resolver resolver(stream.get_io_service());
|
||||||
|
ip::tcp::resolver::query query(server.c_str(), port.c_str());
|
||||||
|
ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
|
||||||
|
ip::tcp::resolver::iterator end;
|
||||||
|
boost::system::error_code error = asio::error::host_not_found;
|
||||||
|
while (error && endpoint_iterator != end)
|
||||||
|
{
|
||||||
|
stream.lowest_layer().close();
|
||||||
|
stream.lowest_layer().connect(*endpoint_iterator++, error);
|
||||||
|
}
|
||||||
|
if (error)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fNeedHandshake;
|
||||||
|
bool fUseSSL;
|
||||||
|
SSLStream& stream;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
void ThreadRPCServer(void* parg)
|
void ThreadRPCServer(void* parg)
|
||||||
{
|
{
|
||||||
|
@ -972,18 +1029,54 @@ void ThreadRPCServer2(void* parg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally
|
bool fUseSSL = (mapArgs.count("-rpcssl") > 0);
|
||||||
boost::asio::io_service io_service;
|
asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
|
||||||
tcp::endpoint endpoint(mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback(), 8332);
|
|
||||||
tcp::acceptor acceptor(io_service, endpoint);
|
asio::io_service io_service;
|
||||||
|
ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
|
||||||
|
ip::tcp::acceptor acceptor(io_service, endpoint);
|
||||||
|
|
||||||
|
#ifdef USE_SSL
|
||||||
|
ssl::context context(io_service, ssl::context::sslv23);
|
||||||
|
if (fUseSSL)
|
||||||
|
{
|
||||||
|
context.set_options(ssl::context::no_sslv2);
|
||||||
|
filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
|
||||||
|
if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
|
||||||
|
if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
|
||||||
|
else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
|
||||||
|
filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
|
||||||
|
if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
|
||||||
|
if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
|
||||||
|
else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
|
||||||
|
|
||||||
|
string ciphers = GetArg("-rpcsslciphers",
|
||||||
|
"TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
|
||||||
|
SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (fUseSSL)
|
||||||
|
throw runtime_error("-rpcssl=true, but bitcoin compiled without full openssl libraries.");
|
||||||
|
#endif
|
||||||
|
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
// Accept connection
|
// Accept connection
|
||||||
tcp::iostream stream;
|
#ifdef USE_SSL
|
||||||
tcp::endpoint peer;
|
SSLStream sslStream(io_service, context);
|
||||||
|
SSLIOStreamDevice d(sslStream, fUseSSL);
|
||||||
|
iostreams::stream<SSLIOStreamDevice> stream(d);
|
||||||
|
#else
|
||||||
|
ip::tcp::iostream stream;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ip::tcp::endpoint peer;
|
||||||
vnThreadsRunning[4]--;
|
vnThreadsRunning[4]--;
|
||||||
|
#ifdef USE_SSL
|
||||||
|
acceptor.accept(sslStream.lowest_layer(), peer);
|
||||||
|
#else
|
||||||
acceptor.accept(*stream.rdbuf(), peer);
|
acceptor.accept(*stream.rdbuf(), peer);
|
||||||
|
#endif
|
||||||
vnThreadsRunning[4]++;
|
vnThreadsRunning[4]++;
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
|
@ -1102,9 +1195,25 @@ Object CallRPC(const string& strMethod, const Array& params)
|
||||||
GetConfigFile().c_str()));
|
GetConfigFile().c_str()));
|
||||||
|
|
||||||
// Connect to localhost
|
// Connect to localhost
|
||||||
tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), "8332");
|
bool fUseSSL = (mapArgs.count("-rpcssl") > 0);
|
||||||
|
#ifdef USE_SSL
|
||||||
|
asio::io_service io_service;
|
||||||
|
ssl::context context(io_service, ssl::context::sslv23);
|
||||||
|
context.set_options(ssl::context::no_sslv2);
|
||||||
|
SSLStream sslStream(io_service, context);
|
||||||
|
SSLIOStreamDevice d(sslStream, fUseSSL);
|
||||||
|
iostreams::stream<SSLIOStreamDevice> stream(d);
|
||||||
|
if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
|
||||||
|
throw runtime_error("couldn't connect to server");
|
||||||
|
#else
|
||||||
|
if (fUseSSL)
|
||||||
|
throw runtime_error("-rpcssl=true, but bitcoin compiled without full openssl libraries.");
|
||||||
|
|
||||||
|
ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
|
||||||
if (stream.fail())
|
if (stream.fail())
|
||||||
throw runtime_error("couldn't connect to server");
|
throw runtime_error("couldn't connect to server");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// HTTP basic authentication
|
// HTTP basic authentication
|
||||||
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
|
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
|
||||||
|
|
|
@ -22,7 +22,7 @@ class CDataStream;
|
||||||
class CAutoFile;
|
class CAutoFile;
|
||||||
static const unsigned int MAX_SIZE = 0x02000000;
|
static const unsigned int MAX_SIZE = 0x02000000;
|
||||||
|
|
||||||
static const int VERSION = 31303;
|
static const int VERSION = 31304;
|
||||||
static const char* pszSubVer = "";
|
static const char* pszSubVer = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
4
util.cpp
4
util.cpp
|
@ -572,7 +572,7 @@ void PrintExceptionContinue(std::exception* pex, const char* pszThread)
|
||||||
strMiscWarning = pszMessage;
|
strMiscWarning = pszMessage;
|
||||||
#ifdef GUI
|
#ifdef GUI
|
||||||
if (wxTheApp && !fDaemon)
|
if (wxTheApp && !fDaemon)
|
||||||
boost::thread(bind(ThreadOneMessageBox, string(pszMessage)));
|
boost::thread(boost::bind(ThreadOneMessageBox, string(pszMessage)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,7 +807,7 @@ void AddTimeData(unsigned int ip, int64 nTime)
|
||||||
string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.");
|
string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.");
|
||||||
strMiscWarning = strMessage;
|
strMiscWarning = strMessage;
|
||||||
printf("*** %s\n", strMessage.c_str());
|
printf("*** %s\n", strMessage.c_str());
|
||||||
boost::thread(bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
|
boost::thread(boost::bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach(int64 n, vTimeOffsets)
|
foreach(int64 n, vTimeOffsets)
|
||||||
|
|
Loading…
Reference in New Issue