-
+ B72B573BA77B095E2497E297BA5B02AA68317F67438EE070FEE86E129A95B85DC9B5CA98E96441BB2B3B98263DD88630990C913AFFBABF890641F349D1C6DA47
bitcoin/src/net.cpp
(0 . 0)(1 . 1951)
14406 // Copyright (c) 2009-2010 Satoshi Nakamoto
14407 // Copyright (c) 2009-2012 The Bitcoin developers
14408 // Distributed under the MIT/X11 software license, see the accompanying
14409 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
14410
14411 #include "headers.h"
14412 #include "irc.h"
14413 #include "db.h"
14414 #include "net.h"
14415 #include "init.h"
14416 #include "strlcpy.h"
14417
14418 #ifdef WIN32
14419 #include <string.h>
14420 #endif
14421
14422 #ifdef USE_UPNP
14423 #include <miniupnpc/miniwget.h>
14424 #include <miniupnpc/miniupnpc.h>
14425 #include <miniupnpc/upnpcommands.h>
14426 #include <miniupnpc/upnperrors.h>
14427 #endif
14428
14429 using namespace std;
14430 using namespace boost;
14431
14432 static const int MAX_OUTBOUND_CONNECTIONS = 8;
14433
14434 void ThreadMessageHandler2(void* parg);
14435 void ThreadSocketHandler2(void* parg);
14436 void ThreadOpenConnections2(void* parg);
14437 #ifdef USE_UPNP
14438 void ThreadMapPort2(void* parg);
14439 #endif
14440 void ThreadDNSAddressSeed2(void* parg);
14441 bool OpenNetworkConnection(const CAddress& addrConnect);
14442
14443
14444
14445
14446
14447 //
14448 // Global state variables
14449 //
14450 bool fClient = false;
14451 bool fAllowDNS = false;
14452 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
14453 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
14454 static CNode* pnodeLocalHost = NULL;
14455 uint64 nLocalHostNonce = 0;
14456 array<int, 10> vnThreadsRunning;
14457 static SOCKET hListenSocket = INVALID_SOCKET;
14458
14459 vector<CNode*> vNodes;
14460 CCriticalSection cs_vNodes;
14461 map<vector<unsigned char>, CAddress> mapAddresses;
14462 CCriticalSection cs_mapAddresses;
14463 map<CInv, CDataStream> mapRelay;
14464 deque<pair<int64, CInv> > vRelayExpiration;
14465 CCriticalSection cs_mapRelay;
14466 map<CInv, int64> mapAlreadyAskedFor;
14467
14468 // Settings
14469 int fUseProxy = false;
14470 int nConnectTimeout = 5000;
14471 CAddress addrProxy("127.0.0.1",9050);
14472
14473
14474
14475
14476 unsigned short GetListenPort()
14477 {
14478 return (unsigned short)(GetArg("-port", GetDefaultPort()));
14479 }
14480
14481 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
14482 {
14483 // Filter out duplicate requests
14484 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
14485 return;
14486 pindexLastGetBlocksBegin = pindexBegin;
14487 hashLastGetBlocksEnd = hashEnd;
14488
14489 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
14490 }
14491
14492
14493
14494
14495
14496 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
14497 {
14498 hSocketRet = INVALID_SOCKET;
14499
14500 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
14501 if (hSocket == INVALID_SOCKET)
14502 return false;
14503 #ifdef SO_NOSIGPIPE
14504 int set = 1;
14505 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
14506 #endif
14507
14508 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
14509 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
14510
14511 #ifdef WIN32
14512 u_long fNonblock = 1;
14513 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
14514 #else
14515 int fFlags = fcntl(hSocket, F_GETFL, 0);
14516 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
14517 #endif
14518 {
14519 closesocket(hSocket);
14520 return false;
14521 }
14522
14523
14524 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
14525 {
14526 // WSAEINVAL is here because some legacy version of winsock uses it
14527 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
14528 {
14529 struct timeval timeout;
14530 timeout.tv_sec = nTimeout / 1000;
14531 timeout.tv_usec = (nTimeout % 1000) * 1000;
14532
14533 fd_set fdset;
14534 FD_ZERO(&fdset);
14535 FD_SET(hSocket, &fdset);
14536 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
14537 if (nRet == 0)
14538 {
14539 printf("connection timeout\n");
14540 closesocket(hSocket);
14541 return false;
14542 }
14543 if (nRet == SOCKET_ERROR)
14544 {
14545 printf("select() for connection failed: %i\n",WSAGetLastError());
14546 closesocket(hSocket);
14547 return false;
14548 }
14549 socklen_t nRetSize = sizeof(nRet);
14550 #ifdef WIN32
14551 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
14552 #else
14553 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
14554 #endif
14555 {
14556 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
14557 closesocket(hSocket);
14558 return false;
14559 }
14560 if (nRet != 0)
14561 {
14562 printf("connect() failed after select(): %s\n",strerror(nRet));
14563 closesocket(hSocket);
14564 return false;
14565 }
14566 }
14567 #ifdef WIN32
14568 else if (WSAGetLastError() != WSAEISCONN)
14569 #else
14570 else
14571 #endif
14572 {
14573 printf("connect() failed: %i\n",WSAGetLastError());
14574 closesocket(hSocket);
14575 return false;
14576 }
14577 }
14578
14579 /*
14580 this isn't even strictly necessary
14581 CNode::ConnectNode immediately turns the socket back to non-blocking
14582 but we'll turn it back to blocking just in case
14583 */
14584 #ifdef WIN32
14585 fNonblock = 0;
14586 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
14587 #else
14588 fFlags = fcntl(hSocket, F_GETFL, 0);
14589 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
14590 #endif
14591 {
14592 closesocket(hSocket);
14593 return false;
14594 }
14595
14596 if (fProxy)
14597 {
14598 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
14599 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
14600 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
14601 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
14602 char* pszSocks4 = pszSocks4IP;
14603 int nSize = sizeof(pszSocks4IP);
14604
14605 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
14606 if (ret != nSize)
14607 {
14608 closesocket(hSocket);
14609 return error("Error sending to proxy");
14610 }
14611 char pchRet[8];
14612 if (recv(hSocket, pchRet, 8, 0) != 8)
14613 {
14614 closesocket(hSocket);
14615 return error("Error reading proxy response");
14616 }
14617 if (pchRet[1] != 0x5a)
14618 {
14619 closesocket(hSocket);
14620 if (pchRet[1] != 0x5b)
14621 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
14622 return false;
14623 }
14624 printf("proxy connected %s\n", addrConnect.ToString().c_str());
14625 }
14626
14627 hSocketRet = hSocket;
14628 return true;
14629 }
14630
14631 // portDefault is in host order
14632 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
14633 {
14634 vaddr.clear();
14635 if (pszName[0] == 0)
14636 return false;
14637 int port = portDefault;
14638 char psz[256];
14639 char *pszHost = psz;
14640 strlcpy(psz, pszName, sizeof(psz));
14641 if (fAllowPort)
14642 {
14643 char* pszColon = strrchr(psz+1,':');
14644 char *pszPortEnd = NULL;
14645 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
14646 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
14647 {
14648 if (psz[0] == '[' && pszColon[-1] == ']')
14649 {
14650 // Future: enable IPv6 colon-notation inside []
14651 pszHost = psz+1;
14652 pszColon[-1] = 0;
14653 }
14654 else
14655 pszColon[0] = 0;
14656 port = portParsed;
14657 if (port < 0 || port > USHRT_MAX)
14658 port = USHRT_MAX;
14659 }
14660 }
14661
14662 unsigned int addrIP = inet_addr(pszHost);
14663 if (addrIP != INADDR_NONE)
14664 {
14665 // valid IP address passed
14666 vaddr.push_back(CAddress(addrIP, port, nServices));
14667 return true;
14668 }
14669
14670 if (!fAllowLookup)
14671 return false;
14672
14673 struct hostent* phostent = gethostbyname(pszHost);
14674 if (!phostent)
14675 return false;
14676
14677 if (phostent->h_addrtype != AF_INET)
14678 return false;
14679
14680 char** ppAddr = phostent->h_addr_list;
14681 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
14682 {
14683 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
14684 if (addr.IsValid())
14685 vaddr.push_back(addr);
14686 ppAddr++;
14687 }
14688
14689 return (vaddr.size() > 0);
14690 }
14691
14692 // portDefault is in host order
14693 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
14694 {
14695 vector<CAddress> vaddr;
14696 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
14697 if (fRet)
14698 addr = vaddr[0];
14699 return fRet;
14700 }
14701
14702 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
14703 {
14704 SOCKET hSocket;
14705 if (!ConnectSocket(addrConnect, hSocket))
14706 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
14707
14708 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
14709
14710 string strLine;
14711 while (RecvLine(hSocket, strLine))
14712 {
14713 if (strLine.empty()) // HTTP response is separated from headers by blank line
14714 {
14715 loop
14716 {
14717 if (!RecvLine(hSocket, strLine))
14718 {
14719 closesocket(hSocket);
14720 return false;
14721 }
14722 if (pszKeyword == NULL)
14723 break;
14724 if (strLine.find(pszKeyword) != -1)
14725 {
14726 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
14727 break;
14728 }
14729 }
14730 closesocket(hSocket);
14731 if (strLine.find("<") != -1)
14732 strLine = strLine.substr(0, strLine.find("<"));
14733 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
14734 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
14735 strLine.resize(strLine.size()-1);
14736 CAddress addr(strLine,0,true);
14737 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
14738 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
14739 return false;
14740 ipRet = addr.ip;
14741 return true;
14742 }
14743 }
14744 closesocket(hSocket);
14745 return error("GetMyExternalIP() : connection closed");
14746 }
14747
14748 // We now get our external IP from the IRC server first and only use this as a backup
14749 bool GetMyExternalIP(unsigned int& ipRet)
14750 {
14751 CAddress addrConnect;
14752 const char* pszGet;
14753 const char* pszKeyword;
14754
14755 if (fUseProxy)
14756 return false;
14757
14758 for (int nLookup = 0; nLookup <= 1; nLookup++)
14759 for (int nHost = 1; nHost <= 2; nHost++)
14760 {
14761 // We should be phasing out our use of sites like these. If we need
14762 // replacements, we should ask for volunteers to put this simple
14763 // php file on their webserver that prints the client IP:
14764 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
14765 if (nHost == 1)
14766 {
14767 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
14768
14769 if (nLookup == 1)
14770 {
14771 CAddress addrIP("checkip.dyndns.org", 80, true);
14772 if (addrIP.IsValid())
14773 addrConnect = addrIP;
14774 }
14775
14776 pszGet = "GET / HTTP/1.1\r\n"
14777 "Host: checkip.dyndns.org\r\n"
14778 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
14779 "Connection: close\r\n"
14780 "\r\n";
14781
14782 pszKeyword = "Address:";
14783 }
14784 else if (nHost == 2)
14785 {
14786 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
14787
14788 if (nLookup == 1)
14789 {
14790 CAddress addrIP("www.showmyip.com", 80, true);
14791 if (addrIP.IsValid())
14792 addrConnect = addrIP;
14793 }
14794
14795 pszGet = "GET /simple/ HTTP/1.1\r\n"
14796 "Host: www.showmyip.com\r\n"
14797 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
14798 "Connection: close\r\n"
14799 "\r\n";
14800
14801 pszKeyword = NULL; // Returns just IP address
14802 }
14803
14804 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
14805 return true;
14806 }
14807
14808 return false;
14809 }
14810
14811 void ThreadGetMyExternalIP(void* parg)
14812 {
14813 // Wait for IRC to get it first
14814 if (!GetBoolArg("-noirc"))
14815 {
14816 for (int i = 0; i < 2 * 60; i++)
14817 {
14818 Sleep(1000);
14819 if (fGotExternalIP || fShutdown)
14820 return;
14821 }
14822 }
14823
14824 // Fallback in case IRC fails to get it
14825 if (GetMyExternalIP(addrLocalHost.ip))
14826 {
14827 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
14828 if (addrLocalHost.IsRoutable())
14829 {
14830 // If we already connected to a few before we had our IP, go back and addr them.
14831 // setAddrKnown automatically filters any duplicate sends.
14832 CAddress addr(addrLocalHost);
14833 addr.nTime = GetAdjustedTime();
14834 CRITICAL_BLOCK(cs_vNodes)
14835 BOOST_FOREACH(CNode* pnode, vNodes)
14836 pnode->PushAddress(addr);
14837 }
14838 }
14839 }
14840
14841
14842
14843
14844
14845 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
14846 {
14847 if (!addr.IsRoutable())
14848 return false;
14849 if (addr.ip == addrLocalHost.ip)
14850 return false;
14851 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
14852 bool fUpdated = false;
14853 bool fNew = false;
14854 CAddress addrFound = addr;
14855
14856 CRITICAL_BLOCK(cs_mapAddresses)
14857 {
14858 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
14859 if (it == mapAddresses.end())
14860 {
14861 // New address
14862 printf("AddAddress(%s)\n", addr.ToString().c_str());
14863 mapAddresses.insert(make_pair(addr.GetKey(), addr));
14864 fUpdated = true;
14865 fNew = true;
14866 }
14867 else
14868 {
14869 addrFound = (*it).second;
14870 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
14871 {
14872 // Services have been added
14873 addrFound.nServices |= addr.nServices;
14874 fUpdated = true;
14875 }
14876 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
14877 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
14878 if (addrFound.nTime < addr.nTime - nUpdateInterval)
14879 {
14880 // Periodically update most recently seen time
14881 addrFound.nTime = addr.nTime;
14882 fUpdated = true;
14883 }
14884 }
14885 }
14886 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
14887 // CRITICAL_BLOCK:
14888 // Thread 1: begin db transaction (locks inside-db-mutex)
14889 // then AddAddress (locks cs_mapAddresses)
14890 // Thread 2: AddAddress (locks cs_mapAddresses)
14891 // ... then db operation hangs waiting for inside-db-mutex
14892 if (fUpdated)
14893 {
14894 if (pAddrDB)
14895 pAddrDB->WriteAddress(addrFound);
14896 else
14897 CAddrDB().WriteAddress(addrFound);
14898 }
14899 return fNew;
14900 }
14901
14902 void AddressCurrentlyConnected(const CAddress& addr)
14903 {
14904 CAddress *paddrFound = NULL;
14905
14906 CRITICAL_BLOCK(cs_mapAddresses)
14907 {
14908 // Only if it's been published already
14909 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
14910 if (it != mapAddresses.end())
14911 paddrFound = &(*it).second;
14912 }
14913
14914 if (paddrFound)
14915 {
14916 int64 nUpdateInterval = 20 * 60;
14917 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
14918 {
14919 // Periodically update most recently seen time
14920 paddrFound->nTime = GetAdjustedTime();
14921 CAddrDB addrdb;
14922 addrdb.WriteAddress(*paddrFound);
14923 }
14924 }
14925 }
14926
14927
14928
14929
14930
14931 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
14932 {
14933 // If the dialog might get closed before the reply comes back,
14934 // call this in the destructor so it doesn't get called after it's deleted.
14935 CRITICAL_BLOCK(cs_vNodes)
14936 {
14937 BOOST_FOREACH(CNode* pnode, vNodes)
14938 {
14939 CRITICAL_BLOCK(pnode->cs_mapRequests)
14940 {
14941 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
14942 {
14943 CRequestTracker& tracker = (*mi).second;
14944 if (tracker.fn == fn && tracker.param1 == param1)
14945 pnode->mapRequests.erase(mi++);
14946 else
14947 mi++;
14948 }
14949 }
14950 }
14951 }
14952 }
14953
14954
14955
14956
14957
14958
14959
14960 //
14961 // Subscription methods for the broadcast and subscription system.
14962 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
14963 //
14964 // The subscription system uses a meet-in-the-middle strategy.
14965 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
14966 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
14967 //
14968
14969 bool AnySubscribed(unsigned int nChannel)
14970 {
14971 if (pnodeLocalHost->IsSubscribed(nChannel))
14972 return true;
14973 CRITICAL_BLOCK(cs_vNodes)
14974 BOOST_FOREACH(CNode* pnode, vNodes)
14975 if (pnode->IsSubscribed(nChannel))
14976 return true;
14977 return false;
14978 }
14979
14980 bool CNode::IsSubscribed(unsigned int nChannel)
14981 {
14982 if (nChannel >= vfSubscribe.size())
14983 return false;
14984 return vfSubscribe[nChannel];
14985 }
14986
14987 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
14988 {
14989 if (nChannel >= vfSubscribe.size())
14990 return;
14991
14992 if (!AnySubscribed(nChannel))
14993 {
14994 // Relay subscribe
14995 CRITICAL_BLOCK(cs_vNodes)
14996 BOOST_FOREACH(CNode* pnode, vNodes)
14997 if (pnode != this)
14998 pnode->PushMessage("subscribe", nChannel, nHops);
14999 }
15000
15001 vfSubscribe[nChannel] = true;
15002 }
15003
15004 void CNode::CancelSubscribe(unsigned int nChannel)
15005 {
15006 if (nChannel >= vfSubscribe.size())
15007 return;
15008
15009 // Prevent from relaying cancel if wasn't subscribed
15010 if (!vfSubscribe[nChannel])
15011 return;
15012 vfSubscribe[nChannel] = false;
15013
15014 if (!AnySubscribed(nChannel))
15015 {
15016 // Relay subscription cancel
15017 CRITICAL_BLOCK(cs_vNodes)
15018 BOOST_FOREACH(CNode* pnode, vNodes)
15019 if (pnode != this)
15020 pnode->PushMessage("sub-cancel", nChannel);
15021 }
15022 }
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032 CNode* FindNode(unsigned int ip)
15033 {
15034 CRITICAL_BLOCK(cs_vNodes)
15035 {
15036 BOOST_FOREACH(CNode* pnode, vNodes)
15037 if (pnode->addr.ip == ip)
15038 return (pnode);
15039 }
15040 return NULL;
15041 }
15042
15043 CNode* FindNode(CAddress addr)
15044 {
15045 CRITICAL_BLOCK(cs_vNodes)
15046 {
15047 BOOST_FOREACH(CNode* pnode, vNodes)
15048 if (pnode->addr == addr)
15049 return (pnode);
15050 }
15051 return NULL;
15052 }
15053
15054 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
15055 {
15056 if (addrConnect.ip == addrLocalHost.ip)
15057 return NULL;
15058
15059 // Look for an existing connection
15060 CNode* pnode = FindNode(addrConnect.ip);
15061 if (pnode)
15062 {
15063 if (nTimeout != 0)
15064 pnode->AddRef(nTimeout);
15065 else
15066 pnode->AddRef();
15067 return pnode;
15068 }
15069
15070 /// debug print
15071 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
15072 addrConnect.ToString().c_str(),
15073 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
15074 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
15075
15076 CRITICAL_BLOCK(cs_mapAddresses)
15077 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
15078
15079 // Connect
15080 SOCKET hSocket;
15081 if (ConnectSocket(addrConnect, hSocket))
15082 {
15083 /// debug print
15084 printf("connected %s\n", addrConnect.ToString().c_str());
15085
15086 // Set to nonblocking
15087 #ifdef WIN32
15088 u_long nOne = 1;
15089 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
15090 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
15091 #else
15092 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
15093 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
15094 #endif
15095
15096 // Add node
15097 CNode* pnode = new CNode(hSocket, addrConnect, false);
15098 if (nTimeout != 0)
15099 pnode->AddRef(nTimeout);
15100 else
15101 pnode->AddRef();
15102 CRITICAL_BLOCK(cs_vNodes)
15103 vNodes.push_back(pnode);
15104
15105 pnode->nTimeConnected = GetTime();
15106 return pnode;
15107 }
15108 else
15109 {
15110 return NULL;
15111 }
15112 }
15113
15114 void CNode::CloseSocketDisconnect()
15115 {
15116 fDisconnect = true;
15117 if (hSocket != INVALID_SOCKET)
15118 {
15119 if (fDebug)
15120 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
15121 printf("disconnecting node %s\n", addr.ToString().c_str());
15122 closesocket(hSocket);
15123 hSocket = INVALID_SOCKET;
15124 }
15125 }
15126
15127 void CNode::Cleanup()
15128 {
15129 // All of a nodes broadcasts and subscriptions are automatically torn down
15130 // when it goes down, so a node has to stay up to keep its broadcast going.
15131
15132 // Cancel subscriptions
15133 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
15134 if (vfSubscribe[nChannel])
15135 CancelSubscribe(nChannel);
15136 }
15137
15138
15139 std::map<unsigned int, int64> CNode::setBanned;
15140 CCriticalSection CNode::cs_setBanned;
15141
15142 void CNode::ClearBanned()
15143 {
15144 setBanned.clear();
15145 }
15146
15147 bool CNode::IsBanned(unsigned int ip)
15148 {
15149 bool fResult = false;
15150 CRITICAL_BLOCK(cs_setBanned)
15151 {
15152 std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
15153 if (i != setBanned.end())
15154 {
15155 int64 t = (*i).second;
15156 if (GetTime() < t)
15157 fResult = true;
15158 }
15159 }
15160 return fResult;
15161 }
15162
15163 bool CNode::Misbehaving(int howmuch)
15164 {
15165 if (addr.IsLocal())
15166 {
15167 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
15168 return false;
15169 }
15170
15171 nMisbehavior += howmuch;
15172 if (nMisbehavior >= GetArg("-banscore", 100))
15173 {
15174 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
15175 CRITICAL_BLOCK(cs_setBanned)
15176 if (setBanned[addr.ip] < banTime)
15177 setBanned[addr.ip] = banTime;
15178 CloseSocketDisconnect();
15179 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
15180 return true;
15181 }
15182 return false;
15183 }
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196 void ThreadSocketHandler(void* parg)
15197 {
15198 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
15199 try
15200 {
15201 vnThreadsRunning[0]++;
15202 ThreadSocketHandler2(parg);
15203 vnThreadsRunning[0]--;
15204 }
15205 catch (std::exception& e) {
15206 vnThreadsRunning[0]--;
15207 PrintException(&e, "ThreadSocketHandler()");
15208 } catch (...) {
15209 vnThreadsRunning[0]--;
15210 throw; // support pthread_cancel()
15211 }
15212 printf("ThreadSocketHandler exiting\n");
15213 }
15214
15215 void ThreadSocketHandler2(void* parg)
15216 {
15217 printf("ThreadSocketHandler started\n");
15218 list<CNode*> vNodesDisconnected;
15219 int nPrevNodeCount = 0;
15220
15221 loop
15222 {
15223 //
15224 // Disconnect nodes
15225 //
15226 CRITICAL_BLOCK(cs_vNodes)
15227 {
15228 // Disconnect unused nodes
15229 vector<CNode*> vNodesCopy = vNodes;
15230 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15231 {
15232 if (pnode->fDisconnect ||
15233 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
15234 {
15235 // remove from vNodes
15236 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
15237
15238 // close socket and cleanup
15239 pnode->CloseSocketDisconnect();
15240 pnode->Cleanup();
15241
15242 // hold in disconnected pool until all refs are released
15243 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
15244 if (pnode->fNetworkNode || pnode->fInbound)
15245 pnode->Release();
15246 vNodesDisconnected.push_back(pnode);
15247 }
15248 }
15249
15250 // Delete disconnected nodes
15251 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
15252 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
15253 {
15254 // wait until threads are done using it
15255 if (pnode->GetRefCount() <= 0)
15256 {
15257 bool fDelete = false;
15258 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
15259 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
15260 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
15261 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
15262 fDelete = true;
15263 if (fDelete)
15264 {
15265 vNodesDisconnected.remove(pnode);
15266 delete pnode;
15267 }
15268 }
15269 }
15270 }
15271 if (vNodes.size() != nPrevNodeCount)
15272 {
15273 nPrevNodeCount = vNodes.size();
15274 MainFrameRepaint();
15275 }
15276
15277
15278 //
15279 // Find which sockets have data to receive
15280 //
15281 struct timeval timeout;
15282 timeout.tv_sec = 0;
15283 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
15284
15285 fd_set fdsetRecv;
15286 fd_set fdsetSend;
15287 fd_set fdsetError;
15288 FD_ZERO(&fdsetRecv);
15289 FD_ZERO(&fdsetSend);
15290 FD_ZERO(&fdsetError);
15291 SOCKET hSocketMax = 0;
15292
15293 if(hListenSocket != INVALID_SOCKET)
15294 FD_SET(hListenSocket, &fdsetRecv);
15295 hSocketMax = max(hSocketMax, hListenSocket);
15296 CRITICAL_BLOCK(cs_vNodes)
15297 {
15298 BOOST_FOREACH(CNode* pnode, vNodes)
15299 {
15300 if (pnode->hSocket == INVALID_SOCKET)
15301 continue;
15302 FD_SET(pnode->hSocket, &fdsetRecv);
15303 FD_SET(pnode->hSocket, &fdsetError);
15304 hSocketMax = max(hSocketMax, pnode->hSocket);
15305 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
15306 if (!pnode->vSend.empty())
15307 FD_SET(pnode->hSocket, &fdsetSend);
15308 }
15309 }
15310
15311 vnThreadsRunning[0]--;
15312 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
15313 vnThreadsRunning[0]++;
15314 if (fShutdown)
15315 return;
15316 if (nSelect == SOCKET_ERROR)
15317 {
15318 int nErr = WSAGetLastError();
15319 if (hSocketMax > -1)
15320 {
15321 printf("socket select error %d\n", nErr);
15322 for (int i = 0; i <= hSocketMax; i++)
15323 FD_SET(i, &fdsetRecv);
15324 }
15325 FD_ZERO(&fdsetSend);
15326 FD_ZERO(&fdsetError);
15327 Sleep(timeout.tv_usec/1000);
15328 }
15329
15330
15331 //
15332 // Accept new connections
15333 //
15334 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
15335 {
15336 struct sockaddr_in sockaddr;
15337 socklen_t len = sizeof(sockaddr);
15338 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
15339 CAddress addr;
15340 int nInbound = 0;
15341
15342 if (hSocket != INVALID_SOCKET)
15343 addr = CAddress(sockaddr);
15344
15345 CRITICAL_BLOCK(cs_vNodes)
15346 BOOST_FOREACH(CNode* pnode, vNodes)
15347 if (pnode->fInbound)
15348 nInbound++;
15349
15350 if (hSocket == INVALID_SOCKET)
15351 {
15352 if (WSAGetLastError() != WSAEWOULDBLOCK)
15353 printf("socket error accept failed: %d\n", WSAGetLastError());
15354 }
15355 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
15356 {
15357 closesocket(hSocket);
15358 }
15359 else if (CNode::IsBanned(addr.ip))
15360 {
15361 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
15362 closesocket(hSocket);
15363 }
15364 else
15365 {
15366 printf("accepted connection %s\n", addr.ToString().c_str());
15367 CNode* pnode = new CNode(hSocket, addr, true);
15368 pnode->AddRef();
15369 CRITICAL_BLOCK(cs_vNodes)
15370 vNodes.push_back(pnode);
15371 }
15372 }
15373
15374
15375 //
15376 // Service each socket
15377 //
15378 vector<CNode*> vNodesCopy;
15379 CRITICAL_BLOCK(cs_vNodes)
15380 {
15381 vNodesCopy = vNodes;
15382 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15383 pnode->AddRef();
15384 }
15385 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15386 {
15387 if (fShutdown)
15388 return;
15389
15390 //
15391 // Receive
15392 //
15393 if (pnode->hSocket == INVALID_SOCKET)
15394 continue;
15395 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
15396 {
15397 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
15398 {
15399 CDataStream& vRecv = pnode->vRecv;
15400 unsigned int nPos = vRecv.size();
15401
15402 if (nPos > ReceiveBufferSize()) {
15403 if (!pnode->fDisconnect)
15404 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
15405 pnode->CloseSocketDisconnect();
15406 }
15407 else {
15408 // typical socket buffer is 8K-64K
15409 char pchBuf[0x10000];
15410 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
15411 if (nBytes > 0)
15412 {
15413 vRecv.resize(nPos + nBytes);
15414 memcpy(&vRecv[nPos], pchBuf, nBytes);
15415 pnode->nLastRecv = GetTime();
15416 }
15417 else if (nBytes == 0)
15418 {
15419 // socket closed gracefully
15420 if (!pnode->fDisconnect)
15421 printf("socket closed\n");
15422 pnode->CloseSocketDisconnect();
15423 }
15424 else if (nBytes < 0)
15425 {
15426 // error
15427 int nErr = WSAGetLastError();
15428 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
15429 {
15430 if (!pnode->fDisconnect)
15431 printf("socket recv error %d\n", nErr);
15432 pnode->CloseSocketDisconnect();
15433 }
15434 }
15435 }
15436 }
15437 }
15438
15439 //
15440 // Send
15441 //
15442 if (pnode->hSocket == INVALID_SOCKET)
15443 continue;
15444 if (FD_ISSET(pnode->hSocket, &fdsetSend))
15445 {
15446 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
15447 {
15448 CDataStream& vSend = pnode->vSend;
15449 if (!vSend.empty())
15450 {
15451 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
15452 if (nBytes > 0)
15453 {
15454 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
15455 pnode->nLastSend = GetTime();
15456 }
15457 else if (nBytes < 0)
15458 {
15459 // error
15460 int nErr = WSAGetLastError();
15461 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
15462 {
15463 printf("socket send error %d\n", nErr);
15464 pnode->CloseSocketDisconnect();
15465 }
15466 }
15467 if (vSend.size() > SendBufferSize()) {
15468 if (!pnode->fDisconnect)
15469 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
15470 pnode->CloseSocketDisconnect();
15471 }
15472 }
15473 }
15474 }
15475
15476 //
15477 // Inactivity checking
15478 //
15479 if (pnode->vSend.empty())
15480 pnode->nLastSendEmpty = GetTime();
15481 if (GetTime() - pnode->nTimeConnected > 60)
15482 {
15483 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
15484 {
15485 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
15486 pnode->fDisconnect = true;
15487 }
15488 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
15489 {
15490 printf("socket not sending\n");
15491 pnode->fDisconnect = true;
15492 }
15493 else if (GetTime() - pnode->nLastRecv > 90*60)
15494 {
15495 printf("socket inactivity timeout\n");
15496 pnode->fDisconnect = true;
15497 }
15498 }
15499 }
15500 CRITICAL_BLOCK(cs_vNodes)
15501 {
15502 BOOST_FOREACH(CNode* pnode, vNodesCopy)
15503 pnode->Release();
15504 }
15505
15506 Sleep(10);
15507 }
15508 }
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518 #ifdef USE_UPNP
15519 void ThreadMapPort(void* parg)
15520 {
15521 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
15522 try
15523 {
15524 vnThreadsRunning[5]++;
15525 ThreadMapPort2(parg);
15526 vnThreadsRunning[5]--;
15527 }
15528 catch (std::exception& e) {
15529 vnThreadsRunning[5]--;
15530 PrintException(&e, "ThreadMapPort()");
15531 } catch (...) {
15532 vnThreadsRunning[5]--;
15533 PrintException(NULL, "ThreadMapPort()");
15534 }
15535 printf("ThreadMapPort exiting\n");
15536 }
15537
15538 void ThreadMapPort2(void* parg)
15539 {
15540 printf("ThreadMapPort started\n");
15541
15542 char port[6];
15543 sprintf(port, "%d", GetListenPort());
15544
15545 const char * multicastif = 0;
15546 const char * minissdpdpath = 0;
15547 struct UPNPDev * devlist = 0;
15548 char lanaddr[64];
15549
15550 #ifndef UPNPDISCOVER_SUCCESS
15551 /* miniupnpc 1.5 */
15552 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
15553 #else
15554 /* miniupnpc 1.6 */
15555 int error = 0;
15556 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
15557 #endif
15558
15559 struct UPNPUrls urls;
15560 struct IGDdatas data;
15561 int r;
15562
15563 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
15564 if (r == 1)
15565 {
15566 if (!addrLocalHost.IsRoutable())
15567 {
15568 char externalIPAddress[40];
15569 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
15570 if(r != UPNPCOMMAND_SUCCESS)
15571 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
15572 else
15573 {
15574 if(externalIPAddress[0])
15575 {
15576 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
15577 CAddress addrExternalFromUPnP(externalIPAddress, 0, false, nLocalServices);
15578 if (addrExternalFromUPnP.IsRoutable())
15579 addrLocalHost = addrExternalFromUPnP;
15580 }
15581 else
15582 printf("UPnP: GetExternalIPAddress failed.\n");
15583 }
15584 }
15585
15586 string strDesc = "Bitcoin " + FormatFullVersion();
15587 #ifndef UPNPDISCOVER_SUCCESS
15588 /* miniupnpc 1.5 */
15589 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15590 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
15591 #else
15592 /* miniupnpc 1.6 */
15593 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15594 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
15595 #endif
15596
15597 if(r!=UPNPCOMMAND_SUCCESS)
15598 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
15599 port, port, lanaddr, r, strupnperror(r));
15600 else
15601 printf("UPnP Port Mapping successful.\n");
15602 int i = 1;
15603 loop {
15604 if (fShutdown || !fUseUPnP)
15605 {
15606 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
15607 printf("UPNP_DeletePortMapping() returned : %d\n", r);
15608 freeUPNPDevlist(devlist); devlist = 0;
15609 FreeUPNPUrls(&urls);
15610 return;
15611 }
15612 if (i % 600 == 0) // Refresh every 20 minutes
15613 {
15614 #ifndef UPNPDISCOVER_SUCCESS
15615 /* miniupnpc 1.5 */
15616 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15617 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
15618 #else
15619 /* miniupnpc 1.6 */
15620 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15621 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
15622 #endif
15623
15624 if(r!=UPNPCOMMAND_SUCCESS)
15625 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
15626 port, port, lanaddr, r, strupnperror(r));
15627 else
15628 printf("UPnP Port Mapping successful.\n");;
15629 }
15630 Sleep(2000);
15631 i++;
15632 }
15633 } else {
15634 printf("No valid UPnP IGDs found\n");
15635 freeUPNPDevlist(devlist); devlist = 0;
15636 if (r != 0)
15637 FreeUPNPUrls(&urls);
15638 loop {
15639 if (fShutdown || !fUseUPnP)
15640 return;
15641 Sleep(2000);
15642 }
15643 }
15644 }
15645
15646 void MapPort(bool fMapPort)
15647 {
15648 if (fUseUPnP != fMapPort)
15649 {
15650 fUseUPnP = fMapPort;
15651 WriteSetting("fUseUPnP", fUseUPnP);
15652 }
15653 if (fUseUPnP && vnThreadsRunning[5] < 1)
15654 {
15655 if (!CreateThread(ThreadMapPort, NULL))
15656 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
15657 }
15658 }
15659 #else
15660 void MapPort(bool /* unused fMapPort */)
15661 {
15662 // Intentionally left blank.
15663 }
15664 #endif
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675 static const char *strDNSSeed[] = {
15676 "bitseed.xf2.org",
15677 "dnsseed.bluematt.me",
15678 "seed.bitcoin.sipa.be",
15679 "dnsseed.bitcoin.dashjr.org",
15680 };
15681
15682 void ThreadDNSAddressSeed(void* parg)
15683 {
15684 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
15685 try
15686 {
15687 vnThreadsRunning[6]++;
15688 ThreadDNSAddressSeed2(parg);
15689 vnThreadsRunning[6]--;
15690 }
15691 catch (std::exception& e) {
15692 vnThreadsRunning[6]--;
15693 PrintException(&e, "ThreadDNSAddressSeed()");
15694 } catch (...) {
15695 vnThreadsRunning[6]--;
15696 throw; // support pthread_cancel()
15697 }
15698 printf("ThreadDNSAddressSeed exiting\n");
15699 }
15700
15701 void ThreadDNSAddressSeed2(void* parg)
15702 {
15703 printf("ThreadDNSAddressSeed started\n");
15704 int found = 0;
15705
15706 if (!fTestNet)
15707 {
15708 printf("Loading addresses from DNS seeds (could take a while)\n");
15709
15710 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
15711 vector<CAddress> vaddr;
15712 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
15713 {
15714 CAddrDB addrDB;
15715 addrDB.TxnBegin();
15716 BOOST_FOREACH (CAddress& addr, vaddr)
15717 {
15718 if (addr.GetByte(3) != 127)
15719 {
15720 addr.nTime = 0;
15721 AddAddress(addr, 0, &addrDB);
15722 found++;
15723 }
15724 }
15725 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
15726 }
15727 }
15728 }
15729
15730 printf("%d addresses found from DNS seeds\n", found);
15731 }
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744 unsigned int pnSeed[] =
15745 {
15746 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
15747 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
15748 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
15749 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
15750 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
15751 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
15752 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
15753 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
15754 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
15755 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
15756 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
15757 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
15758 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
15759 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
15760 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
15761 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
15762 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
15763 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
15764 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
15765 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
15766 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
15767 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
15768 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
15769 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
15770 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
15771 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
15772 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
15773 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
15774 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
15775 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
15776 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
15777 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
15778 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
15779 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
15780 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
15781 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
15782 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
15783 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
15784 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
15785 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
15786 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
15787 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
15788 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
15789 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
15790 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
15791 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
15792 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
15793 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
15794 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
15795 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
15796 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
15797 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
15798 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
15799 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
15800 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
15801 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
15802 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
15803 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
15804 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
15805 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
15806 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
15807 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
15808 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
15809 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
15810 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
15811 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
15812 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
15813 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
15814 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
15815 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
15816 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
15817 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
15818 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
15819 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
15820 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
15821 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
15822 0xc461d84a, 0xb2dbe247,
15823 };
15824
15825
15826
15827 void ThreadOpenConnections(void* parg)
15828 {
15829 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
15830 try
15831 {
15832 vnThreadsRunning[1]++;
15833 ThreadOpenConnections2(parg);
15834 vnThreadsRunning[1]--;
15835 }
15836 catch (std::exception& e) {
15837 vnThreadsRunning[1]--;
15838 PrintException(&e, "ThreadOpenConnections()");
15839 } catch (...) {
15840 vnThreadsRunning[1]--;
15841 PrintException(NULL, "ThreadOpenConnections()");
15842 }
15843 printf("ThreadOpenConnections exiting\n");
15844 }
15845
15846 void ThreadOpenConnections2(void* parg)
15847 {
15848 printf("ThreadOpenConnections started\n");
15849
15850 // Connect to specific addresses
15851 if (mapArgs.count("-connect"))
15852 {
15853 for (int64 nLoop = 0;; nLoop++)
15854 {
15855 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
15856 {
15857 CAddress addr(strAddr, fAllowDNS);
15858 if (addr.IsValid())
15859 OpenNetworkConnection(addr);
15860 for (int i = 0; i < 10 && i < nLoop; i++)
15861 {
15862 Sleep(500);
15863 if (fShutdown)
15864 return;
15865 }
15866 }
15867 }
15868 }
15869
15870 // Connect to manually added nodes first
15871 if (mapArgs.count("-addnode"))
15872 {
15873 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
15874 {
15875 CAddress addr(strAddr, fAllowDNS);
15876 if (addr.IsValid())
15877 {
15878 OpenNetworkConnection(addr);
15879 Sleep(500);
15880 if (fShutdown)
15881 return;
15882 }
15883 }
15884 }
15885
15886 // Initiate network connections
15887 int64 nStart = GetTime();
15888 loop
15889 {
15890 vnThreadsRunning[1]--;
15891 Sleep(500);
15892 vnThreadsRunning[1]++;
15893 if (fShutdown)
15894 return;
15895
15896 // Limit outbound connections
15897 loop
15898 {
15899 int nOutbound = 0;
15900 CRITICAL_BLOCK(cs_vNodes)
15901 BOOST_FOREACH(CNode* pnode, vNodes)
15902 if (!pnode->fInbound)
15903 nOutbound++;
15904 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
15905 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
15906 if (nOutbound < nMaxOutboundConnections)
15907 break;
15908 vnThreadsRunning[1]--;
15909 Sleep(2000);
15910 vnThreadsRunning[1]++;
15911 if (fShutdown)
15912 return;
15913 }
15914
15915 bool fAddSeeds = false;
15916
15917 CRITICAL_BLOCK(cs_mapAddresses)
15918 {
15919 // Add seed nodes if IRC isn't working
15920 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
15921 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
15922 fAddSeeds = true;
15923 }
15924
15925 if (fAddSeeds)
15926 {
15927 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
15928 {
15929 // It'll only connect to one or two seed nodes because once it connects,
15930 // it'll get a pile of addresses with newer timestamps.
15931 // Seed nodes are given a random 'last seen time' of between one and two
15932 // weeks ago.
15933 const int64 nOneWeek = 7*24*60*60;
15934 CAddress addr;
15935 addr.ip = pnSeed[i];
15936 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
15937 AddAddress(addr);
15938 }
15939 }
15940
15941 //
15942 // Choose an address to connect to based on most recently seen
15943 //
15944 CAddress addrConnect;
15945 int64 nBest = INT64_MIN;
15946
15947 // Only connect to one address per a.b.?.? range.
15948 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
15949 set<unsigned int> setConnected;
15950 CRITICAL_BLOCK(cs_vNodes)
15951 BOOST_FOREACH(CNode* pnode, vNodes)
15952 setConnected.insert(pnode->addr.ip & 0x0000ffff);
15953
15954 int64 nANow = GetAdjustedTime();
15955
15956 CRITICAL_BLOCK(cs_mapAddresses)
15957 {
15958 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
15959 {
15960 const CAddress& addr = item.second;
15961 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
15962 continue;
15963 int64 nSinceLastSeen = nANow - addr.nTime;
15964 int64 nSinceLastTry = nANow - addr.nLastTry;
15965
15966 // Randomize the order in a deterministic way, putting the standard port first
15967 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
15968 if (addr.port != htons(GetDefaultPort()))
15969 nRandomizer += 2 * 60 * 60;
15970
15971 // Last seen Base retry frequency
15972 // <1 hour 10 min
15973 // 1 hour 1 hour
15974 // 4 hours 2 hours
15975 // 24 hours 5 hours
15976 // 48 hours 7 hours
15977 // 7 days 13 hours
15978 // 30 days 27 hours
15979 // 90 days 46 hours
15980 // 365 days 93 hours
15981 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
15982
15983 // Fast reconnect for one hour after last seen
15984 if (nSinceLastSeen < 60 * 60)
15985 nDelay = 10 * 60;
15986
15987 // Limit retry frequency
15988 if (nSinceLastTry < nDelay)
15989 continue;
15990
15991 // If we have IRC, we'll be notified when they first come online,
15992 // and again every 24 hours by the refresh broadcast.
15993 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
15994 continue;
15995
15996 // Only try the old stuff if we don't have enough connections
15997 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
15998 continue;
15999
16000 // If multiple addresses are ready, prioritize by time since
16001 // last seen and time since last tried.
16002 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
16003 if (nScore > nBest)
16004 {
16005 nBest = nScore;
16006 addrConnect = addr;
16007 }
16008 }
16009 }
16010
16011 if (addrConnect.IsValid())
16012 OpenNetworkConnection(addrConnect);
16013 }
16014 }
16015
16016 bool OpenNetworkConnection(const CAddress& addrConnect)
16017 {
16018 //
16019 // Initiate outbound network connection
16020 //
16021 if (fShutdown)
16022 return false;
16023 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
16024 FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
16025 return false;
16026
16027 vnThreadsRunning[1]--;
16028 CNode* pnode = ConnectNode(addrConnect);
16029 vnThreadsRunning[1]++;
16030 if (fShutdown)
16031 return false;
16032 if (!pnode)
16033 return false;
16034 pnode->fNetworkNode = true;
16035
16036 return true;
16037 }
16038
16039
16040
16041
16042
16043
16044
16045
16046 void ThreadMessageHandler(void* parg)
16047 {
16048 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
16049 try
16050 {
16051 vnThreadsRunning[2]++;
16052 ThreadMessageHandler2(parg);
16053 vnThreadsRunning[2]--;
16054 }
16055 catch (std::exception& e) {
16056 vnThreadsRunning[2]--;
16057 PrintException(&e, "ThreadMessageHandler()");
16058 } catch (...) {
16059 vnThreadsRunning[2]--;
16060 PrintException(NULL, "ThreadMessageHandler()");
16061 }
16062 printf("ThreadMessageHandler exiting\n");
16063 }
16064
16065 void ThreadMessageHandler2(void* parg)
16066 {
16067 printf("ThreadMessageHandler started\n");
16068 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
16069 while (!fShutdown)
16070 {
16071 vector<CNode*> vNodesCopy;
16072 CRITICAL_BLOCK(cs_vNodes)
16073 {
16074 vNodesCopy = vNodes;
16075 BOOST_FOREACH(CNode* pnode, vNodesCopy)
16076 pnode->AddRef();
16077 }
16078
16079 // Poll the connected nodes for messages
16080 CNode* pnodeTrickle = NULL;
16081 if (!vNodesCopy.empty())
16082 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
16083 BOOST_FOREACH(CNode* pnode, vNodesCopy)
16084 {
16085 // Receive messages
16086 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
16087 ProcessMessages(pnode);
16088 if (fShutdown)
16089 return;
16090
16091 // Send messages
16092 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
16093 SendMessages(pnode, pnode == pnodeTrickle);
16094 if (fShutdown)
16095 return;
16096 }
16097
16098 CRITICAL_BLOCK(cs_vNodes)
16099 {
16100 BOOST_FOREACH(CNode* pnode, vNodesCopy)
16101 pnode->Release();
16102 }
16103
16104 // Wait and allow messages to bunch up.
16105 // Reduce vnThreadsRunning so StopNode has permission to exit while
16106 // we're sleeping, but we must always check fShutdown after doing this.
16107 vnThreadsRunning[2]--;
16108 Sleep(100);
16109 if (fRequestShutdown)
16110 Shutdown(NULL);
16111 vnThreadsRunning[2]++;
16112 if (fShutdown)
16113 return;
16114 }
16115 }
16116
16117
16118
16119
16120
16121
16122 bool BindListenPort(string& strError)
16123 {
16124 strError = "";
16125 int nOne = 1;
16126 addrLocalHost.port = htons(GetListenPort());
16127
16128 #ifdef WIN32
16129 // Initialize Windows Sockets
16130 WSADATA wsadata;
16131 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
16132 if (ret != NO_ERROR)
16133 {
16134 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
16135 printf("%s\n", strError.c_str());
16136 return false;
16137 }
16138 #endif
16139
16140 // Create socket for listening for incoming connections
16141 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
16142 if (hListenSocket == INVALID_SOCKET)
16143 {
16144 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
16145 printf("%s\n", strError.c_str());
16146 return false;
16147 }
16148
16149 #ifdef SO_NOSIGPIPE
16150 // Different way of disabling SIGPIPE on BSD
16151 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
16152 #endif
16153
16154 #ifndef WIN32
16155 // Allow binding if the port is still in TIME_WAIT state after
16156 // the program was closed and restarted. Not an issue on windows.
16157 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
16158 #endif
16159
16160 #ifdef WIN32
16161 // Set to nonblocking, incoming connections will also inherit this
16162 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
16163 #else
16164 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
16165 #endif
16166 {
16167 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
16168 printf("%s\n", strError.c_str());
16169 return false;
16170 }
16171
16172 // The sockaddr_in structure specifies the address family,
16173 // IP address, and port for the socket that is being bound
16174 struct sockaddr_in sockaddr;
16175 memset(&sockaddr, 0, sizeof(sockaddr));
16176 sockaddr.sin_family = AF_INET;
16177 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
16178 sockaddr.sin_port = htons(GetListenPort());
16179 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
16180 {
16181 int nErr = WSAGetLastError();
16182 if (nErr == WSAEADDRINUSE)
16183 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
16184 else
16185 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
16186 printf("%s\n", strError.c_str());
16187 return false;
16188 }
16189 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
16190
16191 // Listen for incoming connections
16192 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
16193 {
16194 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
16195 printf("%s\n", strError.c_str());
16196 return false;
16197 }
16198
16199 return true;
16200 }
16201
16202 void StartNode(void* parg)
16203 {
16204 if (pnodeLocalHost == NULL)
16205 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
16206
16207 #ifdef WIN32
16208 // Get local host ip
16209 char pszHostName[1000] = "";
16210 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
16211 {
16212 vector<CAddress> vaddr;
16213 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
16214 BOOST_FOREACH (const CAddress &addr, vaddr)
16215 if (addr.GetByte(3) != 127)
16216 {
16217 addrLocalHost = addr;
16218 break;
16219 }
16220 }
16221 #else
16222 // Get local host ip
16223 struct ifaddrs* myaddrs;
16224 if (getifaddrs(&myaddrs) == 0)
16225 {
16226 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
16227 {
16228 if (ifa->ifa_addr == NULL) continue;
16229 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
16230 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
16231 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
16232 char pszIP[100];
16233 if (ifa->ifa_addr->sa_family == AF_INET)
16234 {
16235 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
16236 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
16237 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
16238
16239 // Take the first IP that isn't loopback 127.x.x.x
16240 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
16241 if (addr.IsValid() && addr.GetByte(3) != 127)
16242 {
16243 addrLocalHost = addr;
16244 break;
16245 }
16246 }
16247 else if (ifa->ifa_addr->sa_family == AF_INET6)
16248 {
16249 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
16250 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
16251 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
16252 }
16253 }
16254 freeifaddrs(myaddrs);
16255 }
16256 #endif
16257 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
16258
16259 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
16260 {
16261 // Proxies can't take incoming connections
16262 addrLocalHost.ip = CAddress("0.0.0.0").ip;
16263 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
16264 }
16265 else
16266 {
16267 CreateThread(ThreadGetMyExternalIP, NULL);
16268 }
16269
16270 //
16271 // Start threads
16272 //
16273
16274 if (GetBoolArg("-nodnsseed"))
16275 printf("DNS seeding disabled\n");
16276 else
16277 if (!CreateThread(ThreadDNSAddressSeed, NULL))
16278 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
16279
16280 // Map ports with UPnP
16281 if (fHaveUPnP)
16282 MapPort(fUseUPnP);
16283
16284 // Get addresses from IRC and advertise ours
16285 if (!CreateThread(ThreadIRCSeed, NULL))
16286 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
16287
16288 // Send and receive from sockets, accept connections
16289 if (!CreateThread(ThreadSocketHandler, NULL))
16290 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
16291
16292 // Initiate outbound connections
16293 if (!CreateThread(ThreadOpenConnections, NULL))
16294 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
16295
16296 // Process messages
16297 if (!CreateThread(ThreadMessageHandler, NULL))
16298 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
16299
16300 // Generate coins in the background
16301 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
16302 }
16303
16304 bool StopNode()
16305 {
16306 printf("StopNode()\n");
16307 fShutdown = true;
16308 nTransactionsUpdated++;
16309 int64 nStart = GetTime();
16310 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
16311 #ifdef USE_UPNP
16312 || vnThreadsRunning[5] > 0
16313 #endif
16314 )
16315 {
16316 if (GetTime() - nStart > 20)
16317 break;
16318 Sleep(20);
16319 }
16320 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
16321 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
16322 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
16323 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
16324 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
16325 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
16326 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
16327 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
16328 Sleep(20);
16329 Sleep(50);
16330
16331 return true;
16332 }
16333
16334 class CNetCleanup
16335 {
16336 public:
16337 CNetCleanup()
16338 {
16339 }
16340 ~CNetCleanup()
16341 {
16342 // Close sockets
16343 BOOST_FOREACH(CNode* pnode, vNodes)
16344 if (pnode->hSocket != INVALID_SOCKET)
16345 closesocket(pnode->hSocket);
16346 if (hListenSocket != INVALID_SOCKET)
16347 if (closesocket(hListenSocket) == SOCKET_ERROR)
16348 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
16349
16350 #ifdef WIN32
16351 // Shutdown Windows Sockets
16352 WSACleanup();
16353 #endif
16354 }
16355 }
16356 instance_of_cnetcleanup;