Rework network config settings

This commit is contained in:
Pieter Wuille 2012-05-24 19:02:21 +02:00
parent 50fac68654
commit 587f929c64
11 changed files with 237 additions and 164 deletions

View file

@ -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()));

View file

@ -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);
SoftSetBoolArg("-irc", false);
SoftSetBoolArg("-proxydns", true);
}
if (mapArgs.count("-proxy")) {
// to protect privacy, do not listen by default if a proxy server is specified
SoftSetBoolArg("-listen", false);
}
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()));
}
int nSocksVersion = GetArg("-socks", 5);
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);
}
}
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"))

View file

@ -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);

View file

@ -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())

View file

@ -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");

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -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
{

View file

@ -20,7 +20,8 @@ public:
MinimizeToTray, // bool
MapPortUPnP, // bool
MinimizeOnClose, // bool
ConnectSOCKS4, // bool
ProxyUse, // bool
ProxySocksVersion, // int
ProxyIP, // QString
ProxyPort, // QString
Fee, // qint64