[depends] native ccache 3.2.4
[bitcoinplatinum.git] / src / net.h
blobf90b3385afea1f1358d161cd8623c52f938992e0
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #ifndef BITCOIN_NET_H
7 #define BITCOIN_NET_H
9 #include "bloom.h"
10 #include "compat.h"
11 #include "limitedmap.h"
12 #include "mruset.h"
13 #include "netbase.h"
14 #include "protocol.h"
15 #include "random.h"
16 #include "streams.h"
17 #include "sync.h"
18 #include "uint256.h"
20 #include <deque>
21 #include <stdint.h>
23 #ifndef WIN32
24 #include <arpa/inet.h>
25 #endif
27 #include <boost/filesystem/path.hpp>
28 #include <boost/foreach.hpp>
29 #include <boost/signals2/signal.hpp>
31 class CAddrMan;
32 class CScheduler;
33 class CNode;
35 namespace boost {
36 class thread_group;
37 } // namespace boost
39 /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
40 static const int PING_INTERVAL = 2 * 60;
41 /** Time after which to disconnect, after waiting for a ping response (or inactivity). */
42 static const int TIMEOUT_INTERVAL = 20 * 60;
43 /** The maximum number of entries in an 'inv' protocol message */
44 static const unsigned int MAX_INV_SZ = 50000;
45 /** The maximum number of new addresses to accumulate before announcing. */
46 static const unsigned int MAX_ADDR_TO_SEND = 1000;
47 /** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
48 static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
49 /** Maximum length of strSubVer in `version` message */
50 static const unsigned int MAX_SUBVERSION_LENGTH = 256;
51 /** -listen default */
52 static const bool DEFAULT_LISTEN = true;
53 /** -upnp default */
54 #ifdef USE_UPNP
55 static const bool DEFAULT_UPNP = USE_UPNP;
56 #else
57 static const bool DEFAULT_UPNP = false;
58 #endif
59 /** The maximum number of entries in mapAskFor */
60 static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
61 /** The maximum number of peer connections to maintain. */
62 static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
64 unsigned int ReceiveFloodSize();
65 unsigned int SendBufferSize();
67 void AddOneShot(const std::string& strDest);
68 void AddressCurrentlyConnected(const CService& addr);
69 CNode* FindNode(const CNetAddr& ip);
70 CNode* FindNode(const CSubNet& subNet);
71 CNode* FindNode(const std::string& addrName);
72 CNode* FindNode(const CService& ip);
73 CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL);
74 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
75 void MapPort(bool fUseUPnP);
76 unsigned short GetListenPort();
77 bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
78 void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler);
79 bool StopNode();
80 void SocketSendData(CNode *pnode);
82 typedef int NodeId;
84 struct CombinerAll
86 typedef bool result_type;
88 template<typename I>
89 bool operator()(I first, I last) const
91 while (first != last) {
92 if (!(*first)) return false;
93 ++first;
95 return true;
99 // Signals for message handling
100 struct CNodeSignals
102 boost::signals2::signal<int ()> GetHeight;
103 boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
104 boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
105 boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
106 boost::signals2::signal<void (NodeId)> FinalizeNode;
110 CNodeSignals& GetNodeSignals();
113 enum
115 LOCAL_NONE, // unknown
116 LOCAL_IF, // address a local interface listens on
117 LOCAL_BIND, // address explicit bound to
118 LOCAL_UPNP, // address reported by UPnP
119 LOCAL_MANUAL, // address explicitly specified (-externalip=)
121 LOCAL_MAX
124 bool IsPeerAddrLocalGood(CNode *pnode);
125 void AdvertizeLocal(CNode *pnode);
126 void SetLimited(enum Network net, bool fLimited = true);
127 bool IsLimited(enum Network net);
128 bool IsLimited(const CNetAddr& addr);
129 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
130 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
131 bool SeenLocal(const CService& addr);
132 bool IsLocal(const CService& addr);
133 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
134 bool IsReachable(enum Network net);
135 bool IsReachable(const CNetAddr &addr);
136 void SetReachable(enum Network net, bool fFlag = true);
137 CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
140 extern bool fDiscover;
141 extern bool fListen;
142 extern uint64_t nLocalServices;
143 extern uint64_t nLocalHostNonce;
144 extern CAddrMan addrman;
146 /** Maximum number of connections to simultaneously allow (aka connection slots) */
147 extern int nMaxConnections;
149 extern std::vector<CNode*> vNodes;
150 extern CCriticalSection cs_vNodes;
151 extern std::map<CInv, CDataStream> mapRelay;
152 extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
153 extern CCriticalSection cs_mapRelay;
154 extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
156 extern std::vector<std::string> vAddedNodes;
157 extern CCriticalSection cs_vAddedNodes;
159 extern NodeId nLastNodeId;
160 extern CCriticalSection cs_nLastNodeId;
162 /** Subversion as sent to the P2P network in `version` messages */
163 extern std::string strSubVersion;
165 struct LocalServiceInfo {
166 int nScore;
167 int nPort;
170 extern CCriticalSection cs_mapLocalHost;
171 extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
173 class CNodeStats
175 public:
176 NodeId nodeid;
177 uint64_t nServices;
178 int64_t nLastSend;
179 int64_t nLastRecv;
180 int64_t nTimeConnected;
181 int64_t nTimeOffset;
182 std::string addrName;
183 int nVersion;
184 std::string cleanSubVer;
185 bool fInbound;
186 int nStartingHeight;
187 uint64_t nSendBytes;
188 uint64_t nRecvBytes;
189 bool fWhitelisted;
190 double dPingTime;
191 double dPingWait;
192 double dPingMin;
193 std::string addrLocal;
199 class CNetMessage {
200 public:
201 bool in_data; // parsing header (false) or data (true)
203 CDataStream hdrbuf; // partially received header
204 CMessageHeader hdr; // complete header
205 unsigned int nHdrPos;
207 CDataStream vRecv; // received message data
208 unsigned int nDataPos;
210 int64_t nTime; // time (in microseconds) of message receipt.
212 CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
213 hdrbuf.resize(24);
214 in_data = false;
215 nHdrPos = 0;
216 nDataPos = 0;
217 nTime = 0;
220 bool complete() const
222 if (!in_data)
223 return false;
224 return (hdr.nMessageSize == nDataPos);
227 void SetVersion(int nVersionIn)
229 hdrbuf.SetVersion(nVersionIn);
230 vRecv.SetVersion(nVersionIn);
233 int readHeader(const char *pch, unsigned int nBytes);
234 int readData(const char *pch, unsigned int nBytes);
238 typedef enum BanReason
240 BanReasonUnknown = 0,
241 BanReasonNodeMisbehaving = 1,
242 BanReasonManuallyAdded = 2
243 } BanReason;
245 class CBanEntry
247 public:
248 static const int CURRENT_VERSION=1;
249 int nVersion;
250 int64_t nCreateTime;
251 int64_t nBanUntil;
252 uint8_t banReason;
254 CBanEntry()
256 SetNull();
259 CBanEntry(int64_t nCreateTimeIn)
261 SetNull();
262 nCreateTime = nCreateTimeIn;
265 ADD_SERIALIZE_METHODS;
267 template <typename Stream, typename Operation>
268 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
269 READWRITE(this->nVersion);
270 nVersion = this->nVersion;
271 READWRITE(nCreateTime);
272 READWRITE(nBanUntil);
273 READWRITE(banReason);
276 void SetNull()
278 nVersion = CBanEntry::CURRENT_VERSION;
279 nCreateTime = 0;
280 nBanUntil = 0;
281 banReason = BanReasonUnknown;
284 std::string banReasonToString()
286 switch (banReason) {
287 case BanReasonNodeMisbehaving:
288 return "node misbehabing";
289 case BanReasonManuallyAdded:
290 return "manually added";
291 default:
292 return "unknown";
297 typedef std::map<CSubNet, CBanEntry> banmap_t;
299 /** Information about a peer */
300 class CNode
302 public:
303 // socket
304 uint64_t nServices;
305 SOCKET hSocket;
306 CDataStream ssSend;
307 size_t nSendSize; // total size of all vSendMsg entries
308 size_t nSendOffset; // offset inside the first vSendMsg already sent
309 uint64_t nSendBytes;
310 std::deque<CSerializeData> vSendMsg;
311 CCriticalSection cs_vSend;
313 std::deque<CInv> vRecvGetData;
314 std::deque<CNetMessage> vRecvMsg;
315 CCriticalSection cs_vRecvMsg;
316 uint64_t nRecvBytes;
317 int nRecvVersion;
319 int64_t nLastSend;
320 int64_t nLastRecv;
321 int64_t nTimeConnected;
322 int64_t nTimeOffset;
323 CAddress addr;
324 std::string addrName;
325 CService addrLocal;
326 int nVersion;
327 // strSubVer is whatever byte array we read from the wire. However, this field is intended
328 // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
329 // store the sanitized version in cleanSubVer. The original should be used when dealing with
330 // the network or wire types and the cleaned string used when displayed or logged.
331 std::string strSubVer, cleanSubVer;
332 bool fWhitelisted; // This peer can bypass DoS banning.
333 bool fOneShot;
334 bool fClient;
335 bool fInbound;
336 bool fNetworkNode;
337 bool fSuccessfullyConnected;
338 bool fDisconnect;
339 // We use fRelayTxes for two purposes -
340 // a) it allows us to not relay tx invs before receiving the peer's version message
341 // b) the peer may tell us in its version message that we should not relay tx invs
342 // until it has initialized its bloom filter.
343 bool fRelayTxes;
344 CSemaphoreGrant grantOutbound;
345 CCriticalSection cs_filter;
346 CBloomFilter* pfilter;
347 int nRefCount;
348 NodeId id;
349 protected:
351 // Denial-of-service detection/prevention
352 // Key is IP address, value is banned-until-time
353 static banmap_t setBanned;
354 static CCriticalSection cs_setBanned;
355 static bool setBannedIsDirty;
357 // Whitelisted ranges. Any node connecting from these is automatically
358 // whitelisted (as well as those connecting to whitelisted binds).
359 static std::vector<CSubNet> vWhitelistedRange;
360 static CCriticalSection cs_vWhitelistedRange;
362 // Basic fuzz-testing
363 void Fuzz(int nChance); // modifies ssSend
365 public:
366 uint256 hashContinue;
367 int nStartingHeight;
369 // flood relay
370 std::vector<CAddress> vAddrToSend;
371 CRollingBloomFilter addrKnown;
372 bool fGetAddr;
373 std::set<uint256> setKnown;
375 // inventory based relay
376 mruset<CInv> setInventoryKnown;
377 std::vector<CInv> vInventoryToSend;
378 CCriticalSection cs_inventory;
379 std::multimap<int64_t, CInv> mapAskFor;
381 // Ping time measurement:
382 // The pong reply we're expecting, or 0 if no pong expected.
383 uint64_t nPingNonceSent;
384 // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
385 int64_t nPingUsecStart;
386 // Last measured round-trip time.
387 int64_t nPingUsecTime;
388 // Best measured round-trip time.
389 int64_t nMinPingUsecTime;
390 // Whether a ping is requested.
391 bool fPingQueued;
393 CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
394 ~CNode();
396 private:
397 // Network usage totals
398 static CCriticalSection cs_totalBytesRecv;
399 static CCriticalSection cs_totalBytesSent;
400 static uint64_t nTotalBytesRecv;
401 static uint64_t nTotalBytesSent;
403 // outbound limit & stats
404 static uint64_t nMaxOutboundTotalBytesSentInCycle;
405 static uint64_t nMaxOutboundCycleStartTime;
406 static uint64_t nMaxOutboundLimit;
407 static uint64_t nMaxOutboundTimeframe;
409 CNode(const CNode&);
410 void operator=(const CNode&);
412 public:
414 NodeId GetId() const {
415 return id;
418 int GetRefCount()
420 assert(nRefCount >= 0);
421 return nRefCount;
424 // requires LOCK(cs_vRecvMsg)
425 unsigned int GetTotalRecvSize()
427 unsigned int total = 0;
428 BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
429 total += msg.vRecv.size() + 24;
430 return total;
433 // requires LOCK(cs_vRecvMsg)
434 bool ReceiveMsgBytes(const char *pch, unsigned int nBytes);
436 // requires LOCK(cs_vRecvMsg)
437 void SetRecvVersion(int nVersionIn)
439 nRecvVersion = nVersionIn;
440 BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
441 msg.SetVersion(nVersionIn);
444 CNode* AddRef()
446 nRefCount++;
447 return this;
450 void Release()
452 nRefCount--;
457 void AddAddressKnown(const CAddress& addr)
459 addrKnown.insert(addr.GetKey());
462 void PushAddress(const CAddress& addr)
464 // Known checking here is only to save space from duplicates.
465 // SendMessages will filter it again for knowns that were added
466 // after addresses were pushed.
467 if (addr.IsValid() && !addrKnown.contains(addr.GetKey())) {
468 if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
469 vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
470 } else {
471 vAddrToSend.push_back(addr);
477 void AddInventoryKnown(const CInv& inv)
480 LOCK(cs_inventory);
481 setInventoryKnown.insert(inv);
485 void PushInventory(const CInv& inv)
488 LOCK(cs_inventory);
489 if (!setInventoryKnown.count(inv))
490 vInventoryToSend.push_back(inv);
494 void AskFor(const CInv& inv);
496 // TODO: Document the postcondition of this function. Is cs_vSend locked?
497 void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
499 // TODO: Document the precondition of this function. Is cs_vSend locked?
500 void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
502 // TODO: Document the precondition of this function. Is cs_vSend locked?
503 void EndMessage() UNLOCK_FUNCTION(cs_vSend);
505 void PushVersion();
508 void PushMessage(const char* pszCommand)
512 BeginMessage(pszCommand);
513 EndMessage();
515 catch (...)
517 AbortMessage();
518 throw;
522 template<typename T1>
523 void PushMessage(const char* pszCommand, const T1& a1)
527 BeginMessage(pszCommand);
528 ssSend << a1;
529 EndMessage();
531 catch (...)
533 AbortMessage();
534 throw;
538 template<typename T1, typename T2>
539 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
543 BeginMessage(pszCommand);
544 ssSend << a1 << a2;
545 EndMessage();
547 catch (...)
549 AbortMessage();
550 throw;
554 template<typename T1, typename T2, typename T3>
555 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
559 BeginMessage(pszCommand);
560 ssSend << a1 << a2 << a3;
561 EndMessage();
563 catch (...)
565 AbortMessage();
566 throw;
570 template<typename T1, typename T2, typename T3, typename T4>
571 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
575 BeginMessage(pszCommand);
576 ssSend << a1 << a2 << a3 << a4;
577 EndMessage();
579 catch (...)
581 AbortMessage();
582 throw;
586 template<typename T1, typename T2, typename T3, typename T4, typename T5>
587 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
591 BeginMessage(pszCommand);
592 ssSend << a1 << a2 << a3 << a4 << a5;
593 EndMessage();
595 catch (...)
597 AbortMessage();
598 throw;
602 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
603 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
607 BeginMessage(pszCommand);
608 ssSend << a1 << a2 << a3 << a4 << a5 << a6;
609 EndMessage();
611 catch (...)
613 AbortMessage();
614 throw;
618 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
619 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)
623 BeginMessage(pszCommand);
624 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
625 EndMessage();
627 catch (...)
629 AbortMessage();
630 throw;
634 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
635 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)
639 BeginMessage(pszCommand);
640 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
641 EndMessage();
643 catch (...)
645 AbortMessage();
646 throw;
650 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
651 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)
655 BeginMessage(pszCommand);
656 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
657 EndMessage();
659 catch (...)
661 AbortMessage();
662 throw;
666 void CloseSocketDisconnect();
668 // Denial-of-service detection/prevention
669 // The idea is to detect peers that are behaving
670 // badly and disconnect/ban them, but do it in a
671 // one-coding-mistake-won't-shatter-the-entire-network
672 // way.
673 // IMPORTANT: There should be nothing I can give a
674 // node that it will forward on that will make that
675 // node's peers drop it. If there is, an attacker
676 // can isolate a node and/or try to split the network.
677 // Dropping a node for sending stuff that is invalid
678 // now but might be valid in a later version is also
679 // dangerous, because it can cause a network split
680 // between nodes running old code and nodes running
681 // new code.
682 static void ClearBanned(); // needed for unit testing
683 static bool IsBanned(CNetAddr ip);
684 static bool IsBanned(CSubNet subnet);
685 static void Ban(const CNetAddr &ip, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
686 static void Ban(const CSubNet &subNet, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
687 static bool Unban(const CNetAddr &ip);
688 static bool Unban(const CSubNet &ip);
689 static void GetBanned(banmap_t &banmap);
690 static void SetBanned(const banmap_t &banmap);
692 //!check is the banlist has unwritten changes
693 static bool BannedSetIsDirty();
694 //!set the "dirty" flag for the banlist
695 static void SetBannedSetDirty(bool dirty=true);
696 //!clean unused entries (if bantime has expired)
697 static void SweepBanned();
699 void copyStats(CNodeStats &stats);
701 static bool IsWhitelistedRange(const CNetAddr &ip);
702 static void AddWhitelistedRange(const CSubNet &subnet);
704 // Network stats
705 static void RecordBytesRecv(uint64_t bytes);
706 static void RecordBytesSent(uint64_t bytes);
708 static uint64_t GetTotalBytesRecv();
709 static uint64_t GetTotalBytesSent();
711 //!set the max outbound target in bytes
712 static void SetMaxOutboundTarget(uint64_t limit);
713 static uint64_t GetMaxOutboundTarget();
715 //!set the timeframe for the max outbound target
716 static void SetMaxOutboundTimeframe(uint64_t timeframe);
717 static uint64_t GetMaxOutboundTimeframe();
719 //!check if the outbound target is reached
720 // if param historicalBlockServingLimit is set true, the function will
721 // response true if the limit for serving historical blocks has been reached
722 static bool OutboundTargetReached(bool historicalBlockServingLimit);
724 //!response the bytes left in the current max outbound cycle
725 // in case of no limit, it will always response 0
726 static uint64_t GetOutboundTargetBytesLeft();
728 //!response the time in second left in the current max outbound cycle
729 // in case of no limit, it will always response 0
730 static uint64_t GetMaxOutboundTimeLeftInCycle();
735 class CTransaction;
736 void RelayTransaction(const CTransaction& tx);
737 void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
739 /** Access to the (IP) address database (peers.dat) */
740 class CAddrDB
742 private:
743 boost::filesystem::path pathAddr;
744 public:
745 CAddrDB();
746 bool Write(const CAddrMan& addr);
747 bool Read(CAddrMan& addr);
750 /** Access to the banlist database (banlist.dat) */
751 class CBanDB
753 private:
754 boost::filesystem::path pathBanlist;
755 public:
756 CBanDB();
757 bool Write(const banmap_t& banSet);
758 bool Read(banmap_t& banSet);
761 void DumpBanlist();
763 #endif // BITCOIN_NET_H