Skip to content

Loading…

Rework network config settings #1389

Merged
merged 1 commit into from

6 participants

@sipa
Bitcoin member

Rework network config settings according to the specification in https://gist.github.com/2763381.

The network base does no longer call GetArg directly. Instead, everything happens through a few globals and the SetProxy/SetNameProxy methods. These are called in init.cpp:AppInit2, and in Bitcoin-Qt's optionsmodel.cpp.

@jgarzik
Bitcoin member

ACK

Tangentially related: it would be nice to move as much code from init.cpp into net*.cpp as possible, with init.cpp only calling NetParseConfig() or somesuch. Maybe that would help with qt/optionsmodel.cpp long term maintenance.

@sipa
Bitcoin member

@jgarzik agree, I considered that, but wanted to postpone that until after tor hidden service support is merged, as that will extend the network config options further.

@sipa sipa referenced this pull request
Merged

Tor hidden service support #1174

@sipa
Bitcoin member

@laanwj ack on the optionsmodel changes? After tor hidden service support is merged, the network option panel should be extended, I think, but for now, this should do.

@luke-jr luke-jr commented on the diff
src/bitcoinrpc.cpp
@@ -530,6 +530,9 @@ Value getinfo(const Array& params, bool fHelp)
"getinfo\n"
"Returns an object containing various state info.");
+ CService addrProxy;
+ GetProxy(NET_IPV4, addrProxy);
@luke-jr Bitcoin member
luke-jr added a note

Why does GetProxy have NET_IPV4 all over? do IPv6 proxies work?

@sipa Bitcoin member
sipa added a note

Internally, proxies can be selected separately for each network, and for hostname-based destination. The config and GUI right now are pinned to assume the IPv4 one is the only one, so they read NET_IPV4, and modify the NET_IPV4, NET_IPV6, and named ones simuitaneously.

It's just a temporary measure, I expect the GUI config panel will be extended with more proxy options, and for RPC maybe we can move to a "getnetconfig" command that returns this kind of information, including connected peers and some statistics?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@luke-jr luke-jr commented on an outdated diff
src/init.cpp
((12 lines not shown))
" -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" +
- " -externalip=<ip> " + _("Specify your own public address") + "\n" +
+ " -externalip=<ip> " + _("Specify your own public address.") + "\n" +
@luke-jr Bitcoin member
luke-jr added a note

Nothing else ends with a full stop, why this one?

@sipa Bitcoin member
sipa added a note

Good catch. Will fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@luke-jr luke-jr commented on an outdated diff
src/init.cpp
((15 lines not shown))
" -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 on when listening and no -externalip)") + "\n" +
@luke-jr Bitcoin member
luke-jr added a note

Unless we accept -discover=on, this should read "default: 1 iff listening and no -externalip; 0 otherwise"

@sipa Bitcoin member
sipa added a note

Agree, wll change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@sipa
Bitcoin member

updated

@sipa
Bitcoin member

As asked by @gavinandresen: the parameter interactions are now done using SoftSetBoolArg, instead of complex boolean formulas. Also added some comments.

@laanwj
Bitcoin member
@sipa
Bitcoin member

Yes, and it is effectively duplicated code from init.cpp for now. That's why Jeff already suggested a common NetParseConfig somehwere - I think that's the right approach.

@gavinandresen
Bitcoin member

ACK. Lightly tested on OSX.

@gavinandresen gavinandresen merged commit 587f929 into bitcoin:master
@Diapolo

@sipa This introduces a small display bug in the Qt GUI, it displays "localhost" as default Proxy-IP and it seems hostnames are not allowed there. If I enable the proxy and click apply it is changed to 127.0.0.1.

I think this happens in CNetAddr::ToStringIP(), which resolves 127.0.0.1 to "localhost", which is true, but currently not allowed in the GUI input field or in this line: https://github.com/bitcoin/bitcoin/pull/1389/files#L9R151

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 31, 2012
  1. @sipa

    Rework network config settings

    sipa committed
Showing with 237 additions and 164 deletions.
  1. +4 −1 src/bitcoinrpc.cpp
  2. +65 −54 src/init.cpp
  3. +1 −3 src/irc.cpp
  4. +2 −2 src/main.cpp
  5. +19 −35 src/net.cpp
  6. +3 −1 src/net.h
  7. +77 −42 src/netbase.cpp
  8. +8 −9 src/netbase.h
  9. +1 −1 src/qt/optionsdialog.cpp
  10. +55 −15 src/qt/optionsmodel.cpp
  11. +2 −1 src/qt/optionsmodel.h
View
5 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);
@luke-jr Bitcoin member
luke-jr added a note

Why does GetProxy have NET_IPV4 all over? do IPv6 proxies work?

@sipa Bitcoin member
sipa added a note

Internally, proxies can be selected separately for each network, and for hostname-based destination. The config and GUI right now are pinned to assume the IPv4 one is the only one, so they read NET_IPV4, and modify the NET_IPV4, NET_IPV6, and named ones simuitaneously.

It's just a temporary measure, I expect the GUI config panel will be extended with more proxy options, and for RPC maybe we can move to a "getnetconfig" command that returns this kind of information, including connected peers and some statistics?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
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
119 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"))
View
4 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);
View
4 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())
View
54 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");
View
4 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;
View
119 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;
View
17 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
View
2 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);
}
View
70 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
{
View
3 src/qt/optionsmodel.h
@@ -20,7 +20,8 @@ class OptionsModel : public QAbstractListModel
MinimizeToTray, // bool
MapPortUPnP, // bool
MinimizeOnClose, // bool
- ConnectSOCKS4, // bool
+ ProxyUse, // bool
+ ProxySocksVersion, // int
ProxyIP, // QString
ProxyPort, // QString
Fee, // qint64
Something went wrong with that request. Please try again.