Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2015 The Bitcoin developers
3 : // Copyright (c) 2014-2015 The Dash developers
4 : // Copyright (c) 2015-2022 The PIVX Core developers
5 : // Distributed under the MIT/X11 software license, see the accompanying
6 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 :
8 : #if defined(HAVE_CONFIG_H)
9 : #include "config/pivx-config.h"
10 : #endif
11 :
12 : #include "net.h"
13 :
14 : #include "chainparams.h"
15 : #include "clientversion.h"
16 : #include "crypto/common.h"
17 : #include "crypto/sha256.h"
18 : #include "guiinterface.h"
19 : #include "netaddress.h"
20 : #include "netbase.h"
21 : #include "netmessagemaker.h"
22 : #include "optional.h"
23 : #include "primitives/transaction.h"
24 : #include "scheduler.h"
25 : #include "tiertwo/net_masternodes.h"
26 :
27 : #ifdef WIN32
28 : #include <string.h>
29 : #else
30 : #include <fcntl.h>
31 : #endif
32 :
33 : #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
34 : #include <ifaddrs.h>
35 : #endif
36 :
37 : #ifdef USE_POLL
38 : #include <poll.h>
39 : #endif
40 :
41 : #include <cstdint>
42 : #include <unordered_map>
43 :
44 : #include <math.h>
45 :
46 : // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
47 : #define DUMP_ADDRESSES_INTERVAL 900
48 :
49 : // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
50 : #define FEELER_SLEEP_WINDOW 1
51 :
52 : #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
53 : #define MSG_NOSIGNAL 0
54 : #endif
55 :
56 : // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
57 : // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
58 : #ifdef WIN32
59 : #ifndef PROTECTION_LEVEL_UNRESTRICTED
60 : #define PROTECTION_LEVEL_UNRESTRICTED 10
61 : #endif
62 : #ifndef IPV6_PROTECTION_LEVEL
63 : #define IPV6_PROTECTION_LEVEL 23
64 : #endif
65 : #endif
66 :
67 : /** Used to pass flags to the Bind() function */
68 : enum BindFlags {
69 : BF_NONE = 0,
70 : BF_EXPLICIT = (1U << 0),
71 : BF_REPORT_ERROR = (1U << 1),
72 : BF_WHITELIST = (1U << 2),
73 : };
74 :
75 : // The set of sockets cannot be modified while waiting
76 : // The sleep time needs to be small to avoid new sockets stalling
77 : static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
78 :
79 : const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
80 :
81 : constexpr const CConnman::CFullyConnectedOnly CConnman::FullyConnectedOnly;
82 : constexpr const CConnman::CAllNodes CConnman::AllNodes;
83 :
84 : static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
85 : static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
86 : //
87 : // Global state variables
88 : //
89 : bool fDiscover = true;
90 : bool fListen = true;
91 : RecursiveMutex cs_mapLocalHost;
92 : std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
93 : static bool vfLimited[NET_MAX] = {};
94 : std::string strSubVersion;
95 :
96 : limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
97 :
98 0 : void CConnman::AddOneShot(const std::string& strDest)
99 : {
100 0 : LOCK(cs_vOneShots);
101 0 : vOneShots.push_back(strDest);
102 0 : }
103 :
104 2118 : uint16_t GetListenPort()
105 : {
106 2118 : return (uint16_t)(gArgs.GetArg("-port", Params().GetDefaultPort()));
107 : }
108 :
109 : // find 'best' local address for a particular peer
110 1683 : bool GetLocal(CService& addr, const CNetAddr* paddrPeer)
111 : {
112 1683 : if (!fListen)
113 : return false;
114 :
115 1683 : int nBestScore = -1;
116 1683 : int nBestReachability = -1;
117 1683 : {
118 1683 : LOCK(cs_mapLocalHost);
119 1684 : for (const auto& entry : mapLocalHost) {
120 1 : int nScore = entry.second.nScore;
121 1 : int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
122 1 : if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
123 1 : addr = CService(entry.first, entry.second.nPort);
124 1 : nBestReachability = nReachability;
125 1 : nBestScore = nScore;
126 : }
127 : }
128 : }
129 1683 : return nBestScore >= 0;
130 : }
131 :
132 : //! Convert the serialized seeds into usable address objects.
133 118 : static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
134 : {
135 : // It'll only connect to one or two seed nodes because once it connects,
136 : // it'll get a pile of addresses with newer timestamps.
137 : // Seed nodes are given a random 'last seen time' of between one and two
138 : // weeks ago.
139 118 : const int64_t nOneWeek = 7 * 24 * 60 * 60;
140 118 : std::vector<CAddress> vSeedsOut;
141 118 : FastRandomContext rng;
142 118 : CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
143 118 : while (!s.eof()) {
144 0 : CService endpoint;
145 0 : s >> endpoint;
146 0 : CAddress addr{endpoint, NODE_NETWORK};
147 0 : addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
148 0 : LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString());
149 0 : vSeedsOut.push_back(addr);
150 : }
151 118 : return vSeedsOut;
152 : }
153 :
154 : // get best local address for a particular peer as a CAddress
155 : // Otherwise, return the unroutable 0.0.0.0 but filled in with
156 : // the normal parameters, since the IP may be changed to a useful
157 : // one by discovery.
158 1422 : CAddress GetLocalAddress(const CNetAddr* paddrPeer, ServiceFlags nLocalServices)
159 : {
160 2844 : CAddress ret(CService(CNetAddr(), GetListenPort()), nLocalServices);
161 1422 : CService addr;
162 1422 : if (GetLocal(addr, paddrPeer)) {
163 1 : ret = CAddress(addr, nLocalServices);
164 : }
165 1422 : ret.nTime = GetAdjustedTime();
166 1422 : return ret;
167 : }
168 :
169 0 : int GetnScore(const CService& addr)
170 : {
171 0 : LOCK(cs_mapLocalHost);
172 0 : if (mapLocalHost.count(addr) == LOCAL_NONE)
173 0 : return 0;
174 0 : return mapLocalHost[addr].nScore;
175 : }
176 :
177 : // Is our peer's addrLocal potentially useful as an external IP source?
178 1422 : bool IsPeerAddrLocalGood(CNode* pnode)
179 : {
180 1422 : CService addrLocal = pnode->GetAddrLocal();
181 1423 : return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
182 1423 : IsReachable(addrLocal.GetNetwork());
183 : }
184 :
185 : // pushes our own address to a peer
186 1207 : void AdvertiseLocal(CNode* pnode)
187 : {
188 1207 : if (fListen && pnode->fSuccessfullyConnected) {
189 2414 : CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
190 : // If discovery is enabled, sometimes give our peer the address it
191 : // tells us that it sees us as in case it has a better idea of our
192 : // address than we do.
193 1207 : FastRandomContext rng;
194 1207 : if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
195 0 : rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0)) {
196 2 : addrLocal.SetIP(pnode->GetAddrLocal());
197 : }
198 1207 : if (addrLocal.IsRoutable()) {
199 1 : LogPrintf("%s: advertising address %s\n", __func__, addrLocal.ToString());
200 1 : pnode->PushAddress(addrLocal, rng);
201 : }
202 : }
203 1207 : }
204 :
205 : // learn a new local address
206 77 : bool AddLocal(const CService& addr, int nScore)
207 : {
208 77 : if (!addr.IsRoutable())
209 : return false;
210 :
211 1 : if (!fDiscover && nScore < LOCAL_MANUAL)
212 : return false;
213 :
214 1 : if (!IsReachable(addr))
215 : return false;
216 :
217 1 : LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
218 :
219 1 : {
220 1 : LOCK(cs_mapLocalHost);
221 1 : bool fAlready = mapLocalHost.count(addr) > 0;
222 1 : LocalServiceInfo& info = mapLocalHost[addr];
223 1 : if (!fAlready || nScore >= info.nScore) {
224 1 : info.nScore = nScore + (fAlready ? 1 : 0);
225 1 : info.nPort = addr.GetPort();
226 : }
227 : }
228 :
229 1 : return true;
230 : }
231 :
232 0 : bool AddLocal(const CNetAddr& addr, int nScore)
233 : {
234 0 : return AddLocal(CService(addr, GetListenPort()), nScore);
235 : }
236 :
237 1 : bool RemoveLocal(const CService& addr)
238 : {
239 1 : LOCK(cs_mapLocalHost);
240 1 : LogPrintf("RemoveLocal(%s)\n", addr.ToString());
241 1 : mapLocalHost.erase(addr);
242 2 : return true;
243 : }
244 :
245 377 : void SetReachable(enum Network net, bool reachable)
246 : {
247 377 : if (net == NET_UNROUTABLE || net == NET_INTERNAL)
248 2 : return;
249 750 : LOCK(cs_mapLocalHost);
250 375 : vfLimited[net] = !reachable;
251 : }
252 :
253 8103 : bool IsReachable(enum Network net)
254 : {
255 8103 : LOCK(cs_mapLocalHost);
256 8103 : return !vfLimited[net];
257 : }
258 :
259 757 : bool IsReachable(const CNetAddr& addr)
260 : {
261 757 : return IsReachable(addr.GetNetwork());
262 : }
263 :
264 : /** vote for a local address */
265 0 : bool SeenLocal(const CService& addr)
266 : {
267 0 : {
268 0 : LOCK(cs_mapLocalHost);
269 0 : if (mapLocalHost.count(addr) == 0)
270 0 : return false;
271 0 : mapLocalHost[addr].nScore++;
272 : }
273 0 : return true;
274 : }
275 :
276 :
277 : /** check whether a given address is potentially local */
278 648 : bool IsLocal(const CService& addr)
279 : {
280 648 : LOCK(cs_mapLocalHost);
281 1944 : return mapLocalHost.count(addr) > 0;
282 : }
283 :
284 12 : CNode* CConnman::FindNode(const CNetAddr& ip)
285 : {
286 24 : LOCK(cs_vNodes);
287 32 : for (CNode* pnode : vNodes) {
288 20 : if (static_cast<CNetAddr>(pnode->addr) == ip) {
289 0 : return pnode;
290 : }
291 : }
292 12 : return nullptr;
293 : }
294 :
295 0 : CNode* CConnman::FindNode(const CSubNet& subNet)
296 : {
297 0 : LOCK(cs_vNodes);
298 0 : for (CNode* pnode : vNodes) {
299 0 : if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
300 0 : return pnode;
301 : }
302 : }
303 0 : return nullptr;
304 : }
305 :
306 771 : CNode* CConnman::FindNode(const std::string& addrName)
307 : {
308 1542 : LOCK(cs_vNodes);
309 3609 : for (CNode* pnode : vNodes) {
310 2990 : if (pnode->GetAddrName() == addrName) {
311 145 : return pnode;
312 : }
313 : }
314 626 : return nullptr;
315 : }
316 :
317 33 : CNode* CConnman::FindNode(const CService& addr)
318 : {
319 66 : LOCK(cs_vNodes);
320 33 : const bool isRegTestNet = Params().IsRegTestNet();
321 53 : for (CNode* pnode : vNodes) {
322 41 : if (isRegTestNet) {
323 : //if using regtest, just check the IP
324 41 : if (static_cast<CNetAddr>(pnode->addr) == static_cast<CNetAddr>(addr))
325 21 : return pnode;
326 : } else {
327 0 : if (pnode->addr == addr)
328 : return pnode;
329 : }
330 : }
331 12 : return nullptr;
332 : }
333 :
334 711 : bool CConnman::CheckIncomingNonce(uint64_t nonce)
335 : {
336 711 : LOCK(cs_vNodes);
337 4744 : for(CNode* pnode : vNodes) {
338 4033 : if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
339 0 : return false;
340 : }
341 711 : return true;
342 : }
343 :
344 704 : CNode* CConnman::ConnectNode(CAddress addrConnect, const char* pszDest, bool fCountFailure, bool manual_connection)
345 : {
346 704 : if (pszDest == nullptr) {
347 33 : if (IsLocal(addrConnect)) {
348 0 : LogPrintf("%s: cannot connect to local node\n", __func__);
349 0 : return nullptr;
350 : }
351 :
352 : // Look for an existing connection
353 33 : CNode* pnode = FindNode(static_cast<CService>(addrConnect));
354 33 : if (pnode) {
355 21 : LogPrintf("Failed to open new connection, already connected\n");
356 21 : return nullptr;
357 : }
358 : }
359 :
360 : /// debug print
361 1354 : LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
362 : pszDest ? pszDest : addrConnect.ToString(),
363 : pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime) / 3600.0);
364 :
365 : // Resolve
366 683 : const int default_port = Params().GetDefaultPort();
367 683 : if (pszDest) {
368 1342 : std::vector<CService> resolved;
369 1360 : if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
370 667 : addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
371 667 : if (!addrConnect.IsValid()) {
372 0 : LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
373 0 : return nullptr;
374 : }
375 : }
376 : }
377 :
378 : // Connect
379 683 : bool connected = false;
380 683 : SOCKET hSocket = INVALID_SOCKET;
381 1387 : proxyType proxy;
382 683 : if (addrConnect.IsValid()) {
383 679 : bool proxyConnectionFailed = false;
384 :
385 679 : if (GetProxy(addrConnect.GetNetwork(), proxy)) {
386 11 : hSocket = CreateSocket(proxy.proxy);
387 11 : if (hSocket == INVALID_SOCKET) {
388 0 : return nullptr;
389 : }
390 18 : connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
391 : } else {
392 : // no proxy needed (none set for target network)
393 668 : hSocket = CreateSocket(addrConnect);
394 668 : if (hSocket == INVALID_SOCKET) {
395 : return nullptr;
396 : }
397 668 : connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
398 : }
399 679 : if (!proxyConnectionFailed) {
400 : // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
401 : // the proxy, mark this as an attempt.
402 679 : addrman.Attempt(addrConnect, fCountFailure);
403 : }
404 4 : } else if (pszDest && GetNameProxy(proxy)) {
405 4 : hSocket = CreateSocket(proxy.proxy);
406 4 : if (hSocket == INVALID_SOCKET) {
407 0 : return nullptr;
408 : }
409 8 : std::string host;
410 4 : int port = default_port;
411 4 : SplitHostPort(std::string(pszDest), port, host);
412 4 : connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr);
413 : }
414 683 : if (!connected) {
415 15 : CloseSocket(hSocket);
416 : return nullptr;
417 : }
418 :
419 : // Add node
420 668 : NodeId id = GetNewNodeId();
421 668 : uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
422 1336 : CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false);
423 668 : pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
424 668 : pnode->fWhitelisted = IsWhitelistedRange(addrConnect);
425 668 : pnode->AddRef();
426 :
427 : // We're making a new connection, harvest entropy from the time (and our peer count)
428 668 : RandAddEvent((uint32_t)id);
429 :
430 668 : return pnode;
431 : }
432 :
433 652 : void CConnman::DumpBanlist()
434 : {
435 652 : SweepBanned(); // clean unused entries (if bantime has expired)
436 :
437 652 : if (!BannedSetIsDirty())
438 355 : return;
439 :
440 297 : int64_t nStart = GetTimeMillis();
441 :
442 594 : CBanDB bandb;
443 594 : banmap_t banmap;
444 297 : GetBanned(banmap);
445 297 : if (bandb.Write(banmap)) {
446 297 : SetBannedSetDirty(false);
447 : }
448 :
449 297 : LogPrint(BCLog::NET, "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
450 : banmap.size(), GetTimeMillis() - nStart);
451 : }
452 :
453 1780 : void CNode::CloseSocketDisconnect()
454 : {
455 1780 : fDisconnect = true;
456 1780 : LOCK(cs_hSocket);
457 1780 : if (hSocket != INVALID_SOCKET) {
458 1428 : LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
459 1428 : CloseSocket(hSocket);
460 : }
461 1780 : }
462 :
463 26870 : bool CNode::DisconnectOldProtocol(int nVersionIn, int nVersionRequired)
464 : {
465 26870 : fDisconnect = false;
466 26870 : if (nVersionIn < nVersionRequired) {
467 1 : LogPrintf("%s : peer=%d using obsolete version %i; disconnecting\n", __func__, id, nVersionIn);
468 1 : fDisconnect = true;
469 : }
470 26870 : return fDisconnect;
471 : }
472 :
473 11 : void CConnman::ClearBanned()
474 : {
475 11 : {
476 11 : LOCK(cs_setBanned);
477 11 : setBanned.clear();
478 11 : setBannedIsDirty = true;
479 : }
480 11 : DumpBanlist(); // store banlist to Disk
481 11 : if(clientInterface)
482 3 : clientInterface->BannedListChanged();
483 11 : }
484 :
485 932 : bool CConnman::IsBanned(CNetAddr ip)
486 : {
487 1864 : LOCK(cs_setBanned);
488 938 : for (const auto& it : setBanned) {
489 21 : CSubNet subNet = it.first;
490 15 : CBanEntry banEntry = it.second;
491 :
492 15 : if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) {
493 9 : return true;
494 : }
495 : }
496 923 : return false;
497 : }
498 :
499 9 : bool CConnman::IsBanned(CSubNet subnet)
500 : {
501 18 : LOCK(cs_setBanned);
502 9 : banmap_t::iterator i = setBanned.find(subnet);
503 9 : if (i != setBanned.end()) {
504 0 : CBanEntry banEntry = (*i).second;
505 0 : if (GetTime() < banEntry.nBanUntil) {
506 0 : return true;
507 : }
508 : }
509 : return false;
510 : }
511 :
512 8 : void CConnman::Ban(const CNetAddr& addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch)
513 : {
514 8 : CSubNet subNet(addr);
515 8 : Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
516 8 : }
517 :
518 17 : void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch)
519 : {
520 17 : CBanEntry banEntry(GetTime());
521 17 : banEntry.banReason = banReason;
522 17 : if (bantimeoffset <= 0)
523 : {
524 13 : bantimeoffset = gArgs.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); // Default 24-hour ban
525 13 : sinceUnixEpoch = false;
526 : }
527 17 : banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset;
528 :
529 17 : {
530 17 : LOCK(cs_setBanned);
531 17 : if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) {
532 17 : setBanned[subNet] = banEntry;
533 17 : setBannedIsDirty = true;
534 : }
535 : else
536 0 : return;
537 : }
538 17 : if(clientInterface)
539 6 : clientInterface->BannedListChanged();
540 17 : {
541 17 : LOCK(cs_vNodes);
542 19 : for (CNode* pnode : vNodes) {
543 2 : if (subNet.Match(static_cast<CNetAddr>(pnode->addr)))
544 2 : pnode->fDisconnect = true;
545 : }
546 : }
547 17 : if(banReason == BanReasonManuallyAdded)
548 13 : DumpBanlist(); //store banlist to disk immediately if user requested ban
549 : }
550 :
551 2 : bool CConnman::Unban(const CNetAddr &addr)
552 : {
553 2 : CSubNet subNet(addr);
554 2 : return Unban(subNet);
555 : }
556 :
557 4 : bool CConnman::Unban(const CSubNet &subNet)
558 : {
559 4 : {
560 4 : LOCK(cs_setBanned);
561 4 : if (!setBanned.erase(subNet))
562 2 : return false;
563 3 : setBannedIsDirty = true;
564 : }
565 3 : if(clientInterface)
566 1 : clientInterface->BannedListChanged();
567 3 : DumpBanlist(); //store banlist to disk immediately
568 3 : return true;
569 : }
570 :
571 316 : void CConnman::GetBanned(banmap_t &banMap)
572 : {
573 316 : LOCK(cs_setBanned);
574 : // Sweep the banlist so expired bans are not returned
575 316 : SweepBanned();
576 316 : banMap = setBanned; //create a thread safe copy
577 316 : }
578 :
579 86 : void CConnman::SetBanned(const banmap_t &banMap)
580 : {
581 86 : LOCK(cs_setBanned);
582 86 : setBanned = banMap;
583 86 : setBannedIsDirty = true;
584 86 : }
585 :
586 1054 : void CConnman::SweepBanned()
587 : {
588 1054 : int64_t now = GetTime();
589 :
590 1054 : bool notifyUI = false;
591 1054 : {
592 1054 : LOCK(cs_setBanned);
593 1054 : banmap_t::iterator it = setBanned.begin();
594 1122 : while(it != setBanned.end())
595 : {
596 136 : CSubNet subNet = (*it).first;
597 68 : CBanEntry banEntry = (*it).second;
598 68 : if(now > banEntry.nBanUntil)
599 : {
600 1 : setBanned.erase(it++);
601 1 : setBannedIsDirty = true;
602 1 : notifyUI = true;
603 2 : LogPrint(BCLog::NET, "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString());
604 : }
605 : else
606 68 : ++it;
607 : }
608 : }
609 : // update UI
610 1054 : if(notifyUI) {
611 1 : uiInterface.BannedListChanged();
612 : }
613 1054 : }
614 :
615 652 : bool CConnman::BannedSetIsDirty()
616 : {
617 652 : LOCK(cs_setBanned);
618 652 : return setBannedIsDirty;
619 : }
620 :
621 652 : void CConnman::SetBannedSetDirty(bool dirty)
622 : {
623 652 : LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag
624 652 : setBannedIsDirty = dirty;
625 652 : }
626 :
627 :
628 1434 : bool CConnman::IsWhitelistedRange(const CNetAddr& addr)
629 : {
630 1434 : for (const CSubNet& subnet : vWhitelistedRange) {
631 184 : if (subnet.Match(addr))
632 184 : return true;
633 : }
634 1250 : return false;
635 : }
636 :
637 102595 : std::string CNode::GetAddrName() const {
638 102595 : LOCK(cs_addrName);
639 307785 : return addrName;
640 : }
641 :
642 0 : void CNode::MaybeSetAddrName(const std::string& addrNameIn) {
643 0 : LOCK(cs_addrName);
644 0 : if (addrName.empty()) {
645 0 : addrName = addrNameIn;
646 : }
647 0 : }
648 :
649 58217 : CService CNode::GetAddrLocal() const {
650 58217 : LOCK(cs_addrLocal);
651 58217 : return addrLocal;
652 : }
653 :
654 1359 : void CNode::SetAddrLocal(const CService& addrLocalIn) {
655 1359 : LOCK(cs_addrLocal);
656 1359 : if (addrLocal.IsValid()) {
657 0 : error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
658 : } else {
659 2718 : addrLocal = addrLocalIn;
660 : }
661 1359 : }
662 :
663 : #undef X
664 : #define X(name) stats.name = name
665 56794 : void CNode::copyStats(CNodeStats& stats, const std::vector<bool>& m_asmap)
666 : {
667 56794 : stats.nodeid = this->GetId();
668 56794 : X(nServices);
669 56794 : stats.m_mapped_as = addr.GetMappedAS(m_asmap);
670 56794 : X(nLastSend);
671 56794 : X(nLastRecv);
672 56794 : X(nTimeConnected);
673 56794 : X(nTimeOffset);
674 56794 : stats.addrName = GetAddrName();
675 56794 : X(nVersion);
676 56794 : {
677 56794 : LOCK(cs_SubVer);
678 56794 : X(cleanSubVer);
679 : }
680 56794 : X(fInbound);
681 56794 : X(fAddnode);
682 56794 : X(nStartingHeight);
683 56794 : {
684 56794 : LOCK(cs_vSend);
685 56794 : X(mapSendBytesPerMsgCmd);
686 56794 : X(nSendBytes);
687 : }
688 56794 : {
689 56794 : LOCK(cs_vRecv);
690 56794 : X(mapRecvBytesPerMsgCmd);
691 56794 : X(nRecvBytes);
692 : }
693 56794 : X(fWhitelisted);
694 56794 : X(m_masternode_connection);
695 56794 : X(m_masternode_iqr_connection);
696 56794 : X(m_masternode_probe_connection);
697 56794 : {
698 56794 : LOCK(cs_mnauth);
699 56794 : X(verifiedProRegTxHash);
700 56794 : X(verifiedPubKeyHash);
701 : }
702 :
703 : // It is common for nodes with good ping times to suddenly become lagged,
704 : // due to a new block arriving or other large transfer.
705 : // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
706 : // since pingtime does not update until the ping is complete, which might take a while.
707 : // So, if a ping is taking an unusually long time in flight,
708 : // the caller can immediately detect that this is happening.
709 56794 : int64_t nPingUsecWait = 0;
710 56794 : if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
711 184 : nPingUsecWait = GetTimeMicros() - nPingUsecStart;
712 : }
713 :
714 : // Raw ping time is in microseconds, but show it to user as whole seconds (PIVX users should be well used to small numbers with many decimal places by now :)
715 56794 : stats.dPingTime = (((double)nPingUsecTime) / 1e6);
716 56794 : stats.dPingWait = (((double)nPingUsecWait) / 1e6);
717 :
718 : // Leave string empty if addrLocal invalid (not filled in yet)
719 56794 : CService addrLocalUnlocked = GetAddrLocal();
720 56794 : stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
721 56794 : }
722 : #undef X
723 :
724 328275 : bool CNode::ReceiveMsgBytes(const char* pch, unsigned int nBytes, bool& complete)
725 : {
726 328275 : complete = false;
727 328275 : int64_t nTimeMicros = GetTimeMicros();
728 656550 : LOCK(cs_vRecv);
729 328275 : nLastRecv = nTimeMicros / 1000000;
730 328275 : nRecvBytes += nBytes;
731 1071780 : while (nBytes > 0) {
732 : // get current incomplete message, or create a new one
733 743502 : if (vRecvMsg.empty() ||
734 434759 : vRecvMsg.back().complete())
735 745412 : vRecvMsg.emplace_back(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION);
736 :
737 743502 : CNetMessage& msg = vRecvMsg.back();
738 :
739 : // absorb network data
740 743502 : int handled;
741 743502 : if (!msg.in_data)
742 372706 : handled = msg.readHeader(pch, nBytes);
743 : else
744 370796 : handled = msg.readData(pch, nBytes);
745 :
746 743502 : if (handled < 0)
747 : return false;
748 :
749 743502 : if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
750 1 : LogPrint(BCLog::NET, "Oversized message from peer=%i, disconnecting\n", GetId());
751 1 : return false;
752 : }
753 :
754 743501 : pch += handled;
755 743501 : nBytes -= handled;
756 :
757 1815280 : if (msg.complete()) {
758 :
759 : // Store received bytes per message command
760 : // to prevent a memory DOS, only allow valid commands
761 745410 : mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
762 372705 : if (i == mapRecvBytesPerMsgCmd.end())
763 188 : i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
764 372705 : assert(i != mapRecvBytesPerMsgCmd.end());
765 372705 : i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
766 :
767 372705 : msg.nTime = nTimeMicros;
768 372705 : complete = true;
769 : }
770 : }
771 :
772 : return true;
773 : }
774 :
775 1362 : void CNode::SetSendVersion(int nVersionIn)
776 : {
777 : // Send version may only be changed in the version message, and
778 : // only one version message is allowed per session. We can therefore
779 : // treat this value as const and even atomic as long as it's only used
780 : // once a version message has been successfully processed. Any attempt to
781 : // set this twice is an error.
782 1362 : if (nSendVersion != 0) {
783 0 : error("Send version already set for node: %i. Refusing to change from %i to %i", id, nSendVersion, nVersionIn);
784 : } else {
785 1362 : nSendVersion = nVersionIn;
786 : }
787 1362 : }
788 :
789 2730357 : int CNode::GetSendVersion() const
790 : {
791 : // The send version should always be explicitly set to
792 : // INIT_PROTO_VERSION rather than using this value until SetSendVersion
793 : // has been called.
794 2730357 : if (nSendVersion == 0) {
795 0 : error("Requesting unset send version for node: %i. Using %i", id, INIT_PROTO_VERSION);
796 0 : return INIT_PROTO_VERSION;
797 : }
798 : return nSendVersion;
799 : }
800 :
801 372706 : int CNetMessage::readHeader(const char* pch, unsigned int nBytes)
802 : {
803 : // copy data to temporary parsing buffer
804 372706 : unsigned int nRemaining = 24 - nHdrPos;
805 372706 : unsigned int nCopy = std::min(nRemaining, nBytes);
806 :
807 372706 : memcpy(&hdrbuf[nHdrPos], pch, nCopy);
808 372706 : nHdrPos += nCopy;
809 :
810 : // if header incomplete, exit
811 372706 : if (nHdrPos < 24)
812 0 : return nCopy;
813 :
814 : // deserialize to CMessageHeader
815 372706 : try {
816 372706 : hdrbuf >> hdr;
817 0 : } catch (const std::exception&) {
818 0 : return -1;
819 : }
820 :
821 : // reject messages larger than MAX_SIZE
822 372706 : if (hdr.nMessageSize > MAX_SIZE)
823 : return -1;
824 :
825 : // switch state to reading message data
826 372706 : in_data = true;
827 :
828 372706 : return nCopy;
829 : }
830 :
831 370796 : int CNetMessage::readData(const char* pch, unsigned int nBytes)
832 : {
833 370796 : unsigned int nRemaining = hdr.nMessageSize - nDataPos;
834 370796 : unsigned int nCopy = std::min(nRemaining, nBytes);
835 :
836 370796 : if (vRecv.size() < nDataPos + nCopy) {
837 : // Allocate up to 256 KiB ahead, but never more than the total message size.
838 369052 : vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
839 : }
840 :
841 370796 : hasher.Write((const unsigned char*)pch, nCopy);
842 370796 : memcpy(&vRecv[nDataPos], pch, nCopy);
843 370796 : nDataPos += nCopy;
844 :
845 370796 : return nCopy;
846 : }
847 :
848 372488 : const uint256& CNetMessage::GetMessageHash() const
849 : {
850 372488 : assert(complete());
851 12292100 : if (data_hash.IsNull())
852 372488 : hasher.Finalize(data_hash.begin());
853 372488 : return data_hash;
854 : }
855 :
856 : // requires LOCK(cs_vSend)
857 280343 : size_t CConnman::SocketSendData(CNode* pnode)
858 : {
859 280343 : auto it = pnode->vSendMsg.begin();
860 280343 : size_t nSentSize = 0;
861 :
862 921310 : while (it != pnode->vSendMsg.end()) {
863 640990 : const auto& data = *it;
864 640990 : assert(data.size() > pnode->nSendOffset);
865 640990 : int nBytes = 0;
866 640990 : {
867 640990 : LOCK(pnode->cs_hSocket);
868 640990 : if (pnode->hSocket == INVALID_SOCKET)
869 : break;
870 640990 : nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
871 : }
872 640990 : if (nBytes > 0) {
873 640967 : pnode->nLastSend = GetSystemTimeInSeconds();
874 640967 : pnode->nSendBytes += nBytes;
875 640967 : pnode->nSendOffset += nBytes;
876 640967 : nSentSize += nBytes;
877 640967 : if (pnode->nSendOffset == data.size()) {
878 640967 : pnode->nSendOffset = 0;
879 640967 : pnode->nSendSize -= data.size();
880 640967 : pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
881 641722 : it++;
882 : } else {
883 : // could not send full message; stop sending more
884 : break;
885 : }
886 : } else {
887 23 : if (nBytes < 0) {
888 : // error
889 23 : int nErr = WSAGetLastError();
890 23 : if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
891 23 : LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
892 23 : pnode->CloseSocketDisconnect();
893 : }
894 : }
895 : // couldn't send anything at all
896 : break;
897 : }
898 : }
899 :
900 280343 : if (it == pnode->vSendMsg.end()) {
901 280320 : assert(pnode->nSendOffset == 0);
902 280320 : assert(pnode->nSendSize == 0);
903 : }
904 280343 : pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
905 280343 : return nSentSize;
906 : }
907 :
908 3 : void CheckOffsetDisconnectedPeers(const CNetAddr& ip)
909 : {
910 3 : int nConnections = 0;
911 3 : if (g_connman) {
912 3 : g_connman->ForEachNode([&nConnections](CNode* pnode) {
913 20 : if (pnode->fSuccessfullyConnected)
914 20 : nConnections++;
915 20 : if (nConnections == ENOUGH_CONNECTIONS)
916 : return;
917 : });
918 : }
919 :
920 : // Not enough connections. Insert peer.
921 3 : static std::set<CNetAddr> setOffsetDisconnectedPeers;
922 3 : setOffsetDisconnectedPeers.insert(ip);
923 3 : if (setOffsetDisconnectedPeers.size() >= MAX_TIMEOFFSET_DISCONNECTIONS) {
924 : // clear the set
925 0 : setOffsetDisconnectedPeers.clear();
926 : // Trigger the warning
927 0 : std::string strWarn1 = _("Peers are being disconnected due time differences.");
928 0 : std::string strWarn2 = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong %s will not work properly."), PACKAGE_NAME);
929 :
930 0 : LogPrintf("*** Warning: %s %s\n", strWarn1, strWarn2);
931 :
932 0 : static int64_t nLastGUINotif = 0;
933 0 : int64_t now = GetTime();
934 0 : if (nLastGUINotif + 40 < now) { // Notify the GUI if needed.
935 0 : nLastGUINotif = now;
936 0 : uiInterface.ThreadSafeMessageBox(strprintf("%s\n\n%s", strWarn1, strWarn2), _("Warning"), CClientUIInterface::MSG_ERROR);
937 : }
938 : }
939 3 : }
940 :
941 0 : struct NodeEvictionCandidate
942 : {
943 : NodeId id;
944 : int64_t nTimeConnected;
945 : int64_t nMinPingUsecTime;
946 : CAddress addr;
947 : uint64_t nKeyedNetGroup;
948 : };
949 :
950 0 : static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
951 : {
952 0 : return a.nMinPingUsecTime > b.nMinPingUsecTime;
953 : }
954 :
955 0 : static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
956 : {
957 0 : return a.nTimeConnected > b.nTimeConnected;
958 : }
959 :
960 0 : static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
961 0 : return a.nKeyedNetGroup < b.nKeyedNetGroup;
962 : };
963 :
964 : /** Try to find a connection to evict when the node is full.
965 : * Extreme care must be taken to avoid opening the node to attacker
966 : * triggered network partitioning.
967 : * The strategy used here is to protect a small number of peers
968 : * for each of several distinct characteristics which are difficult
969 : * to forge. In order to partition a node the attacker must be
970 : * simultaneously better at all of them than honest peers.
971 : */
972 0 : bool CConnman::AttemptToEvictConnection(bool fPreferNewConnection)
973 : {
974 0 : std::vector<NodeEvictionCandidate> vEvictionCandidates;
975 0 : {
976 0 : LOCK(cs_vNodes);
977 :
978 0 : for (const CNode* node : vNodes) {
979 0 : if (node->fWhitelisted)
980 0 : continue;
981 0 : if (!node->fInbound)
982 0 : continue;
983 0 : if (node->fDisconnect)
984 0 : continue;
985 :
986 : // Protect verified MN-only connections
987 0 : if (fMasterNode) {
988 : // This handles eviction protected nodes. Nodes are always protected for a short time after the connection
989 : // was accepted. This short time is meant for the VERSION/VERACK exchange and the possible MNAUTH that might
990 : // follow when the incoming connection is from another masternode. When a message other than MNAUTH
991 : // is received after VERSION/VERACK, the protection is lifted immediately.
992 0 : bool isProtected = GetSystemTimeInSeconds() - node->nTimeConnected < INBOUND_EVICTION_PROTECTION_TIME;
993 0 : if (node->fFirstMessageReceived && !node->fFirstMessageIsMNAUTH) {
994 : isProtected = false;
995 : }
996 : // if MNAUTH was valid, the node is always protected (and at the same time not accounted when
997 : // checking incoming connection limits)
998 0 : if (!node->verifiedProRegTxHash.IsNull()) {
999 : isProtected = true;
1000 : }
1001 0 : if (isProtected) {
1002 0 : continue;
1003 : }
1004 : }
1005 :
1006 0 : NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->nKeyedNetGroup};
1007 0 : vEvictionCandidates.push_back(candidate);
1008 : }
1009 : }
1010 :
1011 0 : if (vEvictionCandidates.empty()) return false;
1012 :
1013 : // Protect connections with certain characteristics
1014 :
1015 : // Deterministically select 4 peers to protect by netgroup.
1016 : // An attacker cannot predict which netgroups will be protected
1017 0 : std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
1018 0 : vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1019 :
1020 0 : if (vEvictionCandidates.empty()) return false;
1021 :
1022 : // Protect the 8 nodes with the lowest minimum ping time.
1023 : // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
1024 0 : std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
1025 0 : vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1026 :
1027 0 : if (vEvictionCandidates.empty()) return false;
1028 :
1029 : // Protect the half of the remaining nodes which have been connected the longest.
1030 : // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
1031 0 : std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
1032 0 : vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
1033 :
1034 0 : if (vEvictionCandidates.empty()) return false;
1035 :
1036 : // Identify the network group with the most connections and youngest member.
1037 : // (vEvictionCandidates is already sorted by reverse connect time)
1038 0 : uint64_t naMostConnections;
1039 0 : unsigned int nMostConnections = 0;
1040 0 : int64_t nMostConnectionsTime = 0;
1041 0 : std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapAddrCounts;
1042 0 : for (const NodeEvictionCandidate& node : vEvictionCandidates) {
1043 0 : mapAddrCounts[node.nKeyedNetGroup].push_back(node);
1044 0 : int64_t grouptime = mapAddrCounts[node.nKeyedNetGroup][0].nTimeConnected;
1045 0 : size_t groupsize = mapAddrCounts[node.nKeyedNetGroup].size();
1046 0 : if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
1047 0 : nMostConnections = groupsize;
1048 0 : nMostConnectionsTime = grouptime;
1049 0 : naMostConnections = node.nKeyedNetGroup;
1050 : }
1051 : }
1052 :
1053 : // Reduce to the network group with the most connections
1054 0 : vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]);
1055 :
1056 : // Do not disconnect peers if there is only 1 connection from their network group
1057 0 : if (vEvictionCandidates.size() <= 1)
1058 : // unless we prefer the new connection (for whitelisted peers)
1059 0 : if (!fPreferNewConnection)
1060 : return false;
1061 :
1062 : // Disconnect from the network group with the most connections
1063 0 : NodeId evicted = vEvictionCandidates.front().id;
1064 0 : LOCK(cs_vNodes);
1065 0 : for (CNode* pnode : vNodes) {
1066 0 : if (pnode->GetId() == evicted) {
1067 0 : pnode->fDisconnect = true;
1068 0 : return true;
1069 : }
1070 : }
1071 0 : return false;
1072 : }
1073 :
1074 766 : void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
1075 766 : struct sockaddr_storage sockaddr;
1076 766 : socklen_t len = sizeof(sockaddr);
1077 766 : SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
1078 1526 : CAddress addr;
1079 766 : int nInbound = 0;
1080 766 : int nVerifiedInboundMasternodes = 0;
1081 :
1082 766 : if (hSocket != INVALID_SOCKET)
1083 766 : if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
1084 0 : LogPrintf("Warning: Unknown socket family\n");
1085 :
1086 766 : bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
1087 766 : {
1088 766 : LOCK(cs_vNodes);
1089 4631 : for (const CNode* pnode : vNodes) {
1090 3865 : if (pnode->fInbound) {
1091 1830 : nInbound++;
1092 3660 : if (!pnode->verifiedProRegTxHash.IsNull()) {
1093 56 : nVerifiedInboundMasternodes++;
1094 : }
1095 : }
1096 : }
1097 : }
1098 :
1099 766 : if (hSocket == INVALID_SOCKET) {
1100 0 : int nErr = WSAGetLastError();
1101 0 : if (nErr != WSAEWOULDBLOCK)
1102 0 : LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
1103 6 : return;
1104 : }
1105 :
1106 766 : if (!fNetworkActive) {
1107 6 : LogPrintf("connection from %s dropped: not accepting new connections\n", addr.ToString());
1108 6 : CloseSocket(hSocket);
1109 : return;
1110 : }
1111 :
1112 760 : if (!IsSelectableSocket(hSocket)) {
1113 : LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
1114 : CloseSocket(hSocket);
1115 : return;
1116 : }
1117 :
1118 : // According to the internet TCP_NODELAY is not carried into accepted sockets
1119 : // on all platforms. Set it again here just to be sure.
1120 760 : SetSocketNoDelay(hSocket);
1121 :
1122 1520 : if (IsBanned(addr) && !whitelisted)
1123 : {
1124 0 : LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
1125 0 : CloseSocket(hSocket);
1126 : return;
1127 : }
1128 :
1129 : // TODO: pending review.
1130 : // Evict connections until we are below nMaxInbound. In case eviction protection resulted in nodes to not be evicted
1131 : // before, they might get evicted in batches now (after the protection timeout).
1132 : // We don't evict verified MN connections and also don't take them into account when checking limits. We can do this
1133 : // because we know that such connections are naturally limited by the total number of MNs, so this is not usable
1134 : // for attacks.
1135 760 : while (nInbound - nVerifiedInboundMasternodes >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) {
1136 0 : if (!AttemptToEvictConnection(whitelisted)) {
1137 : // No connection to evict, disconnect the new connection
1138 0 : LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
1139 0 : CloseSocket(hSocket);
1140 : return;
1141 : }
1142 0 : nInbound--;
1143 : }
1144 :
1145 760 : NodeId id = GetNewNodeId();
1146 760 : uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
1147 :
1148 760 : CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, "", true);
1149 760 : pnode->AddRef();
1150 760 : pnode->fWhitelisted = whitelisted;
1151 760 : m_msgproc->InitializeNode(pnode);
1152 :
1153 1508 : LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1154 :
1155 760 : {
1156 760 : LOCK(cs_vNodes);
1157 760 : vNodes.push_back(pnode);
1158 : }
1159 :
1160 : // We received a new connection, harvest entropy from the time (and our peer count)
1161 760 : RandAddEvent((uint32_t)id);
1162 : }
1163 :
1164 1019690 : void CConnman::DisconnectNodes()
1165 : {
1166 1019690 : {
1167 1019690 : LOCK(cs_vNodes);
1168 :
1169 1019690 : if (!fNetworkActive) {
1170 : // Disconnect any connected nodes
1171 1065 : for (CNode* pnode : vNodes) {
1172 79 : if (!pnode->fDisconnect) {
1173 79 : LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
1174 79 : pnode->fDisconnect = true;
1175 : }
1176 : }
1177 : }
1178 :
1179 : // Disconnect unused nodes
1180 2039380 : std::vector<CNode*> vNodesCopy = vNodes;
1181 9034290 : for (CNode* pnode : vNodesCopy) {
1182 8014600 : if (pnode->fDisconnect) {
1183 : // remove from vNodes
1184 637 : vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1185 :
1186 : // release outbound grant (if any)
1187 637 : pnode->grantOutbound.Release();
1188 :
1189 : // close socket and cleanup
1190 637 : pnode->CloseSocketDisconnect();
1191 :
1192 : // hold in disconnected pool until all refs are released
1193 637 : pnode->Release();
1194 8014600 : vNodesDisconnected.push_back(pnode);
1195 : }
1196 : }
1197 : }
1198 1019690 : {
1199 : // Delete disconnected nodes
1200 1019690 : std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1201 1020720 : for (CNode* pnode : vNodesDisconnectedCopy) {
1202 : // wait until threads are done using it
1203 1025 : if (pnode->GetRefCount() <= 0) {
1204 637 : bool fDelete = false;
1205 637 : {
1206 637 : TRY_LOCK(pnode->cs_inventory, lockInv);
1207 637 : if (lockInv) {
1208 1274 : TRY_LOCK(pnode->cs_vSend, lockSend);
1209 637 : if (lockSend) {
1210 637 : fDelete = true;
1211 : }
1212 : }
1213 : }
1214 637 : if (fDelete) {
1215 637 : vNodesDisconnected.remove(pnode);
1216 637 : DeleteNode(pnode);
1217 : }
1218 : }
1219 : }
1220 : }
1221 1019690 : }
1222 :
1223 1019690 : void CConnman::NotifyNumConnectionsChanged()
1224 : {
1225 1019690 : size_t vNodesSize;
1226 1019690 : {
1227 1019690 : LOCK(cs_vNodes);
1228 1019690 : vNodesSize = vNodes.size();
1229 : }
1230 1019690 : if (vNodesSize != nPrevNodeCount) {
1231 1829 : nPrevNodeCount = vNodesSize;
1232 1829 : if (clientInterface)
1233 1829 : clientInterface->NotifyNumConnectionsChanged((int)vNodesSize);
1234 : }
1235 1019690 : }
1236 :
1237 8014580 : void CConnman::InactivityCheck(CNode* pnode)
1238 : {
1239 8014580 : int64_t nTime = GetSystemTimeInSeconds();
1240 8014580 : if (nTime - pnode->nTimeConnected > 60) {
1241 2347540 : if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) {
1242 2 : LogPrint(BCLog::NET, "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
1243 2 : pnode->fDisconnect = true;
1244 2347540 : } else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL) {
1245 0 : LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1246 0 : pnode->fDisconnect = true;
1247 2347540 : } else if (nTime - pnode->nLastRecv > TIMEOUT_INTERVAL) {
1248 0 : LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1249 0 : pnode->fDisconnect = true;
1250 2347540 : } else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros()) {
1251 0 : LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1252 0 : pnode->fDisconnect = true;
1253 2347540 : } else if (!pnode->fSuccessfullyConnected) {
1254 1 : LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId());
1255 1 : pnode->fDisconnect = true;
1256 : }
1257 : }
1258 8014580 : }
1259 :
1260 1019690 : bool CConnman::GenerateSelectSet(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set)
1261 : {
1262 2039330 : for (const ListenSocket& hListenSocket : vhListenSocket) {
1263 1019640 : recv_set.insert(hListenSocket.socket);
1264 : }
1265 :
1266 1019690 : {
1267 1019690 : LOCK(cs_vNodes);
1268 9033660 : for (CNode* pnode: vNodes) {
1269 : // Implement the following logic:
1270 : // * If there is data to send, select() for sending data. As this only
1271 : // happens when optimistic write failed, we choose to first drain the
1272 : // write buffer in this case before receiving more. This avoids
1273 : // needlessly queueing received data, if the remote peer is not themselves
1274 : // receiving data. This means properly utilizing TCP flow control signalling.
1275 : // * Otherwise, if there is space left in the receive buffer, select() for
1276 : // receiving data.
1277 : // * Hand off all complete messages to the processor, to be handled without
1278 : // blocking here.
1279 :
1280 8013960 : bool select_recv = !pnode->fPauseRecv;
1281 8013960 : bool select_send;
1282 8013960 : {
1283 8013960 : LOCK(pnode->cs_vSend);
1284 8013960 : select_send = !pnode->vSendMsg.empty();
1285 : }
1286 :
1287 15747600 : LOCK(pnode->cs_hSocket);
1288 8013960 : if (pnode->hSocket == INVALID_SOCKET)
1289 280371 : continue;
1290 :
1291 8013950 : error_set.insert(pnode->hSocket);
1292 8013950 : if (select_send) {
1293 280343 : send_set.insert(pnode->hSocket);
1294 280343 : continue;
1295 : }
1296 7733610 : if (select_recv) {
1297 15467200 : recv_set.insert(pnode->hSocket);
1298 : }
1299 : }
1300 : }
1301 :
1302 : #ifdef USE_WAKEUP_PIPE
1303 : // We add a pipe to the read set so that the select() call can be woken up from the outside
1304 : // This is done when data is added to send buffers (vSendMsg) or when new peers are added
1305 : // This is currently only implemented for POSIX compliant systems. This means that Windows will fall back to
1306 : // timing out after 50ms and then trying to send. This is ok as we assume that heavy-load daemons are usually
1307 : // run on Linux and friends.
1308 1019690 : recv_set.insert(wakeupPipe[0]);
1309 : #endif
1310 :
1311 1019690 : return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1312 : }
1313 :
1314 : #ifdef USE_POLL
1315 1019690 : void CConnman::SocketEvents(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set)
1316 : {
1317 2039020 : std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1318 1019690 : if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1319 0 : interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1320 355 : return;
1321 : }
1322 :
1323 2039020 : std::unordered_map<SOCKET, struct pollfd> pollfds;
1324 10792600 : for (SOCKET socket_id : recv_select_set) {
1325 9772940 : pollfds[socket_id].fd = socket_id;
1326 9772940 : pollfds[socket_id].events |= POLLIN;
1327 : }
1328 :
1329 1300030 : for (SOCKET socket_id : send_select_set) {
1330 280343 : pollfds[socket_id].fd = socket_id;
1331 280343 : pollfds[socket_id].events |= POLLOUT;
1332 : }
1333 :
1334 9033640 : for (SOCKET socket_id : error_select_set) {
1335 8013950 : pollfds[socket_id].fd = socket_id;
1336 : // These flags are ignored, but we set them for clarity
1337 8013950 : pollfds[socket_id].events |= POLLERR|POLLHUP;
1338 : }
1339 :
1340 2039020 : std::vector<struct pollfd> vpollfds;
1341 1019690 : vpollfds.reserve(pollfds.size());
1342 11073000 : for (auto it : pollfds) {
1343 10053300 : vpollfds.push_back(std::move(it.second));
1344 : }
1345 :
1346 1019690 : wakeupSelectNeeded = true;
1347 1019690 : int r = poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS);
1348 1019690 : wakeupSelectNeeded = false;
1349 1019690 : if (r < 0) {
1350 355 : return;
1351 : }
1352 :
1353 1019690 : if (interruptNet) return;
1354 :
1355 11071100 : for (struct pollfd pollfd_entry : vpollfds) {
1356 10051800 : if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1357 10051800 : if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1358 10051800 : if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1359 : }
1360 : }
1361 : #else
1362 : void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1363 : {
1364 : std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1365 : if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1366 : interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1367 : return;
1368 : }
1369 :
1370 : //
1371 : // Find which sockets have data to receive
1372 : //
1373 : struct timeval timeout;
1374 : timeout.tv_sec = 0;
1375 : timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
1376 :
1377 : fd_set fdsetRecv;
1378 : fd_set fdsetSend;
1379 : fd_set fdsetError;
1380 : FD_ZERO(&fdsetRecv);
1381 : FD_ZERO(&fdsetSend);
1382 : FD_ZERO(&fdsetError);
1383 : SOCKET hSocketMax = 0;
1384 :
1385 : for (SOCKET hSocket : recv_select_set) {
1386 : FD_SET(hSocket, &fdsetRecv);
1387 : hSocketMax = std::max(hSocketMax, hSocket);
1388 : }
1389 :
1390 : for (SOCKET hSocket : send_select_set) {
1391 : FD_SET(hSocket, &fdsetSend);
1392 : hSocketMax = std::max(hSocketMax, hSocket);
1393 : }
1394 :
1395 : for (SOCKET hSocket : error_select_set) {
1396 : FD_SET(hSocket, &fdsetError);
1397 : hSocketMax = std::max(hSocketMax, hSocket);
1398 : }
1399 :
1400 : wakeupSelectNeeded = true;
1401 : int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1402 : wakeupSelectNeeded = false;
1403 :
1404 : if (interruptNet)
1405 : return;
1406 :
1407 : if (nSelect == SOCKET_ERROR) {
1408 : int nErr = WSAGetLastError();
1409 : LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1410 : for (unsigned int i = 0; i <= hSocketMax; i++)
1411 : FD_SET(i, &fdsetRecv);
1412 : FD_ZERO(&fdsetSend);
1413 : FD_ZERO(&fdsetError);
1414 : if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1415 : return;
1416 : }
1417 :
1418 : for (SOCKET hSocket : recv_select_set) {
1419 : if (FD_ISSET(hSocket, &fdsetRecv)) {
1420 : recv_set.insert(hSocket);
1421 : }
1422 : }
1423 :
1424 : for (SOCKET hSocket : send_select_set) {
1425 : if (FD_ISSET(hSocket, &fdsetSend)) {
1426 : send_set.insert(hSocket);
1427 : }
1428 : }
1429 :
1430 : for (SOCKET hSocket : error_select_set) {
1431 : if (FD_ISSET(hSocket, &fdsetError)) {
1432 : error_set.insert(hSocket);
1433 : }
1434 : }
1435 : }
1436 : #endif
1437 :
1438 1019690 : void CConnman::SocketHandler()
1439 : {
1440 2039020 : std::set<SOCKET> recv_set, send_set, error_set;
1441 1019690 : SocketEvents(recv_set, send_set, error_set);
1442 :
1443 : #ifdef USE_WAKEUP_PIPE
1444 : // drain the wakeup pipe
1445 1840460 : if (recv_set.count(wakeupPipe[0])) {
1446 198918 : LogPrint(BCLog::NET, "woke up select()\n");
1447 397836 : char buf[128];
1448 397836 : while (true) {
1449 397836 : int r = read(wakeupPipe[0], buf, sizeof(buf));
1450 397836 : if (r <= 0) {
1451 : break;
1452 : }
1453 : }
1454 : }
1455 : #endif
1456 :
1457 1020040 : if (interruptNet) return;
1458 :
1459 : //
1460 : // Accept new connections
1461 : //
1462 2038630 : for (const ListenSocket& hListenSocket : vhListenSocket) {
1463 2037830 : if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0) {
1464 766 : AcceptConnection(hListenSocket);
1465 : }
1466 : }
1467 :
1468 : //
1469 : // Service each socket
1470 : //
1471 2038670 : std::vector<CNode*> vNodesCopy = CopyNodeVector();
1472 :
1473 9033930 : for (CNode* pnode : vNodesCopy) {
1474 8014590 : if (interruptNet)
1475 0 : return;
1476 :
1477 : //
1478 : // Receive
1479 : //
1480 8014590 : bool recvSet = false;
1481 8014590 : bool sendSet = false;
1482 8014590 : bool errorSet = false;
1483 8014590 : {
1484 8014590 : LOCK(pnode->cs_hSocket);
1485 8014590 : if (pnode->hSocket == INVALID_SOCKET)
1486 26 : continue;
1487 8014580 : recvSet = recv_set.count(pnode->hSocket) > 0;
1488 8014580 : sendSet = send_set.count(pnode->hSocket) > 0;
1489 16029200 : errorSet = error_set.count(pnode->hSocket) > 0;
1490 : }
1491 8014580 : if (recvSet || errorSet) {
1492 : // typical socket buffer is 8K-64K
1493 328603 : char pchBuf[0x10000];
1494 328603 : int nBytes = 0;
1495 328603 : {
1496 328603 : LOCK(pnode->cs_hSocket);
1497 328603 : if (pnode->hSocket == INVALID_SOCKET)
1498 0 : continue;
1499 328603 : nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1500 : }
1501 328603 : if (nBytes > 0) {
1502 328275 : bool notify = false;
1503 328275 : if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1504 1 : pnode->CloseSocketDisconnect();
1505 328275 : RecordBytesRecv(nBytes);
1506 328275 : if (notify) {
1507 313283 : size_t nSizeAdded = 0;
1508 313283 : auto it(pnode->vRecvMsg.begin());
1509 685988 : for (; it != pnode->vRecvMsg.end(); ++it) {
1510 377246 : if (!it->complete())
1511 : break;
1512 372705 : nSizeAdded += it->vRecv.size() + CMessageHeader::HEADER_SIZE;
1513 : }
1514 313283 : {
1515 313283 : LOCK(pnode->cs_vProcessMsg);
1516 313283 : pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1517 313283 : pnode->nProcessQueueSize += nSizeAdded;
1518 313283 : pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1519 : }
1520 313283 : WakeMessageHandler();
1521 : }
1522 328 : } else if (nBytes == 0) {
1523 : // socket closed gracefully
1524 326 : if (!pnode->fDisconnect)
1525 326 : LogPrint(BCLog::NET, "socket closed\n");
1526 326 : pnode->CloseSocketDisconnect();
1527 2 : } else if (nBytes < 0) {
1528 : // error
1529 2 : int nErr = WSAGetLastError();
1530 2 : if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
1531 2 : if (!pnode->fDisconnect)
1532 4 : LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1533 2 : pnode->CloseSocketDisconnect();
1534 : }
1535 : }
1536 : }
1537 :
1538 : //
1539 : // Send
1540 : //
1541 8014580 : if (sendSet) {
1542 560686 : LOCK(pnode->cs_vSend);
1543 280343 : size_t nBytes = SocketSendData(pnode);
1544 280343 : if (nBytes)
1545 280343 : RecordBytesSent(nBytes);
1546 : }
1547 :
1548 8014580 : InactivityCheck(pnode);
1549 : }
1550 1019340 : ReleaseNodeVector(vNodesCopy);
1551 : }
1552 :
1553 355 : void CConnman::ThreadSocketHandler()
1554 : {
1555 1020040 : while (!interruptNet) {
1556 1019690 : DisconnectNodes();
1557 1019690 : NotifyNumConnectionsChanged();
1558 1019690 : SocketHandler();
1559 : }
1560 355 : }
1561 :
1562 313283 : void CConnman::WakeMessageHandler()
1563 : {
1564 313283 : {
1565 313283 : std::lock_guard<std::mutex> lock(mutexMsgProc);
1566 313283 : fMsgProcWake = true;
1567 : }
1568 313283 : condMsgProc.notify_one();
1569 313283 : }
1570 :
1571 199060 : void CConnman::WakeSelect()
1572 : {
1573 : #ifdef USE_WAKEUP_PIPE
1574 199060 : if (wakeupPipe[1] == -1) {
1575 0 : return;
1576 : }
1577 :
1578 199060 : LogPrint(BCLog::NET, "waking up select()\n");
1579 :
1580 199060 : char buf[1];
1581 199060 : if (write(wakeupPipe[1], buf, 1) != 1) {
1582 0 : LogPrint(BCLog::NET, "write to wakeupPipe failed\n");
1583 : }
1584 : #endif
1585 :
1586 199060 : wakeupSelectNeeded = false;
1587 : }
1588 :
1589 0 : static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits)
1590 : {
1591 : //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK)
1592 0 : if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) {
1593 0 : *requiredServiceBits = NODE_NETWORK;
1594 0 : return data.host;
1595 : }
1596 :
1597 0 : return strprintf("x%x.%s", *requiredServiceBits, data.host);
1598 : }
1599 :
1600 :
1601 355 : void CConnman::ThreadDNSAddressSeed()
1602 : {
1603 : // goal: only query DNS seeds if address need is acute
1604 710 : if ((addrman.size() > 0) &&
1605 355 : (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
1606 0 : if (!interruptNet.sleep_for(std::chrono::seconds(11)))
1607 0 : return;
1608 :
1609 0 : LOCK(cs_vNodes);
1610 0 : int nRelevant = 0;
1611 0 : for (auto pnode : vNodes) {
1612 0 : nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->fAddnode && !pnode->fInbound && !pnode->m_masternode_probe_connection;
1613 : }
1614 0 : if (nRelevant >= 2) {
1615 0 : LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1616 0 : return;
1617 : }
1618 : }
1619 :
1620 355 : const std::vector<CDNSSeedData>& vSeeds = Params().DNSSeeds();
1621 355 : int found = 0;
1622 :
1623 355 : LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1624 :
1625 355 : for (const CDNSSeedData& seed : vSeeds) {
1626 0 : if (interruptNet) {
1627 0 : return;
1628 : }
1629 0 : if (HaveNameProxy()) {
1630 0 : AddOneShot(seed.host);
1631 : } else {
1632 0 : std::vector<CNetAddr> vIPs;
1633 0 : std::vector<CAddress> vAdd;
1634 0 : ServiceFlags requiredServiceBits = nRelevantServices;
1635 0 : std::string host = GetDNSHost(seed, &requiredServiceBits);
1636 0 : CNetAddr resolveSource;
1637 0 : if (!resolveSource.SetInternal(host)) {
1638 0 : continue;
1639 : }
1640 0 : if (LookupHost(host, vIPs, 0, true)) {
1641 0 : for (CNetAddr& ip : vIPs) {
1642 0 : int nOneDay = 24*3600;
1643 0 : CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1644 0 : addr.nTime = GetTime() - 3 * nOneDay - GetRand(4 * nOneDay); // use a random age between 3 and 7 days old
1645 0 : vAdd.push_back(addr);
1646 0 : found++;
1647 : }
1648 0 : addrman.Add(vAdd, resolveSource);
1649 : }
1650 : }
1651 : }
1652 :
1653 355 : LogPrintf("%d addresses found from DNS seeds\n", found);
1654 : }
1655 :
1656 :
1657 :
1658 :
1659 :
1660 :
1661 :
1662 :
1663 :
1664 :
1665 :
1666 :
1667 626 : void CConnman::DumpAddresses()
1668 : {
1669 626 : int64_t nStart = GetTimeMillis();
1670 :
1671 626 : CAddrDB adb;
1672 626 : adb.Write(addrman);
1673 :
1674 626 : LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1675 : addrman.size(), GetTimeMillis() - nStart);
1676 626 : }
1677 :
1678 356 : void CConnman::DumpData()
1679 : {
1680 356 : DumpAddresses();
1681 356 : DumpBanlist();
1682 356 : }
1683 :
1684 34061 : void CConnman::ProcessOneShot()
1685 : {
1686 34061 : std::string strDest;
1687 34061 : {
1688 34061 : LOCK(cs_vOneShots);
1689 34061 : if (vOneShots.empty())
1690 68122 : return;
1691 0 : strDest = vOneShots.front();
1692 0 : vOneShots.pop_front();
1693 : }
1694 0 : CAddress addr;
1695 0 : CSemaphoreGrant grant(*semOutbound, true);
1696 0 : if (grant) {
1697 0 : OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true);
1698 : }
1699 : }
1700 :
1701 355 : void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
1702 : {
1703 : // Connect to specific addresses
1704 355 : if (!connect.empty()) {
1705 0 : for (int64_t nLoop = 0;; nLoop++) {
1706 0 : ProcessOneShot();
1707 0 : for (const std::string& strAddr : connect) {
1708 0 : CAddress addr(CService(), NODE_NONE);
1709 0 : OpenNetworkConnection(addr, false, nullptr, strAddr.c_str());
1710 0 : for (int i = 0; i < 10 && i < nLoop; i++) {
1711 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1712 0 : return;
1713 : }
1714 : }
1715 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1716 : return;
1717 0 : }
1718 : }
1719 :
1720 : // Initiate network connections
1721 355 : int64_t nStart = GetTime();
1722 :
1723 : // Minimum time before next feeler connection (in microseconds).
1724 355 : int64_t nNextFeeler = PoissonNextSend(nStart * 1000 * 1000, FEELER_INTERVAL);
1725 34065 : while (!interruptNet) {
1726 34061 : ProcessOneShot();
1727 :
1728 34061 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1729 351 : return;
1730 :
1731 67420 : CSemaphoreGrant grant(*semOutbound);
1732 33710 : if (interruptNet)
1733 351 : return;
1734 :
1735 : // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1736 33710 : if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1737 21434 : static bool done = false;
1738 21434 : if (!done) {
1739 118 : LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1740 236 : CNetAddr local;
1741 118 : local.SetInternal("fixedseeds");
1742 118 : addrman.Add(ConvertSeeds(Params().FixedSeeds()), local);
1743 118 : done = true;
1744 : }
1745 : }
1746 :
1747 : //
1748 : // Choose an address to connect to based on most recently seen
1749 : //
1750 67420 : CAddress addrConnect;
1751 :
1752 : // Only connect out to one peer per network group (/16 for IPv4).
1753 : // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1754 33710 : int nOutbound = 0;
1755 67420 : std::set<std::vector<unsigned char> > setConnected;
1756 33710 : {
1757 33710 : LOCK(cs_vNodes);
1758 199177 : for (const CNode* pnode : vNodes) {
1759 165467 : if (!pnode->fInbound && !pnode->fAddnode && !pnode->m_masternode_connection) {
1760 : // Netgroups for inbound and addnode peers are not excluded because our goal here
1761 : // is to not use multiple of our limited outbound slots on a single netgroup
1762 : // but inbound and addnode peers do not use our outbound slots. Inbound peers
1763 : // also have the added issue that they're attacker controlled and could be used
1764 : // to prevent us from connecting to particular hosts if we used them here.
1765 155134 : setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
1766 77567 : nOutbound++;
1767 : }
1768 : }
1769 : }
1770 :
1771 : // Feeler Connections
1772 : //
1773 : // Design goals:
1774 : // * Increase the number of connectable addresses in the tried table.
1775 : //
1776 : // Method:
1777 : // * Choose a random address from new and attempt to connect to it if we can connect
1778 : // successfully it is added to tried.
1779 : // * Start attempting feeler connections only after node finishes making outbound
1780 : // connections.
1781 : // * Only make a feeler connection once every few minutes.
1782 : //
1783 33710 : bool fFeeler = false;
1784 33710 : if (nOutbound >= nMaxOutbound) {
1785 0 : int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
1786 0 : if (nTime > nNextFeeler) {
1787 0 : nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
1788 0 : fFeeler = true;
1789 : } else {
1790 0 : continue;
1791 : }
1792 : }
1793 :
1794 33710 : addrman.ResolveCollisions();
1795 :
1796 33710 : int64_t nANow = GetAdjustedTime();
1797 : int nTries = 0;
1798 34298 : while (!interruptNet) {
1799 34298 : CAddrInfo addr = addrman.SelectTriedCollision();
1800 :
1801 : // SelectTriedCollision returns an invalid address if it is empty.
1802 34298 : if (!fFeeler || !addr.IsValid()) {
1803 34298 : addr = addrman.Select(fFeeler);
1804 : }
1805 :
1806 : // Require outbound connections, other than feelers, to be to distinct network groups
1807 102894 : if (!fFeeler && setConnected.count(addr.GetGroup(addrman.m_asmap))) {
1808 : break;
1809 : }
1810 :
1811 : // if we selected an invalid or local address, restart
1812 8874 : if (!addr.IsValid() || IsLocal(addr)) {
1813 : break;
1814 : }
1815 :
1816 : // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1817 : // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1818 : // already-connected network ranges, ...) before trying new addrman addresses.
1819 600 : nTries++;
1820 600 : if (nTries > 100)
1821 : break;
1822 :
1823 600 : if (!IsReachable(addr))
1824 588 : continue;
1825 :
1826 : // only connect to full nodes
1827 600 : if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1828 0 : continue;
1829 :
1830 : // only consider very recently tried nodes after 30 failed attempts
1831 600 : if (nANow - addr.nLastTry < 600 && nTries < 30)
1832 261 : continue;
1833 :
1834 : // do not allow non-default ports, unless after 50 invalid addresses selected already
1835 339 : if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1836 327 : continue;
1837 :
1838 33722 : addrConnect = addr;
1839 : break;
1840 : }
1841 :
1842 33710 : if (addrConnect.IsValid()) {
1843 12 : if (fFeeler) {
1844 : // Add small amount of random noise before connection to avoid synchronization.
1845 0 : int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
1846 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
1847 0 : return;
1848 0 : LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
1849 : }
1850 :
1851 24 : OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler);
1852 : }
1853 : }
1854 : }
1855 :
1856 8705 : std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
1857 : {
1858 8705 : std::vector<AddedNodeInfo> ret;
1859 :
1860 8705 : std::list<std::string> lAddresses(0);
1861 8705 : {
1862 8705 : LOCK(cs_vAddedNodes);
1863 8705 : ret.reserve(vAddedNodes.size());
1864 8705 : std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
1865 : }
1866 :
1867 :
1868 : // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
1869 17410 : std::map<CService, bool> mapConnected;
1870 8705 : std::map<std::string, std::pair<bool, CService> > mapConnectedByName;
1871 8705 : {
1872 8705 : LOCK(cs_vNodes);
1873 50091 : for (const CNode* pnode : vNodes) {
1874 41386 : if (pnode->addr.IsValid()) {
1875 41386 : mapConnected[pnode->addr] = pnode->fInbound;
1876 : }
1877 82772 : std::string addrName = pnode->GetAddrName();
1878 41386 : if (!addrName.empty()) {
1879 41386 : mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1880 : }
1881 : }
1882 : }
1883 :
1884 8708 : for (const std::string& strAddNode : lAddresses) {
1885 6 : CService service(LookupNumeric(strAddNode, Params().GetDefaultPort()));
1886 6 : AddedNodeInfo addedNode{strAddNode, CService(), false, false};
1887 3 : if (service.IsValid()) {
1888 : // strAddNode is an IP:port
1889 3 : auto it = mapConnected.find(service);
1890 3 : if (it != mapConnected.end()) {
1891 0 : addedNode.resolvedAddress = service;
1892 0 : addedNode.fConnected = true;
1893 0 : addedNode.fInbound = it->second;
1894 : }
1895 : } else {
1896 : // strAddNode is a name
1897 0 : auto it = mapConnectedByName.find(strAddNode);
1898 0 : if (it != mapConnectedByName.end()) {
1899 0 : addedNode.resolvedAddress = it->second.second;
1900 0 : addedNode.fConnected = true;
1901 0 : addedNode.fInbound = it->second.first;
1902 : }
1903 : }
1904 3 : ret.emplace_back(std::move(addedNode));
1905 : }
1906 :
1907 17410 : return ret;
1908 : }
1909 :
1910 355 : void CConnman::ThreadOpenAddedConnections()
1911 : {
1912 8702 : while (true) {
1913 8702 : CSemaphoreGrant grant(*semAddnode);
1914 17049 : std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
1915 8702 : bool tried = false;
1916 8703 : for (const AddedNodeInfo& info : vInfo) {
1917 1 : if (!info.fConnected) {
1918 1 : if (!grant.TryAcquire()) {
1919 : // If we've used up our semaphore and need a new one, lets not wait here since while we are waiting
1920 : // the addednodeinfo state might change.
1921 : break;
1922 : }
1923 1 : tried = true;
1924 3 : CAddress addr(CService(), NODE_NONE);
1925 1 : OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
1926 1 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1927 0 : return;
1928 : }
1929 : }
1930 : // Retry every 60 seconds if a connection was attempted, otherwise two seconds
1931 17403 : if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
1932 : return;
1933 : }
1934 : }
1935 :
1936 : // if successful, this moves the passed grant to the constructed node
1937 725 : void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound, const char* pszDest, bool fOneShot, bool fFeeler, bool fAddnode, bool masternode_connection, bool masternode_probe_connection)
1938 : {
1939 : //
1940 : // Initiate outbound network connection
1941 : //
1942 725 : if (interruptNet || !fNetworkActive) {
1943 57 : return;
1944 : }
1945 725 : if (!pszDest) {
1946 24 : if (IsLocal(addrConnect) ||
1947 60 : FindNode(static_cast<CNetAddr>(addrConnect)) || IsBanned(addrConnect) ||
1948 36 : FindNode(addrConnect.ToStringIPPort()))
1949 : return;
1950 : } else {
1951 713 : CNode* pnode = FindNode(pszDest);
1952 713 : if (pnode) {
1953 : // If this is a mnauth connection and the node is already connected normally,
1954 : // disconnect it and open a new connection
1955 121 : if (masternode_connection && !pnode->m_masternode_connection) {
1956 79 : pnode->fDisconnect = true;
1957 : } else {
1958 42 : return;
1959 : }
1960 : }
1961 : }
1962 :
1963 683 : CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, fAddnode);
1964 :
1965 683 : if (!pnode)
1966 : return;
1967 668 : if (grantOutbound)
1968 0 : grantOutbound->MoveTo(pnode->grantOutbound);
1969 668 : if (fOneShot)
1970 0 : pnode->fOneShot = true;
1971 668 : if (fFeeler)
1972 0 : pnode->fFeeler = true;
1973 668 : if (fAddnode)
1974 0 : pnode->fAddnode = true;
1975 668 : if (masternode_connection)
1976 107 : pnode->m_masternode_connection = true;
1977 668 : if (masternode_probe_connection)
1978 47 : pnode->m_masternode_probe_connection = true;
1979 :
1980 668 : m_msgproc->InitializeNode(pnode);
1981 668 : {
1982 1336 : LOCK(cs_vNodes);
1983 668 : vNodes.push_back(pnode);
1984 : }
1985 : }
1986 :
1987 355 : void CConnman::ThreadMessageHandler()
1988 : {
1989 355 : int64_t nLastSendMessagesTimeMasternodes = 0;
1990 :
1991 364176 : while (!flagInterruptMsgProc) {
1992 727643 : std::vector<CNode*> vNodesCopy = CopyNodeVector();
1993 :
1994 363822 : bool fMoreWork = false;
1995 :
1996 : // Don't send other messages to quorum nodes too often
1997 363822 : bool fSkipSendMessagesForMasternodes = true;
1998 363822 : if (GetTimeMillis() - nLastSendMessagesTimeMasternodes >= 100) {
1999 164355 : fSkipSendMessagesForMasternodes = false;
2000 164355 : nLastSendMessagesTimeMasternodes = GetTimeMillis();
2001 : }
2002 :
2003 2255930 : for (CNode* pnode : vNodesCopy) {
2004 1892100 : if (pnode->fDisconnect)
2005 88 : continue;
2006 :
2007 : // Receive messages
2008 1892020 : bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
2009 1892020 : fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2010 1892020 : if (flagInterruptMsgProc)
2011 1 : return;
2012 :
2013 : // Send messages
2014 1892020 : if (!fSkipSendMessagesForMasternodes || !pnode->m_masternode_connection) {
2015 3652400 : LOCK(pnode->cs_sendProcessing);
2016 1826200 : m_msgproc->SendMessages(pnode, flagInterruptMsgProc);
2017 : }
2018 :
2019 1892020 : if (flagInterruptMsgProc)
2020 : return;
2021 : }
2022 :
2023 :
2024 363821 : ReleaseNodeVector(vNodesCopy);
2025 :
2026 727642 : std::unique_lock<std::mutex> lock(mutexMsgProc);
2027 363821 : if (!fMoreWork) {
2028 490711 : condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this] { return fMsgProcWake; });
2029 : }
2030 363821 : fMsgProcWake = false;
2031 : }
2032 : }
2033 :
2034 346 : bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, bool fWhitelisted)
2035 : {
2036 346 : strError = "";
2037 346 : int nOne = 1;
2038 :
2039 : // Create socket for listening for incoming connections
2040 346 : struct sockaddr_storage sockaddr;
2041 346 : socklen_t len = sizeof(sockaddr);
2042 346 : if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
2043 0 : strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
2044 0 : LogPrintf("%s\n", strError);
2045 0 : return false;
2046 : }
2047 :
2048 346 : SOCKET hListenSocket = CreateSocket(addrBind);
2049 346 : if (hListenSocket == INVALID_SOCKET) {
2050 0 : strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
2051 0 : LogPrintf("%s\n", strError);
2052 0 : return false;
2053 : }
2054 :
2055 : #ifndef WIN32
2056 : // Allow binding if the port is still in TIME_WAIT state after
2057 : // the program was closed and restarted. Not an issue on windows!
2058 346 : setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
2059 : #endif
2060 :
2061 : // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
2062 : // and enable it by default or not. Try to enable it, if possible.
2063 346 : if (addrBind.IsIPv6()) {
2064 : #ifdef IPV6_V6ONLY
2065 1 : setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
2066 : #endif
2067 : #ifdef WIN32
2068 : int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2069 : setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
2070 : #endif
2071 : }
2072 :
2073 346 : if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) {
2074 0 : int nErr = WSAGetLastError();
2075 0 : if (nErr == WSAEADDRINUSE)
2076 0 : strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
2077 : else
2078 0 : strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
2079 0 : LogPrintf("%s\n", strError);
2080 0 : CloseSocket(hListenSocket);
2081 0 : return false;
2082 : }
2083 346 : LogPrintf("Bound to %s\n", addrBind.ToString());
2084 :
2085 : // Listen for incoming connections
2086 346 : if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) {
2087 0 : strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
2088 0 : LogPrintf("%s\n", strError);
2089 0 : CloseSocket(hListenSocket);
2090 0 : return false;
2091 : }
2092 :
2093 346 : vhListenSocket.emplace_back(hListenSocket, fWhitelisted);
2094 :
2095 346 : if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
2096 0 : AddLocal(addrBind, LOCAL_BIND);
2097 :
2098 : return true;
2099 : }
2100 :
2101 355 : void Discover()
2102 : {
2103 355 : if (!fDiscover)
2104 355 : return;
2105 :
2106 : #ifdef WIN32
2107 : // Get local host IP
2108 : char pszHostName[256] = "";
2109 : if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) {
2110 : std::vector<CNetAddr> vaddr;
2111 : if (LookupHost(pszHostName, vaddr, 0, true)) {
2112 : for (const CNetAddr& addr : vaddr) {
2113 : if (AddLocal(addr, LOCAL_IF))
2114 : LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2115 : }
2116 : }
2117 : }
2118 : #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2119 : // Get local host ip
2120 0 : struct ifaddrs* myaddrs;
2121 0 : if (getifaddrs(&myaddrs) == 0) {
2122 0 : for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next) {
2123 0 : if (ifa->ifa_addr == nullptr) continue;
2124 0 : if ((ifa->ifa_flags & IFF_UP) == 0) continue;
2125 0 : if (strcmp(ifa->ifa_name, "lo") == 0) continue;
2126 0 : if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
2127 0 : if (ifa->ifa_addr->sa_family == AF_INET) {
2128 0 : struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
2129 0 : CNetAddr addr(s4->sin_addr);
2130 0 : if (AddLocal(addr, LOCAL_IF))
2131 0 : LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2132 0 : } else if (ifa->ifa_addr->sa_family == AF_INET6) {
2133 0 : struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
2134 0 : CNetAddr addr(s6->sin6_addr);
2135 0 : if (AddLocal(addr, LOCAL_IF))
2136 0 : LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2137 : }
2138 : }
2139 0 : freeifaddrs(myaddrs);
2140 : }
2141 : #endif
2142 : }
2143 :
2144 19 : void CConnman::SetNetworkActive(bool active)
2145 : {
2146 19 : LogPrint(BCLog::NET, "SetNetworkActive: %s\n", active);
2147 :
2148 19 : if (fNetworkActive == active) {
2149 : return;
2150 : }
2151 :
2152 19 : fNetworkActive = active;
2153 :
2154 19 : if (clientInterface) clientInterface->NotifyNetworkActiveChanged(fNetworkActive);
2155 : }
2156 :
2157 968 : CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In)
2158 : {
2159 484 : setBannedIsDirty = false;
2160 484 : fAddressesInitialized = false;
2161 484 : nLastNodeId = 0;
2162 484 : nPrevNodeCount = 0;
2163 484 : nSendBufferMaxSize = 0;
2164 484 : nReceiveFloodSize = 0;
2165 484 : flagInterruptMsgProc = false;
2166 :
2167 484 : Options connOptions;
2168 484 : Init(connOptions);
2169 : // init tier two connections manager
2170 484 : m_tiertwo_conn_man = std::make_unique<TierTwoConnMan>(this);
2171 484 : }
2172 :
2173 1428 : NodeId CConnman::GetNewNodeId()
2174 : {
2175 1428 : return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2176 : }
2177 :
2178 346 : bool CConnman::Bind(const CService& addr, unsigned int flags) {
2179 346 : if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
2180 : return false;
2181 692 : std::string strError;
2182 346 : if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
2183 0 : if ((flags & BF_REPORT_ERROR) && clientInterface) {
2184 0 : clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
2185 : }
2186 0 : return false;
2187 : }
2188 : return true;
2189 : }
2190 :
2191 345 : bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) {
2192 345 : bool fBound = false;
2193 689 : for (const auto& addrBind : binds) {
2194 344 : fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
2195 : }
2196 345 : for (const auto& addrBind : whiteBinds) {
2197 0 : fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
2198 : }
2199 345 : if (binds.empty() && whiteBinds.empty()) {
2200 1 : struct in_addr inaddr_any;
2201 1 : inaddr_any.s_addr = INADDR_ANY;
2202 1 : fBound |= Bind(CService((in6_addr)IN6ADDR_ANY_INIT, GetListenPort()), BF_NONE);
2203 1 : fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
2204 : }
2205 345 : return fBound;
2206 : }
2207 :
2208 355 : bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
2209 : {
2210 355 : Init(connOptions);
2211 :
2212 355 : {
2213 355 : LOCK(cs_totalBytesRecv);
2214 355 : nTotalBytesRecv = 0;
2215 : }
2216 355 : {
2217 355 : LOCK(cs_totalBytesSent);
2218 355 : nTotalBytesSent = 0;
2219 : }
2220 :
2221 355 : if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
2222 0 : if (clientInterface) {
2223 0 : clientInterface->ThreadSafeMessageBox(
2224 0 : _("Failed to listen on any port. Use -listen=0 if you want this."),
2225 : "", CClientUIInterface::MSG_ERROR);
2226 : }
2227 0 : return false;
2228 : }
2229 :
2230 355 : for (const auto& strDest : connOptions.vSeedNodes) {
2231 0 : AddOneShot(strDest);
2232 : }
2233 :
2234 355 : if (clientInterface)
2235 710 : clientInterface->InitMessage(_("Loading addresses..."));
2236 355 : m_msgproc = connOptions.m_msgproc;
2237 : // Load addresses from peers.dat
2238 355 : int64_t nStart = GetTimeMillis();
2239 355 : {
2240 355 : CAddrDB adb;
2241 355 : if (adb.Read(addrman))
2242 85 : LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
2243 : else {
2244 270 : addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2245 270 : LogPrintf("Invalid or missing peers.dat; recreating\n");
2246 270 : DumpAddresses();
2247 : }
2248 : }
2249 355 : if (clientInterface)
2250 710 : clientInterface->InitMessage(_("Loading banlist..."));
2251 : // Load addresses from banlist.dat
2252 355 : nStart = GetTimeMillis();
2253 710 : CBanDB bandb;
2254 710 : banmap_t banmap;
2255 355 : if (bandb.Read(banmap)) {
2256 86 : SetBanned(banmap); // thread save setter
2257 86 : SetBannedSetDirty(false); // no need to write down, just read data
2258 86 : SweepBanned(); // sweep out unused entries
2259 :
2260 86 : LogPrint(BCLog::NET, "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
2261 : banmap.size(), GetTimeMillis() - nStart);
2262 : } else {
2263 269 : LogPrintf("Invalid or missing banlist.dat; recreating\n");
2264 269 : SetBannedSetDirty(true); // force write
2265 269 : DumpBanlist();
2266 : }
2267 :
2268 : // Initialize random numbers. Even when rand() is only usable for trivial use-cases most nodes should have a different
2269 : // seed after all the file-IO done at this point. Should be good enough even when nodes are started via scripts.
2270 355 : srand(time(nullptr));
2271 :
2272 355 : fAddressesInitialized = true;
2273 :
2274 355 : if (semOutbound == nullptr) {
2275 : // initialize semaphore
2276 355 : semOutbound = std::make_unique<CSemaphore>(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
2277 : }
2278 355 : if (semAddnode == nullptr) {
2279 : // initialize semaphore
2280 355 : semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
2281 : }
2282 :
2283 : //
2284 : // Start threads
2285 : //
2286 355 : assert(m_msgproc);
2287 355 : InterruptSocks5(false);
2288 355 : interruptNet.reset();
2289 355 : flagInterruptMsgProc = false;
2290 :
2291 355 : {
2292 355 : std::unique_lock<std::mutex> lock(mutexMsgProc);
2293 355 : fMsgProcWake = false;
2294 : }
2295 :
2296 : #ifdef USE_WAKEUP_PIPE
2297 355 : if (pipe(wakeupPipe) != 0) {
2298 0 : wakeupPipe[0] = wakeupPipe[1] = -1;
2299 0 : LogPrint(BCLog::NET, "pipe() for wakeupPipe failed\n");
2300 : } else {
2301 355 : int fFlags = fcntl(wakeupPipe[0], F_GETFL, 0);
2302 355 : if (fcntl(wakeupPipe[0], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2303 0 : LogPrint(BCLog::NET, "fcntl for O_NONBLOCK on wakeupPipe failed\n");
2304 : }
2305 355 : fFlags = fcntl(wakeupPipe[1], F_GETFL, 0);
2306 355 : if (fcntl(wakeupPipe[1], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2307 0 : LogPrint(BCLog::NET, "fcntl for O_NONBLOCK on wakeupPipe failed\n");
2308 : }
2309 : }
2310 : #endif
2311 :
2312 : // Send and receive from sockets, accept connections
2313 355 : threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
2314 :
2315 355 : if (!gArgs.GetBoolArg("-dnsseed", true))
2316 0 : LogPrintf("DNS seeding disabled\n");
2317 : else
2318 355 : threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
2319 :
2320 : // Initiate outbound connections from -addnode
2321 355 : threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
2322 :
2323 : // Start tier two connection manager
2324 355 : if (m_tiertwo_conn_man) {
2325 355 : TierTwoConnMan::Options opts;
2326 355 : opts.m_has_specified_outgoing = !connOptions.m_specified_outgoing.empty();
2327 355 : m_tiertwo_conn_man->start(scheduler, opts);
2328 : }
2329 :
2330 355 : if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2331 0 : if (clientInterface) {
2332 0 : clientInterface->ThreadSafeMessageBox(
2333 0 : _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
2334 : "", CClientUIInterface::MSG_ERROR);
2335 : }
2336 0 : return false;
2337 : }
2338 355 : if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) {
2339 710 : threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(
2340 1065 : std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
2341 : }
2342 :
2343 : // Process messages
2344 355 : threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
2345 :
2346 : // Dump network addresses
2347 355 : scheduler.scheduleEvery(std::bind(&CConnman::DumpData, this), DUMP_ADDRESSES_INTERVAL * 1000);
2348 :
2349 355 : return true;
2350 : }
2351 :
2352 : class CNetCleanup
2353 : {
2354 : public:
2355 0 : CNetCleanup() {}
2356 :
2357 479 : ~CNetCleanup()
2358 : {
2359 : #ifdef WIN32
2360 : // Shutdown Windows Sockets
2361 : WSACleanup();
2362 : #endif
2363 479 : }
2364 : }
2365 : instance_of_cnetcleanup;
2366 :
2367 0 : void CExplicitNetCleanup::callCleanup()
2368 : {
2369 : // Explicit call to destructor of CNetCleanup because it's not implicitly called
2370 : // when the wallet is restarted from within the wallet itself.
2371 0 : CNetCleanup* tmp = new CNetCleanup();
2372 0 : delete tmp; // Stroustrup's gonna kill me for that
2373 0 : }
2374 :
2375 850 : void CConnman::Interrupt()
2376 : {
2377 850 : {
2378 850 : std::lock_guard<std::mutex> lock(mutexMsgProc);
2379 850 : flagInterruptMsgProc = true;
2380 : }
2381 850 : condMsgProc.notify_all();
2382 :
2383 850 : interruptNet();
2384 850 : if (m_tiertwo_conn_man) m_tiertwo_conn_man->interrupt();
2385 850 : InterruptSocks5(true);
2386 :
2387 850 : if (semOutbound) {
2388 6390 : for (int i=0; i<(nMaxOutbound + nMaxFeeler); i++) {
2389 6035 : semOutbound->post();
2390 : }
2391 : }
2392 :
2393 850 : if (semAddnode) {
2394 6035 : for (int i=0; i<nMaxAddnode; i++) {
2395 5680 : semAddnode->post();
2396 : }
2397 : }
2398 850 : }
2399 :
2400 850 : void CConnman::Stop()
2401 : {
2402 850 : if (threadMessageHandler.joinable())
2403 355 : threadMessageHandler.join();
2404 850 : if (threadOpenConnections.joinable())
2405 355 : threadOpenConnections.join();
2406 850 : if (threadOpenAddedConnections.joinable())
2407 355 : threadOpenAddedConnections.join();
2408 850 : if (threadDNSAddressSeed.joinable())
2409 355 : threadDNSAddressSeed.join();
2410 850 : if (threadSocketHandler.joinable())
2411 355 : threadSocketHandler.join();
2412 : // Stop tier two connection manager
2413 850 : if (m_tiertwo_conn_man) m_tiertwo_conn_man->stop();
2414 :
2415 850 : if (fAddressesInitialized)
2416 : {
2417 355 : DumpData();
2418 355 : fAddressesInitialized = false;
2419 : }
2420 :
2421 : // Close sockets
2422 1641 : for(CNode* pnode : vNodes)
2423 791 : pnode->CloseSocketDisconnect();
2424 1196 : for(ListenSocket& hListenSocket : vhListenSocket)
2425 346 : if (hListenSocket.socket != INVALID_SOCKET)
2426 346 : if (!CloseSocket(hListenSocket.socket))
2427 0 : LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2428 :
2429 : // clean up some globals (to help leak detection)
2430 1641 : for(CNode* pnode : vNodes) {
2431 791 : DeleteNode(pnode);
2432 : }
2433 850 : for(CNode* pnode : vNodesDisconnected) {
2434 0 : DeleteNode(pnode);
2435 : }
2436 850 : vNodes.clear();
2437 850 : vNodesDisconnected.clear();
2438 850 : vhListenSocket.clear();
2439 850 : semOutbound.reset();
2440 850 : semAddnode.reset();
2441 : #ifdef USE_WAKEUP_PIPE
2442 850 : if (wakeupPipe[0] != -1) close(wakeupPipe[0]);
2443 850 : if (wakeupPipe[1] != -1) close(wakeupPipe[1]);
2444 850 : wakeupPipe[0] = wakeupPipe[1] = -1;
2445 : #endif
2446 850 : }
2447 :
2448 1428 : void CConnman::DeleteNode(CNode* pnode)
2449 : {
2450 1428 : assert(pnode);
2451 1428 : bool fUpdateConnectionTime = false;
2452 1428 : m_msgproc->FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
2453 1428 : if (fUpdateConnectionTime) {
2454 642 : addrman.Connected(pnode->addr);
2455 : }
2456 1428 : delete pnode;
2457 1428 : }
2458 :
2459 1077 : CConnman::~CConnman()
2460 : {
2461 484 : Interrupt();
2462 484 : Stop();
2463 484 : }
2464 :
2465 647 : void CConnman::SetServices(const CService &addr, ServiceFlags nServices)
2466 : {
2467 647 : addrman.SetServices(addr, nServices);
2468 647 : }
2469 :
2470 647 : void CConnman::MarkAddressGood(const CAddress& addr)
2471 : {
2472 647 : addrman.Good(addr);
2473 647 : }
2474 :
2475 66 : void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty)
2476 : {
2477 66 : addrman.Add(addr, addrFrom, nTimePenalty);
2478 66 : }
2479 :
2480 10010 : bool CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
2481 : {
2482 10010 : return addrman.Add(vAddr, addrFrom, nTimePenalty);
2483 : }
2484 :
2485 651 : std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, Optional<Network> network)
2486 : {
2487 651 : return addrman.GetAddr(max_addresses, max_pct, network);
2488 : }
2489 :
2490 1 : bool CConnman::AddNode(const std::string& strNode)
2491 : {
2492 2 : LOCK(cs_vAddedNodes);
2493 1 : for (const std::string& it : vAddedNodes) {
2494 0 : if (strNode == it) return false;
2495 : }
2496 :
2497 1 : vAddedNodes.push_back(strNode);
2498 : return true;
2499 : }
2500 :
2501 0 : bool CConnman::RemoveAddedNode(const std::string& strNode)
2502 : {
2503 0 : LOCK(cs_vAddedNodes);
2504 0 : for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2505 0 : if (strNode == *it) {
2506 0 : vAddedNodes.erase(it);
2507 0 : return true;
2508 : }
2509 : }
2510 0 : return false;
2511 : }
2512 :
2513 206 : size_t CConnman::GetMaxOutboundNodeCount()
2514 : {
2515 206 : return nMaxOutbound;
2516 : }
2517 :
2518 1787 : size_t CConnman::GetNodeCount(NumConnections flags)
2519 : {
2520 1787 : LOCK(cs_vNodes);
2521 1787 : if (flags == CConnman::CONNECTIONS_ALL) // Shortcut if we want total
2522 1787 : return vNodes.size();
2523 :
2524 0 : int nNum = 0;
2525 0 : for (const auto& pnode : vNodes) {
2526 0 : if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
2527 0 : nNum++;
2528 : }
2529 : }
2530 :
2531 0 : return nNum;
2532 : }
2533 :
2534 15819 : void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
2535 : {
2536 15819 : vstats.clear();
2537 15819 : LOCK(cs_vNodes);
2538 15819 : vstats.reserve(vNodes.size());
2539 72613 : for (CNode* pnode : vNodes) {
2540 56794 : vstats.emplace_back();
2541 56794 : pnode->copyStats(vstats.back(), addrman.m_asmap);
2542 : }
2543 15819 : }
2544 :
2545 25 : bool CConnman::DisconnectNode(const std::string& strNode)
2546 : {
2547 50 : LOCK(cs_vNodes);
2548 25 : if (CNode* pnode = FindNode(strNode)) {
2549 24 : pnode->fDisconnect = true;
2550 24 : return true;
2551 : }
2552 : return false;
2553 : }
2554 :
2555 0 : bool CConnman::DisconnectNode(NodeId id)
2556 : {
2557 0 : LOCK(cs_vNodes);
2558 0 : for(CNode* pnode : vNodes) {
2559 0 : if (id == pnode->GetId()) {
2560 0 : pnode->fDisconnect = true;
2561 0 : return true;
2562 : }
2563 : }
2564 0 : return false;
2565 : }
2566 :
2567 15230 : void CConnman::RelayInv(CInv& inv, int minProtoVersion)
2568 : {
2569 15230 : LOCK(cs_vNodes);
2570 58897 : for (CNode* pnode : vNodes){
2571 43667 : if (!pnode->fSuccessfullyConnected) continue;
2572 43662 : if ((pnode->nServices == NODE_BLOOM_WITHOUT_MN) && inv.IsMasterNodeType()) continue;
2573 43662 : if (!pnode->CanRelay()) continue;
2574 43606 : if (pnode->nVersion >= minProtoVersion)
2575 43606 : pnode->PushInventory(inv);
2576 : }
2577 15230 : }
2578 :
2579 56610 : void CConnman::RemoveAskFor(const uint256& invHash, int invType)
2580 : {
2581 56610 : mapAlreadyAskedFor.erase(CInv(invType, invHash));
2582 :
2583 56610 : LOCK(cs_vNodes);
2584 151728 : for (const auto& pnode : vNodes) {
2585 95118 : pnode->AskForInvReceived(invHash);
2586 : }
2587 56610 : }
2588 :
2589 105 : void CConnman::UpdateQuorumRelayMemberIfNeeded(CNode* pnode)
2590 : {
2591 116 : if (!pnode->m_masternode_iqr_connection && pnode->m_masternode_connection &&
2592 127 : m_tiertwo_conn_man->isMasternodeQuorumRelayMember(WITH_LOCK(pnode->cs_mnauth, return pnode->verifiedProRegTxHash))) {
2593 0 : pnode->m_masternode_iqr_connection = true;
2594 : }
2595 105 : }
2596 :
2597 328275 : void CConnman::RecordBytesRecv(uint64_t bytes)
2598 : {
2599 328275 : LOCK(cs_totalBytesRecv);
2600 328275 : nTotalBytesRecv += bytes;
2601 328275 : }
2602 :
2603 280343 : void CConnman::RecordBytesSent(uint64_t bytes)
2604 : {
2605 280343 : LOCK(cs_totalBytesSent);
2606 280343 : nTotalBytesSent += bytes;
2607 280343 : }
2608 :
2609 5 : uint64_t CConnman::GetTotalBytesRecv()
2610 : {
2611 5 : LOCK(cs_totalBytesRecv);
2612 5 : return nTotalBytesRecv;
2613 : }
2614 :
2615 5 : uint64_t CConnman::GetTotalBytesSent()
2616 : {
2617 5 : LOCK(cs_totalBytesSent);
2618 5 : return nTotalBytesSent;
2619 : }
2620 :
2621 1230 : ServiceFlags CConnman::GetLocalServices() const
2622 : {
2623 1230 : return nLocalServices;
2624 : }
2625 :
2626 38497 : void CConnman::SetBestHeight(int height)
2627 : {
2628 38497 : nBestHeight.store(height, std::memory_order_release);
2629 38497 : }
2630 :
2631 1428 : int CConnman::GetBestHeight() const
2632 : {
2633 1428 : return nBestHeight.load(std::memory_order_acquire);
2634 : }
2635 :
2636 372490 : unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
2637 0 : unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
2638 :
2639 1436 : CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string& addrNameIn, bool fInboundIn) :
2640 1436 : nTimeConnected(GetSystemTimeInSeconds()),
2641 : addr(addrIn),
2642 : fInbound(fInboundIn),
2643 : nKeyedNetGroup(nKeyedNetGroupIn),
2644 : addrKnown(5000, 0.001),
2645 : filterInventoryKnown(50000, 0.000001),
2646 : id(idIn),
2647 : nLocalHostNonce(nLocalHostNonceIn),
2648 : nLocalServices(nLocalServicesIn),
2649 : nMyStartingHeight(nMyStartingHeightIn),
2650 10052 : nSendVersion(0)
2651 : {
2652 1436 : nServices = NODE_NONE;
2653 1436 : nServicesExpected = NODE_NONE;
2654 1436 : hSocket = hSocketIn;
2655 1436 : nRecvVersion = INIT_PROTO_VERSION;
2656 1436 : nLastSend = 0;
2657 1436 : nLastRecv = 0;
2658 1436 : nSendBytes = 0;
2659 1436 : nRecvBytes = 0;
2660 1436 : nTimeOffset = 0;
2661 2104 : addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2662 1436 : nVersion = 0;
2663 1436 : strSubVer = "";
2664 1436 : fWhitelisted = false;
2665 1436 : fOneShot = false;
2666 1436 : fAddnode = false;
2667 1436 : m_masternode_connection = false;
2668 1436 : fClient = false; // set by version message
2669 1436 : fFeeler = false;
2670 1436 : fSuccessfullyConnected = false;
2671 1436 : fDisconnect = false;
2672 1436 : nRefCount = 0;
2673 1436 : nSendSize = 0;
2674 1436 : nSendOffset = 0;
2675 1436 : hashContinue = UINT256_ZERO;
2676 1436 : nStartingHeight = -1;
2677 1436 : filterInventoryKnown.reset();
2678 1436 : fSendMempool = false;
2679 1436 : fGetAddr = false;
2680 1436 : fRelayTxes = false;
2681 1436 : pfilter = std::make_unique<CBloomFilter>();
2682 1436 : timeLastMempoolReq = 0;
2683 1436 : nPingNonceSent = 0;
2684 1436 : nPingUsecStart = 0;
2685 1436 : nPingUsecTime = 0;
2686 1436 : fPingQueued = false;
2687 1436 : nMinPingUsecTime = std::numeric_limits<int64_t>::max();
2688 1436 : fPauseRecv = false;
2689 1436 : fPauseSend = false;
2690 1436 : nProcessQueueSize = 0;
2691 :
2692 83288 : for (const std::string &msg : getAllNetMessageTypes())
2693 81852 : mapRecvBytesPerMsgCmd[msg] = 0;
2694 1436 : mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
2695 :
2696 1436 : if (fLogIPs)
2697 0 : LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
2698 : else
2699 1436 : LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
2700 1436 : }
2701 :
2702 10438 : CNode::~CNode()
2703 : {
2704 1436 : CloseSocket(hSocket);
2705 1436 : }
2706 :
2707 70145 : void CNode::AskFor(const CInv& inv, int64_t doubleRequestDelay)
2708 : {
2709 70145 : if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
2710 12 : return;
2711 : // a peer may not have multiple non-responded queue positions for a single inv item
2712 70145 : if (!setAskFor.insert(inv.hash).second)
2713 : return;
2714 :
2715 : // We're using mapAskFor as a priority queue,
2716 : // the key is the earliest time the request can be sent
2717 70133 : int64_t nRequestTime;
2718 70133 : limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
2719 70133 : if (it != mapAlreadyAskedFor.end())
2720 4563 : nRequestTime = it->second;
2721 : else
2722 65570 : nRequestTime = 0;
2723 140266 : LogPrint(BCLog::NET, "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, FormatISO8601Time(nRequestTime / 1000000), id);
2724 :
2725 : // Make sure not to reuse time indexes to keep things in the same order
2726 70133 : int64_t nNow = GetTimeMicros() - 1000000;
2727 70133 : static int64_t nLastTime;
2728 70133 : ++nLastTime;
2729 70133 : nNow = std::max(nNow, nLastTime);
2730 70133 : nLastTime = nNow;
2731 :
2732 : // Each retry is 2 minutes after the last
2733 70133 : nRequestTime = std::max(nRequestTime + doubleRequestDelay, nNow);
2734 70133 : if (it != mapAlreadyAskedFor.end())
2735 4563 : mapAlreadyAskedFor.update(it, nRequestTime);
2736 : else
2737 65570 : mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2738 70133 : mapAskFor.insert(std::make_pair(nRequestTime, inv));
2739 : }
2740 :
2741 95118 : void CNode::AskForInvReceived(const uint256& invHash)
2742 : {
2743 95118 : setAskFor.erase(invHash);
2744 95118 : for (auto it = mapAskFor.begin(); it != mapAskFor.end();) {
2745 28929 : if (it->second.hash == invHash) {
2746 4226 : it = mapAskFor.erase(it);
2747 : } else {
2748 148750 : ++it;
2749 : }
2750 : }
2751 95118 : }
2752 :
2753 905512 : bool CConnman::NodeFullyConnected(const CNode* pnode)
2754 : {
2755 905512 : return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
2756 : }
2757 :
2758 322954 : void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg, bool allowOptimisticSend)
2759 : {
2760 322954 : size_t nMessageSize = msg.data.size();
2761 322954 : size_t nTotalSize = nMessageSize + CMessageHeader::HEADER_SIZE;
2762 640337 : LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", SanitizeString(msg.command.c_str()), nMessageSize, pnode->GetId());
2763 :
2764 322954 : std::vector<unsigned char> serializedHeader;
2765 322954 : serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
2766 322954 : uint256 hash = Hash(msg.data.data(), msg.data.data() + nMessageSize);
2767 322954 : CMessageHeader hdr(Params().MessageStart(), msg.command.c_str(), nMessageSize);
2768 322954 : memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
2769 :
2770 322954 : CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, serializedHeader, 0, hdr};
2771 :
2772 322954 : size_t nBytesSent = 0;
2773 322954 : {
2774 322954 : LOCK(pnode->cs_vSend);
2775 322954 : bool hasPendingData = !pnode->vSendMsg.empty();
2776 322954 : bool optimisticSend(allowOptimisticSend && pnode->vSendMsg.empty());
2777 :
2778 : //log total amount of bytes per command
2779 322954 : pnode->mapSendBytesPerMsgCmd[msg.command] += nTotalSize;
2780 322954 : pnode->nSendSize += nTotalSize;
2781 :
2782 322954 : if (pnode->nSendSize > nSendBufferMaxSize)
2783 8 : pnode->fPauseSend = true;
2784 322954 : pnode->vSendMsg.push_back(std::move(serializedHeader));
2785 322954 : if (nMessageSize)
2786 318099 : pnode->vSendMsg.push_back(std::move(msg.data));
2787 :
2788 : // If write queue empty, attempt "optimistic write"
2789 322954 : if (optimisticSend == true)
2790 0 : nBytesSent = SocketSendData(pnode);
2791 : // wake up select() call in case there was no pending data before (so it was not selecting this socket for sending)
2792 322954 : else if (!hasPendingData && wakeupSelectNeeded)
2793 199060 : WakeSelect();
2794 : }
2795 322954 : if (nBytesSent)
2796 0 : RecordBytesSent(nBytesSent);
2797 322954 : }
2798 :
2799 0 : bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
2800 : {
2801 0 : CNode* found = nullptr;
2802 0 : LOCK(cs_vNodes);
2803 0 : for (auto&& pnode : vNodes) {
2804 0 : if(pnode->GetId() == id) {
2805 : found = pnode;
2806 : break;
2807 : }
2808 : }
2809 0 : return found != nullptr && NodeFullyConnected(found) && func(found);
2810 : }
2811 :
2812 109 : bool CConnman::ForNode(const CService& addr, const std::function<bool(const CNode* pnode)>& cond, const std::function<bool(CNode* pnode)>& func)
2813 : {
2814 109 : CNode* found = nullptr;
2815 109 : LOCK(cs_vNodes);
2816 827 : for (auto&& pnode : vNodes) {
2817 825 : if(static_cast<CService>(pnode->addr) == addr) {
2818 107 : found = pnode;
2819 107 : break;
2820 : }
2821 : }
2822 270 : return found != nullptr && cond(found) && func(found);
2823 : }
2824 :
2825 21 : bool CConnman::IsNodeConnected(const CAddress& addr)
2826 : {
2827 21 : return FindNode(addr.ToStringIPPort());
2828 : }
2829 :
2830 21 : CNode* CConnman::ConnectNode(const CAddress& addrConnect)
2831 : {
2832 21 : return ConnectNode(addrConnect, nullptr, true, true);
2833 : }
2834 :
2835 : // valid, reachable and routable address (except for RegTest)
2836 17 : bool validateMasternodeIP(const std::string& addrStr)
2837 : {
2838 34 : CNetAddr resolved;
2839 17 : if (LookupHost(addrStr, resolved, false)) {
2840 12 : return ((IsReachable(resolved) && resolved.IsRoutable()) ||
2841 2 : (Params().IsRegTestNet() && resolved.IsValid()));
2842 : }
2843 : return false;
2844 : }
2845 :
2846 52256 : int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
2847 52256 : return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
2848 : }
2849 :
2850 1467030 : std::vector<CNode*> CConnman::CopyNodeVector(std::function<bool(const CNode* pnode)> cond)
2851 : {
2852 1467030 : std::vector<CNode*> vecNodesCopy;
2853 1467030 : LOCK(cs_vNodes);
2854 11777600 : for (size_t i = 0; i < vNodes.size(); ++i) {
2855 10310500 : CNode* pnode = vNodes[i];
2856 10310500 : if (!cond(pnode))
2857 1113 : continue;
2858 10309400 : pnode->AddRef();
2859 10309400 : vecNodesCopy.push_back(pnode);
2860 : }
2861 2934060 : return vecNodesCopy;
2862 : }
2863 :
2864 1383160 : std::vector<CNode*> CConnman::CopyNodeVector()
2865 : {
2866 2766310 : return CopyNodeVector(AllNodes);
2867 : }
2868 :
2869 1467030 : void CConnman::ReleaseNodeVector(const std::vector<CNode*>& vecNodes)
2870 : {
2871 11776400 : for (size_t i = 0; i < vecNodes.size(); ++i) {
2872 10309400 : CNode* pnode = vecNodes[i];
2873 10309400 : pnode->Release();
2874 : }
2875 1467030 : }
2876 :
2877 2877 : CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id)
2878 : {
2879 2877 : return CSipHasher(nSeed0, nSeed1).Write(id);
2880 : }
2881 :
2882 1428 : uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad)
2883 : {
2884 1428 : std::vector<unsigned char> vchNetGroup(ad.GetGroup(addrman.m_asmap));
2885 :
2886 2856 : return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
2887 : }
2888 :
|