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 static const unsigned short DEFAULT_PORT
= 0x8d20; // 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
);
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 // The message start string is designed to be unlikely to occur in normal data.
52 // The characters are rarely used upper ascii, not valid as UTF-8, and produce
53 // a large 4-byte int at any alignment.
54 static const char pchMessageStart
[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
59 enum { COMMAND_SIZE
=12 };
60 char pchMessageStart
[sizeof(::pchMessageStart
)];
61 char pchCommand
[COMMAND_SIZE
];
62 unsigned int nMessageSize
;
63 unsigned int nChecksum
;
67 memcpy(pchMessageStart
, ::pchMessageStart
, sizeof(pchMessageStart
));
68 memset(pchCommand
, 0, sizeof(pchCommand
));
74 CMessageHeader(const char* pszCommand
, unsigned int nMessageSizeIn
)
76 memcpy(pchMessageStart
, ::pchMessageStart
, sizeof(pchMessageStart
));
77 strncpy(pchCommand
, pszCommand
, COMMAND_SIZE
);
78 nMessageSize
= nMessageSizeIn
;
84 READWRITE(FLATDATA(pchMessageStart
));
85 READWRITE(FLATDATA(pchCommand
));
86 READWRITE(nMessageSize
);
93 if (pchCommand
[COMMAND_SIZE
-1] == 0)
94 return string(pchCommand
, pchCommand
+ strlen(pchCommand
));
96 return string(pchCommand
, pchCommand
+ COMMAND_SIZE
);
101 // Check start string
102 if (memcmp(pchMessageStart
, ::pchMessageStart
, sizeof(pchMessageStart
)) != 0)
105 // Check the command string for errors
106 for (char* p1
= pchCommand
; p1
< pchCommand
+ COMMAND_SIZE
; p1
++)
110 // Must be all zeros after the first zero
111 for (; p1
< pchCommand
+ COMMAND_SIZE
; p1
++)
115 else if (*p1
< ' ' || *p1
> 0x7E)
120 if (nMessageSize
> MAX_SIZE
)
122 printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize
);
135 static const unsigned char pchIPv4
[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
141 unsigned char pchReserved
[12];
149 unsigned int nLastTry
;
156 CAddress(unsigned int ipIn
, unsigned short portIn
=DEFAULT_PORT
, uint64 nServicesIn
=NODE_NETWORK
)
161 nServices
= nServicesIn
;
164 explicit CAddress(const struct sockaddr_in
& sockaddr
, uint64 nServicesIn
=NODE_NETWORK
)
167 ip
= sockaddr
.sin_addr
.s_addr
;
168 port
= sockaddr
.sin_port
;
169 nServices
= nServicesIn
;
172 explicit CAddress(const char* pszIn
, uint64 nServicesIn
=NODE_NETWORK
)
176 nServices
= nServicesIn
;
179 explicit CAddress(string strIn
, uint64 nServicesIn
=NODE_NETWORK
)
182 SetAddress(strIn
.c_str());
183 nServices
= nServicesIn
;
188 nServices
= NODE_NETWORK
;
189 memcpy(pchReserved
, pchIPv4
, sizeof(pchReserved
));
192 nTime
= GetAdjustedTime();
196 bool SetAddress(const char* pszIn
)
201 strlcpy(psz
, pszIn
, sizeof(psz
));
202 unsigned int a
=0, b
=0, c
=0, d
=0, e
=0;
203 if (sscanf(psz
, "%u.%u.%u.%u:%u", &a
, &b
, &c
, &d
, &e
) < 4)
205 char* pszPort
= strchr(psz
, ':');
209 port
= htons(atoi(pszPort
));
210 if (atoi(pszPort
) < 0 || atoi(pszPort
) > USHRT_MAX
)
211 port
= htons(USHRT_MAX
);
217 bool SetAddress(string strIn
)
219 return SetAddress(strIn
.c_str());
224 if (nType
& SER_DISK
)
229 READWRITE(nServices
);
230 READWRITE(FLATDATA(pchReserved
)); // for IPv6
235 friend inline bool operator==(const CAddress
& a
, const CAddress
& b
)
237 return (memcmp(a
.pchReserved
, b
.pchReserved
, sizeof(a
.pchReserved
)) == 0 &&
242 friend inline bool operator!=(const CAddress
& a
, const CAddress
& b
)
247 friend inline bool operator<(const CAddress
& a
, const CAddress
& b
)
249 int ret
= memcmp(a
.pchReserved
, b
.pchReserved
, sizeof(a
.pchReserved
));
254 if (ntohl(a
.ip
) < ntohl(b
.ip
))
256 else if (a
.ip
== b
.ip
)
257 return ntohs(a
.port
) < ntohs(b
.port
);
262 vector
<unsigned char> GetKey() const
266 ss
<< FLATDATA(pchReserved
) << ip
<< port
;
268 #if defined(_MSC_VER) && _MSC_VER < 1300
269 return vector
<unsigned char>((unsigned char*)&ss
.begin()[0], (unsigned char*)&ss
.end()[0]);
271 return vector
<unsigned char>(ss
.begin(), ss
.end());
275 struct sockaddr_in
GetSockAddr() const
277 struct sockaddr_in sockaddr
;
278 memset(&sockaddr
, 0, sizeof(sockaddr
));
279 sockaddr
.sin_family
= AF_INET
;
280 sockaddr
.sin_addr
.s_addr
= ip
;
281 sockaddr
.sin_port
= port
;
287 return (memcmp(pchReserved
, pchIPv4
, sizeof(pchIPv4
)) == 0);
290 bool IsRoutable() const
293 !(GetByte(3) == 10 ||
294 (GetByte(3) == 192 && GetByte(2) == 168) ||
301 // Clean up 3-byte shifted addresses caused by garbage in size field
302 // of addr messages from versions before 0.2.9 checksum.
303 // Two consecutive addr messages look like this:
304 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
305 // so if the first length field is garbled, it reads the second batch
306 // of addr misaligned by 3 bytes.
307 if (memcmp(pchReserved
, pchIPv4
+3, sizeof(pchIPv4
)-3) == 0)
310 return (ip
!= 0 && ip
!= INADDR_NONE
&& port
!= htons(USHRT_MAX
));
313 unsigned char GetByte(int n
) const
315 return ((unsigned char*)&ip
)[3-n
];
318 string
ToStringIPPort() const
320 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port
));
323 string
ToStringIP() const
325 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
328 string
ToStringPort() const
330 return strprintf("%u", ntohs(port
));
333 string
ToStringLog() const
338 string
ToString() const
340 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port
));
345 printf("CAddress(%s)\n", ToString().c_str());
361 static const char* ppszTypeName
[] =
380 CInv(int typeIn
, const uint256
& hashIn
)
386 CInv(const string
& strType
, const uint256
& hashIn
)
389 for (i
= 1; i
< ARRAYLEN(ppszTypeName
); i
++)
391 if (strType
== ppszTypeName
[i
])
397 if (i
== ARRAYLEN(ppszTypeName
))
398 throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType
.c_str()));
408 friend inline bool operator<(const CInv
& a
, const CInv
& b
)
410 return (a
.type
< b
.type
|| (a
.type
== b
.type
&& a
.hash
< b
.hash
));
413 bool IsKnownType() const
415 return (type
>= 1 && type
< ARRAYLEN(ppszTypeName
));
418 const char* GetCommand() const
421 throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type
));
422 return ppszTypeName
[type
];
425 string
ToString() const
427 return strprintf("%s %s", GetCommand(), hash
.ToString().substr(0,20).c_str());
432 printf("CInv(%s)\n", ToString().c_str());
440 class CRequestTracker
443 void (*fn
)(void*, CDataStream
&);
446 explicit CRequestTracker(void (*fnIn
)(void*, CDataStream
&)=NULL
, void* param1In
=NULL
)
463 extern uint64 nLocalServices
;
464 extern CAddress addrLocalHost
;
465 extern CNode
* pnodeLocalHost
;
466 extern uint64 nLocalHostNonce
;
467 extern array
<int, 10> vnThreadsRunning
;
468 extern SOCKET hListenSocket
;
470 extern vector
<CNode
*> vNodes
;
471 extern CCriticalSection cs_vNodes
;
472 extern map
<vector
<unsigned char>, CAddress
> mapAddresses
;
473 extern CCriticalSection cs_mapAddresses
;
474 extern map
<CInv
, CDataStream
> mapRelay
;
475 extern deque
<pair
<int64
, CInv
> > vRelayExpiration
;
476 extern CCriticalSection cs_mapRelay
;
477 extern map
<CInv
, int64
> mapAlreadyAskedFor
;
480 extern int fUseProxy
;
481 extern CAddress addrProxy
;
496 CCriticalSection cs_vSend
;
497 CCriticalSection cs_vRecv
;
500 int64 nLastSendEmpty
;
501 int64 nTimeConnected
;
502 unsigned int nHeaderStart
;
503 unsigned int nMessageStart
;
510 bool fSuccessfullyConnected
;
516 map
<uint256
, CRequestTracker
> mapRequests
;
517 CCriticalSection cs_mapRequests
;
518 uint256 hashContinue
;
519 CBlockIndex
* pindexLastGetBlocksBegin
;
520 uint256 hashLastGetBlocksEnd
;
524 vector
<CAddress
> vAddrToSend
;
525 set
<CAddress
> setAddrKnown
;
527 set
<uint256
> setKnown
;
529 // inventory based relay
530 set
<CInv
> setInventoryKnown
;
531 vector
<CInv
> vInventoryToSend
;
532 CCriticalSection cs_inventory
;
533 multimap
<int64
, CInv
> mapAskFor
;
535 // publish and subscription
536 vector
<char> vfSubscribe
;
539 CNode(SOCKET hSocketIn
, CAddress addrIn
, bool fInboundIn
=false)
543 vSend
.SetType(SER_NETWORK
);
545 vRecv
.SetType(SER_NETWORK
);
547 // Version 0.2 obsoletes 20 Feb 2012
548 if (GetTime() > 1329696000)
550 vSend
.SetVersion(209);
551 vRecv
.SetVersion(209);
555 nLastSendEmpty
= GetTime();
556 nTimeConnected
= GetTime();
562 fClient
= false; // set by version message
563 fInbound
= fInboundIn
;
564 fNetworkNode
= false;
565 fSuccessfullyConnected
= false;
570 pindexLastGetBlocksBegin
= 0;
571 hashLastGetBlocksEnd
= 0;
572 nStartingHeight
= -1;
574 vfSubscribe
.assign(256, false);
576 // Push a version message
577 /// when NTP implemented, change to just nTime = GetAdjustedTime()
578 int64 nTime
= (fInbound
? GetAdjustedTime() : GetTime());
579 CAddress addrYou
= (fUseProxy
? CAddress("0.0.0.0") : addr
);
580 CAddress addrMe
= (fUseProxy
? CAddress("0.0.0.0") : addrLocalHost
);
581 RAND_bytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
582 PushMessage("version", VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
583 nLocalHostNonce
, string(pszSubVer
), nBestHeight
);
588 if (hSocket
!= INVALID_SOCKET
)
590 closesocket(hSocket
);
591 hSocket
= INVALID_SOCKET
;
597 void operator=(const CNode
&);
603 return max(nRefCount
, 0) + (GetTime() < nReleaseTime
? 1 : 0);
606 CNode
* AddRef(int64 nTimeout
=0)
609 nReleaseTime
= max(nReleaseTime
, GetTime() + nTimeout
);
622 void AddAddressKnown(const CAddress
& addr
)
624 setAddrKnown
.insert(addr
);
627 void PushAddress(const CAddress
& addr
)
629 // Known checking here is only to save space from duplicates.
630 // SendMessages will filter it again for knowns that were added
631 // after addresses were pushed.
632 if (addr
.IsValid() && !setAddrKnown
.count(addr
))
633 vAddrToSend
.push_back(addr
);
637 void AddInventoryKnown(const CInv
& inv
)
639 CRITICAL_BLOCK(cs_inventory
)
640 setInventoryKnown
.insert(inv
);
643 void PushInventory(const CInv
& inv
)
645 CRITICAL_BLOCK(cs_inventory
)
646 if (!setInventoryKnown
.count(inv
))
647 vInventoryToSend
.push_back(inv
);
650 void AskFor(const CInv
& inv
)
652 // We're using mapAskFor as a priority queue,
653 // the key is the earliest time the request can be sent
654 int64
& nRequestTime
= mapAlreadyAskedFor
[inv
];
655 printf("askfor %s %"PRI64d
"\n", inv
.ToString().c_str(), nRequestTime
);
657 // Make sure not to reuse time indexes to keep things in the same order
658 int64 nNow
= (GetTime() - 1) * 1000000;
659 static int64 nLastTime
;
660 nLastTime
= nNow
= max(nNow
, ++nLastTime
);
662 // Each retry is 2 minutes after the last
663 nRequestTime
= max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
664 mapAskFor
.insert(make_pair(nRequestTime
, inv
));
669 void BeginMessage(const char* pszCommand
)
672 if (nHeaderStart
!= -1)
674 nHeaderStart
= vSend
.size();
675 vSend
<< CMessageHeader(pszCommand
, 0);
676 nMessageStart
= vSend
.size();
678 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
679 printf("sending: %s ", pszCommand
);
684 if (nHeaderStart
== -1)
686 vSend
.resize(nHeaderStart
);
690 printf("(aborted)\n");
695 if (mapArgs
.count("-dropmessagestest") && GetRand(atoi(mapArgs
["-dropmessagestest"])) == 0)
697 printf("dropmessages DROPPING SEND MESSAGE\n");
702 if (nHeaderStart
== -1)
706 unsigned int nSize
= vSend
.size() - nMessageStart
;
707 memcpy((char*)&vSend
[nHeaderStart
] + offsetof(CMessageHeader
, nMessageSize
), &nSize
, sizeof(nSize
));
710 if (vSend
.GetVersion() >= 209)
712 uint256 hash
= Hash(vSend
.begin() + nMessageStart
, vSend
.end());
713 unsigned int nChecksum
= 0;
714 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
715 assert(nMessageStart
- nHeaderStart
>= offsetof(CMessageHeader
, nChecksum
) + sizeof(nChecksum
));
716 memcpy((char*)&vSend
[nHeaderStart
] + offsetof(CMessageHeader
, nChecksum
), &nChecksum
, sizeof(nChecksum
));
719 printf("(%d bytes) ", nSize
);
727 void EndMessageAbortIfEmpty()
729 if (nHeaderStart
== -1)
731 int nSize
= vSend
.size() - nMessageStart
;
738 const char* GetMessageCommand() const
740 if (nHeaderStart
== -1)
742 return &vSend
[nHeaderStart
] + offsetof(CMessageHeader
, pchCommand
);
748 void PushMessage(const char* pszCommand
)
752 BeginMessage(pszCommand
);
762 template<typename T1
>
763 void PushMessage(const char* pszCommand
, const T1
& a1
)
767 BeginMessage(pszCommand
);
778 template<typename T1
, typename T2
>
779 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
)
783 BeginMessage(pszCommand
);
794 template<typename T1
, typename T2
, typename T3
>
795 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
)
799 BeginMessage(pszCommand
);
800 vSend
<< a1
<< a2
<< a3
;
810 template<typename T1
, typename T2
, typename T3
, typename T4
>
811 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
)
815 BeginMessage(pszCommand
);
816 vSend
<< a1
<< a2
<< a3
<< a4
;
826 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
>
827 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
)
831 BeginMessage(pszCommand
);
832 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
;
842 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
>
843 void PushMessage(const char* pszCommand
, const T1
& a1
, const T2
& a2
, const T3
& a3
, const T4
& a4
, const T5
& a5
, const T6
& a6
)
847 BeginMessage(pszCommand
);
848 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
;
858 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
, typename T7
>
859 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
)
863 BeginMessage(pszCommand
);
864 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
<< a7
;
874 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
, typename T7
, typename T8
>
875 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
)
879 BeginMessage(pszCommand
);
880 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
<< a7
<< a8
;
890 template<typename T1
, typename T2
, typename T3
, typename T4
, typename T5
, typename T6
, typename T7
, typename T8
, typename T9
>
891 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
)
895 BeginMessage(pszCommand
);
896 vSend
<< a1
<< a2
<< a3
<< a4
<< a5
<< a6
<< a7
<< a8
<< a9
;
907 void PushRequest(const char* pszCommand
,
908 void (*fn
)(void*, CDataStream
&), void* param1
)
911 RAND_bytes((unsigned char*)&hashReply
, sizeof(hashReply
));
913 CRITICAL_BLOCK(cs_mapRequests
)
914 mapRequests
[hashReply
] = CRequestTracker(fn
, param1
);
916 PushMessage(pszCommand
, hashReply
);
919 template<typename T1
>
920 void PushRequest(const char* pszCommand
, const T1
& a1
,
921 void (*fn
)(void*, CDataStream
&), void* param1
)
924 RAND_bytes((unsigned char*)&hashReply
, sizeof(hashReply
));
926 CRITICAL_BLOCK(cs_mapRequests
)
927 mapRequests
[hashReply
] = CRequestTracker(fn
, param1
);
929 PushMessage(pszCommand
, hashReply
, a1
);
932 template<typename T1
, typename T2
>
933 void PushRequest(const char* pszCommand
, const T1
& a1
, const T2
& a2
,
934 void (*fn
)(void*, CDataStream
&), void* param1
)
937 RAND_bytes((unsigned char*)&hashReply
, sizeof(hashReply
));
939 CRITICAL_BLOCK(cs_mapRequests
)
940 mapRequests
[hashReply
] = CRequestTracker(fn
, param1
);
942 PushMessage(pszCommand
, hashReply
, a1
, a2
);
947 void PushGetBlocks(CBlockIndex
* pindexBegin
, uint256 hashEnd
);
948 bool IsSubscribed(unsigned int nChannel
);
949 void Subscribe(unsigned int nChannel
, unsigned int nHops
=0);
950 void CancelSubscribe(unsigned int nChannel
);
951 void CloseSocketDisconnect();
964 inline void RelayInventory(const CInv
& inv
)
966 // Put on lists to offer to the other nodes
967 CRITICAL_BLOCK(cs_vNodes
)
968 foreach(CNode
* pnode
, vNodes
)
969 pnode
->PushInventory(inv
);
973 void RelayMessage(const CInv
& inv
, const T
& a
)
975 CDataStream
ss(SER_NETWORK
);
978 RelayMessage(inv
, ss
);
982 inline void RelayMessage
<>(const CInv
& inv
, const CDataStream
& ss
)
984 CRITICAL_BLOCK(cs_mapRelay
)
986 // Expire old relay messages
987 while (!vRelayExpiration
.empty() && vRelayExpiration
.front().first
< GetTime())
989 mapRelay
.erase(vRelayExpiration
.front().second
);
990 vRelayExpiration
.pop_front();
993 // Save original serialized message so newer versions are preserved
995 vRelayExpiration
.push_back(make_pair(GetTime() + 15 * 60, inv
));
1009 // Templates for the publish and subscription system.
1010 // The object being published as T& obj needs to have:
1011 // a set<unsigned int> setSources member
1012 // specializations of AdvertInsert and AdvertErase
1013 // Currently implemented for CTable and CProduct.
1016 template<typename T
>
1017 void AdvertStartPublish(CNode
* pfrom
, unsigned int nChannel
, unsigned int nHops
, T
& obj
)
1020 obj
.setSources
.insert(pfrom
->addr
.ip
);
1022 if (!AdvertInsert(obj
))
1026 CRITICAL_BLOCK(cs_vNodes
)
1027 foreach(CNode
* pnode
, vNodes
)
1028 if (pnode
!= pfrom
&& (nHops
< PUBLISH_HOPS
|| pnode
->IsSubscribed(nChannel
)))
1029 pnode
->PushMessage("publish", nChannel
, nHops
, obj
);
1032 template<typename T
>
1033 void AdvertStopPublish(CNode
* pfrom
, unsigned int nChannel
, unsigned int nHops
, T
& obj
)
1035 uint256 hash
= obj
.GetHash();
1037 CRITICAL_BLOCK(cs_vNodes
)
1038 foreach(CNode
* pnode
, vNodes
)
1039 if (pnode
!= pfrom
&& (nHops
< PUBLISH_HOPS
|| pnode
->IsSubscribed(nChannel
)))
1040 pnode
->PushMessage("pub-cancel", nChannel
, nHops
, hash
);
1045 template<typename T
>
1046 void AdvertRemoveSource(CNode
* pfrom
, unsigned int nChannel
, unsigned int nHops
, T
& obj
)
1049 obj
.setSources
.erase(pfrom
->addr
.ip
);
1051 // If no longer supported by any sources, cancel it
1052 if (obj
.setSources
.empty())
1053 AdvertStopPublish(pfrom
, nChannel
, nHops
, obj
);