]>
Commit | Line | Data |
---|---|---|
0a61b0df | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
78253fcb | 3 | // Distributed under the MIT software license, see the accompanying |
3a25a2b9 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
51ed9ec9 | 5 | |
223b6f1b WL |
6 | #ifndef BITCOIN_NET_H |
7 | #define BITCOIN_NET_H | |
8 | ||
51ed9ec9 BD |
9 | #include "bloom.h" |
10 | #include "compat.h" | |
11 | #include "hash.h" | |
12 | #include "limitedmap.h" | |
13 | #include "mruset.h" | |
14 | #include "netbase.h" | |
15 | #include "protocol.h" | |
6354935c | 16 | #include "random.h" |
fa736190 | 17 | #include "streams.h" |
51ed9ec9 BD |
18 | #include "sync.h" |
19 | #include "uint256.h" | |
ad49c256 | 20 | #include "utilstrencodings.h" |
51ed9ec9 | 21 | |
223b6f1b | 22 | #include <deque> |
51ed9ec9 | 23 | #include <stdint.h> |
223b6f1b | 24 | |
9cb1ec9c | 25 | #ifndef _WIN32 |
223b6f1b WL |
26 | #include <arpa/inet.h> |
27 | #endif | |
0a61b0df | 28 | |
ad49c256 | 29 | #include <boost/filesystem/path.hpp> |
51ed9ec9 BD |
30 | #include <boost/foreach.hpp> |
31 | #include <boost/signals2/signal.hpp> | |
6e68524e | 32 | |
51ed9ec9 | 33 | class CAddrMan; |
0a61b0df | 34 | class CBlockIndex; |
9a1dcea2 | 35 | class CScheduler; |
51ed9ec9 | 36 | class CNode; |
0a61b0df | 37 | |
51ed9ec9 BD |
38 | namespace boost { |
39 | class thread_group; | |
e10dcf27 | 40 | } // namespace boost |
0a61b0df | 41 | |
f1920e86 PW |
42 | /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */ |
43 | static const int PING_INTERVAL = 2 * 60; | |
44 | /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ | |
45 | static const int TIMEOUT_INTERVAL = 20 * 60; | |
51ed9ec9 BD |
46 | /** The maximum number of entries in an 'inv' protocol message */ |
47 | static const unsigned int MAX_INV_SZ = 50000; | |
12a49cac PW |
48 | /** The maximum number of new addresses to accumulate before announcing. */ |
49 | static const unsigned int MAX_ADDR_TO_SEND = 1000; | |
ba04c4a7 PW |
50 | /** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ |
51 | static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; | |
56b07d2d PK |
52 | /** -listen default */ |
53 | static const bool DEFAULT_LISTEN = true; | |
d4e1c612 PK |
54 | /** -upnp default */ |
55 | #ifdef USE_UPNP | |
56 | static const bool DEFAULT_UPNP = USE_UPNP; | |
57 | #else | |
58 | static const bool DEFAULT_UPNP = false; | |
59 | #endif | |
d4168c82 WL |
60 | /** The maximum number of entries in mapAskFor */ |
61 | static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; | |
e2190f80 GM |
62 | /** The maximum number of entries in setAskFor (larger due to getdata latency)*/ |
63 | static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ; | |
8a5ae3c7 MQ |
64 | /** The maximum number of peer connections to maintain. */ |
65 | static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; | |
0a61b0df | 66 | |
651480c8 WL |
67 | unsigned int ReceiveFloodSize(); |
68 | unsigned int SendBufferSize(); | |
0a61b0df | 69 | |
db954a65 | 70 | void AddOneShot(const std::string& strDest); |
67a42f92 PW |
71 | void AddressCurrentlyConnected(const CService& addr); |
72 | CNode* FindNode(const CNetAddr& ip); | |
e5219399 | 73 | CNode* FindNode(const CSubNet& subNet); |
0430c30a | 74 | CNode* FindNode(const std::string& addrName); |
67a42f92 | 75 | CNode* FindNode(const CService& ip); |
5bd6c31b | 76 | CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL); |
b641c9cd | 77 | bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); |
21eb5ada | 78 | void MapPort(bool fUseUPnP); |
5a3cb32e | 79 | unsigned short GetListenPort(); |
dc942e6f | 80 | bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); |
9a1dcea2 | 81 | void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler); |
0a61b0df | 82 | bool StopNode(); |
b9ff2970 | 83 | void SocketSendData(CNode *pnode); |
0a61b0df | 84 | |
b2864d2f PW |
85 | typedef int NodeId; |
86 | ||
9519a9a4 PW |
87 | struct CombinerAll |
88 | { | |
89 | typedef bool result_type; | |
90 | ||
91 | template<typename I> | |
92 | bool operator()(I first, I last) const | |
93 | { | |
94 | while (first != last) { | |
95 | if (!(*first)) return false; | |
96 | ++first; | |
97 | } | |
98 | return true; | |
99 | } | |
100 | }; | |
101 | ||
501da250 EL |
102 | // Signals for message handling |
103 | struct CNodeSignals | |
104 | { | |
4c6d41b8 | 105 | boost::signals2::signal<int ()> GetHeight; |
9519a9a4 PW |
106 | boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages; |
107 | boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages; | |
b2864d2f PW |
108 | boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode; |
109 | boost::signals2::signal<void (NodeId)> FinalizeNode; | |
501da250 EL |
110 | }; |
111 | ||
b2864d2f | 112 | |
501da250 | 113 | CNodeSignals& GetNodeSignals(); |
663224c2 | 114 | |
663224c2 | 115 | |
39857190 PW |
116 | enum |
117 | { | |
7fa4443f PW |
118 | LOCAL_NONE, // unknown |
119 | LOCAL_IF, // address a local interface listens on | |
8f10a288 | 120 | LOCAL_BIND, // address explicit bound to |
7fa4443f | 121 | LOCAL_UPNP, // address reported by UPnP |
7fa4443f | 122 | LOCAL_MANUAL, // address explicitly specified (-externalip=) |
19b6958c PW |
123 | |
124 | LOCAL_MAX | |
39857190 PW |
125 | }; |
126 | ||
845c86d1 GM |
127 | bool IsPeerAddrLocalGood(CNode *pnode); |
128 | void AdvertizeLocal(CNode *pnode); | |
457754d2 | 129 | void SetLimited(enum Network net, bool fLimited = true); |
0f1707de | 130 | bool IsLimited(enum Network net); |
457754d2 | 131 | bool IsLimited(const CNetAddr& addr); |
7fa4443f | 132 | bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); |
5a3cb32e | 133 | bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); |
975dc649 | 134 | bool RemoveLocal(const CService& addr); |
7fa4443f PW |
135 | bool SeenLocal(const CService& addr); |
136 | bool IsLocal(const CService& addr); | |
137 | bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); | |
c91a9471 | 138 | bool IsReachable(enum Network net); |
090e5b40 | 139 | bool IsReachable(const CNetAddr &addr); |
39857190 PW |
140 | CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); |
141 | ||
090e5b40 | 142 | |
587f929c | 143 | extern bool fDiscover; |
53a08815 | 144 | extern bool fListen; |
51ed9ec9 BD |
145 | extern uint64_t nLocalServices; |
146 | extern uint64_t nLocalHostNonce; | |
5fee401f | 147 | extern CAddrMan addrman; |
0560d671 | 148 | /** Maximum number of connections to simultaneously allow (aka connection slots) */ |
ba29a559 | 149 | extern int nMaxConnections; |
0a61b0df | 150 | |
223b6f1b | 151 | extern std::vector<CNode*> vNodes; |
0a61b0df | 152 | extern CCriticalSection cs_vNodes; |
223b6f1b | 153 | extern std::map<CInv, CDataStream> mapRelay; |
51ed9ec9 | 154 | extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration; |
0a61b0df | 155 | extern CCriticalSection cs_mapRelay; |
51ed9ec9 | 156 | extern limitedmap<CInv, int64_t> mapAlreadyAskedFor; |
0a61b0df | 157 | |
74088e86 MC |
158 | extern std::vector<std::string> vAddedNodes; |
159 | extern CCriticalSection cs_vAddedNodes; | |
160 | ||
b2864d2f PW |
161 | extern NodeId nLastNodeId; |
162 | extern CCriticalSection cs_nLastNodeId; | |
0a61b0df | 163 | |
d387b8ec WL |
164 | struct LocalServiceInfo { |
165 | int nScore; | |
166 | int nPort; | |
167 | }; | |
168 | ||
169 | extern CCriticalSection cs_mapLocalHost; | |
2871889e | 170 | extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost; |
0a61b0df | 171 | |
1006f070 JG |
172 | class CNodeStats |
173 | { | |
174 | public: | |
b2864d2f | 175 | NodeId nodeid; |
51ed9ec9 BD |
176 | uint64_t nServices; |
177 | int64_t nLastSend; | |
178 | int64_t nLastRecv; | |
179 | int64_t nTimeConnected; | |
26a6bae7 | 180 | int64_t nTimeOffset; |
1006f070 JG |
181 | std::string addrName; |
182 | int nVersion; | |
a946aa8d | 183 | std::string cleanSubVer; |
1006f070 | 184 | bool fInbound; |
1006f070 | 185 | int nStartingHeight; |
51ed9ec9 BD |
186 | uint64_t nSendBytes; |
187 | uint64_t nRecvBytes; | |
dc942e6f | 188 | bool fWhitelisted; |
971bb3e9 JL |
189 | double dPingTime; |
190 | double dPingWait; | |
547c61f8 | 191 | std::string addrLocal; |
1006f070 JG |
192 | }; |
193 | ||
194 | ||
195 | ||
0a61b0df | 196 | |
607dbfde JG |
197 | class CNetMessage { |
198 | public: | |
199 | bool in_data; // parsing header (false) or data (true) | |
200 | ||
201 | CDataStream hdrbuf; // partially received header | |
202 | CMessageHeader hdr; // complete header | |
203 | unsigned int nHdrPos; | |
204 | ||
205 | CDataStream vRecv; // received message data | |
206 | unsigned int nDataPos; | |
207 | ||
9f4da19b PW |
208 | int64_t nTime; // time (in microseconds) of message receipt. |
209 | ||
eec37136 | 210 | CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) { |
607dbfde JG |
211 | hdrbuf.resize(24); |
212 | in_data = false; | |
213 | nHdrPos = 0; | |
214 | nDataPos = 0; | |
9f4da19b | 215 | nTime = 0; |
607dbfde JG |
216 | } |
217 | ||
218 | bool complete() const | |
219 | { | |
220 | if (!in_data) | |
221 | return false; | |
222 | return (hdr.nMessageSize == nDataPos); | |
223 | } | |
224 | ||
225 | void SetVersion(int nVersionIn) | |
226 | { | |
227 | hdrbuf.SetVersion(nVersionIn); | |
228 | vRecv.SetVersion(nVersionIn); | |
229 | } | |
230 | ||
231 | int readHeader(const char *pch, unsigned int nBytes); | |
232 | int readData(const char *pch, unsigned int nBytes); | |
233 | }; | |
234 | ||
235 | ||
236 | ||
237 | ||
0a61b0df | 238 | |
6b8de05d | 239 | /** Information about a peer */ |
0a61b0df | 240 | class CNode |
241 | { | |
242 | public: | |
243 | // socket | |
51ed9ec9 | 244 | uint64_t nServices; |
0a61b0df | 245 | SOCKET hSocket; |
41b052ad PW |
246 | CDataStream ssSend; |
247 | size_t nSendSize; // total size of all vSendMsg entries | |
248 | size_t nSendOffset; // offset inside the first vSendMsg already sent | |
51ed9ec9 | 249 | uint64_t nSendBytes; |
41b052ad | 250 | std::deque<CSerializeData> vSendMsg; |
0a61b0df | 251 | CCriticalSection cs_vSend; |
607dbfde | 252 | |
c7f039b6 | 253 | std::deque<CInv> vRecvGetData; |
967f2459 | 254 | std::deque<CNetMessage> vRecvMsg; |
607dbfde | 255 | CCriticalSection cs_vRecvMsg; |
51ed9ec9 | 256 | uint64_t nRecvBytes; |
607dbfde JG |
257 | int nRecvVersion; |
258 | ||
51ed9ec9 BD |
259 | int64_t nLastSend; |
260 | int64_t nLastRecv; | |
51ed9ec9 | 261 | int64_t nTimeConnected; |
26a6bae7 | 262 | int64_t nTimeOffset; |
0a61b0df | 263 | CAddress addr; |
9bab521d | 264 | std::string addrName; |
7fa4443f | 265 | CService addrLocal; |
0a61b0df | 266 | int nVersion; |
8ab425f8 | 267 | int lasthdrsreq,sendhdrsreq; |
c037531d | 268 | // strSubVer is whatever byte array we read from the wire. However, this field is intended |
a946aa8d MH |
269 | // to be printed out, displayed to humans in various forms and so on. So we sanitize it and |
270 | // store the sanitized version in cleanSubVer. The original should be used when dealing with | |
271 | // the network or wire types and the cleaned string used when displayed or logged. | |
272 | std::string strSubVer, cleanSubVer; | |
dc942e6f | 273 | bool fWhitelisted; // This peer can bypass DoS banning. |
478b01d9 | 274 | bool fOneShot; |
0a61b0df | 275 | bool fClient; |
276 | bool fInbound; | |
277 | bool fNetworkNode; | |
278 | bool fSuccessfullyConnected; | |
279 | bool fDisconnect; | |
4c8fc1a5 MC |
280 | // We use fRelayTxes for two purposes - |
281 | // a) it allows us to not relay tx invs before receiving the peer's version message | |
7e6d23b1 CD |
282 | // b) the peer may tell us in its version message that we should not relay tx invs |
283 | // until it has initialized its bloom filter. | |
4c8fc1a5 | 284 | bool fRelayTxes; |
a514cb29 | 285 | bool fSentAddr; |
c59abe25 | 286 | CSemaphoreGrant grantOutbound; |
422d1225 MC |
287 | CCriticalSection cs_filter; |
288 | CBloomFilter* pfilter; | |
0a61b0df | 289 | int nRefCount; |
b2864d2f | 290 | NodeId id; |
cedaa714 | 291 | protected: |
15f3ad4d GA |
292 | |
293 | // Denial-of-service detection/prevention | |
814efd6f | 294 | // Key is IP address, value is banned-until-time |
e5219399 | 295 | static std::map<CSubNet, int64_t> setBanned; |
15f3ad4d | 296 | static CCriticalSection cs_setBanned; |
15f3ad4d | 297 | |
dc942e6f PW |
298 | // Whitelisted ranges. Any node connecting from these is automatically |
299 | // whitelisted (as well as those connecting to whitelisted binds). | |
300 | static std::vector<CSubNet> vWhitelistedRange; | |
301 | static CCriticalSection cs_vWhitelistedRange; | |
302 | ||
9038b18f GA |
303 | // Basic fuzz-testing |
304 | void Fuzz(int nChance); // modifies ssSend | |
305 | ||
0a61b0df | 306 | public: |
0a61b0df | 307 | uint256 hashContinue; |
0a61b0df | 308 | int nStartingHeight; |
309 | ||
310 | // flood relay | |
223b6f1b | 311 | std::vector<CAddress> vAddrToSend; |
d81cff32 | 312 | CRollingBloomFilter addrKnown; |
0a61b0df | 313 | bool fGetAddr; |
223b6f1b | 314 | std::set<uint256> setKnown; |
0a61b0df | 315 | |
316 | // inventory based relay | |
c4341fa6 | 317 | mruset<CInv> setInventoryKnown; |
223b6f1b | 318 | std::vector<CInv> vInventoryToSend; |
0a61b0df | 319 | CCriticalSection cs_inventory; |
56f165bd | 320 | std::set<uint256> setAskFor; |
51ed9ec9 | 321 | std::multimap<int64_t, CInv> mapAskFor; |
0a61b0df | 322 | |
f1920e86 PW |
323 | // Ping time measurement: |
324 | // The pong reply we're expecting, or 0 if no pong expected. | |
51ed9ec9 | 325 | uint64_t nPingNonceSent; |
f1920e86 | 326 | // Time (in usec) the last ping was sent, or 0 if no ping was ever sent. |
51ed9ec9 | 327 | int64_t nPingUsecStart; |
f1920e86 | 328 | // Last measured round-trip time. |
51ed9ec9 | 329 | int64_t nPingUsecTime; |
e279e5f9 PS |
330 | // Best measured round-trip time. |
331 | int64_t nMinPingUsecTime; | |
f1920e86 | 332 | // Whether a ping is requested. |
971bb3e9 | 333 | bool fPingQueued; |
c037531d | 334 | |
db954a65 | 335 | CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false); |
651480c8 | 336 | ~CNode(); |
0a61b0df | 337 | |
338 | private: | |
ce14345a SE |
339 | // Network usage totals |
340 | static CCriticalSection cs_totalBytesRecv; | |
341 | static CCriticalSection cs_totalBytesSent; | |
51ed9ec9 BD |
342 | static uint64_t nTotalBytesRecv; |
343 | static uint64_t nTotalBytesSent; | |
ce14345a | 344 | |
0a61b0df | 345 | CNode(const CNode&); |
346 | void operator=(const CNode&); | |
ce14345a | 347 | |
0a61b0df | 348 | public: |
349 | ||
b2864d2f PW |
350 | NodeId GetId() const { |
351 | return id; | |
352 | } | |
0a61b0df | 353 | |
354 | int GetRefCount() | |
355 | { | |
cedaa714 PW |
356 | assert(nRefCount >= 0); |
357 | return nRefCount; | |
0a61b0df | 358 | } |
359 | ||
607dbfde JG |
360 | // requires LOCK(cs_vRecvMsg) |
361 | unsigned int GetTotalRecvSize() | |
362 | { | |
363 | unsigned int total = 0; | |
96b9603c | 364 | BOOST_FOREACH(const CNetMessage &msg, vRecvMsg) |
967f2459 | 365 | total += msg.vRecv.size() + 24; |
607dbfde JG |
366 | return total; |
367 | } | |
368 | ||
369 | // requires LOCK(cs_vRecvMsg) | |
370 | bool ReceiveMsgBytes(const char *pch, unsigned int nBytes); | |
371 | ||
372 | // requires LOCK(cs_vRecvMsg) | |
373 | void SetRecvVersion(int nVersionIn) | |
374 | { | |
375 | nRecvVersion = nVersionIn; | |
967f2459 PW |
376 | BOOST_FOREACH(CNetMessage &msg, vRecvMsg) |
377 | msg.SetVersion(nVersionIn); | |
607dbfde JG |
378 | } |
379 | ||
cedaa714 | 380 | CNode* AddRef() |
0a61b0df | 381 | { |
cedaa714 | 382 | nRefCount++; |
0a61b0df | 383 | return this; |
384 | } | |
385 | ||
386 | void Release() | |
387 | { | |
388 | nRefCount--; | |
389 | } | |
390 | ||
391 | ||
392 | ||
393 | void AddAddressKnown(const CAddress& addr) | |
394 | { | |
d81cff32 | 395 | addrKnown.insert(addr.GetKey()); |
0a61b0df | 396 | } |
397 | ||
398 | void PushAddress(const CAddress& addr) | |
399 | { | |
400 | // Known checking here is only to save space from duplicates. | |
401 | // SendMessages will filter it again for knowns that were added | |
402 | // after addresses were pushed. | |
d81cff32 | 403 | if (addr.IsValid() && !addrKnown.contains(addr.GetKey())) { |
12a49cac PW |
404 | if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) { |
405 | vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr; | |
406 | } else { | |
407 | vAddrToSend.push_back(addr); | |
408 | } | |
409 | } | |
0a61b0df | 410 | } |
411 | ||
412 | ||
413 | void AddInventoryKnown(const CInv& inv) | |
414 | { | |
f8dcd5ca PW |
415 | { |
416 | LOCK(cs_inventory); | |
0a61b0df | 417 | setInventoryKnown.insert(inv); |
f8dcd5ca | 418 | } |
0a61b0df | 419 | } |
420 | ||
421 | void PushInventory(const CInv& inv) | |
422 | { | |
f8dcd5ca PW |
423 | { |
424 | LOCK(cs_inventory); | |
0a61b0df | 425 | if (!setInventoryKnown.count(inv)) |
426 | vInventoryToSend.push_back(inv); | |
f8dcd5ca | 427 | } |
0a61b0df | 428 | } |
429 | ||
651480c8 | 430 | void AskFor(const CInv& inv); |
0a61b0df | 431 | |
25511af4 | 432 | // TODO: Document the postcondition of this function. Is cs_vSend locked? |
651480c8 | 433 | void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend); |
0a61b0df | 434 | |
25511af4 | 435 | // TODO: Document the precondition of this function. Is cs_vSend locked? |
651480c8 | 436 | void AbortMessage() UNLOCK_FUNCTION(cs_vSend); |
0a61b0df | 437 | |
25511af4 | 438 | // TODO: Document the precondition of this function. Is cs_vSend locked? |
651480c8 | 439 | void EndMessage() UNLOCK_FUNCTION(cs_vSend); |
0a61b0df | 440 | |
f8ded588 | 441 | void PushVersion(); |
cbc920d4 | 442 | |
0a61b0df | 443 | |
444 | void PushMessage(const char* pszCommand) | |
445 | { | |
446 | try | |
447 | { | |
448 | BeginMessage(pszCommand); | |
449 | EndMessage(); | |
450 | } | |
451 | catch (...) | |
452 | { | |
453 | AbortMessage(); | |
454 | throw; | |
455 | } | |
456 | } | |
457 | ||
458 | template<typename T1> | |
459 | void PushMessage(const char* pszCommand, const T1& a1) | |
460 | { | |
461 | try | |
462 | { | |
463 | BeginMessage(pszCommand); | |
41b052ad | 464 | ssSend << a1; |
0a61b0df | 465 | EndMessage(); |
466 | } | |
467 | catch (...) | |
468 | { | |
469 | AbortMessage(); | |
470 | throw; | |
471 | } | |
472 | } | |
473 | ||
474 | template<typename T1, typename T2> | |
475 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) | |
476 | { | |
477 | try | |
478 | { | |
479 | BeginMessage(pszCommand); | |
41b052ad | 480 | ssSend << a1 << a2; |
0a61b0df | 481 | EndMessage(); |
482 | } | |
483 | catch (...) | |
484 | { | |
485 | AbortMessage(); | |
486 | throw; | |
487 | } | |
488 | } | |
489 | ||
490 | template<typename T1, typename T2, typename T3> | |
491 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) | |
492 | { | |
493 | try | |
494 | { | |
495 | BeginMessage(pszCommand); | |
41b052ad | 496 | ssSend << a1 << a2 << a3; |
0a61b0df | 497 | EndMessage(); |
498 | } | |
499 | catch (...) | |
500 | { | |
501 | AbortMessage(); | |
502 | throw; | |
503 | } | |
504 | } | |
505 | ||
506 | template<typename T1, typename T2, typename T3, typename T4> | |
507 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) | |
508 | { | |
509 | try | |
510 | { | |
511 | BeginMessage(pszCommand); | |
41b052ad | 512 | ssSend << a1 << a2 << a3 << a4; |
0a61b0df | 513 | EndMessage(); |
514 | } | |
515 | catch (...) | |
516 | { | |
517 | AbortMessage(); | |
518 | throw; | |
519 | } | |
520 | } | |
521 | ||
522 | template<typename T1, typename T2, typename T3, typename T4, typename T5> | |
523 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) | |
524 | { | |
525 | try | |
526 | { | |
527 | BeginMessage(pszCommand); | |
41b052ad | 528 | ssSend << a1 << a2 << a3 << a4 << a5; |
0a61b0df | 529 | EndMessage(); |
530 | } | |
531 | catch (...) | |
532 | { | |
533 | AbortMessage(); | |
534 | throw; | |
535 | } | |
536 | } | |
537 | ||
538 | template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> | |
539 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6) | |
540 | { | |
541 | try | |
542 | { | |
543 | BeginMessage(pszCommand); | |
41b052ad | 544 | ssSend << a1 << a2 << a3 << a4 << a5 << a6; |
0a61b0df | 545 | EndMessage(); |
546 | } | |
547 | catch (...) | |
548 | { | |
549 | AbortMessage(); | |
550 | throw; | |
551 | } | |
552 | } | |
553 | ||
554 | template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> | |
555 | 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) | |
556 | { | |
557 | try | |
558 | { | |
559 | BeginMessage(pszCommand); | |
41b052ad | 560 | ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; |
0a61b0df | 561 | EndMessage(); |
562 | } | |
563 | catch (...) | |
564 | { | |
565 | AbortMessage(); | |
566 | throw; | |
567 | } | |
568 | } | |
569 | ||
570 | template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> | |
571 | 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) | |
572 | { | |
573 | try | |
574 | { | |
575 | BeginMessage(pszCommand); | |
41b052ad | 576 | ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; |
0a61b0df | 577 | EndMessage(); |
578 | } | |
579 | catch (...) | |
580 | { | |
581 | AbortMessage(); | |
582 | throw; | |
583 | } | |
584 | } | |
585 | ||
586 | template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> | |
587 | 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) | |
588 | { | |
589 | try | |
590 | { | |
591 | BeginMessage(pszCommand); | |
41b052ad | 592 | ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; |
0a61b0df | 593 | EndMessage(); |
594 | } | |
595 | catch (...) | |
596 | { | |
597 | AbortMessage(); | |
598 | throw; | |
599 | } | |
600 | } | |
601 | ||
0a61b0df | 602 | void CloseSocketDisconnect(); |
15f3ad4d GA |
603 | |
604 | // Denial-of-service detection/prevention | |
605 | // The idea is to detect peers that are behaving | |
606 | // badly and disconnect/ban them, but do it in a | |
607 | // one-coding-mistake-won't-shatter-the-entire-network | |
608 | // way. | |
609 | // IMPORTANT: There should be nothing I can give a | |
610 | // node that it will forward on that will make that | |
611 | // node's peers drop it. If there is, an attacker | |
612 | // can isolate a node and/or try to split the network. | |
613 | // Dropping a node for sending stuff that is invalid | |
614 | // now but might be valid in a later version is also | |
615 | // dangerous, because it can cause a network split | |
616 | // between nodes running old code and nodes running | |
617 | // new code. | |
618 | static void ClearBanned(); // needed for unit testing | |
67a42f92 | 619 | static bool IsBanned(CNetAddr ip); |
e5219399 | 620 | static bool IsBanned(CSubNet subnet); |
fcc8920f JS |
621 | static void Ban(const CNetAddr &ip, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false); |
622 | static void Ban(const CSubNet &subNet, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false); | |
99782971 | 623 | static bool Unban(const CNetAddr &ip); |
e5219399 JS |
624 | static bool Unban(const CSubNet &ip); |
625 | static void GetBanned(std::map<CSubNet, int64_t> &banmap); | |
99782971 | 626 | |
1006f070 | 627 | void copyStats(CNodeStats &stats); |
ce14345a | 628 | |
dc942e6f PW |
629 | static bool IsWhitelistedRange(const CNetAddr &ip); |
630 | static void AddWhitelistedRange(const CSubNet &subnet); | |
631 | ||
ce14345a | 632 | // Network stats |
51ed9ec9 BD |
633 | static void RecordBytesRecv(uint64_t bytes); |
634 | static void RecordBytesSent(uint64_t bytes); | |
ce14345a | 635 | |
51ed9ec9 BD |
636 | static uint64_t GetTotalBytesRecv(); |
637 | static uint64_t GetTotalBytesSent(); | |
0a61b0df | 638 | }; |
639 | ||
640 | ||
641 | ||
269d9c64 | 642 | class CTransaction; |
d38da59b PW |
643 | void RelayTransaction(const CTransaction& tx); |
644 | void RelayTransaction(const CTransaction& tx, const CDataStream& ss); | |
0a61b0df | 645 | |
d004d727 WL |
646 | /** Access to the (IP) address database (peers.dat) */ |
647 | class CAddrDB | |
648 | { | |
649 | private: | |
650 | boost::filesystem::path pathAddr; | |
651 | public: | |
652 | CAddrDB(); | |
653 | bool Write(const CAddrMan& addr); | |
654 | bool Read(CAddrMan& addr); | |
655 | }; | |
656 | ||
093303a8 | 657 | #endif // BITCOIN_NET_H |