Back to home page

Bitcoin sources

 
 

    


0001 // Copyright (c) 2009-2010 Satoshi Nakamoto
0002 // Copyright (c) 2009-2012 The Bitcoin developers
0003 // Distributed under the MIT/X11 software license, see the accompanying
0004 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
0005 #ifndef BITCOIN_NET_H
0006 #define BITCOIN_NET_H
0007 
0008 #include <deque>
0009 #include <boost/array.hpp>
0010 #include <boost/foreach.hpp>
0011 #include <openssl/rand.h>
0012 
0013 #include "protocol.h"
0014 
0015 class CAddrDB;
0016 class CRequestTracker;
0017 class CNode;
0018 class CBlockIndex;
0019 extern int nBestHeight;
0020 extern int nConnectTimeout;
0021 
0022 
0023 
0024 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
0025 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
0026 static const unsigned int PUBLISH_HOPS = 5;
0027 
0028 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
0029 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, int portDefault = 0, bool fAllowPort = false);
0030 bool Lookup(const char *pszName, CAddress& addr, int nServices, int portDefault = 0, bool fAllowPort = false);
0031 bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
0032 void AddressCurrentlyConnected(const CAddress& addr);
0033 CNode* FindNode(unsigned int ip);
0034 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
0035 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
0036 bool AnySubscribed(unsigned int nChannel);
0037 void MapPort(bool fMapPort);
0038 bool BindListenPort(std::string& strError=REF(std::string()));
0039 void StartNode(void* parg);
0040 bool StopNode();
0041 
0042 enum
0043 {
0044     MSG_TX = 1,
0045     MSG_BLOCK,
0046 };
0047 
0048 class CRequestTracker
0049 {
0050 public:
0051     void (*fn)(void*, CDataStream&);
0052     void* param1;
0053 
0054     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
0055     {
0056         fn = fnIn;
0057         param1 = param1In;
0058     }
0059 
0060     bool IsNull()
0061     {
0062         return fn == NULL;
0063     }
0064 };
0065 
0066 
0067 
0068 
0069 
0070 extern bool fClient;
0071 extern bool fAllowDNS;
0072 extern uint64 nLocalServices;
0073 extern CAddress addrLocalHost;
0074 extern uint64 nLocalHostNonce;
0075 extern boost::array<int, 10> vnThreadsRunning;
0076 
0077 extern std::vector<CNode*> vNodes;
0078 extern CCriticalSection cs_vNodes;
0079 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
0080 extern CCriticalSection cs_mapAddresses;
0081 extern std::map<CInv, CDataStream> mapRelay;
0082 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
0083 extern CCriticalSection cs_mapRelay;
0084 extern std::map<CInv, int64> mapAlreadyAskedFor;
0085 
0086 // Settings
0087 extern int fUseProxy;
0088 extern CAddress addrProxy;
0089 
0090 
0091 
0092 
0093 
0094 
0095 class CNode
0096 {
0097 public:
0098     // socket
0099     uint64 nServices;
0100     SOCKET hSocket;
0101     CDataStream vSend;
0102     CDataStream vRecv;
0103     CCriticalSection cs_vSend;
0104     CCriticalSection cs_vRecv;
0105     int64 nLastSend;
0106     int64 nLastRecv;
0107     int64 nLastSendEmpty;
0108     int64 nTimeConnected;
0109     unsigned int nHeaderStart;
0110     unsigned int nMessageStart;
0111     CAddress addr;
0112     int nVersion;
0113     std::string strSubVer;
0114     bool fClient;
0115     bool fInbound;
0116     bool fNetworkNode;
0117     bool fSuccessfullyConnected;
0118     bool fDisconnect;
0119 protected:
0120     int nRefCount;
0121 
0122     // Denial-of-service detection/prevention
0123     // Key is ip address, value is banned-until-time
0124     static std::map<unsigned int, int64> setBanned;
0125     static CCriticalSection cs_setBanned;
0126     int nMisbehavior;
0127 
0128 public:
0129     int64 nReleaseTime;
0130     std::map<uint256, CRequestTracker> mapRequests;
0131     CCriticalSection cs_mapRequests;
0132     uint256 hashContinue;
0133     CBlockIndex* pindexLastGetBlocksBegin;
0134     uint256 hashLastGetBlocksEnd;
0135     int nStartingHeight;
0136 
0137     // flood relay
0138     std::vector<CAddress> vAddrToSend;
0139     std::set<CAddress> setAddrKnown;
0140     bool fGetAddr;
0141     std::set<uint256> setKnown;
0142 
0143     // inventory based relay
0144     std::set<CInv> setInventoryKnown;
0145     std::vector<CInv> vInventoryToSend;
0146     CCriticalSection cs_inventory;
0147     std::multimap<int64, CInv> mapAskFor;
0148 
0149     // publish and subscription
0150     std::vector<char> vfSubscribe;
0151 
0152     CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
0153     {
0154         nServices = 0;
0155         hSocket = hSocketIn;
0156         vSend.SetType(SER_NETWORK);
0157         vSend.SetVersion(0);
0158         vRecv.SetType(SER_NETWORK);
0159         vRecv.SetVersion(0);
0160         // Version 0.2 obsoletes 20 Feb 2012
0161         if (GetTime() > 1329696000)
0162         {
0163             vSend.SetVersion(209);
0164             vRecv.SetVersion(209);
0165         }
0166         nLastSend = 0;
0167         nLastRecv = 0;
0168         nLastSendEmpty = GetTime();
0169         nTimeConnected = GetTime();
0170         nHeaderStart = -1;
0171         nMessageStart = -1;
0172         addr = addrIn;
0173         nVersion = 0;
0174         strSubVer = "";
0175         fClient = false; // set by version message
0176         fInbound = fInboundIn;
0177         fNetworkNode = false;
0178         fSuccessfullyConnected = false;
0179         fDisconnect = false;
0180         nRefCount = 0;
0181         nReleaseTime = 0;
0182         hashContinue = 0;
0183         pindexLastGetBlocksBegin = 0;
0184         hashLastGetBlocksEnd = 0;
0185         nStartingHeight = -1;
0186         fGetAddr = false;
0187         vfSubscribe.assign(256, false);
0188         nMisbehavior = 0;
0189 
0190         // Be shy and don't send version until we hear
0191         if (!fInbound)
0192             PushVersion();
0193     }
0194 
0195     ~CNode()
0196     {
0197         if (hSocket != INVALID_SOCKET)
0198         {
0199             closesocket(hSocket);
0200             hSocket = INVALID_SOCKET;
0201         }
0202     }
0203 
0204 private:
0205     CNode(const CNode&);
0206     void operator=(const CNode&);
0207 public:
0208 
0209 
0210     int GetRefCount()
0211     {
0212         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
0213     }
0214 
0215     CNode* AddRef(int64 nTimeout=0)
0216     {
0217         if (nTimeout != 0)
0218             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
0219         else
0220             nRefCount++;
0221         return this;
0222     }
0223 
0224     void Release()
0225     {
0226         nRefCount--;
0227     }
0228 
0229 
0230 
0231     void AddAddressKnown(const CAddress& addr)
0232     {
0233         setAddrKnown.insert(addr);
0234     }
0235 
0236     void PushAddress(const CAddress& addr)
0237     {
0238         // Known checking here is only to save space from duplicates.
0239         // SendMessages will filter it again for knowns that were added
0240         // after addresses were pushed.
0241         if (addr.IsValid() && !setAddrKnown.count(addr))
0242             vAddrToSend.push_back(addr);
0243     }
0244 
0245 
0246     void AddInventoryKnown(const CInv& inv)
0247     {
0248         CRITICAL_BLOCK(cs_inventory)
0249             setInventoryKnown.insert(inv);
0250     }
0251 
0252     void PushInventory(const CInv& inv)
0253     {
0254         CRITICAL_BLOCK(cs_inventory)
0255             if (!setInventoryKnown.count(inv))
0256                 vInventoryToSend.push_back(inv);
0257     }
0258 
0259     void AskFor(const CInv& inv)
0260     {
0261         // We're using mapAskFor as a priority queue,
0262         // the key is the earliest time the request can be sent
0263         int64& nRequestTime = mapAlreadyAskedFor[inv];
0264         printf("askfor %s   %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
0265 
0266         // Make sure not to reuse time indexes to keep things in the same order
0267         int64 nNow = (GetTime() - 1) * 1000000;
0268         static int64 nLastTime;
0269         ++nLastTime;
0270         nNow = std::max(nNow, nLastTime);
0271         nLastTime = nNow;
0272 
0273         // Each retry is 2 minutes after the last
0274         nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
0275         mapAskFor.insert(std::make_pair(nRequestTime, inv));
0276     }
0277 
0278 
0279 
0280     void BeginMessage(const char* pszCommand)
0281     {
0282         ENTER_CRITICAL_SECTION(cs_vSend);
0283         if (nHeaderStart != -1)
0284             AbortMessage();
0285         nHeaderStart = vSend.size();
0286         vSend << CMessageHeader(pszCommand, 0);
0287         nMessageStart = vSend.size();
0288         if (fDebug) {
0289             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
0290             printf("sending: %s ", pszCommand);
0291         }
0292     }
0293 
0294     void AbortMessage()
0295     {
0296         if (nHeaderStart == -1)
0297             return;
0298         vSend.resize(nHeaderStart);
0299         nHeaderStart = -1;
0300         nMessageStart = -1;
0301         LEAVE_CRITICAL_SECTION(cs_vSend);
0302 
0303         if (fDebug)
0304             printf("(aborted)\n");
0305     }
0306 
0307     void EndMessage()
0308     {
0309         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
0310         {
0311             printf("dropmessages DROPPING SEND MESSAGE\n");
0312             AbortMessage();
0313             return;
0314         }
0315 
0316         if (nHeaderStart == -1)
0317             return;
0318 
0319         // Set the size
0320         unsigned int nSize = vSend.size() - nMessageStart;
0321         memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
0322 
0323         // Set the checksum
0324         if (vSend.GetVersion() >= 209)
0325         {
0326             uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
0327             unsigned int nChecksum = 0;
0328             memcpy(&nChecksum, &hash, sizeof(nChecksum));
0329             assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
0330             memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
0331         }
0332 
0333         if (fDebug) {
0334             printf("(%d bytes)\n", nSize);
0335         }
0336 
0337         nHeaderStart = -1;
0338         nMessageStart = -1;
0339         LEAVE_CRITICAL_SECTION(cs_vSend);
0340     }
0341 
0342     void EndMessageAbortIfEmpty()
0343     {
0344         if (nHeaderStart == -1)
0345             return;
0346         int nSize = vSend.size() - nMessageStart;
0347         if (nSize > 0)
0348             EndMessage();
0349         else
0350             AbortMessage();
0351     }
0352 
0353 
0354 
0355     void PushVersion()
0356     {
0357         /// when NTP implemented, change to just nTime = GetAdjustedTime()
0358         int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
0359         CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
0360         CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress("0.0.0.0") : addrLocalHost);
0361         RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
0362         PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
0363                     nLocalHostNonce, std::string(pszSubVer), nBestHeight);
0364     }
0365 
0366 
0367 
0368 
0369     void PushMessage(const char* pszCommand)
0370     {
0371         try
0372         {
0373             BeginMessage(pszCommand);
0374             EndMessage();
0375         }
0376         catch (...)
0377         {
0378             AbortMessage();
0379             throw;
0380         }
0381     }
0382 
0383     template<typename T1>
0384     void PushMessage(const char* pszCommand, const T1& a1)
0385     {
0386         try
0387         {
0388             BeginMessage(pszCommand);
0389             vSend << a1;
0390             EndMessage();
0391         }
0392         catch (...)
0393         {
0394             AbortMessage();
0395             throw;
0396         }
0397     }
0398 
0399     template<typename T1, typename T2>
0400     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
0401     {
0402         try
0403         {
0404             BeginMessage(pszCommand);
0405             vSend << a1 << a2;
0406             EndMessage();
0407         }
0408         catch (...)
0409         {
0410             AbortMessage();
0411             throw;
0412         }
0413     }
0414 
0415     template<typename T1, typename T2, typename T3>
0416     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
0417     {
0418         try
0419         {
0420             BeginMessage(pszCommand);
0421             vSend << a1 << a2 << a3;
0422             EndMessage();
0423         }
0424         catch (...)
0425         {
0426             AbortMessage();
0427             throw;
0428         }
0429     }
0430 
0431     template<typename T1, typename T2, typename T3, typename T4>
0432     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
0433     {
0434         try
0435         {
0436             BeginMessage(pszCommand);
0437             vSend << a1 << a2 << a3 << a4;
0438             EndMessage();
0439         }
0440         catch (...)
0441         {
0442             AbortMessage();
0443             throw;
0444         }
0445     }
0446 
0447     template<typename T1, typename T2, typename T3, typename T4, typename T5>
0448     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
0449     {
0450         try
0451         {
0452             BeginMessage(pszCommand);
0453             vSend << a1 << a2 << a3 << a4 << a5;
0454             EndMessage();
0455         }
0456         catch (...)
0457         {
0458             AbortMessage();
0459             throw;
0460         }
0461     }
0462 
0463     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
0464     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
0465     {
0466         try
0467         {
0468             BeginMessage(pszCommand);
0469             vSend << a1 << a2 << a3 << a4 << a5 << a6;
0470             EndMessage();
0471         }
0472         catch (...)
0473         {
0474             AbortMessage();
0475             throw;
0476         }
0477     }
0478 
0479     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
0480     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)
0481     {
0482         try
0483         {
0484             BeginMessage(pszCommand);
0485             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
0486             EndMessage();
0487         }
0488         catch (...)
0489         {
0490             AbortMessage();
0491             throw;
0492         }
0493     }
0494 
0495     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
0496     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)
0497     {
0498         try
0499         {
0500             BeginMessage(pszCommand);
0501             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
0502             EndMessage();
0503         }
0504         catch (...)
0505         {
0506             AbortMessage();
0507             throw;
0508         }
0509     }
0510 
0511     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
0512     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)
0513     {
0514         try
0515         {
0516             BeginMessage(pszCommand);
0517             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
0518             EndMessage();
0519         }
0520         catch (...)
0521         {
0522             AbortMessage();
0523             throw;
0524         }
0525     }
0526 
0527 
0528     void PushRequest(const char* pszCommand,
0529                      void (*fn)(void*, CDataStream&), void* param1)
0530     {
0531         uint256 hashReply;
0532         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
0533 
0534         CRITICAL_BLOCK(cs_mapRequests)
0535             mapRequests[hashReply] = CRequestTracker(fn, param1);
0536 
0537         PushMessage(pszCommand, hashReply);
0538     }
0539 
0540     template<typename T1>
0541     void PushRequest(const char* pszCommand, const T1& a1,
0542                      void (*fn)(void*, CDataStream&), void* param1)
0543     {
0544         uint256 hashReply;
0545         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
0546 
0547         CRITICAL_BLOCK(cs_mapRequests)
0548             mapRequests[hashReply] = CRequestTracker(fn, param1);
0549 
0550         PushMessage(pszCommand, hashReply, a1);
0551     }
0552 
0553     template<typename T1, typename T2>
0554     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
0555                      void (*fn)(void*, CDataStream&), void* param1)
0556     {
0557         uint256 hashReply;
0558         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
0559 
0560         CRITICAL_BLOCK(cs_mapRequests)
0561             mapRequests[hashReply] = CRequestTracker(fn, param1);
0562 
0563         PushMessage(pszCommand, hashReply, a1, a2);
0564     }
0565 
0566 
0567 
0568     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
0569     bool IsSubscribed(unsigned int nChannel);
0570     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
0571     void CancelSubscribe(unsigned int nChannel);
0572     void CloseSocketDisconnect();
0573     void Cleanup();
0574 
0575 
0576     // Denial-of-service detection/prevention
0577     // The idea is to detect peers that are behaving
0578     // badly and disconnect/ban them, but do it in a
0579     // one-coding-mistake-won't-shatter-the-entire-network
0580     // way.
0581     // IMPORTANT:  There should be nothing I can give a
0582     // node that it will forward on that will make that
0583     // node's peers drop it. If there is, an attacker
0584     // can isolate a node and/or try to split the network.
0585     // Dropping a node for sending stuff that is invalid
0586     // now but might be valid in a later version is also
0587     // dangerous, because it can cause a network split
0588     // between nodes running old code and nodes running
0589     // new code.
0590     static void ClearBanned(); // needed for unit testing
0591     static bool IsBanned(unsigned int ip);
0592     bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
0593 };
0594 
0595 
0596 
0597 
0598 
0599 
0600 
0601 
0602 
0603 
0604 inline void RelayInventory(const CInv& inv)
0605 {
0606     // Put on lists to offer to the other nodes
0607     CRITICAL_BLOCK(cs_vNodes)
0608         BOOST_FOREACH(CNode* pnode, vNodes)
0609             pnode->PushInventory(inv);
0610 }
0611 
0612 template<typename T>
0613 void RelayMessage(const CInv& inv, const T& a)
0614 {
0615     CDataStream ss(SER_NETWORK);
0616     ss.reserve(10000);
0617     ss << a;
0618     RelayMessage(inv, ss);
0619 }
0620 
0621 template<>
0622 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
0623 {
0624     CRITICAL_BLOCK(cs_mapRelay)
0625     {
0626         // Expire old relay messages
0627         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
0628         {
0629             mapRelay.erase(vRelayExpiration.front().second);
0630             vRelayExpiration.pop_front();
0631         }
0632 
0633         // Save original serialized message so newer versions are preserved
0634         mapRelay[inv] = ss;
0635         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
0636     }
0637 
0638     RelayInventory(inv);
0639 }
0640 
0641 
0642 
0643 
0644 
0645 
0646 
0647 
0648 //
0649 // Templates for the publish and subscription system.
0650 // The object being published as T& obj needs to have:
0651 //   a set<unsigned int> setSources member
0652 //   specializations of AdvertInsert and AdvertErase
0653 // Currently implemented for CTable and CProduct.
0654 //
0655 
0656 template<typename T>
0657 void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
0658 {
0659     // Add to sources
0660     obj.setSources.insert(pfrom->addr.ip);
0661 
0662     if (!AdvertInsert(obj))
0663         return;
0664 
0665     // Relay
0666     CRITICAL_BLOCK(cs_vNodes)
0667         BOOST_FOREACH(CNode* pnode, vNodes)
0668             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
0669                 pnode->PushMessage("publish", nChannel, nHops, obj);
0670 }
0671 
0672 template<typename T>
0673 void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
0674 {
0675     uint256 hash = obj.GetHash();
0676 
0677     CRITICAL_BLOCK(cs_vNodes)
0678         BOOST_FOREACH(CNode* pnode, vNodes)
0679             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
0680                 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
0681 
0682     AdvertErase(obj);
0683 }
0684 
0685 template<typename T>
0686 void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
0687 {
0688     // Remove a source
0689     obj.setSources.erase(pfrom->addr.ip);
0690 
0691     // If no longer supported by any sources, cancel it
0692     if (obj.setSources.empty())
0693         AdvertStopPublish(pfrom, nChannel, nHops, obj);
0694 }
0695 
0696 #endif