net: Introduce CConnection::Options to avoid passing so many params
[bitcoinplatinum.git] / src / net.h
blob8067ee68a7d39d03e6e496e13b5b3072abfff51f
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 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 "addrdb.h"
10 #include "addrman.h"
11 #include "amount.h"
12 #include "bloom.h"
13 #include "compat.h"
14 #include "limitedmap.h"
15 #include "netaddress.h"
16 #include "protocol.h"
17 #include "random.h"
18 #include "streams.h"
19 #include "sync.h"
20 #include "uint256.h"
22 #include <atomic>
23 #include <deque>
24 #include <stdint.h>
25 #include <memory>
27 #ifndef WIN32
28 #include <arpa/inet.h>
29 #endif
31 #include <boost/filesystem/path.hpp>
32 #include <boost/foreach.hpp>
33 #include <boost/signals2/signal.hpp>
35 class CAddrMan;
36 class CScheduler;
37 class CNode;
39 namespace boost {
40 class thread_group;
41 } // namespace boost
43 /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
44 static const int PING_INTERVAL = 2 * 60;
45 /** Time after which to disconnect, after waiting for a ping response (or inactivity). */
46 static const int TIMEOUT_INTERVAL = 20 * 60;
47 /** Run the feeler connection loop once every 2 minutes or 120 seconds. **/
48 static const int FEELER_INTERVAL = 120;
49 /** The maximum number of entries in an 'inv' protocol message */
50 static const unsigned int MAX_INV_SZ = 50000;
51 /** The maximum number of new addresses to accumulate before announcing. */
52 static const unsigned int MAX_ADDR_TO_SEND = 1000;
53 /** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */
54 static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000;
55 /** Maximum length of strSubVer in `version` message */
56 static const unsigned int MAX_SUBVERSION_LENGTH = 256;
57 /** Maximum number of outgoing nodes */
58 static const int MAX_OUTBOUND_CONNECTIONS = 8;
59 /** -listen default */
60 static const bool DEFAULT_LISTEN = true;
61 /** -upnp default */
62 #ifdef USE_UPNP
63 static const bool DEFAULT_UPNP = USE_UPNP;
64 #else
65 static const bool DEFAULT_UPNP = false;
66 #endif
67 /** The maximum number of entries in mapAskFor */
68 static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
69 /** The maximum number of entries in setAskFor (larger due to getdata latency)*/
70 static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
71 /** The maximum number of peer connections to maintain. */
72 static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
73 /** The default for -maxuploadtarget. 0 = Unlimited */
74 static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
75 /** Default for blocks only*/
76 static const bool DEFAULT_BLOCKSONLY = false;
78 static const bool DEFAULT_FORCEDNSSEED = false;
79 static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
80 static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
82 static const ServiceFlags REQUIRED_SERVICES = NODE_NETWORK;
84 // NOTE: When adjusting this, update rpcnet:setban's help ("24h")
85 static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban
87 typedef int NodeId;
89 struct AddedNodeInfo
91 std::string strAddedNode;
92 CService resolvedAddress;
93 bool fConnected;
94 bool fInbound;
97 class CTransaction;
98 class CNodeStats;
99 class CClientUIInterface;
101 class CConnman
103 public:
105 enum NumConnections {
106 CONNECTIONS_NONE = 0,
107 CONNECTIONS_IN = (1U << 0),
108 CONNECTIONS_OUT = (1U << 1),
109 CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
112 struct Options
114 ServiceFlags nLocalServices = NODE_NONE;
115 ServiceFlags nRelevantServices = NODE_NONE;
116 int nMaxConnections = 0;
117 int nMaxOutbound = 0;
118 int nBestHeight = 0;
119 CClientUIInterface* uiInterface = nullptr;
121 CConnman();
122 ~CConnman();
123 bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options options);
124 void Stop();
125 bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
126 bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false);
127 bool CheckIncomingNonce(uint64_t nonce);
129 bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
130 bool ForEachNode(std::function<bool(CNode* pnode)> func);
131 bool ForEachNode(std::function<bool(const CNode* pnode)> func) const;
132 bool ForEachNodeThen(std::function<bool(CNode* pnode)> pre, std::function<void()> post);
133 bool ForEachNodeThen(std::function<bool(const CNode* pnode)> pre, std::function<void()> post) const;
135 void RelayTransaction(const CTransaction& tx);
137 // Addrman functions
138 size_t GetAddressCount() const;
139 void SetServices(const CService &addr, ServiceFlags nServices);
140 void MarkAddressGood(const CAddress& addr);
141 void AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
142 void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
143 std::vector<CAddress> GetAddresses();
144 void AddressCurrentlyConnected(const CService& addr);
146 // Denial-of-service detection/prevention
147 // The idea is to detect peers that are behaving
148 // badly and disconnect/ban them, but do it in a
149 // one-coding-mistake-won't-shatter-the-entire-network
150 // way.
151 // IMPORTANT: There should be nothing I can give a
152 // node that it will forward on that will make that
153 // node's peers drop it. If there is, an attacker
154 // can isolate a node and/or try to split the network.
155 // Dropping a node for sending stuff that is invalid
156 // now but might be valid in a later version is also
157 // dangerous, because it can cause a network split
158 // between nodes running old code and nodes running
159 // new code.
160 void Ban(const CNetAddr& netAddr, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
161 void Ban(const CSubNet& subNet, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
162 void ClearBanned(); // needed for unit testing
163 bool IsBanned(CNetAddr ip);
164 bool IsBanned(CSubNet subnet);
165 bool Unban(const CNetAddr &ip);
166 bool Unban(const CSubNet &ip);
167 void GetBanned(banmap_t &banmap);
168 void SetBanned(const banmap_t &banmap);
170 void AddOneShot(const std::string& strDest);
172 bool AddNode(const std::string& node);
173 bool RemoveAddedNode(const std::string& node);
174 std::vector<AddedNodeInfo> GetAddedNodeInfo();
176 size_t GetNodeCount(NumConnections num);
177 void GetNodeStats(std::vector<CNodeStats>& vstats);
178 bool DisconnectAddress(const CNetAddr& addr);
179 bool DisconnectNode(const std::string& node);
180 bool DisconnectNode(NodeId id);
181 bool DisconnectSubnet(const CSubNet& subnet);
183 unsigned int GetSendBufferSize() const;
185 void AddWhitelistedRange(const CSubNet &subnet);
187 ServiceFlags GetLocalServices() const;
189 //!set the max outbound target in bytes
190 void SetMaxOutboundTarget(uint64_t limit);
191 uint64_t GetMaxOutboundTarget();
193 //!set the timeframe for the max outbound target
194 void SetMaxOutboundTimeframe(uint64_t timeframe);
195 uint64_t GetMaxOutboundTimeframe();
197 //!check if the outbound target is reached
198 // if param historicalBlockServingLimit is set true, the function will
199 // response true if the limit for serving historical blocks has been reached
200 bool OutboundTargetReached(bool historicalBlockServingLimit);
202 //!response the bytes left in the current max outbound cycle
203 // in case of no limit, it will always response 0
204 uint64_t GetOutboundTargetBytesLeft();
206 //!response the time in second left in the current max outbound cycle
207 // in case of no limit, it will always response 0
208 uint64_t GetMaxOutboundTimeLeftInCycle();
210 uint64_t GetTotalBytesRecv();
211 uint64_t GetTotalBytesSent();
213 void SetBestHeight(int height);
214 int GetBestHeight() const;
217 private:
218 struct ListenSocket {
219 SOCKET socket;
220 bool whitelisted;
222 ListenSocket(SOCKET socket_, bool whitelisted_) : socket(socket_), whitelisted(whitelisted_) {}
225 void ThreadOpenAddedConnections();
226 void ProcessOneShot();
227 void ThreadOpenConnections();
228 void ThreadMessageHandler();
229 void AcceptConnection(const ListenSocket& hListenSocket);
230 void ThreadSocketHandler();
231 void ThreadDNSAddressSeed();
233 CNode* FindNode(const CNetAddr& ip);
234 CNode* FindNode(const CSubNet& subNet);
235 CNode* FindNode(const std::string& addrName);
236 CNode* FindNode(const CService& addr);
238 bool AttemptToEvictConnection();
239 CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure);
240 bool IsWhitelistedRange(const CNetAddr &addr);
242 void DeleteNode(CNode* pnode);
244 NodeId GetNewNodeId();
246 //!check is the banlist has unwritten changes
247 bool BannedSetIsDirty();
248 //!set the "dirty" flag for the banlist
249 void SetBannedSetDirty(bool dirty=true);
250 //!clean unused entries (if bantime has expired)
251 void SweepBanned();
252 void DumpAddresses();
253 void DumpData();
254 void DumpBanlist();
256 unsigned int GetReceiveFloodSize() const;
258 // Network stats
259 void RecordBytesRecv(uint64_t bytes);
260 void RecordBytesSent(uint64_t bytes);
262 // Network usage totals
263 CCriticalSection cs_totalBytesRecv;
264 CCriticalSection cs_totalBytesSent;
265 uint64_t nTotalBytesRecv;
266 uint64_t nTotalBytesSent;
268 // outbound limit & stats
269 uint64_t nMaxOutboundTotalBytesSentInCycle;
270 uint64_t nMaxOutboundCycleStartTime;
271 uint64_t nMaxOutboundLimit;
272 uint64_t nMaxOutboundTimeframe;
274 // Whitelisted ranges. Any node connecting from these is automatically
275 // whitelisted (as well as those connecting to whitelisted binds).
276 std::vector<CSubNet> vWhitelistedRange;
277 CCriticalSection cs_vWhitelistedRange;
279 unsigned int nSendBufferMaxSize;
280 unsigned int nReceiveFloodSize;
282 std::vector<ListenSocket> vhListenSocket;
283 banmap_t setBanned;
284 CCriticalSection cs_setBanned;
285 bool setBannedIsDirty;
286 bool fAddressesInitialized;
287 CAddrMan addrman;
288 std::deque<std::string> vOneShots;
289 CCriticalSection cs_vOneShots;
290 std::vector<std::string> vAddedNodes;
291 CCriticalSection cs_vAddedNodes;
292 std::vector<CNode*> vNodes;
293 mutable CCriticalSection cs_vNodes;
294 std::atomic<NodeId> nLastNodeId;
295 boost::condition_variable messageHandlerCondition;
297 /** Services this instance offers */
298 ServiceFlags nLocalServices;
300 /** Services this instance cares about */
301 ServiceFlags nRelevantServices;
303 CSemaphore *semOutbound;
304 int nMaxConnections;
305 int nMaxOutbound;
306 std::atomic<int> nBestHeight;
307 CClientUIInterface* clientInterface;
309 extern std::unique_ptr<CConnman> g_connman;
310 void Discover(boost::thread_group& threadGroup);
311 void MapPort(bool fUseUPnP);
312 unsigned short GetListenPort();
313 bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
314 size_t SocketSendData(CNode *pnode);
316 struct CombinerAll
318 typedef bool result_type;
320 template<typename I>
321 bool operator()(I first, I last) const
323 while (first != last) {
324 if (!(*first)) return false;
325 ++first;
327 return true;
331 // Signals for message handling
332 struct CNodeSignals
334 boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> ProcessMessages;
335 boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> SendMessages;
336 boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
337 boost::signals2::signal<void (NodeId, bool&)> FinalizeNode;
341 CNodeSignals& GetNodeSignals();
344 enum
346 LOCAL_NONE, // unknown
347 LOCAL_IF, // address a local interface listens on
348 LOCAL_BIND, // address explicit bound to
349 LOCAL_UPNP, // address reported by UPnP
350 LOCAL_MANUAL, // address explicitly specified (-externalip=)
352 LOCAL_MAX
355 bool IsPeerAddrLocalGood(CNode *pnode);
356 void AdvertiseLocal(CNode *pnode);
357 void SetLimited(enum Network net, bool fLimited = true);
358 bool IsLimited(enum Network net);
359 bool IsLimited(const CNetAddr& addr);
360 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
361 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
362 bool RemoveLocal(const CService& addr);
363 bool SeenLocal(const CService& addr);
364 bool IsLocal(const CService& addr);
365 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
366 bool IsReachable(enum Network net);
367 bool IsReachable(const CNetAddr &addr);
368 CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices);
371 extern bool fDiscover;
372 extern bool fListen;
373 extern bool fRelayTxes;
375 extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
377 /** Subversion as sent to the P2P network in `version` messages */
378 extern std::string strSubVersion;
380 struct LocalServiceInfo {
381 int nScore;
382 int nPort;
385 extern CCriticalSection cs_mapLocalHost;
386 extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
387 typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes
389 class CNodeStats
391 public:
392 NodeId nodeid;
393 ServiceFlags nServices;
394 bool fRelayTxes;
395 int64_t nLastSend;
396 int64_t nLastRecv;
397 int64_t nTimeConnected;
398 int64_t nTimeOffset;
399 std::string addrName;
400 int nVersion;
401 std::string cleanSubVer;
402 bool fInbound;
403 int nStartingHeight;
404 uint64_t nSendBytes;
405 mapMsgCmdSize mapSendBytesPerMsgCmd;
406 uint64_t nRecvBytes;
407 mapMsgCmdSize mapRecvBytesPerMsgCmd;
408 bool fWhitelisted;
409 double dPingTime;
410 double dPingWait;
411 double dPingMin;
412 std::string addrLocal;
418 class CNetMessage {
419 public:
420 bool in_data; // parsing header (false) or data (true)
422 CDataStream hdrbuf; // partially received header
423 CMessageHeader hdr; // complete header
424 unsigned int nHdrPos;
426 CDataStream vRecv; // received message data
427 unsigned int nDataPos;
429 int64_t nTime; // time (in microseconds) of message receipt.
431 CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
432 hdrbuf.resize(24);
433 in_data = false;
434 nHdrPos = 0;
435 nDataPos = 0;
436 nTime = 0;
439 bool complete() const
441 if (!in_data)
442 return false;
443 return (hdr.nMessageSize == nDataPos);
446 void SetVersion(int nVersionIn)
448 hdrbuf.SetVersion(nVersionIn);
449 vRecv.SetVersion(nVersionIn);
452 int readHeader(const char *pch, unsigned int nBytes);
453 int readData(const char *pch, unsigned int nBytes);
457 /** Information about a peer */
458 class CNode
460 public:
461 // socket
462 ServiceFlags nServices;
463 ServiceFlags nServicesExpected;
464 SOCKET hSocket;
465 CDataStream ssSend;
466 size_t nSendSize; // total size of all vSendMsg entries
467 size_t nSendOffset; // offset inside the first vSendMsg already sent
468 uint64_t nOptimisticBytesWritten;
469 uint64_t nSendBytes;
470 std::deque<CSerializeData> vSendMsg;
471 CCriticalSection cs_vSend;
473 std::deque<CInv> vRecvGetData;
474 std::deque<CNetMessage> vRecvMsg;
475 CCriticalSection cs_vRecvMsg;
476 uint64_t nRecvBytes;
477 int nRecvVersion;
479 int64_t nLastSend;
480 int64_t nLastRecv;
481 int64_t nTimeConnected;
482 int64_t nTimeOffset;
483 const CAddress addr;
484 std::string addrName;
485 CService addrLocal;
486 int nVersion;
487 // strSubVer is whatever byte array we read from the wire. However, this field is intended
488 // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
489 // store the sanitized version in cleanSubVer. The original should be used when dealing with
490 // the network or wire types and the cleaned string used when displayed or logged.
491 std::string strSubVer, cleanSubVer;
492 bool fWhitelisted; // This peer can bypass DoS banning.
493 bool fFeeler; // If true this node is being used as a short lived feeler.
494 bool fOneShot;
495 bool fClient;
496 bool fInbound;
497 bool fNetworkNode;
498 bool fSuccessfullyConnected;
499 bool fDisconnect;
500 // We use fRelayTxes for two purposes -
501 // a) it allows us to not relay tx invs before receiving the peer's version message
502 // b) the peer may tell us in its version message that we should not relay tx invs
503 // unless it loads a bloom filter.
504 bool fRelayTxes; //protected by cs_filter
505 bool fSentAddr;
506 CSemaphoreGrant grantOutbound;
507 CCriticalSection cs_filter;
508 CBloomFilter* pfilter;
509 int nRefCount;
510 NodeId id;
512 const uint64_t nKeyedNetGroup;
513 protected:
515 mapMsgCmdSize mapSendBytesPerMsgCmd;
516 mapMsgCmdSize mapRecvBytesPerMsgCmd;
518 // Basic fuzz-testing
519 void Fuzz(int nChance); // modifies ssSend
521 public:
522 uint256 hashContinue;
523 int nStartingHeight;
525 // flood relay
526 std::vector<CAddress> vAddrToSend;
527 CRollingBloomFilter addrKnown;
528 bool fGetAddr;
529 std::set<uint256> setKnown;
530 int64_t nNextAddrSend;
531 int64_t nNextLocalAddrSend;
533 // inventory based relay
534 CRollingBloomFilter filterInventoryKnown;
535 // Set of transaction ids we still have to announce.
536 // They are sorted by the mempool before relay, so the order is not important.
537 std::set<uint256> setInventoryTxToSend;
538 // List of block ids we still have announce.
539 // There is no final sorting before sending, as they are always sent immediately
540 // and in the order requested.
541 std::vector<uint256> vInventoryBlockToSend;
542 CCriticalSection cs_inventory;
543 std::set<uint256> setAskFor;
544 std::multimap<int64_t, CInv> mapAskFor;
545 int64_t nNextInvSend;
546 // Used for headers announcements - unfiltered blocks to relay
547 // Also protected by cs_inventory
548 std::vector<uint256> vBlockHashesToAnnounce;
549 // Used for BIP35 mempool sending, also protected by cs_inventory
550 bool fSendMempool;
552 // Last time a "MEMPOOL" request was serviced.
553 std::atomic<int64_t> timeLastMempoolReq;
555 // Block and TXN accept times
556 std::atomic<int64_t> nLastBlockTime;
557 std::atomic<int64_t> nLastTXTime;
559 // Ping time measurement:
560 // The pong reply we're expecting, or 0 if no pong expected.
561 uint64_t nPingNonceSent;
562 // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
563 int64_t nPingUsecStart;
564 // Last measured round-trip time.
565 int64_t nPingUsecTime;
566 // Best measured round-trip time.
567 int64_t nMinPingUsecTime;
568 // Whether a ping is requested.
569 bool fPingQueued;
570 // Minimum fee rate with which to filter inv's to this node
571 CAmount minFeeFilter;
572 CCriticalSection cs_feeFilter;
573 CAmount lastSentFeeFilter;
574 int64_t nextSendTimeFeeFilter;
576 CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
577 ~CNode();
579 private:
580 CNode(const CNode&);
581 void operator=(const CNode&);
583 static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
585 uint64_t nLocalHostNonce;
586 ServiceFlags nLocalServices;
587 int nMyStartingHeight;
588 public:
590 NodeId GetId() const {
591 return id;
594 uint64_t GetLocalNonce() const {
595 return nLocalHostNonce;
598 int GetRefCount()
600 assert(nRefCount >= 0);
601 return nRefCount;
604 // requires LOCK(cs_vRecvMsg)
605 unsigned int GetTotalRecvSize()
607 unsigned int total = 0;
608 BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
609 total += msg.vRecv.size() + 24;
610 return total;
613 // requires LOCK(cs_vRecvMsg)
614 bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete);
616 // requires LOCK(cs_vRecvMsg)
617 void SetRecvVersion(int nVersionIn)
619 nRecvVersion = nVersionIn;
620 BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
621 msg.SetVersion(nVersionIn);
624 CNode* AddRef()
626 nRefCount++;
627 return this;
630 void Release()
632 nRefCount--;
637 void AddAddressKnown(const CAddress& _addr)
639 addrKnown.insert(_addr.GetKey());
642 void PushAddress(const CAddress& _addr)
644 // Known checking here is only to save space from duplicates.
645 // SendMessages will filter it again for knowns that were added
646 // after addresses were pushed.
647 if (_addr.IsValid() && !addrKnown.contains(_addr.GetKey())) {
648 if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
649 vAddrToSend[insecure_rand() % vAddrToSend.size()] = _addr;
650 } else {
651 vAddrToSend.push_back(_addr);
657 void AddInventoryKnown(const CInv& inv)
660 LOCK(cs_inventory);
661 filterInventoryKnown.insert(inv.hash);
665 void PushInventory(const CInv& inv)
667 LOCK(cs_inventory);
668 if (inv.type == MSG_TX) {
669 if (!filterInventoryKnown.contains(inv.hash)) {
670 setInventoryTxToSend.insert(inv.hash);
672 } else if (inv.type == MSG_BLOCK) {
673 vInventoryBlockToSend.push_back(inv.hash);
677 void PushBlockHash(const uint256 &hash)
679 LOCK(cs_inventory);
680 vBlockHashesToAnnounce.push_back(hash);
683 void AskFor(const CInv& inv);
685 // TODO: Document the postcondition of this function. Is cs_vSend locked?
686 void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
688 // TODO: Document the precondition of this function. Is cs_vSend locked?
689 void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
691 // TODO: Document the precondition of this function. Is cs_vSend locked?
692 void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend);
694 void PushVersion();
697 void PushMessage(const char* pszCommand)
701 BeginMessage(pszCommand);
702 EndMessage(pszCommand);
704 catch (...)
706 AbortMessage();
707 throw;
711 template<typename T1>
712 void PushMessage(const char* pszCommand, const T1& a1)
716 BeginMessage(pszCommand);
717 ssSend << a1;
718 EndMessage(pszCommand);
720 catch (...)
722 AbortMessage();
723 throw;
727 /** Send a message containing a1, serialized with flag flag. */
728 template<typename T1>
729 void PushMessageWithFlag(int flag, const char* pszCommand, const T1& a1)
733 BeginMessage(pszCommand);
734 WithOrVersion(&ssSend, flag) << a1;
735 EndMessage(pszCommand);
737 catch (...)
739 AbortMessage();
740 throw;
744 template<typename T1, typename T2>
745 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
749 BeginMessage(pszCommand);
750 ssSend << a1 << a2;
751 EndMessage(pszCommand);
753 catch (...)
755 AbortMessage();
756 throw;
760 template<typename T1, typename T2, typename T3>
761 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
765 BeginMessage(pszCommand);
766 ssSend << a1 << a2 << a3;
767 EndMessage(pszCommand);
769 catch (...)
771 AbortMessage();
772 throw;
776 template<typename T1, typename T2, typename T3, typename T4>
777 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
781 BeginMessage(pszCommand);
782 ssSend << a1 << a2 << a3 << a4;
783 EndMessage(pszCommand);
785 catch (...)
787 AbortMessage();
788 throw;
792 template<typename T1, typename T2, typename T3, typename T4, typename T5>
793 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
797 BeginMessage(pszCommand);
798 ssSend << a1 << a2 << a3 << a4 << a5;
799 EndMessage(pszCommand);
801 catch (...)
803 AbortMessage();
804 throw;
808 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
809 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
813 BeginMessage(pszCommand);
814 ssSend << a1 << a2 << a3 << a4 << a5 << a6;
815 EndMessage(pszCommand);
817 catch (...)
819 AbortMessage();
820 throw;
824 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
825 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)
829 BeginMessage(pszCommand);
830 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
831 EndMessage(pszCommand);
833 catch (...)
835 AbortMessage();
836 throw;
840 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
841 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)
845 BeginMessage(pszCommand);
846 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
847 EndMessage(pszCommand);
849 catch (...)
851 AbortMessage();
852 throw;
856 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
857 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)
861 BeginMessage(pszCommand);
862 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
863 EndMessage(pszCommand);
865 catch (...)
867 AbortMessage();
868 throw;
872 void CloseSocketDisconnect();
874 void copyStats(CNodeStats &stats);
876 ServiceFlags GetLocalServices() const
878 return nLocalServices;
886 /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
887 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
889 #endif // BITCOIN_NET_H