Line data Source code
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.
5 :
6 : #ifndef BITCOIN_NET_H
7 : #define BITCOIN_NET_H
8 :
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"
19 :
20 : #include <deque>
21 : #include <stdint.h>
22 :
23 : #ifndef WIN32
24 : #include <arpa/inet.h>
25 : #endif
26 :
27 : #include <boost/filesystem/path.hpp>
28 : #include <boost/foreach.hpp>
29 : #include <boost/signals2/signal.hpp>
30 :
31 : class CAddrMan;
32 : class CScheduler;
33 : class CNode;
34 :
35 : namespace boost {
36 : class thread_group;
37 : } // namespace boost
38 :
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;
63 :
64 : unsigned int ReceiveFloodSize();
65 : unsigned int SendBufferSize();
66 :
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);
81 :
82 : typedef int NodeId;
83 :
84 : struct CombinerAll
85 : {
86 : typedef bool result_type;
87 :
88 : template<typename I>
89 118431 : bool operator()(I first, I last) const
90 : {
91 236858 : while (first != last) {
92 118429 : if (!(*first)) return false;
93 : ++first;
94 : }
95 : return true;
96 : }
97 : };
98 :
99 : // Signals for message handling
100 1152 : struct CNodeSignals
101 : {
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;
107 : };
108 :
109 :
110 : CNodeSignals& GetNodeSignals();
111 :
112 :
113 : enum
114 : {
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=)
120 :
121 : LOCAL_MAX
122 : };
123 :
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);
138 :
139 :
140 : extern bool fDiscover;
141 : extern bool fListen;
142 : extern uint64_t nLocalServices;
143 : extern uint64_t nLocalHostNonce;
144 : extern CAddrMan addrman;
145 :
146 : /** Maximum number of connections to simultaneously allow (aka connection slots) */
147 : extern int nMaxConnections;
148 :
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;
155 :
156 : extern std::vector<std::string> vAddedNodes;
157 : extern CCriticalSection cs_vAddedNodes;
158 :
159 : extern NodeId nLastNodeId;
160 : extern CCriticalSection cs_nLastNodeId;
161 :
162 : /** Subversion as sent to the P2P network in `version` messages */
163 : extern std::string strSubVersion;
164 :
165 : struct LocalServiceInfo {
166 : int nScore;
167 : int nPort;
168 : };
169 :
170 : extern CCriticalSection cs_mapLocalHost;
171 : extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
172 :
173 6456 : class CNodeStats
174 : {
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;
194 : };
195 :
196 :
197 :
198 :
199 190853 : class CNetMessage {
200 : public:
201 : bool in_data; // parsing header (false) or data (true)
202 :
203 : CDataStream hdrbuf; // partially received header
204 : CMessageHeader hdr; // complete header
205 : unsigned int nHdrPos;
206 :
207 : CDataStream vRecv; // received message data
208 : unsigned int nDataPos;
209 :
210 : int64_t nTime; // time (in microseconds) of message receipt.
211 :
212 42412 : CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
213 21206 : hdrbuf.resize(24);
214 21206 : in_data = false;
215 21206 : nHdrPos = 0;
216 21206 : nDataPos = 0;
217 21206 : nTime = 0;
218 21206 : }
219 :
220 : bool complete() const
221 : {
222 126001 : if (!in_data)
223 : return false;
224 126001 : return (hdr.nMessageSize == nDataPos);
225 : }
226 :
227 : void SetVersion(int nVersionIn)
228 : {
229 448 : hdrbuf.SetVersion(nVersionIn);
230 448 : vRecv.SetVersion(nVersionIn);
231 : }
232 :
233 : int readHeader(const char *pch, unsigned int nBytes);
234 : int readData(const char *pch, unsigned int nBytes);
235 : };
236 :
237 :
238 : typedef enum BanReason
239 : {
240 : BanReasonUnknown = 0,
241 : BanReasonNodeMisbehaving = 1,
242 : BanReasonManuallyAdded = 2
243 : } BanReason;
244 :
245 : class CBanEntry
246 : {
247 : public:
248 : static const int CURRENT_VERSION=1;
249 : int nVersion;
250 : int64_t nCreateTime;
251 : int64_t nBanUntil;
252 : uint8_t banReason;
253 :
254 0 : CBanEntry()
255 : {
256 : SetNull();
257 0 : }
258 :
259 0 : CBanEntry(int64_t nCreateTimeIn)
260 : {
261 : SetNull();
262 17 : nCreateTime = nCreateTimeIn;
263 0 : }
264 :
265 25 : ADD_SERIALIZE_METHODS;
266 :
267 : template <typename Stream, typename Operation>
268 25 : inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
269 25 : READWRITE(this->nVersion);
270 25 : nVersion = this->nVersion;
271 25 : READWRITE(nCreateTime);
272 25 : READWRITE(nBanUntil);
273 25 : READWRITE(banReason);
274 25 : }
275 :
276 : void SetNull()
277 : {
278 20 : nVersion = CBanEntry::CURRENT_VERSION;
279 20 : nCreateTime = 0;
280 20 : nBanUntil = 0;
281 20 : banReason = BanReasonUnknown;
282 : }
283 :
284 17 : std::string banReasonToString()
285 : {
286 17 : switch (banReason) {
287 : case BanReasonNodeMisbehaving:
288 0 : return "node misbehabing";
289 : case BanReasonManuallyAdded:
290 34 : return "manually added";
291 : default:
292 0 : return "unknown";
293 : }
294 : }
295 : };
296 :
297 : typedef std::map<CSubNet, CBanEntry> banmap_t;
298 :
299 : /** Information about a peer */
300 : class CNode
301 : {
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;
312 :
313 : std::deque<CInv> vRecvGetData;
314 : std::deque<CNetMessage> vRecvMsg;
315 : CCriticalSection cs_vRecvMsg;
316 : uint64_t nRecvBytes;
317 : int nRecvVersion;
318 :
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:
350 :
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;
356 :
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;
361 :
362 : // Basic fuzz-testing
363 : void Fuzz(int nChance); // modifies ssSend
364 :
365 : public:
366 : uint256 hashContinue;
367 : int nStartingHeight;
368 :
369 : // flood relay
370 : std::vector<CAddress> vAddrToSend;
371 : CRollingBloomFilter addrKnown;
372 : bool fGetAddr;
373 : std::set<uint256> setKnown;
374 :
375 : // inventory based relay
376 : mruset<CInv> setInventoryKnown;
377 : std::vector<CInv> vInventoryToSend;
378 : CCriticalSection cs_inventory;
379 : std::multimap<int64_t, CInv> mapAskFor;
380 :
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;
392 :
393 : CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
394 : ~CNode();
395 :
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;
402 :
403 : CNode(const CNode&);
404 : void operator=(const CNode&);
405 :
406 : public:
407 :
408 0 : NodeId GetId() const {
409 0 : return id;
410 : }
411 :
412 0 : int GetRefCount()
413 : {
414 59305 : assert(nRefCount >= 0);
415 0 : return nRefCount;
416 : }
417 :
418 : // requires LOCK(cs_vRecvMsg)
419 11580 : unsigned int GetTotalRecvSize()
420 : {
421 11580 : unsigned int total = 0;
422 466000 : BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
423 198260 : total += msg.vRecv.size() + 24;
424 11580 : return total;
425 : }
426 :
427 : // requires LOCK(cs_vRecvMsg)
428 : bool ReceiveMsgBytes(const char *pch, unsigned int nBytes);
429 :
430 : // requires LOCK(cs_vRecvMsg)
431 250 : void SetRecvVersion(int nVersionIn)
432 : {
433 250 : nRecvVersion = nVersionIn;
434 3740 : BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
435 : msg.SetVersion(nVersionIn);
436 250 : }
437 :
438 : CNode* AddRef()
439 : {
440 118931 : nRefCount++;
441 : return this;
442 : }
443 :
444 0 : void Release()
445 : {
446 118705 : nRefCount--;
447 0 : }
448 :
449 :
450 :
451 0 : void AddAddressKnown(const CAddress& addr)
452 : {
453 0 : addrKnown.insert(addr.GetKey());
454 0 : }
455 :
456 0 : void PushAddress(const CAddress& addr)
457 : {
458 : // Known checking here is only to save space from duplicates.
459 : // SendMessages will filter it again for knowns that were added
460 : // after addresses were pushed.
461 0 : if (addr.IsValid() && !addrKnown.contains(addr.GetKey())) {
462 0 : if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
463 0 : vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
464 : } else {
465 0 : vAddrToSend.push_back(addr);
466 : }
467 : }
468 0 : }
469 :
470 :
471 12769 : void AddInventoryKnown(const CInv& inv)
472 : {
473 : {
474 12769 : LOCK(cs_inventory);
475 12769 : setInventoryKnown.insert(inv);
476 : }
477 12769 : }
478 :
479 14989 : void PushInventory(const CInv& inv)
480 : {
481 : {
482 14989 : LOCK(cs_inventory);
483 29978 : if (!setInventoryKnown.count(inv))
484 8339 : vInventoryToSend.push_back(inv);
485 : }
486 14989 : }
487 :
488 : void AskFor(const CInv& inv);
489 :
490 : // TODO: Document the postcondition of this function. Is cs_vSend locked?
491 : void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
492 :
493 : // TODO: Document the precondition of this function. Is cs_vSend locked?
494 : void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
495 :
496 : // TODO: Document the precondition of this function. Is cs_vSend locked?
497 : void EndMessage() UNLOCK_FUNCTION(cs_vSend);
498 :
499 : void PushVersion();
500 :
501 :
502 378 : void PushMessage(const char* pszCommand)
503 : {
504 : try
505 : {
506 378 : BeginMessage(pszCommand);
507 378 : EndMessage();
508 : }
509 0 : catch (...)
510 : {
511 0 : AbortMessage();
512 0 : throw;
513 : }
514 378 : }
515 :
516 : template<typename T1>
517 15526 : void PushMessage(const char* pszCommand, const T1& a1)
518 : {
519 : try
520 : {
521 15526 : BeginMessage(pszCommand);
522 15526 : ssSend << a1;
523 15526 : EndMessage();
524 : }
525 0 : catch (...)
526 : {
527 0 : AbortMessage();
528 0 : throw;
529 : }
530 15526 : }
531 :
532 : template<typename T1, typename T2>
533 4752 : void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
534 : {
535 : try
536 : {
537 4752 : BeginMessage(pszCommand);
538 9504 : ssSend << a1 << a2;
539 4752 : EndMessage();
540 : }
541 0 : catch (...)
542 : {
543 0 : AbortMessage();
544 0 : throw;
545 : }
546 4752 : }
547 :
548 : template<typename T1, typename T2, typename T3>
549 0 : void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
550 : {
551 : try
552 : {
553 0 : BeginMessage(pszCommand);
554 0 : ssSend << a1 << a2 << a3;
555 0 : EndMessage();
556 : }
557 0 : catch (...)
558 : {
559 0 : AbortMessage();
560 0 : throw;
561 : }
562 0 : }
563 :
564 : template<typename T1, typename T2, typename T3, typename T4>
565 53 : void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
566 : {
567 : try
568 : {
569 53 : BeginMessage(pszCommand);
570 212 : ssSend << a1 << a2 << a3 << a4;
571 53 : EndMessage();
572 : }
573 0 : catch (...)
574 : {
575 0 : AbortMessage();
576 0 : throw;
577 : }
578 53 : }
579 :
580 : template<typename T1, typename T2, typename T3, typename T4, typename T5>
581 : void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
582 : {
583 : try
584 : {
585 : BeginMessage(pszCommand);
586 : ssSend << a1 << a2 << a3 << a4 << a5;
587 : EndMessage();
588 : }
589 : catch (...)
590 : {
591 : AbortMessage();
592 : throw;
593 : }
594 : }
595 :
596 : template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
597 : void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
598 : {
599 : try
600 : {
601 : BeginMessage(pszCommand);
602 : ssSend << a1 << a2 << a3 << a4 << a5 << a6;
603 : EndMessage();
604 : }
605 : catch (...)
606 : {
607 : AbortMessage();
608 : throw;
609 : }
610 : }
611 :
612 : template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
613 : 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)
614 : {
615 : try
616 : {
617 : BeginMessage(pszCommand);
618 : ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
619 : EndMessage();
620 : }
621 : catch (...)
622 : {
623 : AbortMessage();
624 : throw;
625 : }
626 : }
627 :
628 : template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
629 : 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)
630 : {
631 : try
632 : {
633 : BeginMessage(pszCommand);
634 : ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
635 : EndMessage();
636 : }
637 : catch (...)
638 : {
639 : AbortMessage();
640 : throw;
641 : }
642 : }
643 :
644 : template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
645 265 : 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)
646 : {
647 : try
648 : {
649 265 : BeginMessage(pszCommand);
650 2385 : ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
651 265 : EndMessage();
652 : }
653 0 : catch (...)
654 : {
655 0 : AbortMessage();
656 0 : throw;
657 : }
658 265 : }
659 :
660 : void CloseSocketDisconnect();
661 :
662 : // Denial-of-service detection/prevention
663 : // The idea is to detect peers that are behaving
664 : // badly and disconnect/ban them, but do it in a
665 : // one-coding-mistake-won't-shatter-the-entire-network
666 : // way.
667 : // IMPORTANT: There should be nothing I can give a
668 : // node that it will forward on that will make that
669 : // node's peers drop it. If there is, an attacker
670 : // can isolate a node and/or try to split the network.
671 : // Dropping a node for sending stuff that is invalid
672 : // now but might be valid in a later version is also
673 : // dangerous, because it can cause a network split
674 : // between nodes running old code and nodes running
675 : // new code.
676 : static void ClearBanned(); // needed for unit testing
677 : static bool IsBanned(CNetAddr ip);
678 : static bool IsBanned(CSubNet subnet);
679 : static void Ban(const CNetAddr &ip, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
680 : static void Ban(const CSubNet &subNet, const BanReason &banReason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
681 : static bool Unban(const CNetAddr &ip);
682 : static bool Unban(const CSubNet &ip);
683 : static void GetBanned(banmap_t &banmap);
684 : static void SetBanned(const banmap_t &banmap);
685 :
686 : //!check is the banlist has unwritten changes
687 : static bool BannedSetIsDirty();
688 : //!set the "dirty" flag for the banlist
689 : static void SetBannedSetDirty(bool dirty=true);
690 : //!clean unused entries (if bantime has expired)
691 : static void SweepBanned();
692 :
693 : void copyStats(CNodeStats &stats);
694 :
695 : static bool IsWhitelistedRange(const CNetAddr &ip);
696 : static void AddWhitelistedRange(const CSubNet &subnet);
697 :
698 : // Network stats
699 : static void RecordBytesRecv(uint64_t bytes);
700 : static void RecordBytesSent(uint64_t bytes);
701 :
702 : static uint64_t GetTotalBytesRecv();
703 : static uint64_t GetTotalBytesSent();
704 : };
705 :
706 :
707 :
708 : class CTransaction;
709 : void RelayTransaction(const CTransaction& tx);
710 : void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
711 :
712 : /** Access to the (IP) address database (peers.dat) */
713 376 : class CAddrDB
714 : {
715 : private:
716 : boost::filesystem::path pathAddr;
717 : public:
718 : CAddrDB();
719 : bool Write(const CAddrMan& addr);
720 : bool Read(CAddrMan& addr);
721 : };
722 :
723 : /** Access to the banlist database (banlist.dat) */
724 236 : class CBanDB
725 : {
726 : private:
727 : boost::filesystem::path pathBanlist;
728 : public:
729 : CBanDB();
730 : bool Write(const banmap_t& banSet);
731 : bool Read(banmap_t& banSet);
732 : };
733 :
734 : void DumpBanlist();
735 :
736 : #endif // BITCOIN_NET_H
|