0001
0002
0003
0004
0005
0006 #include "headers.h"
0007 #include "irc.h"
0008 #include "db.h"
0009 #include "net.h"
0010 #include "init.h"
0011 #include "strlcpy.h"
0012
0013
0014 using namespace std;
0015 using namespace boost;
0016
0017 static const int MAX_OUTBOUND_CONNECTIONS = 8;
0018
0019 void ThreadMessageHandler2(void* parg);
0020 void ThreadSocketHandler2(void* parg);
0021 void ThreadOpenConnections2(void* parg);
0022 void ThreadDNSAddressSeed2(void* parg);
0023 bool OpenNetworkConnection(const CAddress& addrConnect);
0024
0025
0026
0027
0028
0029
0030
0031
0032 bool fClient = false;
0033 bool fAllowDNS = false;
0034 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
0035 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
0036 static CNode* pnodeLocalHost = NULL;
0037 uint64 nLocalHostNonce = 0;
0038 array<int, 10> vnThreadsRunning;
0039 static SOCKET hListenSocket = INVALID_SOCKET;
0040
0041 vector<CNode*> vNodes;
0042 CCriticalSection cs_vNodes;
0043 map<vector<unsigned char>, CAddress> mapAddresses;
0044 CCriticalSection cs_mapAddresses;
0045 map<CInv, CDataStream> mapRelay;
0046 deque<pair<int64, CInv> > vRelayExpiration;
0047 CCriticalSection cs_mapRelay;
0048 map<CInv, int64> mapAlreadyAskedFor;
0049
0050
0051 int fUseProxy = false;
0052 int nConnectTimeout = 5000;
0053 CAddress addrProxy("127.0.0.1",9050);
0054
0055
0056
0057
0058 unsigned short GetListenPort()
0059 {
0060 return (unsigned short)(GetArg("-port", GetDefaultPort()));
0061 }
0062
0063 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
0064 {
0065
0066 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
0067 return;
0068 pindexLastGetBlocksBegin = pindexBegin;
0069 hashLastGetBlocksEnd = hashEnd;
0070
0071 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
0072 }
0073
0074
0075
0076
0077
0078 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
0079 {
0080 hSocketRet = INVALID_SOCKET;
0081
0082 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
0083 if (hSocket == INVALID_SOCKET)
0084 return false;
0085 #ifdef SO_NOSIGPIPE
0086 int set = 1;
0087 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
0088 #endif
0089
0090 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
0091 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
0092
0093 int fFlags = fcntl(hSocket, F_GETFL, 0);
0094 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
0095
0096 {
0097 closesocket(hSocket);
0098 return false;
0099 }
0100
0101
0102 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
0103 {
0104
0105 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
0106 {
0107 struct timeval timeout;
0108 timeout.tv_sec = nTimeout / 1000;
0109 timeout.tv_usec = (nTimeout % 1000) * 1000;
0110
0111 fd_set fdset;
0112 FD_ZERO(&fdset);
0113 FD_SET(hSocket, &fdset);
0114 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
0115 if (nRet == 0)
0116 {
0117 printf("connection timeout\n");
0118 closesocket(hSocket);
0119 return false;
0120 }
0121 if (nRet == SOCKET_ERROR)
0122 {
0123 printf("select() for connection failed: %i\n",WSAGetLastError());
0124 closesocket(hSocket);
0125 return false;
0126 }
0127 socklen_t nRetSize = sizeof(nRet);
0128 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
0129 {
0130 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
0131 closesocket(hSocket);
0132 return false;
0133 }
0134 if (nRet != 0)
0135 {
0136 printf("connect() failed after select(): %s\n",strerror(nRet));
0137 closesocket(hSocket);
0138 return false;
0139 }
0140 }
0141 else
0142 {
0143 printf("connect() failed: %i\n",WSAGetLastError());
0144 closesocket(hSocket);
0145 return false;
0146 }
0147 }
0148
0149
0150
0151
0152
0153
0154 fFlags = fcntl(hSocket, F_GETFL, 0);
0155 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
0156 {
0157 closesocket(hSocket);
0158 return false;
0159 }
0160
0161 if (fProxy)
0162 {
0163 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
0164 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
0165 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
0166 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
0167 char* pszSocks4 = pszSocks4IP;
0168 int nSize = sizeof(pszSocks4IP);
0169
0170 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
0171 if (ret != nSize)
0172 {
0173 closesocket(hSocket);
0174 return error("Error sending to proxy");
0175 }
0176 char pchRet[8];
0177 if (recv(hSocket, pchRet, 8, 0) != 8)
0178 {
0179 closesocket(hSocket);
0180 return error("Error reading proxy response");
0181 }
0182 if (pchRet[1] != 0x5a)
0183 {
0184 closesocket(hSocket);
0185 if (pchRet[1] != 0x5b)
0186 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
0187 return false;
0188 }
0189 printf("proxy connected %s\n", addrConnect.ToString().c_str());
0190 }
0191
0192 hSocketRet = hSocket;
0193 return true;
0194 }
0195
0196
0197 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
0198 {
0199 vaddr.clear();
0200 if (pszName[0] == 0)
0201 return false;
0202 int port = portDefault;
0203 char psz[256];
0204 char *pszHost = psz;
0205 strlcpy(psz, pszName, sizeof(psz));
0206 if (fAllowPort)
0207 {
0208 char* pszColon = strrchr(psz+1,':');
0209 char *pszPortEnd = NULL;
0210 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
0211 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
0212 {
0213 if (psz[0] == '[' && pszColon[-1] == ']')
0214 {
0215
0216 pszHost = psz+1;
0217 pszColon[-1] = 0;
0218 }
0219 else
0220 pszColon[0] = 0;
0221 port = portParsed;
0222 if (port < 0 || port > USHRT_MAX)
0223 port = USHRT_MAX;
0224 }
0225 }
0226
0227 unsigned int addrIP = inet_addr(pszHost);
0228 if (addrIP != INADDR_NONE)
0229 {
0230
0231 vaddr.push_back(CAddress(addrIP, port, nServices));
0232 return true;
0233 }
0234
0235 if (!fAllowLookup)
0236 return false;
0237
0238 struct hostent* phostent = gethostbyname(pszHost);
0239 if (!phostent)
0240 return false;
0241
0242 if (phostent->h_addrtype != AF_INET)
0243 return false;
0244
0245 char** ppAddr = phostent->h_addr_list;
0246 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
0247 {
0248 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
0249 if (addr.IsValid())
0250 vaddr.push_back(addr);
0251 ppAddr++;
0252 }
0253
0254 return (vaddr.size() > 0);
0255 }
0256
0257
0258 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
0259 {
0260 vector<CAddress> vaddr;
0261 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
0262 if (fRet)
0263 addr = vaddr[0];
0264 return fRet;
0265 }
0266
0267 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
0268 {
0269 SOCKET hSocket;
0270 if (!ConnectSocket(addrConnect, hSocket))
0271 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
0272
0273 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
0274
0275 string strLine;
0276 while (RecvLine(hSocket, strLine))
0277 {
0278 if (strLine.empty())
0279 {
0280 loop
0281 {
0282 if (!RecvLine(hSocket, strLine))
0283 {
0284 closesocket(hSocket);
0285 return false;
0286 }
0287 if (pszKeyword == NULL)
0288 break;
0289 if (strLine.find(pszKeyword) != -1)
0290 {
0291 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
0292 break;
0293 }
0294 }
0295 closesocket(hSocket);
0296 if (strLine.find("<") != -1)
0297 strLine = strLine.substr(0, strLine.find("<"));
0298 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
0299 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
0300 strLine.resize(strLine.size()-1);
0301 CAddress addr(strLine,0,true);
0302 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
0303 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
0304 return false;
0305 ipRet = addr.ip;
0306 return true;
0307 }
0308 }
0309 closesocket(hSocket);
0310 return error("GetMyExternalIP() : connection closed");
0311 }
0312
0313
0314 bool GetMyExternalIP(unsigned int& ipRet)
0315 {
0316 CAddress addrConnect;
0317 const char* pszGet;
0318 const char* pszKeyword;
0319
0320 if (fUseProxy)
0321 return false;
0322
0323 for (int nLookup = 0; nLookup <= 1; nLookup++)
0324 for (int nHost = 1; nHost <= 2; nHost++)
0325 {
0326
0327
0328
0329
0330 if (nHost == 1)
0331 {
0332 addrConnect = CAddress("91.198.22.70",80);
0333
0334 if (nLookup == 1)
0335 {
0336 CAddress addrIP("checkip.dyndns.org", 80, true);
0337 if (addrIP.IsValid())
0338 addrConnect = addrIP;
0339 }
0340
0341 pszGet = "GET / HTTP/1.1\r\n"
0342 "Host: checkip.dyndns.org\r\n"
0343 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
0344 "Connection: close\r\n"
0345 "\r\n";
0346
0347 pszKeyword = "Address:";
0348 }
0349 else if (nHost == 2)
0350 {
0351 addrConnect = CAddress("74.208.43.192", 80);
0352
0353 if (nLookup == 1)
0354 {
0355 CAddress addrIP("www.showmyip.com", 80, true);
0356 if (addrIP.IsValid())
0357 addrConnect = addrIP;
0358 }
0359
0360 pszGet = "GET /simple/ HTTP/1.1\r\n"
0361 "Host: www.showmyip.com\r\n"
0362 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
0363 "Connection: close\r\n"
0364 "\r\n";
0365
0366 pszKeyword = NULL;
0367 }
0368
0369 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
0370 return true;
0371 }
0372
0373 return false;
0374 }
0375
0376 void ThreadGetMyExternalIP(void* parg)
0377 {
0378
0379 if (!GetBoolArg("-noirc"))
0380 {
0381 for (int i = 0; i < 2 * 60; i++)
0382 {
0383 Sleep(1000);
0384 if (fGotExternalIP || fShutdown)
0385 return;
0386 }
0387 }
0388
0389
0390 if (GetMyExternalIP(addrLocalHost.ip))
0391 {
0392 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
0393 if (addrLocalHost.IsRoutable())
0394 {
0395
0396
0397 CAddress addr(addrLocalHost);
0398 addr.nTime = GetAdjustedTime();
0399 CRITICAL_BLOCK(cs_vNodes)
0400 BOOST_FOREACH(CNode* pnode, vNodes)
0401 pnode->PushAddress(addr);
0402 }
0403 }
0404 }
0405
0406
0407
0408
0409
0410 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
0411 {
0412 if (!addr.IsRoutable())
0413 return false;
0414 if (addr.ip == addrLocalHost.ip)
0415 return false;
0416 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
0417 bool fUpdated = false;
0418 bool fNew = false;
0419 CAddress addrFound = addr;
0420
0421 CRITICAL_BLOCK(cs_mapAddresses)
0422 {
0423 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
0424 if (it == mapAddresses.end())
0425 {
0426
0427 printf("AddAddress(%s)\n", addr.ToString().c_str());
0428 mapAddresses.insert(make_pair(addr.GetKey(), addr));
0429 fUpdated = true;
0430 fNew = true;
0431 }
0432 else
0433 {
0434 addrFound = (*it).second;
0435 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
0436 {
0437
0438 addrFound.nServices |= addr.nServices;
0439 fUpdated = true;
0440 }
0441 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
0442 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
0443 if (addrFound.nTime < addr.nTime - nUpdateInterval)
0444 {
0445
0446 addrFound.nTime = addr.nTime;
0447 fUpdated = true;
0448 }
0449 }
0450 }
0451
0452
0453
0454
0455
0456
0457 if (fUpdated)
0458 {
0459 if (pAddrDB)
0460 pAddrDB->WriteAddress(addrFound);
0461 else
0462 CAddrDB().WriteAddress(addrFound);
0463 }
0464 return fNew;
0465 }
0466
0467 void AddressCurrentlyConnected(const CAddress& addr)
0468 {
0469 CAddress *paddrFound = NULL;
0470
0471 CRITICAL_BLOCK(cs_mapAddresses)
0472 {
0473
0474 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
0475 if (it != mapAddresses.end())
0476 paddrFound = &(*it).second;
0477 }
0478
0479 if (paddrFound)
0480 {
0481 int64 nUpdateInterval = 20 * 60;
0482 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
0483 {
0484
0485 paddrFound->nTime = GetAdjustedTime();
0486 CAddrDB addrdb;
0487 addrdb.WriteAddress(*paddrFound);
0488 }
0489 }
0490 }
0491
0492
0493
0494
0495
0496 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
0497 {
0498
0499
0500 CRITICAL_BLOCK(cs_vNodes)
0501 {
0502 BOOST_FOREACH(CNode* pnode, vNodes)
0503 {
0504 CRITICAL_BLOCK(pnode->cs_mapRequests)
0505 {
0506 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
0507 {
0508 CRequestTracker& tracker = (*mi).second;
0509 if (tracker.fn == fn && tracker.param1 == param1)
0510 pnode->mapRequests.erase(mi++);
0511 else
0512 mi++;
0513 }
0514 }
0515 }
0516 }
0517 }
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534 bool AnySubscribed(unsigned int nChannel)
0535 {
0536 if (pnodeLocalHost->IsSubscribed(nChannel))
0537 return true;
0538 CRITICAL_BLOCK(cs_vNodes)
0539 BOOST_FOREACH(CNode* pnode, vNodes)
0540 if (pnode->IsSubscribed(nChannel))
0541 return true;
0542 return false;
0543 }
0544
0545 bool CNode::IsSubscribed(unsigned int nChannel)
0546 {
0547 if (nChannel >= vfSubscribe.size())
0548 return false;
0549 return vfSubscribe[nChannel];
0550 }
0551
0552 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
0553 {
0554 if (nChannel >= vfSubscribe.size())
0555 return;
0556
0557 if (!AnySubscribed(nChannel))
0558 {
0559
0560 CRITICAL_BLOCK(cs_vNodes)
0561 BOOST_FOREACH(CNode* pnode, vNodes)
0562 if (pnode != this)
0563 pnode->PushMessage("subscribe", nChannel, nHops);
0564 }
0565
0566 vfSubscribe[nChannel] = true;
0567 }
0568
0569 void CNode::CancelSubscribe(unsigned int nChannel)
0570 {
0571 if (nChannel >= vfSubscribe.size())
0572 return;
0573
0574
0575 if (!vfSubscribe[nChannel])
0576 return;
0577 vfSubscribe[nChannel] = false;
0578
0579 if (!AnySubscribed(nChannel))
0580 {
0581
0582 CRITICAL_BLOCK(cs_vNodes)
0583 BOOST_FOREACH(CNode* pnode, vNodes)
0584 if (pnode != this)
0585 pnode->PushMessage("sub-cancel", nChannel);
0586 }
0587 }
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 CNode* FindNode(unsigned int ip)
0598 {
0599 CRITICAL_BLOCK(cs_vNodes)
0600 {
0601 BOOST_FOREACH(CNode* pnode, vNodes)
0602 if (pnode->addr.ip == ip)
0603 return (pnode);
0604 }
0605 return NULL;
0606 }
0607
0608 CNode* FindNode(CAddress addr)
0609 {
0610 CRITICAL_BLOCK(cs_vNodes)
0611 {
0612 BOOST_FOREACH(CNode* pnode, vNodes)
0613 if (pnode->addr == addr)
0614 return (pnode);
0615 }
0616 return NULL;
0617 }
0618
0619 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
0620 {
0621 if (addrConnect.ip == addrLocalHost.ip)
0622 return NULL;
0623
0624
0625 CNode* pnode = FindNode(addrConnect.ip);
0626 if (pnode)
0627 {
0628 if (nTimeout != 0)
0629 pnode->AddRef(nTimeout);
0630 else
0631 pnode->AddRef();
0632 return pnode;
0633 }
0634
0635
0636 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
0637 addrConnect.ToString().c_str(),
0638 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
0639 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
0640
0641 CRITICAL_BLOCK(cs_mapAddresses)
0642 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
0643
0644
0645 SOCKET hSocket;
0646 if (ConnectSocket(addrConnect, hSocket))
0647 {
0648
0649 printf("connected %s\n", addrConnect.ToString().c_str());
0650
0651
0652 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
0653 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
0654
0655
0656 CNode* pnode = new CNode(hSocket, addrConnect, false);
0657 if (nTimeout != 0)
0658 pnode->AddRef(nTimeout);
0659 else
0660 pnode->AddRef();
0661 CRITICAL_BLOCK(cs_vNodes)
0662 vNodes.push_back(pnode);
0663
0664 pnode->nTimeConnected = GetTime();
0665 return pnode;
0666 }
0667 else
0668 {
0669 return NULL;
0670 }
0671 }
0672
0673 void CNode::CloseSocketDisconnect()
0674 {
0675 fDisconnect = true;
0676 if (hSocket != INVALID_SOCKET)
0677 {
0678 if (fDebug)
0679 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
0680 printf("disconnecting node %s\n", addr.ToString().c_str());
0681 closesocket(hSocket);
0682 hSocket = INVALID_SOCKET;
0683 }
0684 }
0685
0686 void CNode::Cleanup()
0687 {
0688
0689
0690
0691
0692 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
0693 if (vfSubscribe[nChannel])
0694 CancelSubscribe(nChannel);
0695 }
0696
0697
0698 std::map<unsigned int, int64> CNode::setBanned;
0699 CCriticalSection CNode::cs_setBanned;
0700
0701 void CNode::ClearBanned()
0702 {
0703 setBanned.clear();
0704 }
0705
0706 bool CNode::IsBanned(unsigned int ip)
0707 {
0708 bool fResult = false;
0709 CRITICAL_BLOCK(cs_setBanned)
0710 {
0711 std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
0712 if (i != setBanned.end())
0713 {
0714 int64 t = (*i).second;
0715 if (GetTime() < t)
0716 fResult = true;
0717 }
0718 }
0719 return fResult;
0720 }
0721
0722 bool CNode::Misbehaving(int howmuch)
0723 {
0724 if (addr.IsLocal())
0725 {
0726 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
0727 return false;
0728 }
0729
0730 nMisbehavior += howmuch;
0731 if (nMisbehavior >= GetArg("-banscore", 100))
0732 {
0733 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);
0734 CRITICAL_BLOCK(cs_setBanned)
0735 if (setBanned[addr.ip] < banTime)
0736 setBanned[addr.ip] = banTime;
0737 CloseSocketDisconnect();
0738 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
0739 return true;
0740 }
0741 return false;
0742 }
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755 void ThreadSocketHandler(void* parg)
0756 {
0757 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
0758 try
0759 {
0760 vnThreadsRunning[0]++;
0761 ThreadSocketHandler2(parg);
0762 vnThreadsRunning[0]--;
0763 }
0764 catch (std::exception& e) {
0765 vnThreadsRunning[0]--;
0766 PrintException(&e, "ThreadSocketHandler()");
0767 } catch (...) {
0768 vnThreadsRunning[0]--;
0769 throw;
0770 }
0771 printf("ThreadSocketHandler exiting\n");
0772 }
0773
0774 void ThreadSocketHandler2(void* parg)
0775 {
0776 printf("ThreadSocketHandler started\n");
0777 list<CNode*> vNodesDisconnected;
0778 int nPrevNodeCount = 0;
0779
0780 loop
0781 {
0782
0783
0784
0785 CRITICAL_BLOCK(cs_vNodes)
0786 {
0787
0788 vector<CNode*> vNodesCopy = vNodes;
0789 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0790 {
0791 if (pnode->fDisconnect ||
0792 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
0793 {
0794
0795 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
0796
0797
0798 pnode->CloseSocketDisconnect();
0799 pnode->Cleanup();
0800
0801
0802 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
0803 if (pnode->fNetworkNode || pnode->fInbound)
0804 pnode->Release();
0805 vNodesDisconnected.push_back(pnode);
0806 }
0807 }
0808
0809
0810 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
0811 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
0812 {
0813
0814 if (pnode->GetRefCount() <= 0)
0815 {
0816 bool fDelete = false;
0817 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
0818 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
0819 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
0820 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
0821 fDelete = true;
0822 if (fDelete)
0823 {
0824 vNodesDisconnected.remove(pnode);
0825 delete pnode;
0826 }
0827 }
0828 }
0829 }
0830 if (vNodes.size() != nPrevNodeCount)
0831 {
0832 nPrevNodeCount = vNodes.size();
0833 MainFrameRepaint();
0834 }
0835
0836
0837
0838
0839
0840 struct timeval timeout;
0841 timeout.tv_sec = 0;
0842 timeout.tv_usec = 50000;
0843
0844 fd_set fdsetRecv;
0845 fd_set fdsetSend;
0846 fd_set fdsetError;
0847 FD_ZERO(&fdsetRecv);
0848 FD_ZERO(&fdsetSend);
0849 FD_ZERO(&fdsetError);
0850 SOCKET hSocketMax = 0;
0851
0852 if(hListenSocket != INVALID_SOCKET)
0853 FD_SET(hListenSocket, &fdsetRecv);
0854 hSocketMax = max(hSocketMax, hListenSocket);
0855 CRITICAL_BLOCK(cs_vNodes)
0856 {
0857 BOOST_FOREACH(CNode* pnode, vNodes)
0858 {
0859 if (pnode->hSocket == INVALID_SOCKET)
0860 continue;
0861 FD_SET(pnode->hSocket, &fdsetRecv);
0862 FD_SET(pnode->hSocket, &fdsetError);
0863 hSocketMax = max(hSocketMax, pnode->hSocket);
0864 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
0865 if (!pnode->vSend.empty())
0866 FD_SET(pnode->hSocket, &fdsetSend);
0867 }
0868 }
0869
0870 vnThreadsRunning[0]--;
0871 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
0872 vnThreadsRunning[0]++;
0873 if (fShutdown)
0874 return;
0875 if (nSelect == SOCKET_ERROR)
0876 {
0877 int nErr = WSAGetLastError();
0878 if (hSocketMax > -1)
0879 {
0880 printf("socket select error %d\n", nErr);
0881 for (int i = 0; i <= hSocketMax; i++)
0882 FD_SET(i, &fdsetRecv);
0883 }
0884 FD_ZERO(&fdsetSend);
0885 FD_ZERO(&fdsetError);
0886 Sleep(timeout.tv_usec/1000);
0887 }
0888
0889
0890
0891
0892
0893 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
0894 {
0895 struct sockaddr_in sockaddr;
0896 socklen_t len = sizeof(sockaddr);
0897 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
0898 CAddress addr;
0899 int nInbound = 0;
0900
0901 if (hSocket != INVALID_SOCKET)
0902 addr = CAddress(sockaddr);
0903
0904 CRITICAL_BLOCK(cs_vNodes)
0905 BOOST_FOREACH(CNode* pnode, vNodes)
0906 if (pnode->fInbound)
0907 nInbound++;
0908
0909 if (hSocket == INVALID_SOCKET)
0910 {
0911 if (WSAGetLastError() != WSAEWOULDBLOCK)
0912 printf("socket error accept failed: %d\n", WSAGetLastError());
0913 }
0914 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
0915 {
0916 closesocket(hSocket);
0917 }
0918 else if (CNode::IsBanned(addr.ip))
0919 {
0920 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
0921 closesocket(hSocket);
0922 }
0923 else
0924 {
0925 printf("accepted connection %s\n", addr.ToString().c_str());
0926 CNode* pnode = new CNode(hSocket, addr, true);
0927 pnode->AddRef();
0928 CRITICAL_BLOCK(cs_vNodes)
0929 vNodes.push_back(pnode);
0930 }
0931 }
0932
0933
0934
0935
0936
0937 vector<CNode*> vNodesCopy;
0938 CRITICAL_BLOCK(cs_vNodes)
0939 {
0940 vNodesCopy = vNodes;
0941 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0942 pnode->AddRef();
0943 }
0944 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0945 {
0946 if (fShutdown)
0947 return;
0948
0949
0950
0951
0952 if (pnode->hSocket == INVALID_SOCKET)
0953 continue;
0954 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
0955 {
0956 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
0957 {
0958 CDataStream& vRecv = pnode->vRecv;
0959 unsigned int nPos = vRecv.size();
0960
0961 if (nPos > ReceiveBufferSize()) {
0962 if (!pnode->fDisconnect)
0963 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
0964 pnode->CloseSocketDisconnect();
0965 }
0966 else {
0967
0968 char pchBuf[0x10000];
0969 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
0970 if (nBytes > 0)
0971 {
0972 vRecv.resize(nPos + nBytes);
0973 memcpy(&vRecv[nPos], pchBuf, nBytes);
0974 pnode->nLastRecv = GetTime();
0975 }
0976 else if (nBytes == 0)
0977 {
0978
0979 if (!pnode->fDisconnect)
0980 printf("socket closed\n");
0981 pnode->CloseSocketDisconnect();
0982 }
0983 else if (nBytes < 0)
0984 {
0985
0986 int nErr = WSAGetLastError();
0987 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
0988 {
0989 if (!pnode->fDisconnect)
0990 printf("socket recv error %d\n", nErr);
0991 pnode->CloseSocketDisconnect();
0992 }
0993 }
0994 }
0995 }
0996 }
0997
0998
0999
1000
1001 if (pnode->hSocket == INVALID_SOCKET)
1002 continue;
1003 if (FD_ISSET(pnode->hSocket, &fdsetSend))
1004 {
1005 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1006 {
1007 CDataStream& vSend = pnode->vSend;
1008 if (!vSend.empty())
1009 {
1010 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
1011 if (nBytes > 0)
1012 {
1013 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1014 pnode->nLastSend = GetTime();
1015 }
1016 else if (nBytes < 0)
1017 {
1018
1019 int nErr = WSAGetLastError();
1020 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1021 {
1022 printf("socket send error %d\n", nErr);
1023 pnode->CloseSocketDisconnect();
1024 }
1025 }
1026 if (vSend.size() > SendBufferSize()) {
1027 if (!pnode->fDisconnect)
1028 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1029 pnode->CloseSocketDisconnect();
1030 }
1031 }
1032 }
1033 }
1034
1035
1036
1037
1038 if (pnode->vSend.empty())
1039 pnode->nLastSendEmpty = GetTime();
1040 if (GetTime() - pnode->nTimeConnected > 60)
1041 {
1042 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1043 {
1044 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1045 pnode->fDisconnect = true;
1046 }
1047 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1048 {
1049 printf("socket not sending\n");
1050 pnode->fDisconnect = true;
1051 }
1052 else if (GetTime() - pnode->nLastRecv > 90*60)
1053 {
1054 printf("socket inactivity timeout\n");
1055 pnode->fDisconnect = true;
1056 }
1057 }
1058 }
1059 CRITICAL_BLOCK(cs_vNodes)
1060 {
1061 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1062 pnode->Release();
1063 }
1064
1065 Sleep(10);
1066 }
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 static const char *strDNSSeed[] = {
1088 "bitseed.xf2.org",
1089 "dnsseed.bluematt.me",
1090 "seed.bitcoin.sipa.be",
1091 "dnsseed.bitcoin.dashjr.org",
1092 };
1093
1094 void ThreadDNSAddressSeed(void* parg)
1095 {
1096 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1097 try
1098 {
1099 vnThreadsRunning[6]++;
1100 ThreadDNSAddressSeed2(parg);
1101 vnThreadsRunning[6]--;
1102 }
1103 catch (std::exception& e) {
1104 vnThreadsRunning[6]--;
1105 PrintException(&e, "ThreadDNSAddressSeed()");
1106 } catch (...) {
1107 vnThreadsRunning[6]--;
1108 throw;
1109 }
1110 printf("ThreadDNSAddressSeed exiting\n");
1111 }
1112
1113 void ThreadDNSAddressSeed2(void* parg)
1114 {
1115 printf("ThreadDNSAddressSeed started\n");
1116 int found = 0;
1117
1118 if (!fTestNet)
1119 {
1120 printf("Loading addresses from DNS seeds (could take a while)\n");
1121
1122 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1123 vector<CAddress> vaddr;
1124 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1125 {
1126 CAddrDB addrDB;
1127 addrDB.TxnBegin();
1128 BOOST_FOREACH (CAddress& addr, vaddr)
1129 {
1130 if (addr.GetByte(3) != 127)
1131 {
1132 addr.nTime = 0;
1133 AddAddress(addr, 0, &addrDB);
1134 found++;
1135 }
1136 }
1137 addrDB.TxnCommit();
1138 }
1139 }
1140 }
1141
1142 printf("%d addresses found from DNS seeds\n", found);
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 unsigned int pnSeed[] =
1157 {
1158 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1159 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1160 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1161 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1162 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1163 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1164 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1165 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1166 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1167 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1168 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1169 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1170 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1171 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1172 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1173 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1174 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1175 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1176 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1177 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1178 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1179 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1180 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1181 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1182 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1183 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1184 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1185 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1186 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1187 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1188 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1189 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1190 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1191 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1192 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1193 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1194 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1195 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1196 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1197 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1198 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1199 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1200 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1201 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1202 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1203 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1204 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1205 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1206 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1207 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1208 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1209 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1210 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1211 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1212 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1213 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1214 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1215 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1216 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1217 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1218 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1219 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1220 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1221 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1222 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1223 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1224 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1225 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1226 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1227 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1228 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1229 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1230 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1231 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1232 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1233 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1234 0xc461d84a, 0xb2dbe247,
1235 };
1236
1237
1238
1239 void ThreadOpenConnections(void* parg)
1240 {
1241 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1242 try
1243 {
1244 vnThreadsRunning[1]++;
1245 ThreadOpenConnections2(parg);
1246 vnThreadsRunning[1]--;
1247 }
1248 catch (std::exception& e) {
1249 vnThreadsRunning[1]--;
1250 PrintException(&e, "ThreadOpenConnections()");
1251 } catch (...) {
1252 vnThreadsRunning[1]--;
1253 PrintException(NULL, "ThreadOpenConnections()");
1254 }
1255 printf("ThreadOpenConnections exiting\n");
1256 }
1257
1258 void ThreadOpenConnections2(void* parg)
1259 {
1260 printf("ThreadOpenConnections started\n");
1261
1262
1263 if (mapArgs.count("-connect"))
1264 {
1265 for (int64 nLoop = 0;; nLoop++)
1266 {
1267 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1268 {
1269 CAddress addr(strAddr, fAllowDNS);
1270 if (addr.IsValid())
1271 OpenNetworkConnection(addr);
1272 for (int i = 0; i < 10 && i < nLoop; i++)
1273 {
1274 Sleep(500);
1275 if (fShutdown)
1276 return;
1277 }
1278 }
1279 }
1280 }
1281
1282
1283 if (mapArgs.count("-addnode"))
1284 {
1285 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1286 {
1287 CAddress addr(strAddr, fAllowDNS);
1288 if (addr.IsValid())
1289 {
1290 OpenNetworkConnection(addr);
1291 Sleep(500);
1292 if (fShutdown)
1293 return;
1294 }
1295 }
1296 }
1297
1298
1299 int64 nStart = GetTime();
1300 loop
1301 {
1302 vnThreadsRunning[1]--;
1303 Sleep(500);
1304 vnThreadsRunning[1]++;
1305 if (fShutdown)
1306 return;
1307
1308
1309 loop
1310 {
1311 int nOutbound = 0;
1312 CRITICAL_BLOCK(cs_vNodes)
1313 BOOST_FOREACH(CNode* pnode, vNodes)
1314 if (!pnode->fInbound)
1315 nOutbound++;
1316 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1317 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1318 if (nOutbound < nMaxOutboundConnections)
1319 break;
1320 vnThreadsRunning[1]--;
1321 Sleep(2000);
1322 vnThreadsRunning[1]++;
1323 if (fShutdown)
1324 return;
1325 }
1326
1327 bool fAddSeeds = false;
1328
1329 CRITICAL_BLOCK(cs_mapAddresses)
1330 {
1331
1332 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1333 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
1334 fAddSeeds = true;
1335 }
1336
1337 if (fAddSeeds)
1338 {
1339 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1340 {
1341
1342
1343
1344
1345 const int64 nOneWeek = 7*24*60*60;
1346 CAddress addr;
1347 addr.ip = pnSeed[i];
1348 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1349 AddAddress(addr);
1350 }
1351 }
1352
1353
1354
1355
1356 CAddress addrConnect;
1357 int64 nBest = INT64_MIN;
1358
1359
1360
1361 set<unsigned int> setConnected;
1362 CRITICAL_BLOCK(cs_vNodes)
1363 BOOST_FOREACH(CNode* pnode, vNodes)
1364 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1365
1366 int64 nANow = GetAdjustedTime();
1367
1368 CRITICAL_BLOCK(cs_mapAddresses)
1369 {
1370 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1371 {
1372 const CAddress& addr = item.second;
1373 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1374 continue;
1375 int64 nSinceLastSeen = nANow - addr.nTime;
1376 int64 nSinceLastTry = nANow - addr.nLastTry;
1377
1378
1379 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1380 if (addr.port != htons(GetDefaultPort()))
1381 nRandomizer += 2 * 60 * 60;
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1394
1395
1396 if (nSinceLastSeen < 60 * 60)
1397 nDelay = 10 * 60;
1398
1399
1400 if (nSinceLastTry < nDelay)
1401 continue;
1402
1403
1404
1405 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1406 continue;
1407
1408
1409 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1410 continue;
1411
1412
1413
1414 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1415 if (nScore > nBest)
1416 {
1417 nBest = nScore;
1418 addrConnect = addr;
1419 }
1420 }
1421 }
1422
1423 if (addrConnect.IsValid())
1424 OpenNetworkConnection(addrConnect);
1425 }
1426 }
1427
1428 bool OpenNetworkConnection(const CAddress& addrConnect)
1429 {
1430
1431
1432
1433 if (fShutdown)
1434 return false;
1435 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1436 FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1437 return false;
1438
1439 vnThreadsRunning[1]--;
1440 CNode* pnode = ConnectNode(addrConnect);
1441 vnThreadsRunning[1]++;
1442 if (fShutdown)
1443 return false;
1444 if (!pnode)
1445 return false;
1446 pnode->fNetworkNode = true;
1447
1448 return true;
1449 }
1450
1451
1452
1453
1454
1455
1456
1457
1458 void ThreadMessageHandler(void* parg)
1459 {
1460 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1461 try
1462 {
1463 vnThreadsRunning[2]++;
1464 ThreadMessageHandler2(parg);
1465 vnThreadsRunning[2]--;
1466 }
1467 catch (std::exception& e) {
1468 vnThreadsRunning[2]--;
1469 PrintException(&e, "ThreadMessageHandler()");
1470 } catch (...) {
1471 vnThreadsRunning[2]--;
1472 PrintException(NULL, "ThreadMessageHandler()");
1473 }
1474 printf("ThreadMessageHandler exiting\n");
1475 }
1476
1477 void ThreadMessageHandler2(void* parg)
1478 {
1479 printf("ThreadMessageHandler started\n");
1480 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1481 while (!fShutdown)
1482 {
1483 vector<CNode*> vNodesCopy;
1484 CRITICAL_BLOCK(cs_vNodes)
1485 {
1486 vNodesCopy = vNodes;
1487 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1488 pnode->AddRef();
1489 }
1490
1491
1492 CNode* pnodeTrickle = NULL;
1493 if (!vNodesCopy.empty())
1494 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1495 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1496 {
1497
1498 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1499 ProcessMessages(pnode);
1500 if (fShutdown)
1501 return;
1502
1503
1504 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1505 SendMessages(pnode, pnode == pnodeTrickle);
1506 if (fShutdown)
1507 return;
1508 }
1509
1510 CRITICAL_BLOCK(cs_vNodes)
1511 {
1512 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1513 pnode->Release();
1514 }
1515
1516
1517
1518
1519 vnThreadsRunning[2]--;
1520 Sleep(100);
1521 if (fRequestShutdown)
1522 Shutdown(NULL);
1523 vnThreadsRunning[2]++;
1524 if (fShutdown)
1525 return;
1526 }
1527 }
1528
1529
1530
1531
1532
1533
1534 bool BindListenPort(string& strError)
1535 {
1536 strError = "";
1537 int nOne = 1;
1538 addrLocalHost.port = htons(GetListenPort());
1539
1540
1541 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1542 if (hListenSocket == INVALID_SOCKET)
1543 {
1544 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1545 printf("%s\n", strError.c_str());
1546 return false;
1547 }
1548
1549 #ifdef SO_NOSIGPIPE
1550
1551 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1552 #endif
1553
1554
1555
1556 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1557
1558 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1559 {
1560 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1561 printf("%s\n", strError.c_str());
1562 return false;
1563 }
1564
1565
1566
1567 struct sockaddr_in sockaddr;
1568 memset(&sockaddr, 0, sizeof(sockaddr));
1569 sockaddr.sin_family = AF_INET;
1570 sockaddr.sin_addr.s_addr = INADDR_ANY;
1571 sockaddr.sin_port = htons(GetListenPort());
1572 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1573 {
1574 int nErr = WSAGetLastError();
1575 if (nErr == WSAEADDRINUSE)
1576 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1577 else
1578 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1579 printf("%s\n", strError.c_str());
1580 return false;
1581 }
1582 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1583
1584
1585 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1586 {
1587 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1588 printf("%s\n", strError.c_str());
1589 return false;
1590 }
1591
1592 return true;
1593 }
1594
1595 void StartNode(void* parg)
1596 {
1597 if (pnodeLocalHost == NULL)
1598 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1599
1600
1601 struct ifaddrs* myaddrs;
1602 if (getifaddrs(&myaddrs) == 0)
1603 {
1604 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1605 {
1606 if (ifa->ifa_addr == NULL) continue;
1607 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1608 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1609 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1610 char pszIP[100];
1611 if (ifa->ifa_addr->sa_family == AF_INET)
1612 {
1613 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1614 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1615 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1616
1617
1618 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1619 if (addr.IsValid() && addr.GetByte(3) != 127)
1620 {
1621 addrLocalHost = addr;
1622 break;
1623 }
1624 }
1625 else if (ifa->ifa_addr->sa_family == AF_INET6)
1626 {
1627 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1628 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1629 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1630 }
1631 }
1632 freeifaddrs(myaddrs);
1633 }
1634
1635 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1636
1637 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1638 {
1639
1640 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1641 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1642 }
1643 else
1644 {
1645 CreateThread(ThreadGetMyExternalIP, NULL);
1646 }
1647
1648
1649
1650
1651
1652 if (GetBoolArg("-nodnsseed"))
1653 printf("DNS seeding disabled\n");
1654 else
1655 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1656 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1657
1658
1659 if (!CreateThread(ThreadIRCSeed, NULL))
1660 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1661
1662
1663 if (!CreateThread(ThreadSocketHandler, NULL))
1664 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1665
1666
1667 if (!CreateThread(ThreadOpenConnections, NULL))
1668 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1669
1670
1671 if (!CreateThread(ThreadMessageHandler, NULL))
1672 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1673
1674
1675 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1676 }
1677
1678 bool StopNode()
1679 {
1680 printf("StopNode()\n");
1681 fShutdown = true;
1682 nTransactionsUpdated++;
1683 int64 nStart = GetTime();
1684 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1685 )
1686 {
1687 if (GetTime() - nStart > 20)
1688 break;
1689 Sleep(20);
1690 }
1691 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1692 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1693 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1694 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1695 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1696 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1697 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1698 Sleep(20);
1699 Sleep(50);
1700
1701 return true;
1702 }
1703
1704 class CNetCleanup
1705 {
1706 public:
1707 CNetCleanup()
1708 {
1709 }
1710 ~CNetCleanup()
1711 {
1712
1713 BOOST_FOREACH(CNode* pnode, vNodes)
1714 if (pnode->hSocket != INVALID_SOCKET)
1715 closesocket(pnode->hSocket);
1716 if (hListenSocket != INVALID_SOCKET)
1717 if (closesocket(hListenSocket) == SOCKET_ERROR)
1718 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1719
1720 }
1721 }
1722 instance_of_cnetcleanup;