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