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.
11 extern int nBestHeight
;
15 inline unsigned short GetDefaultPort() { return fTestNet
? htons(18333) : htons(8333); }
16 static const unsigned int PUBLISH_HOPS
= 5;
19 NODE_NETWORK
= (1 << 0),
25 bool ConnectSocket(const CAddress
& addrConnect
, SOCKET
& hSocketRet
);
26 bool GetMyExternalIP(unsigned int& ipRet
);
27 bool AddAddress(CAddress addr
, int64 nTimePenalty
=0);
28 void AddressCurrentlyConnected(const CAddress
& addr
);
29 CNode
* FindNode(unsigned int ip
);
30 CNode
* ConnectNode(CAddress addrConnect
, int64 nTimeout
=0);
31 void AbandonRequests(void (*fn
)(void*, CDataStream
&), void* param1
);
32 bool AnySubscribed(unsigned int nChannel
);
33 bool BindListenPort(string
& strError
=REF(string()));
34 void StartNode(void* parg
);
51 extern char pchMessageStart
[4];
56 enum { COMMAND_SIZE
=12 };
57 char pchMessageStart
[sizeof(::pchMessageStart
)];
58 char pchCommand
[COMMAND_SIZE
];
59 unsigned int nMessageSize
;
60 unsigned int nChecksum
;
64 memcpy(pchMessageStart
, ::pchMessageStart
, sizeof(pchMessageStart
));
65 memset(pchCommand
, 0, sizeof(pchCommand
));
71 CMessageHeader(const char* pszCommand
, unsigned int nMessageSizeIn
)
73 memcpy(pchMessageStart
, ::pchMessageStart
, sizeof(pchMessageStart
));
74 strncpy(pchCommand
, pszCommand
, COMMAND_SIZE
);
75 nMessageSize
= nMessageSizeIn
;
81 READWRITE(FLATDATA(pchMessageStart
));
82 READWRITE(FLATDATA(pchCommand
));
83 READWRITE(nMessageSize
);
90 if (pchCommand
[COMMAND_SIZE
-1] == 0)
91 return string(pchCommand
, pchCommand
+ strlen(pchCommand
));
93 return string(pchCommand
, pchCommand
+ COMMAND_SIZE
);
99 if (memcmp(pchMessageStart
, ::pchMessageStart
, sizeof(pchMessageStart
)) != 0)
102 // Check the command string for errors
103 for (char* p1
= pchCommand
; p1
< pchCommand
+ COMMAND_SIZE
; p1
++)
107 // Must be all zeros after the first zero
108 for (; p1
< pchCommand
+ COMMAND_SIZE
; p1
++)
112 else if (*p1
< ' ' || *p1
> 0x7E)
117 if (nMessageSize
> MAX_SIZE
)
119 printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize
);
132 static const unsigned char pchIPv4
[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
138 unsigned char pchReserved
[12];
142 // disk and network only
146 unsigned int nLastTry
;
153 CAddress(unsigned int ipIn
, unsigned short portIn
=0, uint64 nServicesIn
=NODE_NETWORK
)
157 port
= (portIn
== 0 ? GetDefaultPort() : portIn
);
158 nServices
= nServicesIn
;
161 explicit CAddress(const struct sockaddr_in
& sockaddr
, uint64 nServicesIn
=NODE_NETWORK
)
164 ip
= sockaddr
.sin_addr
.s_addr
;
165 port
= sockaddr
.sin_port
;
166 nServices
= nServicesIn
;
169 explicit CAddress(const char* pszIn
, uint64 nServicesIn
=NODE_NETWORK
)
173 nServices
= nServicesIn
;
176 explicit CAddress(string strIn
, uint64 nServicesIn
=NODE_NETWORK
)
179 SetAddress(strIn
.c_str());
180 nServices
= nServicesIn
;
185 nServices
= NODE_NETWORK
;
186 memcpy(pchReserved
, pchIPv4
, sizeof(pchReserved
));
188 port
= GetDefaultPort();
193 bool SetAddress(const char* pszIn
)
196 port
= GetDefaultPort();
198 strlcpy(psz
, pszIn
, sizeof(psz
));
199 unsigned int a
=0, b
=0, c
=0, d
=0, e
=0;
200 if (sscanf(psz
, "%u.%u.%u.%u:%u", &a
, &b
, &c
, &d
, &e
) < 4)
202 char* pszPort
= strchr(psz
, ':');
206 port
= htons(atoi(pszPort
));
207 if (atoi(pszPort
) < 0 || atoi(pszPort
) > USHRT_MAX
)
208 port
= htons(USHRT_MAX
);
214 bool SetAddress(string strIn
)
216 return SetAddress(strIn
.c_str());
222 const_cast<CAddress
*>(this)->Init();
223 if (nType
& SER_DISK
)
225 if ((nType
& SER_DISK
) || (nVersion
>= 31402 && !(nType
& SER_GETHASH
)))
227 READWRITE(nServices
);
228 READWRITE(FLATDATA(pchReserved
)); // for IPv6
233 friend inline bool operator==(const CAddress
& a
, const CAddress
& b
)
235 return (memcmp(a
.pchReserved
, b
.pchReserved
, sizeof(a
.pchReserved
)) == 0 &&
240 friend inline bool operator!=(const CAddress
& a
, const CAddress
& b
)
245 friend inline bool operator<(const CAddress
& a
, const CAddress
& b
)
247 int ret
= memcmp(a
.pchReserved
, b
.pchReserved
, sizeof(a
.pchReserved
));
252 if (ntohl(a
.ip
) < ntohl(b
.ip
))
254 else if (a
.ip
== b
.ip
)
255 return ntohs(a
.port
) < ntohs(b
.port
);
260 vector
<unsigned char> GetKey() const
264 ss
<< FLATDATA(pchReserved
) << ip
<< port
;
266 #if defined(_MSC_VER) && _MSC_VER < 1300
267 return vector
<unsigned char>((unsigned char*)&ss
.begin()[0], (unsigned char*)&ss
.end()[0]);
269 return vector
<unsigned char>(ss
.begin(), ss
.end());
273 struct sockaddr_in
GetSockAddr() const
275 struct sockaddr_in sockaddr
;
276 memset(&sockaddr
, 0, sizeof(sockaddr
));
277 sockaddr
.sin_family
= AF_INET
;
278 sockaddr
.sin_addr
.s_addr
= ip
;
279 sockaddr
.sin_port
= port
;
285 return (memcmp(pchReserved
, pchIPv4
, sizeof(pchIPv4
)) == 0);
288 bool IsRoutable() const
291 !(GetByte(3) == 10 ||
292 (GetByte(3) == 192 && GetByte(2) == 168) ||
299 // Clean up 3-byte shifted addresses caused by garbage in size field
300 // of addr messages from versions before 0.2.9 checksum.
301 // Two consecutive addr messages look like this:
302 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
303 // so if the first length field is garbled, it reads the second batch
304 // of addr misaligned by 3 bytes.
305 if (memcmp(pchReserved
, pchIPv4
+3, sizeof(pchIPv4
)-3) == 0)
308 return (ip
!= 0 && ip
!= INADDR_NONE
&& port
!= htons(USHRT_MAX
));
311 unsigned char GetByte(int n
) const
313 return ((unsigned char*)&ip
)[3-n
];
316 string
ToStringIPPort() const
318 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port
));
321 string
ToStringIP() const
323 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
326 string
ToStringPort() const
328 return strprintf("%u", ntohs(port
));
331 string
ToStringLog() const
336 string
ToString() const
338 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port
));
343 printf("CAddress(%s)\n", ToString().c_str());
359 static const char* ppszTypeName
[] =
378 CInv(int typeIn
, const uint256
& hashIn
)
384 CInv(const string
& strType
, const uint256
& hashIn
)
387 for (i
= 1; i
< ARRAYLEN(ppszTypeName
); i
++)
389 if (strType
== ppszTypeName
[i
])
395 if (i
== ARRAYLEN(ppszTypeName
))
396 throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType
.c_str()));
406 friend inline bool operator<(const CInv
& a
, const CInv
& b
)
408 return (a
.type
< b
.type
|| (a
.type
== b
.type
&& a
.hash
< b
.hash
));
411 bool IsKnownType() const
413 return (type
>= 1 && type
< ARRAYLEN(ppszTypeName
));
416 const char* GetCommand() const
419 throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type
));
420 return ppszTypeName
[type
];
423 string
ToString() const
425 return strprintf("%s %s", GetCommand(), hash
.ToString().substr(0,20).c_str());
430 printf("CInv(%s)\n", ToString().c_str());
438 class CRequestTracker
441 void (*fn
)(void*, CDataStream
&);
444 explicit CRequestTracker(void (*fnIn
)(void*, CDataStream
&)=NULL
, void* param1In
=NULL
)
461 extern uint64 nLocalServices
;
462 extern CAddress addrLocalHost
;
463 extern CNode
* pnodeLocalHost
;
464 extern uint64 nLocalHostNonce
;
465 extern array
<int, 10> vnThreadsRunning
;
466 extern SOCKET hListenSocket
;
468 extern vector
<CNode
*> vNodes
;
469 extern CCriticalSection cs_vNodes
;
470 extern map
<vector
<unsigned char>, CAddress
> mapAddresses
;
471 extern CCriticalSection cs_mapAddresses
;
472 extern map
<CInv
, CDataStream
> mapRelay
;
473 extern deque
<pair
<int64
, CInv
> > vRelayExpiration
;
474 extern CCriticalSection cs_mapRelay
;
475 extern map
<CInv
, int64
> mapAlreadyAskedFor
;
478 extern int fUseProxy
;
479 extern CAddress addrProxy
;
494 CCriticalSection cs_vSend
;
495 CCriticalSection cs_vRecv
;
498 int64 nLastSendEmpty
;
499 int64 nTimeConnected
;
500 unsigned int nHeaderStart
;
501 unsigned int nMessageStart
;
508 bool fSuccessfullyConnected
;
514 map
<uint256
, CRequestTracker
> mapRequests
;
515 CCriticalSection cs_mapRequests
;
516 uint256 hashContinue
;
517 CBlockIndex
* pindexLastGetBlocksBegin
;
518 uint256 hashLastGetBlocksEnd
;
522 vector
<CAddress
> vAddrToSend
;
523 set
<CAddress
> setAddrKnown
;
525 set
<uint256
> setKnown
;
527 // inventory based relay
528 set
<CInv
> setInventoryKnown
;
529 vector
<CInv
> vInventoryToSend
;
530 CCriticalSection cs_inventory
;
531 multimap
<int64
, CInv
> mapAskFor
;
533 // publish and subscription
534 vector
<char> vfSubscribe
;
537 CNode(SOCKET hSocketIn
, CAddress addrIn
, bool fInboundIn
=false)
541 vSend
.SetType(SER_NETWORK
);
543 vRecv
.SetType(SER_NETWORK
);
545 // Version 0.2 obsoletes 20 Feb 2012
546 if (GetTime() > 1329696000)
548 vSend
.SetVersion(209);
549 vRecv
.SetVersion(209);
553 nLastSendEmpty
= GetTime();
554 nTimeConnected
= GetTime();
560 fClient
= false; // set by version message
561 fInbound
= fInboundIn
;
562 fNetworkNode
= false;
563 fSuccessfullyConnected
= false;
568 pindexLastGetBlocksBegin
= 0;
569 hashLastGetBlocksEnd
= 0;
570 nStartingHeight
= -1;
572 vfSubscribe
.assign(256, false);
574 // Push a version message
575 /// when NTP implemented, change to just nTime = GetAdjustedTime()
576 int64 nTime
= (fInbound
? GetAdjustedTime() : GetTime());
577 CAddress addrYou
= (fUseProxy
? CAddress("0.0.0.0") : addr
);
578 CAddress addrMe
= (fUseProxy
? CAddress("0.0.0.0") : addrLocalHost
);
579 RAND_bytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
580 PushMessage("version", VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
581 nLocalHostNonce
, string(pszSubVer
), nBestHeight
);
586 if (hSocket
!= INVALID_SOCKET
)
588 closesocket(hSocket
);
589 hSocket
= INVALID_SOCKET
;
595 void operator=(const CNode
&);
601 return max(nRefCount
, 0) + (GetTime() < nReleaseTime
? 1 : 0);
604 CNode
* AddRef(int64 nTimeout
=0)
607 nReleaseTime
= max(nReleaseTime
, GetTime() + nTimeout
);
620 void AddAddressKnown(const CAddress
& addr
)
622 setAddrKnown
.insert(addr
);
625 void PushAddress(const CAddress
& addr
)
627 // Known checking here is only to save space from duplicates.
628 // SendMessages will filter it again for knowns that were added
629 // after addresses were pushed.
630 if (addr
.IsValid() && !setAddrKnown
.count(addr
))
631 vAddrToSend
.push_back(addr
);
635 void AddInventoryKnown(const CInv
& inv
)
637 CRITICAL_BLOCK(cs_inventory
)
638 setInventoryKnown
.insert(inv
);
641 void PushInventory(const CInv
& inv
)
643 CRITICAL_BLOCK(cs_inventory
)
644 if (!setInventoryKnown
.count(inv
))
645 vInventoryToSend
.push_back(inv
);
648 void AskFor(const CInv
& inv
)
650 // We're using mapAskFor as a priority queue,
651 // the key is the earliest time the request can be sent
652 int64
& nRequestTime
= mapAlreadyAskedFor
[inv
];
653 printf("askfor %s %"PRI64d
"\n", inv
.ToString().c_str(), nRequestTime
);
655 // Make sure not to reuse time indexes to keep things in the same order
656 int64 nNow
= (GetTime() - 1) * 1000000;
657 static int64 nLastTime
;
658 nLastTime
= nNow
= max(nNow
, ++nLastTime
);
660 // Each retry is 2 minutes after the last
661 nRequestTime
= max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
662 mapAskFor
.insert(make_pair(nRequestTime
, inv
));
667 void BeginMessage(const char* pszCommand
)
670 if (nHeaderStart
!= -1)
672 nHeaderStart
= vSend
.size();
673 vSend
<< CMessageHeader(pszCommand
, 0);
674 nMessageStart
= vSend
.size();
676 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
677 printf("sending: %s ", pszCommand
);
682 if (nHeaderStart
== -1)
684 vSend
.resize(nHeaderStart
);
688 printf("(aborted)\n");
693 if (mapArgs
.count("-dropmessagestest") && GetRand(atoi(mapArgs
["-dropmessagestest"])) == 0)
695 printf("dropmessages DROPPING SEND MESSAGE\n");
700 if (nHeaderStart
== -1)
704 unsigned int nSize
= vSend
.size() - nMessageStart
;
705 memcpy((char*)&vSend
[nHeaderStart
] + offsetof(CMessageHeader
, nMessageSize
), &nSize
, sizeof(nSize
));
708 if (vSend
.GetVersion() >= 209)
710 uint256 hash
= Hash(vSend
.begin() + nMessageStart
, vSend
.end());
711 unsigned int nChecksum
= 0;
712 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
713 assert(nMessageStart
- nHeaderStart
>= offsetof(CMessageHeader
, nChecksum
) + sizeof(nChecksum
));
714 memcpy((char*)&vSend
[nHeaderStart
] + offsetof(CMessageHeader
, nChecksum
), &nChecksum
, sizeof(nChecksum
));
717 printf("(%d bytes) ", nSize
);
725 void EndMessageAbortIfEmpty()
727 if (nHeaderStart
== -1)
729 int nSize
= vSend
.size() - nMessageStart
;
739 void PushMessage(const char* pszCommand
)
743 BeginMessage(pszCommand
);
753 template<typename T1
>
754 void PushMessage(const char* pszCommand
, const T1
& a1
)
758 BeginMessage(pszCommand
);
769 template<typename T1
, typename T2
>
770 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
)
774 BeginMessage(pszCommand
);
785 template<typename T1
, typename T2
, typename T3
>
786 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
)
790 BeginMessage(pszCommand
);
791 vSend
<< a1
<< a2
<< a3
;
801 template<typename T1
, typename T2
, typename T3
, typename T4
>
802 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
)
806 BeginMessage(pszCommand
);
807 vSend
<< a1
<< a2
<< a3
<< a4
;
817 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
>
818 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
)
822 BeginMessage(pszCommand
);
823 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
;
833 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
>
834 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
, const T6
& a6
)
838 BeginMessage(pszCommand
);
839 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
;
849 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
, typename T7
>
850 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
, const T6
& a6
, const T7
& a7
)
854 BeginMessage(pszCommand
);
855 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
<< a7
;
865 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
, typename T7
, typename T8
>
866 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
, const T6
& a6
, const T7
& a7
, const T8
& a8
)
870 BeginMessage(pszCommand
);
871 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
<< a7
<< a8
;
881 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
, typename T7
, typename T8
, typename T9
>
882 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
, const T6
& a6
, const T7
& a7
, const T8
& a8
, const T9
& a9
)
886 BeginMessage(pszCommand
);
887 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
<< a7
<< a8
<< a9
;
898 void PushRequest(const char* pszCommand
,
899 void (*fn
)(void*, CDataStream
&), void* param1
)
902 RAND_bytes((unsigned char*)&hashReply
, sizeof(hashReply
));
904 CRITICAL_BLOCK(cs_mapRequests
)
905 mapRequests
[hashReply
] = CRequestTracker(fn
, param1
);
907 PushMessage(pszCommand
, hashReply
);
910 template<typename T1
>
911 void PushRequest(const char* pszCommand
, const T1
& a1
,
912 void (*fn
)(void*, CDataStream
&), void* param1
)
915 RAND_bytes((unsigned char*)&hashReply
, sizeof(hashReply
));
917 CRITICAL_BLOCK(cs_mapRequests
)
918 mapRequests
[hashReply
] = CRequestTracker(fn
, param1
);
920 PushMessage(pszCommand
, hashReply
, a1
);
923 template<typename T1
, typename T2
>
924 void PushRequest(const char* pszCommand
, const T1
& a1
, const T2
& a2
,
925 void (*fn
)(void*, CDataStream
&), void* param1
)
928 RAND_bytes((unsigned char*)&hashReply
, sizeof(hashReply
));
930 CRITICAL_BLOCK(cs_mapRequests
)
931 mapRequests
[hashReply
] = CRequestTracker(fn
, param1
);
933 PushMessage(pszCommand
, hashReply
, a1
, a2
);
938 void PushGetBlocks(CBlockIndex
* pindexBegin
, uint256 hashEnd
);
939 bool IsSubscribed(unsigned int nChannel
);
940 void Subscribe(unsigned int nChannel
, unsigned int nHops
=0);
941 void CancelSubscribe(unsigned int nChannel
);
942 void CloseSocketDisconnect();
955 inline void RelayInventory(const CInv
& inv
)
957 // Put on lists to offer to the other nodes
958 CRITICAL_BLOCK(cs_vNodes
)
959 foreach(CNode
* pnode
, vNodes
)
960 pnode
->PushInventory(inv
);
964 void RelayMessage(const CInv
& inv
, const T
& a
)
966 CDataStream
ss(SER_NETWORK
);
969 RelayMessage(inv
, ss
);
973 inline void RelayMessage
<>(const CInv
& inv
, const CDataStream
& ss
)
975 CRITICAL_BLOCK(cs_mapRelay
)
977 // Expire old relay messages
978 while (!vRelayExpiration
.empty() && vRelayExpiration
.front().first
< GetTime())
980 mapRelay
.erase(vRelayExpiration
.front().second
);
981 vRelayExpiration
.pop_front();
984 // Save original serialized message so newer versions are preserved
986 vRelayExpiration
.push_back(make_pair(GetTime() + 15 * 60, inv
));
1000 // Templates for the publish and subscription system.
1001 // The object being published as T& obj needs to have:
1002 // a set<unsigned int> setSources member
1003 // specializations of AdvertInsert and AdvertErase
1004 // Currently implemented for CTable and CProduct.
1007 template<typename T
>
1008 void AdvertStartPublish(CNode
* pfrom
, unsigned int nChannel
, unsigned int nHops
, T
& obj
)
1011 obj
.setSources
.insert(pfrom
->addr
.ip
);
1013 if (!AdvertInsert(obj
))
1017 CRITICAL_BLOCK(cs_vNodes
)
1018 foreach(CNode
* pnode
, vNodes
)
1019 if (pnode
!= pfrom
&& (nHops
< PUBLISH_HOPS
|| pnode
->IsSubscribed(nChannel
)))
1020 pnode
->PushMessage("publish", nChannel
, nHops
, obj
);
1023 template<typename T
>
1024 void AdvertStopPublish(CNode
* pfrom
, unsigned int nChannel
, unsigned int nHops
, T
& obj
)
1026 uint256 hash
= obj
.GetHash();
1028 CRITICAL_BLOCK(cs_vNodes
)
1029 foreach(CNode
* pnode
, vNodes
)
1030 if (pnode
!= pfrom
&& (nHops
< PUBLISH_HOPS
|| pnode
->IsSubscribed(nChannel
)))
1031 pnode
->PushMessage("pub-cancel", nChannel
, nHops
, hash
);
1036 template<typename T
>
1037 void AdvertRemoveSource(CNode
* pfrom
, unsigned int nChannel
, unsigned int nHops
, T
& obj
)
1040 obj
.setSources
.erase(pfrom
->addr
.ip
);
1042 // If no longer supported by any sources, cancel it
1043 if (obj
.setSources
.empty())
1044 AdvertStopPublish(pfrom
, nChannel
, nHops
, obj
);