1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
12 #include "ui_interface.h"
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
26 using namespace boost
;
28 static const int MAX_OUTBOUND_CONNECTIONS
= 8;
30 void ThreadMessageHandler2(void* parg
);
31 void ThreadSocketHandler2(void* parg
);
32 void ThreadOpenConnections2(void* parg
);
33 void ThreadOpenAddedConnections2(void* parg
);
35 void ThreadMapPort2(void* parg
);
37 void ThreadDNSAddressSeed2(void* parg
);
38 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
= NULL
, const char *strDest
= NULL
, bool fOneShot
= false);
41 struct LocalServiceInfo
{
47 // Global state variables
50 bool fDiscover
= true;
51 bool fUseUPnP
= false;
52 uint64 nLocalServices
= (fClient
? 0 : NODE_NETWORK
);
53 static CCriticalSection cs_mapLocalHost
;
54 static map
<CNetAddr
, LocalServiceInfo
> mapLocalHost
;
55 static bool vfReachable
[NET_MAX
] = {};
56 static bool vfLimited
[NET_MAX
] = {};
57 static CNode
* pnodeLocalHost
= NULL
;
58 uint64 nLocalHostNonce
= 0;
59 array
<int, THREAD_MAX
> vnThreadsRunning
;
60 static std::vector
<SOCKET
> vhListenSocket
;
63 vector
<CNode
*> vNodes
;
64 CCriticalSection cs_vNodes
;
65 map
<CInv
, CDataStream
> mapRelay
;
66 deque
<pair
<int64
, CInv
> > vRelayExpiration
;
67 CCriticalSection cs_mapRelay
;
68 map
<CInv
, int64
> mapAlreadyAskedFor
;
70 static deque
<string
> vOneShots
;
71 CCriticalSection cs_vOneShots
;
73 set
<CNetAddr
> setservAddNodeAddresses
;
74 CCriticalSection cs_setservAddNodeAddresses
;
76 static CSemaphore
*semOutbound
= NULL
;
78 void AddOneShot(string strDest
)
81 vOneShots
.push_back(strDest
);
84 unsigned short GetListenPort()
86 return (unsigned short)(GetArg("-port", GetDefaultPort()));
89 void CNode::PushGetBlocks(CBlockIndex
* pindexBegin
, uint256 hashEnd
)
91 // Filter out duplicate requests
92 if (pindexBegin
== pindexLastGetBlocksBegin
&& hashEnd
== hashLastGetBlocksEnd
)
94 pindexLastGetBlocksBegin
= pindexBegin
;
95 hashLastGetBlocksEnd
= hashEnd
;
97 PushMessage("getblocks", CBlockLocator(pindexBegin
), hashEnd
);
100 // find 'best' local address for a particular peer
101 bool GetLocal(CService
& addr
, const CNetAddr
*paddrPeer
)
107 int nBestReachability
= -1;
109 LOCK(cs_mapLocalHost
);
110 for (map
<CNetAddr
, LocalServiceInfo
>::iterator it
= mapLocalHost
.begin(); it
!= mapLocalHost
.end(); it
++)
112 int nScore
= (*it
).second
.nScore
;
113 int nReachability
= (*it
).first
.GetReachabilityFrom(paddrPeer
);
114 if (nReachability
> nBestReachability
|| (nReachability
== nBestReachability
&& nScore
> nBestScore
))
116 addr
= CService((*it
).first
, (*it
).second
.nPort
);
117 nBestReachability
= nReachability
;
122 return nBestScore
>= 0;
125 // get best local address for a particular peer as a CAddress
126 CAddress
GetLocalAddress(const CNetAddr
*paddrPeer
)
128 CAddress
ret(CService("0.0.0.0",0),0);
130 if (GetLocal(addr
, paddrPeer
))
132 ret
= CAddress(addr
);
133 ret
.nServices
= nLocalServices
;
134 ret
.nTime
= GetAdjustedTime();
139 bool RecvLine(SOCKET hSocket
, string
& strLine
)
145 int nBytes
= recv(hSocket
, &c
, 1, 0);
153 if (strLine
.size() >= 9000)
156 else if (nBytes
<= 0)
162 int nErr
= WSAGetLastError();
163 if (nErr
== WSAEMSGSIZE
)
165 if (nErr
== WSAEWOULDBLOCK
|| nErr
== WSAEINTR
|| nErr
== WSAEINPROGRESS
)
171 if (!strLine
.empty())
176 printf("socket closed\n");
182 int nErr
= WSAGetLastError();
183 printf("recv failed: %d\n", nErr
);
190 // used when scores of local addresses may have changed
191 // pushes better local address to peers
192 void static AdvertizeLocal()
195 BOOST_FOREACH(CNode
* pnode
, vNodes
)
197 if (pnode
->fSuccessfullyConnected
)
199 CAddress addrLocal
= GetLocalAddress(&pnode
->addr
);
200 if (addrLocal
.IsRoutable() && (CService
)addrLocal
!= (CService
)pnode
->addrLocal
)
202 pnode
->PushAddress(addrLocal
);
203 pnode
->addrLocal
= addrLocal
;
209 void SetReachable(enum Network net
, bool fFlag
)
211 LOCK(cs_mapLocalHost
);
212 vfReachable
[net
] = fFlag
;
213 if (net
== NET_IPV6
&& fFlag
)
214 vfReachable
[NET_IPV4
] = true;
217 // learn a new local address
218 bool AddLocal(const CService
& addr
, int nScore
)
220 if (!addr
.IsRoutable())
223 if (!fDiscover
&& nScore
< LOCAL_MANUAL
)
229 printf("AddLocal(%s,%i)\n", addr
.ToString().c_str(), nScore
);
232 LOCK(cs_mapLocalHost
);
233 bool fAlready
= mapLocalHost
.count(addr
) > 0;
234 LocalServiceInfo
&info
= mapLocalHost
[addr
];
235 if (!fAlready
|| nScore
>= info
.nScore
) {
236 info
.nScore
= nScore
+ (fAlready
? 1 : 0);
237 info
.nPort
= addr
.GetPort();
239 SetReachable(addr
.GetNetwork());
247 bool AddLocal(const CNetAddr
&addr
, int nScore
)
249 return AddLocal(CService(addr
, GetListenPort()), nScore
);
252 /** Make a particular network entirely off-limits (no automatic connects to it) */
253 void SetLimited(enum Network net
, bool fLimited
)
255 if (net
== NET_UNROUTABLE
)
257 LOCK(cs_mapLocalHost
);
258 vfLimited
[net
] = fLimited
;
261 bool IsLimited(enum Network net
)
263 LOCK(cs_mapLocalHost
);
264 return vfLimited
[net
];
267 bool IsLimited(const CNetAddr
&addr
)
269 return IsLimited(addr
.GetNetwork());
272 /** vote for a local address */
273 bool SeenLocal(const CService
& addr
)
276 LOCK(cs_mapLocalHost
);
277 if (mapLocalHost
.count(addr
) == 0)
279 mapLocalHost
[addr
].nScore
++;
287 /** check whether a given address is potentially local */
288 bool IsLocal(const CService
& addr
)
290 LOCK(cs_mapLocalHost
);
291 return mapLocalHost
.count(addr
) > 0;
294 /** check whether a given address is in a network we can probably connect to */
295 bool IsReachable(const CNetAddr
& addr
)
297 LOCK(cs_mapLocalHost
);
298 enum Network net
= addr
.GetNetwork();
299 return vfReachable
[net
] && !vfLimited
[net
];
302 bool GetMyExternalIP2(const CService
& addrConnect
, const char* pszGet
, const char* pszKeyword
, CNetAddr
& ipRet
)
305 if (!ConnectSocket(addrConnect
, hSocket
))
306 return error("GetMyExternalIP() : connection to %s failed", addrConnect
.ToString().c_str());
308 send(hSocket
, pszGet
, strlen(pszGet
), MSG_NOSIGNAL
);
311 while (RecvLine(hSocket
, strLine
))
313 if (strLine
.empty()) // HTTP response is separated from headers by blank line
317 if (!RecvLine(hSocket
, strLine
))
319 closesocket(hSocket
);
322 if (pszKeyword
== NULL
)
324 if (strLine
.find(pszKeyword
) != string::npos
)
326 strLine
= strLine
.substr(strLine
.find(pszKeyword
) + strlen(pszKeyword
));
330 closesocket(hSocket
);
331 if (strLine
.find("<") != string::npos
)
332 strLine
= strLine
.substr(0, strLine
.find("<"));
333 strLine
= strLine
.substr(strspn(strLine
.c_str(), " \t\n\r"));
334 while (strLine
.size() > 0 && isspace(strLine
[strLine
.size()-1]))
335 strLine
.resize(strLine
.size()-1);
336 CService
addr(strLine
,0,true);
337 printf("GetMyExternalIP() received [%s] %s\n", strLine
.c_str(), addr
.ToString().c_str());
338 if (!addr
.IsValid() || !addr
.IsRoutable())
344 closesocket(hSocket
);
345 return error("GetMyExternalIP() : connection closed");
348 // We now get our external IP from the IRC server first and only use this as a backup
349 bool GetMyExternalIP(CNetAddr
& ipRet
)
351 CService addrConnect
;
353 const char* pszKeyword
;
355 for (int nLookup
= 0; nLookup
<= 1; nLookup
++)
356 for (int nHost
= 1; nHost
<= 2; nHost
++)
358 // We should be phasing out our use of sites like these. If we need
359 // replacements, we should ask for volunteers to put this simple
360 // php file on their web server that prints the client IP:
361 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
364 addrConnect
= CService("91.198.22.70",80); // checkip.dyndns.org
368 CService
addrIP("checkip.dyndns.org", 80, true);
369 if (addrIP
.IsValid())
370 addrConnect
= addrIP
;
373 pszGet
= "GET / HTTP/1.1\r\n"
374 "Host: checkip.dyndns.org\r\n"
375 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
376 "Connection: close\r\n"
379 pszKeyword
= "Address:";
383 addrConnect
= CService("74.208.43.192", 80); // www.showmyip.com
387 CService
addrIP("www.showmyip.com", 80, true);
388 if (addrIP
.IsValid())
389 addrConnect
= addrIP
;
392 pszGet
= "GET /simple/ HTTP/1.1\r\n"
393 "Host: www.showmyip.com\r\n"
394 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
395 "Connection: close\r\n"
398 pszKeyword
= NULL
; // Returns just IP address
401 if (GetMyExternalIP2(addrConnect
, pszGet
, pszKeyword
, ipRet
))
408 void ThreadGetMyExternalIP(void* parg
)
410 // Make this thread recognisable as the external IP detection thread
411 RenameThread("bitcoin-ext-ip");
413 CNetAddr addrLocalHost
;
414 if (GetMyExternalIP(addrLocalHost
))
416 printf("GetMyExternalIP() returned %s\n", addrLocalHost
.ToStringIP().c_str());
417 AddLocal(addrLocalHost
, LOCAL_HTTP
);
425 void AddressCurrentlyConnected(const CService
& addr
)
427 addrman
.Connected(addr
);
436 CNode
* FindNode(const CNetAddr
& ip
)
440 BOOST_FOREACH(CNode
* pnode
, vNodes
)
441 if ((CNetAddr
)pnode
->addr
== ip
)
447 CNode
* FindNode(std::string addrName
)
450 BOOST_FOREACH(CNode
* pnode
, vNodes
)
451 if (pnode
->addrName
== addrName
)
456 CNode
* FindNode(const CService
& addr
)
460 BOOST_FOREACH(CNode
* pnode
, vNodes
)
461 if ((CService
)pnode
->addr
== addr
)
467 CNode
* ConnectNode(CAddress addrConnect
, const char *pszDest
, int64 nTimeout
)
469 if (pszDest
== NULL
) {
470 if (IsLocal(addrConnect
))
473 // Look for an existing connection
474 CNode
* pnode
= FindNode((CService
)addrConnect
);
478 pnode
->AddRef(nTimeout
);
487 printf("trying connection %s lastseen=%.1fhrs\n",
488 pszDest
? pszDest
: addrConnect
.ToString().c_str(),
489 pszDest
? 0 : (double)(GetAdjustedTime() - addrConnect
.nTime
)/3600.0);
493 if (pszDest
? ConnectSocketByName(addrConnect
, hSocket
, pszDest
, GetDefaultPort()) : ConnectSocket(addrConnect
, hSocket
))
495 addrman
.Attempt(addrConnect
);
498 printf("connected %s\n", pszDest
? pszDest
: addrConnect
.ToString().c_str());
500 // Set to non-blocking
503 if (ioctlsocket(hSocket
, FIONBIO
, &nOne
) == SOCKET_ERROR
)
504 printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
506 if (fcntl(hSocket
, F_SETFL
, O_NONBLOCK
) == SOCKET_ERROR
)
507 printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno
);
511 CNode
* pnode
= new CNode(hSocket
, addrConnect
, pszDest
? pszDest
: "", false);
513 pnode
->AddRef(nTimeout
);
519 vNodes
.push_back(pnode
);
522 pnode
->nTimeConnected
= GetTime();
531 void CNode::CloseSocketDisconnect()
534 if (hSocket
!= INVALID_SOCKET
)
536 printf("disconnecting node %s\n", addrName
.c_str());
537 closesocket(hSocket
);
538 hSocket
= INVALID_SOCKET
;
543 void CNode::Cleanup()
548 void CNode::PushVersion()
550 /// when NTP implemented, change to just nTime = GetAdjustedTime()
551 int64 nTime
= (fInbound
? GetAdjustedTime() : GetTime());
552 CAddress addrYou
= (addr
.IsRoutable() && !IsProxy(addr
) ? addr
: CAddress(CService("0.0.0.0",0)));
553 CAddress addrMe
= GetLocalAddress(&addr
);
554 RAND_bytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
555 printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString().c_str(), addrYou
.ToString().c_str(), addr
.ToString().c_str());
556 PushMessage("version", PROTOCOL_VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
557 nLocalHostNonce
, FormatSubVersion(CLIENT_NAME
, CLIENT_VERSION
, std::vector
<string
>()), nBestHeight
);
564 std::map
<CNetAddr
, int64
> CNode::setBanned
;
565 CCriticalSection
CNode::cs_setBanned
;
567 void CNode::ClearBanned()
572 bool CNode::IsBanned(CNetAddr ip
)
574 bool fResult
= false;
577 std::map
<CNetAddr
, int64
>::iterator i
= setBanned
.find(ip
);
578 if (i
!= setBanned
.end())
580 int64 t
= (*i
).second
;
588 bool CNode::Misbehaving(int howmuch
)
592 printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName
.c_str(), howmuch
);
596 nMisbehavior
+= howmuch
;
597 if (nMisbehavior
>= GetArg("-banscore", 100))
599 int64 banTime
= GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
600 printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr
.ToString().c_str(), nMisbehavior
-howmuch
, nMisbehavior
);
603 if (setBanned
[addr
] < banTime
)
604 setBanned
[addr
] = banTime
;
606 CloseSocketDisconnect();
609 printf("Misbehaving: %s (%d -> %d)\n", addr
.ToString().c_str(), nMisbehavior
-howmuch
, nMisbehavior
);
614 #define X(name) stats.name = name
615 void CNode::copyStats(CNodeStats
&stats
)
640 void ThreadSocketHandler(void* parg
)
642 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg
));
644 // Make this thread recognisable as the networking thread
645 RenameThread("bitcoin-net");
649 vnThreadsRunning
[THREAD_SOCKETHANDLER
]++;
650 ThreadSocketHandler2(parg
);
651 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
653 catch (std::exception
& e
) {
654 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
655 PrintException(&e
, "ThreadSocketHandler()");
657 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
658 throw; // support pthread_cancel()
660 printf("ThreadSocketHandler exited\n");
663 void ThreadSocketHandler2(void* parg
)
665 printf("ThreadSocketHandler started\n");
666 list
<CNode
*> vNodesDisconnected
;
667 unsigned int nPrevNodeCount
= 0;
676 // Disconnect unused nodes
677 vector
<CNode
*> vNodesCopy
= vNodes
;
678 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
680 if (pnode
->fDisconnect
||
681 (pnode
->GetRefCount() <= 0 && pnode
->vRecv
.empty() && pnode
->vSend
.empty()))
683 // remove from vNodes
684 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
686 // release outbound grant (if any)
687 pnode
->grantOutbound
.Release();
689 // close socket and cleanup
690 pnode
->CloseSocketDisconnect();
693 // hold in disconnected pool until all refs are released
694 pnode
->nReleaseTime
= max(pnode
->nReleaseTime
, GetTime() + 15 * 60);
695 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
697 vNodesDisconnected
.push_back(pnode
);
701 // Delete disconnected nodes
702 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
703 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
705 // wait until threads are done using it
706 if (pnode
->GetRefCount() <= 0)
708 bool fDelete
= false;
710 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
713 TRY_LOCK(pnode
->cs_vRecv
, lockRecv
);
716 TRY_LOCK(pnode
->cs_mapRequests
, lockReq
);
719 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
728 vNodesDisconnected
.remove(pnode
);
734 if (vNodes
.size() != nPrevNodeCount
)
736 nPrevNodeCount
= vNodes
.size();
737 uiInterface
.NotifyNumConnectionsChanged(vNodes
.size());
742 // Find which sockets have data to receive
744 struct timeval timeout
;
746 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
753 FD_ZERO(&fdsetError
);
754 SOCKET hSocketMax
= 0;
755 bool have_fds
= false;
757 BOOST_FOREACH(SOCKET hListenSocket
, vhListenSocket
) {
758 FD_SET(hListenSocket
, &fdsetRecv
);
759 hSocketMax
= max(hSocketMax
, hListenSocket
);
764 BOOST_FOREACH(CNode
* pnode
, vNodes
)
766 if (pnode
->hSocket
== INVALID_SOCKET
)
768 FD_SET(pnode
->hSocket
, &fdsetRecv
);
769 FD_SET(pnode
->hSocket
, &fdsetError
);
770 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
773 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
774 if (lockSend
&& !pnode
->vSend
.empty())
775 FD_SET(pnode
->hSocket
, &fdsetSend
);
780 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
781 int nSelect
= select(have_fds
? hSocketMax
+ 1 : 0,
782 &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
783 vnThreadsRunning
[THREAD_SOCKETHANDLER
]++;
786 if (nSelect
== SOCKET_ERROR
)
790 int nErr
= WSAGetLastError();
791 printf("socket select error %d\n", nErr
);
792 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
793 FD_SET(i
, &fdsetRecv
);
796 FD_ZERO(&fdsetError
);
797 Sleep(timeout
.tv_usec
/1000);
802 // Accept new connections
804 BOOST_FOREACH(SOCKET hListenSocket
, vhListenSocket
)
805 if (hListenSocket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
, &fdsetRecv
))
808 struct sockaddr_storage sockaddr
;
810 struct sockaddr sockaddr
;
812 socklen_t len
= sizeof(sockaddr
);
813 SOCKET hSocket
= accept(hListenSocket
, (struct sockaddr
*)&sockaddr
, &len
);
817 if (hSocket
!= INVALID_SOCKET
)
818 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
819 printf("Warning: Unknown socket family\n");
823 BOOST_FOREACH(CNode
* pnode
, vNodes
)
828 if (hSocket
== INVALID_SOCKET
)
830 int nErr
= WSAGetLastError();
831 if (nErr
!= WSAEWOULDBLOCK
)
832 printf("socket error accept failed: %d\n", nErr
);
834 else if (nInbound
>= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS
)
837 LOCK(cs_setservAddNodeAddresses
);
838 if (!setservAddNodeAddresses
.count(addr
))
839 closesocket(hSocket
);
842 else if (CNode::IsBanned(addr
))
844 printf("connection from %s dropped (banned)\n", addr
.ToString().c_str());
845 closesocket(hSocket
);
849 printf("accepted connection %s\n", addr
.ToString().c_str());
850 CNode
* pnode
= new CNode(hSocket
, addr
, "", true);
854 vNodes
.push_back(pnode
);
861 // Service each socket
863 vector
<CNode
*> vNodesCopy
;
867 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
870 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
878 if (pnode
->hSocket
== INVALID_SOCKET
)
880 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
882 TRY_LOCK(pnode
->cs_vRecv
, lockRecv
);
885 CDataStream
& vRecv
= pnode
->vRecv
;
886 unsigned int nPos
= vRecv
.size();
888 if (nPos
> ReceiveBufferSize()) {
889 if (!pnode
->fDisconnect
)
890 printf("socket recv flood control disconnect (%d bytes)\n", vRecv
.size());
891 pnode
->CloseSocketDisconnect();
894 // typical socket buffer is 8K-64K
895 char pchBuf
[0x10000];
896 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
899 vRecv
.resize(nPos
+ nBytes
);
900 memcpy(&vRecv
[nPos
], pchBuf
, nBytes
);
901 pnode
->nLastRecv
= GetTime();
903 else if (nBytes
== 0)
905 // socket closed gracefully
906 if (!pnode
->fDisconnect
)
907 printf("socket closed\n");
908 pnode
->CloseSocketDisconnect();
913 int nErr
= WSAGetLastError();
914 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
916 if (!pnode
->fDisconnect
)
917 printf("socket recv error %d\n", nErr
);
918 pnode
->CloseSocketDisconnect();
928 if (pnode
->hSocket
== INVALID_SOCKET
)
930 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
932 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
935 CDataStream
& vSend
= pnode
->vSend
;
938 int nBytes
= send(pnode
->hSocket
, &vSend
[0], vSend
.size(), MSG_NOSIGNAL
| MSG_DONTWAIT
);
941 vSend
.erase(vSend
.begin(), vSend
.begin() + nBytes
);
942 pnode
->nLastSend
= GetTime();
947 int nErr
= WSAGetLastError();
948 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
950 printf("socket send error %d\n", nErr
);
951 pnode
->CloseSocketDisconnect();
959 // Inactivity checking
961 if (pnode
->vSend
.empty())
962 pnode
->nLastSendEmpty
= GetTime();
963 if (GetTime() - pnode
->nTimeConnected
> 60)
965 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
967 printf("socket no message in first 60 seconds, %d %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0);
968 pnode
->fDisconnect
= true;
970 else if (GetTime() - pnode
->nLastSend
> 90*60 && GetTime() - pnode
->nLastSendEmpty
> 90*60)
972 printf("socket not sending\n");
973 pnode
->fDisconnect
= true;
975 else if (GetTime() - pnode
->nLastRecv
> 90*60)
977 printf("socket inactivity timeout\n");
978 pnode
->fDisconnect
= true;
984 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1001 void ThreadMapPort(void* parg
)
1003 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg
));
1005 // Make this thread recognisable as the UPnP thread
1006 RenameThread("bitcoin-UPnP");
1010 vnThreadsRunning
[THREAD_UPNP
]++;
1011 ThreadMapPort2(parg
);
1012 vnThreadsRunning
[THREAD_UPNP
]--;
1014 catch (std::exception
& e
) {
1015 vnThreadsRunning
[THREAD_UPNP
]--;
1016 PrintException(&e
, "ThreadMapPort()");
1018 vnThreadsRunning
[THREAD_UPNP
]--;
1019 PrintException(NULL
, "ThreadMapPort()");
1021 printf("ThreadMapPort exited\n");
1024 void ThreadMapPort2(void* parg
)
1026 printf("ThreadMapPort started\n");
1028 std::string port
= strprintf("%u", GetListenPort());
1029 const char * multicastif
= 0;
1030 const char * minissdpdpath
= 0;
1031 struct UPNPDev
* devlist
= 0;
1034 #ifndef UPNPDISCOVER_SUCCESS
1036 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1040 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1043 struct UPNPUrls urls
;
1044 struct IGDdatas data
;
1047 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1051 char externalIPAddress
[40];
1052 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1053 if(r
!= UPNPCOMMAND_SUCCESS
)
1054 printf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1057 if(externalIPAddress
[0])
1059 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress
);
1060 AddLocal(CNetAddr(externalIPAddress
), LOCAL_UPNP
);
1063 printf("UPnP: GetExternalIPAddress failed.\n");
1067 string strDesc
= "Bitcoin " + FormatFullVersion();
1068 #ifndef UPNPDISCOVER_SUCCESS
1070 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1071 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1074 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1075 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1078 if(r
!=UPNPCOMMAND_SUCCESS
)
1079 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1080 port
.c_str(), port
.c_str(), lanaddr
, r
, strupnperror(r
));
1082 printf("UPnP Port Mapping successful.\n");
1085 if (fShutdown
|| !fUseUPnP
)
1087 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
.c_str(), "TCP", 0);
1088 printf("UPNP_DeletePortMapping() returned : %d\n", r
);
1089 freeUPNPDevlist(devlist
); devlist
= 0;
1090 FreeUPNPUrls(&urls
);
1093 if (i
% 600 == 0) // Refresh every 20 minutes
1095 #ifndef UPNPDISCOVER_SUCCESS
1097 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1098 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1101 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1102 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1105 if(r
!=UPNPCOMMAND_SUCCESS
)
1106 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1107 port
.c_str(), port
.c_str(), lanaddr
, r
, strupnperror(r
));
1109 printf("UPnP Port Mapping successful.\n");;
1115 printf("No valid UPnP IGDs found\n");
1116 freeUPNPDevlist(devlist
); devlist
= 0;
1118 FreeUPNPUrls(&urls
);
1120 if (fShutdown
|| !fUseUPnP
)
1129 if (fUseUPnP
&& vnThreadsRunning
[THREAD_UPNP
] < 1)
1131 if (!NewThread(ThreadMapPort
, NULL
))
1132 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1138 // Intentionally left blank.
1151 // Each pair gives a source name and a seed name.
1152 // The first name is used as information source for addrman.
1153 // The second name should resolve to a list of seed addresses.
1154 static const char *strDNSSeed
[][2] = {
1155 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1156 {"bluematt.me", "dnsseed.bluematt.me"},
1157 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1158 {"xf2.org", "bitseed.xf2.org"},
1161 void ThreadDNSAddressSeed(void* parg
)
1163 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg
));
1165 // Make this thread recognisable as the DNS seeding thread
1166 RenameThread("bitcoin-dnsseed");
1170 vnThreadsRunning
[THREAD_DNSSEED
]++;
1171 ThreadDNSAddressSeed2(parg
);
1172 vnThreadsRunning
[THREAD_DNSSEED
]--;
1174 catch (std::exception
& e
) {
1175 vnThreadsRunning
[THREAD_DNSSEED
]--;
1176 PrintException(&e
, "ThreadDNSAddressSeed()");
1178 vnThreadsRunning
[THREAD_DNSSEED
]--;
1179 throw; // support pthread_cancel()
1181 printf("ThreadDNSAddressSeed exited\n");
1184 void ThreadDNSAddressSeed2(void* parg
)
1186 printf("ThreadDNSAddressSeed started\n");
1191 printf("Loading addresses from DNS seeds (could take a while)\n");
1193 for (unsigned int seed_idx
= 0; seed_idx
< ARRAYLEN(strDNSSeed
); seed_idx
++) {
1194 if (GetNameProxy()) {
1195 AddOneShot(strDNSSeed
[seed_idx
][1]);
1197 vector
<CNetAddr
> vaddr
;
1198 vector
<CAddress
> vAdd
;
1199 if (LookupHost(strDNSSeed
[seed_idx
][1], vaddr
))
1201 BOOST_FOREACH(CNetAddr
& ip
, vaddr
)
1203 int nOneDay
= 24*3600;
1204 CAddress addr
= CAddress(CService(ip
, GetDefaultPort()));
1205 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1206 vAdd
.push_back(addr
);
1210 addrman
.Add(vAdd
, CNetAddr(strDNSSeed
[seed_idx
][0], true));
1215 printf("%d addresses found from DNS seeds\n", found
);
1229 unsigned int pnSeed
[] =
1231 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1232 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1233 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1234 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1235 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1236 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1237 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1238 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1239 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1240 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1241 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1242 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1243 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1244 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1245 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1246 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1247 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1248 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1249 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1250 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1251 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1252 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1253 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1254 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1255 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1256 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1257 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1258 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1259 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1260 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1261 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1262 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1263 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1264 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1265 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1266 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1267 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1268 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1269 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1270 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1271 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1272 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1273 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1274 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1275 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1276 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1277 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1278 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1279 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1280 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1281 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1282 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1283 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1284 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1285 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1286 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1287 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1288 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1289 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1290 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1291 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1292 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1293 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1294 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1295 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1296 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1297 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1298 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1299 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1300 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1301 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1302 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1303 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1304 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1305 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1306 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1307 0xc461d84a, 0xb2dbe247,
1310 void DumpAddresses()
1312 int64 nStart
= GetTimeMillis();
1317 printf("Flushed %d addresses to peers.dat %"PRI64d
"ms\n",
1318 addrman
.size(), GetTimeMillis() - nStart
);
1321 void ThreadDumpAddress2(void* parg
)
1323 vnThreadsRunning
[THREAD_DUMPADDRESS
]++;
1327 vnThreadsRunning
[THREAD_DUMPADDRESS
]--;
1329 vnThreadsRunning
[THREAD_DUMPADDRESS
]++;
1331 vnThreadsRunning
[THREAD_DUMPADDRESS
]--;
1334 void ThreadDumpAddress(void* parg
)
1336 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg
));
1338 // Make this thread recognisable as the address dumping thread
1339 RenameThread("bitcoin-adrdump");
1343 ThreadDumpAddress2(parg
);
1345 catch (std::exception
& e
) {
1346 PrintException(&e
, "ThreadDumpAddress()");
1348 printf("ThreadDumpAddress exited\n");
1351 void ThreadOpenConnections(void* parg
)
1353 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg
));
1355 // Make this thread recognisable as the connection opening thread
1356 RenameThread("bitcoin-opencon");
1360 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1361 ThreadOpenConnections2(parg
);
1362 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1364 catch (std::exception
& e
) {
1365 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1366 PrintException(&e
, "ThreadOpenConnections()");
1368 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1369 PrintException(NULL
, "ThreadOpenConnections()");
1371 printf("ThreadOpenConnections exited\n");
1374 void static ProcessOneShot()
1379 if (vOneShots
.empty())
1381 strDest
= vOneShots
.front();
1382 vOneShots
.pop_front();
1385 CSemaphoreGrant
grant(*semOutbound
, true);
1387 if (!OpenNetworkConnection(addr
, &grant
, strDest
.c_str(), true))
1388 AddOneShot(strDest
);
1392 void ThreadOpenConnections2(void* parg
)
1394 printf("ThreadOpenConnections started\n");
1396 // Connect to specific addresses
1397 if (mapArgs
.count("-connect") && mapMultiArgs
["-connect"].size() > 0)
1399 for (int64 nLoop
= 0;; nLoop
++)
1402 BOOST_FOREACH(string strAddr
, mapMultiArgs
["-connect"])
1405 OpenNetworkConnection(addr
, NULL
, strAddr
.c_str());
1406 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1417 // Initiate network connections
1418 int64 nStart
= GetTime();
1423 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1425 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1430 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1431 CSemaphoreGrant
grant(*semOutbound
);
1432 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1436 // Add seed nodes if IRC isn't working
1437 if (addrman
.size()==0 && (GetTime() - nStart
> 60) && !fTestNet
)
1439 std::vector
<CAddress
> vAdd
;
1440 for (unsigned int i
= 0; i
< ARRAYLEN(pnSeed
); i
++)
1442 // It'll only connect to one or two seed nodes because once it connects,
1443 // it'll get a pile of addresses with newer timestamps.
1444 // Seed nodes are given a random 'last seen time' of between one and two
1446 const int64 nOneWeek
= 7*24*60*60;
1448 memcpy(&ip
, &pnSeed
[i
], sizeof(ip
));
1449 CAddress
addr(CService(ip
, GetDefaultPort()));
1450 addr
.nTime
= GetTime()-GetRand(nOneWeek
)-nOneWeek
;
1451 vAdd
.push_back(addr
);
1453 addrman
.Add(vAdd
, CNetAddr("127.0.0.1"));
1457 // Choose an address to connect to based on most recently seen
1459 CAddress addrConnect
;
1461 // Only connect out to one peer per network group (/16 for IPv4).
1462 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1464 set
<vector
<unsigned char> > setConnected
;
1467 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1468 if (!pnode
->fInbound
) {
1469 setConnected
.insert(pnode
->addr
.GetGroup());
1475 int64 nANow
= GetAdjustedTime();
1480 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1481 CAddress addr
= addrman
.Select(10 + min(nOutbound
,8)*10);
1483 // if we selected an invalid address, restart
1484 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1487 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1488 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1489 // already-connected network ranges, ...) before trying new addrman addresses.
1494 if (IsLimited(addr
))
1497 // only consider very recently tried nodes after 30 failed attempts
1498 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1501 // do not allow non-default ports, unless after 50 invalid addresses selected already
1502 if (addr
.GetPort() != GetDefaultPort() && nTries
< 50)
1509 if (addrConnect
.IsValid())
1510 OpenNetworkConnection(addrConnect
, &grant
);
1514 void ThreadOpenAddedConnections(void* parg
)
1516 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg
));
1518 // Make this thread recognisable as the connection opening thread
1519 RenameThread("bitcoin-opencon");
1523 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]++;
1524 ThreadOpenAddedConnections2(parg
);
1525 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1527 catch (std::exception
& e
) {
1528 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1529 PrintException(&e
, "ThreadOpenAddedConnections()");
1531 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1532 PrintException(NULL
, "ThreadOpenAddedConnections()");
1534 printf("ThreadOpenAddedConnections exited\n");
1537 void ThreadOpenAddedConnections2(void* parg
)
1539 printf("ThreadOpenAddedConnections started\n");
1541 if (mapArgs
.count("-addnode") == 0)
1544 if (GetNameProxy()) {
1546 BOOST_FOREACH(string
& strAddNode
, mapMultiArgs
["-addnode"]) {
1548 CSemaphoreGrant
grant(*semOutbound
);
1549 OpenNetworkConnection(addr
, &grant
, strAddNode
.c_str());
1552 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1553 Sleep(120000); // Retry every 2 minutes
1554 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]++;
1559 vector
<vector
<CService
> > vservAddressesToAdd(0);
1560 BOOST_FOREACH(string
& strAddNode
, mapMultiArgs
["-addnode"])
1562 vector
<CService
> vservNode(0);
1563 if(Lookup(strAddNode
.c_str(), vservNode
, GetDefaultPort(), fNameLookup
, 0))
1565 vservAddressesToAdd
.push_back(vservNode
);
1567 LOCK(cs_setservAddNodeAddresses
);
1568 BOOST_FOREACH(CService
& serv
, vservNode
)
1569 setservAddNodeAddresses
.insert(serv
);
1575 vector
<vector
<CService
> > vservConnectAddresses
= vservAddressesToAdd
;
1576 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1577 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1580 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1581 for (vector
<vector
<CService
> >::iterator it
= vservConnectAddresses
.begin(); it
!= vservConnectAddresses
.end(); it
++)
1582 BOOST_FOREACH(CService
& addrNode
, *(it
))
1583 if (pnode
->addr
== addrNode
)
1585 it
= vservConnectAddresses
.erase(it
);
1590 BOOST_FOREACH(vector
<CService
>& vserv
, vservConnectAddresses
)
1592 CSemaphoreGrant
grant(*semOutbound
);
1593 OpenNetworkConnection(CAddress(*(vserv
.begin())), &grant
);
1600 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1601 Sleep(120000); // Retry every 2 minutes
1602 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]++;
1608 // if successful, this moves the passed grant to the constructed node
1609 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
, const char *strDest
, bool fOneShot
)
1612 // Initiate outbound network connection
1617 if (IsLocal(addrConnect
) ||
1618 FindNode((CNetAddr
)addrConnect
) || CNode::IsBanned(addrConnect
) ||
1619 FindNode(addrConnect
.ToStringIPPort().c_str()))
1621 if (strDest
&& FindNode(strDest
))
1624 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1625 CNode
* pnode
= ConnectNode(addrConnect
, strDest
);
1626 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1632 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1633 pnode
->fNetworkNode
= true;
1635 pnode
->fOneShot
= true;
1647 void ThreadMessageHandler(void* parg
)
1649 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg
));
1651 // Make this thread recognisable as the message handling thread
1652 RenameThread("bitcoin-msghand");
1656 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]++;
1657 ThreadMessageHandler2(parg
);
1658 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1660 catch (std::exception
& e
) {
1661 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1662 PrintException(&e
, "ThreadMessageHandler()");
1664 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1665 PrintException(NULL
, "ThreadMessageHandler()");
1667 printf("ThreadMessageHandler exited\n");
1670 void ThreadMessageHandler2(void* parg
)
1672 printf("ThreadMessageHandler started\n");
1673 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1676 vector
<CNode
*> vNodesCopy
;
1679 vNodesCopy
= vNodes
;
1680 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1684 // Poll the connected nodes for messages
1685 CNode
* pnodeTrickle
= NULL
;
1686 if (!vNodesCopy
.empty())
1687 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1688 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1692 TRY_LOCK(pnode
->cs_vRecv
, lockRecv
);
1694 ProcessMessages(pnode
);
1701 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1703 SendMessages(pnode
, pnode
== pnodeTrickle
);
1711 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1715 // Wait and allow messages to bunch up.
1716 // Reduce vnThreadsRunning so StopNode has permission to exit while
1717 // we're sleeping, but we must always check fShutdown after doing this.
1718 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1720 if (fRequestShutdown
)
1722 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]++;
1733 bool BindListenPort(const CService
&addrBind
, string
& strError
)
1739 // Initialize Windows Sockets
1741 int ret
= WSAStartup(MAKEWORD(2,2), &wsadata
);
1742 if (ret
!= NO_ERROR
)
1744 strError
= strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret
);
1745 printf("%s\n", strError
.c_str());
1750 // Create socket for listening for incoming connections
1752 struct sockaddr_storage sockaddr
;
1754 struct sockaddr sockaddr
;
1756 socklen_t len
= sizeof(sockaddr
);
1757 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1759 strError
= strprintf("Error: bind address family for %s not supported", addrBind
.ToString().c_str());
1760 printf("%s\n", strError
.c_str());
1764 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1765 if (hListenSocket
== INVALID_SOCKET
)
1767 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1768 printf("%s\n", strError
.c_str());
1773 // Different way of disabling SIGPIPE on BSD
1774 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1778 // Allow binding if the port is still in TIME_WAIT state after
1779 // the program was closed and restarted. Not an issue on windows.
1780 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1785 // Set to non-blocking, incoming connections will also inherit this
1786 if (ioctlsocket(hListenSocket
, FIONBIO
, (u_long
*)&nOne
) == SOCKET_ERROR
)
1788 if (fcntl(hListenSocket
, F_SETFL
, O_NONBLOCK
) == SOCKET_ERROR
)
1791 strError
= strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1792 printf("%s\n", strError
.c_str());
1797 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1798 // and enable it by default or not. Try to enable it, if possible.
1799 if (addrBind
.IsIPv6()) {
1801 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1804 int nProtLevel
= 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1805 int nParameterId
= 23 /* IPV6_PROTECTION_LEVEl */;
1806 // this call is allowed to fail
1807 setsockopt(hListenSocket
, IPPROTO_IPV6
, nParameterId
, (const char*)&nProtLevel
, sizeof(int));
1812 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1814 int nErr
= WSAGetLastError();
1815 if (nErr
== WSAEADDRINUSE
)
1816 strError
= strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind
.ToString().c_str());
1818 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind
.ToString().c_str(), nErr
, strerror(nErr
));
1819 printf("%s\n", strError
.c_str());
1822 printf("Bound to %s\n", addrBind
.ToString().c_str());
1824 // Listen for incoming connections
1825 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1827 strError
= strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1828 printf("%s\n", strError
.c_str());
1832 vhListenSocket
.push_back(hListenSocket
);
1834 if (addrBind
.IsRoutable() && fDiscover
)
1835 AddLocal(addrBind
, LOCAL_BIND
);
1840 void static Discover()
1846 // Get local host IP
1847 char pszHostName
[1000] = "";
1848 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1850 vector
<CNetAddr
> vaddr
;
1851 if (LookupHost(pszHostName
, vaddr
))
1853 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1855 AddLocal(addr
, LOCAL_IF
);
1860 // Get local host ip
1861 struct ifaddrs
* myaddrs
;
1862 if (getifaddrs(&myaddrs
) == 0)
1864 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1866 if (ifa
->ifa_addr
== NULL
) continue;
1867 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1868 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1869 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1870 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1872 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1873 CNetAddr
addr(s4
->sin_addr
);
1874 if (AddLocal(addr
, LOCAL_IF
))
1875 printf("IPv4 %s: %s\n", ifa
->ifa_name
, addr
.ToString().c_str());
1878 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1880 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1881 CNetAddr
addr(s6
->sin6_addr
);
1882 if (AddLocal(addr
, LOCAL_IF
))
1883 printf("IPv6 %s: %s\n", ifa
->ifa_name
, addr
.ToString().c_str());
1887 freeifaddrs(myaddrs
);
1891 // Don't use external IPv4 discovery, when -onlynet="IPv6"
1892 if (!IsLimited(NET_IPV4
))
1893 NewThread(ThreadGetMyExternalIP
, NULL
);
1896 void StartNode(void* parg
)
1898 // Make this thread recognisable as the startup thread
1899 RenameThread("bitcoin-start");
1901 if (semOutbound
== NULL
) {
1902 // initialize semaphore
1903 int nMaxOutbound
= min(MAX_OUTBOUND_CONNECTIONS
, (int)GetArg("-maxconnections", 125));
1904 semOutbound
= new CSemaphore(nMaxOutbound
);
1907 if (pnodeLocalHost
== NULL
)
1908 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress(CService("127.0.0.1", 0), nLocalServices
));
1916 if (!GetBoolArg("-dnsseed", true))
1917 printf("DNS seeding disabled\n");
1919 if (!NewThread(ThreadDNSAddressSeed
, NULL
))
1920 printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1922 // Map ports with UPnP
1926 // Get addresses from IRC and advertise ours
1927 if (!NewThread(ThreadIRCSeed
, NULL
))
1928 printf("Error: NewThread(ThreadIRCSeed) failed\n");
1930 // Send and receive from sockets, accept connections
1931 if (!NewThread(ThreadSocketHandler
, NULL
))
1932 printf("Error: NewThread(ThreadSocketHandler) failed\n");
1934 // Initiate outbound connections from -addnode
1935 if (!NewThread(ThreadOpenAddedConnections
, NULL
))
1936 printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1938 // Initiate outbound connections
1939 if (!NewThread(ThreadOpenConnections
, NULL
))
1940 printf("Error: NewThread(ThreadOpenConnections) failed\n");
1943 if (!NewThread(ThreadMessageHandler
, NULL
))
1944 printf("Error: NewThread(ThreadMessageHandler) failed\n");
1946 // Dump network addresses
1947 if (!NewThread(ThreadDumpAddress
, NULL
))
1948 printf("Error; NewThread(ThreadDumpAddress) failed\n");
1950 // Generate coins in the background
1951 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain
);
1956 printf("StopNode()\n");
1958 nTransactionsUpdated
++;
1959 int64 nStart
= GetTime();
1961 for (int i
=0; i
<MAX_OUTBOUND_CONNECTIONS
; i
++)
1962 semOutbound
->post();
1965 int nThreadsRunning
= 0;
1966 for (int n
= 0; n
< THREAD_MAX
; n
++)
1967 nThreadsRunning
+= vnThreadsRunning
[n
];
1968 if (nThreadsRunning
== 0)
1970 if (GetTime() - nStart
> 20)
1974 if (vnThreadsRunning
[THREAD_SOCKETHANDLER
] > 0) printf("ThreadSocketHandler still running\n");
1975 if (vnThreadsRunning
[THREAD_OPENCONNECTIONS
] > 0) printf("ThreadOpenConnections still running\n");
1976 if (vnThreadsRunning
[THREAD_MESSAGEHANDLER
] > 0) printf("ThreadMessageHandler still running\n");
1977 if (vnThreadsRunning
[THREAD_MINER
] > 0) printf("ThreadBitcoinMiner still running\n");
1978 if (vnThreadsRunning
[THREAD_RPCLISTENER
] > 0) printf("ThreadRPCListener still running\n");
1979 if (vnThreadsRunning
[THREAD_RPCHANDLER
] > 0) printf("ThreadsRPCServer still running\n");
1981 if (vnThreadsRunning
[THREAD_UPNP
] > 0) printf("ThreadMapPort still running\n");
1983 if (vnThreadsRunning
[THREAD_DNSSEED
] > 0) printf("ThreadDNSAddressSeed still running\n");
1984 if (vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
] > 0) printf("ThreadOpenAddedConnections still running\n");
1985 if (vnThreadsRunning
[THREAD_DUMPADDRESS
] > 0) printf("ThreadDumpAddresses still running\n");
1986 while (vnThreadsRunning
[THREAD_MESSAGEHANDLER
] > 0 || vnThreadsRunning
[THREAD_RPCHANDLER
] > 0)
2002 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2003 if (pnode
->hSocket
!= INVALID_SOCKET
)
2004 closesocket(pnode
->hSocket
);
2005 BOOST_FOREACH(SOCKET hListenSocket
, vhListenSocket
)
2006 if (hListenSocket
!= INVALID_SOCKET
)
2007 if (closesocket(hListenSocket
) == SOCKET_ERROR
)
2008 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
2011 // Shutdown Windows Sockets
2016 instance_of_cnetcleanup
;