1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
7 static const int MAX_OUTBOUND_CONNECTIONS
= 8;
9 void ThreadMessageHandler2(void* parg
);
10 void ThreadSocketHandler2(void* parg
);
11 void ThreadOpenConnections2(void* parg
);
12 bool OpenNetworkConnection(const CAddress
& addrConnect
);
19 // Global state variables
22 uint64 nLocalServices
= (fClient
? 0 : NODE_NETWORK
);
23 CAddress
addrLocalHost(0, DEFAULT_PORT
, nLocalServices
);
24 CNode
* pnodeLocalHost
= NULL
;
25 uint64 nLocalHostNonce
= 0;
26 array
<int, 10> vnThreadsRunning
;
27 SOCKET hListenSocket
= INVALID_SOCKET
;
29 vector
<CNode
*> vNodes
;
30 CCriticalSection cs_vNodes
;
31 map
<vector
<unsigned char>, CAddress
> mapAddresses
;
32 CCriticalSection cs_mapAddresses
;
33 map
<CInv
, CDataStream
> mapRelay
;
34 deque
<pair
<int64
, CInv
> > vRelayExpiration
;
35 CCriticalSection cs_mapRelay
;
36 map
<CInv
, int64
> mapAlreadyAskedFor
;
39 int fUseProxy
= false;
40 CAddress
addrProxy("127.0.0.1:9050");
46 void CNode::PushGetBlocks(CBlockIndex
* pindexBegin
, uint256 hashEnd
)
48 // Filter out duplicate requests
49 if (pindexBegin
== pindexLastGetBlocksBegin
&& hashEnd
== hashLastGetBlocksEnd
)
51 pindexLastGetBlocksBegin
= pindexBegin
;
52 hashLastGetBlocksEnd
= hashEnd
;
54 PushMessage("getblocks", CBlockLocator(pindexBegin
), hashEnd
);
61 bool ConnectSocket(const CAddress
& addrConnect
, SOCKET
& hSocketRet
)
63 hSocketRet
= INVALID_SOCKET
;
65 SOCKET hSocket
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
66 if (hSocket
== INVALID_SOCKET
)
70 setsockopt(hSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&set
, sizeof(int));
73 bool fRoutable
= !(addrConnect
.GetByte(3) == 10 || (addrConnect
.GetByte(3) == 192 && addrConnect
.GetByte(2) == 168));
74 bool fProxy
= (fUseProxy
&& fRoutable
);
75 struct sockaddr_in sockaddr
= (fProxy
? addrProxy
.GetSockAddr() : addrConnect
.GetSockAddr());
77 if (connect(hSocket
, (struct sockaddr
*)&sockaddr
, sizeof(sockaddr
)) == SOCKET_ERROR
)
85 printf("proxy connecting %s\n", addrConnect
.ToStringLog().c_str());
86 char pszSocks4IP
[] = "\4\1\0\0\0\0\0\0user";
87 memcpy(pszSocks4IP
+ 2, &addrConnect
.port
, 2);
88 memcpy(pszSocks4IP
+ 4, &addrConnect
.ip
, 4);
89 char* pszSocks4
= pszSocks4IP
;
90 int nSize
= sizeof(pszSocks4IP
);
92 int ret
= send(hSocket
, pszSocks4
, nSize
, MSG_NOSIGNAL
);
96 return error("Error sending to proxy");
99 if (recv(hSocket
, pchRet
, 8, 0) != 8)
101 closesocket(hSocket
);
102 return error("Error reading proxy response");
104 if (pchRet
[1] != 0x5a)
106 closesocket(hSocket
);
107 if (pchRet
[1] != 0x5b)
108 printf("ERROR: Proxy returned error %d\n", pchRet
[1]);
111 printf("proxy connected %s\n", addrConnect
.ToStringLog().c_str());
114 hSocketRet
= hSocket
;
120 bool GetMyExternalIP2(const CAddress
& addrConnect
, const char* pszGet
, const char* pszKeyword
, unsigned int& ipRet
)
123 if (!ConnectSocket(addrConnect
, hSocket
))
124 return error("GetMyExternalIP() : connection to %s failed", addrConnect
.ToString().c_str());
126 send(hSocket
, pszGet
, strlen(pszGet
), MSG_NOSIGNAL
);
129 while (RecvLine(hSocket
, strLine
))
135 if (!RecvLine(hSocket
, strLine
))
137 closesocket(hSocket
);
140 if (strLine
.find(pszKeyword
) != -1)
142 strLine
= strLine
.substr(strLine
.find(pszKeyword
) + strlen(pszKeyword
));
146 closesocket(hSocket
);
147 if (strLine
.find("<"))
148 strLine
= strLine
.substr(0, strLine
.find("<"));
149 strLine
= strLine
.substr(strspn(strLine
.c_str(), " \t\n\r"));
150 while (strLine
.size() > 0 && isspace(strLine
[strLine
.size()-1]))
151 strLine
.resize(strLine
.size()-1);
152 CAddress
addr(strLine
.c_str());
153 printf("GetMyExternalIP() received [%s] %s\n", strLine
.c_str(), addr
.ToString().c_str());
154 if (addr
.ip
== 0 || addr
.ip
== INADDR_NONE
|| !addr
.IsRoutable())
160 closesocket(hSocket
);
161 return error("GetMyExternalIP() : connection closed");
165 bool GetMyExternalIP(unsigned int& ipRet
)
167 CAddress addrConnect
;
169 const char* pszKeyword
;
174 for (int nLookup
= 0; nLookup
<= 1; nLookup
++)
175 for (int nHost
= 1; nHost
<= 2; nHost
++)
179 addrConnect
= CAddress("70.86.96.218:80"); // www.ipaddressworld.com
183 struct hostent
* phostent
= gethostbyname("www.ipaddressworld.com");
184 if (phostent
&& phostent
->h_addr_list
&& phostent
->h_addr_list
[0])
185 addrConnect
= CAddress(*(u_long
*)phostent
->h_addr_list
[0], htons(80));
188 pszGet
= "GET /ip.php HTTP/1.1\r\n"
189 "Host: www.ipaddressworld.com\r\n"
190 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
191 "Connection: close\r\n"
198 addrConnect
= CAddress("208.78.68.70:80"); // checkip.dyndns.org
202 struct hostent
* phostent
= gethostbyname("checkip.dyndns.org");
203 if (phostent
&& phostent
->h_addr_list
&& phostent
->h_addr_list
[0])
204 addrConnect
= CAddress(*(u_long
*)phostent
->h_addr_list
[0], htons(80));
207 pszGet
= "GET / HTTP/1.1\r\n"
208 "Host: checkip.dyndns.org\r\n"
209 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
210 "Connection: close\r\n"
213 pszKeyword
= "Address:";
216 if (GetMyExternalIP2(addrConnect
, pszGet
, pszKeyword
, ipRet
))
227 bool AddAddress(CAddress addr
)
229 if (!addr
.IsRoutable())
231 if (addr
.ip
== addrLocalHost
.ip
)
233 CRITICAL_BLOCK(cs_mapAddresses
)
235 map
<vector
<unsigned char>, CAddress
>::iterator it
= mapAddresses
.find(addr
.GetKey());
236 if (it
== mapAddresses
.end())
239 printf("AddAddress(%s)\n", addr
.ToStringLog().c_str());
240 mapAddresses
.insert(make_pair(addr
.GetKey(), addr
));
241 CAddrDB().WriteAddress(addr
);
246 bool fUpdated
= false;
247 CAddress
& addrFound
= (*it
).second
;
248 if ((addrFound
.nServices
| addr
.nServices
) != addrFound
.nServices
)
250 // Services have been added
251 addrFound
.nServices
|= addr
.nServices
;
254 bool fCurrentlyOnline
= (GetAdjustedTime() - addr
.nTime
< 24 * 60 * 60);
255 int64 nUpdateInterval
= (fCurrentlyOnline
? 60 * 60 : 24 * 60 * 60);
256 if (addrFound
.nTime
< addr
.nTime
- nUpdateInterval
)
258 // Periodically update most recently seen time
259 addrFound
.nTime
= addr
.nTime
;
263 CAddrDB().WriteAddress(addrFound
);
269 void AddressCurrentlyConnected(const CAddress
& addr
)
271 CRITICAL_BLOCK(cs_mapAddresses
)
273 // Only if it's been published already
274 map
<vector
<unsigned char>, CAddress
>::iterator it
= mapAddresses
.find(addr
.GetKey());
275 if (it
!= mapAddresses
.end())
277 CAddress
& addrFound
= (*it
).second
;
278 int64 nUpdateInterval
= 20 * 60;
279 if (addrFound
.nTime
< GetAdjustedTime() - nUpdateInterval
)
281 // Periodically update most recently seen time
282 addrFound
.nTime
= GetAdjustedTime();
284 addrdb
.WriteAddress(addrFound
);
294 void AbandonRequests(void (*fn
)(void*, CDataStream
&), void* param1
)
296 // If the dialog might get closed before the reply comes back,
297 // call this in the destructor so it doesn't get called after it's deleted.
298 CRITICAL_BLOCK(cs_vNodes
)
300 foreach(CNode
* pnode
, vNodes
)
302 CRITICAL_BLOCK(pnode
->cs_mapRequests
)
304 for (map
<uint256
, CRequestTracker
>::iterator mi
= pnode
->mapRequests
.begin(); mi
!= pnode
->mapRequests
.end();)
306 CRequestTracker
& tracker
= (*mi
).second
;
307 if (tracker
.fn
== fn
&& tracker
.param1
== param1
)
308 pnode
->mapRequests
.erase(mi
++);
324 // Subscription methods for the broadcast and subscription system.
325 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
327 // The subscription system uses a meet-in-the-middle strategy.
328 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
329 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
332 bool AnySubscribed(unsigned int nChannel
)
334 if (pnodeLocalHost
->IsSubscribed(nChannel
))
336 CRITICAL_BLOCK(cs_vNodes
)
337 foreach(CNode
* pnode
, vNodes
)
338 if (pnode
->IsSubscribed(nChannel
))
343 bool CNode::IsSubscribed(unsigned int nChannel
)
345 if (nChannel
>= vfSubscribe
.size())
347 return vfSubscribe
[nChannel
];
350 void CNode::Subscribe(unsigned int nChannel
, unsigned int nHops
)
352 if (nChannel
>= vfSubscribe
.size())
355 if (!AnySubscribed(nChannel
))
358 CRITICAL_BLOCK(cs_vNodes
)
359 foreach(CNode
* pnode
, vNodes
)
361 pnode
->PushMessage("subscribe", nChannel
, nHops
);
364 vfSubscribe
[nChannel
] = true;
367 void CNode::CancelSubscribe(unsigned int nChannel
)
369 if (nChannel
>= vfSubscribe
.size())
372 // Prevent from relaying cancel if wasn't subscribed
373 if (!vfSubscribe
[nChannel
])
375 vfSubscribe
[nChannel
] = false;
377 if (!AnySubscribed(nChannel
))
379 // Relay subscription cancel
380 CRITICAL_BLOCK(cs_vNodes
)
381 foreach(CNode
* pnode
, vNodes
)
383 pnode
->PushMessage("sub-cancel", nChannel
);
395 CNode
* FindNode(unsigned int ip
)
397 CRITICAL_BLOCK(cs_vNodes
)
399 foreach(CNode
* pnode
, vNodes
)
400 if (pnode
->addr
.ip
== ip
)
406 CNode
* FindNode(CAddress addr
)
408 CRITICAL_BLOCK(cs_vNodes
)
410 foreach(CNode
* pnode
, vNodes
)
411 if (pnode
->addr
== addr
)
417 CNode
* ConnectNode(CAddress addrConnect
, int64 nTimeout
)
419 if (addrConnect
.ip
== addrLocalHost
.ip
)
422 // Look for an existing connection
423 CNode
* pnode
= FindNode(addrConnect
.ip
);
427 pnode
->AddRef(nTimeout
);
434 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
435 addrConnect
.ToStringLog().c_str(),
436 (double)(addrConnect
.nTime
- GetAdjustedTime())/3600.0,
437 (double)(addrConnect
.nLastTry
- GetAdjustedTime())/3600.0);
439 CRITICAL_BLOCK(cs_mapAddresses
)
440 mapAddresses
[addrConnect
.GetKey()].nLastTry
= GetAdjustedTime();
444 if (ConnectSocket(addrConnect
, hSocket
))
447 printf("connected %s\n", addrConnect
.ToStringLog().c_str());
449 // Set to nonblocking
452 if (ioctlsocket(hSocket
, FIONBIO
, &nOne
) == SOCKET_ERROR
)
453 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
455 if (fcntl(hSocket
, F_SETFL
, O_NONBLOCK
) == SOCKET_ERROR
)
456 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno
);
460 CNode
* pnode
= new CNode(hSocket
, addrConnect
, false);
462 pnode
->AddRef(nTimeout
);
465 CRITICAL_BLOCK(cs_vNodes
)
466 vNodes
.push_back(pnode
);
468 pnode
->nTimeConnected
= GetTime();
477 void CNode::CloseSocketDisconnect()
480 if (hSocket
!= INVALID_SOCKET
)
483 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
484 printf("disconnecting node %s\n", addr
.ToStringLog().c_str());
485 closesocket(hSocket
);
486 hSocket
= INVALID_SOCKET
;
490 void CNode::Cleanup()
492 // All of a nodes broadcasts and subscriptions are automatically torn down
493 // when it goes down, so a node has to stay up to keep its broadcast going.
495 // Cancel subscriptions
496 for (unsigned int nChannel
= 0; nChannel
< vfSubscribe
.size(); nChannel
++)
497 if (vfSubscribe
[nChannel
])
498 CancelSubscribe(nChannel
);
513 void ThreadSocketHandler(void* parg
)
515 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg
));
518 vnThreadsRunning
[0]++;
519 ThreadSocketHandler2(parg
);
520 vnThreadsRunning
[0]--;
522 catch (std::exception
& e
) {
523 vnThreadsRunning
[0]--;
524 PrintException(&e
, "ThreadSocketHandler()");
526 vnThreadsRunning
[0]--;
527 throw; // support pthread_cancel()
529 printf("ThreadSocketHandler exiting\n");
532 void ThreadSocketHandler2(void* parg
)
534 printf("ThreadSocketHandler started\n");
535 list
<CNode
*> vNodesDisconnected
;
536 int nPrevNodeCount
= 0;
543 CRITICAL_BLOCK(cs_vNodes
)
545 // Disconnect unused nodes
546 vector
<CNode
*> vNodesCopy
= vNodes
;
547 foreach(CNode
* pnode
, vNodesCopy
)
549 if (pnode
->fDisconnect
||
550 (pnode
->GetRefCount() <= 0 && pnode
->vRecv
.empty() && pnode
->vSend
.empty()))
552 // remove from vNodes
553 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
555 // close socket and cleanup
556 pnode
->CloseSocketDisconnect();
559 // hold in disconnected pool until all refs are released
560 pnode
->nReleaseTime
= max(pnode
->nReleaseTime
, GetTime() + 15 * 60);
561 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
563 vNodesDisconnected
.push_back(pnode
);
567 // Delete disconnected nodes
568 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
569 foreach(CNode
* pnode
, vNodesDisconnectedCopy
)
571 // wait until threads are done using it
572 if (pnode
->GetRefCount() <= 0)
574 bool fDelete
= false;
575 TRY_CRITICAL_BLOCK(pnode
->cs_vSend
)
576 TRY_CRITICAL_BLOCK(pnode
->cs_vRecv
)
577 TRY_CRITICAL_BLOCK(pnode
->cs_mapRequests
)
578 TRY_CRITICAL_BLOCK(pnode
->cs_inventory
)
582 vNodesDisconnected
.remove(pnode
);
588 if (vNodes
.size() != nPrevNodeCount
)
590 nPrevNodeCount
= vNodes
.size();
596 // Find which sockets have data to receive
598 struct timeval timeout
;
600 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
607 FD_ZERO(&fdsetError
);
608 SOCKET hSocketMax
= 0;
609 FD_SET(hListenSocket
, &fdsetRecv
);
610 hSocketMax
= max(hSocketMax
, hListenSocket
);
611 CRITICAL_BLOCK(cs_vNodes
)
613 foreach(CNode
* pnode
, vNodes
)
615 if (pnode
->hSocket
== INVALID_SOCKET
|| pnode
->hSocket
< 0)
617 FD_SET(pnode
->hSocket
, &fdsetRecv
);
618 FD_SET(pnode
->hSocket
, &fdsetError
);
619 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
620 TRY_CRITICAL_BLOCK(pnode
->cs_vSend
)
621 if (!pnode
->vSend
.empty())
622 FD_SET(pnode
->hSocket
, &fdsetSend
);
626 vnThreadsRunning
[0]--;
627 int nSelect
= select(hSocketMax
+ 1, &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
628 vnThreadsRunning
[0]++;
631 if (nSelect
== SOCKET_ERROR
)
633 int nErr
= WSAGetLastError();
634 printf("socket select error %d\n", nErr
);
635 for (int i
= 0; i
<= hSocketMax
; i
++)
636 FD_SET(i
, &fdsetRecv
);
638 FD_ZERO(&fdsetError
);
639 Sleep(timeout
.tv_usec
/1000);
644 // Accept new connections
646 if (FD_ISSET(hListenSocket
, &fdsetRecv
))
648 struct sockaddr_in sockaddr
;
649 socklen_t len
= sizeof(sockaddr
);
650 SOCKET hSocket
= accept(hListenSocket
, (struct sockaddr
*)&sockaddr
, &len
);
651 CAddress
addr(sockaddr
);
652 if (hSocket
== INVALID_SOCKET
)
654 if (WSAGetLastError() != WSAEWOULDBLOCK
)
655 printf("socket error accept failed: %d\n", WSAGetLastError());
657 else if (mapArgs
.count("-maxconnections") && (int)vNodes
.size() >= atoi(mapArgs
["-maxconnections"]) - MAX_OUTBOUND_CONNECTIONS
)
659 closesocket(hSocket
);
663 printf("accepted connection %s\n", addr
.ToStringLog().c_str());
664 CNode
* pnode
= new CNode(hSocket
, addr
, true);
666 CRITICAL_BLOCK(cs_vNodes
)
667 vNodes
.push_back(pnode
);
673 // Service each socket
675 vector
<CNode
*> vNodesCopy
;
676 CRITICAL_BLOCK(cs_vNodes
)
679 foreach(CNode
* pnode
, vNodesCopy
)
682 foreach(CNode
* pnode
, vNodesCopy
)
690 if (pnode
->hSocket
== INVALID_SOCKET
)
692 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
694 TRY_CRITICAL_BLOCK(pnode
->cs_vRecv
)
696 CDataStream
& vRecv
= pnode
->vRecv
;
697 unsigned int nPos
= vRecv
.size();
699 // typical socket buffer is 8K-64K
700 char pchBuf
[0x10000];
701 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
704 vRecv
.resize(nPos
+ nBytes
);
705 memcpy(&vRecv
[nPos
], pchBuf
, nBytes
);
706 pnode
->nLastRecv
= GetTime();
708 else if (nBytes
== 0)
710 // socket closed gracefully
711 if (!pnode
->fDisconnect
)
712 printf("socket closed\n");
713 pnode
->CloseSocketDisconnect();
718 int nErr
= WSAGetLastError();
719 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
721 if (!pnode
->fDisconnect
)
722 printf("socket recv error %d\n", nErr
);
723 pnode
->CloseSocketDisconnect();
732 if (pnode
->hSocket
== INVALID_SOCKET
)
734 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
736 TRY_CRITICAL_BLOCK(pnode
->cs_vSend
)
738 CDataStream
& vSend
= pnode
->vSend
;
741 int nBytes
= send(pnode
->hSocket
, &vSend
[0], vSend
.size(), MSG_NOSIGNAL
| MSG_DONTWAIT
);
744 vSend
.erase(vSend
.begin(), vSend
.begin() + nBytes
);
745 pnode
->nLastSend
= GetTime();
750 int nErr
= WSAGetLastError();
751 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
753 printf("socket send error %d\n", nErr
);
754 pnode
->CloseSocketDisconnect();
762 // Inactivity checking
764 if (pnode
->vSend
.empty())
765 pnode
->nLastSendEmpty
= GetTime();
766 if (GetTime() - pnode
->nTimeConnected
> 60)
768 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
770 printf("socket no message in first 60 seconds, %d %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0);
771 pnode
->fDisconnect
= true;
773 else if (GetTime() - pnode
->nLastSend
> 90*60 && GetTime() - pnode
->nLastSendEmpty
> 90*60)
775 printf("socket not sending\n");
776 pnode
->fDisconnect
= true;
778 else if (GetTime() - pnode
->nLastRecv
> 90*60)
780 printf("socket inactivity timeout\n");
781 pnode
->fDisconnect
= true;
785 CRITICAL_BLOCK(cs_vNodes
)
787 foreach(CNode
* pnode
, vNodesCopy
)
807 unsigned int pnSeed
[] =
810 0x35218252, 0x9c9c9618, 0xda6bacad, 0xb9aca862, 0x97c235c6,
811 0x146f9562, 0xb67b9e4b, 0x87cf4bc0, 0xb83945d0, 0x984333ad,
812 0xbbeec555, 0x6f0eb440, 0xe0005318, 0x7797e460, 0xddc60fcc,
813 0xb3bbd24a, 0x1ac85746, 0x641846a6, 0x85ee1155, 0xbb2e7a4c,
814 0x9cb8514b, 0xfc342648, 0x62958fae, 0xd0a8c87a, 0xa800795b,
815 0xda8c814e, 0x256a0c80, 0x3f23ec63, 0xd565df43, 0x997d9044,
816 0xaa121448, 0xbed8688e, 0x59d09a5e, 0xb2931243, 0x3730ba18,
817 0xdd3462d0, 0x4e4d1448, 0x171df645, 0x84ee1155,
818 0x248ac445, 0x0e634444, 0x0ded1b63, 0x30c01e60,
819 0xa2b9a094, 0x29e4fd43, 0x9ce61b4c, 0xdae09744,
822 0x5ae6bf43, 0x460be257, 0x7245c0cf, 0x4e0f028d, 0x26501760, 0x38643255, 0x67094f4f, 0x480449b8,
823 0x16545143, 0x1f082e5a, 0xaa428018, 0xe411e793, 0x14c1f862, 0x2726105b, 0x9b33ea50, 0xeeef86ca,
824 0xe3210d44, 0x0dca8b63, 0x3f9dfb18, 0x860340ad, 0xf33ba17a, 0x9018375c, 0x1de4e353, 0x0fa52dcb,
825 0x89c4555b, 0x109cf37b, 0x28c55b40, 0x04c801ae, 0x275c1e80, 0x6f7f745d, 0x7a2a5653, 0xa28e26d8,
826 0xa4e65db2, 0x99a06580, 0xf253ba44, 0x82cf6ab8, 0x859c2e8e, 0xf71a815d, 0xc18f1454, 0x71c8a943,
827 0x90d24e18, 0x311789b2, 0x74aba645, 0xde0bbfc3, 0xad724fad, 0xbf1ae15e, 0xbaa6fb54, 0x06e4d145,
828 0x51528645, 0x72120cd4, 0xd4cfd145, 0x0a7afed8, 0x9b9a5fad, 0x9e9ff45e, 0x10128355, 0xd44e8646,
829 0x04a07b47, 0x5fc9d547, 0xe0491e45, 0xbac21b41, 0x7aa31bae, 0x10483c5f, 0x94a23055, 0x73d9dc47,
830 0x1a99c247, 0x822fe847, 0x7e57ba48, 0xb19ea843, 0xa60621b2, 0x778cf163, 0x125c6556, 0xf94ba44f,
831 0xa61a0948, 0x6c839e4b, 0x29af5348, 0x68d84845, 0x752b95c3, 0xcf0d4663, 0x08e11e56, 0x75109550,
832 0x5f24b94c, 0x42426d4d, 0xfbbc0a4c, 0x70a9a246, 0xda7837cb, 0xae2a986d, 0xe283c358, 0x0c7ca954,
833 0x8e9bde59, 0x61521760, 0x6884444c, 0xa194e548, 0x9b8809cc, 0x16e96a8f, 0x956ff859, 0xfad5e555,
834 0x0ea70c80, 0x5b4ce26d, 0x7984444c, 0x1080d24a, 0x22a686cf, 0x6bf8c2ad, 0xb0f7485f, 0x06b66e56,
835 0x668373bc, 0x75506279, 0x3868694e, 0x12a5954b, 0x3a8b62d1, 0xb74fcbad, 0xa7dc3360, 0xc070b359,
836 0xa2b87242, 0xc45cab7c, 0x69882050, 0x14a5464b, 0x386acad5, 0x80b85db2, 0x1f78a062, 0xc608c55b,
837 0x4257d543, 0x7636ad80, 0x4432d655, 0xb2114d4b, 0x32639bd9, 0xadd75db2, 0x9be5a362, 0x6831bc5e,
838 0xf7f77046, 0x8f35ba81, 0x09bb4e59, 0xd0fb6b4e, 0xc5daa445, 0x9c611618, 0x355dcc62, 0xf2cf435e,
839 0x31e72c46, 0xdd8a43ad, 0x171f9c5b, 0xb4c2e355, 0xbe8af945, 0x613d3942, 0xe6f9e863, 0x7a3d855f,
840 0xa66adc47, 0x261089b2, 0x5a27105b, 0x6c28105b, 0xdd247946, 0xe6c3a445, 0x43a1ec63, 0x99b4dd5f,
841 0xb6834347, 0x5e9649bc, 0xf9dd545d, 0x6ae4c15b, 0xa5318a47, 0x7984ec47, 0x93a73b63, 0x0c60195f,
842 0xa5c85e4b, 0xa0a36dc2, 0x0739a95e, 0x3d44c15b, 0xfb940f4b, 0xd67c9148, 0x614f9876, 0x0a241c5f,
843 0xad9da74c, 0x4459abc8, 0x12e71b5f, 0x1c534a5d, 0x8ff5fc50, 0x2ca8864b, 0xd894fd80, 0x82ab3160,
844 0x390d804e, 0x2cf310cc, 0x680dad80, 0x691be15e, 0x5a8f4652, 0xaad0784d, 0x0d2431ad,
849 void ThreadOpenConnections(void* parg
)
851 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg
));
854 vnThreadsRunning
[1]++;
855 ThreadOpenConnections2(parg
);
856 vnThreadsRunning
[1]--;
858 catch (std::exception
& e
) {
859 vnThreadsRunning
[1]--;
860 PrintException(&e
, "ThreadOpenConnections()");
862 vnThreadsRunning
[1]--;
863 PrintException(NULL
, "ThreadOpenConnections()");
865 printf("ThreadOpenConnections exiting\n");
868 void ThreadOpenConnections2(void* parg
)
870 printf("ThreadOpenConnections started\n");
872 // Connect to specific addresses
873 if (mapArgs
.count("-connect"))
875 for (int64 nLoop
= 0;; nLoop
++)
877 foreach(string strAddr
, mapMultiArgs
["-connect"])
879 CAddress
addr(strAddr
, NODE_NETWORK
);
881 OpenNetworkConnection(addr
);
882 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
892 // Connect to manually added nodes first
893 if (mapArgs
.count("-addnode"))
895 foreach(string strAddr
, mapMultiArgs
["-addnode"])
897 CAddress
addr(strAddr
, NODE_NETWORK
);
900 OpenNetworkConnection(addr
);
908 // Initiate network connections
909 int64 nStart
= GetTime();
912 // Limit outbound connections
913 vnThreadsRunning
[1]--;
918 CRITICAL_BLOCK(cs_vNodes
)
919 foreach(CNode
* pnode
, vNodes
)
920 if (!pnode
->fInbound
)
922 int nMaxOutboundConnections
= MAX_OUTBOUND_CONNECTIONS
;
923 if (mapArgs
.count("-maxconnections"))
924 nMaxOutboundConnections
= min(nMaxOutboundConnections
, atoi(mapArgs
["-maxconnections"]));
925 if (nOutbound
< nMaxOutboundConnections
)
931 vnThreadsRunning
[1]++;
935 CRITICAL_BLOCK(cs_mapAddresses
)
937 // Add seed nodes if IRC isn't working
938 static bool fSeedUsed
;
939 bool fTOR
= (fUseProxy
&& addrProxy
.port
== htons(9050));
940 if (mapAddresses
.empty() && (GetTime() - nStart
> 60 || fTOR
))
942 for (int i
= 0; i
< ARRAYLEN(pnSeed
); i
++)
944 // It'll only connect to one or two seed nodes because once it connects,
945 // it'll get a pile of addresses with newer timestamps.
954 if (fSeedUsed
&& mapAddresses
.size() > ARRAYLEN(pnSeed
) + 100)
956 // Disconnect seed nodes
957 set
<unsigned int> setSeed(pnSeed
, pnSeed
+ ARRAYLEN(pnSeed
));
958 static int64 nSeedDisconnected
;
959 if (nSeedDisconnected
== 0)
961 nSeedDisconnected
= GetTime();
962 CRITICAL_BLOCK(cs_vNodes
)
963 foreach(CNode
* pnode
, vNodes
)
964 if (setSeed
.count(pnode
->addr
.ip
))
965 pnode
->fDisconnect
= true;
968 // Keep setting timestamps to 0 so they won't reconnect
969 if (GetTime() - nSeedDisconnected
< 60 * 60)
971 foreach(PAIRTYPE(const vector
<unsigned char>, CAddress
)& item
, mapAddresses
)
973 if (setSeed
.count(item
.second
.ip
))
975 item
.second
.nTime
= 0;
976 CAddrDB().WriteAddress(item
.second
);
985 // Choose an address to connect to based on most recently seen
987 CAddress addrConnect
;
988 int64 nBest
= INT64_MIN
;
990 // Only connect to one address per a.b.?.? range.
991 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
992 set
<unsigned int> setConnected
;
993 CRITICAL_BLOCK(cs_vNodes
)
994 foreach(CNode
* pnode
, vNodes
)
995 setConnected
.insert(pnode
->addr
.ip
& 0x0000ffff);
997 CRITICAL_BLOCK(cs_mapAddresses
)
999 foreach(const PAIRTYPE(vector
<unsigned char>, CAddress
)& item
, mapAddresses
)
1001 const CAddress
& addr
= item
.second
;
1002 if (!addr
.IsIPv4() || !addr
.IsValid() || setConnected
.count(addr
.ip
& 0x0000ffff))
1004 int64 nSinceLastSeen
= GetAdjustedTime() - addr
.nTime
;
1005 int64 nSinceLastTry
= GetAdjustedTime() - addr
.nLastTry
;
1007 // Randomize the order in a deterministic way, putting the standard port first
1008 int64 nRandomizer
= (uint64
)(nStart
* 4951 + addr
.nLastTry
* 9567851 + addr
.ip
* 7789) % (2 * 60 * 60);
1009 if (addr
.port
!= DEFAULT_PORT
)
1010 nRandomizer
+= 2 * 60 * 60;
1012 // Last seen Base retry frequency
1021 // 365 days 93 hours
1022 int64 nDelay
= (int64
)(3600.0 * sqrt(fabs((double)nSinceLastSeen
) / 3600.0) + nRandomizer
);
1024 // Fast reconnect for one hour after last seen
1025 if (nSinceLastSeen
< 60 * 60)
1028 // Limit retry frequency
1029 if (nSinceLastTry
< nDelay
)
1032 // If we have IRC, we'll be notified when they first come online,
1033 // and again every 24 hours by the refresh broadcast.
1034 if (nGotIRCAddresses
> 0 && vNodes
.size() >= 2 && nSinceLastSeen
> 24 * 60 * 60)
1037 // Only try the old stuff if we don't have enough connections
1038 if (vNodes
.size() >= 8 && nSinceLastSeen
> 24 * 60 * 60)
1041 // If multiple addresses are ready, prioritize by time since
1042 // last seen and time since last tried.
1043 int64 nScore
= min(nSinceLastTry
, (int64
)24 * 60 * 60) - nSinceLastSeen
- nRandomizer
;
1052 if (addrConnect
.IsValid())
1053 OpenNetworkConnection(addrConnect
);
1057 bool OpenNetworkConnection(const CAddress
& addrConnect
)
1060 // Initiate outbound network connection
1064 if (addrConnect
.ip
== addrLocalHost
.ip
|| !addrConnect
.IsIPv4() || FindNode(addrConnect
.ip
))
1067 vnThreadsRunning
[1]--;
1068 CNode
* pnode
= ConnectNode(addrConnect
);
1069 vnThreadsRunning
[1]++;
1074 pnode
->fNetworkNode
= true;
1076 if (addrLocalHost
.IsRoutable() && !fUseProxy
)
1078 // Advertise our address
1079 vector
<CAddress
> vAddr
;
1080 vAddr
.push_back(addrLocalHost
);
1081 pnode
->PushMessage("addr", vAddr
);
1084 // Get as many addresses as we can
1085 pnode
->PushMessage("getaddr");
1086 pnode
->fGetAddr
= true; // don't relay the results of the getaddr
1088 ////// should the one on the receiving end do this too?
1089 // Subscribe our local subscription list
1090 const unsigned int nHops
= 0;
1091 for (unsigned int nChannel
= 0; nChannel
< pnodeLocalHost
->vfSubscribe
.size(); nChannel
++)
1092 if (pnodeLocalHost
->vfSubscribe
[nChannel
])
1093 pnode
->PushMessage("subscribe", nChannel
, nHops
);
1105 void ThreadMessageHandler(void* parg
)
1107 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg
));
1110 vnThreadsRunning
[2]++;
1111 ThreadMessageHandler2(parg
);
1112 vnThreadsRunning
[2]--;
1114 catch (std::exception
& e
) {
1115 vnThreadsRunning
[2]--;
1116 PrintException(&e
, "ThreadMessageHandler()");
1118 vnThreadsRunning
[2]--;
1119 PrintException(NULL
, "ThreadMessageHandler()");
1121 printf("ThreadMessageHandler exiting\n");
1124 void ThreadMessageHandler2(void* parg
)
1126 printf("ThreadMessageHandler started\n");
1127 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1130 vector
<CNode
*> vNodesCopy
;
1131 CRITICAL_BLOCK(cs_vNodes
)
1133 vNodesCopy
= vNodes
;
1134 foreach(CNode
* pnode
, vNodesCopy
)
1138 // Poll the connected nodes for messages
1139 CNode
* pnodeTrickle
= NULL
;
1140 if (!vNodesCopy
.empty())
1141 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1142 foreach(CNode
* pnode
, vNodesCopy
)
1145 TRY_CRITICAL_BLOCK(pnode
->cs_vRecv
)
1146 ProcessMessages(pnode
);
1151 TRY_CRITICAL_BLOCK(pnode
->cs_vSend
)
1152 SendMessages(pnode
, pnode
== pnodeTrickle
);
1157 CRITICAL_BLOCK(cs_vNodes
)
1159 foreach(CNode
* pnode
, vNodesCopy
)
1163 // Wait and allow messages to bunch up.
1164 // Reduce vnThreadsRunning so StopNode has permission to exit while
1165 // we're sleeping, but we must always check fShutdown after doing this.
1166 vnThreadsRunning
[2]--;
1168 if (fRequestShutdown
)
1170 vnThreadsRunning
[2]++;
1184 bool BindListenPort(string
& strError
)
1190 // Initialize Windows Sockets
1192 int ret
= WSAStartup(MAKEWORD(2,2), &wsadata
);
1193 if (ret
!= NO_ERROR
)
1195 strError
= strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret
);
1196 printf("%s\n", strError
.c_str());
1201 // Create socket for listening for incoming connections
1202 hListenSocket
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
1203 if (hListenSocket
== INVALID_SOCKET
)
1205 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1206 printf("%s\n", strError
.c_str());
1211 // Different way of disabling SIGPIPE on BSD
1212 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1216 // Allow binding if the port is still in TIME_WAIT state after
1217 // the program was closed and restarted. Not an issue on windows.
1218 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1222 // Set to nonblocking, incoming connections will also inherit this
1223 if (ioctlsocket(hListenSocket
, FIONBIO
, (u_long
*)&nOne
) == SOCKET_ERROR
)
1225 if (fcntl(hListenSocket
, F_SETFL
, O_NONBLOCK
) == SOCKET_ERROR
)
1228 strError
= strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1229 printf("%s\n", strError
.c_str());
1233 // The sockaddr_in structure specifies the address family,
1234 // IP address, and port for the socket that is being bound
1235 struct sockaddr_in sockaddr
;
1236 memset(&sockaddr
, 0, sizeof(sockaddr
));
1237 sockaddr
.sin_family
= AF_INET
;
1238 sockaddr
.sin_addr
.s_addr
= INADDR_ANY
; // bind to all IPs on this computer
1239 sockaddr
.sin_port
= DEFAULT_PORT
;
1240 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, sizeof(sockaddr
)) == SOCKET_ERROR
)
1242 int nErr
= WSAGetLastError();
1243 if (nErr
== WSAEADDRINUSE
)
1244 strError
= strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr
.sin_port
));
1246 strError
= strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr
.sin_port
), nErr
);
1247 printf("%s\n", strError
.c_str());
1250 printf("Bound to port %d\n", ntohs(sockaddr
.sin_port
));
1252 // Listen for incoming connections
1253 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1255 strError
= strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1256 printf("%s\n", strError
.c_str());
1263 void StartNode(void* parg
)
1265 if (pnodeLocalHost
== NULL
)
1266 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress("127.0.0.1", nLocalServices
));
1269 // Get local host ip
1270 char pszHostName
[1000] = "";
1271 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1273 struct hostent
* phostent
= gethostbyname(pszHostName
);
1276 // Take the first IP that isn't loopback 127.x.x.x
1277 for (int i
= 0; phostent
->h_addr_list
[i
] != NULL
; i
++)
1278 printf("host ip %d: %s\n", i
, CAddress(*(unsigned int*)phostent
->h_addr_list
[i
]).ToStringIP().c_str());
1279 for (int i
= 0; phostent
->h_addr_list
[i
] != NULL
; i
++)
1281 CAddress
addr(*(unsigned int*)phostent
->h_addr_list
[i
], DEFAULT_PORT
, nLocalServices
);
1282 if (addr
.IsValid() && addr
.GetByte(3) != 127)
1284 addrLocalHost
= addr
;
1291 // Get local host ip
1292 struct ifaddrs
* myaddrs
;
1293 if (getifaddrs(&myaddrs
) == 0)
1295 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1297 if (ifa
->ifa_addr
== NULL
) continue;
1298 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1299 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1300 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1302 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1304 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1305 if (inet_ntop(ifa
->ifa_addr
->sa_family
, (void*)&(s4
->sin_addr
), pszIP
, sizeof(pszIP
)) != NULL
)
1306 printf("ipv4 %s: %s\n", ifa
->ifa_name
, pszIP
);
1308 // Take the first IP that isn't loopback 127.x.x.x
1309 CAddress
addr(*(unsigned int*)&s4
->sin_addr
, DEFAULT_PORT
, nLocalServices
);
1310 if (addr
.IsValid() && addr
.GetByte(3) != 127)
1312 addrLocalHost
= addr
;
1316 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1318 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1319 if (inet_ntop(ifa
->ifa_addr
->sa_family
, (void*)&(s6
->sin6_addr
), pszIP
, sizeof(pszIP
)) != NULL
)
1320 printf("ipv6 %s: %s\n", ifa
->ifa_name
, pszIP
);
1323 freeifaddrs(myaddrs
);
1326 printf("addrLocalHost = %s\n", addrLocalHost
.ToString().c_str());
1328 // Get our external IP address for incoming connections
1331 // Proxies can't take incoming connections
1332 addrLocalHost
.ip
= CAddress("0.0.0.0").ip
;
1333 printf("addrLocalHost = %s\n", addrLocalHost
.ToString().c_str());
1337 if (addrIncoming
.IsValid())
1338 addrLocalHost
.ip
= addrIncoming
.ip
;
1340 if (GetMyExternalIP(addrLocalHost
.ip
))
1342 addrIncoming
= addrLocalHost
;
1343 CWalletDB().WriteSetting("addrIncoming", addrIncoming
);
1344 printf("addrLocalHost = %s\n", addrLocalHost
.ToString().c_str());
1352 // Get addresses from IRC and advertise ours
1353 if (!CreateThread(ThreadIRCSeed
, NULL
))
1354 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1356 // Send and receive from sockets, accept connections
1357 pthread_t hThreadSocketHandler
= CreateThread(ThreadSocketHandler
, NULL
, true);
1359 // Initiate outbound connections
1360 if (!CreateThread(ThreadOpenConnections
, NULL
))
1361 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1364 if (!CreateThread(ThreadMessageHandler
, NULL
))
1365 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1367 // Generate coins in the background
1368 GenerateBitcoins(fGenerateBitcoins
);
1373 printf("StopNode()\n");
1375 nTransactionsUpdated
++;
1376 int64 nStart
= GetTime();
1377 while (vnThreadsRunning
[0] > 0 || vnThreadsRunning
[2] > 0 || vnThreadsRunning
[3] > 0 || vnThreadsRunning
[4] > 0)
1379 if (GetTime() - nStart
> 20)
1383 if (vnThreadsRunning
[0] > 0) printf("ThreadSocketHandler still running\n");
1384 if (vnThreadsRunning
[1] > 0) printf("ThreadOpenConnections still running\n");
1385 if (vnThreadsRunning
[2] > 0) printf("ThreadMessageHandler still running\n");
1386 if (vnThreadsRunning
[3] > 0) printf("ThreadBitcoinMiner still running\n");
1387 if (vnThreadsRunning
[4] > 0) printf("ThreadRPCServer still running\n");
1388 while (vnThreadsRunning
[2] > 0 || vnThreadsRunning
[4] > 0)
1404 foreach(CNode
* pnode
, vNodes
)
1405 if (pnode
->hSocket
!= INVALID_SOCKET
)
1406 closesocket(pnode
->hSocket
);
1407 if (hListenSocket
!= INVALID_SOCKET
)
1408 if (closesocket(hListenSocket
) == SOCKET_ERROR
)
1409 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1412 // Shutdown Windows Sockets
1417 instance_of_cnetcleanup
;