#ifdef USE_UPNP
void ThreadMapPort2(void* parg);
#endif
+void ThreadDNSAddressSeed2(void* parg);
bool OpenNetworkConnection(const CAddress& addrConnect);
if (addr.ip == addrLocalHost.ip)
return false;
addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
+ bool fUpdated = false;
+ bool fNew = false;
+ CAddress addrFound = addr;
+
CRITICAL_BLOCK(cs_mapAddresses)
{
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
// New address
printf("AddAddress(%s)\n", addr.ToString().c_str());
mapAddresses.insert(make_pair(addr.GetKey(), addr));
- if (pAddrDB)
- pAddrDB->WriteAddress(addr);
- else
- CAddrDB().WriteAddress(addr);
- return true;
+ fUpdated = true;
+ fNew = true;
}
else
{
- bool fUpdated = false;
- CAddress& addrFound = (*it).second;
+ addrFound = (*it).second;
if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
{
// Services have been added
addrFound.nTime = addr.nTime;
fUpdated = true;
}
- if (fUpdated)
- {
- if (pAddrDB)
- pAddrDB->WriteAddress(addrFound);
- else
- CAddrDB().WriteAddress(addrFound);
- }
}
}
- return false;
+ // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
+ // CRITICAL_BLOCK:
+ // Thread 1: begin db transaction (locks inside-db-mutex)
+ // then AddAddress (locks cs_mapAddresses)
+ // Thread 2: AddAddress (locks cs_mapAddresses)
+ // ... then db operation hangs waiting for inside-db-mutex
+ if (fUpdated)
+ {
+ if (pAddrDB)
+ pAddrDB->WriteAddress(addrFound);
+ else
+ CAddrDB().WriteAddress(addrFound);
+ }
+ return fNew;
}
void AddressCurrentlyConnected(const CAddress& addr)
static const char *strDNSSeed[] = {
"bitseed.xf2.org",
- "bitseed.bitcoin.org.uk",
"dnsseed.bluematt.me",
};
-void DNSAddressSeed()
+void ThreadDNSAddressSeed(void* parg)
+{
+ IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
+ try
+ {
+ vnThreadsRunning[6]++;
+ ThreadDNSAddressSeed2(parg);
+ vnThreadsRunning[6]--;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[6]--;
+ PrintException(&e, "ThreadDNSAddressSeed()");
+ } catch (...) {
+ vnThreadsRunning[6]--;
+ throw; // support pthread_cancel()
+ }
+ printf("ThreadDNSAddressSeed exiting\n");
+}
+
+void ThreadDNSAddressSeed2(void* parg)
{
+ printf("ThreadDNSAddressSeed started\n");
int found = 0;
if (!fTestNet)
+
+
+
+
+
+
+
+
+
unsigned int pnSeed[] =
{
0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
CRITICAL_BLOCK(cs_mapAddresses)
{
// Add seed nodes if IRC isn't working
- static bool fSeedUsed;
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
{
{
// It'll only connect to one or two seed nodes because once it connects,
// it'll get a pile of addresses with newer timestamps.
+ // Seed nodes are given a random 'last seen time' of between one and two
+ // weeks ago.
+ const int64 nOneWeek = 7*24*60*60;
CAddress addr;
addr.ip = pnSeed[i];
- addr.nTime = 0;
+ addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
AddAddress(addr);
}
- fSeedUsed = true;
- }
-
- if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
- {
- // Disconnect seed nodes
- set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
- static int64 nSeedDisconnected;
- if (nSeedDisconnected == 0)
- {
- nSeedDisconnected = GetTime();
- CRITICAL_BLOCK(cs_vNodes)
- BOOST_FOREACH(CNode* pnode, vNodes)
- if (setSeed.count(pnode->addr.ip))
- pnode->fDisconnect = true;
- }
-
- // Keep setting timestamps to 0 so they won't reconnect
- if (GetTime() - nSeedDisconnected < 60 * 60)
- {
- BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
- {
- if (setSeed.count(item.second.ip) && item.second.nTime != 0)
- {
- item.second.nTime = 0;
- CAddrDB().WriteAddress(item.second);
- }
- }
- }
}
}
// Start threads
//
+ if (GetBoolArg("-nodnsseed"))
+ printf("DNS seeding disabled\n");
+ else
+ if (!CreateThread(ThreadDNSAddressSeed, NULL))
+ printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
+
// Map ports with UPnP
if (fHaveUPnP)
MapPort(fUseUPnP);
printf("Error: CreateThread(ThreadIRCSeed) failed\n");
// Send and receive from sockets, accept connections
- CreateThread(ThreadSocketHandler, NULL, true);
+ if (!CreateThread(ThreadSocketHandler, NULL))
+ printf("Error: CreateThread(ThreadSocketHandler) failed\n");
// Initiate outbound connections
if (!CreateThread(ThreadOpenConnections, NULL))
if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
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");
while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
Sleep(20);
Sleep(50);