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
;
237 info
.nPort
= addr
.GetPort() + (fAlready
? 1 : 0);
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 webserver 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 nonblocking
503 if (ioctlsocket(hSocket
, FIONBIO
, &nOne
) == SOCKET_ERROR
)
504 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
506 if (fcntl(hSocket
, F_SETFL
, O_NONBLOCK
) == SOCKET_ERROR
)
507 printf("ConnectSocket() : fcntl nonblocking 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\n", addrName
.c_str());
596 nMisbehavior
+= howmuch
;
597 if (nMisbehavior
>= GetArg("-banscore", 100))
599 int64 banTime
= GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
602 if (setBanned
[addr
] < banTime
)
603 setBanned
[addr
] = banTime
;
605 CloseSocketDisconnect();
606 printf("Disconnected %s for misbehavior (score=%d)\n", addrName
.c_str(), nMisbehavior
);
613 #define X(name) stats.name = name
614 void CNode::copyStats(CNodeStats
&stats
)
639 void ThreadSocketHandler(void* parg
)
641 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg
));
643 // Make this thread recognisable as the networking thread
644 RenameThread("bitcoin-net");
648 vnThreadsRunning
[THREAD_SOCKETHANDLER
]++;
649 ThreadSocketHandler2(parg
);
650 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
652 catch (std::exception
& e
) {
653 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
654 PrintException(&e
, "ThreadSocketHandler()");
656 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
657 throw; // support pthread_cancel()
659 printf("ThreadSocketHandler exited\n");
662 void ThreadSocketHandler2(void* parg
)
664 printf("ThreadSocketHandler started\n");
665 list
<CNode
*> vNodesDisconnected
;
666 unsigned int nPrevNodeCount
= 0;
675 // Disconnect unused nodes
676 vector
<CNode
*> vNodesCopy
= vNodes
;
677 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
679 if (pnode
->fDisconnect
||
680 (pnode
->GetRefCount() <= 0 && pnode
->vRecv
.empty() && pnode
->vSend
.empty()))
682 // remove from vNodes
683 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
685 // release outbound grant (if any)
686 pnode
->grantOutbound
.Release();
688 // close socket and cleanup
689 pnode
->CloseSocketDisconnect();
692 // hold in disconnected pool until all refs are released
693 pnode
->nReleaseTime
= max(pnode
->nReleaseTime
, GetTime() + 15 * 60);
694 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
696 vNodesDisconnected
.push_back(pnode
);
700 // Delete disconnected nodes
701 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
702 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
704 // wait until threads are done using it
705 if (pnode
->GetRefCount() <= 0)
707 bool fDelete
= false;
709 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
712 TRY_LOCK(pnode
->cs_vRecv
, lockRecv
);
715 TRY_LOCK(pnode
->cs_mapRequests
, lockReq
);
718 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
727 vNodesDisconnected
.remove(pnode
);
733 if (vNodes
.size() != nPrevNodeCount
)
735 nPrevNodeCount
= vNodes
.size();
736 uiInterface
.NotifyNumConnectionsChanged(vNodes
.size());
741 // Find which sockets have data to receive
743 struct timeval timeout
;
745 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
752 FD_ZERO(&fdsetError
);
753 SOCKET hSocketMax
= 0;
755 BOOST_FOREACH(SOCKET hListenSocket
, vhListenSocket
) {
756 FD_SET(hListenSocket
, &fdsetRecv
);
757 hSocketMax
= max(hSocketMax
, hListenSocket
);
761 BOOST_FOREACH(CNode
* pnode
, vNodes
)
763 if (pnode
->hSocket
== INVALID_SOCKET
)
765 FD_SET(pnode
->hSocket
, &fdsetRecv
);
766 FD_SET(pnode
->hSocket
, &fdsetError
);
767 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
769 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
770 if (lockSend
&& !pnode
->vSend
.empty())
771 FD_SET(pnode
->hSocket
, &fdsetSend
);
776 vnThreadsRunning
[THREAD_SOCKETHANDLER
]--;
777 int nSelect
= select(hSocketMax
+ 1, &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
778 vnThreadsRunning
[THREAD_SOCKETHANDLER
]++;
781 if (nSelect
== SOCKET_ERROR
)
783 int nErr
= WSAGetLastError();
784 if (hSocketMax
!= INVALID_SOCKET
)
786 printf("socket select error %d\n", nErr
);
787 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
788 FD_SET(i
, &fdsetRecv
);
791 FD_ZERO(&fdsetError
);
792 Sleep(timeout
.tv_usec
/1000);
797 // Accept new connections
799 BOOST_FOREACH(SOCKET hListenSocket
, vhListenSocket
)
800 if (hListenSocket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
, &fdsetRecv
))
803 struct sockaddr_storage sockaddr
;
805 struct sockaddr sockaddr
;
807 socklen_t len
= sizeof(sockaddr
);
808 SOCKET hSocket
= accept(hListenSocket
, (struct sockaddr
*)&sockaddr
, &len
);
812 if (hSocket
!= INVALID_SOCKET
)
813 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
814 printf("warning: unknown socket family\n");
818 BOOST_FOREACH(CNode
* pnode
, vNodes
)
823 if (hSocket
== INVALID_SOCKET
)
825 if (WSAGetLastError() != WSAEWOULDBLOCK
)
826 printf("socket error accept failed: %d\n", WSAGetLastError());
828 else if (nInbound
>= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS
)
831 LOCK(cs_setservAddNodeAddresses
);
832 if (!setservAddNodeAddresses
.count(addr
))
833 closesocket(hSocket
);
836 else if (CNode::IsBanned(addr
))
838 printf("connection from %s dropped (banned)\n", addr
.ToString().c_str());
839 closesocket(hSocket
);
843 printf("accepted connection %s\n", addr
.ToString().c_str());
844 CNode
* pnode
= new CNode(hSocket
, addr
, "", true);
848 vNodes
.push_back(pnode
);
855 // Service each socket
857 vector
<CNode
*> vNodesCopy
;
861 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
864 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
872 if (pnode
->hSocket
== INVALID_SOCKET
)
874 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
876 TRY_LOCK(pnode
->cs_vRecv
, lockRecv
);
879 CDataStream
& vRecv
= pnode
->vRecv
;
880 unsigned int nPos
= vRecv
.size();
882 if (nPos
> ReceiveBufferSize()) {
883 if (!pnode
->fDisconnect
)
884 printf("socket recv flood control disconnect (%d bytes)\n", vRecv
.size());
885 pnode
->CloseSocketDisconnect();
888 // typical socket buffer is 8K-64K
889 char pchBuf
[0x10000];
890 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
893 vRecv
.resize(nPos
+ nBytes
);
894 memcpy(&vRecv
[nPos
], pchBuf
, nBytes
);
895 pnode
->nLastRecv
= GetTime();
897 else if (nBytes
== 0)
899 // socket closed gracefully
900 if (!pnode
->fDisconnect
)
901 printf("socket closed\n");
902 pnode
->CloseSocketDisconnect();
907 int nErr
= WSAGetLastError();
908 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
910 if (!pnode
->fDisconnect
)
911 printf("socket recv error %d\n", nErr
);
912 pnode
->CloseSocketDisconnect();
922 if (pnode
->hSocket
== INVALID_SOCKET
)
924 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
926 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
929 CDataStream
& vSend
= pnode
->vSend
;
932 int nBytes
= send(pnode
->hSocket
, &vSend
[0], vSend
.size(), MSG_NOSIGNAL
| MSG_DONTWAIT
);
935 vSend
.erase(vSend
.begin(), vSend
.begin() + nBytes
);
936 pnode
->nLastSend
= GetTime();
941 int nErr
= WSAGetLastError();
942 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
944 printf("socket send error %d\n", nErr
);
945 pnode
->CloseSocketDisconnect();
953 // Inactivity checking
955 if (pnode
->vSend
.empty())
956 pnode
->nLastSendEmpty
= GetTime();
957 if (GetTime() - pnode
->nTimeConnected
> 60)
959 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
961 printf("socket no message in first 60 seconds, %d %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0);
962 pnode
->fDisconnect
= true;
964 else if (GetTime() - pnode
->nLastSend
> 90*60 && GetTime() - pnode
->nLastSendEmpty
> 90*60)
966 printf("socket not sending\n");
967 pnode
->fDisconnect
= true;
969 else if (GetTime() - pnode
->nLastRecv
> 90*60)
971 printf("socket inactivity timeout\n");
972 pnode
->fDisconnect
= true;
978 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
995 void ThreadMapPort(void* parg
)
997 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg
));
999 // Make this thread recognisable as the UPnP thread
1000 RenameThread("bitcoin-UPnP");
1004 vnThreadsRunning
[THREAD_UPNP
]++;
1005 ThreadMapPort2(parg
);
1006 vnThreadsRunning
[THREAD_UPNP
]--;
1008 catch (std::exception
& e
) {
1009 vnThreadsRunning
[THREAD_UPNP
]--;
1010 PrintException(&e
, "ThreadMapPort()");
1012 vnThreadsRunning
[THREAD_UPNP
]--;
1013 PrintException(NULL
, "ThreadMapPort()");
1015 printf("ThreadMapPort exited\n");
1018 void ThreadMapPort2(void* parg
)
1020 printf("ThreadMapPort started\n");
1023 sprintf(port
, "%d", GetListenPort());
1025 const char * multicastif
= 0;
1026 const char * minissdpdpath
= 0;
1027 struct UPNPDev
* devlist
= 0;
1030 #ifndef UPNPDISCOVER_SUCCESS
1032 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1036 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1039 struct UPNPUrls urls
;
1040 struct IGDdatas data
;
1043 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1047 char externalIPAddress
[40];
1048 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1049 if(r
!= UPNPCOMMAND_SUCCESS
)
1050 printf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1053 if(externalIPAddress
[0])
1055 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress
);
1056 AddLocal(CNetAddr(externalIPAddress
), LOCAL_UPNP
);
1059 printf("UPnP: GetExternalIPAddress failed.\n");
1063 string strDesc
= "Bitcoin " + FormatFullVersion();
1064 #ifndef UPNPDISCOVER_SUCCESS
1066 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1067 port
, port
, lanaddr
, strDesc
.c_str(), "TCP", 0);
1070 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1071 port
, port
, lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1074 if(r
!=UPNPCOMMAND_SUCCESS
)
1075 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1076 port
, port
, lanaddr
, r
, strupnperror(r
));
1078 printf("UPnP Port Mapping successful.\n");
1081 if (fShutdown
|| !fUseUPnP
)
1083 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
, "TCP", 0);
1084 printf("UPNP_DeletePortMapping() returned : %d\n", r
);
1085 freeUPNPDevlist(devlist
); devlist
= 0;
1086 FreeUPNPUrls(&urls
);
1089 if (i
% 600 == 0) // Refresh every 20 minutes
1091 #ifndef UPNPDISCOVER_SUCCESS
1093 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1094 port
, port
, lanaddr
, strDesc
.c_str(), "TCP", 0);
1097 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1098 port
, port
, lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1101 if(r
!=UPNPCOMMAND_SUCCESS
)
1102 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1103 port
, port
, lanaddr
, r
, strupnperror(r
));
1105 printf("UPnP Port Mapping successful.\n");;
1111 printf("No valid UPnP IGDs found\n");
1112 freeUPNPDevlist(devlist
); devlist
= 0;
1114 FreeUPNPUrls(&urls
);
1116 if (fShutdown
|| !fUseUPnP
)
1125 if (fUseUPnP
&& vnThreadsRunning
[THREAD_UPNP
] < 1)
1127 if (!CreateThread(ThreadMapPort
, NULL
))
1128 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1134 // Intentionally left blank.
1147 // Each pair gives a source name and a seed name.
1148 // The first name is used as information source for addrman.
1149 // The second name should resolve to a list of seed addresses.
1150 static const char *strDNSSeed
[][2] = {
1151 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1152 {"bluematt.me", "dnsseed.bluematt.me"},
1153 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1154 {"xf2.org", "bitseed.xf2.org"},
1157 void ThreadDNSAddressSeed(void* parg
)
1159 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg
));
1161 // Make this thread recognisable as the DNS seeding thread
1162 RenameThread("bitcoin-dnsseed");
1166 vnThreadsRunning
[THREAD_DNSSEED
]++;
1167 ThreadDNSAddressSeed2(parg
);
1168 vnThreadsRunning
[THREAD_DNSSEED
]--;
1170 catch (std::exception
& e
) {
1171 vnThreadsRunning
[THREAD_DNSSEED
]--;
1172 PrintException(&e
, "ThreadDNSAddressSeed()");
1174 vnThreadsRunning
[THREAD_DNSSEED
]--;
1175 throw; // support pthread_cancel()
1177 printf("ThreadDNSAddressSeed exited\n");
1180 void ThreadDNSAddressSeed2(void* parg
)
1182 printf("ThreadDNSAddressSeed started\n");
1187 printf("Loading addresses from DNS seeds (could take a while)\n");
1189 for (unsigned int seed_idx
= 0; seed_idx
< ARRAYLEN(strDNSSeed
); seed_idx
++) {
1190 if (GetNameProxy()) {
1191 AddOneShot(strDNSSeed
[seed_idx
][1]);
1193 vector
<CNetAddr
> vaddr
;
1194 vector
<CAddress
> vAdd
;
1195 if (LookupHost(strDNSSeed
[seed_idx
][1], vaddr
))
1197 BOOST_FOREACH(CNetAddr
& ip
, vaddr
)
1199 int nOneDay
= 24*3600;
1200 CAddress addr
= CAddress(CService(ip
, GetDefaultPort()));
1201 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1202 vAdd
.push_back(addr
);
1206 addrman
.Add(vAdd
, CNetAddr(strDNSSeed
[seed_idx
][0], true));
1211 printf("%d addresses found from DNS seeds\n", found
);
1225 unsigned int pnSeed
[] =
1227 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1228 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1229 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1230 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1231 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1232 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1233 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1234 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1235 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1236 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1237 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1238 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1239 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1240 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1241 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1242 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1243 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1244 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1245 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1246 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1247 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1248 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1249 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1250 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1251 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1252 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1253 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1254 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1255 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1256 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1257 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1258 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1259 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1260 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1261 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1262 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1263 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1264 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1265 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1266 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1267 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1268 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1269 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1270 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1271 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1272 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1273 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1274 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1275 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1276 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1277 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1278 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1279 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1280 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1281 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1282 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1283 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1284 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1285 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1286 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1287 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1288 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1289 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1290 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1291 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1292 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1293 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1294 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1295 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1296 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1297 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1298 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1299 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1300 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1301 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1302 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1303 0xc461d84a, 0xb2dbe247,
1306 void DumpAddresses()
1308 int64 nStart
= GetTimeMillis();
1313 printf("Flushed %d addresses to peers.dat %"PRI64d
"ms\n",
1314 addrman
.size(), GetTimeMillis() - nStart
);
1317 void ThreadDumpAddress2(void* parg
)
1319 vnThreadsRunning
[THREAD_DUMPADDRESS
]++;
1323 vnThreadsRunning
[THREAD_DUMPADDRESS
]--;
1325 vnThreadsRunning
[THREAD_DUMPADDRESS
]++;
1327 vnThreadsRunning
[THREAD_DUMPADDRESS
]--;
1330 void ThreadDumpAddress(void* parg
)
1332 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg
));
1334 // Make this thread recognisable as the address dumping thread
1335 RenameThread("bitcoin-adrdump");
1339 ThreadDumpAddress2(parg
);
1341 catch (std::exception
& e
) {
1342 PrintException(&e
, "ThreadDumpAddress()");
1344 printf("ThreadDumpAddress exited\n");
1347 void ThreadOpenConnections(void* parg
)
1349 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg
));
1351 // Make this thread recognisable as the connection opening thread
1352 RenameThread("bitcoin-opencon");
1356 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1357 ThreadOpenConnections2(parg
);
1358 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1360 catch (std::exception
& e
) {
1361 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1362 PrintException(&e
, "ThreadOpenConnections()");
1364 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1365 PrintException(NULL
, "ThreadOpenConnections()");
1367 printf("ThreadOpenConnections exited\n");
1370 void static ProcessOneShot()
1375 if (vOneShots
.empty())
1377 strDest
= vOneShots
.front();
1378 vOneShots
.pop_front();
1381 CSemaphoreGrant
grant(*semOutbound
, true);
1383 if (!OpenNetworkConnection(addr
, &grant
, strDest
.c_str(), true))
1384 AddOneShot(strDest
);
1388 void ThreadOpenConnections2(void* parg
)
1390 printf("ThreadOpenConnections started\n");
1392 // Connect to specific addresses
1393 if (mapArgs
.count("-connect"))
1395 for (int64 nLoop
= 0;; nLoop
++)
1398 BOOST_FOREACH(string strAddr
, mapMultiArgs
["-connect"])
1401 OpenNetworkConnection(addr
, NULL
, strAddr
.c_str());
1402 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1412 // Initiate network connections
1413 int64 nStart
= GetTime();
1418 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1420 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1425 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1426 CSemaphoreGrant
grant(*semOutbound
);
1427 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1431 // Add seed nodes if IRC isn't working
1432 if (addrman
.size()==0 && (GetTime() - nStart
> 60) && !fTestNet
)
1434 std::vector
<CAddress
> vAdd
;
1435 for (unsigned int i
= 0; i
< ARRAYLEN(pnSeed
); i
++)
1437 // It'll only connect to one or two seed nodes because once it connects,
1438 // it'll get a pile of addresses with newer timestamps.
1439 // Seed nodes are given a random 'last seen time' of between one and two
1441 const int64 nOneWeek
= 7*24*60*60;
1443 memcpy(&ip
, &pnSeed
[i
], sizeof(ip
));
1444 CAddress
addr(CService(ip
, GetDefaultPort()));
1445 addr
.nTime
= GetTime()-GetRand(nOneWeek
)-nOneWeek
;
1446 vAdd
.push_back(addr
);
1448 addrman
.Add(vAdd
, CNetAddr("127.0.0.1"));
1452 // Choose an address to connect to based on most recently seen
1454 CAddress addrConnect
;
1456 // Only connect out to one peer per network group (/16 for IPv4).
1457 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1459 set
<vector
<unsigned char> > setConnected
;
1462 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1463 if (!pnode
->fInbound
) {
1464 setConnected
.insert(pnode
->addr
.GetGroup());
1470 int64 nANow
= GetAdjustedTime();
1475 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1476 CAddress addr
= addrman
.Select(10 + min(nOutbound
,8)*10);
1478 // if we selected an invalid address, restart
1479 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1484 if (IsLimited(addr
))
1487 // only consider very recently tried nodes after 30 failed attempts
1488 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1491 // do not allow non-default ports, unless after 50 invalid addresses selected already
1492 if (addr
.GetPort() != GetDefaultPort() && nTries
< 50)
1499 if (addrConnect
.IsValid())
1500 OpenNetworkConnection(addrConnect
, &grant
);
1504 void ThreadOpenAddedConnections(void* parg
)
1506 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg
));
1508 // Make this thread recognisable as the connection opening thread
1509 RenameThread("bitcoin-opencon");
1513 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]++;
1514 ThreadOpenAddedConnections2(parg
);
1515 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1517 catch (std::exception
& e
) {
1518 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1519 PrintException(&e
, "ThreadOpenAddedConnections()");
1521 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1522 PrintException(NULL
, "ThreadOpenAddedConnections()");
1524 printf("ThreadOpenAddedConnections exited\n");
1527 void ThreadOpenAddedConnections2(void* parg
)
1529 printf("ThreadOpenAddedConnections started\n");
1531 if (mapArgs
.count("-addnode") == 0)
1534 if (GetNameProxy()) {
1536 BOOST_FOREACH(string
& strAddNode
, mapMultiArgs
["-addnode"]) {
1538 CSemaphoreGrant
grant(*semOutbound
);
1539 OpenNetworkConnection(addr
, &grant
, strAddNode
.c_str());
1542 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1543 Sleep(120000); // Retry every 2 minutes
1544 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]++;
1549 vector
<vector
<CService
> > vservAddressesToAdd(0);
1550 BOOST_FOREACH(string
& strAddNode
, mapMultiArgs
["-addnode"])
1552 vector
<CService
> vservNode(0);
1553 if(Lookup(strAddNode
.c_str(), vservNode
, GetDefaultPort(), fNameLookup
, 0))
1555 vservAddressesToAdd
.push_back(vservNode
);
1557 LOCK(cs_setservAddNodeAddresses
);
1558 BOOST_FOREACH(CService
& serv
, vservNode
)
1559 setservAddNodeAddresses
.insert(serv
);
1565 vector
<vector
<CService
> > vservConnectAddresses
= vservAddressesToAdd
;
1566 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1567 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1570 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1571 for (vector
<vector
<CService
> >::iterator it
= vservConnectAddresses
.begin(); it
!= vservConnectAddresses
.end(); it
++)
1572 BOOST_FOREACH(CService
& addrNode
, *(it
))
1573 if (pnode
->addr
== addrNode
)
1575 it
= vservConnectAddresses
.erase(it
);
1580 BOOST_FOREACH(vector
<CService
>& vserv
, vservConnectAddresses
)
1582 CSemaphoreGrant
grant(*semOutbound
);
1583 OpenNetworkConnection(CAddress(*(vserv
.begin())), &grant
);
1590 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]--;
1591 Sleep(120000); // Retry every 2 minutes
1592 vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
]++;
1598 // if succesful, this moves the passed grant to the constructed node
1599 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
, const char *strDest
, bool fOneShot
)
1602 // Initiate outbound network connection
1607 if (IsLocal(addrConnect
) ||
1608 FindNode((CNetAddr
)addrConnect
) || CNode::IsBanned(addrConnect
) ||
1609 FindNode(addrConnect
.ToStringIPPort().c_str()))
1611 if (strDest
&& FindNode(strDest
))
1614 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]--;
1615 CNode
* pnode
= ConnectNode(addrConnect
, strDest
);
1616 vnThreadsRunning
[THREAD_OPENCONNECTIONS
]++;
1622 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1623 pnode
->fNetworkNode
= true;
1625 pnode
->fOneShot
= true;
1637 void ThreadMessageHandler(void* parg
)
1639 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg
));
1641 // Make this thread recognisable as the message handling thread
1642 RenameThread("bitcoin-msghand");
1646 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]++;
1647 ThreadMessageHandler2(parg
);
1648 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1650 catch (std::exception
& e
) {
1651 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1652 PrintException(&e
, "ThreadMessageHandler()");
1654 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1655 PrintException(NULL
, "ThreadMessageHandler()");
1657 printf("ThreadMessageHandler exited\n");
1660 void ThreadMessageHandler2(void* parg
)
1662 printf("ThreadMessageHandler started\n");
1663 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1666 vector
<CNode
*> vNodesCopy
;
1669 vNodesCopy
= vNodes
;
1670 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1674 // Poll the connected nodes for messages
1675 CNode
* pnodeTrickle
= NULL
;
1676 if (!vNodesCopy
.empty())
1677 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1678 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1682 TRY_LOCK(pnode
->cs_vRecv
, lockRecv
);
1684 ProcessMessages(pnode
);
1691 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1693 SendMessages(pnode
, pnode
== pnodeTrickle
);
1701 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1705 // Wait and allow messages to bunch up.
1706 // Reduce vnThreadsRunning so StopNode has permission to exit while
1707 // we're sleeping, but we must always check fShutdown after doing this.
1708 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]--;
1710 if (fRequestShutdown
)
1712 vnThreadsRunning
[THREAD_MESSAGEHANDLER
]++;
1723 bool BindListenPort(const CService
&addrBind
, string
& strError
)
1729 // Initialize Windows Sockets
1731 int ret
= WSAStartup(MAKEWORD(2,2), &wsadata
);
1732 if (ret
!= NO_ERROR
)
1734 strError
= strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret
);
1735 printf("%s\n", strError
.c_str());
1740 // Create socket for listening for incoming connections
1742 struct sockaddr_storage sockaddr
;
1744 struct sockaddr sockaddr
;
1746 socklen_t len
= sizeof(sockaddr
);
1747 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1749 strError
= strprintf("Error: bind address family for %s not supported", addrBind
.ToString().c_str());
1750 printf("%s\n", strError
.c_str());
1754 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1755 if (hListenSocket
== INVALID_SOCKET
)
1757 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1758 printf("%s\n", strError
.c_str());
1763 // Different way of disabling SIGPIPE on BSD
1764 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1768 // Allow binding if the port is still in TIME_WAIT state after
1769 // the program was closed and restarted. Not an issue on windows.
1770 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1775 // Set to nonblocking, incoming connections will also inherit this
1776 if (ioctlsocket(hListenSocket
, FIONBIO
, (u_long
*)&nOne
) == SOCKET_ERROR
)
1778 if (fcntl(hListenSocket
, F_SETFL
, O_NONBLOCK
) == SOCKET_ERROR
)
1781 strError
= strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1782 printf("%s\n", strError
.c_str());
1787 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1788 // and enable it by default or not. Try to enable it, if possible.
1789 if (addrBind
.IsIPv6()) {
1791 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1794 int nProtLevel
= 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1795 int nParameterId
= 23 /* IPV6_PROTECTION_LEVEl */;
1796 // this call is allowed to fail
1797 setsockopt(hListenSocket
, IPPROTO_IPV6
, nParameterId
, (const char*)&nProtLevel
, sizeof(int));
1802 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1804 int nErr
= WSAGetLastError();
1805 if (nErr
== WSAEADDRINUSE
)
1806 strError
= strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind
.ToString().c_str());
1808 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind
.ToString().c_str(), nErr
, strerror(nErr
));
1809 printf("%s\n", strError
.c_str());
1812 printf("Bound to %s\n", addrBind
.ToString().c_str());
1814 // Listen for incoming connections
1815 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1817 strError
= strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1818 printf("%s\n", strError
.c_str());
1822 vhListenSocket
.push_back(hListenSocket
);
1824 if (addrBind
.IsRoutable() && fDiscover
)
1825 AddLocal(addrBind
, LOCAL_BIND
);
1830 void static Discover()
1836 // Get local host ip
1837 char pszHostName
[1000] = "";
1838 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1840 vector
<CNetAddr
> vaddr
;
1841 if (LookupHost(pszHostName
, vaddr
))
1843 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1845 AddLocal(addr
, LOCAL_IF
);
1850 // Get local host ip
1851 struct ifaddrs
* myaddrs
;
1852 if (getifaddrs(&myaddrs
) == 0)
1854 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1856 if (ifa
->ifa_addr
== NULL
) continue;
1857 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1858 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1859 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1860 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1862 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1863 CNetAddr
addr(s4
->sin_addr
);
1864 if (AddLocal(addr
, LOCAL_IF
))
1865 printf("IPv4 %s: %s\n", ifa
->ifa_name
, addr
.ToString().c_str());
1868 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1870 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1871 CNetAddr
addr(s6
->sin6_addr
);
1872 if (AddLocal(addr
, LOCAL_IF
))
1873 printf("IPv6 %s: %s\n", ifa
->ifa_name
, addr
.ToString().c_str());
1877 freeifaddrs(myaddrs
);
1881 CreateThread(ThreadGetMyExternalIP
, NULL
);
1884 void StartNode(void* parg
)
1886 // Make this thread recognisable as the startup thread
1887 RenameThread("bitcoin-start");
1889 if (semOutbound
== NULL
) {
1890 // initialize semaphore
1891 int nMaxOutbound
= min(MAX_OUTBOUND_CONNECTIONS
, (int)GetArg("-maxconnections", 125));
1892 semOutbound
= new CSemaphore(nMaxOutbound
);
1895 if (pnodeLocalHost
== NULL
)
1896 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress(CService("127.0.0.1", 0), nLocalServices
));
1904 if (!GetBoolArg("-dnsseed", true))
1905 printf("DNS seeding disabled\n");
1907 if (!CreateThread(ThreadDNSAddressSeed
, NULL
))
1908 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1910 // Map ports with UPnP
1914 // Get addresses from IRC and advertise ours
1915 if (!CreateThread(ThreadIRCSeed
, NULL
))
1916 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1918 // Send and receive from sockets, accept connections
1919 if (!CreateThread(ThreadSocketHandler
, NULL
))
1920 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1922 // Initiate outbound connections from -addnode
1923 if (!CreateThread(ThreadOpenAddedConnections
, NULL
))
1924 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1926 // Initiate outbound connections
1927 if (!CreateThread(ThreadOpenConnections
, NULL
))
1928 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1931 if (!CreateThread(ThreadMessageHandler
, NULL
))
1932 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1934 // Dump network addresses
1935 if (!CreateThread(ThreadDumpAddress
, NULL
))
1936 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1938 // Generate coins in the background
1939 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain
);
1944 printf("StopNode()\n");
1946 nTransactionsUpdated
++;
1947 int64 nStart
= GetTime();
1949 for (int i
=0; i
<MAX_OUTBOUND_CONNECTIONS
; i
++)
1950 semOutbound
->post();
1953 int nThreadsRunning
= 0;
1954 for (int n
= 0; n
< THREAD_MAX
; n
++)
1955 nThreadsRunning
+= vnThreadsRunning
[n
];
1956 if (nThreadsRunning
== 0)
1958 if (GetTime() - nStart
> 20)
1962 if (vnThreadsRunning
[THREAD_SOCKETHANDLER
] > 0) printf("ThreadSocketHandler still running\n");
1963 if (vnThreadsRunning
[THREAD_OPENCONNECTIONS
] > 0) printf("ThreadOpenConnections still running\n");
1964 if (vnThreadsRunning
[THREAD_MESSAGEHANDLER
] > 0) printf("ThreadMessageHandler still running\n");
1965 if (vnThreadsRunning
[THREAD_MINER
] > 0) printf("ThreadBitcoinMiner still running\n");
1966 if (vnThreadsRunning
[THREAD_RPCLISTENER
] > 0) printf("ThreadRPCListener still running\n");
1967 if (vnThreadsRunning
[THREAD_RPCHANDLER
] > 0) printf("ThreadsRPCServer still running\n");
1969 if (vnThreadsRunning
[THREAD_UPNP
] > 0) printf("ThreadMapPort still running\n");
1971 if (vnThreadsRunning
[THREAD_DNSSEED
] > 0) printf("ThreadDNSAddressSeed still running\n");
1972 if (vnThreadsRunning
[THREAD_ADDEDCONNECTIONS
] > 0) printf("ThreadOpenAddedConnections still running\n");
1973 if (vnThreadsRunning
[THREAD_DUMPADDRESS
] > 0) printf("ThreadDumpAddresses still running\n");
1974 while (vnThreadsRunning
[THREAD_MESSAGEHANDLER
] > 0 || vnThreadsRunning
[THREAD_RPCHANDLER
] > 0)
1990 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1991 if (pnode
->hSocket
!= INVALID_SOCKET
)
1992 closesocket(pnode
->hSocket
);
1993 BOOST_FOREACH(SOCKET hListenSocket
, vhListenSocket
)
1994 if (hListenSocket
!= INVALID_SOCKET
)
1995 if (closesocket(hListenSocket
) == SOCKET_ERROR
)
1996 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1999 // Shutdown Windows Sockets
2004 instance_of_cnetcleanup
;