aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp6
-rw-r--r--src/net.cpp115
-rw-r--r--src/netbase.cpp36
-rw-r--r--src/netbase.h13
-rw-r--r--src/protocol.h2
-rw-r--r--src/qt/bitcoingui.cpp5
-rw-r--r--src/qt/forms/aboutdialog.ui2
-rw-r--r--src/qt/forms/sendcoinsdialog.ui3
-rw-r--r--src/qt/optionsmodel.cpp4
9 files changed, 133 insertions, 53 deletions
diff --git a/src/init.cpp b/src/init.cpp
index e01516eb33..837d73f959 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -192,7 +192,7 @@ bool AppInit2(int argc, char* argv[])
" -dns \t " + _("Allow DNS lookups for addnode and connect") + "\n" +
" -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
" -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
- " -addnode=<ip> \t " + _("Add a node to connect to") + "\n" +
+ " -addnode=<ip> \t " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
" -connect=<ip> \t\t " + _("Connect only to the specified node") + "\n" +
" -noirc \t " + _("Don't find peers using internet relay chat") + "\n" +
" -nolisten \t " + _("Don't accept connections from outside") + "\n" +
@@ -463,7 +463,7 @@ bool AppInit2(int argc, char* argv[])
if (mapArgs.count("-proxy"))
{
fUseProxy = true;
- addrProxy = CAddress(mapArgs["-proxy"]);
+ addrProxy = CService(mapArgs["-proxy"], 9050);
if (!addrProxy.IsValid())
{
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
@@ -512,7 +512,7 @@ bool AppInit2(int argc, char* argv[])
{
BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
{
- CAddress addr(strAddr, fAllowDNS);
+ CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
addr.nTime = 0; // so it won't relay unless successfully connected
if (addr.IsValid())
AddAddress(addr);
diff --git a/src/net.cpp b/src/net.cpp
index 817203b013..b91a8f69c6 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -29,6 +29,7 @@ static const int MAX_OUTBOUND_CONNECTIONS = 8;
void ThreadMessageHandler2(void* parg);
void ThreadSocketHandler2(void* parg);
void ThreadOpenConnections2(void* parg);
+void ThreadOpenAddedConnections2(void* parg);
#ifdef USE_UPNP
void ThreadMapPort2(void* parg);
#endif
@@ -61,6 +62,9 @@ CCriticalSection cs_mapRelay;
map<CInv, int64> mapAlreadyAskedFor;
+set<CNetAddr> setservAddNodeAddresses;
+CCriticalSection cs_setservAddNodeAddresses;
+
@@ -133,7 +137,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
// We now get our external IP from the IRC server first and only use this as a backup
bool GetMyExternalIP(CNetAddr& ipRet)
{
- CAddress addrConnect;
+ CService addrConnect;
const char* pszGet;
const char* pszKeyword;
@@ -149,7 +153,7 @@ bool GetMyExternalIP(CNetAddr& ipRet)
// <?php echo $_SERVER["REMOTE_ADDR"]; ?>
if (nHost == 1)
{
- addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
+ addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
if (nLookup == 1)
{
@@ -168,7 +172,7 @@ bool GetMyExternalIP(CNetAddr& ipRet)
}
else if (nHost == 2)
{
- addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
+ addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
if (nLookup == 1)
{
@@ -525,8 +529,8 @@ void CNode::PushVersion()
{
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
- CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
- CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
+ CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
+ CAddress addrMe = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
@@ -750,7 +754,9 @@ void ThreadSocketHandler2(void* parg)
}
else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
{
- closesocket(hSocket);
+ CRITICAL_BLOCK(cs_setservAddNodeAddresses)
+ if (!setservAddNodeAddresses.count(addr))
+ closesocket(hSocket);
}
else if (CNode::IsBanned(addr))
{
@@ -1198,7 +1204,7 @@ void ThreadOpenConnections2(void* parg)
{
BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
{
- CAddress addr(strAddr, fAllowDNS);
+ CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
if (addr.IsValid())
OpenNetworkConnection(addr);
for (int i = 0; i < 10 && i < nLoop; i++)
@@ -1211,22 +1217,6 @@ void ThreadOpenConnections2(void* parg)
}
}
- // Connect to manually added nodes first
- if (mapArgs.count("-addnode"))
- {
- BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
- {
- CAddress addr(strAddr, fAllowDNS);
- if (addr.IsValid())
- {
- OpenNetworkConnection(addr);
- Sleep(500);
- if (fShutdown)
- return;
- }
- }
- }
-
// Initiate network connections
int64 nStart = GetTime();
loop
@@ -1355,6 +1345,76 @@ void ThreadOpenConnections2(void* parg)
}
}
+void ThreadOpenAddedConnections(void* parg)
+{
+ IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
+ try
+ {
+ vnThreadsRunning[7]++;
+ ThreadOpenAddedConnections2(parg);
+ vnThreadsRunning[7]--;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[7]--;
+ PrintException(&e, "ThreadOpenAddedConnections()");
+ } catch (...) {
+ vnThreadsRunning[7]--;
+ PrintException(NULL, "ThreadOpenAddedConnections()");
+ }
+ printf("ThreadOpenAddedConnections exiting\n");
+}
+
+void ThreadOpenAddedConnections2(void* parg)
+{
+ printf("ThreadOpenAddedConnections started\n");
+
+ if (mapArgs.count("-addnode") == 0)
+ return;
+
+ vector<vector<CService> > vservAddressesToAdd(0);
+ BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
+ {
+ vector<CService> vservNode(0);
+ if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
+ {
+ vservAddressesToAdd.push_back(vservNode);
+ CRITICAL_BLOCK(cs_setservAddNodeAddresses)
+ BOOST_FOREACH(CService& serv, vservNode)
+ setservAddNodeAddresses.insert(serv);
+ }
+ }
+ loop
+ {
+ vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
+ // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
+ // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
+ CRITICAL_BLOCK(cs_vNodes)
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
+ BOOST_FOREACH(CService& addrNode, *(it))
+ if (pnode->addr == addrNode)
+ {
+ it = vservConnectAddresses.erase(it);
+ it--;
+ break;
+ }
+ BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
+ {
+ OpenNetworkConnection(CAddress(*(vserv.begin())));
+ Sleep(500);
+ if (fShutdown)
+ return;
+ }
+ if (fShutdown)
+ return;
+ vnThreadsRunning[7]--;
+ Sleep(120000); // Retry every 2 minutes
+ vnThreadsRunning[7]++;
+ if (fShutdown)
+ return;
+ }
+}
+
bool OpenNetworkConnection(const CAddress& addrConnect)
{
//
@@ -1631,6 +1691,10 @@ void StartNode(void* parg)
if (!CreateThread(ThreadSocketHandler, NULL))
printf("Error: CreateThread(ThreadSocketHandler) failed\n");
+ // Initiate outbound connections from -addnode
+ if (!CreateThread(ThreadOpenAddedConnections, NULL))
+ printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
+
// Initiate outbound connections
if (!CreateThread(ThreadOpenConnections, NULL))
printf("Error: CreateThread(ThreadOpenConnections) failed\n");
@@ -1650,9 +1714,7 @@ bool StopNode()
nTransactionsUpdated++;
int64 nStart = GetTime();
while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
-#ifdef USE_UPNP
- || vnThreadsRunning[5] > 0
-#endif
+ || (fHaveUPnP && vnThreadsRunning[5] > 0) || vnThreadsRunning[6] > 0 || vnThreadsRunning[7] > 0
)
{
if (GetTime() - nStart > 20)
@@ -1666,6 +1728,7 @@ bool StopNode()
if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
+ if (vnThreadsRunning[7] > 0) printf("ThreadOpenAddedConnections still running\n");
while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
Sleep(20);
Sleep(50);
diff --git a/src/netbase.cpp b/src/netbase.cpp
index ca27c2a8ce..54e3119153 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -98,7 +98,7 @@ bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, int nMax
return LookupHost(pszName, vIP, nMaxSolutions, false);
}
-bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup)
+bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, int nMaxSolutions)
{
if (pszName[0] == 0)
return false;
@@ -132,10 +132,22 @@ bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLoo
}
std::vector<CNetAddr> vIP;
- bool fRet = LookupIntern(pszHost, vIP, 1, fAllowLookup);
+ bool fRet = LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
+ if (!fRet)
+ return false;
+ vAddr.resize(vIP.size());
+ for (int i = 0; i < vIP.size(); i++)
+ vAddr[i] = CService(vIP[i], port);
+ return true;
+}
+
+bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup)
+{
+ std::vector<CService> vService;
+ bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1);
if (!fRet)
return false;
- addr = CService(vIP[0], port);
+ addr = vService[0];
return true;
}
@@ -615,11 +627,12 @@ CService::CService(const char *pszIpPort, bool fAllowLookup)
*this = ip;
}
-CService::CService(const char *pszIp, int portIn, bool fAllowLookup)
+CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup)
{
- std::vector<CNetAddr> ip;
- if (LookupHost(pszIp, ip, 1, fAllowLookup))
- *this = CService(ip[0], portIn);
+ Init();
+ CService ip;
+ if (Lookup(pszIpPort, ip, portDefault, fAllowLookup))
+ *this = ip;
}
CService::CService(const std::string &strIpPort, bool fAllowLookup)
@@ -630,11 +643,12 @@ CService::CService(const std::string &strIpPort, bool fAllowLookup)
*this = ip;
}
-CService::CService(const std::string &strIp, int portIn, bool fAllowLookup)
+CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup)
{
- std::vector<CNetAddr> ip;
- if (LookupHost(strIp.c_str(), ip, 1, fAllowLookup))
- *this = CService(ip[0], portIn);
+ Init();
+ CService ip;
+ if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup))
+ *this = ip;
}
unsigned short CService::GetPort() const
diff --git a/src/netbase.h b/src/netbase.h
index 6f06f8fe08..04ced18260 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -39,8 +39,8 @@ class CNetAddr
public:
CNetAddr();
CNetAddr(const struct in_addr& ipv4Addr);
- CNetAddr(const char *pszIp, bool fAllowLookup = false);
- CNetAddr(const std::string &strIp, bool fAllowLookup = false);
+ explicit CNetAddr(const char *pszIp, bool fAllowLookup = false);
+ explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false);
void Init();
void SetIP(const CNetAddr& ip);
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
@@ -91,10 +91,10 @@ class CService : public CNetAddr
CService(const CNetAddr& ip, unsigned short port);
CService(const struct in_addr& ipv4Addr, unsigned short port);
CService(const struct sockaddr_in& addr);
- CService(const char *pszIp, int port, bool fAllowLookup = false);
- CService(const char *pszIpPort, bool fAllowLookup = false);
- CService(const std::string& strIp, int port, bool fAllowLookup = false);
- CService(const std::string& strIpPort, bool fAllowLookup = false);
+ explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false);
+ explicit CService(const char *pszIpPort, bool fAllowLookup = false);
+ explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false);
+ explicit CService(const std::string& strIpPort, bool fAllowLookup = false);
void Init();
void SetPort(unsigned short portIn);
unsigned short GetPort() const;
@@ -128,6 +128,7 @@ class CService : public CNetAddr
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions = 0, bool fAllowLookup = true);
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions = 0);
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
+bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, int nMaxSolutions = 0);
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
diff --git a/src/protocol.h b/src/protocol.h
index 67e20d94e1..a0bf677aac 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -67,7 +67,7 @@ class CAddress : public CService
{
public:
CAddress();
- CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK);
+ explicit CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK);
void Init();
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index d4ce8a79e1..d77279d42b 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -417,7 +417,6 @@ void BitcoinGUI::setNumBlocks(int count)
{
if(!clientModel)
return;
- int initTotal = clientModel->getNumBlocksAtStartup();
int total = clientModel->getNumBlocksOfPeers();
QString tooltip;
@@ -428,8 +427,8 @@ void BitcoinGUI::setNumBlocks(int count)
progressBarLabel->setVisible(true);
progressBarLabel->setText(tr("Synchronizing with network..."));
progressBar->setVisible(true);
- progressBar->setMaximum(total - initTotal);
- progressBar->setValue(count - initTotal);
+ progressBar->setMaximum(total);
+ progressBar->setValue(count);
}
else
{
diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui
index cf7997326c..127b90965a 100644
--- a/src/qt/forms/aboutdialog.ui
+++ b/src/qt/forms/aboutdialog.ui
@@ -82,7 +82,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
- <string>Copyright © 2009-2011 Bitcoin Developers
+ <string>Copyright © 2009-2012 Bitcoin Developers
This is experimental software.
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index e5e19e1015..04cf404ae3 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -80,6 +80,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="toolTip">
+ <string>Remove all transaction fields</string>
+ </property>
<property name="text">
<string>Clear all</string>
</property>
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 3237845c2c..edc1d61e9d 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -40,7 +40,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
case ProxyIP:
return QVariant(QString::fromStdString(addrProxy.ToStringIP()));
case ProxyPort:
- return QVariant(QString::fromStdString(addrProxy.ToStringPort()));
+ return QVariant(addrProxy.GetPort());
case Fee:
return QVariant(nTransactionFee);
case DisplayUnit:
@@ -87,7 +87,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
case ProxyIP:
{
// Use CAddress to parse and check IP
- CAddress addr(value.toString().toStdString() + ":1");
+ CNetAddr addr(value.toString().toStdString());
if (addr.IsValid())
{
addrProxy.SetIP(addr);