Back to home page

Bitcoin sources

 
 

    


0001 // Copyright (c) 2009-2010 Satoshi Nakamoto
0002 // Copyright (c) 2009-2012 The Bitcoin developers
0003 // Distributed under the MIT/X11 software license, see the accompanying
0004 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
0005 
0006 #include "headers.h"
0007 #include "db.h"
0008 #include "net.h"
0009 #include "init.h"
0010 #include "strlcpy.h"
0011 
0012 
0013 using namespace std;
0014 using namespace boost;
0015 
0016 static const int MAX_OUTBOUND_CONNECTIONS = 8;
0017 
0018 void ThreadMessageHandler2(void* parg);
0019 void ThreadSocketHandler2(void* parg);
0020 void ThreadOpenConnections2(void* parg);
0021 bool OpenNetworkConnection(const CAddress& addrConnect);
0022 
0023 
0024 
0025 
0026 
0027 //
0028 // Global state variables
0029 //
0030 bool fClient = false;
0031 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
0032 CAddress addrLocalHost("0.0.0.0", 0, nLocalServices);
0033 static CNode* pnodeLocalHost = NULL;
0034 uint64 nLocalHostNonce = 0;
0035 array<int, 10> vnThreadsRunning;
0036 static SOCKET hListenSocket = INVALID_SOCKET;
0037 
0038 vector<CNode*> vNodes;
0039 CCriticalSection cs_vNodes;
0040 map<vector<unsigned char>, CAddress> mapAddresses;
0041 CCriticalSection cs_mapAddresses;
0042 map<CInv, CDataStream> mapRelay;
0043 deque<pair<int64, CInv> > vRelayExpiration;
0044 CCriticalSection cs_mapRelay;
0045 map<CInv, int64> mapAlreadyAskedFor;
0046 
0047 // Settings
0048 int fUseProxy = false;
0049 int nConnectTimeout = 5000;
0050 CAddress addrProxy("127.0.0.1",9050);
0051 
0052 
0053 
0054 
0055 unsigned short GetListenPort()
0056 {
0057     return (unsigned short)(GetArg("-port", GetDefaultPort()));
0058 }
0059 
0060 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
0061 {
0062     // Filter out duplicate requests
0063     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
0064         return;
0065     pindexLastGetBlocksBegin = pindexBegin;
0066     hashLastGetBlocksEnd = hashEnd;
0067 
0068     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
0069 }
0070 
0071 
0072 
0073 
0074 
0075 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
0076 {
0077     hSocketRet = INVALID_SOCKET;
0078 
0079     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
0080     if (hSocket == INVALID_SOCKET)
0081         return false;
0082 #ifdef SO_NOSIGPIPE
0083     int set = 1;
0084     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
0085 #endif
0086 
0087     bool fProxy = (fUseProxy && addrConnect.IsRoutable());
0088     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
0089 
0090     int fFlags = fcntl(hSocket, F_GETFL, 0);
0091     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
0092 
0093     {
0094         closesocket(hSocket);
0095         return false;
0096     }
0097 
0098 
0099     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
0100     {
0101         // WSAEINVAL is here because some legacy version of winsock uses it
0102         if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
0103         {
0104             struct timeval timeout;
0105             timeout.tv_sec  = nTimeout / 1000;
0106             timeout.tv_usec = (nTimeout % 1000) * 1000;
0107 
0108             fd_set fdset;
0109             FD_ZERO(&fdset);
0110             FD_SET(hSocket, &fdset);
0111             int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
0112             if (nRet == 0)
0113             {
0114                 printf("connection timeout\n");
0115                 closesocket(hSocket);
0116                 return false;
0117             }
0118             if (nRet == SOCKET_ERROR)
0119             {
0120                 printf("select() for connection failed: %i\n",WSAGetLastError());
0121                 closesocket(hSocket);
0122                 return false;
0123             }
0124             socklen_t nRetSize = sizeof(nRet);
0125             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
0126             {
0127                 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
0128                 closesocket(hSocket);
0129                 return false;
0130             }
0131             if (nRet != 0)
0132             {
0133                 printf("connect() failed after select(): %s\n",strerror(nRet));
0134                 closesocket(hSocket);
0135                 return false;
0136             }
0137         }
0138         else
0139         {
0140             printf("connect() failed: %i\n",WSAGetLastError());
0141             closesocket(hSocket);
0142             return false;
0143         }
0144     }
0145 
0146     /*
0147     this isn't even strictly necessary
0148     CNode::ConnectNode immediately turns the socket back to non-blocking
0149     but we'll turn it back to blocking just in case
0150     */
0151     fFlags = fcntl(hSocket, F_GETFL, 0);
0152     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
0153     {
0154         closesocket(hSocket);
0155         return false;
0156     }
0157 
0158     if (fProxy)
0159     {
0160         printf("proxy connecting %s\n", addrConnect.ToString().c_str());
0161         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
0162         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
0163         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
0164         char* pszSocks4 = pszSocks4IP;
0165         int nSize = sizeof(pszSocks4IP);
0166 
0167         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
0168         if (ret != nSize)
0169         {
0170             closesocket(hSocket);
0171             return error("Error sending to proxy");
0172         }
0173         char pchRet[8];
0174         if (recv(hSocket, pchRet, 8, 0) != 8)
0175         {
0176             closesocket(hSocket);
0177             return error("Error reading proxy response");
0178         }
0179         if (pchRet[1] != 0x5a)
0180         {
0181             closesocket(hSocket);
0182             if (pchRet[1] != 0x5b)
0183                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
0184             return false;
0185         }
0186         printf("proxy connected %s\n", addrConnect.ToString().c_str());
0187     }
0188 
0189     hSocketRet = hSocket;
0190     return true;
0191 }
0192 
0193 // portDefault is in host order
0194 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, int portDefault, bool fAllowPort)
0195 {
0196     vaddr.clear();
0197     if (pszName[0] == 0)
0198         return false;
0199     int port = portDefault;
0200     char psz[256];
0201     char *pszHost = psz;
0202     strlcpy(psz, pszName, sizeof(psz));
0203     if (fAllowPort)
0204     {
0205         char* pszColon = strrchr(psz+1,':');
0206         char *pszPortEnd = NULL;
0207         int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
0208         if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
0209         {
0210             if (psz[0] == '[' && pszColon[-1] == ']')
0211             {
0212                 // Future: enable IPv6 colon-notation inside []
0213                 pszHost = psz+1;
0214                 pszColon[-1] = 0;
0215             }
0216             else
0217                 pszColon[0] = 0;
0218             port = portParsed;
0219             if (port < 0 || port > USHRT_MAX)
0220                 port = USHRT_MAX;
0221         }
0222     }
0223 
0224     unsigned int addrIP = inet_addr(pszHost);
0225     if (addrIP != INADDR_NONE)
0226     {
0227         // valid IP address passed
0228         vaddr.push_back(CAddress(addrIP, port, nServices));
0229         return true;
0230     }
0231 
0232     return false;
0233 }
0234 
0235 // portDefault is in host order
0236 bool Lookup(const char *pszName, CAddress& addr, int nServices, int portDefault, bool fAllowPort)
0237 {
0238     vector<CAddress> vaddr;
0239     bool fRet = Lookup(pszName, vaddr, nServices, 1, portDefault, fAllowPort);
0240     if (fRet)
0241         addr = vaddr[0];
0242     return fRet;
0243 }
0244 
0245 
0246 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
0247 {
0248     if (!addr.IsRoutable())
0249         return false;
0250     if (addr.ip == addrLocalHost.ip)
0251         return false;
0252     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
0253     bool fUpdated = false;
0254     bool fNew = false;
0255     CAddress addrFound = addr;
0256 
0257     CRITICAL_BLOCK(cs_mapAddresses)
0258     {
0259         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
0260         if (it == mapAddresses.end())
0261         {
0262             // New address
0263             printf("AddAddress(%s)\n", addr.ToString().c_str());
0264             mapAddresses.insert(make_pair(addr.GetKey(), addr));
0265             fUpdated = true;
0266             fNew = true;
0267         }
0268         else
0269         {
0270             addrFound = (*it).second;
0271             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
0272             {
0273                 // Services have been added
0274                 addrFound.nServices |= addr.nServices;
0275                 fUpdated = true;
0276             }
0277             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
0278             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
0279             if (addrFound.nTime < addr.nTime - nUpdateInterval)
0280             {
0281                 // Periodically update most recently seen time
0282                 addrFound.nTime = addr.nTime;
0283                 fUpdated = true;
0284             }
0285         }
0286     }
0287     // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
0288     // CRITICAL_BLOCK:
0289     // Thread 1:  begin db transaction (locks inside-db-mutex)
0290     //            then AddAddress (locks cs_mapAddresses)
0291     // Thread 2:  AddAddress (locks cs_mapAddresses)
0292     //             ... then db operation hangs waiting for inside-db-mutex
0293     if (fUpdated)
0294     {
0295         if (pAddrDB)
0296             pAddrDB->WriteAddress(addrFound);
0297         else
0298             CAddrDB().WriteAddress(addrFound);
0299     }
0300     return fNew;
0301 }
0302 
0303 void AddressCurrentlyConnected(const CAddress& addr)
0304 {
0305     CAddress *paddrFound = NULL;
0306 
0307     CRITICAL_BLOCK(cs_mapAddresses)
0308     {
0309         // Only if it's been published already
0310         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
0311         if (it != mapAddresses.end())
0312             paddrFound = &(*it).second;
0313     }
0314 
0315     if (paddrFound)
0316     {
0317         int64 nUpdateInterval = 20 * 60;
0318         if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
0319         {
0320             // Periodically update most recently seen time
0321             paddrFound->nTime = GetAdjustedTime();
0322             CAddrDB addrdb;
0323             addrdb.WriteAddress(*paddrFound);
0324         }
0325     }
0326 }
0327 
0328 
0329 
0330 
0331 
0332 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
0333 {
0334     // If the dialog might get closed before the reply comes back,
0335     // call this in the destructor so it doesn't get called after it's deleted.
0336     CRITICAL_BLOCK(cs_vNodes)
0337     {
0338         BOOST_FOREACH(CNode* pnode, vNodes)
0339         {
0340             CRITICAL_BLOCK(pnode->cs_mapRequests)
0341             {
0342                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
0343                 {
0344                     CRequestTracker& tracker = (*mi).second;
0345                     if (tracker.fn == fn && tracker.param1 == param1)
0346                         pnode->mapRequests.erase(mi++);
0347                     else
0348                         mi++;
0349                 }
0350             }
0351         }
0352     }
0353 }
0354 
0355 
0356 
0357 
0358 
0359 
0360 
0361 //
0362 // Subscription methods for the broadcast and subscription system.
0363 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
0364 //
0365 // The subscription system uses a meet-in-the-middle strategy.
0366 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
0367 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
0368 //
0369 
0370 bool AnySubscribed(unsigned int nChannel)
0371 {
0372     if (pnodeLocalHost->IsSubscribed(nChannel))
0373         return true;
0374     CRITICAL_BLOCK(cs_vNodes)
0375         BOOST_FOREACH(CNode* pnode, vNodes)
0376             if (pnode->IsSubscribed(nChannel))
0377                 return true;
0378     return false;
0379 }
0380 
0381 bool CNode::IsSubscribed(unsigned int nChannel)
0382 {
0383     if (nChannel >= vfSubscribe.size())
0384         return false;
0385     return vfSubscribe[nChannel];
0386 }
0387 
0388 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
0389 {
0390     if (nChannel >= vfSubscribe.size())
0391         return;
0392 
0393     if (!AnySubscribed(nChannel))
0394     {
0395         // Relay subscribe
0396         CRITICAL_BLOCK(cs_vNodes)
0397             BOOST_FOREACH(CNode* pnode, vNodes)
0398                 if (pnode != this)
0399                     pnode->PushMessage("subscribe", nChannel, nHops);
0400     }
0401 
0402     vfSubscribe[nChannel] = true;
0403 }
0404 
0405 void CNode::CancelSubscribe(unsigned int nChannel)
0406 {
0407     if (nChannel >= vfSubscribe.size())
0408         return;
0409 
0410     // Prevent from relaying cancel if wasn't subscribed
0411     if (!vfSubscribe[nChannel])
0412         return;
0413     vfSubscribe[nChannel] = false;
0414 
0415     if (!AnySubscribed(nChannel))
0416     {
0417         // Relay subscription cancel
0418         CRITICAL_BLOCK(cs_vNodes)
0419             BOOST_FOREACH(CNode* pnode, vNodes)
0420                 if (pnode != this)
0421                     pnode->PushMessage("sub-cancel", nChannel);
0422     }
0423 }
0424 
0425 
0426 
0427 
0428 
0429 
0430 
0431 
0432 
0433 CNode* FindNode(unsigned int ip)
0434 {
0435     CRITICAL_BLOCK(cs_vNodes)
0436     {
0437         BOOST_FOREACH(CNode* pnode, vNodes)
0438             if (pnode->addr.ip == ip)
0439                 return (pnode);
0440     }
0441     return NULL;
0442 }
0443 
0444 CNode* FindNode(CAddress addr)
0445 {
0446     CRITICAL_BLOCK(cs_vNodes)
0447     {
0448         BOOST_FOREACH(CNode* pnode, vNodes)
0449             if (pnode->addr == addr)
0450                 return (pnode);
0451     }
0452     return NULL;
0453 }
0454 
0455 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
0456 {
0457     if (addrConnect.ip == addrLocalHost.ip)
0458         return NULL;
0459 
0460     // Look for an existing connection
0461     CNode* pnode = FindNode(addrConnect.ip);
0462     if (pnode)
0463     {
0464         if (nTimeout != 0)
0465             pnode->AddRef(nTimeout);
0466         else
0467             pnode->AddRef();
0468         return pnode;
0469     }
0470 
0471     /// debug print
0472     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
0473         addrConnect.ToString().c_str(),
0474         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
0475         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
0476 
0477     CRITICAL_BLOCK(cs_mapAddresses)
0478         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
0479 
0480     // Connect
0481     SOCKET hSocket;
0482     if (ConnectSocket(addrConnect, hSocket))
0483     {
0484         /// debug print
0485         printf("connected %s\n", addrConnect.ToString().c_str());
0486 
0487         // Set to nonblocking
0488         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
0489             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
0490 
0491         // Add node
0492         CNode* pnode = new CNode(hSocket, addrConnect, false);
0493         if (nTimeout != 0)
0494             pnode->AddRef(nTimeout);
0495         else
0496             pnode->AddRef();
0497         CRITICAL_BLOCK(cs_vNodes)
0498             vNodes.push_back(pnode);
0499 
0500         pnode->nTimeConnected = GetTime();
0501         return pnode;
0502     }
0503     else
0504     {
0505         return NULL;
0506     }
0507 }
0508 
0509 void CNode::CloseSocketDisconnect()
0510 {
0511     fDisconnect = true;
0512     if (hSocket != INVALID_SOCKET)
0513     {
0514         if (fDebug)
0515             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
0516         printf("disconnecting node %s\n", addr.ToString().c_str());
0517         closesocket(hSocket);
0518         hSocket = INVALID_SOCKET;
0519     }
0520 }
0521 
0522 void CNode::Cleanup()
0523 {
0524     // All of a nodes broadcasts and subscriptions are automatically torn down
0525     // when it goes down, so a node has to stay up to keep its broadcast going.
0526 
0527     // Cancel subscriptions
0528     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
0529         if (vfSubscribe[nChannel])
0530             CancelSubscribe(nChannel);
0531 }
0532 
0533 
0534 std::map<unsigned int, int64> CNode::setBanned;
0535 CCriticalSection CNode::cs_setBanned;
0536 
0537 void CNode::ClearBanned()
0538 {
0539     setBanned.clear();
0540 }
0541 
0542 bool CNode::IsBanned(unsigned int ip)
0543 {
0544     bool fResult = false;
0545     CRITICAL_BLOCK(cs_setBanned)
0546     {
0547         std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
0548         if (i != setBanned.end())
0549         {
0550             int64 t = (*i).second;
0551             if (GetTime() < t)
0552                 fResult = true;
0553         }
0554     }
0555     return fResult;
0556 }
0557 
0558 bool CNode::Misbehaving(int howmuch)
0559 {
0560     if (addr.IsLocal())
0561     {
0562         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
0563         return false;
0564     }
0565 
0566     nMisbehavior += howmuch;
0567     if (nMisbehavior >= GetArg("-banscore", 100))
0568     {
0569         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
0570         CRITICAL_BLOCK(cs_setBanned)
0571             if (setBanned[addr.ip] < banTime)
0572                 setBanned[addr.ip] = banTime;
0573         CloseSocketDisconnect();
0574         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
0575         return true;
0576     }
0577     return false;
0578 }
0579 
0580 
0581 
0582 
0583 
0584 
0585 
0586 
0587 
0588 
0589 
0590 
0591 void ThreadSocketHandler(void* parg)
0592 {
0593     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
0594     try
0595     {
0596         vnThreadsRunning[0]++;
0597         ThreadSocketHandler2(parg);
0598         vnThreadsRunning[0]--;
0599     }
0600     catch (std::exception& e) {
0601         vnThreadsRunning[0]--;
0602         PrintException(&e, "ThreadSocketHandler()");
0603     } catch (...) {
0604         vnThreadsRunning[0]--;
0605         throw; // support pthread_cancel()
0606     }
0607     printf("ThreadSocketHandler exiting\n");
0608 }
0609 
0610 void ThreadSocketHandler2(void* parg)
0611 {
0612     printf("ThreadSocketHandler started\n");
0613     list<CNode*> vNodesDisconnected;
0614     int nPrevNodeCount = 0;
0615 
0616     loop
0617     {
0618         //
0619         // Disconnect nodes
0620         //
0621         CRITICAL_BLOCK(cs_vNodes)
0622         {
0623             // Disconnect unused nodes
0624             vector<CNode*> vNodesCopy = vNodes;
0625             BOOST_FOREACH(CNode* pnode, vNodesCopy)
0626             {
0627                 if (pnode->fDisconnect ||
0628                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
0629                 {
0630                     // remove from vNodes
0631                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
0632 
0633                     // close socket and cleanup
0634                     pnode->CloseSocketDisconnect();
0635                     pnode->Cleanup();
0636 
0637                     // hold in disconnected pool until all refs are released
0638                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
0639                     if (pnode->fNetworkNode || pnode->fInbound)
0640                         pnode->Release();
0641                     vNodesDisconnected.push_back(pnode);
0642                 }
0643             }
0644 
0645             // Delete disconnected nodes
0646             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
0647             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
0648             {
0649                 // wait until threads are done using it
0650                 if (pnode->GetRefCount() <= 0)
0651                 {
0652                     bool fDelete = false;
0653                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
0654                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
0655                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
0656                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
0657                         fDelete = true;
0658                     if (fDelete)
0659                     {
0660                         vNodesDisconnected.remove(pnode);
0661                         delete pnode;
0662                     }
0663                 }
0664             }
0665         }
0666         if (vNodes.size() != nPrevNodeCount)
0667         {
0668             nPrevNodeCount = vNodes.size();
0669             MainFrameRepaint();
0670         }
0671 
0672 
0673         //
0674         // Find which sockets have data to receive
0675         //
0676         struct timeval timeout;
0677         timeout.tv_sec  = 0;
0678         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
0679 
0680         fd_set fdsetRecv;
0681         fd_set fdsetSend;
0682         fd_set fdsetError;
0683         FD_ZERO(&fdsetRecv);
0684         FD_ZERO(&fdsetSend);
0685         FD_ZERO(&fdsetError);
0686         SOCKET hSocketMax = 0;
0687 
0688         if(hListenSocket != INVALID_SOCKET)
0689             FD_SET(hListenSocket, &fdsetRecv);
0690         hSocketMax = max(hSocketMax, hListenSocket);
0691         CRITICAL_BLOCK(cs_vNodes)
0692         {
0693             BOOST_FOREACH(CNode* pnode, vNodes)
0694             {
0695                 if (pnode->hSocket == INVALID_SOCKET)
0696                     continue;
0697                 FD_SET(pnode->hSocket, &fdsetRecv);
0698                 FD_SET(pnode->hSocket, &fdsetError);
0699                 hSocketMax = max(hSocketMax, pnode->hSocket);
0700                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
0701                     if (!pnode->vSend.empty())
0702                         FD_SET(pnode->hSocket, &fdsetSend);
0703             }
0704         }
0705 
0706         vnThreadsRunning[0]--;
0707         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
0708         vnThreadsRunning[0]++;
0709         if (fShutdown)
0710             return;
0711         if (nSelect == SOCKET_ERROR)
0712         {
0713             int nErr = WSAGetLastError();
0714             if (hSocketMax > -1)
0715             {
0716                 printf("socket select error %d\n", nErr);
0717                 for (int i = 0; i <= hSocketMax; i++)
0718                     FD_SET(i, &fdsetRecv);
0719             }
0720             FD_ZERO(&fdsetSend);
0721             FD_ZERO(&fdsetError);
0722             Sleep(timeout.tv_usec/1000);
0723         }
0724 
0725 
0726         //
0727         // Accept new connections
0728         //
0729         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
0730         {
0731             struct sockaddr_in sockaddr;
0732             socklen_t len = sizeof(sockaddr);
0733             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
0734             CAddress addr;
0735             int nInbound = 0;
0736 
0737             if (hSocket != INVALID_SOCKET)
0738                 addr = CAddress(sockaddr);
0739 
0740             CRITICAL_BLOCK(cs_vNodes)
0741                 BOOST_FOREACH(CNode* pnode, vNodes)
0742                 if (pnode->fInbound)
0743                     nInbound++;
0744 
0745             if (hSocket == INVALID_SOCKET)
0746             {
0747                 if (WSAGetLastError() != WSAEWOULDBLOCK)
0748                     printf("socket error accept failed: %d\n", WSAGetLastError());
0749             }
0750             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
0751             {
0752                 closesocket(hSocket);
0753             }
0754             else if (CNode::IsBanned(addr.ip))
0755             {
0756                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
0757                 closesocket(hSocket);
0758             }
0759             else
0760             {
0761                 printf("accepted connection %s\n", addr.ToString().c_str());
0762                 CNode* pnode = new CNode(hSocket, addr, true);
0763                 pnode->AddRef();
0764                 CRITICAL_BLOCK(cs_vNodes)
0765                     vNodes.push_back(pnode);
0766             }
0767         }
0768 
0769 
0770         //
0771         // Service each socket
0772         //
0773         vector<CNode*> vNodesCopy;
0774         CRITICAL_BLOCK(cs_vNodes)
0775         {
0776             vNodesCopy = vNodes;
0777             BOOST_FOREACH(CNode* pnode, vNodesCopy)
0778                 pnode->AddRef();
0779         }
0780         BOOST_FOREACH(CNode* pnode, vNodesCopy)
0781         {
0782             if (fShutdown)
0783                 return;
0784 
0785             //
0786             // Receive
0787             //
0788             if (pnode->hSocket == INVALID_SOCKET)
0789                 continue;
0790             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
0791             {
0792                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
0793                 {
0794                     CDataStream& vRecv = pnode->vRecv;
0795                     unsigned int nPos = vRecv.size();
0796 
0797                     if (nPos > ReceiveBufferSize()) {
0798                         if (!pnode->fDisconnect)
0799                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
0800                         pnode->CloseSocketDisconnect();
0801                     }
0802                     else {
0803                         // typical socket buffer is 8K-64K
0804                         char pchBuf[0x10000];
0805                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
0806                         if (nBytes > 0)
0807                         {
0808                             vRecv.resize(nPos + nBytes);
0809                             memcpy(&vRecv[nPos], pchBuf, nBytes);
0810                             pnode->nLastRecv = GetTime();
0811                         }
0812                         else if (nBytes == 0)
0813                         {
0814                             // socket closed gracefully
0815                             if (!pnode->fDisconnect)
0816                                 printf("socket closed\n");
0817                             pnode->CloseSocketDisconnect();
0818                         }
0819                         else if (nBytes < 0)
0820                         {
0821                             // error
0822                             int nErr = WSAGetLastError();
0823                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
0824                             {
0825                                 if (!pnode->fDisconnect)
0826                                     printf("socket recv error %d\n", nErr);
0827                                 pnode->CloseSocketDisconnect();
0828                             }
0829                         }
0830                     }
0831                 }
0832             }
0833 
0834             //
0835             // Send
0836             //
0837             if (pnode->hSocket == INVALID_SOCKET)
0838                 continue;
0839             if (FD_ISSET(pnode->hSocket, &fdsetSend))
0840             {
0841                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
0842                 {
0843                     CDataStream& vSend = pnode->vSend;
0844                     if (!vSend.empty())
0845                     {
0846                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
0847                         if (nBytes > 0)
0848                         {
0849                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
0850                             pnode->nLastSend = GetTime();
0851                         }
0852                         else if (nBytes < 0)
0853                         {
0854                             // error
0855                             int nErr = WSAGetLastError();
0856                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
0857                             {
0858                                 printf("socket send error %d\n", nErr);
0859                                 pnode->CloseSocketDisconnect();
0860                             }
0861                         }
0862                         if (vSend.size() > SendBufferSize()) {
0863                             if (!pnode->fDisconnect)
0864                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
0865                             pnode->CloseSocketDisconnect();
0866                         }
0867                     }
0868                 }
0869             }
0870 
0871             //
0872             // Inactivity checking
0873             //
0874             if (pnode->vSend.empty())
0875                 pnode->nLastSendEmpty = GetTime();
0876             if (GetTime() - pnode->nTimeConnected > 60)
0877             {
0878                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
0879                 {
0880                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
0881                     pnode->fDisconnect = true;
0882                 }
0883                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
0884                 {
0885                     printf("socket not sending\n");
0886                     pnode->fDisconnect = true;
0887                 }
0888                 else if (GetTime() - pnode->nLastRecv > 90*60)
0889                 {
0890                     printf("socket inactivity timeout\n");
0891                     pnode->fDisconnect = true;
0892                 }
0893             }
0894         }
0895         CRITICAL_BLOCK(cs_vNodes)
0896         {
0897             BOOST_FOREACH(CNode* pnode, vNodesCopy)
0898                 pnode->Release();
0899         }
0900 
0901         Sleep(10);
0902     }
0903 }
0904 
0905 
0906 void ThreadOpenConnections(void* parg)
0907 {
0908     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
0909     try
0910     {
0911         vnThreadsRunning[1]++;
0912         ThreadOpenConnections2(parg);
0913         vnThreadsRunning[1]--;
0914     }
0915     catch (std::exception& e) {
0916         vnThreadsRunning[1]--;
0917         PrintException(&e, "ThreadOpenConnections()");
0918     } catch (...) {
0919         vnThreadsRunning[1]--;
0920         PrintException(NULL, "ThreadOpenConnections()");
0921     }
0922     printf("ThreadOpenConnections exiting\n");
0923 }
0924 
0925 void ThreadOpenConnections2(void* parg)
0926 {
0927     printf("ThreadOpenConnections started\n");
0928 
0929     // Connect to specific addresses
0930     if (mapArgs.count("-connect"))
0931     {
0932         for (int64 nLoop = 0;; nLoop++)
0933         {
0934             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
0935             {
0936                 CAddress addr(strAddr);
0937                 if (addr.IsValid())
0938                     OpenNetworkConnection(addr);
0939                 for (int i = 0; i < 10 && i < nLoop; i++)
0940                 {
0941                     Sleep(500);
0942                     if (fShutdown)
0943                         return;
0944                 }
0945             }
0946         }
0947     }
0948 
0949     // Connect to manually added nodes first
0950     if (mapArgs.count("-addnode"))
0951     {
0952         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
0953         {
0954             CAddress addr(strAddr);
0955             if (addr.IsValid())
0956             {
0957                 OpenNetworkConnection(addr);
0958                 Sleep(500);
0959                 if (fShutdown)
0960                     return;
0961             }
0962         }
0963     }
0964 
0965     // Initiate network connections
0966     int64 nStart = GetTime();
0967     loop
0968     {
0969         vnThreadsRunning[1]--;
0970         Sleep(500);
0971         vnThreadsRunning[1]++;
0972         if (fShutdown)
0973             return;
0974 
0975         // Limit outbound connections
0976         loop
0977         {
0978             int nOutbound = 0;
0979             CRITICAL_BLOCK(cs_vNodes)
0980                 BOOST_FOREACH(CNode* pnode, vNodes)
0981                     if (!pnode->fInbound)
0982                         nOutbound++;
0983             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
0984             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
0985             if (nOutbound < nMaxOutboundConnections)
0986                 break;
0987             vnThreadsRunning[1]--;
0988             Sleep(2000);
0989             vnThreadsRunning[1]++;
0990             if (fShutdown)
0991                 return;
0992         }
0993 
0994         //
0995         // Choose an address to connect to based on most recently seen
0996         //
0997         CAddress addrConnect;
0998         int64 nBest = INT64_MIN;
0999 
1000         // Only connect to one address per a.b.?.? range.
1001         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1002         set<unsigned int> setConnected;
1003         CRITICAL_BLOCK(cs_vNodes)
1004             BOOST_FOREACH(CNode* pnode, vNodes)
1005                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1006 
1007         int64 nANow = GetAdjustedTime();
1008 
1009         CRITICAL_BLOCK(cs_mapAddresses)
1010         {
1011             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1012             {
1013                 const CAddress& addr = item.second;
1014                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1015                     continue;
1016                 int64 nSinceLastSeen = nANow - addr.nTime;
1017                 int64 nSinceLastTry = nANow - addr.nLastTry;
1018 
1019                 // Randomize the order in a deterministic way, putting the standard port first
1020                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1021                 if (addr.port != htons(GetDefaultPort()))
1022                     nRandomizer += 2 * 60 * 60;
1023 
1024                 // Last seen  Base retry frequency
1025                 //   <1 hour   10 min
1026                 //    1 hour    1 hour
1027                 //    4 hours   2 hours
1028                 //   24 hours   5 hours
1029                 //   48 hours   7 hours
1030                 //    7 days   13 hours
1031                 //   30 days   27 hours
1032                 //   90 days   46 hours
1033                 //  365 days   93 hours
1034                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1035 
1036                 // Fast reconnect for one hour after last seen
1037                 if (nSinceLastSeen < 60 * 60)
1038                     nDelay = 10 * 60;
1039 
1040                 // Limit retry frequency
1041                 if (nSinceLastTry < nDelay)
1042                     continue;
1043 
1044                 // Only try the old stuff if we don't have enough connections
1045                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1046                     continue;
1047 
1048                 // If multiple addresses are ready, prioritize by time since
1049                 // last seen and time since last tried.
1050                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1051                 if (nScore > nBest)
1052                 {
1053                     nBest = nScore;
1054                     addrConnect = addr;
1055                 }
1056             }
1057         }
1058 
1059         if (addrConnect.IsValid())
1060             OpenNetworkConnection(addrConnect);
1061     }
1062 }
1063 
1064 bool OpenNetworkConnection(const CAddress& addrConnect)
1065 {
1066     //
1067     // Initiate outbound network connection
1068     //
1069     if (fShutdown)
1070         return false;
1071     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1072         FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1073         return false;
1074 
1075     vnThreadsRunning[1]--;
1076     CNode* pnode = ConnectNode(addrConnect);
1077     vnThreadsRunning[1]++;
1078     if (fShutdown)
1079         return false;
1080     if (!pnode)
1081         return false;
1082     pnode->fNetworkNode = true;
1083 
1084     return true;
1085 }
1086 
1087 
1088 
1089 
1090 
1091 
1092 
1093 
1094 void ThreadMessageHandler(void* parg)
1095 {
1096     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1097     try
1098     {
1099         vnThreadsRunning[2]++;
1100         ThreadMessageHandler2(parg);
1101         vnThreadsRunning[2]--;
1102     }
1103     catch (std::exception& e) {
1104         vnThreadsRunning[2]--;
1105         PrintException(&e, "ThreadMessageHandler()");
1106     } catch (...) {
1107         vnThreadsRunning[2]--;
1108         PrintException(NULL, "ThreadMessageHandler()");
1109     }
1110     printf("ThreadMessageHandler exiting\n");
1111 }
1112 
1113 void ThreadMessageHandler2(void* parg)
1114 {
1115     printf("ThreadMessageHandler started\n");
1116     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1117     while (!fShutdown)
1118     {
1119         vector<CNode*> vNodesCopy;
1120         CRITICAL_BLOCK(cs_vNodes)
1121         {
1122             vNodesCopy = vNodes;
1123             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1124                 pnode->AddRef();
1125         }
1126 
1127         // Poll the connected nodes for messages
1128         CNode* pnodeTrickle = NULL;
1129         if (!vNodesCopy.empty())
1130             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1131         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1132         {
1133             // Receive messages
1134             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1135                 ProcessMessages(pnode);
1136             if (fShutdown)
1137                 return;
1138 
1139             // Send messages
1140             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1141                 SendMessages(pnode, pnode == pnodeTrickle);
1142             if (fShutdown)
1143                 return;
1144         }
1145 
1146         CRITICAL_BLOCK(cs_vNodes)
1147         {
1148             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1149                 pnode->Release();
1150         }
1151 
1152         // Wait and allow messages to bunch up.
1153         // Reduce vnThreadsRunning so StopNode has permission to exit while
1154         // we're sleeping, but we must always check fShutdown after doing this.
1155         vnThreadsRunning[2]--;
1156         Sleep(100);
1157         if (fRequestShutdown)
1158             Shutdown(NULL);
1159         vnThreadsRunning[2]++;
1160         if (fShutdown)
1161             return;
1162     }
1163 }
1164 
1165 
1166 
1167 
1168 
1169 
1170 bool BindListenPort(string& strError)
1171 {
1172     strError = "";
1173     int nOne = 1;
1174     addrLocalHost.port = htons(GetListenPort());
1175 
1176     // Create socket for listening for incoming connections
1177     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1178     if (hListenSocket == INVALID_SOCKET)
1179     {
1180         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1181         printf("%s\n", strError.c_str());
1182         return false;
1183     }
1184 
1185 #ifdef SO_NOSIGPIPE
1186     // Different way of disabling SIGPIPE on BSD
1187     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1188 #endif
1189 
1190     // Allow binding if the port is still in TIME_WAIT state after
1191     // the program was closed and restarted.  Not an issue on windows.
1192     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1193 
1194     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1195     {
1196         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1197         printf("%s\n", strError.c_str());
1198         return false;
1199     }
1200 
1201     // The sockaddr_in structure specifies the address family,
1202     // IP address, and port for the socket that is being bound
1203     struct sockaddr_in sockaddr;
1204     memset(&sockaddr, 0, sizeof(sockaddr));
1205     sockaddr.sin_family = AF_INET;
1206     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1207     sockaddr.sin_port = htons(GetListenPort());
1208     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1209     {
1210         int nErr = WSAGetLastError();
1211         if (nErr == WSAEADDRINUSE)
1212             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1213         else
1214             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1215         printf("%s\n", strError.c_str());
1216         return false;
1217     }
1218     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1219 
1220     // Listen for incoming connections
1221     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1222     {
1223         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1224         printf("%s\n", strError.c_str());
1225         return false;
1226     }
1227 
1228     return true;
1229 }
1230 
1231 void StartNode(void* parg)
1232 {
1233     if (pnodeLocalHost == NULL)
1234         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, nLocalServices));
1235 
1236     // Get local host ip
1237     struct ifaddrs* myaddrs;
1238     if (getifaddrs(&myaddrs) == 0)
1239     {
1240         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1241         {
1242             if (ifa->ifa_addr == NULL) continue;
1243             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1244             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1245             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1246             char pszIP[100];
1247             if (ifa->ifa_addr->sa_family == AF_INET)
1248             {
1249                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1250                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1251                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1252 
1253                 // Take the first IP that isn't loopback 127.x.x.x
1254                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1255                 if (addr.IsValid() && addr.GetByte(3) != 127)
1256                 {
1257                     addrLocalHost = addr;
1258                     break;
1259                 }
1260             }
1261             else if (ifa->ifa_addr->sa_family == AF_INET6)
1262             {
1263                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1264                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1265                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1266             }
1267         }
1268         freeifaddrs(myaddrs);
1269     }
1270 
1271     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1272 
1273     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1274     {
1275         // Proxies can't take incoming connections
1276         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1277     }
1278     else
1279     {
1280         addrLocalHost.ip = CAddress(mapArgs["-myip"]).ip;
1281         if (!addrLocalHost.IsValid())
1282       throw runtime_error(strprintf(_("You must set myip=<ipaddress> on the command line or in the configuration file:\n%s\n"
1283                       "If the file does not exist, create it with owner-readable-only file permissions."),
1284                     GetConfigFile().c_str()));
1285     }
1286 
1287     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1288 
1289     //
1290     // Start threads
1291     //
1292 
1293     // Send and receive from sockets, accept connections
1294     if (!CreateThread(ThreadSocketHandler, NULL))
1295         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1296 
1297     // Initiate outbound connections
1298     if (!CreateThread(ThreadOpenConnections, NULL))
1299         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1300 
1301     // Process messages
1302     if (!CreateThread(ThreadMessageHandler, NULL))
1303         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1304 
1305     // Generate coins in the background
1306     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1307 }
1308 
1309 bool StopNode()
1310 {
1311     printf("StopNode()\n");
1312     fShutdown = true;
1313     nTransactionsUpdated++;
1314     int64 nStart = GetTime();
1315     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1316     )
1317     {
1318         if (GetTime() - nStart > 20)
1319             break;
1320         Sleep(20);
1321     }
1322     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1323     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1324     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1325     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1326     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1327     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1328         Sleep(20);
1329     Sleep(50);
1330 
1331     return true;
1332 }
1333 
1334 class CNetCleanup
1335 {
1336 public:
1337     CNetCleanup()
1338     {
1339     }
1340     ~CNetCleanup()
1341     {
1342         // Close sockets
1343         BOOST_FOREACH(CNode* pnode, vNodes)
1344             if (pnode->hSocket != INVALID_SOCKET)
1345                 closesocket(pnode->hSocket);
1346         if (hListenSocket != INVALID_SOCKET)
1347             if (closesocket(hListenSocket) == SOCKET_ERROR)
1348                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1349 
1350     }
1351 }
1352 instance_of_cnetcleanup;