diff options
-rw-r--r-- | src/bitcoinrpc.cpp | 5 | ||||
-rw-r--r-- | src/init.cpp | 119 | ||||
-rw-r--r-- | src/irc.cpp | 4 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/net.cpp | 54 | ||||
-rw-r--r-- | src/net.h | 4 | ||||
-rw-r--r-- | src/netbase.cpp | 119 | ||||
-rw-r--r-- | src/netbase.h | 17 | ||||
-rw-r--r-- | src/qt/optionsdialog.cpp | 2 | ||||
-rw-r--r-- | src/qt/optionsmodel.cpp | 70 | ||||
-rw-r--r-- | src/qt/optionsmodel.h | 3 |
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"); @@ -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 |