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