Update License in File Headers
[novacoin.git] / src / net.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING 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 WIN32
14 #include <arpa/inet.h>
15 #endif
16
17 #include "mruset.h"
18 #include "netbase.h"
19 #include "protocol.h"
20 #include "addrman.h"
21
22 class CAddrDB;
23 class CRequestTracker;
24 class CNode;
25 class CBlockIndex;
26 extern int nBestHeight;
27
28
29
30 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
31 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
32
33 bool RecvLine(SOCKET hSocket, std::string& strLine);
34 bool GetMyExternalIP(CNetAddr& ipRet);
35 void AddressCurrentlyConnected(const CService& addr);
36 CNode* FindNode(const CNetAddr& ip);
37 CNode* FindNode(const CService& ip);
38 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
39 void MapPort(bool fMapPort);
40 bool BindListenPort(std::string& strError=REF(std::string()));
41 void StartNode(void* parg);
42 bool StopNode();
43
44 enum
45 {
46     MSG_TX = 1,
47     MSG_BLOCK,
48 };
49
50 class CRequestTracker
51 {
52 public:
53     void (*fn)(void*, CDataStream&);
54     void* param1;
55
56     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
57     {
58         fn = fnIn;
59         param1 = param1In;
60     }
61
62     bool IsNull()
63     {
64         return fn == NULL;
65     }
66 };
67
68
69 /** Thread types */
70 enum threadId
71 {
72     THREAD_SOCKETHANDLER,
73     THREAD_OPENCONNECTIONS,
74     THREAD_MESSAGEHANDLER,
75     THREAD_MINER,
76     THREAD_RPCSERVER,
77     THREAD_UPNP,
78     THREAD_DNSSEED,
79     THREAD_ADDEDCONNECTIONS,
80     THREAD_DUMPADDRESS,
81
82     THREAD_MAX
83 };
84
85 extern bool fClient;
86 extern bool fAllowDNS;
87 extern uint64 nLocalServices;
88 extern CAddress addrLocalHost;
89 extern uint64 nLocalHostNonce;
90 extern boost::array<int, THREAD_MAX> vnThreadsRunning;
91 extern CAddrMan addrman;
92
93 extern std::vector<CNode*> vNodes;
94 extern CCriticalSection cs_vNodes;
95 extern std::map<CInv, CDataStream> mapRelay;
96 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
97 extern CCriticalSection cs_mapRelay;
98 extern std::map<CInv, int64> mapAlreadyAskedFor;
99
100
101
102
103
104
105 /** Information about a peer */
106 class CNode
107 {
108 public:
109     // socket
110     uint64 nServices;
111     SOCKET hSocket;
112     CDataStream vSend;
113     CDataStream vRecv;
114     CCriticalSection cs_vSend;
115     CCriticalSection cs_vRecv;
116     int64 nLastSend;
117     int64 nLastRecv;
118     int64 nLastSendEmpty;
119     int64 nTimeConnected;
120     int nHeaderStart;
121     unsigned int nMessageStart;
122     CAddress addr;
123     int nVersion;
124     std::string strSubVer;
125     bool fClient;
126     bool fInbound;
127     bool fNetworkNode;
128     bool fSuccessfullyConnected;
129     bool fDisconnect;
130     bool fHasGrant; // whether to call semOutbound.post() at disconnect
131 protected:
132     int nRefCount;
133
134     // Denial-of-service detection/prevention
135     // Key is ip address, value is banned-until-time
136     static std::map<CNetAddr, int64> setBanned;
137     static CCriticalSection cs_setBanned;
138     int nMisbehavior;
139
140 public:
141     int64 nReleaseTime;
142     std::map<uint256, CRequestTracker> mapRequests;
143     CCriticalSection cs_mapRequests;
144     uint256 hashContinue;
145     CBlockIndex* pindexLastGetBlocksBegin;
146     uint256 hashLastGetBlocksEnd;
147     int nStartingHeight;
148
149     // flood relay
150     std::vector<CAddress> vAddrToSend;
151     std::set<CAddress> setAddrKnown;
152     bool fGetAddr;
153     std::set<uint256> setKnown;
154
155     // inventory based relay
156     mruset<CInv> setInventoryKnown;
157     std::vector<CInv> vInventoryToSend;
158     CCriticalSection cs_inventory;
159     std::multimap<int64, CInv> mapAskFor;
160
161     CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
162     {
163         nServices = 0;
164         hSocket = hSocketIn;
165         nLastSend = 0;
166         nLastRecv = 0;
167         nLastSendEmpty = GetTime();
168         nTimeConnected = GetTime();
169         nHeaderStart = -1;
170         nMessageStart = -1;
171         addr = addrIn;
172         nVersion = 0;
173         strSubVer = "";
174         fClient = false; // set by version message
175         fHasGrant = false;
176         fInbound = fInboundIn;
177         fNetworkNode = false;
178         fSuccessfullyConnected = false;
179         fDisconnect = false;
180         nRefCount = 0;
181         nReleaseTime = 0;
182         hashContinue = 0;
183         pindexLastGetBlocksBegin = 0;
184         hashLastGetBlocksEnd = 0;
185         nStartingHeight = -1;
186         fGetAddr = false;
187         nMisbehavior = 0;
188         setInventoryKnown.max_size(SendBufferSize() / 1000);
189
190         // Be shy and don't send version until we hear
191         if (!fInbound)
192             PushVersion();
193     }
194
195     ~CNode()
196     {
197         if (hSocket != INVALID_SOCKET)
198         {
199             closesocket(hSocket);
200             hSocket = INVALID_SOCKET;
201         }
202     }
203
204 private:
205     CNode(const CNode&);
206     void operator=(const CNode&);
207 public:
208
209
210     int GetRefCount()
211     {
212         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
213     }
214
215     CNode* AddRef(int64 nTimeout=0)
216     {
217         if (nTimeout != 0)
218             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
219         else
220             nRefCount++;
221         return this;
222     }
223
224     void Release()
225     {
226         nRefCount--;
227     }
228
229
230
231     void AddAddressKnown(const CAddress& addr)
232     {
233         setAddrKnown.insert(addr);
234     }
235
236     void PushAddress(const CAddress& addr)
237     {
238         // Known checking here is only to save space from duplicates.
239         // SendMessages will filter it again for knowns that were added
240         // after addresses were pushed.
241         if (addr.IsValid() && !setAddrKnown.count(addr))
242             vAddrToSend.push_back(addr);
243     }
244
245
246     void AddInventoryKnown(const CInv& inv)
247     {
248         {
249             LOCK(cs_inventory);
250             setInventoryKnown.insert(inv);
251         }
252     }
253
254     void PushInventory(const CInv& inv)
255     {
256         {
257             LOCK(cs_inventory);
258             if (!setInventoryKnown.count(inv))
259                 vInventoryToSend.push_back(inv);
260         }
261     }
262
263     void AskFor(const CInv& inv)
264     {
265         // We're using mapAskFor as a priority queue,
266         // the key is the earliest time the request can be sent
267         int64& nRequestTime = mapAlreadyAskedFor[inv];
268         printf("askfor %s   %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
269
270         // Make sure not to reuse time indexes to keep things in the same order
271         int64 nNow = (GetTime() - 1) * 1000000;
272         static int64 nLastTime;
273         ++nLastTime;
274         nNow = std::max(nNow, nLastTime);
275         nLastTime = nNow;
276
277         // Each retry is 2 minutes after the last
278         nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
279         mapAskFor.insert(std::make_pair(nRequestTime, inv));
280     }
281
282
283
284     void BeginMessage(const char* pszCommand)
285     {
286         ENTER_CRITICAL_SECTION(cs_vSend);
287         if (nHeaderStart != -1)
288             AbortMessage();
289         nHeaderStart = vSend.size();
290         vSend << CMessageHeader(pszCommand, 0);
291         nMessageStart = vSend.size();
292         if (fDebug) {
293             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
294             printf("sending: %s ", pszCommand);
295         }
296     }
297
298     void AbortMessage()
299     {
300         if (nHeaderStart < 0)
301             return;
302         vSend.resize(nHeaderStart);
303         nHeaderStart = -1;
304         nMessageStart = -1;
305         LEAVE_CRITICAL_SECTION(cs_vSend);
306
307         if (fDebug)
308             printf("(aborted)\n");
309     }
310
311     void EndMessage()
312     {
313         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
314         {
315             printf("dropmessages DROPPING SEND MESSAGE\n");
316             AbortMessage();
317             return;
318         }
319
320         if (nHeaderStart < 0)
321             return;
322
323         // Set the size
324         unsigned int nSize = vSend.size() - nMessageStart;
325         memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
326
327         // Set the checksum
328         uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
329         unsigned int nChecksum = 0;
330         memcpy(&nChecksum, &hash, sizeof(nChecksum));
331         assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
332         memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
333
334         if (fDebug) {
335             printf("(%d bytes)\n", nSize);
336         }
337
338         nHeaderStart = -1;
339         nMessageStart = -1;
340         LEAVE_CRITICAL_SECTION(cs_vSend);
341     }
342
343     void EndMessageAbortIfEmpty()
344     {
345         if (nHeaderStart < 0)
346             return;
347         int nSize = vSend.size() - nMessageStart;
348         if (nSize > 0)
349             EndMessage();
350         else
351             AbortMessage();
352     }
353
354
355
356     void PushVersion();
357
358
359     void PushMessage(const char* pszCommand)
360     {
361         try
362         {
363             BeginMessage(pszCommand);
364             EndMessage();
365         }
366         catch (...)
367         {
368             AbortMessage();
369             throw;
370         }
371     }
372
373     template<typename T1>
374     void PushMessage(const char* pszCommand, const T1& a1)
375     {
376         try
377         {
378             BeginMessage(pszCommand);
379             vSend << a1;
380             EndMessage();
381         }
382         catch (...)
383         {
384             AbortMessage();
385             throw;
386         }
387     }
388
389     template<typename T1, typename T2>
390     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
391     {
392         try
393         {
394             BeginMessage(pszCommand);
395             vSend << a1 << a2;
396             EndMessage();
397         }
398         catch (...)
399         {
400             AbortMessage();
401             throw;
402         }
403     }
404
405     template<typename T1, typename T2, typename T3>
406     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
407     {
408         try
409         {
410             BeginMessage(pszCommand);
411             vSend << a1 << a2 << a3;
412             EndMessage();
413         }
414         catch (...)
415         {
416             AbortMessage();
417             throw;
418         }
419     }
420
421     template<typename T1, typename T2, typename T3, typename T4>
422     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
423     {
424         try
425         {
426             BeginMessage(pszCommand);
427             vSend << a1 << a2 << a3 << a4;
428             EndMessage();
429         }
430         catch (...)
431         {
432             AbortMessage();
433             throw;
434         }
435     }
436
437     template<typename T1, typename T2, typename T3, typename T4, typename T5>
438     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
439     {
440         try
441         {
442             BeginMessage(pszCommand);
443             vSend << a1 << a2 << a3 << a4 << a5;
444             EndMessage();
445         }
446         catch (...)
447         {
448             AbortMessage();
449             throw;
450         }
451     }
452
453     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
454     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
455     {
456         try
457         {
458             BeginMessage(pszCommand);
459             vSend << a1 << a2 << a3 << a4 << a5 << a6;
460             EndMessage();
461         }
462         catch (...)
463         {
464             AbortMessage();
465             throw;
466         }
467     }
468
469     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
470     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)
471     {
472         try
473         {
474             BeginMessage(pszCommand);
475             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
476             EndMessage();
477         }
478         catch (...)
479         {
480             AbortMessage();
481             throw;
482         }
483     }
484
485     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
486     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)
487     {
488         try
489         {
490             BeginMessage(pszCommand);
491             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
492             EndMessage();
493         }
494         catch (...)
495         {
496             AbortMessage();
497             throw;
498         }
499     }
500
501     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
502     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)
503     {
504         try
505         {
506             BeginMessage(pszCommand);
507             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
508             EndMessage();
509         }
510         catch (...)
511         {
512             AbortMessage();
513             throw;
514         }
515     }
516
517
518     void PushRequest(const char* pszCommand,
519                      void (*fn)(void*, CDataStream&), void* param1)
520     {
521         uint256 hashReply;
522         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
523
524         {
525             LOCK(cs_mapRequests);
526             mapRequests[hashReply] = CRequestTracker(fn, param1);
527         }
528
529         PushMessage(pszCommand, hashReply);
530     }
531
532     template<typename T1>
533     void PushRequest(const char* pszCommand, const T1& a1,
534                      void (*fn)(void*, CDataStream&), void* param1)
535     {
536         uint256 hashReply;
537         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
538
539         {
540             LOCK(cs_mapRequests);
541             mapRequests[hashReply] = CRequestTracker(fn, param1);
542         }
543
544         PushMessage(pszCommand, hashReply, a1);
545     }
546
547     template<typename T1, typename T2>
548     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
549                      void (*fn)(void*, CDataStream&), void* param1)
550     {
551         uint256 hashReply;
552         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
553
554         {
555             LOCK(cs_mapRequests);
556             mapRequests[hashReply] = CRequestTracker(fn, param1);
557         }
558
559         PushMessage(pszCommand, hashReply, a1, a2);
560     }
561
562
563
564     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
565     bool IsSubscribed(unsigned int nChannel);
566     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
567     void CancelSubscribe(unsigned int nChannel);
568     void CloseSocketDisconnect();
569     void Cleanup();
570
571
572     // Denial-of-service detection/prevention
573     // The idea is to detect peers that are behaving
574     // badly and disconnect/ban them, but do it in a
575     // one-coding-mistake-won't-shatter-the-entire-network
576     // way.
577     // IMPORTANT:  There should be nothing I can give a
578     // node that it will forward on that will make that
579     // node's peers drop it. If there is, an attacker
580     // can isolate a node and/or try to split the network.
581     // Dropping a node for sending stuff that is invalid
582     // now but might be valid in a later version is also
583     // dangerous, because it can cause a network split
584     // between nodes running old code and nodes running
585     // new code.
586     static void ClearBanned(); // needed for unit testing
587     static bool IsBanned(CNetAddr ip);
588     bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
589 };
590
591
592
593
594
595
596
597
598
599
600 inline void RelayInventory(const CInv& inv)
601 {
602     // Put on lists to offer to the other nodes
603     {
604         LOCK(cs_vNodes);
605         BOOST_FOREACH(CNode* pnode, vNodes)
606             pnode->PushInventory(inv);
607     }
608 }
609
610 template<typename T>
611 void RelayMessage(const CInv& inv, const T& a)
612 {
613     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
614     ss.reserve(10000);
615     ss << a;
616     RelayMessage(inv, ss);
617 }
618
619 template<>
620 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
621 {
622     {
623         LOCK(cs_mapRelay);
624         // Expire old relay messages
625         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
626         {
627             mapRelay.erase(vRelayExpiration.front().second);
628             vRelayExpiration.pop_front();
629         }
630
631         // Save original serialized message so newer versions are preserved
632         mapRelay.insert(std::make_pair(inv, ss));
633         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
634     }
635
636     RelayInventory(inv);
637 }
638
639
640 #endif