genesis                 1 
genesis                 2 
genesis                 3 
genesis                 4 
genesis                 5 #ifndef BITCOIN_NET_H
genesis                 6 #define BITCOIN_NET_H
genesis                 7 
genesis                 8 #include <deque>
genesis                 9 #include <boost/array.hpp>
genesis                10 #include <boost/foreach.hpp>
genesis                11 #include <openssl/rand.h>
genesis                12 
genesis                13 #include "protocol.h"
genesis                14 
genesis                15 class CAddrDB;
genesis                16 class CRequestTracker;
genesis                17 class CNode;
genesis                18 class CBlockIndex;
genesis                19 extern int nBestHeight;
genesis                20 extern int nConnectTimeout;
genesis                21 
genesis                22 
genesis                23 
genesis                24 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
genesis                25 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
genesis                26 static const unsigned int PUBLISH_HOPS = 5;
genesis                27 
genesis                28 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
asciilifeform_dns...   29 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, int portDefault = 0, bool fAllowPort = false);
asciilifeform_dns...   30 bool Lookup(const char *pszName, CAddress& addr, int nServices, int portDefault = 0, bool fAllowPort = false);
genesis                31 bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
genesis                32 void AddressCurrentlyConnected(const CAddress& addr);
genesis                33 CNode* FindNode(unsigned int ip);
genesis                34 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
genesis                35 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
genesis                36 bool AnySubscribed(unsigned int nChannel);
genesis                37 void MapPort(bool fMapPort);
genesis                38 bool BindListenPort(std::string& strError=REF(std::string()));
genesis                39 void StartNode(void* parg);
genesis                40 bool StopNode();
genesis                41 
genesis                42 enum
genesis                43 {
genesis                44     MSG_TX = 1,
genesis                45     MSG_BLOCK,
genesis                46 };
genesis                47 
genesis                48 class CRequestTracker
genesis                49 {
genesis                50 public:
genesis                51     void (*fn)(void*, CDataStream&);
genesis                52     void* param1;
genesis                53 
genesis                54     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
genesis                55     {
genesis                56         fn = fnIn;
genesis                57         param1 = param1In;
genesis                58     }
genesis                59 
genesis                60     bool IsNull()
genesis                61     {
genesis                62         return fn == NULL;
genesis                63     }
genesis                64 };
genesis                65 
genesis                66 
genesis                67 
genesis                68 
genesis                69 
genesis                70 extern bool fClient;
genesis                71 extern bool fAllowDNS;
genesis                72 extern uint64 nLocalServices;
genesis                73 extern CAddress addrLocalHost;
genesis                74 extern uint64 nLocalHostNonce;
genesis                75 extern boost::array<int, 10> vnThreadsRunning;
genesis                76 
genesis                77 extern std::vector<CNode*> vNodes;
genesis                78 extern CCriticalSection cs_vNodes;
genesis                79 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
genesis                80 extern CCriticalSection cs_mapAddresses;
genesis                81 extern std::map<CInv, CDataStream> mapRelay;
genesis                82 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
genesis                83 extern CCriticalSection cs_mapRelay;
genesis                84 extern std::map<CInv, int64> mapAlreadyAskedFor;
genesis                85 
genesis                86 
genesis                87 extern int fUseProxy;
genesis                88 extern CAddress addrProxy;
genesis                89 
genesis                90 
genesis                91 
genesis                92 
genesis                93 
genesis                94 
genesis                95 class CNode
genesis                96 {
genesis                97 public:
genesis                98     
genesis                99     uint64 nServices;
genesis               100     SOCKET hSocket;
genesis               101     CDataStream vSend;
genesis               102     CDataStream vRecv;
genesis               103     CCriticalSection cs_vSend;
genesis               104     CCriticalSection cs_vRecv;
genesis               105     int64 nLastSend;
genesis               106     int64 nLastRecv;
genesis               107     int64 nLastSendEmpty;
genesis               108     int64 nTimeConnected;
genesis               109     unsigned int nHeaderStart;
genesis               110     unsigned int nMessageStart;
genesis               111     CAddress addr;
genesis               112     int nVersion;
genesis               113     std::string strSubVer;
genesis               114     bool fClient;
genesis               115     bool fInbound;
genesis               116     bool fNetworkNode;
genesis               117     bool fSuccessfullyConnected;
genesis               118     bool fDisconnect;
genesis               119 protected:
genesis               120     int nRefCount;
genesis               121 
genesis               122     
genesis               123     
genesis               124     static std::map<unsigned int, int64> setBanned;
genesis               125     static CCriticalSection cs_setBanned;
genesis               126     int nMisbehavior;
genesis               127 
genesis               128 public:
genesis               129     int64 nReleaseTime;
genesis               130     std::map<uint256, CRequestTracker> mapRequests;
genesis               131     CCriticalSection cs_mapRequests;
genesis               132     uint256 hashContinue;
genesis               133     CBlockIndex* pindexLastGetBlocksBegin;
genesis               134     uint256 hashLastGetBlocksEnd;
genesis               135     int nStartingHeight;
genesis               136 
genesis               137     
genesis               138     std::vector<CAddress> vAddrToSend;
genesis               139     std::set<CAddress> setAddrKnown;
genesis               140     bool fGetAddr;
genesis               141     std::set<uint256> setKnown;
genesis               142 
genesis               143     
genesis               144     std::set<CInv> setInventoryKnown;
genesis               145     std::vector<CInv> vInventoryToSend;
genesis               146     CCriticalSection cs_inventory;
genesis               147     std::multimap<int64, CInv> mapAskFor;
genesis               148 
genesis               149     
genesis               150     std::vector<char> vfSubscribe;
genesis               151 
genesis               152     CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
genesis               153     {
genesis               154         nServices = 0;
genesis               155         hSocket = hSocketIn;
genesis               156         vSend.SetType(SER_NETWORK);
genesis               157         vSend.SetVersion(0);
genesis               158         vRecv.SetType(SER_NETWORK);
genesis               159         vRecv.SetVersion(0);
genesis               160         
genesis               161         if (GetTime() > 1329696000)
genesis               162         {
genesis               163             vSend.SetVersion(209);
genesis               164             vRecv.SetVersion(209);
genesis               165         }
genesis               166         nLastSend = 0;
genesis               167         nLastRecv = 0;
genesis               168         nLastSendEmpty = GetTime();
genesis               169         nTimeConnected = GetTime();
genesis               170         nHeaderStart = -1;
genesis               171         nMessageStart = -1;
genesis               172         addr = addrIn;
genesis               173         nVersion = 0;
genesis               174         strSubVer = "";
genesis               175         fClient = false; 
genesis               176         fInbound = fInboundIn;
genesis               177         fNetworkNode = false;
genesis               178         fSuccessfullyConnected = false;
genesis               179         fDisconnect = false;
genesis               180         nRefCount = 0;
genesis               181         nReleaseTime = 0;
genesis               182         hashContinue = 0;
genesis               183         pindexLastGetBlocksBegin = 0;
genesis               184         hashLastGetBlocksEnd = 0;
genesis               185         nStartingHeight = -1;
genesis               186         fGetAddr = false;
genesis               187         vfSubscribe.assign(256, false);
genesis               188         nMisbehavior = 0;
genesis               189 
genesis               190         
genesis               191         if (!fInbound)
genesis               192             PushVersion();
genesis               193     }
genesis               194 
genesis               195     ~CNode()
genesis               196     {
genesis               197         if (hSocket != INVALID_SOCKET)
genesis               198         {
genesis               199             closesocket(hSocket);
genesis               200             hSocket = INVALID_SOCKET;
genesis               201         }
genesis               202     }
genesis               203 
genesis               204 private:
genesis               205     CNode(const CNode&);
genesis               206     void operator=(const CNode&);
genesis               207 public:
genesis               208 
genesis               209 
genesis               210     int GetRefCount()
genesis               211     {
genesis               212         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
genesis               213     }
genesis               214 
genesis               215     CNode* AddRef(int64 nTimeout=0)
genesis               216     {
genesis               217         if (nTimeout != 0)
genesis               218             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
genesis               219         else
genesis               220             nRefCount++;
genesis               221         return this;
genesis               222     }
genesis               223 
genesis               224     void Release()
genesis               225     {
genesis               226         nRefCount--;
genesis               227     }
genesis               228 
genesis               229 
genesis               230 
genesis               231     void AddAddressKnown(const CAddress& addr)
genesis               232     {
genesis               233         setAddrKnown.insert(addr);
genesis               234     }
genesis               235 
genesis               236     void PushAddress(const CAddress& addr)
genesis               237     {
genesis               238         
genesis               239         
genesis               240         
genesis               241         if (addr.IsValid() && !setAddrKnown.count(addr))
genesis               242             vAddrToSend.push_back(addr);
genesis               243     }
genesis               244 
genesis               245 
genesis               246     void AddInventoryKnown(const CInv& inv)
genesis               247     {
genesis               248         CRITICAL_BLOCK(cs_inventory)
genesis               249             setInventoryKnown.insert(inv);
genesis               250     }
genesis               251 
genesis               252     void PushInventory(const CInv& inv)
genesis               253     {
genesis               254         CRITICAL_BLOCK(cs_inventory)
genesis               255             if (!setInventoryKnown.count(inv))
genesis               256                 vInventoryToSend.push_back(inv);
genesis               257     }
genesis               258 
genesis               259     void AskFor(const CInv& inv)
genesis               260     {
genesis               261         
genesis               262         
genesis               263         int64& nRequestTime = mapAlreadyAskedFor[inv];
genesis               264         printf("askfor %s   %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
genesis               265 
genesis               266         
genesis               267         int64 nNow = (GetTime() - 1) * 1000000;
genesis               268         static int64 nLastTime;
genesis               269         ++nLastTime;
genesis               270         nNow = std::max(nNow, nLastTime);
genesis               271         nLastTime = nNow;
genesis               272 
genesis               273         
genesis               274         nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
genesis               275         mapAskFor.insert(std::make_pair(nRequestTime, inv));
genesis               276     }
genesis               277 
genesis               278 
genesis               279 
genesis               280     void BeginMessage(const char* pszCommand)
genesis               281     {
genesis               282         ENTER_CRITICAL_SECTION(cs_vSend);
genesis               283         if (nHeaderStart != -1)
genesis               284             AbortMessage();
genesis               285         nHeaderStart = vSend.size();
genesis               286         vSend << CMessageHeader(pszCommand, 0);
genesis               287         nMessageStart = vSend.size();
genesis               288         if (fDebug) {
genesis               289             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
genesis               290             printf("sending: %s ", pszCommand);
genesis               291         }
genesis               292     }
genesis               293 
genesis               294     void AbortMessage()
genesis               295     {
genesis               296         if (nHeaderStart == -1)
genesis               297             return;
genesis               298         vSend.resize(nHeaderStart);
genesis               299         nHeaderStart = -1;
genesis               300         nMessageStart = -1;
genesis               301         LEAVE_CRITICAL_SECTION(cs_vSend);
genesis               302 
genesis               303         if (fDebug)
genesis               304             printf("(aborted)\n");
genesis               305     }
genesis               306 
genesis               307     void EndMessage()
genesis               308     {
genesis               309         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
genesis               310         {
genesis               311             printf("dropmessages DROPPING SEND MESSAGE\n");
genesis               312             AbortMessage();
genesis               313             return;
genesis               314         }
genesis               315 
genesis               316         if (nHeaderStart == -1)
genesis               317             return;
genesis               318 
genesis               319         
genesis               320         unsigned int nSize = vSend.size() - nMessageStart;
genesis               321         memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
genesis               322 
genesis               323         
genesis               324         if (vSend.GetVersion() >= 209)
genesis               325         {
genesis               326             uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
genesis               327             unsigned int nChecksum = 0;
genesis               328             memcpy(&nChecksum, &hash, sizeof(nChecksum));
genesis               329             assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
genesis               330             memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
genesis               331         }
genesis               332 
genesis               333         if (fDebug) {
genesis               334             printf("(%d bytes)\n", nSize);
genesis               335         }
genesis               336 
genesis               337         nHeaderStart = -1;
genesis               338         nMessageStart = -1;
genesis               339         LEAVE_CRITICAL_SECTION(cs_vSend);
genesis               340     }
genesis               341 
genesis               342     void EndMessageAbortIfEmpty()
genesis               343     {
genesis               344         if (nHeaderStart == -1)
genesis               345             return;
genesis               346         int nSize = vSend.size() - nMessageStart;
genesis               347         if (nSize > 0)
genesis               348             EndMessage();
genesis               349         else
genesis               350             AbortMessage();
genesis               351     }
genesis               352 
genesis               353 
genesis               354 
genesis               355     void PushVersion()
genesis               356     {
genesis               357         
genesis               358         int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
genesis               359         CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
genesis               360         CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress("0.0.0.0") : addrLocalHost);
genesis               361         RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
genesis               362         PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
programmable-vers...  363                     nLocalHostNonce, FormatSubVersion(CLIENT_NAME, VERSION), nBestHeight);
genesis               364     }
genesis               365 
genesis               366 
genesis               367 
genesis               368 
genesis               369     void PushMessage(const char* pszCommand)
genesis               370     {
genesis               371         try
genesis               372         {
genesis               373             BeginMessage(pszCommand);
genesis               374             EndMessage();
genesis               375         }
genesis               376         catch (...)
genesis               377         {
genesis               378             AbortMessage();
genesis               379             throw;
genesis               380         }
genesis               381     }
genesis               382 
genesis               383     template<typename T1>
genesis               384     void PushMessage(const char* pszCommand, const T1& a1)
genesis               385     {
genesis               386         try
genesis               387         {
genesis               388             BeginMessage(pszCommand);
genesis               389             vSend << a1;
genesis               390             EndMessage();
genesis               391         }
genesis               392         catch (...)
genesis               393         {
genesis               394             AbortMessage();
genesis               395             throw;
genesis               396         }
genesis               397     }
genesis               398 
genesis               399     template<typename T1, typename T2>
genesis               400     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
genesis               401     {
genesis               402         try
genesis               403         {
genesis               404             BeginMessage(pszCommand);
genesis               405             vSend << a1 << a2;
genesis               406             EndMessage();
genesis               407         }
genesis               408         catch (...)
genesis               409         {
genesis               410             AbortMessage();
genesis               411             throw;
genesis               412         }
genesis               413     }
genesis               414 
genesis               415     template<typename T1, typename T2, typename T3>
genesis               416     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
genesis               417     {
genesis               418         try
genesis               419         {
genesis               420             BeginMessage(pszCommand);
genesis               421             vSend << a1 << a2 << a3;
genesis               422             EndMessage();
genesis               423         }
genesis               424         catch (...)
genesis               425         {
genesis               426             AbortMessage();
genesis               427             throw;
genesis               428         }
genesis               429     }
genesis               430 
genesis               431     template<typename T1, typename T2, typename T3, typename T4>
genesis               432     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
genesis               433     {
genesis               434         try
genesis               435         {
genesis               436             BeginMessage(pszCommand);
genesis               437             vSend << a1 << a2 << a3 << a4;
genesis               438             EndMessage();
genesis               439         }
genesis               440         catch (...)
genesis               441         {
genesis               442             AbortMessage();
genesis               443             throw;
genesis               444         }
genesis               445     }
genesis               446 
genesis               447     template<typename T1, typename T2, typename T3, typename T4, typename T5>
genesis               448     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
genesis               449     {
genesis               450         try
genesis               451         {
genesis               452             BeginMessage(pszCommand);
genesis               453             vSend << a1 << a2 << a3 << a4 << a5;
genesis               454             EndMessage();
genesis               455         }
genesis               456         catch (...)
genesis               457         {
genesis               458             AbortMessage();
genesis               459             throw;
genesis               460         }
genesis               461     }
genesis               462 
genesis               463     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
genesis               464     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
genesis               465     {
genesis               466         try
genesis               467         {
genesis               468             BeginMessage(pszCommand);
genesis               469             vSend << a1 << a2 << a3 << a4 << a5 << a6;
genesis               470             EndMessage();
genesis               471         }
genesis               472         catch (...)
genesis               473         {
genesis               474             AbortMessage();
genesis               475             throw;
genesis               476         }
genesis               477     }
genesis               478 
genesis               479     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
genesis               480     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)
genesis               481     {
genesis               482         try
genesis               483         {
genesis               484             BeginMessage(pszCommand);
genesis               485             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
genesis               486             EndMessage();
genesis               487         }
genesis               488         catch (...)
genesis               489         {
genesis               490             AbortMessage();
genesis               491             throw;
genesis               492         }
genesis               493     }
genesis               494 
genesis               495     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
genesis               496     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)
genesis               497     {
genesis               498         try
genesis               499         {
genesis               500             BeginMessage(pszCommand);
genesis               501             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
genesis               502             EndMessage();
genesis               503         }
genesis               504         catch (...)
genesis               505         {
genesis               506             AbortMessage();
genesis               507             throw;
genesis               508         }
genesis               509     }
genesis               510 
genesis               511     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
genesis               512     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)
genesis               513     {
genesis               514         try
genesis               515         {
genesis               516             BeginMessage(pszCommand);
genesis               517             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
genesis               518             EndMessage();
genesis               519         }
genesis               520         catch (...)
genesis               521         {
genesis               522             AbortMessage();
genesis               523             throw;
genesis               524         }
genesis               525     }
genesis               526 
genesis               527 
genesis               528     void PushRequest(const char* pszCommand,
genesis               529                      void (*fn)(void*, CDataStream&), void* param1)
genesis               530     {
genesis               531         uint256 hashReply;
genesis               532         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis               533 
genesis               534         CRITICAL_BLOCK(cs_mapRequests)
genesis               535             mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis               536 
genesis               537         PushMessage(pszCommand, hashReply);
genesis               538     }
genesis               539 
genesis               540     template<typename T1>
genesis               541     void PushRequest(const char* pszCommand, const T1& a1,
genesis               542                      void (*fn)(void*, CDataStream&), void* param1)
genesis               543     {
genesis               544         uint256 hashReply;
genesis               545         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis               546 
genesis               547         CRITICAL_BLOCK(cs_mapRequests)
genesis               548             mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis               549 
genesis               550         PushMessage(pszCommand, hashReply, a1);
genesis               551     }
genesis               552 
genesis               553     template<typename T1, typename T2>
genesis               554     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
genesis               555                      void (*fn)(void*, CDataStream&), void* param1)
genesis               556     {
genesis               557         uint256 hashReply;
genesis               558         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis               559 
genesis               560         CRITICAL_BLOCK(cs_mapRequests)
genesis               561             mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis               562 
genesis               563         PushMessage(pszCommand, hashReply, a1, a2);
genesis               564     }
genesis               565 
genesis               566 
genesis               567 
genesis               568     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
genesis               569     bool IsSubscribed(unsigned int nChannel);
genesis               570     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
genesis               571     void CancelSubscribe(unsigned int nChannel);
genesis               572     void CloseSocketDisconnect();
genesis               573     void Cleanup();
genesis               574 
genesis               575 
genesis               576     
genesis               577     
genesis               578     
genesis               579     
genesis               580     
genesis               581     
genesis               582     
genesis               583     
genesis               584     
genesis               585     
genesis               586     
genesis               587     
genesis               588     
genesis               589     
genesis               590     static void ClearBanned(); 
genesis               591     static bool IsBanned(unsigned int ip);
genesis               592     bool Misbehaving(int howmuch); 
genesis               593 };
genesis               594 
genesis               595 
genesis               596 
genesis               597 
genesis               598 
genesis               599 
genesis               600 
genesis               601 
genesis               602 
genesis               603 
genesis               604 inline void RelayInventory(const CInv& inv)
genesis               605 {
genesis               606     
genesis               607     CRITICAL_BLOCK(cs_vNodes)
genesis               608         BOOST_FOREACH(CNode* pnode, vNodes)
genesis               609             pnode->PushInventory(inv);
genesis               610 }
genesis               611 
genesis               612 template<typename T>
genesis               613 void RelayMessage(const CInv& inv, const T& a)
genesis               614 {
genesis               615     CDataStream ss(SER_NETWORK);
genesis               616     ss.reserve(10000);
genesis               617     ss << a;
genesis               618     RelayMessage(inv, ss);
genesis               619 }
genesis               620 
genesis               621 template<>
genesis               622 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
genesis               623 {
genesis               624     CRITICAL_BLOCK(cs_mapRelay)
genesis               625     {
genesis               626         
genesis               627         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
genesis               628         {
genesis               629             mapRelay.erase(vRelayExpiration.front().second);
genesis               630             vRelayExpiration.pop_front();
genesis               631         }
genesis               632 
genesis               633         
genesis               634         mapRelay[inv] = ss;
genesis               635         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
genesis               636     }
genesis               637 
genesis               638     RelayInventory(inv);
genesis               639 }
genesis               640 
genesis               641 
genesis               642 
genesis               643 
genesis               644 
genesis               645 
genesis               646 
genesis               647 
genesis               648 
genesis               649 
genesis               650 
genesis               651 
genesis               652 
genesis               653 
genesis               654 
genesis               655 
genesis               656 template<typename T>
genesis               657 void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis               658 {
genesis               659     
genesis               660     obj.setSources.insert(pfrom->addr.ip);
genesis               661 
genesis               662     if (!AdvertInsert(obj))
genesis               663         return;
genesis               664 
genesis               665     
genesis               666     CRITICAL_BLOCK(cs_vNodes)
genesis               667         BOOST_FOREACH(CNode* pnode, vNodes)
genesis               668             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
genesis               669                 pnode->PushMessage("publish", nChannel, nHops, obj);
genesis               670 }
genesis               671 
genesis               672 template<typename T>
genesis               673 void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis               674 {
genesis               675     uint256 hash = obj.GetHash();
genesis               676 
genesis               677     CRITICAL_BLOCK(cs_vNodes)
genesis               678         BOOST_FOREACH(CNode* pnode, vNodes)
genesis               679             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
genesis               680                 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
genesis               681 
genesis               682     AdvertErase(obj);
genesis               683 }
genesis               684 
genesis               685 template<typename T>
genesis               686 void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis               687 {
genesis               688     
genesis               689     obj.setSources.erase(pfrom->addr.ip);
genesis               690 
genesis               691     
genesis               692     if (obj.setSources.empty())
genesis               693         AdvertStopPublish(pfrom, nChannel, nHops, obj);
genesis               694 }
genesis               695 
genesis               696 #endif