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