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