void ThreadMessageHandler2(void* parg);
void ThreadSocketHandler2(void* parg);
void ThreadOpenConnections2(void* parg);
+ void ThreadOpenAddedConnections2(void* parg);
#ifdef USE_UPNP
void ThreadMapPort2(void* parg);
#endif
map<CInv, int64> mapAlreadyAskedFor;
+ set<CNetAddr> setservAddNodeAddresses;
+ CCriticalSection cs_setservAddNodeAddresses;
+
}
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))
{
char port[6];
sprintf(port, "%d", GetListenPort());
- const char * rootdescurl = 0;
const char * multicastif = 0;
const char * minissdpdpath = 0;
struct UPNPDev * devlist = 0;
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
if (r == 1)
{
- char intClient[16];
- char intPort[6];
string strDesc = "Bitcoin " + FormatFullVersion();
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
}
}
- // 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
}
}
+ 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)
{
//
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");
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)
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);
bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
- struct addrinfo aiHint = {};
+ struct addrinfo aiHint;
+ memset(&aiHint, 0, sizeof(struct addrinfo));
+
aiHint.ai_socktype = SOCK_STREAM;
aiHint.ai_protocol = IPPROTO_TCP;
#ifdef WIN32
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;
}
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;
}