add LOCK() for proxy related data-structures
- fix #1560 by properly locking proxy related data-structures - update GetProxy() and introduce GetNameProxy() to be able to use a thread-safe local copy from proxyInfo and nameproxyInfo - update usage of GetProxy() all over the source to match the new behaviour, as it now fills a full proxyType object - rename GetNameProxy() into HaveNameProxy() to be more clear
This commit is contained in:
parent
0547b02af7
commit
81bbef2609
@ -1185,7 +1185,7 @@ void ThreadDNSAddressSeed2(void* parg)
|
|||||||
printf("Loading addresses from DNS seeds (could take a while)\n");
|
printf("Loading addresses from DNS seeds (could take a while)\n");
|
||||||
|
|
||||||
for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
|
for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
|
||||||
if (GetNameProxy()) {
|
if (HaveNameProxy()) {
|
||||||
AddOneShot(strDNSSeed[seed_idx][1]);
|
AddOneShot(strDNSSeed[seed_idx][1]);
|
||||||
} else {
|
} else {
|
||||||
vector<CNetAddr> vaddr;
|
vector<CNetAddr> vaddr;
|
||||||
@ -1529,7 +1529,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
|||||||
if (mapArgs.count("-addnode") == 0)
|
if (mapArgs.count("-addnode") == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (GetNameProxy()) {
|
if (HaveNameProxy()) {
|
||||||
while(!fShutdown) {
|
while(!fShutdown) {
|
||||||
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
|
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "netbase.h"
|
#include "netbase.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
@ -16,9 +17,9 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
typedef std::pair<CService, int> proxyType;
|
|
||||||
static proxyType proxyInfo[NET_MAX];
|
static proxyType proxyInfo[NET_MAX];
|
||||||
static proxyType nameproxyInfo;
|
static proxyType nameproxyInfo;
|
||||||
|
static CCriticalSection cs_proxyInfos;
|
||||||
int nConnectTimeout = 5000;
|
int nConnectTimeout = 5000;
|
||||||
bool fNameLookup = false;
|
bool fNameLookup = false;
|
||||||
|
|
||||||
@ -432,15 +433,17 @@ bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
|
|||||||
return false;
|
return false;
|
||||||
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
||||||
return false;
|
return false;
|
||||||
|
LOCK(cs_proxyInfos);
|
||||||
proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
|
proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetProxy(enum Network net, CService &addrProxy) {
|
bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
|
||||||
assert(net >= 0 && net < NET_MAX);
|
assert(net >= 0 && net < NET_MAX);
|
||||||
|
LOCK(cs_proxyInfos);
|
||||||
if (!proxyInfo[net].second)
|
if (!proxyInfo[net].second)
|
||||||
return false;
|
return false;
|
||||||
addrProxy = proxyInfo[net].first;
|
proxyInfoOut = proxyInfo[net];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,15 +452,26 @@ bool SetNameProxy(CService addrProxy, int nSocksVersion) {
|
|||||||
return false;
|
return false;
|
||||||
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
||||||
return false;
|
return false;
|
||||||
|
LOCK(cs_proxyInfos);
|
||||||
nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
|
nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetNameProxy() {
|
bool GetNameProxy(proxyType &nameproxyInfoOut) {
|
||||||
|
LOCK(cs_proxyInfos);
|
||||||
|
if (!nameproxyInfo.second)
|
||||||
|
return false;
|
||||||
|
nameproxyInfoOut = nameproxyInfo;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HaveNameProxy() {
|
||||||
|
LOCK(cs_proxyInfos);
|
||||||
return nameproxyInfo.second != 0;
|
return nameproxyInfo.second != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsProxy(const CNetAddr &addr) {
|
bool IsProxy(const CNetAddr &addr) {
|
||||||
|
LOCK(cs_proxyInfos);
|
||||||
for (int i = 0; i < NET_MAX; i++) {
|
for (int i = 0; i < NET_MAX; i++) {
|
||||||
if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
|
if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
|
||||||
return true;
|
return true;
|
||||||
@ -467,10 +481,10 @@ bool IsProxy(const CNetAddr &addr) {
|
|||||||
|
|
||||||
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
|
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
|
||||||
{
|
{
|
||||||
const proxyType &proxy = proxyInfo[addrDest.GetNetwork()];
|
proxyType proxy;
|
||||||
|
|
||||||
// no proxy needed
|
// no proxy needed
|
||||||
if (!proxy.second)
|
if (!GetProxy(addrDest.GetNetwork(), proxy))
|
||||||
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
|
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
|
||||||
|
|
||||||
SOCKET hSocket = INVALID_SOCKET;
|
SOCKET hSocket = INVALID_SOCKET;
|
||||||
@ -504,19 +518,22 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
|
|||||||
SplitHostPort(string(pszDest), port, strDest);
|
SplitHostPort(string(pszDest), port, strDest);
|
||||||
|
|
||||||
SOCKET hSocket = INVALID_SOCKET;
|
SOCKET hSocket = INVALID_SOCKET;
|
||||||
CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxyInfo.second), port);
|
|
||||||
|
proxyType nameproxy;
|
||||||
|
GetNameProxy(nameproxy);
|
||||||
|
|
||||||
|
CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxy.second), port);
|
||||||
if (addrResolved.IsValid()) {
|
if (addrResolved.IsValid()) {
|
||||||
addr = addrResolved;
|
addr = addrResolved;
|
||||||
return ConnectSocket(addr, hSocketRet, nTimeout);
|
return ConnectSocket(addr, hSocketRet, nTimeout);
|
||||||
}
|
}
|
||||||
addr = CService("0.0.0.0:0");
|
addr = CService("0.0.0.0:0");
|
||||||
if (!nameproxyInfo.second)
|
if (!nameproxy.second)
|
||||||
return false;
|
return false;
|
||||||
if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout))
|
if (!ConnectSocketDirectly(nameproxy.first, hSocket, nTimeout))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch(nameproxyInfo.second)
|
switch(nameproxy.second) {
|
||||||
{
|
|
||||||
default:
|
default:
|
||||||
case 4: return false;
|
case 4: return false;
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -133,13 +133,15 @@ class CService : public CNetAddr
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::pair<CService, int> proxyType;
|
||||||
|
|
||||||
enum Network ParseNetwork(std::string net);
|
enum Network ParseNetwork(std::string net);
|
||||||
void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
|
void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
|
||||||
bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);
|
bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);
|
||||||
bool GetProxy(enum Network net, CService &addrProxy);
|
bool GetProxy(enum Network net, proxyType &proxyInfoOut);
|
||||||
bool IsProxy(const CNetAddr &addr);
|
bool IsProxy(const CNetAddr &addr);
|
||||||
bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);
|
bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);
|
||||||
bool GetNameProxy();
|
bool HaveNameProxy();
|
||||||
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
|
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
|
||||||
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0);
|
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0);
|
||||||
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
|
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
|
||||||
|
@ -145,18 +145,18 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
|||||||
case ProxyUse:
|
case ProxyUse:
|
||||||
return settings.value("fUseProxy", false);
|
return settings.value("fUseProxy", false);
|
||||||
case ProxyIP: {
|
case ProxyIP: {
|
||||||
CService addrProxy;
|
proxyType proxy;
|
||||||
if (GetProxy(NET_IPV4, addrProxy))
|
if (GetProxy(NET_IPV4, proxy))
|
||||||
return QVariant(QString::fromStdString(addrProxy.ToStringIP()));
|
return QVariant(QString::fromStdString(proxy.first.ToStringIP()));
|
||||||
else
|
else
|
||||||
return QVariant(QString::fromStdString("127.0.0.1"));
|
return QVariant(QString::fromStdString("127.0.0.1"));
|
||||||
}
|
}
|
||||||
case ProxyPort: {
|
case ProxyPort: {
|
||||||
CService addrProxy;
|
proxyType proxy;
|
||||||
if (GetProxy(NET_IPV4, addrProxy))
|
if (GetProxy(NET_IPV4, proxy))
|
||||||
return QVariant(addrProxy.GetPort());
|
return QVariant(proxy.first.GetPort());
|
||||||
else
|
else
|
||||||
return 9050;
|
return QVariant(9050);
|
||||||
}
|
}
|
||||||
case ProxySocksVersion:
|
case ProxySocksVersion:
|
||||||
return settings.value("nSocksVersion", 5);
|
return settings.value("nSocksVersion", 5);
|
||||||
@ -176,6 +176,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
|||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
|
bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
|
||||||
{
|
{
|
||||||
bool successful = true; /* set to false on parse error */
|
bool successful = true; /* set to false on parse error */
|
||||||
@ -204,28 +205,36 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||||||
settings.setValue("fUseProxy", value.toBool());
|
settings.setValue("fUseProxy", value.toBool());
|
||||||
ApplyProxySettings();
|
ApplyProxySettings();
|
||||||
break;
|
break;
|
||||||
case ProxyIP:
|
case ProxyIP: {
|
||||||
{
|
proxyType proxy;
|
||||||
CService addrProxy("127.0.0.1", 9050);
|
proxy.first = CService("127.0.0.1", 9050);
|
||||||
GetProxy(NET_IPV4, addrProxy);
|
GetProxy(NET_IPV4, proxy);
|
||||||
|
|
||||||
CNetAddr addr(value.toString().toStdString());
|
CNetAddr addr(value.toString().toStdString());
|
||||||
addrProxy.SetIP(addr);
|
proxy.first.SetIP(addr);
|
||||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str());
|
||||||
successful = ApplyProxySettings();
|
successful = ApplyProxySettings();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProxyPort:
|
case ProxyPort: {
|
||||||
{
|
proxyType proxy;
|
||||||
CService addrProxy("127.0.0.1", 9050);
|
proxy.first = CService("127.0.0.1", 9050);
|
||||||
GetProxy(NET_IPV4, addrProxy);
|
GetProxy(NET_IPV4, proxy);
|
||||||
addrProxy.SetPort(value.toInt());
|
|
||||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
proxy.first.SetPort(value.toInt());
|
||||||
|
settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str());
|
||||||
successful = ApplyProxySettings();
|
successful = ApplyProxySettings();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProxySocksVersion:
|
case ProxySocksVersion: {
|
||||||
settings.setValue("nSocksVersion", value.toInt());
|
proxyType proxy;
|
||||||
ApplyProxySettings();
|
proxy.second = 5;
|
||||||
|
GetProxy(NET_IPV4, proxy);
|
||||||
|
|
||||||
|
proxy.second = value.toInt();
|
||||||
|
settings.setValue("nSocksVersion", proxy.second);
|
||||||
|
successful = ApplyProxySettings();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Fee:
|
case Fee:
|
||||||
nTransactionFee = value.toLongLong();
|
nTransactionFee = value.toLongLong();
|
||||||
|
@ -62,8 +62,8 @@ Value getinfo(const Array& params, bool fHelp)
|
|||||||
"getinfo\n"
|
"getinfo\n"
|
||||||
"Returns an object containing various state info.");
|
"Returns an object containing various state info.");
|
||||||
|
|
||||||
CService addrProxy;
|
proxyType proxy;
|
||||||
GetProxy(NET_IPV4, addrProxy);
|
GetProxy(NET_IPV4, proxy);
|
||||||
|
|
||||||
Object obj;
|
Object obj;
|
||||||
obj.push_back(Pair("version", (int)CLIENT_VERSION));
|
obj.push_back(Pair("version", (int)CLIENT_VERSION));
|
||||||
@ -72,7 +72,7 @@ Value getinfo(const Array& params, bool fHelp)
|
|||||||
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
||||||
obj.push_back(Pair("blocks", (int)nBestHeight));
|
obj.push_back(Pair("blocks", (int)nBestHeight));
|
||||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||||
obj.push_back(Pair("proxy", (addrProxy.IsValid() ? addrProxy.ToStringIPPort() : string())));
|
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
|
||||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||||
obj.push_back(Pair("testnet", fTestNet));
|
obj.push_back(Pair("testnet", fTestNet));
|
||||||
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||||
|
Loading…
Reference in New Issue
Block a user