aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bitcoinrpc.cpp5
-rw-r--r--src/init.cpp119
-rw-r--r--src/irc.cpp4
-rw-r--r--src/main.cpp4
-rw-r--r--src/net.cpp54
-rw-r--r--src/net.h4
-rw-r--r--src/netbase.cpp119
-rw-r--r--src/netbase.h17
-rw-r--r--src/qt/optionsdialog.cpp2
-rw-r--r--src/qt/optionsmodel.cpp70
-rw-r--r--src/qt/optionsmodel.h3
11 files changed, 237 insertions, 164 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 75e3fd6e92..e31022d822 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -531,6 +531,9 @@ Value getinfo(const Array& params, bool fHelp)
"getinfo\n"
"Returns an object containing various state info.");
+ CService addrProxy;
+ GetProxy(NET_IPV4, addrProxy);
+
Object obj;
obj.push_back(Pair("version", (int)CLIENT_VERSION));
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
@@ -538,7 +541,7 @@ Value getinfo(const Array& params, bool fHelp)
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("connections", (int)vNodes.size()));
- obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
+ obj.push_back(Pair("proxy", (addrProxy.IsValid() ? addrProxy.ToStringIPPort() : string())));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("testnet", fTestNet));
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
diff --git a/src/init.cpp b/src/init.cpp
index 687cb9a9d1..f6f443d77d 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -182,12 +182,15 @@ bool static InitWarning(const std::string &str)
}
-bool static Bind(const CService &addr) {
+bool static Bind(const CService &addr, bool fError = true) {
if (IsLimited(addr))
return false;
std::string strError;
- if (!BindListenPort(addr, strError))
- return InitError(strError);
+ if (!BindListenPort(addr, strError)) {
+ if (fError)
+ return InitError(strError);
+ return false;
+ }
return true;
}
@@ -204,20 +207,18 @@ std::string HelpMessage()
" -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
" -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" +
" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
- " -socks=<n> " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" +
- " -noproxy=<net> " + _("Do not use proxy for connections to network <net> (IPv4 or IPv6)") + "\n" +
+ " -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
" -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" +
- " -proxydns " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" +
" -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
" -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
" -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
- " -connect=<ip> " + _("Connect only to the specified node") + "\n" +
+ " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n" +
" -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" +
" -externalip=<ip> " + _("Specify your own public address") + "\n" +
" -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4 or IPv6)") + "\n" +
- " -discover " + _("Try to discover public IP address (default: 1)") + "\n" +
+ " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" +
" -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
- " -listen " + _("Accept connections from outside (default: 1)") + "\n" +
+ " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" +
" -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
" -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" +
" -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
@@ -226,9 +227,9 @@ std::string HelpMessage()
" -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
#ifdef USE_UPNP
#if USE_UPNP
- " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
+ " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n" +
#else
- " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
+ " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n" +
#endif
#endif
" -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
@@ -308,30 +309,38 @@ bool AppInit2()
// ********************************************************* Step 2: parameter interactions
fTestNet = GetBoolArg("-testnet");
- if (fTestNet)
- {
+ if (fTestNet) {
SoftSetBoolArg("-irc", true);
}
- if (mapArgs.count("-connect"))
- SoftSetBoolArg("-dnsseed", false);
-
- // even in Tor mode, if -bind is specified, you really want -listen
- if (mapArgs.count("-bind"))
+ if (mapArgs.count("-bind")) {
+ // when specifying an explicit binding address, you want to listen on it
+ // even when -connect or -proxy is specified
SoftSetBoolArg("-listen", true);
+ }
- bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
- if (fTor)
- {
- // Use SoftSetBoolArg here so user can override any of these if they wish.
- // Note: the GetBoolArg() calls for all of these must happen later.
+ if (mapArgs.count("-connect")) {
+ // when only connecting to trusted nodes, do not seed via DNS, or listen by default
+ SoftSetBoolArg("-dnsseed", false);
+ SoftSetBoolArg("-listen", false);
+ }
+
+ if (mapArgs.count("-proxy")) {
+ // to protect privacy, do not listen by default if a proxy server is specified
SoftSetBoolArg("-listen", false);
- SoftSetBoolArg("-irc", false);
- SoftSetBoolArg("-proxydns", true);
+ }
+
+ if (GetBoolArg("-listen", true)) {
+ // do not map ports or try to retrieve public IP when not listening (pointless)
SoftSetBoolArg("-upnp", false);
SoftSetBoolArg("-discover", false);
}
+ if (mapArgs.count("-externalip")) {
+ // if an explicit public IP is specified, do not try to find others
+ SoftSetBoolArg("-discover", false);
+ }
+
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = GetBoolArg("-debug");
@@ -425,30 +434,8 @@ bool AppInit2()
// ********************************************************* Step 5: network initialization
- if (mapArgs.count("-proxy"))
- {
- fUseProxy = true;
- addrProxy = CService(mapArgs["-proxy"], 9050);
- if (!addrProxy.IsValid())
- return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
- }
-
- if (mapArgs.count("-noproxy"))
- {
- BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
- enum Network net = ParseNetwork(snet);
- if (net == NET_UNROUTABLE)
- return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
- SetNoProxy(net);
- }
- }
+ int nSocksVersion = GetArg("-socks", 5);
- fNameLookup = GetBoolArg("-dns");
- fProxyNameLookup = GetBoolArg("-proxydns");
- if (fProxyNameLookup)
- fNameLookup = true;
- fNoListen = !GetBoolArg("-listen", true);
- nSocksVersion = GetArg("-socks", 5);
if (nSocksVersion != 4 && nSocksVersion != 5)
return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
@@ -467,8 +454,29 @@ bool AppInit2()
}
}
- BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
- AddOneShot(strDest);
+ if (mapArgs.count("-proxy")) {
+ CService addrProxy = CService(mapArgs["-proxy"], 9050);
+ if (!addrProxy.IsValid())
+ return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
+
+ if (!IsLimited(NET_IPV4))
+ SetProxy(NET_IPV4, addrProxy, nSocksVersion);
+ if (nSocksVersion > 4) {
+#ifdef USE_IPV6
+ if (!IsLimited(NET_IPV6))
+ SetProxy(NET_IPV6, addrProxy, nSocksVersion);
+#endif
+ SetNameProxy(addrProxy, nSocksVersion);
+ }
+ }
+
+ // see Step 2: parameter interactions for more information about these
+ fNoListen = !GetBoolArg("-listen", true);
+ fDiscover = GetBoolArg("-discover", true);
+ fNameLookup = GetBoolArg("-dns", true);
+#ifdef USE_UPNP
+ fUseUPnP = GetBoolArg("-upnp", USE_UPNP);
+#endif
bool fBound = false;
if (!fNoListen)
@@ -484,15 +492,15 @@ bool AppInit2()
} else {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
- if (!IsLimited(NET_IPV4))
- fBound |= Bind(CService(inaddr_any, GetListenPort()));
#ifdef USE_IPV6
if (!IsLimited(NET_IPV6))
- fBound |= Bind(CService(in6addr_any, GetListenPort()));
+ fBound |= Bind(CService(in6addr_any, GetListenPort()), false);
#endif
+ if (!IsLimited(NET_IPV4))
+ fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound);
}
if (!fBound)
- return InitError(_("Not listening on any port"));
+ return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
}
if (mapArgs.count("-externalip"))
@@ -505,6 +513,9 @@ bool AppInit2()
}
}
+ BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
+ AddOneShot(strDest);
+
// ********************************************************* Step 6: load blockchain
if (GetBoolArg("-loadblockindextest"))
diff --git a/src/irc.cpp b/src/irc.cpp
index c0b3b7478d..185be02f29 100644
--- a/src/irc.cpp
+++ b/src/irc.cpp
@@ -176,8 +176,6 @@ bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet)
// Hybrid IRC used by lfnet always returns IP when you userhost yourself,
// but in case another IRC is ever used this should work.
printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
- if (fUseProxy)
- return false;
CNetAddr addr(strHost, true);
if (!addr.IsValid())
return false;
@@ -281,7 +279,7 @@ void ThreadIRCSeed2(void* parg)
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
{
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
- if (!fUseProxy && addrFromIRC.IsRoutable())
+ if (addrFromIRC.IsRoutable())
{
// IRC lets you to re-nick
AddLocal(addrFromIRC, LOCAL_IRC);
diff --git a/src/main.cpp b/src/main.cpp
index 981de62659..50a740d160 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2377,7 +2377,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (!pfrom->fInbound)
{
// Advertise our address
- if (!fNoListen && !fUseProxy && !IsInitialBlockDownload())
+ if (!fNoListen && !IsInitialBlockDownload())
{
CAddress addr = GetLocalAddress(&pfrom->addr);
if (addr.IsRoutable())
@@ -3035,7 +3035,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
pnode->setAddrKnown.clear();
// Rebroadcast our address
- if (!fNoListen && !fUseProxy)
+ if (!fNoListen)
{
CAddress addr = GetLocalAddress(&pnode->addr);
if (addr.IsRoutable())
diff --git a/src/net.cpp b/src/net.cpp
index 9193e873e7..d510709082 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -47,7 +47,8 @@ struct LocalServiceInfo {
// Global state variables
//
bool fClient = false;
-static bool fUseUPnP = false;
+bool fDiscover = true;
+bool fUseUPnP = false;
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
static CCriticalSection cs_mapLocalHost;
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
@@ -99,7 +100,7 @@ void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
// find 'best' local address for a particular peer
bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
{
- if (fUseProxy || mapArgs.count("-connect") || fNoListen)
+ if (fNoListen)
return false;
int nBestScore = -1;
@@ -211,7 +212,7 @@ bool AddLocal(const CService& addr, int nScore)
if (!addr.IsRoutable())
return false;
- if (!GetBoolArg("-discover", true) && nScore < LOCAL_MANUAL)
+ if (!fDiscover && nScore < LOCAL_MANUAL)
return false;
if (IsLimited(addr))
@@ -345,9 +346,6 @@ bool GetMyExternalIP(CNetAddr& ipRet)
const char* pszGet;
const char* pszKeyword;
- if (fNoListen||fUseProxy)
- return false;
-
for (int nLookup = 0; nLookup <= 1; nLookup++)
for (int nHost = 1; nHost <= 2; nHost++)
{
@@ -542,7 +540,7 @@ void CNode::PushVersion()
{
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
- CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
+ CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
CAddress addrMe = GetLocalAddress(&addr);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
@@ -1016,7 +1014,7 @@ void ThreadMapPort2(void* parg)
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
if (r == 1)
{
- if (GetBoolArg("-discover", true)) {
+ if (fDiscover) {
char externalIPAddress[40];
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS)
@@ -1093,12 +1091,8 @@ void ThreadMapPort2(void* parg)
}
}
-void MapPort(bool fMapPort)
+void MapPort()
{
- if (fUseUPnP != fMapPort)
- {
- fUseUPnP = fMapPort;
- }
if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
{
if (!CreateThread(ThreadMapPort, NULL))
@@ -1106,7 +1100,7 @@ void MapPort(bool fMapPort)
}
}
#else
-void MapPort(bool /* unused fMapPort */)
+void MapPort()
{
// Intentionally left blank.
}
@@ -1160,7 +1154,7 @@ void ThreadDNSAddressSeed2(void* parg)
printf("Loading addresses from DNS seeds (could take a while)\n");
for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
- if (fProxyNameLookup) {
+ if (GetNameProxy()) {
AddOneShot(strDNSSeed[seed_idx][1]);
} else {
vector<CNetAddr> vaddr;
@@ -1394,8 +1388,7 @@ void ThreadOpenConnections2(void* parg)
return;
// Add seed nodes if IRC isn't working
- bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
- if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
+ if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
{
std::vector<CAddress> vAdd;
for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
@@ -1492,7 +1485,7 @@ void ThreadOpenAddedConnections2(void* parg)
if (mapArgs.count("-addnode") == 0)
return;
- if (fProxyNameLookup) {
+ if (GetNameProxy()) {
while(!fShutdown) {
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
CAddress addr;
@@ -1778,7 +1771,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
vhListenSocket.push_back(hListenSocket);
- if (addrBind.IsRoutable() && GetBoolArg("-discover", true))
+ if (addrBind.IsRoutable() && fDiscover)
AddLocal(addrBind, LOCAL_BIND);
return true;
@@ -1786,7 +1779,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
void static Discover()
{
- if (!GetBoolArg("-discover", true))
+ if (!fDiscover)
return;
#ifdef WIN32
@@ -1835,22 +1828,11 @@ void static Discover()
}
#endif
- if (!fUseProxy && !mapArgs.count("-connect") && !fNoListen)
- {
- CreateThread(ThreadGetMyExternalIP, NULL);
- }
+ CreateThread(ThreadGetMyExternalIP, NULL);
}
void StartNode(void* parg)
{
-#ifdef USE_UPNP
-#if USE_UPNP
- fUseUPnP = GetBoolArg("-upnp", true);
-#else
- fUseUPnP = GetBoolArg("-upnp", false);
-#endif
-#endif
-
if (semOutbound == NULL) {
// initialize semaphore
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
@@ -1873,8 +1855,8 @@ void StartNode(void* parg)
printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
// Map ports with UPnP
- if (fHaveUPnP)
- MapPort(fUseUPnP);
+ if (fUseUPnP)
+ MapPort();
// Get addresses from IRC and advertise ours
if (!CreateThread(ThreadIRCSeed, NULL))
@@ -1930,7 +1912,9 @@ bool StopNode()
if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
- if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
+#ifdef USE_UPNP
+ if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
+#endif
if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
diff --git a/src/net.h b/src/net.h
index 8075328b13..c9c965722e 100644
--- a/src/net.h
+++ b/src/net.h
@@ -36,7 +36,7 @@ void AddressCurrentlyConnected(const CService& addr);
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CService& ip);
CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
-void MapPort(bool fMapPort);
+void MapPort();
unsigned short GetListenPort();
bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
void StartNode(void* parg);
@@ -110,6 +110,8 @@ enum threadId
};
extern bool fClient;
+extern bool fDiscover;
+extern bool fUseUPnP;
extern uint64 nLocalServices;
extern uint64 nLocalHostNonce;
extern boost::array<int, THREAD_MAX> vnThreadsRunning;
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 7de06eaef8..80b0e32c39 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -16,14 +16,11 @@
using namespace std;
// Settings
-int nSocksVersion = 5;
-int fUseProxy = false;
-bool fProxyNameLookup = false;
-bool fNameLookup = false;
-CService addrProxy("127.0.0.1",9050);
+typedef std::pair<CService, int> proxyType;
+static proxyType proxyInfo[NET_MAX];
+static proxyType nameproxyInfo;
int nConnectTimeout = 5000;
-static bool vfNoProxy[NET_MAX] = {};
-
+bool fNameLookup = false;
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
@@ -36,11 +33,6 @@ enum Network ParseNetwork(std::string net) {
return NET_UNROUTABLE;
}
-void SetNoProxy(enum Network net, bool fNoProxy) {
- assert(net >= 0 && net < NET_MAX);
- vfNoProxy[net] = fNoProxy;
-}
-
bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
@@ -431,29 +423,71 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
return true;
}
+bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
+ assert(net >= 0 && net < NET_MAX);
+ if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5)
+ return false;
+ if (nSocksVersion != 0 && !addrProxy.IsValid())
+ return false;
+ proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
+ return true;
+}
+
+bool GetProxy(enum Network net, CService &addrProxy) {
+ assert(net >= 0 && net < NET_MAX);
+ if (!proxyInfo[net].second)
+ return false;
+ addrProxy = proxyInfo[net].first;
+ return true;
+}
+
+bool SetNameProxy(CService addrProxy, int nSocksVersion) {
+ if (nSocksVersion != 0 && nSocksVersion != 5)
+ return false;
+ if (nSocksVersion != 0 && !addrProxy.IsValid())
+ return false;
+ nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
+ return true;
+}
+
+bool GetNameProxy() {
+ return nameproxyInfo.second != 0;
+}
+
+bool IsProxy(const CNetAddr &addr) {
+ for (int i=0; i<NET_MAX; i++) {
+ if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
+ return true;
+ }
+ return false;
+}
+
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
{
+ const proxyType &proxy = proxyInfo[addrDest.GetNetwork()];
+
+ // no proxy needed
+ if (!proxy.second)
+ return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
+
SOCKET hSocket = INVALID_SOCKET;
- bool fProxy = (fUseProxy && addrDest.IsRoutable() && !vfNoProxy[addrDest.GetNetwork()]);
- if (!ConnectSocketDirectly(fProxy ? addrProxy : addrDest, hSocket, nTimeout))
+ // first connect to proxy server
+ if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout))
+ return false;
+
+ // do socks negotiation
+ switch (proxy.second) {
+ case 4:
+ if (!Socks4(addrDest, hSocket))
+ return false;
+ break;
+ case 5:
+ if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
+ return false;
+ break;
+ default:
return false;
-
- if (fProxy)
- {
- switch(nSocksVersion)
- {
- case 4:
- if (!Socks4(addrDest, hSocket))
- return false;
- break;
-
- case 5:
- default:
- if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
- return false;
- break;
- }
}
hSocketRet = hSocket;
@@ -465,6 +499,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
string strDest(pszDest);
int port = portDefault;
+ // split hostname and port
size_t colon = strDest.find_last_of(':');
if (colon != strDest.npos) {
char *endp = NULL;
@@ -479,26 +514,26 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
strDest = strDest.substr(1, strDest.size()-2);
SOCKET hSocket = INVALID_SOCKET;
- CService addrResolved(CNetAddr(strDest, fNameLookup && !fProxyNameLookup), port);
+ CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxyInfo.second), port);
if (addrResolved.IsValid()) {
addr = addrResolved;
return ConnectSocket(addr, hSocketRet, nTimeout);
}
addr = CService("0.0.0.0:0");
- if (!fNameLookup)
+ if (!nameproxyInfo.second)
return false;
- if (!ConnectSocketDirectly(addrProxy, hSocket, nTimeout))
+ if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout))
return false;
- switch(nSocksVersion)
- {
- case 4: return false;
- case 5:
- default:
- if (!Socks5(strDest, port, hSocket))
- return false;
- break;
- }
+ switch(nameproxyInfo.second)
+ {
+ default:
+ case 4: return false;
+ case 5:
+ if (!Socks5(strDest, port, hSocket))
+ return false;
+ break;
+ }
hSocketRet = hSocket;
return true;
diff --git a/src/netbase.h b/src/netbase.h
index 2cbc8bd8a2..0f6fc9b499 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -28,8 +28,8 @@ enum Network
NET_MAX
};
-enum Network ParseNetwork(std::string net);
-void SetNoProxy(enum Network net, bool fNoProxy = true);
+extern int nConnectTimeout;
+extern bool fNameLookup;
/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
class CNetAddr
@@ -132,6 +132,12 @@ class CService : public CNetAddr
)
};
+enum Network ParseNetwork(std::string net);
+bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);
+bool GetProxy(enum Network net, CService &addrProxy);
+bool IsProxy(const CNetAddr &addr);
+bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);
+bool GetNameProxy();
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 Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
@@ -140,11 +146,4 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
-// Settings
-extern int nSocksVersion;
-extern int fUseProxy;
-extern bool fProxyNameLookup;
-extern bool fNameLookup;
-extern CService addrProxy;
-
#endif
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 7c6ad087cb..50374ddc4b 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -390,7 +390,7 @@ void NetworkOptionsPage::setMapper(MonitoredDataMapper *mapper)
{
// Map model to widgets
mapper->addMapping(map_port_upnp, OptionsModel::MapPortUPnP);
- mapper->addMapping(connect_socks4, OptionsModel::ConnectSOCKS4);
+ mapper->addMapping(connect_socks4, OptionsModel::ProxyUse);
mapper->addMapping(proxy_ip, OptionsModel::ProxyIP);
mapper->addMapping(proxy_port, OptionsModel::ProxyPort);
}
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index e110cfa6af..e65694bb52 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -12,6 +12,29 @@ OptionsModel::OptionsModel(QObject *parent) :
Init();
}
+bool static ApplyProxySettings()
+{
+ QSettings settings;
+ CService addrProxy(settings.value("addrProxy", "127.0.0.1:9050").toString().toStdString());
+ int nSocksVersion(settings.value("nSocksVersion", 5).toInt());
+ if (!settings.value("fUseProxy", false).toBool()) {
+ addrProxy = CService();
+ nSocksVersion = 0;
+ }
+ if (nSocksVersion && !addrProxy.IsValid())
+ return false;
+ if (!IsLimited(NET_IPV4))
+ SetProxy(NET_IPV4, addrProxy, nSocksVersion);
+ if (nSocksVersion > 4) {
+#ifdef USE_IPV6
+ if (!IsLimited(NET_IPV6))
+ SetProxy(NET_IPV6, addrProxy, nSocksVersion);
+#endif
+ SetNameProxy(addrProxy, nSocksVersion);
+ }
+ return true;
+}
+
void OptionsModel::Init()
{
QSettings settings;
@@ -75,20 +98,21 @@ bool OptionsModel::Upgrade()
CAddress addrProxyAddress;
if (walletdb.ReadSetting("addrProxy", addrProxyAddress))
{
- addrProxy = addrProxyAddress;
- settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
+ settings.setValue("addrProxy", addrProxyAddress.ToStringIPPort().c_str());
walletdb.EraseSetting("addrProxy");
}
}
catch (std::ios_base::failure &e)
{
// 0.6.0rc1 saved this as a CService, which causes failure when parsing as a CAddress
+ CService addrProxy;
if (walletdb.ReadSetting("addrProxy", addrProxy))
{
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
walletdb.EraseSetting("addrProxy");
}
}
+ ApplyProxySettings();
Init();
return true;
@@ -115,12 +139,24 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return settings.value("fUseUPnP", GetBoolArg("-upnp", true));
case MinimizeOnClose:
return QVariant(fMinimizeOnClose);
- case ConnectSOCKS4:
+ case ProxyUse:
return settings.value("fUseProxy", false);
- case ProxyIP:
- return QVariant(QString::fromStdString(addrProxy.ToStringIP()));
- case ProxyPort:
- return QVariant(addrProxy.GetPort());
+ case ProxySocksVersion:
+ return settings.value("nSocksVersion", false);
+ case ProxyIP: {
+ CService addrProxy;
+ if (GetProxy(NET_IPV4, addrProxy))
+ return QVariant(QString::fromStdString(addrProxy.ToStringIP()));
+ else
+ return QVariant(QString::fromStdString("localhost"));
+ }
+ case ProxyPort: {
+ CService addrProxy;
+ if (GetProxy(NET_IPV4, addrProxy))
+ return QVariant(addrProxy.GetPort());
+ else
+ return 9050;
+ }
case Fee:
return QVariant(nTransactionFee);
case DisplayUnit:
@@ -137,7 +173,6 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
}
return QVariant();
}
-
bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
bool successful = true; /* set to false on parse error */
@@ -155,27 +190,29 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
break;
case MapPortUPnP:
{
- bool bUseUPnP = value.toBool();
- settings.setValue("fUseUPnP", bUseUPnP);
- MapPort(bUseUPnP);
+ fUseUPnP = value.toBool();
+ settings.setValue("fUseUPnP", fUseUPnP);
+ MapPort();
}
break;
case MinimizeOnClose:
fMinimizeOnClose = value.toBool();
settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
break;
- case ConnectSOCKS4:
- fUseProxy = value.toBool();
- settings.setValue("fUseProxy", fUseProxy);
+ case ProxyUse:
+ settings.setValue("fUseProxy", value.toBool());
+ ApplyProxySettings();
break;
case ProxyIP:
{
- // Use CAddress to parse and check IP
+ CService addrProxy("127.0.0.1", 9050);
+ GetProxy(NET_IPV4, addrProxy);
CNetAddr addr(value.toString().toStdString());
if (addr.IsValid())
{
addrProxy.SetIP(addr);
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
+ successful = ApplyProxySettings();
}
else
{
@@ -185,11 +222,14 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
break;
case ProxyPort:
{
+ CService addrProxy("127.0.0.1", 9050);
+ GetProxy(NET_IPV4, addrProxy);
int nPort = atoi(value.toString().toAscii().data());
if (nPort > 0 && nPort < std::numeric_limits<unsigned short>::max())
{
addrProxy.SetPort(nPort);
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
+ successful = ApplyProxySettings();
}
else
{
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index c0374689c6..c74a8dfb43 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -20,7 +20,8 @@ public:
MinimizeToTray, // bool
MapPortUPnP, // bool
MinimizeOnClose, // bool
- ConnectSOCKS4, // bool
+ ProxyUse, // bool
+ ProxySocksVersion, // int
ProxyIP, // QString
ProxyPort, // QString
Fee, // qint64