1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
9 #include <boost/array.hpp>
10 #include <boost/foreach.hpp>
11 #include <openssl/rand.h>
14 #include <arpa/inet.h>
21 class CRequestTracker;
24 extern int nBestHeight;
25 extern int nConnectTimeout;
29 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
30 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
31 inline unsigned short GetDefaultPort() { return fTestNet ? 18333 : 8333; }
32 static const unsigned int PUBLISH_HOPS = 5;
35 NODE_NETWORK = (1 << 0),
41 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
42 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
43 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
44 bool GetMyExternalIP(unsigned int& ipRet);
45 bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
46 void AddressCurrentlyConnected(const CAddress& addr);
47 CNode* FindNode(unsigned int ip);
48 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
49 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
50 bool AnySubscribed(unsigned int nChannel);
51 void MapPort(bool fMapPort);
52 void DNSAddressSeed();
53 bool BindListenPort(std::string& strError=REF(std::string()));
54 void StartNode(void* parg);
71 extern unsigned char pchMessageStart[4];
76 enum { COMMAND_SIZE=12 };
77 char pchMessageStart[sizeof(::pchMessageStart)];
78 char pchCommand[COMMAND_SIZE];
79 unsigned int nMessageSize;
80 unsigned int nChecksum;
84 memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
85 memset(pchCommand, 0, sizeof(pchCommand));
91 CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
93 memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
94 strncpy(pchCommand, pszCommand, COMMAND_SIZE);
95 nMessageSize = nMessageSizeIn;
101 READWRITE(FLATDATA(pchMessageStart));
102 READWRITE(FLATDATA(pchCommand));
103 READWRITE(nMessageSize);
105 READWRITE(nChecksum);
108 std::string GetCommand()
110 if (pchCommand[COMMAND_SIZE-1] == 0)
111 return std::string(pchCommand, pchCommand + strlen(pchCommand));
113 return std::string(pchCommand, pchCommand + COMMAND_SIZE);
118 // Check start string
119 if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
122 // Check the command string for errors
123 for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
127 // Must be all zeros after the first zero
128 for (; p1 < pchCommand + COMMAND_SIZE; p1++)
132 else if (*p1 < ' ' || *p1 > 0x7E)
137 if (nMessageSize > MAX_SIZE)
139 printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
152 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
158 unsigned char pchReserved[12];
162 // disk and network only
166 unsigned int nLastTry;
173 CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK)
177 port = htons(portIn == 0 ? GetDefaultPort() : portIn);
178 nServices = nServicesIn;
181 explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK)
184 ip = sockaddr.sin_addr.s_addr;
185 port = sockaddr.sin_port;
186 nServices = nServicesIn;
189 explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
192 Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
195 explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
198 Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
201 explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
204 Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
207 explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
210 Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
215 nServices = NODE_NETWORK;
216 memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
218 port = htons(GetDefaultPort());
226 const_cast<CAddress*>(this)->Init();
227 if (nType & SER_DISK)
229 if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
231 READWRITE(nServices);
232 READWRITE(FLATDATA(pchReserved)); // for IPv6
237 friend inline bool operator==(const CAddress& a, const CAddress& b)
239 return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
244 friend inline bool operator!=(const CAddress& a, const CAddress& b)
249 friend inline bool operator<(const CAddress& a, const CAddress& b)
251 int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
256 if (ntohl(a.ip) < ntohl(b.ip))
258 else if (a.ip == b.ip)
259 return ntohs(a.port) < ntohs(b.port);
264 std::vector<unsigned char> GetKey() const
268 ss << FLATDATA(pchReserved) << ip << port;
270 #if defined(_MSC_VER) && _MSC_VER < 1300
271 return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
273 return std::vector<unsigned char>(ss.begin(), ss.end());
277 struct sockaddr_in GetSockAddr() const
279 struct sockaddr_in sockaddr;
280 memset(&sockaddr, 0, sizeof(sockaddr));
281 sockaddr.sin_family = AF_INET;
282 sockaddr.sin_addr.s_addr = ip;
283 sockaddr.sin_port = port;
289 return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
292 bool IsRFC1918() const
294 return IsIPv4() && (GetByte(3) == 10 ||
295 (GetByte(3) == 192 && GetByte(2) == 168) ||
296 (GetByte(3) == 172 &&
297 (GetByte(2) >= 16 && GetByte(2) <= 31)));
300 bool IsRFC3927() const
302 return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
307 return IsIPv4() && (GetByte(3) == 127 ||
311 bool IsRoutable() const
314 !(IsRFC1918() || IsRFC3927() || IsLocal());
319 // Clean up 3-byte shifted addresses caused by garbage in size field
320 // of addr messages from versions before 0.2.9 checksum.
321 // Two consecutive addr messages look like this:
322 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
323 // so if the first length field is garbled, it reads the second batch
324 // of addr misaligned by 3 bytes.
325 if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
328 return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
331 unsigned char GetByte(int n) const
333 return ((unsigned char*)&ip)[3-n];
336 std::string ToStringIPPort() const
338 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
341 std::string ToStringIP() const
343 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
346 std::string ToStringPort() const
348 return strprintf("%u", ntohs(port));
351 std::string ToString() const
353 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
358 printf("CAddress(%s)\n", ToString().c_str());
374 static const char* ppszTypeName[] =
393 CInv(int typeIn, const uint256& hashIn)
399 CInv(const std::string& strType, const uint256& hashIn)
402 for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
404 if (strType == ppszTypeName[i])
410 if (i == ARRAYLEN(ppszTypeName))
411 throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
421 friend inline bool operator<(const CInv& a, const CInv& b)
423 return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
426 bool IsKnownType() const
428 return (type >= 1 && type < ARRAYLEN(ppszTypeName));
431 const char* GetCommand() const
434 throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
435 return ppszTypeName[type];
438 std::string ToString() const
440 return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
445 printf("CInv(%s)\n", ToString().c_str());
453 class CRequestTracker
456 void (*fn)(void*, CDataStream&);
459 explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
476 extern bool fAllowDNS;
477 extern uint64 nLocalServices;
478 extern CAddress addrLocalHost;
479 extern CNode* pnodeLocalHost;
480 extern uint64 nLocalHostNonce;
481 extern boost::array<int, 10> vnThreadsRunning;
482 extern SOCKET hListenSocket;
484 extern std::vector<CNode*> vNodes;
485 extern CCriticalSection cs_vNodes;
486 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
487 extern CCriticalSection cs_mapAddresses;
488 extern std::map<CInv, CDataStream> mapRelay;
489 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
490 extern CCriticalSection cs_mapRelay;
491 extern std::map<CInv, int64> mapAlreadyAskedFor;
494 extern int fUseProxy;
495 extern CAddress addrProxy;
510 CCriticalSection cs_vSend;
511 CCriticalSection cs_vRecv;
514 int64 nLastSendEmpty;
515 int64 nTimeConnected;
516 unsigned int nHeaderStart;
517 unsigned int nMessageStart;
520 std::string strSubVer;
524 bool fSuccessfullyConnected;
530 std::map<uint256, CRequestTracker> mapRequests;
531 CCriticalSection cs_mapRequests;
532 uint256 hashContinue;
533 CBlockIndex* pindexLastGetBlocksBegin;
534 uint256 hashLastGetBlocksEnd;
538 std::vector<CAddress> vAddrToSend;
539 std::set<CAddress> setAddrKnown;
541 std::set<uint256> setKnown;
543 // inventory based relay
544 std::set<CInv> setInventoryKnown;
545 std::vector<CInv> vInventoryToSend;
546 CCriticalSection cs_inventory;
547 std::multimap<int64, CInv> mapAskFor;
549 // publish and subscription
550 std::vector<char> vfSubscribe;
553 CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
557 vSend.SetType(SER_NETWORK);
559 vRecv.SetType(SER_NETWORK);
561 // Version 0.2 obsoletes 20 Feb 2012
562 if (GetTime() > 1329696000)
564 vSend.SetVersion(209);
565 vRecv.SetVersion(209);
569 nLastSendEmpty = GetTime();
570 nTimeConnected = GetTime();
576 fClient = false; // set by version message
577 fInbound = fInboundIn;
578 fNetworkNode = false;
579 fSuccessfullyConnected = false;
584 pindexLastGetBlocksBegin = 0;
585 hashLastGetBlocksEnd = 0;
586 nStartingHeight = -1;
588 vfSubscribe.assign(256, false);
590 // Be shy and don't send version until we hear
597 if (hSocket != INVALID_SOCKET)
599 closesocket(hSocket);
600 hSocket = INVALID_SOCKET;
606 void operator=(const CNode&);
612 return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
615 CNode* AddRef(int64 nTimeout=0)
618 nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
631 void AddAddressKnown(const CAddress& addr)
633 setAddrKnown.insert(addr);
636 void PushAddress(const CAddress& addr)
638 // Known checking here is only to save space from duplicates.
639 // SendMessages will filter it again for knowns that were added
640 // after addresses were pushed.
641 if (addr.IsValid() && !setAddrKnown.count(addr))
642 vAddrToSend.push_back(addr);
646 void AddInventoryKnown(const CInv& inv)
648 CRITICAL_BLOCK(cs_inventory)
649 setInventoryKnown.insert(inv);
652 void PushInventory(const CInv& inv)
654 CRITICAL_BLOCK(cs_inventory)
655 if (!setInventoryKnown.count(inv))
656 vInventoryToSend.push_back(inv);
659 void AskFor(const CInv& inv)
661 // We're using mapAskFor as a priority queue,
662 // the key is the earliest time the request can be sent
663 int64& nRequestTime = mapAlreadyAskedFor[inv];
664 printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
666 // Make sure not to reuse time indexes to keep things in the same order
667 int64 nNow = (GetTime() - 1) * 1000000;
668 static int64 nLastTime;
669 nLastTime = nNow = std::max(nNow, ++nLastTime);
671 // Each retry is 2 minutes after the last
672 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
673 mapAskFor.insert(std::make_pair(nRequestTime, inv));
678 void BeginMessage(const char* pszCommand)
680 cs_vSend.Enter("cs_vSend", __FILE__, __LINE__);
681 if (nHeaderStart != -1)
683 nHeaderStart = vSend.size();
684 vSend << CMessageHeader(pszCommand, 0);
685 nMessageStart = vSend.size();
687 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
688 printf("sending: %s ", pszCommand);
693 if (nHeaderStart == -1)
695 vSend.resize(nHeaderStart);
699 printf("(aborted)\n");
704 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
706 printf("dropmessages DROPPING SEND MESSAGE\n");
711 if (nHeaderStart == -1)
715 unsigned int nSize = vSend.size() - nMessageStart;
716 memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
719 if (vSend.GetVersion() >= 209)
721 uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
722 unsigned int nChecksum = 0;
723 memcpy(&nChecksum, &hash, sizeof(nChecksum));
724 assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
725 memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
728 printf("(%d bytes) ", nSize);
736 void EndMessageAbortIfEmpty()
738 if (nHeaderStart == -1)
740 int nSize = vSend.size() - nMessageStart;
751 /// when NTP implemented, change to just nTime = GetAdjustedTime()
752 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
753 CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
754 CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
755 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
756 PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
757 nLocalHostNonce, std::string(pszSubVer), nBestHeight);
763 void PushMessage(const char* pszCommand)
767 BeginMessage(pszCommand);
777 template<typename T1>
778 void PushMessage(const char* pszCommand, const T1& a1)
782 BeginMessage(pszCommand);
793 template<typename T1, typename T2>
794 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
798 BeginMessage(pszCommand);
809 template<typename T1, typename T2, typename T3>
810 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
814 BeginMessage(pszCommand);
815 vSend << a1 << a2 << a3;
825 template<typename T1, typename T2, typename T3, typename T4>
826 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
830 BeginMessage(pszCommand);
831 vSend << a1 << a2 << a3 << a4;
841 template<typename T1, typename T2, typename T3, typename T4, typename T5>
842 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
846 BeginMessage(pszCommand);
847 vSend << a1 << a2 << a3 << a4 << a5;
857 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
858 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
862 BeginMessage(pszCommand);
863 vSend << a1 << a2 << a3 << a4 << a5 << a6;
873 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
874 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)
878 BeginMessage(pszCommand);
879 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
889 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
890 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)
894 BeginMessage(pszCommand);
895 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
905 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
906 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)
910 BeginMessage(pszCommand);
911 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
922 void PushRequest(const char* pszCommand,
923 void (*fn)(void*, CDataStream&), void* param1)
926 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
928 CRITICAL_BLOCK(cs_mapRequests)
929 mapRequests[hashReply] = CRequestTracker(fn, param1);
931 PushMessage(pszCommand, hashReply);
934 template<typename T1>
935 void PushRequest(const char* pszCommand, const T1& a1,
936 void (*fn)(void*, CDataStream&), void* param1)
939 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
941 CRITICAL_BLOCK(cs_mapRequests)
942 mapRequests[hashReply] = CRequestTracker(fn, param1);
944 PushMessage(pszCommand, hashReply, a1);
947 template<typename T1, typename T2>
948 void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
949 void (*fn)(void*, CDataStream&), void* param1)
952 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
954 CRITICAL_BLOCK(cs_mapRequests)
955 mapRequests[hashReply] = CRequestTracker(fn, param1);
957 PushMessage(pszCommand, hashReply, a1, a2);
962 void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
963 bool IsSubscribed(unsigned int nChannel);
964 void Subscribe(unsigned int nChannel, unsigned int nHops=0);
965 void CancelSubscribe(unsigned int nChannel);
966 void CloseSocketDisconnect();
979 inline void RelayInventory(const CInv& inv)
981 // Put on lists to offer to the other nodes
982 CRITICAL_BLOCK(cs_vNodes)
983 BOOST_FOREACH(CNode* pnode, vNodes)
984 pnode->PushInventory(inv);
988 void RelayMessage(const CInv& inv, const T& a)
990 CDataStream ss(SER_NETWORK);
993 RelayMessage(inv, ss);
997 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
999 CRITICAL_BLOCK(cs_mapRelay)
1001 // Expire old relay messages
1002 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1004 mapRelay.erase(vRelayExpiration.front().second);
1005 vRelayExpiration.pop_front();
1008 // Save original serialized message so newer versions are preserved
1010 vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1013 RelayInventory(inv);
1024 // Templates for the publish and subscription system.
1025 // The object being published as T& obj needs to have:
1026 // a set<unsigned int> setSources member
1027 // specializations of AdvertInsert and AdvertErase
1028 // Currently implemented for CTable and CProduct.
1031 template<typename T>
1032 void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
1035 obj.setSources.insert(pfrom->addr.ip);
1037 if (!AdvertInsert(obj))
1041 CRITICAL_BLOCK(cs_vNodes)
1042 BOOST_FOREACH(CNode* pnode, vNodes)
1043 if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
1044 pnode->PushMessage("publish", nChannel, nHops, obj);
1047 template<typename T>
1048 void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
1050 uint256 hash = obj.GetHash();
1052 CRITICAL_BLOCK(cs_vNodes)
1053 BOOST_FOREACH(CNode* pnode, vNodes)
1054 if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
1055 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
1060 template<typename T>
1061 void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
1064 obj.setSources.erase(pfrom->addr.ip);
1066 // If no longer supported by any sources, cancel it
1067 if (obj.setSources.empty())
1068 AdvertStopPublish(pfrom, nChannel, nHops, obj);