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 2154 : uint16_t GetListenPort()
105 : {
106 2154 : return (uint16_t)(gArgs.GetArg("-port", Params().GetDefaultPort()));
107 : }
108 :
109 : // find 'best' local address for a particular peer
110 1719 : bool GetLocal(CService& addr, const CNetAddr* paddrPeer)
111 : {
112 1719 : if (!fListen)
113 : return false;
114 :
115 1719 : int nBestScore = -1;
116 1719 : int nBestReachability = -1;
117 1719 : {
118 1719 : LOCK(cs_mapLocalHost);
119 1720 : 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 1719 : return nBestScore >= 0;
130 : }
131 :
132 : //! Convert the serialized seeds into usable address objects.
133 121 : 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 121 : const int64_t nOneWeek = 7 * 24 * 60 * 60;
140 121 : std::vector<CAddress> vSeedsOut;
141 121 : FastRandomContext rng;
142 121 : CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
143 121 : 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 121 : 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 1458 : CAddress GetLocalAddress(const CNetAddr* paddrPeer, ServiceFlags nLocalServices)
159 : {
160 2916 : CAddress ret(CService(CNetAddr(), GetListenPort()), nLocalServices);
161 1458 : CService addr;
162 1458 : if (GetLocal(addr, paddrPeer)) {
163 1 : ret = CAddress(addr, nLocalServices);
164 : }
165 1458 : ret.nTime = GetAdjustedTime();
166 1458 : 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 1458 : bool IsPeerAddrLocalGood(CNode* pnode)
179 : {
180 1458 : CService addrLocal = pnode->GetAddrLocal();
181 1459 : return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
182 1459 : IsReachable(addrLocal.GetNetwork());
183 : }
184 :
185 : // pushes our own address to a peer
186 1240 : void AdvertiseLocal(CNode* pnode)
187 : {
188 1240 : if (fListen && pnode->fSuccessfullyConnected) {
189 2480 : 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 1240 : FastRandomContext rng;
194 1240 : if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
195 0 : rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0)) {
196 2 : addrLocal.SetIP(pnode->GetAddrLocal());
197 : }
198 1240 : if (addrLocal.IsRoutable()) {
199 1 : LogPrintf("%s: advertising address %s\n", __func__, addrLocal.ToString());
200 1 : pnode->PushAddress(addrLocal, rng);
201 : }
202 : }
203 1240 : }
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 647 : bool IsLocal(const CService& addr)
279 : {
280 647 : LOCK(cs_mapLocalHost);
281 1941 : return mapLocalHost.count(addr) > 0;
282 : }
283 :
284 12 : CNode* CConnman::FindNode(const CNetAddr& ip)
285 : {
286 24 : LOCK(cs_vNodes);
287 31 : for (CNode* pnode : vNodes) {
288 19 : 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 793 : CNode* CConnman::FindNode(const std::string& addrName)
307 : {
308 1586 : LOCK(cs_vNodes);
309 3880 : for (CNode* pnode : vNodes) {
310 3239 : if (pnode->GetAddrName() == addrName) {
311 152 : return pnode;
312 : }
313 : }
314 641 : return nullptr;
315 : }
316 :
317 32 : CNode* CConnman::FindNode(const CService& addr)
318 : {
319 64 : LOCK(cs_vNodes);
320 32 : const bool isRegTestNet = Params().IsRegTestNet();
321 51 : for (CNode* pnode : vNodes) {
322 39 : if (isRegTestNet) {
323 : //if using regtest, just check the IP
324 39 : if (static_cast<CNetAddr>(pnode->addr) == static_cast<CNetAddr>(addr))
325 20 : return pnode;
326 : } else {
327 0 : if (pnode->addr == addr)
328 : return pnode;
329 : }
330 : }
331 12 : return nullptr;
332 : }
333 :
334 714 : bool CConnman::CheckIncomingNonce(uint64_t nonce)
335 : {
336 714 : LOCK(cs_vNodes);
337 4811 : for(CNode* pnode : vNodes) {
338 4097 : if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
339 0 : return false;
340 : }
341 714 : return true;
342 : }
343 :
344 726 : CNode* CConnman::ConnectNode(CAddress addrConnect, const char* pszDest, bool fCountFailure, bool manual_connection)
345 : {
346 726 : if (pszDest == nullptr) {
347 32 : 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 32 : CNode* pnode = FindNode(static_cast<CService>(addrConnect));
354 32 : if (pnode) {
355 20 : LogPrintf("Failed to open new connection, already connected\n");
356 20 : return nullptr;
357 : }
358 : }
359 :
360 : /// debug print
361 1400 : 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 706 : const int default_port = Params().GetDefaultPort();
367 706 : if (pszDest) {
368 1388 : std::vector<CService> resolved;
369 1406 : if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
370 690 : addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
371 690 : 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 706 : bool connected = false;
380 706 : SOCKET hSocket = INVALID_SOCKET;
381 1432 : proxyType proxy;
382 706 : if (addrConnect.IsValid()) {
383 702 : bool proxyConnectionFailed = false;
384 :
385 702 : 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 691 : hSocket = CreateSocket(addrConnect);
394 691 : if (hSocket == INVALID_SOCKET) {
395 : return nullptr;
396 : }
397 691 : connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
398 : }
399 702 : 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 702 : 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 706 : if (!connected) {
415 13 : CloseSocket(hSocket);
416 : return nullptr;
417 : }
418 :
419 : // Add node
420 693 : NodeId id = GetNewNodeId();
421 693 : uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
422 1386 : CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false);
423 693 : pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
424 693 : pnode->fWhitelisted = IsWhitelistedRange(addrConnect);
425 693 : pnode->AddRef();
426 :
427 : // We're making a new connection, harvest entropy from the time (and our peer count)
428 693 : RandAddEvent((uint32_t)id);
429 :
430 693 : 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 1839 : void CNode::CloseSocketDisconnect()
454 : {
455 1839 : fDisconnect = true;
456 1839 : LOCK(cs_hSocket);
457 1839 : if (hSocket != INVALID_SOCKET) {
458 1456 : LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
459 1456 : CloseSocket(hSocket);
460 : }
461 1839 : }
462 :
463 27114 : bool CNode::DisconnectOldProtocol(int nVersionIn, int nVersionRequired)
464 : {
465 27114 : fDisconnect = false;
466 27114 : if (nVersionIn < nVersionRequired) {
467 1 : LogPrintf("%s : peer=%d using obsolete version %i; disconnecting\n", __func__, id, nVersionIn);
468 1 : fDisconnect = true;
469 : }
470 27114 : 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 935 : bool CConnman::IsBanned(CNetAddr ip)
486 : {
487 1870 : LOCK(cs_setBanned);
488 941 : 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 926 : 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 1484 : bool CConnman::IsWhitelistedRange(const CNetAddr& addr)
629 : {
630 1484 : for (const CSubNet& subnet : vWhitelistedRange) {
631 184 : if (subnet.Match(addr))
632 184 : return true;
633 : }
634 1300 : return false;
635 : }
636 :
637 112100 : std::string CNode::GetAddrName() const {
638 112100 : LOCK(cs_addrName);
639 336300 : 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 62832 : CService CNode::GetAddrLocal() const {
650 62832 : LOCK(cs_addrLocal);
651 62832 : return addrLocal;
652 : }
653 :
654 1363 : void CNode::SetAddrLocal(const CService& addrLocalIn) {
655 1363 : LOCK(cs_addrLocal);
656 1363 : 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 2726 : addrLocal = addrLocalIn;
660 : }
661 1363 : }
662 :
663 : #undef X
664 : #define X(name) stats.name = name
665 61373 : void CNode::copyStats(CNodeStats& stats, const std::vector<bool>& m_asmap)
666 : {
667 61373 : stats.nodeid = this->GetId();
668 61373 : X(nServices);
669 61373 : stats.m_mapped_as = addr.GetMappedAS(m_asmap);
670 61373 : X(nLastSend);
671 61373 : X(nLastRecv);
672 61373 : X(nTimeConnected);
673 61373 : X(nTimeOffset);
674 61373 : stats.addrName = GetAddrName();
675 61373 : X(nVersion);
676 61373 : {
677 61373 : LOCK(cs_SubVer);
678 61373 : X(cleanSubVer);
679 : }
680 61373 : X(fInbound);
681 61373 : X(fAddnode);
682 61373 : X(nStartingHeight);
683 61373 : {
684 61373 : LOCK(cs_vSend);
685 61373 : X(mapSendBytesPerMsgCmd);
686 61373 : X(nSendBytes);
687 : }
688 61373 : {
689 61373 : LOCK(cs_vRecv);
690 61373 : X(mapRecvBytesPerMsgCmd);
691 61373 : X(nRecvBytes);
692 : }
693 61373 : X(fWhitelisted);
694 61373 : X(m_masternode_connection);
695 61373 : X(m_masternode_iqr_connection);
696 61373 : X(m_masternode_probe_connection);
697 61373 : {
698 61373 : LOCK(cs_mnauth);
699 61373 : X(verifiedProRegTxHash);
700 61373 : 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 61373 : int64_t nPingUsecWait = 0;
710 61373 : if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
711 810 : 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 61373 : stats.dPingTime = (((double)nPingUsecTime) / 1e6);
716 61373 : stats.dPingWait = (((double)nPingUsecWait) / 1e6);
717 :
718 : // Leave string empty if addrLocal invalid (not filled in yet)
719 61373 : CService addrLocalUnlocked = GetAddrLocal();
720 61373 : stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
721 61373 : }
722 : #undef X
723 :
724 344736 : bool CNode::ReceiveMsgBytes(const char* pch, unsigned int nBytes, bool& complete)
725 : {
726 344736 : complete = false;
727 344736 : int64_t nTimeMicros = GetTimeMicros();
728 689472 : LOCK(cs_vRecv);
729 344736 : nLastRecv = nTimeMicros / 1000000;
730 344736 : nRecvBytes += nBytes;
731 1101100 : while (nBytes > 0) {
732 : // get current incomplete message, or create a new one
733 756365 : if (vRecvMsg.empty() ||
734 514249 : vRecvMsg.back().complete())
735 758312 : vRecvMsg.emplace_back(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION);
736 :
737 756365 : CNetMessage& msg = vRecvMsg.back();
738 :
739 : // absorb network data
740 756365 : int handled;
741 756365 : if (!msg.in_data)
742 379156 : handled = msg.readHeader(pch, nBytes);
743 : else
744 377209 : handled = msg.readData(pch, nBytes);
745 :
746 756365 : if (handled < 0)
747 : return false;
748 :
749 756365 : 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 756364 : pch += handled;
755 756364 : nBytes -= handled;
756 :
757 1857460 : if (msg.complete()) {
758 :
759 : // Store received bytes per message command
760 : // to prevent a memory DOS, only allow valid commands
761 758280 : mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
762 379140 : if (i == mapRecvBytesPerMsgCmd.end())
763 191 : i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
764 379140 : assert(i != mapRecvBytesPerMsgCmd.end());
765 379140 : i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
766 :
767 379140 : msg.nTime = nTimeMicros;
768 379140 : complete = true;
769 : }
770 : }
771 :
772 : return true;
773 : }
774 :
775 1366 : 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 1366 : 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 1366 : nSendVersion = nVersionIn;
786 : }
787 1366 : }
788 :
789 2908617 : 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 2908617 : 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 379156 : int CNetMessage::readHeader(const char* pch, unsigned int nBytes)
802 : {
803 : // copy data to temporary parsing buffer
804 379156 : unsigned int nRemaining = 24 - nHdrPos;
805 379156 : unsigned int nCopy = std::min(nRemaining, nBytes);
806 :
807 379156 : memcpy(&hdrbuf[nHdrPos], pch, nCopy);
808 379156 : nHdrPos += nCopy;
809 :
810 : // if header incomplete, exit
811 379156 : if (nHdrPos < 24)
812 0 : return nCopy;
813 :
814 : // deserialize to CMessageHeader
815 379156 : try {
816 379156 : hdrbuf >> hdr;
817 0 : } catch (const std::exception&) {
818 0 : return -1;
819 : }
820 :
821 : // reject messages larger than MAX_SIZE
822 379156 : if (hdr.nMessageSize > MAX_SIZE)
823 : return -1;
824 :
825 : // switch state to reading message data
826 379156 : in_data = true;
827 :
828 379156 : return nCopy;
829 : }
830 :
831 377209 : int CNetMessage::readData(const char* pch, unsigned int nBytes)
832 : {
833 377209 : unsigned int nRemaining = hdr.nMessageSize - nDataPos;
834 377209 : unsigned int nCopy = std::min(nRemaining, nBytes);
835 :
836 377209 : if (vRecv.size() < nDataPos + nCopy) {
837 : // Allocate up to 256 KiB ahead, but never more than the total message size.
838 375454 : vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
839 : }
840 :
841 377209 : hasher.Write((const unsigned char*)pch, nCopy);
842 377209 : memcpy(&vRecv[nDataPos], pch, nCopy);
843 377209 : nDataPos += nCopy;
844 :
845 377209 : return nCopy;
846 : }
847 :
848 378828 : const uint256& CNetMessage::GetMessageHash() const
849 : {
850 378828 : assert(complete());
851 12501300 : if (data_hash.IsNull())
852 378828 : hasher.Finalize(data_hash.begin());
853 378828 : return data_hash;
854 : }
855 :
856 : // requires LOCK(cs_vSend)
857 288071 : size_t CConnman::SocketSendData(CNode* pnode)
858 : {
859 288071 : auto it = pnode->vSendMsg.begin();
860 288071 : size_t nSentSize = 0;
861 :
862 942008 : while (it != pnode->vSendMsg.end()) {
863 653981 : const auto& data = *it;
864 653981 : assert(data.size() > pnode->nSendOffset);
865 653981 : int nBytes = 0;
866 653981 : {
867 653981 : LOCK(pnode->cs_hSocket);
868 653981 : if (pnode->hSocket == INVALID_SOCKET)
869 : break;
870 653981 : nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
871 : }
872 653981 : if (nBytes > 0) {
873 653937 : pnode->nLastSend = GetSystemTimeInSeconds();
874 653937 : pnode->nSendBytes += nBytes;
875 653937 : pnode->nSendOffset += nBytes;
876 653937 : nSentSize += nBytes;
877 653937 : if (pnode->nSendOffset == data.size()) {
878 653937 : pnode->nSendOffset = 0;
879 653937 : pnode->nSendSize -= data.size();
880 653937 : pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
881 654548 : it++;
882 : } else {
883 : // could not send full message; stop sending more
884 : break;
885 : }
886 : } else {
887 44 : if (nBytes < 0) {
888 : // error
889 44 : int nErr = WSAGetLastError();
890 44 : if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
891 44 : LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
892 44 : pnode->CloseSocketDisconnect();
893 : }
894 : }
895 : // couldn't send anything at all
896 : break;
897 : }
898 : }
899 :
900 288071 : if (it == pnode->vSendMsg.end()) {
901 288027 : assert(pnode->nSendOffset == 0);
902 288027 : assert(pnode->nSendSize == 0);
903 : }
904 288071 : pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
905 288071 : return nSentSize;
906 : }
907 :
908 2 : void CheckOffsetDisconnectedPeers(const CNetAddr& ip)
909 : {
910 2 : int nConnections = 0;
911 2 : if (g_connman) {
912 2 : g_connman->ForEachNode([&nConnections](CNode* pnode) {
913 10 : if (pnode->fSuccessfullyConnected)
914 10 : nConnections++;
915 10 : if (nConnections == ENOUGH_CONNECTIONS)
916 : return;
917 : });
918 : }
919 :
920 : // Not enough connections. Insert peer.
921 2 : static std::set<CNetAddr> setOffsetDisconnectedPeers;
922 2 : setOffsetDisconnectedPeers.insert(ip);
923 2 : 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 2 : }
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 791 : void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
1075 791 : struct sockaddr_storage sockaddr;
1076 791 : socklen_t len = sizeof(sockaddr);
1077 791 : SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
1078 1554 : CAddress addr;
1079 791 : int nInbound = 0;
1080 791 : int nVerifiedInboundMasternodes = 0;
1081 :
1082 791 : if (hSocket != INVALID_SOCKET)
1083 791 : if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
1084 0 : LogPrintf("Warning: Unknown socket family\n");
1085 :
1086 791 : bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
1087 791 : {
1088 791 : LOCK(cs_vNodes);
1089 4729 : for (const CNode* pnode : vNodes) {
1090 3938 : if (pnode->fInbound) {
1091 1881 : nInbound++;
1092 3762 : if (!pnode->verifiedProRegTxHash.IsNull()) {
1093 58 : nVerifiedInboundMasternodes++;
1094 : }
1095 : }
1096 : }
1097 : }
1098 :
1099 791 : 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 28 : return;
1104 : }
1105 :
1106 791 : if (!fNetworkActive) {
1107 28 : LogPrintf("connection from %s dropped: not accepting new connections\n", addr.ToString());
1108 28 : CloseSocket(hSocket);
1109 : return;
1110 : }
1111 :
1112 763 : if (!IsSelectableSocket(hSocket)) {
1113 : LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
1114 : CloseSocket(hSocket);
1115 : return;
1116 : }
1117 :
1118 1526 : if (IsBanned(addr) && !whitelisted) {
1119 0 : LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
1120 0 : CloseSocket(hSocket);
1121 : return;
1122 : }
1123 :
1124 : // TODO: pending review.
1125 : // Evict connections until we are below nMaxInbound. In case eviction protection resulted in nodes to not be evicted
1126 : // before, they might get evicted in batches now (after the protection timeout).
1127 : // We don't evict verified MN connections and also don't take them into account when checking limits. We can do this
1128 : // because we know that such connections are naturally limited by the total number of MNs, so this is not usable
1129 : // for attacks.
1130 763 : while (nInbound - nVerifiedInboundMasternodes >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) {
1131 0 : if (!AttemptToEvictConnection(whitelisted)) {
1132 : // No connection to evict, disconnect the new connection
1133 0 : LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
1134 0 : CloseSocket(hSocket);
1135 : return;
1136 : }
1137 0 : nInbound--;
1138 : }
1139 :
1140 763 : NodeId id = GetNewNodeId();
1141 763 : uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
1142 :
1143 763 : CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, "", true);
1144 763 : pnode->AddRef();
1145 763 : pnode->fWhitelisted = whitelisted;
1146 763 : m_msgproc->InitializeNode(pnode);
1147 :
1148 1514 : LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1149 :
1150 763 : {
1151 763 : LOCK(cs_vNodes);
1152 763 : vNodes.push_back(pnode);
1153 : }
1154 :
1155 : // We received a new connection, harvest entropy from the time (and our peer count)
1156 763 : RandAddEvent((uint32_t)id);
1157 : }
1158 :
1159 1049560 : void CConnman::DisconnectNodes()
1160 : {
1161 1049560 : {
1162 1049560 : LOCK(cs_vNodes);
1163 :
1164 1049560 : if (!fNetworkActive) {
1165 : // Disconnect any connected nodes
1166 1775 : for (CNode* pnode : vNodes) {
1167 80 : if (!pnode->fDisconnect) {
1168 80 : LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
1169 80 : pnode->fDisconnect = true;
1170 : }
1171 : }
1172 : }
1173 :
1174 : // Disconnect unused nodes
1175 2099120 : std::vector<CNode*> vNodesCopy = vNodes;
1176 9330120 : for (CNode* pnode : vNodesCopy) {
1177 8280560 : if (pnode->fDisconnect) {
1178 : // remove from vNodes
1179 676 : vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1180 :
1181 : // release outbound grant (if any)
1182 676 : pnode->grantOutbound.Release();
1183 :
1184 : // close socket and cleanup
1185 676 : pnode->CloseSocketDisconnect();
1186 :
1187 : // hold in disconnected pool until all refs are released
1188 676 : pnode->Release();
1189 8280560 : vNodesDisconnected.push_back(pnode);
1190 : }
1191 : }
1192 : }
1193 1049560 : {
1194 : // Delete disconnected nodes
1195 1049560 : std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1196 1050740 : for (CNode* pnode : vNodesDisconnectedCopy) {
1197 : // wait until threads are done using it
1198 1175 : if (pnode->GetRefCount() <= 0) {
1199 676 : bool fDelete = false;
1200 676 : {
1201 676 : TRY_LOCK(pnode->cs_inventory, lockInv);
1202 676 : if (lockInv) {
1203 1352 : TRY_LOCK(pnode->cs_vSend, lockSend);
1204 676 : if (lockSend) {
1205 676 : fDelete = true;
1206 : }
1207 : }
1208 : }
1209 676 : if (fDelete) {
1210 676 : vNodesDisconnected.remove(pnode);
1211 676 : DeleteNode(pnode);
1212 : }
1213 : }
1214 : }
1215 : }
1216 1049560 : }
1217 :
1218 1049560 : void CConnman::NotifyNumConnectionsChanged()
1219 : {
1220 1049560 : size_t vNodesSize;
1221 1049560 : {
1222 1049560 : LOCK(cs_vNodes);
1223 1049560 : vNodesSize = vNodes.size();
1224 : }
1225 1049560 : if (vNodesSize != nPrevNodeCount) {
1226 1882 : nPrevNodeCount = vNodesSize;
1227 1882 : if (clientInterface)
1228 1882 : clientInterface->NotifyNumConnectionsChanged((int)vNodesSize);
1229 : }
1230 1049560 : }
1231 :
1232 8280560 : void CConnman::InactivityCheck(CNode* pnode)
1233 : {
1234 8280560 : int64_t nTime = GetSystemTimeInSeconds();
1235 8280560 : if (nTime - pnode->nTimeConnected > 60) {
1236 2881300 : if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) {
1237 2 : LogPrint(BCLog::NET, "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
1238 2 : pnode->fDisconnect = true;
1239 2881300 : } else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL) {
1240 0 : LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1241 0 : pnode->fDisconnect = true;
1242 2881300 : } else if (nTime - pnode->nLastRecv > TIMEOUT_INTERVAL) {
1243 0 : LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1244 0 : pnode->fDisconnect = true;
1245 2881300 : } else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros()) {
1246 0 : LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1247 0 : pnode->fDisconnect = true;
1248 2881300 : } else if (!pnode->fSuccessfullyConnected) {
1249 1 : LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId());
1250 1 : pnode->fDisconnect = true;
1251 : }
1252 : }
1253 8280560 : }
1254 :
1255 1049560 : bool CConnman::GenerateSelectSet(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set)
1256 : {
1257 2099070 : for (const ListenSocket& hListenSocket : vhListenSocket) {
1258 1049510 : recv_set.insert(hListenSocket.socket);
1259 : }
1260 :
1261 1049560 : {
1262 1049560 : LOCK(cs_vNodes);
1263 9329450 : for (CNode* pnode: vNodes) {
1264 : // Implement the following logic:
1265 : // * If there is data to send, select() for sending data. As this only
1266 : // happens when optimistic write failed, we choose to first drain the
1267 : // write buffer in this case before receiving more. This avoids
1268 : // needlessly queueing received data, if the remote peer is not themselves
1269 : // receiving data. This means properly utilizing TCP flow control signalling.
1270 : // * Otherwise, if there is space left in the receive buffer, select() for
1271 : // receiving data.
1272 : // * Hand off all complete messages to the processor, to be handled without
1273 : // blocking here.
1274 :
1275 8279890 : bool select_recv = !pnode->fPauseRecv;
1276 8279890 : bool select_send;
1277 8279890 : {
1278 8279890 : LOCK(pnode->cs_vSend);
1279 8279890 : select_send = !pnode->vSendMsg.empty();
1280 : }
1281 :
1282 16271700 : LOCK(pnode->cs_hSocket);
1283 8279890 : if (pnode->hSocket == INVALID_SOCKET)
1284 288071 : continue;
1285 :
1286 8279890 : error_set.insert(pnode->hSocket);
1287 8279890 : if (select_send) {
1288 288071 : send_set.insert(pnode->hSocket);
1289 288071 : continue;
1290 : }
1291 7991820 : if (select_recv) {
1292 15983600 : recv_set.insert(pnode->hSocket);
1293 : }
1294 : }
1295 : }
1296 :
1297 : #ifdef USE_WAKEUP_PIPE
1298 : // We add a pipe to the read set so that the select() call can be woken up from the outside
1299 : // This is done when data is added to send buffers (vSendMsg) or when new peers are added
1300 : // This is currently only implemented for POSIX compliant systems. This means that Windows will fall back to
1301 : // timing out after 50ms and then trying to send. This is ok as we assume that heavy-load daemons are usually
1302 : // run on Linux and friends.
1303 1049560 : recv_set.insert(wakeupPipe[0]);
1304 : #endif
1305 :
1306 1049560 : return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1307 : }
1308 :
1309 : #ifdef USE_POLL
1310 1049560 : void CConnman::SocketEvents(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set)
1311 : {
1312 2098770 : std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1313 1049560 : if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1314 0 : interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1315 355 : return;
1316 : }
1317 :
1318 2098770 : std::unordered_map<SOCKET, struct pollfd> pollfds;
1319 11140400 : for (SOCKET socket_id : recv_select_set) {
1320 10090900 : pollfds[socket_id].fd = socket_id;
1321 10090900 : pollfds[socket_id].events |= POLLIN;
1322 : }
1323 :
1324 1337630 : for (SOCKET socket_id : send_select_set) {
1325 288071 : pollfds[socket_id].fd = socket_id;
1326 288071 : pollfds[socket_id].events |= POLLOUT;
1327 : }
1328 :
1329 9329450 : for (SOCKET socket_id : error_select_set) {
1330 8279890 : pollfds[socket_id].fd = socket_id;
1331 : // These flags are ignored, but we set them for clarity
1332 8279890 : pollfds[socket_id].events |= POLLERR|POLLHUP;
1333 : }
1334 :
1335 2098770 : std::vector<struct pollfd> vpollfds;
1336 1049560 : vpollfds.reserve(pollfds.size());
1337 11428500 : for (auto it : pollfds) {
1338 10379000 : vpollfds.push_back(std::move(it.second));
1339 : }
1340 :
1341 1049560 : wakeupSelectNeeded = true;
1342 1049560 : int r = poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS);
1343 1049560 : wakeupSelectNeeded = false;
1344 1049560 : if (r < 0) {
1345 355 : return;
1346 : }
1347 :
1348 1049560 : if (interruptNet) return;
1349 :
1350 11426700 : for (struct pollfd pollfd_entry : vpollfds) {
1351 10377500 : if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1352 10377500 : if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1353 10377500 : if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1354 : }
1355 : }
1356 : #else
1357 : void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1358 : {
1359 : std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1360 : if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1361 : interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1362 : return;
1363 : }
1364 :
1365 : //
1366 : // Find which sockets have data to receive
1367 : //
1368 : struct timeval timeout;
1369 : timeout.tv_sec = 0;
1370 : timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
1371 :
1372 : fd_set fdsetRecv;
1373 : fd_set fdsetSend;
1374 : fd_set fdsetError;
1375 : FD_ZERO(&fdsetRecv);
1376 : FD_ZERO(&fdsetSend);
1377 : FD_ZERO(&fdsetError);
1378 : SOCKET hSocketMax = 0;
1379 :
1380 : for (SOCKET hSocket : recv_select_set) {
1381 : FD_SET(hSocket, &fdsetRecv);
1382 : hSocketMax = std::max(hSocketMax, hSocket);
1383 : }
1384 :
1385 : for (SOCKET hSocket : send_select_set) {
1386 : FD_SET(hSocket, &fdsetSend);
1387 : hSocketMax = std::max(hSocketMax, hSocket);
1388 : }
1389 :
1390 : for (SOCKET hSocket : error_select_set) {
1391 : FD_SET(hSocket, &fdsetError);
1392 : hSocketMax = std::max(hSocketMax, hSocket);
1393 : }
1394 :
1395 : wakeupSelectNeeded = true;
1396 : int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1397 : wakeupSelectNeeded = false;
1398 :
1399 : if (interruptNet)
1400 : return;
1401 :
1402 : if (nSelect == SOCKET_ERROR) {
1403 : int nErr = WSAGetLastError();
1404 : LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1405 : for (unsigned int i = 0; i <= hSocketMax; i++)
1406 : FD_SET(i, &fdsetRecv);
1407 : FD_ZERO(&fdsetSend);
1408 : FD_ZERO(&fdsetError);
1409 : if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1410 : return;
1411 : }
1412 :
1413 : for (SOCKET hSocket : recv_select_set) {
1414 : if (FD_ISSET(hSocket, &fdsetRecv)) {
1415 : recv_set.insert(hSocket);
1416 : }
1417 : }
1418 :
1419 : for (SOCKET hSocket : send_select_set) {
1420 : if (FD_ISSET(hSocket, &fdsetSend)) {
1421 : send_set.insert(hSocket);
1422 : }
1423 : }
1424 :
1425 : for (SOCKET hSocket : error_select_set) {
1426 : if (FD_ISSET(hSocket, &fdsetError)) {
1427 : error_set.insert(hSocket);
1428 : }
1429 : }
1430 : }
1431 : #endif
1432 :
1433 1049560 : void CConnman::SocketHandler()
1434 : {
1435 2098770 : std::set<SOCKET> recv_set, send_set, error_set;
1436 1049560 : SocketEvents(recv_set, send_set, error_set);
1437 :
1438 : #ifdef USE_WAKEUP_PIPE
1439 : // drain the wakeup pipe
1440 1892880 : if (recv_set.count(wakeupPipe[0])) {
1441 206240 : LogPrint(BCLog::NET, "woke up select()\n");
1442 412480 : char buf[128];
1443 412480 : while (true) {
1444 412480 : int r = read(wakeupPipe[0], buf, sizeof(buf));
1445 412480 : if (r <= 0) {
1446 : break;
1447 : }
1448 : }
1449 : }
1450 : #endif
1451 :
1452 1049920 : if (interruptNet) return;
1453 :
1454 : //
1455 : // Accept new connections
1456 : //
1457 2098370 : for (const ListenSocket& hListenSocket : vhListenSocket) {
1458 2097530 : if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0) {
1459 791 : AcceptConnection(hListenSocket);
1460 : }
1461 : }
1462 :
1463 : //
1464 : // Service each socket
1465 : //
1466 2098410 : std::vector<CNode*> vNodesCopy = CopyNodeVector();
1467 :
1468 9329770 : for (CNode* pnode : vNodesCopy) {
1469 8280560 : if (interruptNet)
1470 0 : return;
1471 :
1472 : //
1473 : // Receive
1474 : //
1475 8280560 : bool recvSet = false;
1476 8280560 : bool sendSet = false;
1477 8280560 : bool errorSet = false;
1478 8280560 : {
1479 8280560 : LOCK(pnode->cs_hSocket);
1480 8280560 : if (pnode->hSocket == INVALID_SOCKET)
1481 0 : continue;
1482 8280560 : recvSet = recv_set.count(pnode->hSocket) > 0;
1483 8280560 : sendSet = send_set.count(pnode->hSocket) > 0;
1484 16561100 : errorSet = error_set.count(pnode->hSocket) > 0;
1485 : }
1486 8280560 : if (recvSet || errorSet) {
1487 : // typical socket buffer is 8K-64K
1488 345074 : char pchBuf[0x10000];
1489 345074 : int nBytes = 0;
1490 345074 : {
1491 345074 : LOCK(pnode->cs_hSocket);
1492 345074 : if (pnode->hSocket == INVALID_SOCKET)
1493 0 : continue;
1494 345074 : nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1495 : }
1496 345074 : if (nBytes > 0) {
1497 344736 : bool notify = false;
1498 344736 : if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1499 1 : pnode->CloseSocketDisconnect();
1500 344736 : RecordBytesRecv(nBytes);
1501 344736 : if (notify) {
1502 242881 : size_t nSizeAdded = 0;
1503 242881 : auto it(pnode->vRecvMsg.begin());
1504 622021 : for (; it != pnode->vRecvMsg.end(); ++it) {
1505 379921 : if (!it->complete())
1506 : break;
1507 379140 : nSizeAdded += it->vRecv.size() + CMessageHeader::HEADER_SIZE;
1508 : }
1509 242881 : {
1510 242881 : LOCK(pnode->cs_vProcessMsg);
1511 242881 : pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1512 242881 : pnode->nProcessQueueSize += nSizeAdded;
1513 242881 : pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1514 : }
1515 242881 : WakeMessageHandler();
1516 : }
1517 338 : } else if (nBytes == 0) {
1518 : // socket closed gracefully
1519 331 : if (!pnode->fDisconnect)
1520 331 : LogPrint(BCLog::NET, "socket closed\n");
1521 331 : pnode->CloseSocketDisconnect();
1522 7 : } else if (nBytes < 0) {
1523 : // error
1524 7 : int nErr = WSAGetLastError();
1525 7 : if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
1526 7 : if (!pnode->fDisconnect)
1527 14 : LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1528 7 : pnode->CloseSocketDisconnect();
1529 : }
1530 : }
1531 : }
1532 :
1533 : //
1534 : // Send
1535 : //
1536 8280560 : if (sendSet) {
1537 576142 : LOCK(pnode->cs_vSend);
1538 288071 : size_t nBytes = SocketSendData(pnode);
1539 288071 : if (nBytes)
1540 288071 : RecordBytesSent(nBytes);
1541 : }
1542 :
1543 8280560 : InactivityCheck(pnode);
1544 : }
1545 1049210 : ReleaseNodeVector(vNodesCopy);
1546 : }
1547 :
1548 355 : void CConnman::ThreadSocketHandler()
1549 : {
1550 1049920 : while (!interruptNet) {
1551 1049560 : DisconnectNodes();
1552 1049560 : NotifyNumConnectionsChanged();
1553 1049560 : SocketHandler();
1554 : }
1555 355 : }
1556 :
1557 242881 : void CConnman::WakeMessageHandler()
1558 : {
1559 242881 : {
1560 242881 : std::lock_guard<std::mutex> lock(mutexMsgProc);
1561 242881 : fMsgProcWake = true;
1562 : }
1563 242881 : condMsgProc.notify_one();
1564 242881 : }
1565 :
1566 206411 : void CConnman::WakeSelect()
1567 : {
1568 : #ifdef USE_WAKEUP_PIPE
1569 206411 : if (wakeupPipe[1] == -1) {
1570 0 : return;
1571 : }
1572 :
1573 206411 : LogPrint(BCLog::NET, "waking up select()\n");
1574 :
1575 206411 : char buf[1];
1576 206411 : if (write(wakeupPipe[1], buf, 1) != 1) {
1577 0 : LogPrint(BCLog::NET, "write to wakeupPipe failed\n");
1578 : }
1579 : #endif
1580 :
1581 206411 : wakeupSelectNeeded = false;
1582 : }
1583 :
1584 0 : static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits)
1585 : {
1586 : //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK)
1587 0 : if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) {
1588 0 : *requiredServiceBits = NODE_NETWORK;
1589 0 : return data.host;
1590 : }
1591 :
1592 0 : return strprintf("x%x.%s", *requiredServiceBits, data.host);
1593 : }
1594 :
1595 :
1596 355 : void CConnman::ThreadDNSAddressSeed()
1597 : {
1598 : // goal: only query DNS seeds if address need is acute
1599 710 : if ((addrman.size() > 0) &&
1600 355 : (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
1601 0 : if (!interruptNet.sleep_for(std::chrono::seconds(11)))
1602 0 : return;
1603 :
1604 0 : LOCK(cs_vNodes);
1605 0 : int nRelevant = 0;
1606 0 : for (auto pnode : vNodes) {
1607 0 : nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->fAddnode && !pnode->fInbound && !pnode->m_masternode_probe_connection;
1608 : }
1609 0 : if (nRelevant >= 2) {
1610 0 : LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1611 0 : return;
1612 : }
1613 : }
1614 :
1615 355 : const std::vector<CDNSSeedData>& vSeeds = Params().DNSSeeds();
1616 355 : int found = 0;
1617 :
1618 355 : LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1619 :
1620 355 : for (const CDNSSeedData& seed : vSeeds) {
1621 0 : if (interruptNet) {
1622 0 : return;
1623 : }
1624 0 : if (HaveNameProxy()) {
1625 0 : AddOneShot(seed.host);
1626 : } else {
1627 0 : std::vector<CNetAddr> vIPs;
1628 0 : std::vector<CAddress> vAdd;
1629 0 : ServiceFlags requiredServiceBits = nRelevantServices;
1630 0 : std::string host = GetDNSHost(seed, &requiredServiceBits);
1631 0 : CNetAddr resolveSource;
1632 0 : if (!resolveSource.SetInternal(host)) {
1633 0 : continue;
1634 : }
1635 0 : if (LookupHost(host, vIPs, 0, true)) {
1636 0 : for (CNetAddr& ip : vIPs) {
1637 0 : int nOneDay = 24*3600;
1638 0 : CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1639 0 : addr.nTime = GetTime() - 3 * nOneDay - GetRand(4 * nOneDay); // use a random age between 3 and 7 days old
1640 0 : vAdd.push_back(addr);
1641 0 : found++;
1642 : }
1643 0 : addrman.Add(vAdd, resolveSource);
1644 : }
1645 : }
1646 : }
1647 :
1648 355 : LogPrintf("%d addresses found from DNS seeds\n", found);
1649 : }
1650 :
1651 :
1652 :
1653 :
1654 :
1655 :
1656 :
1657 :
1658 :
1659 :
1660 :
1661 :
1662 626 : void CConnman::DumpAddresses()
1663 : {
1664 626 : int64_t nStart = GetTimeMillis();
1665 :
1666 626 : CAddrDB adb;
1667 626 : adb.Write(addrman);
1668 :
1669 626 : LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1670 : addrman.size(), GetTimeMillis() - nStart);
1671 626 : }
1672 :
1673 356 : void CConnman::DumpData()
1674 : {
1675 356 : DumpAddresses();
1676 356 : DumpBanlist();
1677 356 : }
1678 :
1679 38128 : void CConnman::ProcessOneShot()
1680 : {
1681 38128 : std::string strDest;
1682 38128 : {
1683 38128 : LOCK(cs_vOneShots);
1684 38128 : if (vOneShots.empty())
1685 76256 : return;
1686 0 : strDest = vOneShots.front();
1687 0 : vOneShots.pop_front();
1688 : }
1689 0 : CAddress addr;
1690 0 : CSemaphoreGrant grant(*semOutbound, true);
1691 0 : if (grant) {
1692 0 : OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true);
1693 : }
1694 : }
1695 :
1696 355 : void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
1697 : {
1698 : // Connect to specific addresses
1699 355 : if (!connect.empty()) {
1700 0 : for (int64_t nLoop = 0;; nLoop++) {
1701 0 : ProcessOneShot();
1702 0 : for (const std::string& strAddr : connect) {
1703 0 : CAddress addr(CService(), NODE_NONE);
1704 0 : OpenNetworkConnection(addr, false, nullptr, strAddr.c_str());
1705 0 : for (int i = 0; i < 10 && i < nLoop; i++) {
1706 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1707 0 : return;
1708 : }
1709 : }
1710 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1711 : return;
1712 0 : }
1713 : }
1714 :
1715 : // Initiate network connections
1716 355 : int64_t nStart = GetTime();
1717 :
1718 : // Minimum time before next feeler connection (in microseconds).
1719 355 : int64_t nNextFeeler = PoissonNextSend(nStart * 1000 * 1000, FEELER_INTERVAL);
1720 38132 : while (!interruptNet) {
1721 38128 : ProcessOneShot();
1722 :
1723 38128 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1724 351 : return;
1725 :
1726 75554 : CSemaphoreGrant grant(*semOutbound);
1727 37777 : if (interruptNet)
1728 351 : return;
1729 :
1730 : // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1731 37777 : if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1732 25041 : static bool done = false;
1733 25041 : if (!done) {
1734 121 : LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1735 242 : CNetAddr local;
1736 121 : local.SetInternal("fixedseeds");
1737 121 : addrman.Add(ConvertSeeds(Params().FixedSeeds()), local);
1738 121 : done = true;
1739 : }
1740 : }
1741 :
1742 : //
1743 : // Choose an address to connect to based on most recently seen
1744 : //
1745 75554 : CAddress addrConnect;
1746 :
1747 : // Only connect out to one peer per network group (/16 for IPv4).
1748 : // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1749 37777 : int nOutbound = 0;
1750 75554 : std::set<std::vector<unsigned char> > setConnected;
1751 37777 : {
1752 37777 : LOCK(cs_vNodes);
1753 222106 : for (const CNode* pnode : vNodes) {
1754 184329 : if (!pnode->fInbound && !pnode->fAddnode && !pnode->m_masternode_connection) {
1755 : // Netgroups for inbound and addnode peers are not excluded because our goal here
1756 : // is to not use multiple of our limited outbound slots on a single netgroup
1757 : // but inbound and addnode peers do not use our outbound slots. Inbound peers
1758 : // also have the added issue that they're attacker controlled and could be used
1759 : // to prevent us from connecting to particular hosts if we used them here.
1760 172416 : setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
1761 86208 : nOutbound++;
1762 : }
1763 : }
1764 : }
1765 :
1766 : // Feeler Connections
1767 : //
1768 : // Design goals:
1769 : // * Increase the number of connectable addresses in the tried table.
1770 : //
1771 : // Method:
1772 : // * Choose a random address from new and attempt to connect to it if we can connect
1773 : // successfully it is added to tried.
1774 : // * Start attempting feeler connections only after node finishes making outbound
1775 : // connections.
1776 : // * Only make a feeler connection once every few minutes.
1777 : //
1778 37777 : bool fFeeler = false;
1779 37777 : if (nOutbound >= nMaxOutbound) {
1780 0 : int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
1781 0 : if (nTime > nNextFeeler) {
1782 0 : nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
1783 0 : fFeeler = true;
1784 : } else {
1785 0 : continue;
1786 : }
1787 : }
1788 :
1789 37777 : addrman.ResolveCollisions();
1790 :
1791 37777 : int64_t nANow = GetAdjustedTime();
1792 : int nTries = 0;
1793 38365 : while (!interruptNet) {
1794 38365 : CAddrInfo addr = addrman.SelectTriedCollision();
1795 :
1796 : // SelectTriedCollision returns an invalid address if it is empty.
1797 38365 : if (!fFeeler || !addr.IsValid()) {
1798 38365 : addr = addrman.Select(fFeeler);
1799 : }
1800 :
1801 : // Require outbound connections, other than feelers, to be to distinct network groups
1802 115095 : if (!fFeeler && setConnected.count(addr.GetGroup(addrman.m_asmap))) {
1803 : break;
1804 : }
1805 :
1806 : // if we selected an invalid or local address, restart
1807 9829 : if (!addr.IsValid() || IsLocal(addr)) {
1808 : break;
1809 : }
1810 :
1811 : // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1812 : // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1813 : // already-connected network ranges, ...) before trying new addrman addresses.
1814 600 : nTries++;
1815 600 : if (nTries > 100)
1816 : break;
1817 :
1818 600 : if (!IsReachable(addr))
1819 588 : continue;
1820 :
1821 : // only connect to full nodes
1822 600 : if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1823 0 : continue;
1824 :
1825 : // only consider very recently tried nodes after 30 failed attempts
1826 600 : if (nANow - addr.nLastTry < 600 && nTries < 30)
1827 261 : continue;
1828 :
1829 : // do not allow non-default ports, unless after 50 invalid addresses selected already
1830 339 : if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1831 327 : continue;
1832 :
1833 37789 : addrConnect = addr;
1834 : break;
1835 : }
1836 :
1837 37777 : if (addrConnect.IsValid()) {
1838 12 : if (fFeeler) {
1839 : // Add small amount of random noise before connection to avoid synchronization.
1840 0 : int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
1841 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
1842 0 : return;
1843 0 : LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
1844 : }
1845 :
1846 24 : OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler);
1847 : }
1848 : }
1849 : }
1850 :
1851 9713 : std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
1852 : {
1853 9713 : std::vector<AddedNodeInfo> ret;
1854 :
1855 9713 : std::list<std::string> lAddresses(0);
1856 9713 : {
1857 9713 : LOCK(cs_vAddedNodes);
1858 9713 : ret.reserve(vAddedNodes.size());
1859 9713 : std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
1860 : }
1861 :
1862 :
1863 : // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
1864 19426 : std::map<CService, bool> mapConnected;
1865 9713 : std::map<std::string, std::pair<bool, CService> > mapConnectedByName;
1866 9713 : {
1867 9713 : LOCK(cs_vNodes);
1868 55741 : for (const CNode* pnode : vNodes) {
1869 46028 : if (pnode->addr.IsValid()) {
1870 46028 : mapConnected[pnode->addr] = pnode->fInbound;
1871 : }
1872 92056 : std::string addrName = pnode->GetAddrName();
1873 46028 : if (!addrName.empty()) {
1874 46028 : mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1875 : }
1876 : }
1877 : }
1878 :
1879 9716 : for (const std::string& strAddNode : lAddresses) {
1880 6 : CService service(LookupNumeric(strAddNode, Params().GetDefaultPort()));
1881 6 : AddedNodeInfo addedNode{strAddNode, CService(), false, false};
1882 3 : if (service.IsValid()) {
1883 : // strAddNode is an IP:port
1884 3 : auto it = mapConnected.find(service);
1885 3 : if (it != mapConnected.end()) {
1886 0 : addedNode.resolvedAddress = service;
1887 0 : addedNode.fConnected = true;
1888 0 : addedNode.fInbound = it->second;
1889 : }
1890 : } else {
1891 : // strAddNode is a name
1892 0 : auto it = mapConnectedByName.find(strAddNode);
1893 0 : if (it != mapConnectedByName.end()) {
1894 0 : addedNode.resolvedAddress = it->second.second;
1895 0 : addedNode.fConnected = true;
1896 0 : addedNode.fInbound = it->second.first;
1897 : }
1898 : }
1899 3 : ret.emplace_back(std::move(addedNode));
1900 : }
1901 :
1902 19426 : return ret;
1903 : }
1904 :
1905 355 : void CConnman::ThreadOpenAddedConnections()
1906 : {
1907 9710 : while (true) {
1908 9710 : CSemaphoreGrant grant(*semAddnode);
1909 19065 : std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
1910 9710 : bool tried = false;
1911 9711 : for (const AddedNodeInfo& info : vInfo) {
1912 1 : if (!info.fConnected) {
1913 1 : if (!grant.TryAcquire()) {
1914 : // If we've used up our semaphore and need a new one, lets not wait here since while we are waiting
1915 : // the addednodeinfo state might change.
1916 : break;
1917 : }
1918 1 : tried = true;
1919 3 : CAddress addr(CService(), NODE_NONE);
1920 1 : OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
1921 1 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1922 0 : return;
1923 : }
1924 : }
1925 : // Retry every 60 seconds if a connection was attempted, otherwise two seconds
1926 19419 : if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
1927 : return;
1928 : }
1929 : }
1930 :
1931 : // if successful, this moves the passed grant to the constructed node
1932 748 : 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)
1933 : {
1934 : //
1935 : // Initiate outbound network connection
1936 : //
1937 748 : if (interruptNet || !fNetworkActive) {
1938 55 : return;
1939 : }
1940 748 : if (!pszDest) {
1941 24 : if (IsLocal(addrConnect) ||
1942 60 : FindNode(static_cast<CNetAddr>(addrConnect)) || IsBanned(addrConnect) ||
1943 36 : FindNode(addrConnect.ToStringIPPort()))
1944 : return;
1945 : } else {
1946 736 : CNode* pnode = FindNode(pszDest);
1947 736 : if (pnode) {
1948 : // If this is a mnauth connection and the node is already connected normally,
1949 : // disconnect it and open a new connection
1950 128 : if (masternode_connection && !pnode->m_masternode_connection) {
1951 86 : pnode->fDisconnect = true;
1952 : } else {
1953 42 : return;
1954 : }
1955 : }
1956 : }
1957 :
1958 706 : CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, fAddnode);
1959 :
1960 706 : if (!pnode)
1961 : return;
1962 693 : if (grantOutbound)
1963 0 : grantOutbound->MoveTo(pnode->grantOutbound);
1964 693 : if (fOneShot)
1965 0 : pnode->fOneShot = true;
1966 693 : if (fFeeler)
1967 0 : pnode->fFeeler = true;
1968 693 : if (fAddnode)
1969 0 : pnode->fAddnode = true;
1970 693 : if (masternode_connection)
1971 132 : pnode->m_masternode_connection = true;
1972 693 : if (masternode_probe_connection)
1973 49 : pnode->m_masternode_probe_connection = true;
1974 :
1975 693 : m_msgproc->InitializeNode(pnode);
1976 693 : {
1977 1386 : LOCK(cs_vNodes);
1978 693 : vNodes.push_back(pnode);
1979 : }
1980 : }
1981 :
1982 355 : void CConnman::ThreadMessageHandler()
1983 : {
1984 355 : int64_t nLastSendMessagesTimeMasternodes = 0;
1985 :
1986 386203 : while (!flagInterruptMsgProc) {
1987 771696 : std::vector<CNode*> vNodesCopy = CopyNodeVector();
1988 :
1989 385848 : bool fMoreWork = false;
1990 :
1991 : // Don't send other messages to quorum nodes too often
1992 385848 : bool fSkipSendMessagesForMasternodes = true;
1993 385848 : if (GetTimeMillis() - nLastSendMessagesTimeMasternodes >= 100) {
1994 180333 : fSkipSendMessagesForMasternodes = false;
1995 180333 : nLastSendMessagesTimeMasternodes = GetTimeMillis();
1996 : }
1997 :
1998 2423560 : for (CNode* pnode : vNodesCopy) {
1999 2037710 : if (pnode->fDisconnect)
2000 100 : continue;
2001 :
2002 : // Receive messages
2003 2037610 : bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
2004 2037610 : fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2005 2037610 : if (flagInterruptMsgProc)
2006 0 : return;
2007 :
2008 : // Send messages
2009 2037610 : if (!fSkipSendMessagesForMasternodes || !pnode->m_masternode_connection) {
2010 3911790 : LOCK(pnode->cs_sendProcessing);
2011 1955900 : m_msgproc->SendMessages(pnode, flagInterruptMsgProc);
2012 : }
2013 :
2014 2037610 : if (flagInterruptMsgProc)
2015 : return;
2016 : }
2017 :
2018 :
2019 385848 : ReleaseNodeVector(vNodesCopy);
2020 :
2021 771696 : std::unique_lock<std::mutex> lock(mutexMsgProc);
2022 385848 : if (!fMoreWork) {
2023 503002 : condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this] { return fMsgProcWake; });
2024 : }
2025 385848 : fMsgProcWake = false;
2026 : }
2027 : }
2028 :
2029 346 : bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, bool fWhitelisted)
2030 : {
2031 346 : strError = "";
2032 346 : int nOne = 1;
2033 :
2034 : // Create socket for listening for incoming connections
2035 346 : struct sockaddr_storage sockaddr;
2036 346 : socklen_t len = sizeof(sockaddr);
2037 346 : if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
2038 0 : strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
2039 0 : LogPrintf("%s\n", strError);
2040 0 : return false;
2041 : }
2042 :
2043 346 : SOCKET hListenSocket = CreateSocket(addrBind);
2044 346 : if (hListenSocket == INVALID_SOCKET) {
2045 0 : strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
2046 0 : LogPrintf("%s\n", strError);
2047 0 : return false;
2048 : }
2049 :
2050 : #ifndef WIN32
2051 : // Allow binding if the port is still in TIME_WAIT state after
2052 : // the program was closed and restarted. Not an issue on windows!
2053 346 : setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
2054 : #endif
2055 :
2056 : // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
2057 : // and enable it by default or not. Try to enable it, if possible.
2058 346 : if (addrBind.IsIPv6()) {
2059 : #ifdef IPV6_V6ONLY
2060 1 : setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
2061 : #endif
2062 : #ifdef WIN32
2063 : int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2064 : setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
2065 : #endif
2066 : }
2067 :
2068 346 : if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) {
2069 0 : int nErr = WSAGetLastError();
2070 0 : if (nErr == WSAEADDRINUSE)
2071 0 : strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
2072 : else
2073 0 : strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
2074 0 : LogPrintf("%s\n", strError);
2075 0 : CloseSocket(hListenSocket);
2076 0 : return false;
2077 : }
2078 346 : LogPrintf("Bound to %s\n", addrBind.ToString());
2079 :
2080 : // Listen for incoming connections
2081 346 : if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) {
2082 0 : strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
2083 0 : LogPrintf("%s\n", strError);
2084 0 : CloseSocket(hListenSocket);
2085 0 : return false;
2086 : }
2087 :
2088 346 : vhListenSocket.emplace_back(hListenSocket, fWhitelisted);
2089 :
2090 346 : if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
2091 0 : AddLocal(addrBind, LOCAL_BIND);
2092 :
2093 : return true;
2094 : }
2095 :
2096 355 : void Discover()
2097 : {
2098 355 : if (!fDiscover)
2099 355 : return;
2100 :
2101 : #ifdef WIN32
2102 : // Get local host IP
2103 : char pszHostName[256] = "";
2104 : if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) {
2105 : std::vector<CNetAddr> vaddr;
2106 : if (LookupHost(pszHostName, vaddr, 0, true)) {
2107 : for (const CNetAddr& addr : vaddr) {
2108 : if (AddLocal(addr, LOCAL_IF))
2109 : LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2110 : }
2111 : }
2112 : }
2113 : #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2114 : // Get local host ip
2115 0 : struct ifaddrs* myaddrs;
2116 0 : if (getifaddrs(&myaddrs) == 0) {
2117 0 : for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next) {
2118 0 : if (ifa->ifa_addr == nullptr) continue;
2119 0 : if ((ifa->ifa_flags & IFF_UP) == 0) continue;
2120 0 : if (strcmp(ifa->ifa_name, "lo") == 0) continue;
2121 0 : if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
2122 0 : if (ifa->ifa_addr->sa_family == AF_INET) {
2123 0 : struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
2124 0 : CNetAddr addr(s4->sin_addr);
2125 0 : if (AddLocal(addr, LOCAL_IF))
2126 0 : LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2127 0 : } else if (ifa->ifa_addr->sa_family == AF_INET6) {
2128 0 : struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
2129 0 : CNetAddr addr(s6->sin6_addr);
2130 0 : if (AddLocal(addr, LOCAL_IF))
2131 0 : LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2132 : }
2133 : }
2134 0 : freeifaddrs(myaddrs);
2135 : }
2136 : #endif
2137 : }
2138 :
2139 19 : void CConnman::SetNetworkActive(bool active)
2140 : {
2141 19 : LogPrint(BCLog::NET, "SetNetworkActive: %s\n", active);
2142 :
2143 19 : if (fNetworkActive == active) {
2144 : return;
2145 : }
2146 :
2147 19 : fNetworkActive = active;
2148 :
2149 19 : if (clientInterface) clientInterface->NotifyNetworkActiveChanged(fNetworkActive);
2150 : }
2151 :
2152 968 : CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In)
2153 : {
2154 484 : setBannedIsDirty = false;
2155 484 : fAddressesInitialized = false;
2156 484 : nLastNodeId = 0;
2157 484 : nPrevNodeCount = 0;
2158 484 : nSendBufferMaxSize = 0;
2159 484 : nReceiveFloodSize = 0;
2160 484 : flagInterruptMsgProc = false;
2161 :
2162 484 : Options connOptions;
2163 484 : Init(connOptions);
2164 : // init tier two connections manager
2165 484 : m_tiertwo_conn_man = std::make_unique<TierTwoConnMan>(this);
2166 484 : }
2167 :
2168 1456 : NodeId CConnman::GetNewNodeId()
2169 : {
2170 1456 : return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2171 : }
2172 :
2173 346 : bool CConnman::Bind(const CService& addr, unsigned int flags) {
2174 346 : if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
2175 : return false;
2176 692 : std::string strError;
2177 346 : if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
2178 0 : if ((flags & BF_REPORT_ERROR) && clientInterface) {
2179 0 : clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
2180 : }
2181 0 : return false;
2182 : }
2183 : return true;
2184 : }
2185 :
2186 345 : bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) {
2187 345 : bool fBound = false;
2188 689 : for (const auto& addrBind : binds) {
2189 344 : fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
2190 : }
2191 345 : for (const auto& addrBind : whiteBinds) {
2192 0 : fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
2193 : }
2194 345 : if (binds.empty() && whiteBinds.empty()) {
2195 1 : struct in_addr inaddr_any;
2196 1 : inaddr_any.s_addr = INADDR_ANY;
2197 1 : fBound |= Bind(CService((in6_addr)IN6ADDR_ANY_INIT, GetListenPort()), BF_NONE);
2198 1 : fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
2199 : }
2200 345 : return fBound;
2201 : }
2202 :
2203 355 : bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
2204 : {
2205 355 : Init(connOptions);
2206 :
2207 355 : {
2208 355 : LOCK(cs_totalBytesRecv);
2209 355 : nTotalBytesRecv = 0;
2210 : }
2211 355 : {
2212 355 : LOCK(cs_totalBytesSent);
2213 355 : nTotalBytesSent = 0;
2214 : }
2215 :
2216 355 : if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
2217 0 : if (clientInterface) {
2218 0 : clientInterface->ThreadSafeMessageBox(
2219 0 : _("Failed to listen on any port. Use -listen=0 if you want this."),
2220 : "", CClientUIInterface::MSG_ERROR);
2221 : }
2222 0 : return false;
2223 : }
2224 :
2225 355 : for (const auto& strDest : connOptions.vSeedNodes) {
2226 0 : AddOneShot(strDest);
2227 : }
2228 :
2229 355 : if (clientInterface)
2230 710 : clientInterface->InitMessage(_("Loading addresses..."));
2231 355 : m_msgproc = connOptions.m_msgproc;
2232 : // Load addresses from peers.dat
2233 355 : int64_t nStart = GetTimeMillis();
2234 355 : {
2235 355 : CAddrDB adb;
2236 355 : if (adb.Read(addrman))
2237 85 : LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
2238 : else {
2239 270 : addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2240 270 : LogPrintf("Invalid or missing peers.dat; recreating\n");
2241 270 : DumpAddresses();
2242 : }
2243 : }
2244 355 : if (clientInterface)
2245 710 : clientInterface->InitMessage(_("Loading banlist..."));
2246 : // Load addresses from banlist.dat
2247 355 : nStart = GetTimeMillis();
2248 710 : CBanDB bandb;
2249 710 : banmap_t banmap;
2250 355 : if (bandb.Read(banmap)) {
2251 86 : SetBanned(banmap); // thread save setter
2252 86 : SetBannedSetDirty(false); // no need to write down, just read data
2253 86 : SweepBanned(); // sweep out unused entries
2254 :
2255 86 : LogPrint(BCLog::NET, "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
2256 : banmap.size(), GetTimeMillis() - nStart);
2257 : } else {
2258 269 : LogPrintf("Invalid or missing banlist.dat; recreating\n");
2259 269 : SetBannedSetDirty(true); // force write
2260 269 : DumpBanlist();
2261 : }
2262 :
2263 : // Initialize random numbers. Even when rand() is only usable for trivial use-cases most nodes should have a different
2264 : // seed after all the file-IO done at this point. Should be good enough even when nodes are started via scripts.
2265 355 : srand(time(nullptr));
2266 :
2267 355 : fAddressesInitialized = true;
2268 :
2269 355 : if (semOutbound == nullptr) {
2270 : // initialize semaphore
2271 355 : semOutbound = std::make_unique<CSemaphore>(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
2272 : }
2273 355 : if (semAddnode == nullptr) {
2274 : // initialize semaphore
2275 355 : semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
2276 : }
2277 :
2278 : //
2279 : // Start threads
2280 : //
2281 355 : assert(m_msgproc);
2282 355 : InterruptSocks5(false);
2283 355 : interruptNet.reset();
2284 355 : flagInterruptMsgProc = false;
2285 :
2286 355 : {
2287 355 : std::unique_lock<std::mutex> lock(mutexMsgProc);
2288 355 : fMsgProcWake = false;
2289 : }
2290 :
2291 : #ifdef USE_WAKEUP_PIPE
2292 355 : if (pipe(wakeupPipe) != 0) {
2293 0 : wakeupPipe[0] = wakeupPipe[1] = -1;
2294 0 : LogPrint(BCLog::NET, "pipe() for wakeupPipe failed\n");
2295 : } else {
2296 355 : int fFlags = fcntl(wakeupPipe[0], F_GETFL, 0);
2297 355 : if (fcntl(wakeupPipe[0], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2298 0 : LogPrint(BCLog::NET, "fcntl for O_NONBLOCK on wakeupPipe failed\n");
2299 : }
2300 355 : fFlags = fcntl(wakeupPipe[1], F_GETFL, 0);
2301 355 : if (fcntl(wakeupPipe[1], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2302 0 : LogPrint(BCLog::NET, "fcntl for O_NONBLOCK on wakeupPipe failed\n");
2303 : }
2304 : }
2305 : #endif
2306 :
2307 : // Send and receive from sockets, accept connections
2308 355 : threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
2309 :
2310 355 : if (!gArgs.GetBoolArg("-dnsseed", true))
2311 0 : LogPrintf("DNS seeding disabled\n");
2312 : else
2313 355 : threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
2314 :
2315 : // Initiate outbound connections from -addnode
2316 355 : threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
2317 :
2318 : // Start tier two connection manager
2319 355 : if (m_tiertwo_conn_man) {
2320 355 : TierTwoConnMan::Options opts;
2321 355 : opts.m_has_specified_outgoing = !connOptions.m_specified_outgoing.empty();
2322 355 : m_tiertwo_conn_man->start(scheduler, opts);
2323 : }
2324 :
2325 355 : if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2326 0 : if (clientInterface) {
2327 0 : clientInterface->ThreadSafeMessageBox(
2328 0 : _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
2329 : "", CClientUIInterface::MSG_ERROR);
2330 : }
2331 0 : return false;
2332 : }
2333 355 : if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) {
2334 710 : threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(
2335 1065 : std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
2336 : }
2337 :
2338 : // Process messages
2339 355 : threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
2340 :
2341 : // Dump network addresses
2342 355 : scheduler.scheduleEvery(std::bind(&CConnman::DumpData, this), DUMP_ADDRESSES_INTERVAL * 1000);
2343 :
2344 355 : return true;
2345 : }
2346 :
2347 : class CNetCleanup
2348 : {
2349 : public:
2350 0 : CNetCleanup() {}
2351 :
2352 479 : ~CNetCleanup()
2353 : {
2354 : #ifdef WIN32
2355 : // Shutdown Windows Sockets
2356 : WSACleanup();
2357 : #endif
2358 479 : }
2359 : }
2360 : instance_of_cnetcleanup;
2361 :
2362 0 : void CExplicitNetCleanup::callCleanup()
2363 : {
2364 : // Explicit call to destructor of CNetCleanup because it's not implicitly called
2365 : // when the wallet is restarted from within the wallet itself.
2366 0 : CNetCleanup* tmp = new CNetCleanup();
2367 0 : delete tmp; // Stroustrup's gonna kill me for that
2368 0 : }
2369 :
2370 850 : void CConnman::Interrupt()
2371 : {
2372 850 : {
2373 850 : std::lock_guard<std::mutex> lock(mutexMsgProc);
2374 850 : flagInterruptMsgProc = true;
2375 : }
2376 850 : condMsgProc.notify_all();
2377 :
2378 850 : interruptNet();
2379 850 : if (m_tiertwo_conn_man) m_tiertwo_conn_man->interrupt();
2380 850 : InterruptSocks5(true);
2381 :
2382 850 : if (semOutbound) {
2383 6390 : for (int i=0; i<(nMaxOutbound + nMaxFeeler); i++) {
2384 6035 : semOutbound->post();
2385 : }
2386 : }
2387 :
2388 850 : if (semAddnode) {
2389 6035 : for (int i=0; i<nMaxAddnode; i++) {
2390 5680 : semAddnode->post();
2391 : }
2392 : }
2393 850 : }
2394 :
2395 850 : void CConnman::Stop()
2396 : {
2397 850 : if (threadMessageHandler.joinable())
2398 355 : threadMessageHandler.join();
2399 850 : if (threadOpenConnections.joinable())
2400 355 : threadOpenConnections.join();
2401 850 : if (threadOpenAddedConnections.joinable())
2402 355 : threadOpenAddedConnections.join();
2403 850 : if (threadDNSAddressSeed.joinable())
2404 355 : threadDNSAddressSeed.join();
2405 850 : if (threadSocketHandler.joinable())
2406 355 : threadSocketHandler.join();
2407 : // Stop tier two connection manager
2408 850 : if (m_tiertwo_conn_man) m_tiertwo_conn_man->stop();
2409 :
2410 850 : if (fAddressesInitialized)
2411 : {
2412 355 : DumpData();
2413 355 : fAddressesInitialized = false;
2414 : }
2415 :
2416 : // Close sockets
2417 1630 : for(CNode* pnode : vNodes)
2418 780 : pnode->CloseSocketDisconnect();
2419 1196 : for(ListenSocket& hListenSocket : vhListenSocket)
2420 346 : if (hListenSocket.socket != INVALID_SOCKET)
2421 346 : if (!CloseSocket(hListenSocket.socket))
2422 0 : LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2423 :
2424 : // clean up some globals (to help leak detection)
2425 1630 : for(CNode* pnode : vNodes) {
2426 780 : DeleteNode(pnode);
2427 : }
2428 850 : for(CNode* pnode : vNodesDisconnected) {
2429 0 : DeleteNode(pnode);
2430 : }
2431 850 : vNodes.clear();
2432 850 : vNodesDisconnected.clear();
2433 850 : vhListenSocket.clear();
2434 850 : semOutbound.reset();
2435 850 : semAddnode.reset();
2436 : #ifdef USE_WAKEUP_PIPE
2437 850 : if (wakeupPipe[0] != -1) close(wakeupPipe[0]);
2438 850 : if (wakeupPipe[1] != -1) close(wakeupPipe[1]);
2439 850 : wakeupPipe[0] = wakeupPipe[1] = -1;
2440 : #endif
2441 850 : }
2442 :
2443 1456 : void CConnman::DeleteNode(CNode* pnode)
2444 : {
2445 1456 : assert(pnode);
2446 1456 : bool fUpdateConnectionTime = false;
2447 1456 : m_msgproc->FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
2448 1456 : if (fUpdateConnectionTime) {
2449 642 : addrman.Connected(pnode->addr);
2450 : }
2451 1456 : delete pnode;
2452 1456 : }
2453 :
2454 1077 : CConnman::~CConnman()
2455 : {
2456 484 : Interrupt();
2457 484 : Stop();
2458 484 : }
2459 :
2460 648 : void CConnman::SetServices(const CService &addr, ServiceFlags nServices)
2461 : {
2462 648 : addrman.SetServices(addr, nServices);
2463 648 : }
2464 :
2465 648 : void CConnman::MarkAddressGood(const CAddress& addr)
2466 : {
2467 648 : addrman.Good(addr);
2468 648 : }
2469 :
2470 66 : void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty)
2471 : {
2472 66 : addrman.Add(addr, addrFrom, nTimePenalty);
2473 66 : }
2474 :
2475 10010 : bool CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
2476 : {
2477 10010 : return addrman.Add(vAddr, addrFrom, nTimePenalty);
2478 : }
2479 :
2480 654 : std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, Optional<Network> network)
2481 : {
2482 654 : return addrman.GetAddr(max_addresses, max_pct, network);
2483 : }
2484 :
2485 1 : bool CConnman::AddNode(const std::string& strNode)
2486 : {
2487 2 : LOCK(cs_vAddedNodes);
2488 1 : for (const std::string& it : vAddedNodes) {
2489 0 : if (strNode == it) return false;
2490 : }
2491 :
2492 1 : vAddedNodes.push_back(strNode);
2493 : return true;
2494 : }
2495 :
2496 0 : bool CConnman::RemoveAddedNode(const std::string& strNode)
2497 : {
2498 0 : LOCK(cs_vAddedNodes);
2499 0 : for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2500 0 : if (strNode == *it) {
2501 0 : vAddedNodes.erase(it);
2502 0 : return true;
2503 : }
2504 : }
2505 0 : return false;
2506 : }
2507 :
2508 226 : size_t CConnman::GetMaxOutboundNodeCount()
2509 : {
2510 226 : return nMaxOutbound;
2511 : }
2512 :
2513 1787 : size_t CConnman::GetNodeCount(NumConnections flags)
2514 : {
2515 1787 : LOCK(cs_vNodes);
2516 1787 : if (flags == CConnman::CONNECTIONS_ALL) // Shortcut if we want total
2517 1787 : return vNodes.size();
2518 :
2519 0 : int nNum = 0;
2520 0 : for (const auto& pnode : vNodes) {
2521 0 : if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
2522 0 : nNum++;
2523 : }
2524 : }
2525 :
2526 0 : return nNum;
2527 : }
2528 :
2529 16992 : void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
2530 : {
2531 16992 : vstats.clear();
2532 16992 : LOCK(cs_vNodes);
2533 16992 : vstats.reserve(vNodes.size());
2534 78365 : for (CNode* pnode : vNodes) {
2535 61373 : vstats.emplace_back();
2536 61373 : pnode->copyStats(vstats.back(), addrman.m_asmap);
2537 : }
2538 16992 : }
2539 :
2540 25 : bool CConnman::DisconnectNode(const std::string& strNode)
2541 : {
2542 50 : LOCK(cs_vNodes);
2543 25 : if (CNode* pnode = FindNode(strNode)) {
2544 24 : pnode->fDisconnect = true;
2545 24 : return true;
2546 : }
2547 : return false;
2548 : }
2549 :
2550 0 : bool CConnman::DisconnectNode(NodeId id)
2551 : {
2552 0 : LOCK(cs_vNodes);
2553 0 : for(CNode* pnode : vNodes) {
2554 0 : if (id == pnode->GetId()) {
2555 0 : pnode->fDisconnect = true;
2556 0 : return true;
2557 : }
2558 : }
2559 0 : return false;
2560 : }
2561 :
2562 15462 : void CConnman::RelayInv(CInv& inv, int minProtoVersion)
2563 : {
2564 15462 : LOCK(cs_vNodes);
2565 60344 : for (CNode* pnode : vNodes){
2566 44882 : if (!pnode->fSuccessfullyConnected) continue;
2567 44872 : if ((pnode->nServices == NODE_BLOOM_WITHOUT_MN) && inv.IsMasterNodeType()) continue;
2568 44872 : if (!pnode->CanRelay()) continue;
2569 44860 : if (pnode->nVersion >= minProtoVersion)
2570 44860 : pnode->PushInventory(inv);
2571 : }
2572 15462 : }
2573 :
2574 56830 : void CConnman::RemoveAskFor(const uint256& invHash, int invType)
2575 : {
2576 56830 : mapAlreadyAskedFor.erase(CInv(invType, invHash));
2577 :
2578 56830 : LOCK(cs_vNodes);
2579 152474 : for (const auto& pnode : vNodes) {
2580 95644 : pnode->AskForInvReceived(invHash);
2581 : }
2582 56830 : }
2583 :
2584 108 : void CConnman::UpdateQuorumRelayMemberIfNeeded(CNode* pnode)
2585 : {
2586 113 : if (!pnode->m_masternode_iqr_connection && pnode->m_masternode_connection &&
2587 118 : m_tiertwo_conn_man->isMasternodeQuorumRelayMember(WITH_LOCK(pnode->cs_mnauth, return pnode->verifiedProRegTxHash))) {
2588 0 : pnode->m_masternode_iqr_connection = true;
2589 : }
2590 108 : }
2591 :
2592 344736 : void CConnman::RecordBytesRecv(uint64_t bytes)
2593 : {
2594 344736 : LOCK(cs_totalBytesRecv);
2595 344736 : nTotalBytesRecv += bytes;
2596 344736 : }
2597 :
2598 288071 : void CConnman::RecordBytesSent(uint64_t bytes)
2599 : {
2600 288071 : LOCK(cs_totalBytesSent);
2601 288071 : nTotalBytesSent += bytes;
2602 288071 : }
2603 :
2604 5 : uint64_t CConnman::GetTotalBytesRecv()
2605 : {
2606 5 : LOCK(cs_totalBytesRecv);
2607 5 : return nTotalBytesRecv;
2608 : }
2609 :
2610 5 : uint64_t CConnman::GetTotalBytesSent()
2611 : {
2612 5 : LOCK(cs_totalBytesSent);
2613 5 : return nTotalBytesSent;
2614 : }
2615 :
2616 1230 : ServiceFlags CConnman::GetLocalServices() const
2617 : {
2618 1230 : return nLocalServices;
2619 : }
2620 :
2621 38794 : void CConnman::SetBestHeight(int height)
2622 : {
2623 38794 : nBestHeight.store(height, std::memory_order_release);
2624 38794 : }
2625 :
2626 1456 : int CConnman::GetBestHeight() const
2627 : {
2628 1456 : return nBestHeight.load(std::memory_order_acquire);
2629 : }
2630 :
2631 378830 : unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
2632 0 : unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
2633 :
2634 1464 : 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) :
2635 1464 : nTimeConnected(GetSystemTimeInSeconds()),
2636 : addr(addrIn),
2637 : fInbound(fInboundIn),
2638 : nKeyedNetGroup(nKeyedNetGroupIn),
2639 : addrKnown(5000, 0.001),
2640 : filterInventoryKnown(50000, 0.000001),
2641 : id(idIn),
2642 : nLocalHostNonce(nLocalHostNonceIn),
2643 : nLocalServices(nLocalServicesIn),
2644 : nMyStartingHeight(nMyStartingHeightIn),
2645 10248 : nSendVersion(0)
2646 : {
2647 1464 : nServices = NODE_NONE;
2648 1464 : nServicesExpected = NODE_NONE;
2649 1464 : hSocket = hSocketIn;
2650 1464 : nRecvVersion = INIT_PROTO_VERSION;
2651 1464 : nLastSend = 0;
2652 1464 : nLastRecv = 0;
2653 1464 : nSendBytes = 0;
2654 1464 : nRecvBytes = 0;
2655 1464 : nTimeOffset = 0;
2656 2157 : addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2657 1464 : nVersion = 0;
2658 1464 : strSubVer = "";
2659 1464 : fWhitelisted = false;
2660 1464 : fOneShot = false;
2661 1464 : fAddnode = false;
2662 1464 : m_masternode_connection = false;
2663 1464 : fClient = false; // set by version message
2664 1464 : fFeeler = false;
2665 1464 : fSuccessfullyConnected = false;
2666 1464 : fDisconnect = false;
2667 1464 : nRefCount = 0;
2668 1464 : nSendSize = 0;
2669 1464 : nSendOffset = 0;
2670 1464 : hashContinue = UINT256_ZERO;
2671 1464 : nStartingHeight = -1;
2672 1464 : filterInventoryKnown.reset();
2673 1464 : fSendMempool = false;
2674 1464 : fGetAddr = false;
2675 1464 : fRelayTxes = false;
2676 1464 : pfilter = std::make_unique<CBloomFilter>();
2677 1464 : timeLastMempoolReq = 0;
2678 1464 : nPingNonceSent = 0;
2679 1464 : nPingUsecStart = 0;
2680 1464 : nPingUsecTime = 0;
2681 1464 : fPingQueued = false;
2682 1464 : nMinPingUsecTime = std::numeric_limits<int64_t>::max();
2683 1464 : fPauseRecv = false;
2684 1464 : fPauseSend = false;
2685 1464 : nProcessQueueSize = 0;
2686 :
2687 84912 : for (const std::string &msg : getAllNetMessageTypes())
2688 83448 : mapRecvBytesPerMsgCmd[msg] = 0;
2689 1464 : mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
2690 :
2691 1464 : if (fLogIPs)
2692 0 : LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
2693 : else
2694 1464 : LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
2695 1464 : }
2696 :
2697 10584 : CNode::~CNode()
2698 : {
2699 1464 : CloseSocket(hSocket);
2700 1464 : }
2701 :
2702 71263 : void CNode::AskFor(const CInv& inv, int64_t doubleRequestDelay)
2703 : {
2704 71263 : if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
2705 12 : return;
2706 : // a peer may not have multiple non-responded queue positions for a single inv item
2707 71263 : if (!setAskFor.insert(inv.hash).second)
2708 : return;
2709 :
2710 : // We're using mapAskFor as a priority queue,
2711 : // the key is the earliest time the request can be sent
2712 71251 : int64_t nRequestTime;
2713 71251 : limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
2714 71251 : if (it != mapAlreadyAskedFor.end())
2715 5397 : nRequestTime = it->second;
2716 : else
2717 65854 : nRequestTime = 0;
2718 142502 : LogPrint(BCLog::NET, "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, FormatISO8601Time(nRequestTime / 1000000), id);
2719 :
2720 : // Make sure not to reuse time indexes to keep things in the same order
2721 71251 : int64_t nNow = GetTimeMicros() - 1000000;
2722 71251 : static int64_t nLastTime;
2723 71251 : ++nLastTime;
2724 71251 : nNow = std::max(nNow, nLastTime);
2725 71251 : nLastTime = nNow;
2726 :
2727 : // Each retry is 2 minutes after the last
2728 71251 : nRequestTime = std::max(nRequestTime + doubleRequestDelay, nNow);
2729 71251 : if (it != mapAlreadyAskedFor.end())
2730 5397 : mapAlreadyAskedFor.update(it, nRequestTime);
2731 : else
2732 65854 : mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2733 71251 : mapAskFor.insert(std::make_pair(nRequestTime, inv));
2734 : }
2735 :
2736 95644 : void CNode::AskForInvReceived(const uint256& invHash)
2737 : {
2738 95644 : setAskFor.erase(invHash);
2739 95644 : for (auto it = mapAskFor.begin(); it != mapAskFor.end();) {
2740 26673 : if (it->second.hash == invHash) {
2741 4989 : it = mapAskFor.erase(it);
2742 : } else {
2743 144001 : ++it;
2744 : }
2745 : }
2746 95644 : }
2747 :
2748 959341 : bool CConnman::NodeFullyConnected(const CNode* pnode)
2749 : {
2750 959341 : return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
2751 : }
2752 :
2753 329466 : void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg, bool allowOptimisticSend)
2754 : {
2755 329466 : size_t nMessageSize = msg.data.size();
2756 329466 : size_t nTotalSize = nMessageSize + CMessageHeader::HEADER_SIZE;
2757 653124 : LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", SanitizeString(msg.command.c_str()), nMessageSize, pnode->GetId());
2758 :
2759 329466 : std::vector<unsigned char> serializedHeader;
2760 329466 : serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
2761 329466 : uint256 hash = Hash(msg.data.data(), msg.data.data() + nMessageSize);
2762 329466 : CMessageHeader hdr(Params().MessageStart(), msg.command.c_str(), nMessageSize);
2763 329466 : memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
2764 :
2765 329466 : CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, serializedHeader, 0, hdr};
2766 :
2767 329466 : size_t nBytesSent = 0;
2768 329466 : {
2769 329466 : LOCK(pnode->cs_vSend);
2770 329466 : bool hasPendingData = !pnode->vSendMsg.empty();
2771 329466 : bool optimisticSend(allowOptimisticSend && pnode->vSendMsg.empty());
2772 :
2773 : //log total amount of bytes per command
2774 329466 : pnode->mapSendBytesPerMsgCmd[msg.command] += nTotalSize;
2775 329466 : pnode->nSendSize += nTotalSize;
2776 :
2777 329466 : if (pnode->nSendSize > nSendBufferMaxSize)
2778 8 : pnode->fPauseSend = true;
2779 329466 : pnode->vSendMsg.push_back(std::move(serializedHeader));
2780 329466 : if (nMessageSize)
2781 324574 : pnode->vSendMsg.push_back(std::move(msg.data));
2782 :
2783 : // If write queue empty, attempt "optimistic write"
2784 329466 : if (optimisticSend == true)
2785 0 : nBytesSent = SocketSendData(pnode);
2786 : // wake up select() call in case there was no pending data before (so it was not selecting this socket for sending)
2787 329466 : else if (!hasPendingData && wakeupSelectNeeded)
2788 206411 : WakeSelect();
2789 : }
2790 329466 : if (nBytesSent)
2791 0 : RecordBytesSent(nBytesSent);
2792 329466 : }
2793 :
2794 0 : bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
2795 : {
2796 0 : CNode* found = nullptr;
2797 0 : LOCK(cs_vNodes);
2798 0 : for (auto&& pnode : vNodes) {
2799 0 : if(pnode->GetId() == id) {
2800 : found = pnode;
2801 : break;
2802 : }
2803 : }
2804 0 : return found != nullptr && NodeFullyConnected(found) && func(found);
2805 : }
2806 :
2807 132 : bool CConnman::ForNode(const CService& addr, const std::function<bool(const CNode* pnode)>& cond, const std::function<bool(CNode* pnode)>& func)
2808 : {
2809 132 : CNode* found = nullptr;
2810 132 : LOCK(cs_vNodes);
2811 1088 : for (auto&& pnode : vNodes) {
2812 1088 : if(static_cast<CService>(pnode->addr) == addr) {
2813 132 : found = pnode;
2814 132 : break;
2815 : }
2816 : }
2817 327 : return found != nullptr && cond(found) && func(found);
2818 : }
2819 :
2820 20 : bool CConnman::IsNodeConnected(const CAddress& addr)
2821 : {
2822 20 : return FindNode(addr.ToStringIPPort());
2823 : }
2824 :
2825 20 : CNode* CConnman::ConnectNode(const CAddress& addrConnect)
2826 : {
2827 20 : return ConnectNode(addrConnect, nullptr, true, true);
2828 : }
2829 :
2830 : // valid, reachable and routable address (except for RegTest)
2831 17 : bool validateMasternodeIP(const std::string& addrStr)
2832 : {
2833 34 : CNetAddr resolved;
2834 17 : if (LookupHost(addrStr, resolved, false)) {
2835 12 : return ((IsReachable(resolved) && resolved.IsRoutable()) ||
2836 2 : (Params().IsRegTestNet() && resolved.IsValid()));
2837 : }
2838 : return false;
2839 : }
2840 :
2841 56995 : int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
2842 56995 : return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
2843 : }
2844 :
2845 1528450 : std::vector<CNode*> CConnman::CopyNodeVector(std::function<bool(const CNode* pnode)> cond)
2846 : {
2847 1528450 : std::vector<CNode*> vecNodesCopy;
2848 1528450 : LOCK(cs_vNodes);
2849 12290800 : for (size_t i = 0; i < vNodes.size(); ++i) {
2850 10762300 : CNode* pnode = vNodes[i];
2851 10762300 : if (!cond(pnode))
2852 1162 : continue;
2853 10761100 : pnode->AddRef();
2854 10761100 : vecNodesCopy.push_back(pnode);
2855 : }
2856 3056900 : return vecNodesCopy;
2857 : }
2858 :
2859 1435050 : std::vector<CNode*> CConnman::CopyNodeVector()
2860 : {
2861 2870110 : return CopyNodeVector(AllNodes);
2862 : }
2863 :
2864 1528450 : void CConnman::ReleaseNodeVector(const std::vector<CNode*>& vecNodes)
2865 : {
2866 12289600 : for (size_t i = 0; i < vecNodes.size(); ++i) {
2867 10761100 : CNode* pnode = vecNodes[i];
2868 10761100 : pnode->Release();
2869 : }
2870 1528450 : }
2871 :
2872 2933 : CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id)
2873 : {
2874 2933 : return CSipHasher(nSeed0, nSeed1).Write(id);
2875 : }
2876 :
2877 1456 : uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad)
2878 : {
2879 1456 : std::vector<unsigned char> vchNetGroup(ad.GetGroup(addrman.m_asmap));
2880 :
2881 2912 : return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
2882 : }
2883 :
|