Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2020 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #if defined(HAVE_CONFIG_H)
7 : #include <config/bitcoin-config.h>
8 : #endif
9 :
10 : #include <net.h>
11 :
12 : #include <banman.h>
13 : #include <chainparams.h>
14 : #include <clientversion.h>
15 : #include <consensus/consensus.h>
16 : #include <crypto/sha256.h>
17 : #include <net_permissions.h>
18 : #include <netbase.h>
19 : #include <node/ui_interface.h>
20 : #include <protocol.h>
21 : #include <random.h>
22 : #include <scheduler.h>
23 : #include <util/strencodings.h>
24 : #include <util/translation.h>
25 :
26 : #ifdef WIN32
27 : #include <string.h>
28 : #else
29 : #include <fcntl.h>
30 : #endif
31 :
32 : #ifdef USE_POLL
33 : #include <poll.h>
34 : #endif
35 :
36 : #ifdef USE_UPNP
37 : #include <miniupnpc/miniupnpc.h>
38 : #include <miniupnpc/upnpcommands.h>
39 : #include <miniupnpc/upnperrors.h>
40 : // The minimum supported miniUPnPc API version is set to 10. This keeps compatibility
41 : // with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages.
42 : static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed");
43 : #endif
44 :
45 : #include <cstdint>
46 : #include <unordered_map>
47 :
48 : #include <math.h>
49 :
50 : // How often to dump addresses to peers.dat
51 : static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
52 :
53 : /** Number of DNS seeds to query when the number of connections is low. */
54 : static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
55 :
56 : /** How long to delay before querying DNS seeds
57 : *
58 : * If we have more than THRESHOLD entries in addrman, then it's likely
59 : * that we got those addresses from having previously connected to the P2P
60 : * network, and that we'll be able to successfully reconnect to the P2P
61 : * network via contacting one of them. So if that's the case, spend a
62 : * little longer trying to connect to known peers before querying the
63 : * DNS seeds.
64 : */
65 : static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
66 : static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
67 : static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000; // "many" vs "few" peers
68 :
69 : // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
70 : #define FEELER_SLEEP_WINDOW 1
71 :
72 : // MSG_NOSIGNAL is not available on some platforms, if it doesn't exist define it as 0
73 : #if !defined(MSG_NOSIGNAL)
74 : #define MSG_NOSIGNAL 0
75 : #endif
76 :
77 : // MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0
78 : #if !defined(MSG_DONTWAIT)
79 : #define MSG_DONTWAIT 0
80 : #endif
81 :
82 : /** Used to pass flags to the Bind() function */
83 : enum BindFlags {
84 : BF_NONE = 0,
85 : BF_EXPLICIT = (1U << 0),
86 : BF_REPORT_ERROR = (1U << 1),
87 : };
88 :
89 : // The set of sockets cannot be modified while waiting
90 : // The sleep time needs to be small to avoid new sockets stalling
91 : static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
92 :
93 640 : const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
94 :
95 : static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
96 : static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
97 : //
98 : // Global state variables
99 : //
100 : bool fDiscover = true;
101 : bool fListen = true;
102 : bool g_relay_txes = !DEFAULT_BLOCKSONLY;
103 640 : RecursiveMutex cs_mapLocalHost;
104 640 : std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
105 : static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
106 640 : std::string strSubVersion;
107 :
108 0 : void CConnman::AddAddrFetch(const std::string& strDest)
109 : {
110 0 : LOCK(m_addr_fetches_mutex);
111 0 : m_addr_fetches.push_back(strDest);
112 0 : }
113 :
114 1318 : uint16_t GetListenPort()
115 : {
116 1318 : return (uint16_t)(gArgs.GetArg("-port", Params().GetDefaultPort()));
117 0 : }
118 :
119 : // find 'best' local address for a particular peer
120 816 : bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
121 : {
122 816 : if (!fListen)
123 0 : return false;
124 :
125 : int nBestScore = -1;
126 : int nBestReachability = -1;
127 : {
128 816 : LOCK(cs_mapLocalHost);
129 817 : for (const auto& entry : mapLocalHost)
130 : {
131 1 : int nScore = entry.second.nScore;
132 1 : int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
133 1 : if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
134 : {
135 1 : addr = CService(entry.first, entry.second.nPort);
136 : nBestReachability = nReachability;
137 : nBestScore = nScore;
138 1 : }
139 0 : }
140 816 : }
141 816 : return nBestScore >= 0;
142 816 : }
143 :
144 : //! Convert the pnSeed6 array into usable address objects.
145 63 : static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
146 : {
147 : // It'll only connect to one or two seed nodes because once it connects,
148 : // it'll get a pile of addresses with newer timestamps.
149 : // Seed nodes are given a random 'last seen time' of between one and two
150 : // weeks ago.
151 : const int64_t nOneWeek = 7*24*60*60;
152 63 : std::vector<CAddress> vSeedsOut;
153 63 : vSeedsOut.reserve(vSeedsIn.size());
154 63 : FastRandomContext rng;
155 63 : for (const auto& seed_in : vSeedsIn) {
156 0 : struct in6_addr ip;
157 0 : memcpy(&ip, seed_in.addr, sizeof(ip));
158 0 : CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE));
159 0 : addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
160 0 : vSeedsOut.push_back(addr);
161 0 : }
162 : return vSeedsOut;
163 63 : }
164 :
165 : // get best local address for a particular peer as a CAddress
166 : // Otherwise, return the unroutable 0.0.0.0 but filled in with
167 : // the normal parameters, since the IP may be changed to a useful
168 : // one by discovery.
169 816 : CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
170 : {
171 816 : CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices);
172 816 : CService addr;
173 816 : if (GetLocal(addr, paddrPeer))
174 : {
175 1 : ret = CAddress(addr, nLocalServices);
176 1 : }
177 816 : ret.nTime = GetAdjustedTime();
178 : return ret;
179 816 : }
180 :
181 0 : static int GetnScore(const CService& addr)
182 : {
183 0 : LOCK(cs_mapLocalHost);
184 0 : if (mapLocalHost.count(addr) == 0) return 0;
185 0 : return mapLocalHost[addr].nScore;
186 0 : }
187 :
188 : // Is our peer's addrLocal potentially useful as an external IP source?
189 816 : bool IsPeerAddrLocalGood(CNode *pnode)
190 : {
191 816 : CService addrLocal = pnode->GetAddrLocal();
192 816 : return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
193 1 : IsReachable(addrLocal.GetNetwork());
194 816 : }
195 :
196 : // pushes our own address to a peer
197 663 : void AdvertiseLocal(CNode *pnode)
198 : {
199 663 : if (fListen && pnode->fSuccessfullyConnected)
200 : {
201 663 : CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
202 663 : if (gArgs.GetBoolArg("-addrmantest", false)) {
203 : // use IPv4 loopback during addrmantest
204 5 : addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
205 5 : }
206 : // If discovery is enabled, sometimes give our peer the address it
207 : // tells us that it sees us as in case it has a better idea of our
208 : // address than we do.
209 663 : FastRandomContext rng;
210 663 : if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
211 0 : rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0))
212 : {
213 1 : addrLocal.SetIP(pnode->GetAddrLocal());
214 1 : }
215 663 : if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
216 : {
217 6 : LogPrint(BCLog::NET, "AdvertiseLocal: advertising address %s\n", addrLocal.ToString());
218 6 : pnode->PushAddress(addrLocal, rng);
219 : }
220 663 : }
221 663 : }
222 :
223 : // learn a new local address
224 1 : bool AddLocal(const CService& addr, int nScore)
225 : {
226 1 : if (!addr.IsRoutable())
227 0 : return false;
228 :
229 1 : if (!fDiscover && nScore < LOCAL_MANUAL)
230 0 : return false;
231 :
232 1 : if (!IsReachable(addr))
233 0 : return false;
234 :
235 1 : LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
236 :
237 : {
238 1 : LOCK(cs_mapLocalHost);
239 1 : bool fAlready = mapLocalHost.count(addr) > 0;
240 1 : LocalServiceInfo &info = mapLocalHost[addr];
241 1 : if (!fAlready || nScore >= info.nScore) {
242 1 : info.nScore = nScore + (fAlready ? 1 : 0);
243 1 : info.nPort = addr.GetPort();
244 1 : }
245 1 : }
246 :
247 1 : return true;
248 1 : }
249 :
250 0 : bool AddLocal(const CNetAddr &addr, int nScore)
251 : {
252 0 : return AddLocal(CService(addr, GetListenPort()), nScore);
253 0 : }
254 :
255 1 : void RemoveLocal(const CService& addr)
256 : {
257 1 : LOCK(cs_mapLocalHost);
258 1 : LogPrintf("RemoveLocal(%s)\n", addr.ToString());
259 1 : mapLocalHost.erase(addr);
260 1 : }
261 :
262 516 : void SetReachable(enum Network net, bool reachable)
263 : {
264 516 : if (net == NET_UNROUTABLE || net == NET_INTERNAL)
265 : return;
266 514 : LOCK(cs_mapLocalHost);
267 514 : vfLimited[net] = !reachable;
268 516 : }
269 :
270 10615 : bool IsReachable(enum Network net)
271 : {
272 10615 : LOCK(cs_mapLocalHost);
273 10615 : return !vfLimited[net];
274 10615 : }
275 :
276 10337 : bool IsReachable(const CNetAddr &addr)
277 : {
278 10337 : return IsReachable(addr.GetNetwork());
279 : }
280 :
281 : /** vote for a local address */
282 0 : bool SeenLocal(const CService& addr)
283 : {
284 : {
285 0 : LOCK(cs_mapLocalHost);
286 0 : if (mapLocalHost.count(addr) == 0)
287 0 : return false;
288 0 : mapLocalHost[addr].nScore++;
289 0 : }
290 0 : return true;
291 0 : }
292 :
293 :
294 : /** check whether a given address is potentially local */
295 334 : bool IsLocal(const CService& addr)
296 : {
297 334 : LOCK(cs_mapLocalHost);
298 334 : return mapLocalHost.count(addr) > 0;
299 334 : }
300 :
301 6 : CNode* CConnman::FindNode(const CNetAddr& ip)
302 : {
303 6 : LOCK(cs_vNodes);
304 22 : for (CNode* pnode : vNodes) {
305 16 : if (static_cast<CNetAddr>(pnode->addr) == ip) {
306 0 : return pnode;
307 : }
308 16 : }
309 6 : return nullptr;
310 6 : }
311 :
312 0 : CNode* CConnman::FindNode(const CSubNet& subNet)
313 : {
314 0 : LOCK(cs_vNodes);
315 0 : for (CNode* pnode : vNodes) {
316 0 : if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
317 0 : return pnode;
318 : }
319 0 : }
320 0 : return nullptr;
321 0 : }
322 :
323 260 : CNode* CConnman::FindNode(const std::string& addrName)
324 : {
325 260 : LOCK(cs_vNodes);
326 400 : for (CNode* pnode : vNodes) {
327 140 : if (pnode->GetAddrName() == addrName) {
328 3 : return pnode;
329 : }
330 137 : }
331 257 : return nullptr;
332 260 : }
333 :
334 252 : CNode* CConnman::FindNode(const CService& addr)
335 : {
336 252 : LOCK(cs_vNodes);
337 377 : for (CNode* pnode : vNodes) {
338 125 : if (static_cast<CService>(pnode->addr) == addr) {
339 0 : return pnode;
340 : }
341 125 : }
342 252 : return nullptr;
343 252 : }
344 :
345 460 : bool CConnman::CheckIncomingNonce(uint64_t nonce)
346 : {
347 460 : LOCK(cs_vNodes);
348 1473 : for (const CNode* pnode : vNodes) {
349 1013 : if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
350 0 : return false;
351 1013 : }
352 460 : return true;
353 460 : }
354 :
355 : /** Get the bind address for a socket as CAddress */
356 713 : static CAddress GetBindAddress(SOCKET sock)
357 : {
358 713 : CAddress addr_bind;
359 713 : struct sockaddr_storage sockaddr_bind;
360 713 : socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
361 713 : if (sock != INVALID_SOCKET) {
362 713 : if (!getsockname(sock, (struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
363 713 : addr_bind.SetSockAddr((const struct sockaddr*)&sockaddr_bind);
364 : } else {
365 0 : LogPrint(BCLog::NET, "Warning: getsockname failed\n");
366 : }
367 : }
368 : return addr_bind;
369 713 : }
370 :
371 256 : CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
372 : {
373 256 : assert(conn_type != ConnectionType::INBOUND);
374 :
375 256 : if (pszDest == nullptr) {
376 6 : if (IsLocal(addrConnect))
377 0 : return nullptr;
378 :
379 : // Look for an existing connection
380 6 : CNode* pnode = FindNode(static_cast<CService>(addrConnect));
381 6 : if (pnode)
382 : {
383 0 : LogPrintf("Failed to open new connection, already connected\n");
384 0 : return nullptr;
385 : }
386 6 : }
387 :
388 : /// debug print
389 256 : LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
390 : pszDest ? pszDest : addrConnect.ToString(),
391 : pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
392 :
393 : // Resolve
394 256 : const int default_port = Params().GetDefaultPort();
395 256 : if (pszDest) {
396 250 : std::vector<CService> resolved;
397 250 : if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
398 246 : addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
399 246 : if (!addrConnect.IsValid()) {
400 0 : LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
401 0 : return nullptr;
402 : }
403 : // It is possible that we already have a connection to the IP/port pszDest resolved to.
404 : // In that case, drop the connection that was just created, and return the existing CNode instead.
405 : // Also store the name we used to connect in that CNode, so that future FindNode() calls to that
406 : // name catch this early.
407 246 : LOCK(cs_vNodes);
408 246 : CNode* pnode = FindNode(static_cast<CService>(addrConnect));
409 246 : if (pnode)
410 : {
411 0 : pnode->MaybeSetAddrName(std::string(pszDest));
412 0 : LogPrintf("Failed to open new connection, already connected\n");
413 0 : return nullptr;
414 : }
415 246 : }
416 250 : }
417 :
418 : // Connect
419 : bool connected = false;
420 256 : SOCKET hSocket = INVALID_SOCKET;
421 256 : proxyType proxy;
422 256 : if (addrConnect.IsValid()) {
423 252 : bool proxyConnectionFailed = false;
424 :
425 252 : if (GetProxy(addrConnect.GetNetwork(), proxy)) {
426 6 : hSocket = CreateSocket(proxy.proxy);
427 6 : if (hSocket == INVALID_SOCKET) {
428 0 : return nullptr;
429 : }
430 6 : connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, proxyConnectionFailed);
431 6 : } else {
432 : // no proxy needed (none set for target network)
433 246 : hSocket = CreateSocket(addrConnect);
434 246 : if (hSocket == INVALID_SOCKET) {
435 0 : return nullptr;
436 : }
437 246 : connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, conn_type == ConnectionType::MANUAL);
438 : }
439 252 : if (!proxyConnectionFailed) {
440 : // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
441 : // the proxy, mark this as an attempt.
442 252 : addrman.Attempt(addrConnect, fCountFailure);
443 : }
444 256 : } else if (pszDest && GetNameProxy(proxy)) {
445 3 : hSocket = CreateSocket(proxy.proxy);
446 613 : if (hSocket == INVALID_SOCKET) {
447 610 : return nullptr;
448 : }
449 3 : std::string host;
450 3 : int port = default_port;
451 3 : SplitHostPort(std::string(pszDest), port, host);
452 3 : bool proxyConnectionFailed;
453 3 : connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, proxyConnectionFailed);
454 3 : }
455 256 : if (!connected) {
456 8 : CloseSocket(hSocket);
457 8 : return nullptr;
458 : }
459 :
460 : // Add node
461 248 : NodeId id = GetNewNodeId();
462 858 : uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
463 858 : CAddress addr_bind = GetBindAddress(hSocket);
464 248 : CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type);
465 248 : pnode->AddRef();
466 610 :
467 610 : // We're making a new connection, harvest entropy from the time (and our peer count)
468 248 : RandAddEvent((uint32_t)id);
469 :
470 : return pnode;
471 512 : }
472 :
473 871 : void CNode::CloseSocketDisconnect()
474 : {
475 871 : fDisconnect = true;
476 1481 : LOCK(cs_hSocket);
477 1481 : if (hSocket != INVALID_SOCKET)
478 : {
479 713 : LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
480 713 : CloseSocket(hSocket);
481 : }
482 871 : }
483 :
484 466 : void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const {
485 538 : for (const auto& subnet : vWhitelistedRange) {
486 72 : if (subnet.m_subnet.Match(addr)) NetPermissions::AddFlag(flags, subnet.m_flags);
487 : }
488 466 : }
489 :
490 18752 : std::string CNode::GetAddrName() const {
491 18752 : LOCK(cs_addrName);
492 18752 : return addrName;
493 18752 : }
494 :
495 0 : void CNode::MaybeSetAddrName(const std::string& addrNameIn) {
496 0 : LOCK(cs_addrName);
497 0 : if (addrName.empty()) {
498 0 : addrName = addrNameIn;
499 : }
500 0 : }
501 :
502 9452 : CService CNode::GetAddrLocal() const {
503 9452 : LOCK(cs_addrLocal);
504 9452 : return addrLocal;
505 9452 : }
506 :
507 699 : void CNode::SetAddrLocal(const CService& addrLocalIn) {
508 699 : LOCK(cs_addrLocal);
509 699 : if (addrLocal.IsValid()) {
510 0 : error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
511 0 : } else {
512 699 : addrLocal = addrLocalIn;
513 : }
514 699 : }
515 :
516 : #undef X
517 : #define X(name) stats.name = name
518 8635 : void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
519 : {
520 8635 : stats.nodeid = this->GetId();
521 8635 : X(nServices);
522 8635 : X(addr);
523 8635 : X(addrBind);
524 8635 : stats.m_mapped_as = addr.GetMappedAS(m_asmap);
525 8635 : if (m_tx_relay != nullptr) {
526 8635 : LOCK(m_tx_relay->cs_filter);
527 8635 : stats.fRelayTxes = m_tx_relay->fRelayTxes;
528 8635 : } else {
529 0 : stats.fRelayTxes = false;
530 : }
531 8635 : X(nLastSend);
532 8635 : X(nLastRecv);
533 8635 : X(nLastTXTime);
534 8635 : X(nLastBlockTime);
535 8635 : X(nTimeConnected);
536 8635 : X(nTimeOffset);
537 8635 : stats.addrName = GetAddrName();
538 8635 : X(nVersion);
539 : {
540 8635 : LOCK(cs_SubVer);
541 8635 : X(cleanSubVer);
542 8635 : }
543 8635 : stats.fInbound = IsInboundConn();
544 8635 : stats.m_manual_connection = IsManualConn();
545 9245 : X(nStartingHeight);
546 : {
547 8635 : LOCK(cs_vSend);
548 8635 : X(mapSendBytesPerMsgCmd);
549 8635 : X(nSendBytes);
550 8635 : }
551 : {
552 8635 : LOCK(cs_vRecv);
553 8635 : X(mapRecvBytesPerMsgCmd);
554 8635 : X(nRecvBytes);
555 8635 : }
556 8635 : X(m_legacyWhitelisted);
557 8635 : X(m_permissionFlags);
558 8635 : if (m_tx_relay != nullptr) {
559 8635 : LOCK(m_tx_relay->cs_feeFilter);
560 9245 : stats.minFeeFilter = m_tx_relay->minFeeFilter;
561 8635 : } else {
562 0 : stats.minFeeFilter = 0;
563 : }
564 :
565 : // It is common for nodes with good ping times to suddenly become lagged,
566 : // due to a new block arriving or other large transfer.
567 : // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
568 : // since pingtime does not update until the ping is complete, which might take a while.
569 : // So, if a ping is taking an unusually long time in flight,
570 : // the caller can immediately detect that this is happening.
571 : std::chrono::microseconds ping_wait{0};
572 8635 : if ((0 != nPingNonceSent) && (0 != m_ping_start.load().count())) {
573 251 : ping_wait = GetTime<std::chrono::microseconds>() - m_ping_start.load();
574 251 : }
575 :
576 : // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
577 8635 : stats.m_ping_usec = nPingUsecTime;
578 8635 : stats.m_min_ping_usec = nMinPingUsecTime;
579 8635 : stats.m_ping_wait_usec = count_microseconds(ping_wait);
580 :
581 : // Leave string empty if addrLocal invalid (not filled in yet)
582 8635 : CService addrLocalUnlocked = GetAddrLocal();
583 8635 : stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
584 8635 : }
585 : #undef X
586 :
587 104828 : bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete)
588 : {
589 104828 : complete = false;
590 104828 : const auto time = GetTime<std::chrono::microseconds>();
591 104828 : LOCK(cs_vRecv);
592 104828 : nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count();
593 104828 : nRecvBytes += nBytes;
594 298533 : while (nBytes > 0) {
595 : // absorb network data
596 193706 : int handled = m_deserializer->Read(pch, nBytes);
597 193706 : if (handled < 0) return false;
598 :
599 193705 : pch += handled;
600 193705 : nBytes -= handled;
601 :
602 193705 : if (m_deserializer->Complete()) {
603 : // decompose a transport agnostic CNetMessage from the deserializer
604 86838 : CNetMessage msg = m_deserializer->GetMessage(Params().MessageStart(), time);
605 :
606 : //store received bytes per message command
607 : //to prevent a memory DOS, only allow valid commands
608 86838 : mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.m_command);
609 86838 : if (i == mapRecvBytesPerMsgCmd.end())
610 83 : i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
611 86838 : assert(i != mapRecvBytesPerMsgCmd.end());
612 86838 : i->second += msg.m_raw_message_size;
613 :
614 : // push the message to the process queue,
615 86838 : vRecvMsg.push_back(std::move(msg));
616 :
617 86838 : complete = true;
618 86838 : }
619 193705 : }
620 :
621 104827 : return true;
622 104828 : }
623 :
624 711 : void CNode::SetSendVersion(int nVersionIn)
625 : {
626 : // Send version may only be changed in the version message, and
627 : // only one version message is allowed per session. We can therefore
628 : // treat this value as const and even atomic as long as it's only used
629 : // once a version message has been successfully processed. Any attempt to
630 : // set this twice is an error.
631 711 : if (nSendVersion != 0) {
632 0 : error("Send version already set for node: %i. Refusing to change from %i to %i", id, nSendVersion, nVersionIn);
633 0 : } else {
634 711 : nSendVersion = nVersionIn;
635 : }
636 711 : }
637 :
638 707468 : int CNode::GetSendVersion() const
639 : {
640 : // The send version should always be explicitly set to
641 : // INIT_PROTO_VERSION rather than using this value until SetSendVersion
642 : // has been called.
643 707468 : if (nSendVersion == 0) {
644 0 : error("Requesting unset send version for node: %i. Using %i", id, INIT_PROTO_VERSION);
645 0 : return INIT_PROTO_VERSION;
646 : }
647 707468 : return nSendVersion;
648 707468 : }
649 :
650 86840 : int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
651 : {
652 : // copy data to temporary parsing buffer
653 86840 : unsigned int nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
654 86840 : unsigned int nCopy = std::min(nRemaining, nBytes);
655 :
656 86840 : memcpy(&hdrbuf[nHdrPos], pch, nCopy);
657 86840 : nHdrPos += nCopy;
658 :
659 : // if header incomplete, exit
660 86840 : if (nHdrPos < CMessageHeader::HEADER_SIZE)
661 1 : return nCopy;
662 :
663 : // deserialize to CMessageHeader
664 : try {
665 86839 : hdrbuf >> hdr;
666 0 : }
667 : catch (const std::exception&) {
668 : return -1;
669 0 : }
670 :
671 : // reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH
672 86839 : if (hdr.nMessageSize > MAX_SIZE || hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
673 1 : return -1;
674 : }
675 :
676 : // switch state to reading message data
677 86838 : in_data = true;
678 :
679 86838 : return nCopy;
680 86840 : }
681 :
682 106866 : int V1TransportDeserializer::readData(const char *pch, unsigned int nBytes)
683 : {
684 106866 : unsigned int nRemaining = hdr.nMessageSize - nDataPos;
685 106866 : unsigned int nCopy = std::min(nRemaining, nBytes);
686 :
687 106866 : if (vRecv.size() < nDataPos + nCopy) {
688 : // Allocate up to 256 KiB ahead, but never more than the total message size.
689 89025 : vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
690 89025 : }
691 :
692 106866 : hasher.Write({(const unsigned char*)pch, nCopy});
693 106866 : memcpy(&vRecv[nDataPos], pch, nCopy);
694 106866 : nDataPos += nCopy;
695 :
696 106866 : return nCopy;
697 106866 : }
698 :
699 86838 : const uint256& V1TransportDeserializer::GetMessageHash() const
700 : {
701 86838 : assert(Complete());
702 86838 : if (data_hash.IsNull())
703 86838 : hasher.Finalize(data_hash);
704 86838 : return data_hash;
705 : }
706 :
707 86838 : CNetMessage V1TransportDeserializer::GetMessage(const CMessageHeader::MessageStartChars& message_start, const std::chrono::microseconds time)
708 : {
709 : // decompose a single CNetMessage from the TransportDeserializer
710 86838 : CNetMessage msg(std::move(vRecv));
711 :
712 : // store state about valid header, netmagic and checksum
713 86838 : msg.m_valid_header = hdr.IsValid(message_start);
714 86838 : msg.m_valid_netmagic = (memcmp(hdr.pchMessageStart, message_start, CMessageHeader::MESSAGE_START_SIZE) == 0);
715 86838 : uint256 hash = GetMessageHash();
716 :
717 : // store command string, payload size
718 86838 : msg.m_command = hdr.GetCommand();
719 86838 : msg.m_message_size = hdr.nMessageSize;
720 86838 : msg.m_raw_message_size = hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
721 :
722 : // We just received a message off the wire, harvest entropy from the time (and the message checksum)
723 86838 : RandAddEvent(ReadLE32(hash.begin()));
724 :
725 86838 : msg.m_valid_checksum = (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) == 0);
726 86838 : if (!msg.m_valid_checksum) {
727 1 : LogPrint(BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s\n",
728 : SanitizeString(msg.m_command), msg.m_message_size,
729 : HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
730 : HexStr(hdr.pchChecksum));
731 : }
732 :
733 : // store receive time
734 86838 : msg.m_time = time;
735 :
736 : // reset the network deserializer (prepare for the next message)
737 86838 : Reset();
738 : return msg;
739 86838 : }
740 :
741 91268 : void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) {
742 : // create dbl-sha256 checksum
743 91268 : uint256 hash = Hash(msg.data);
744 :
745 : // create header
746 91268 : CMessageHeader hdr(Params().MessageStart(), msg.m_type.c_str(), msg.data.size());
747 91268 : memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
748 :
749 : // serialize header
750 91268 : header.reserve(CMessageHeader::HEADER_SIZE);
751 91268 : CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, header, 0, hdr};
752 91268 : }
753 :
754 91153 : size_t CConnman::SocketSendData(CNode *pnode) const EXCLUSIVE_LOCKS_REQUIRED(pnode->cs_vSend)
755 : {
756 91153 : auto it = pnode->vSendMsg.begin();
757 : size_t nSentSize = 0;
758 :
759 271319 : while (it != pnode->vSendMsg.end()) {
760 180275 : const auto &data = *it;
761 180275 : assert(data.size() > pnode->nSendOffset);
762 : int nBytes = 0;
763 : {
764 180275 : LOCK(pnode->cs_hSocket);
765 180275 : if (pnode->hSocket == INVALID_SOCKET)
766 12 : break;
767 180263 : nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
768 180275 : }
769 180263 : if (nBytes > 0) {
770 180259 : pnode->nLastSend = GetSystemTimeInSeconds();
771 180259 : pnode->nSendBytes += nBytes;
772 180259 : pnode->nSendOffset += nBytes;
773 180259 : nSentSize += nBytes;
774 180259 : if (pnode->nSendOffset == data.size()) {
775 180166 : pnode->nSendOffset = 0;
776 180166 : pnode->nSendSize -= data.size();
777 180166 : pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
778 180166 : it++;
779 : } else {
780 : // could not send full message; stop sending more
781 93 : break;
782 : }
783 : } else {
784 4 : if (nBytes < 0) {
785 : // error
786 4 : int nErr = WSAGetLastError();
787 4 : if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
788 : {
789 3 : LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
790 3 : pnode->CloseSocketDisconnect();
791 3 : }
792 4 : }
793 : // couldn't send anything at all
794 4 : break;
795 : }
796 180166 : }
797 :
798 91153 : if (it == pnode->vSendMsg.end()) {
799 91044 : assert(pnode->nSendOffset == 0);
800 91044 : assert(pnode->nSendSize == 0);
801 : }
802 91153 : pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
803 91153 : return nSentSize;
804 91153 : }
805 :
806 388 : struct NodeEvictionCandidate
807 : {
808 : NodeId id;
809 : int64_t nTimeConnected;
810 : int64_t nMinPingUsecTime;
811 : int64_t nLastBlockTime;
812 729 : int64_t nLastTXTime;
813 : bool fRelevantServices;
814 729 : bool fRelayTxes;
815 729 : bool fBloomFilter;
816 729 : CAddress addr;
817 : uint64_t nKeyedNetGroup;
818 : bool prefer_evict;
819 : bool m_is_local;
820 : };
821 :
822 67 : static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
823 : {
824 796 : return a.nMinPingUsecTime > b.nMinPingUsecTime;
825 : }
826 :
827 0 : static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
828 : {
829 729 : return a.nTimeConnected > b.nTimeConnected;
830 729 : }
831 :
832 729 : static bool CompareLocalHostTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
833 729 : {
834 0 : if (a.m_is_local != b.m_is_local) return b.m_is_local;
835 729 : return a.nTimeConnected > b.nTimeConnected;
836 0 : }
837 :
838 42 : static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
839 42 : return a.nKeyedNetGroup < b.nKeyedNetGroup;
840 729 : }
841 :
842 4 : static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
843 : {
844 : // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
845 4 : if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
846 732 : if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
847 732 : return a.nTimeConnected > b.nTimeConnected;
848 4 : }
849 :
850 24 : static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
851 : {
852 729 : // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn.
853 753 : if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime;
854 749 : if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes;
855 749 : if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
856 20 : return a.nTimeConnected > b.nTimeConnected;
857 24 : }
858 729 :
859 729 : // Pick out the potential block-relay only peers, and sort them by last block time.
860 4 : static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
861 729 : {
862 4 : if (a.fRelayTxes != b.fRelayTxes) return a.fRelayTxes;
863 4 : if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
864 732 : if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
865 732 : return a.nTimeConnected > b.nTimeConnected;
866 4 : }
867 :
868 : //! Sort an array by the specified comparator, then erase the last K elements.
869 : template<typename T, typename Comparator>
870 5 : static void EraseLastKElements(std::vector<T> &elements, Comparator comparator, size_t k)
871 : {
872 5 : std::sort(elements.begin(), elements.end(), comparator);
873 5 : size_t eraseSize = std::min(k, elements.size());
874 5 : elements.erase(elements.end() - eraseSize, elements.end());
875 5 : }
876 :
877 : /** Try to find a connection to evict when the node is full.
878 : * Extreme care must be taken to avoid opening the node to attacker
879 : * triggered network partitioning.
880 : * The strategy used here is to protect a small number of peers
881 : * for each of several distinct characteristics which are difficult
882 : * to forge. In order to partition a node the attacker must be
883 : * simultaneously better at all of them than honest peers.
884 : */
885 1 : bool CConnman::AttemptToEvictConnection()
886 : {
887 1 : std::vector<NodeEvictionCandidate> vEvictionCandidates;
888 : {
889 1 : LOCK(cs_vNodes);
890 :
891 22 : for (const CNode* node : vNodes) {
892 21 : if (node->HasPermission(PF_NOBAN))
893 0 : continue;
894 21 : if (!node->IsInboundConn())
895 0 : continue;
896 21 : if (node->fDisconnect)
897 0 : continue;
898 : bool peer_relay_txes = false;
899 : bool peer_filter_not_null = false;
900 21 : if (node->m_tx_relay != nullptr) {
901 21 : LOCK(node->m_tx_relay->cs_filter);
902 21 : peer_relay_txes = node->m_tx_relay->fRelayTxes;
903 21 : peer_filter_not_null = node->m_tx_relay->pfilter != nullptr;
904 21 : }
905 63 : NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
906 42 : node->nLastBlockTime, node->nLastTXTime,
907 21 : HasAllDesirableServiceFlags(node->nServices),
908 63 : peer_relay_txes, peer_filter_not_null, node->addr, node->nKeyedNetGroup,
909 42 : node->m_prefer_evict, node->addr.IsLocal()};
910 21 : vEvictionCandidates.push_back(candidate);
911 21 : }
912 1 : }
913 :
914 : // Protect connections with certain characteristics
915 :
916 : // Deterministically select 4 peers to protect by netgroup.
917 : // An attacker cannot predict which netgroups will be protected
918 1 : EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
919 : // Protect the 8 nodes with the lowest minimum ping time.
920 : // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
921 1 : EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
922 : // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
923 : // An attacker cannot manipulate this metric without performing useful work.
924 1 : EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
925 : // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
926 1 : std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockRelayOnlyTime);
927 1 : size_t erase_size = std::min(size_t(8), vEvictionCandidates.size());
928 6 : vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - erase_size, vEvictionCandidates.end(), [](NodeEvictionCandidate const &n) { return !n.fRelayTxes && n.fRelevantServices; }), vEvictionCandidates.end());
929 :
930 : // Protect 4 nodes that most recently sent us novel blocks.
931 : // An attacker cannot manipulate this metric without performing useful work.
932 1 : EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
933 729 :
934 : // Protect the half of the remaining nodes which have been connected the longest.
935 : // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
936 : // Reserve half of these protected spots for localhost peers, even if
937 729 : // they're not longest-uptime overall. This helps protect tor peers, which
938 729 : // tend to be otherwise disadvantaged under our eviction criteria.
939 730 : size_t initial_size = vEvictionCandidates.size();
940 730 : size_t total_protect_size = initial_size / 2;
941 :
942 : // Pick out up to 1/4 peers that are localhost, sorted by longest uptime.
943 1 : std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareLocalHostTimeConnected);
944 1 : size_t local_erase_size = total_protect_size / 2;
945 1 : vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - local_erase_size, vEvictionCandidates.end(), [](NodeEvictionCandidate const &n) { return n.m_is_local; }), vEvictionCandidates.end());
946 : // Calculate how many we removed, and update our total number of peers that
947 : // we want to protect based on uptime accordingly.
948 1 : total_protect_size -= initial_size - vEvictionCandidates.size();
949 1 : EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, total_protect_size);
950 :
951 1 : if (vEvictionCandidates.empty()) return false;
952 :
953 : // If any remaining peers are preferred for eviction consider only them.
954 : // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
955 : // then we probably don't want to evict it no matter what.
956 2 : if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
957 0 : vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
958 0 : [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
959 0 : }
960 :
961 : // Identify the network group with the most connections and youngest member.
962 : // (vEvictionCandidates is already sorted by reverse connect time)
963 1 : uint64_t naMostConnections;
964 : unsigned int nMostConnections = 0;
965 : int64_t nMostConnectionsTime = 0;
966 1 : std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
967 2 : for (const NodeEvictionCandidate &node : vEvictionCandidates) {
968 1 : std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
969 1 : group.push_back(node);
970 1 : int64_t grouptime = group[0].nTimeConnected;
971 :
972 1 : if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
973 1 : nMostConnections = group.size();
974 : nMostConnectionsTime = grouptime;
975 1 : naMostConnections = node.nKeyedNetGroup;
976 1 : }
977 : }
978 :
979 : // Reduce to the network group with the most connections
980 1 : vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
981 :
982 : // Disconnect from the network group with the most connections
983 1 : NodeId evicted = vEvictionCandidates.front().id;
984 1 : LOCK(cs_vNodes);
985 6 : for (CNode* pnode : vNodes) {
986 734 : if (pnode->GetId() == evicted) {
987 1 : pnode->fDisconnect = true;
988 1 : return true;
989 : }
990 4 : }
991 0 : return false;
992 730 : }
993 :
994 466 : void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
995 466 : struct sockaddr_storage sockaddr;
996 1195 : socklen_t len = sizeof(sockaddr);
997 466 : SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
998 1195 : CAddress addr;
999 : int nInbound = 0;
1000 1195 : int nMaxInbound = nMaxConnections - m_max_outbound;
1001 :
1002 1195 : if (hSocket != INVALID_SOCKET) {
1003 466 : if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
1004 729 : LogPrintf("Warning: Unknown socket family\n");
1005 : }
1006 : }
1007 :
1008 466 : NetPermissionFlags permissionFlags = NetPermissionFlags::PF_NONE;
1009 466 : hListenSocket.AddSocketPermissionFlags(permissionFlags);
1010 466 : AddWhitelistPermissionFlags(permissionFlags, addr);
1011 : bool legacyWhitelisted = false;
1012 466 : if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_ISIMPLICIT)) {
1013 7 : NetPermissions::ClearFlag(permissionFlags, PF_ISIMPLICIT);
1014 7 : if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, PF_FORCERELAY);
1015 7 : if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, PF_RELAY);
1016 7 : NetPermissions::AddFlag(permissionFlags, PF_MEMPOOL);
1017 7 : NetPermissions::AddFlag(permissionFlags, PF_NOBAN);
1018 : legacyWhitelisted = true;
1019 7 : }
1020 :
1021 : {
1022 466 : LOCK(cs_vNodes);
1023 1026 : for (const CNode* pnode : vNodes) {
1024 560 : if (pnode->IsInboundConn()) nInbound++;
1025 : }
1026 466 : }
1027 :
1028 466 : if (hSocket == INVALID_SOCKET)
1029 : {
1030 0 : int nErr = WSAGetLastError();
1031 0 : if (nErr != WSAEWOULDBLOCK)
1032 0 : LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
1033 : return;
1034 0 : }
1035 :
1036 1195 : if (!fNetworkActive) {
1037 729 : LogPrintf("connection from %s dropped: not accepting new connections\n", addr.ToString());
1038 0 : CloseSocket(hSocket);
1039 0 : return;
1040 : }
1041 :
1042 466 : if (!IsSelectableSocket(hSocket))
1043 : {
1044 0 : LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
1045 0 : CloseSocket(hSocket);
1046 0 : return;
1047 : }
1048 :
1049 : // According to the internet TCP_NODELAY is not carried into accepted sockets
1050 : // on all platforms. Set it again here just to be sure.
1051 466 : SetSocketNoDelay(hSocket);
1052 :
1053 : // Don't accept connections from banned peers.
1054 466 : bool banned = m_banman && m_banman->IsBanned(addr);
1055 466 : if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && banned)
1056 : {
1057 1 : LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
1058 1 : CloseSocket(hSocket);
1059 1 : return;
1060 : }
1061 :
1062 : // Only accept connections from discouraged peers if our inbound slots aren't (almost) full.
1063 465 : bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1064 465 : if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && nInbound + 1 >= nMaxInbound && discouraged)
1065 : {
1066 0 : LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString());
1067 0 : CloseSocket(hSocket);
1068 0 : return;
1069 : }
1070 :
1071 465 : if (nInbound >= nMaxInbound)
1072 : {
1073 1 : if (!AttemptToEvictConnection()) {
1074 : // No connection to evict, disconnect the new connection
1075 0 : LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
1076 0 : CloseSocket(hSocket);
1077 0 : return;
1078 : }
1079 : }
1080 :
1081 465 : NodeId id = GetNewNodeId();
1082 465 : uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
1083 465 : CAddress addr_bind = GetBindAddress(hSocket);
1084 :
1085 465 : ServiceFlags nodeServices = nLocalServices;
1086 465 : if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
1087 2 : nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
1088 2 : }
1089 465 : CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND);
1090 465 : pnode->AddRef();
1091 465 : pnode->m_permissionFlags = permissionFlags;
1092 : // If this flag is present, the user probably expect that RPC and QT report it as whitelisted (backward compatibility)
1093 465 : pnode->m_legacyWhitelisted = legacyWhitelisted;
1094 465 : pnode->m_prefer_evict = discouraged;
1095 465 : m_msgproc->InitializeNode(pnode);
1096 :
1097 465 : LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1098 :
1099 : {
1100 465 : LOCK(cs_vNodes);
1101 465 : vNodes.push_back(pnode);
1102 465 : }
1103 :
1104 : // We received a new connection, harvest entropy from the time (and our peer count)
1105 465 : RandAddEvent((uint32_t)id);
1106 931 : }
1107 :
1108 332444 : void CConnman::DisconnectNodes()
1109 : {
1110 : {
1111 332444 : LOCK(cs_vNodes);
1112 :
1113 332444 : if (!fNetworkActive) {
1114 : // Disconnect any connected nodes
1115 95 : for (CNode* pnode : vNodes) {
1116 3 : if (!pnode->fDisconnect) {
1117 3 : LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
1118 3 : pnode->fDisconnect = true;
1119 3 : }
1120 : }
1121 92 : }
1122 :
1123 : // Disconnect unused nodes
1124 332444 : std::vector<CNode*> vNodesCopy = vNodes;
1125 835629 : for (CNode* pnode : vNodesCopy)
1126 : {
1127 503185 : if (pnode->fDisconnect)
1128 : {
1129 : // remove from vNodes
1130 299 : vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1131 :
1132 : // release outbound grant (if any)
1133 299 : pnode->grantOutbound.Release();
1134 :
1135 : // close socket and cleanup
1136 299 : pnode->CloseSocketDisconnect();
1137 :
1138 : // hold in disconnected pool until all refs are released
1139 299 : pnode->Release();
1140 299 : vNodesDisconnected.push_back(pnode);
1141 : }
1142 503185 : }
1143 332444 : }
1144 : {
1145 : // Delete disconnected nodes
1146 332444 : std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1147 332746 : for (CNode* pnode : vNodesDisconnectedCopy)
1148 : {
1149 : // wait until threads are done using it
1150 302 : if (pnode->GetRefCount() <= 0) {
1151 : bool fDelete = false;
1152 : {
1153 299 : TRY_LOCK(pnode->cs_vSend, lockSend);
1154 299 : if (lockSend) {
1155 : fDelete = true;
1156 299 : }
1157 299 : }
1158 299 : if (fDelete) {
1159 299 : vNodesDisconnected.remove(pnode);
1160 299 : DeleteNode(pnode);
1161 : }
1162 299 : }
1163 302 : }
1164 332444 : }
1165 332444 : }
1166 :
1167 332444 : void CConnman::NotifyNumConnectionsChanged()
1168 : {
1169 : size_t vNodesSize;
1170 : {
1171 332444 : LOCK(cs_vNodes);
1172 332444 : vNodesSize = vNodes.size();
1173 332444 : }
1174 332444 : if(vNodesSize != nPrevNodeCount) {
1175 989 : nPrevNodeCount = vNodesSize;
1176 989 : if(clientInterface)
1177 989 : clientInterface->NotifyNumConnectionsChanged(vNodesSize);
1178 : }
1179 332444 : }
1180 :
1181 503184 : void CConnman::InactivityCheck(CNode *pnode)
1182 : {
1183 503184 : int64_t nTime = GetSystemTimeInSeconds();
1184 503184 : if (nTime - pnode->nTimeConnected > m_peer_connect_timeout)
1185 : {
1186 188057 : if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1187 : {
1188 2 : LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d from %d\n", m_peer_connect_timeout, pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
1189 2 : pnode->fDisconnect = true;
1190 2 : }
1191 188055 : else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1192 : {
1193 0 : LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1194 0 : pnode->fDisconnect = true;
1195 0 : }
1196 188055 : else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1197 : {
1198 0 : LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1199 0 : pnode->fDisconnect = true;
1200 0 : }
1201 188055 : else if (pnode->nPingNonceSent && pnode->m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL} < GetTime<std::chrono::microseconds>())
1202 : {
1203 1 : LogPrintf("ping timeout: %fs\n", 0.000001 * count_microseconds(GetTime<std::chrono::microseconds>() - pnode->m_ping_start.load()));
1204 1 : pnode->fDisconnect = true;
1205 1 : }
1206 188054 : else if (!pnode->fSuccessfullyConnected)
1207 : {
1208 1 : LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId());
1209 1 : pnode->fDisconnect = true;
1210 1 : }
1211 : }
1212 503184 : }
1213 :
1214 332444 : bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1215 : {
1216 664896 : for (const ListenSocket& hListenSocket : vhListenSocket) {
1217 332452 : recv_set.insert(hListenSocket.socket);
1218 : }
1219 :
1220 : {
1221 332444 : LOCK(cs_vNodes);
1222 835330 : for (CNode* pnode : vNodes)
1223 : {
1224 : // Implement the following logic:
1225 : // * If there is data to send, select() for sending data. As this only
1226 : // happens when optimistic write failed, we choose to first drain the
1227 : // write buffer in this case before receiving more. This avoids
1228 : // needlessly queueing received data, if the remote peer is not themselves
1229 : // receiving data. This means properly utilizing TCP flow control signalling.
1230 : // * Otherwise, if there is space left in the receive buffer, select() for
1231 : // receiving data.
1232 : // * Hand off all complete messages to the processor, to be handled without
1233 : // blocking here.
1234 :
1235 502886 : bool select_recv = !pnode->fPauseRecv;
1236 : bool select_send;
1237 : {
1238 502886 : LOCK(pnode->cs_vSend);
1239 502886 : select_send = !pnode->vSendMsg.empty();
1240 502886 : }
1241 :
1242 502886 : LOCK(pnode->cs_hSocket);
1243 502886 : if (pnode->hSocket == INVALID_SOCKET)
1244 0 : continue;
1245 :
1246 502886 : error_set.insert(pnode->hSocket);
1247 502886 : if (select_send) {
1248 2828 : send_set.insert(pnode->hSocket);
1249 2828 : continue;
1250 : }
1251 500058 : if (select_recv) {
1252 496844 : recv_set.insert(pnode->hSocket);
1253 496844 : }
1254 502886 : }
1255 332444 : }
1256 :
1257 332444 : return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1258 0 : }
1259 :
1260 : #ifdef USE_POLL
1261 : void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1262 : {
1263 : std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1264 : if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1265 : interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1266 : return;
1267 : }
1268 :
1269 : std::unordered_map<SOCKET, struct pollfd> pollfds;
1270 : for (SOCKET socket_id : recv_select_set) {
1271 : pollfds[socket_id].fd = socket_id;
1272 : pollfds[socket_id].events |= POLLIN;
1273 : }
1274 :
1275 : for (SOCKET socket_id : send_select_set) {
1276 : pollfds[socket_id].fd = socket_id;
1277 : pollfds[socket_id].events |= POLLOUT;
1278 : }
1279 :
1280 : for (SOCKET socket_id : error_select_set) {
1281 : pollfds[socket_id].fd = socket_id;
1282 : // These flags are ignored, but we set them for clarity
1283 : pollfds[socket_id].events |= POLLERR|POLLHUP;
1284 : }
1285 :
1286 : std::vector<struct pollfd> vpollfds;
1287 : vpollfds.reserve(pollfds.size());
1288 : for (auto it : pollfds) {
1289 : vpollfds.push_back(std::move(it.second));
1290 : }
1291 :
1292 : if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
1293 :
1294 : if (interruptNet) return;
1295 :
1296 : for (struct pollfd pollfd_entry : vpollfds) {
1297 : if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1298 : if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1299 : if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1300 : }
1301 : }
1302 : #else
1303 332444 : void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1304 : {
1305 332444 : std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1306 332444 : if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1307 0 : interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1308 0 : return;
1309 : }
1310 :
1311 : //
1312 : // Find which sockets have data to receive
1313 : //
1314 332444 : struct timeval timeout;
1315 332444 : timeout.tv_sec = 0;
1316 332444 : timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
1317 :
1318 332444 : fd_set fdsetRecv;
1319 332444 : fd_set fdsetSend;
1320 332444 : fd_set fdsetError;
1321 332444 : FD_ZERO(&fdsetRecv);
1322 332444 : FD_ZERO(&fdsetSend);
1323 332444 : FD_ZERO(&fdsetError);
1324 332444 : SOCKET hSocketMax = 0;
1325 :
1326 1161740 : for (SOCKET hSocket : recv_select_set) {
1327 829296 : FD_SET(hSocket, &fdsetRecv);
1328 829296 : hSocketMax = std::max(hSocketMax, hSocket);
1329 829296 : }
1330 :
1331 335272 : for (SOCKET hSocket : send_select_set) {
1332 2828 : FD_SET(hSocket, &fdsetSend);
1333 2828 : hSocketMax = std::max(hSocketMax, hSocket);
1334 2828 : }
1335 :
1336 835330 : for (SOCKET hSocket : error_select_set) {
1337 502886 : FD_SET(hSocket, &fdsetError);
1338 502886 : hSocketMax = std::max(hSocketMax, hSocket);
1339 502886 : }
1340 :
1341 332444 : int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1342 :
1343 332444 : if (interruptNet)
1344 491 : return;
1345 :
1346 331953 : if (nSelect == SOCKET_ERROR)
1347 : {
1348 0 : int nErr = WSAGetLastError();
1349 0 : LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1350 0 : for (unsigned int i = 0; i <= hSocketMax; i++)
1351 0 : FD_SET(i, &fdsetRecv);
1352 0 : FD_ZERO(&fdsetSend);
1353 0 : FD_ZERO(&fdsetError);
1354 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1355 0 : return;
1356 0 : }
1357 :
1358 1160344 : for (SOCKET hSocket : recv_select_set) {
1359 828391 : if (FD_ISSET(hSocket, &fdsetRecv)) {
1360 105448 : recv_set.insert(hSocket);
1361 105448 : }
1362 828391 : }
1363 :
1364 334781 : for (SOCKET hSocket : send_select_set) {
1365 2828 : if (FD_ISSET(hSocket, &fdsetSend)) {
1366 94 : send_set.insert(hSocket);
1367 94 : }
1368 2828 : }
1369 :
1370 834426 : for (SOCKET hSocket : error_select_set) {
1371 502473 : if (FD_ISSET(hSocket, &fdsetError)) {
1372 0 : error_set.insert(hSocket);
1373 0 : }
1374 502473 : }
1375 332444 : }
1376 : #endif
1377 :
1378 332444 : void CConnman::SocketHandler()
1379 : {
1380 332444 : std::set<SOCKET> recv_set, send_set, error_set;
1381 332444 : SocketEvents(recv_set, send_set, error_set);
1382 :
1383 332444 : if (interruptNet) return;
1384 :
1385 : //
1386 : // Accept new connections
1387 : //
1388 663913 : for (const ListenSocket& hListenSocket : vhListenSocket)
1389 : {
1390 331960 : if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1391 : {
1392 466 : AcceptConnection(hListenSocket);
1393 : }
1394 : }
1395 :
1396 : //
1397 : // Service each socket
1398 : //
1399 331953 : std::vector<CNode*> vNodesCopy;
1400 : {
1401 331953 : LOCK(cs_vNodes);
1402 331953 : vNodesCopy = vNodes;
1403 835139 : for (CNode* pnode : vNodesCopy)
1404 503186 : pnode->AddRef();
1405 331953 : }
1406 835139 : for (CNode* pnode : vNodesCopy)
1407 : {
1408 503186 : if (interruptNet)
1409 0 : return;
1410 :
1411 : //
1412 : // Receive
1413 : //
1414 : bool recvSet = false;
1415 : bool sendSet = false;
1416 : bool errorSet = false;
1417 : {
1418 503186 : LOCK(pnode->cs_hSocket);
1419 503186 : if (pnode->hSocket == INVALID_SOCKET)
1420 2 : continue;
1421 503184 : recvSet = recv_set.count(pnode->hSocket) > 0;
1422 503184 : sendSet = send_set.count(pnode->hSocket) > 0;
1423 503184 : errorSet = error_set.count(pnode->hSocket) > 0;
1424 503186 : }
1425 503184 : if (recvSet || errorSet)
1426 : {
1427 : // typical socket buffer is 8K-64K
1428 104982 : char pchBuf[0x10000];
1429 : int nBytes = 0;
1430 : {
1431 104982 : LOCK(pnode->cs_hSocket);
1432 104982 : if (pnode->hSocket == INVALID_SOCKET)
1433 0 : continue;
1434 104982 : nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1435 104982 : }
1436 104982 : if (nBytes > 0)
1437 : {
1438 104828 : bool notify = false;
1439 104828 : if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1440 1 : pnode->CloseSocketDisconnect();
1441 104828 : RecordBytesRecv(nBytes);
1442 104828 : if (notify) {
1443 : size_t nSizeAdded = 0;
1444 77821 : auto it(pnode->vRecvMsg.begin());
1445 164659 : for (; it != pnode->vRecvMsg.end(); ++it) {
1446 : // vRecvMsg contains only completed CNetMessage
1447 : // the single possible partially deserialized message are held by TransportDeserializer
1448 86838 : nSizeAdded += it->m_raw_message_size;
1449 : }
1450 : {
1451 77821 : LOCK(pnode->cs_vProcessMsg);
1452 77821 : pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1453 77821 : pnode->nProcessQueueSize += nSizeAdded;
1454 77821 : pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1455 77821 : }
1456 77821 : WakeMessageHandler();
1457 77821 : }
1458 104828 : }
1459 154 : else if (nBytes == 0)
1460 : {
1461 : // socket closed gracefully
1462 144 : if (!pnode->fDisconnect) {
1463 144 : LogPrint(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
1464 : }
1465 144 : pnode->CloseSocketDisconnect();
1466 : }
1467 10 : else if (nBytes < 0)
1468 : {
1469 : // error
1470 10 : int nErr = WSAGetLastError();
1471 10 : if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1472 : {
1473 10 : if (!pnode->fDisconnect) {
1474 10 : LogPrint(BCLog::NET, "socket recv error for peer=%d: %s\n", pnode->GetId(), NetworkErrorString(nErr));
1475 : }
1476 10 : pnode->CloseSocketDisconnect();
1477 : }
1478 10 : }
1479 104982 : }
1480 :
1481 : //
1482 : // Send
1483 : //
1484 503184 : if (sendSet)
1485 : {
1486 94 : LOCK(pnode->cs_vSend);
1487 94 : size_t nBytes = SocketSendData(pnode);
1488 94 : if (nBytes) {
1489 94 : RecordBytesSent(nBytes);
1490 : }
1491 94 : }
1492 :
1493 503184 : InactivityCheck(pnode);
1494 1006368 : }
1495 : {
1496 331953 : LOCK(cs_vNodes);
1497 835139 : for (CNode* pnode : vNodesCopy)
1498 503186 : pnode->Release();
1499 331953 : }
1500 332444 : }
1501 :
1502 492 : void CConnman::ThreadSocketHandler()
1503 : {
1504 332936 : while (!interruptNet)
1505 : {
1506 332444 : DisconnectNodes();
1507 332444 : NotifyNumConnectionsChanged();
1508 332444 : SocketHandler();
1509 : }
1510 492 : }
1511 :
1512 113144 : void CConnman::WakeMessageHandler()
1513 : {
1514 : {
1515 113144 : LOCK(mutexMsgProc);
1516 113144 : fMsgProcWake = true;
1517 113144 : }
1518 113144 : condMsgProc.notify_one();
1519 113144 : }
1520 :
1521 :
1522 :
1523 :
1524 :
1525 :
1526 : #ifdef USE_UPNP
1527 640 : static CThreadInterrupt g_upnp_interrupt;
1528 640 : static std::thread g_upnp_thread;
1529 0 : static void ThreadMapPort()
1530 : {
1531 0 : std::string port = strprintf("%u", GetListenPort());
1532 : const char * multicastif = nullptr;
1533 : const char * minissdpdpath = nullptr;
1534 : struct UPNPDev * devlist = nullptr;
1535 0 : char lanaddr[64];
1536 :
1537 0 : int error = 0;
1538 : #if MINIUPNPC_API_VERSION < 14
1539 : devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1540 : #else
1541 0 : devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1542 : #endif
1543 :
1544 0 : struct UPNPUrls urls;
1545 0 : struct IGDdatas data;
1546 0 : int r;
1547 :
1548 0 : r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1549 0 : if (r == 1)
1550 : {
1551 0 : if (fDiscover) {
1552 0 : char externalIPAddress[40];
1553 0 : r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1554 0 : if (r != UPNPCOMMAND_SUCCESS) {
1555 0 : LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1556 : } else {
1557 0 : if (externalIPAddress[0]) {
1558 0 : CNetAddr resolved;
1559 0 : if (LookupHost(externalIPAddress, resolved, false)) {
1560 0 : LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString());
1561 0 : AddLocal(resolved, LOCAL_UPNP);
1562 : }
1563 0 : } else {
1564 0 : LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1565 : }
1566 : }
1567 0 : }
1568 :
1569 0 : std::string strDesc = PACKAGE_NAME " " + FormatFullVersion();
1570 :
1571 0 : do {
1572 0 : r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1573 :
1574 0 : if (r != UPNPCOMMAND_SUCCESS) {
1575 0 : LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
1576 0 : } else {
1577 0 : LogPrintf("UPnP Port Mapping successful.\n");
1578 : }
1579 0 : } while (g_upnp_interrupt.sleep_for(std::chrono::minutes(20)));
1580 :
1581 0 : r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1582 0 : LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
1583 0 : freeUPNPDevlist(devlist); devlist = nullptr;
1584 0 : FreeUPNPUrls(&urls);
1585 0 : } else {
1586 0 : LogPrintf("No valid UPnP IGDs found\n");
1587 0 : freeUPNPDevlist(devlist); devlist = nullptr;
1588 0 : if (r != 0)
1589 0 : FreeUPNPUrls(&urls);
1590 : }
1591 0 : }
1592 :
1593 0 : void StartMapPort()
1594 : {
1595 0 : if (!g_upnp_thread.joinable()) {
1596 0 : assert(!g_upnp_interrupt);
1597 0 : g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
1598 0 : }
1599 0 : }
1600 :
1601 529 : void InterruptMapPort()
1602 : {
1603 529 : if(g_upnp_thread.joinable()) {
1604 0 : g_upnp_interrupt();
1605 0 : }
1606 529 : }
1607 :
1608 529 : void StopMapPort()
1609 : {
1610 529 : if(g_upnp_thread.joinable()) {
1611 0 : g_upnp_thread.join();
1612 0 : g_upnp_interrupt.reset();
1613 0 : }
1614 529 : }
1615 :
1616 : #else
1617 : void StartMapPort()
1618 : {
1619 : // Intentionally left blank.
1620 : }
1621 : void InterruptMapPort()
1622 : {
1623 : // Intentionally left blank.
1624 : }
1625 : void StopMapPort()
1626 : {
1627 : // Intentionally left blank.
1628 : }
1629 : #endif
1630 :
1631 :
1632 :
1633 :
1634 :
1635 :
1636 0 : void CConnman::ThreadDNSAddressSeed()
1637 : {
1638 0 : FastRandomContext rng;
1639 0 : std::vector<std::string> seeds = Params().DNSSeeds();
1640 0 : Shuffle(seeds.begin(), seeds.end(), rng);
1641 : int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
1642 0 : int found = 0;
1643 :
1644 0 : if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
1645 : // When -forcednsseed is provided, query all.
1646 0 : seeds_right_now = seeds.size();
1647 0 : } else if (addrman.size() == 0) {
1648 : // If we have no known peers, query all.
1649 : // This will occur on the first run, or if peers.dat has been
1650 : // deleted.
1651 0 : seeds_right_now = seeds.size();
1652 0 : }
1653 :
1654 : // goal: only query DNS seed if address need is acute
1655 : // * If we have a reasonable number of peers in addrman, spend
1656 : // some time trying them first. This improves user privacy by
1657 : // creating fewer identifying DNS requests, reduces trust by
1658 : // giving seeds less influence on the network topology, and
1659 : // reduces traffic to the seeds.
1660 : // * When querying DNS seeds query a few at once, this ensures
1661 : // that we don't give DNS seeds the ability to eclipse nodes
1662 : // that query them.
1663 : // * If we continue having problems, eventually query all the
1664 : // DNS seeds, and if that fails too, also try the fixed seeds.
1665 : // (done in ThreadOpenConnections)
1666 0 : const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
1667 :
1668 0 : for (const std::string& seed : seeds) {
1669 0 : if (seeds_right_now == 0) {
1670 0 : seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1671 :
1672 0 : if (addrman.size() > 0) {
1673 0 : LogPrintf("Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1674 0 : std::chrono::seconds to_wait = seeds_wait_time;
1675 0 : while (to_wait.count() > 0) {
1676 : // if sleeping for the MANY_PEERS interval, wake up
1677 : // early to see if we have enough peers and can stop
1678 : // this thread entirely freeing up its resources
1679 0 : std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
1680 0 : if (!interruptNet.sleep_for(w)) return;
1681 0 : to_wait -= w;
1682 :
1683 : int nRelevant = 0;
1684 : {
1685 0 : LOCK(cs_vNodes);
1686 0 : for (const CNode* pnode : vNodes) {
1687 0 : if (pnode->fSuccessfullyConnected && pnode->IsOutboundOrBlockRelayConn()) ++nRelevant;
1688 : }
1689 0 : }
1690 0 : if (nRelevant >= 2) {
1691 0 : if (found > 0) {
1692 0 : LogPrintf("%d addresses found from DNS seeds\n", found);
1693 0 : LogPrintf("P2P peers available. Finished DNS seeding.\n");
1694 : } else {
1695 0 : LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1696 : }
1697 0 : return;
1698 : }
1699 0 : }
1700 0 : }
1701 : }
1702 :
1703 0 : if (interruptNet) return;
1704 :
1705 : // hold off on querying seeds if P2P network deactivated
1706 0 : if (!fNetworkActive) {
1707 0 : LogPrintf("Waiting for network to be reactivated before querying DNS seeds.\n");
1708 : do {
1709 0 : if (!interruptNet.sleep_for(std::chrono::seconds{1})) return;
1710 0 : } while (!fNetworkActive);
1711 : }
1712 :
1713 0 : LogPrintf("Loading addresses from DNS seed %s\n", seed);
1714 0 : if (HaveNameProxy()) {
1715 0 : AddAddrFetch(seed);
1716 : } else {
1717 0 : std::vector<CNetAddr> vIPs;
1718 0 : std::vector<CAddress> vAdd;
1719 0 : ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
1720 0 : std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
1721 0 : CNetAddr resolveSource;
1722 0 : if (!resolveSource.SetInternal(host)) {
1723 0 : continue;
1724 : }
1725 : unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
1726 0 : if (LookupHost(host, vIPs, nMaxIPs, true)) {
1727 0 : for (const CNetAddr& ip : vIPs) {
1728 : int nOneDay = 24*3600;
1729 0 : CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1730 0 : addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
1731 0 : vAdd.push_back(addr);
1732 0 : found++;
1733 0 : }
1734 0 : addrman.Add(vAdd, resolveSource);
1735 : } else {
1736 : // We now avoid directly using results from DNS Seeds which do not support service bit filtering,
1737 : // instead using them as a addrfetch to get nodes with our desired service bits.
1738 0 : AddAddrFetch(seed);
1739 : }
1740 0 : }
1741 0 : --seeds_right_now;
1742 0 : }
1743 0 : LogPrintf("%d addresses found from DNS seeds\n", found);
1744 0 : }
1745 :
1746 799 : void CConnman::DumpAddresses()
1747 : {
1748 799 : int64_t nStart = GetTimeMillis();
1749 :
1750 799 : CAddrDB adb;
1751 799 : adb.Write(addrman);
1752 :
1753 799 : LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1754 : addrman.size(), GetTimeMillis() - nStart);
1755 799 : }
1756 :
1757 25952 : void CConnman::ProcessAddrFetch()
1758 : {
1759 25952 : std::string strDest;
1760 : {
1761 25952 : LOCK(m_addr_fetches_mutex);
1762 25952 : if (m_addr_fetches.empty())
1763 25952 : return;
1764 0 : strDest = m_addr_fetches.front();
1765 0 : m_addr_fetches.pop_front();
1766 25952 : }
1767 0 : CAddress addr;
1768 0 : CSemaphoreGrant grant(*semOutbound, true);
1769 0 : if (grant) {
1770 0 : OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
1771 : }
1772 25952 : }
1773 :
1774 92 : bool CConnman::GetTryNewOutboundPeer()
1775 : {
1776 92 : return m_try_another_outbound_peer;
1777 : }
1778 :
1779 613 : void CConnman::SetTryNewOutboundPeer(bool flag)
1780 : {
1781 613 : m_try_another_outbound_peer = flag;
1782 613 : LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
1783 613 : }
1784 :
1785 : // Return the number of peers we have over our outbound connection limit
1786 : // Exclude peers that are marked for disconnect, or are going to be
1787 : // disconnected soon (eg one-shots and feelers)
1788 : // Also exclude peers that haven't finished initial connection handshake yet
1789 : // (so that we don't decide we're over our desired connection limit, and then
1790 : // evict some peer that has finished the handshake)
1791 202 : int CConnman::GetExtraOutboundCount()
1792 : {
1793 551 : int nOutbound = 0;
1794 : {
1795 202 : LOCK(cs_vNodes);
1796 551 : for (const CNode* pnode : vNodes) {
1797 349 : if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsOutboundOrBlockRelayConn()) {
1798 34 : ++nOutbound;
1799 34 : }
1800 : }
1801 202 : }
1802 202 : return std::max(nOutbound - m_max_outbound_full_relay - m_max_outbound_block_relay, 0);
1803 0 : }
1804 :
1805 492 : void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
1806 : {
1807 : // Connect to specific addresses
1808 492 : if (!connect.empty())
1809 : {
1810 1 : for (int64_t nLoop = 0;; nLoop++)
1811 : {
1812 1 : ProcessAddrFetch();
1813 2 : for (const std::string& strAddr : connect)
1814 : {
1815 1 : CAddress addr(CService(), NODE_NONE);
1816 1 : OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
1817 1 : for (int i = 0; i < 10 && i < nLoop; i++)
1818 : {
1819 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1820 0 : return;
1821 : }
1822 1 : }
1823 1 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1824 1 : return;
1825 : }
1826 : }
1827 :
1828 : // Initiate network connections
1829 491 : int64_t nStart = GetTime();
1830 :
1831 : // Minimum time before next feeler connection (in microseconds).
1832 25954 : int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
1833 25954 : while (!interruptNet)
1834 : {
1835 25951 : ProcessAddrFetch();
1836 :
1837 25951 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1838 488 : return;
1839 :
1840 25463 : CSemaphoreGrant grant(*semOutbound);
1841 25463 : if (interruptNet)
1842 0 : return;
1843 :
1844 : // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1845 : // Note that we only do this if we started with an empty peers.dat,
1846 : // (in which case we will query DNS seeds immediately) *and* the DNS
1847 : // seeds have not returned any results.
1848 25463 : if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1849 : static bool done = false;
1850 10582 : if (!done) {
1851 63 : LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1852 63 : CNetAddr local;
1853 63 : local.SetInternal("fixedseeds");
1854 63 : addrman.Add(convertSeed6(Params().FixedSeeds()), local);
1855 63 : done = true;
1856 63 : }
1857 : }
1858 :
1859 : //
1860 : // Choose an address to connect to based on most recently seen
1861 : //
1862 25463 : CAddress addrConnect;
1863 :
1864 : // Only connect out to one peer per network group (/16 for IPv4).
1865 : int nOutboundFullRelay = 0;
1866 : int nOutboundBlockRelay = 0;
1867 25463 : std::set<std::vector<unsigned char> > setConnected;
1868 :
1869 : {
1870 25463 : LOCK(cs_vNodes);
1871 62288 : for (const CNode* pnode : vNodes) {
1872 36825 : if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1873 36825 : if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1874 :
1875 : // Netgroups for inbound and manual peers are not excluded because our goal here
1876 : // is to not use multiple of our limited outbound slots on a single netgroup
1877 : // but inbound and manual peers do not use our outbound slots. Inbound peers
1878 : // also have the added issue that they could be attacker controlled and used
1879 : // to prevent us from connecting to particular hosts if we used them here.
1880 36825 : switch (pnode->m_conn_type) {
1881 : case ConnectionType::INBOUND:
1882 : case ConnectionType::MANUAL:
1883 : break;
1884 : case ConnectionType::OUTBOUND_FULL_RELAY:
1885 : case ConnectionType::BLOCK_RELAY:
1886 : case ConnectionType::ADDR_FETCH:
1887 : case ConnectionType::FEELER:
1888 0 : setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
1889 0 : } // no default case, so the compiler can warn about missing cases
1890 : }
1891 25463 : }
1892 :
1893 : ConnectionType conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
1894 25463 : int64_t nTime = GetTimeMicros();
1895 : bool fFeeler = false;
1896 :
1897 : // Determine what type of connection to open. Opening
1898 : // OUTBOUND_FULL_RELAY connections gets the highest priority until we
1899 : // meet our full-relay capacity. Then we open BLOCK_RELAY connection
1900 : // until we hit our block-relay-only peer limit.
1901 : // GetTryNewOutboundPeer() gets set when a stale tip is detected, so we
1902 : // try opening an additional OUTBOUND_FULL_RELAY connection. If none of
1903 : // these conditions are met, check the nNextFeeler timer to decide if
1904 : // we should open a FEELER.
1905 :
1906 25463 : if (nOutboundFullRelay < m_max_outbound_full_relay) {
1907 : // OUTBOUND_FULL_RELAY
1908 0 : } else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
1909 : conn_type = ConnectionType::BLOCK_RELAY;
1910 0 : } else if (GetTryNewOutboundPeer()) {
1911 : // OUTBOUND_FULL_RELAY
1912 0 : } else if (nTime > nNextFeeler) {
1913 0 : nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
1914 : conn_type = ConnectionType::FEELER;
1915 : fFeeler = true;
1916 : } else {
1917 : // skip to next iteration of while loop
1918 0 : continue;
1919 : }
1920 :
1921 25463 : addrman.ResolveCollisions();
1922 :
1923 25463 : int64_t nANow = GetAdjustedTime();
1924 25776 : int nTries = 0;
1925 25776 : while (!interruptNet)
1926 : {
1927 25775 : CAddrInfo addr = addrman.SelectTriedCollision();
1928 :
1929 : // SelectTriedCollision returns an invalid address if it is empty.
1930 25775 : if (!fFeeler || !addr.IsValid()) {
1931 25775 : addr = addrman.Select(fFeeler);
1932 25775 : }
1933 :
1934 : // Require outbound connections, other than feelers, to be to distinct network groups
1935 25775 : if (!fFeeler && setConnected.count(addr.GetGroup(addrman.m_asmap))) {
1936 0 : break;
1937 : }
1938 :
1939 : // if we selected an invalid or local address, restart
1940 25775 : if (!addr.IsValid() || IsLocal(addr)) {
1941 25456 : break;
1942 : }
1943 :
1944 : // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1945 : // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1946 : // already-connected network ranges, ...) before trying new addrman addresses.
1947 319 : nTries++;
1948 319 : if (nTries > 100)
1949 0 : break;
1950 :
1951 319 : if (!IsReachable(addr))
1952 0 : continue;
1953 :
1954 : // only consider very recently tried nodes after 30 failed attempts
1955 319 : if (nANow - addr.nLastTry < 600 && nTries < 30)
1956 0 : continue;
1957 :
1958 : // for non-feelers, require all the services we'll want,
1959 : // for feelers, only require they be a full node (only because most
1960 : // SPV clients don't have a good address DB available)
1961 319 : if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
1962 0 : continue;
1963 319 : } else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
1964 0 : continue;
1965 : }
1966 :
1967 : // do not allow non-default ports, unless after 50 invalid addresses selected already
1968 319 : if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1969 313 : continue;
1970 :
1971 6 : addrConnect = addr;
1972 6 : break;
1973 25775 : }
1974 :
1975 25463 : if (addrConnect.IsValid()) {
1976 :
1977 6 : if (fFeeler) {
1978 : // Add small amount of random noise before connection to avoid synchronization.
1979 0 : int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
1980 0 : if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
1981 0 : return;
1982 0 : LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
1983 0 : }
1984 :
1985 6 : OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
1986 6 : }
1987 50926 : }
1988 495 : }
1989 :
1990 6743 : std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
1991 : {
1992 6743 : std::vector<AddedNodeInfo> ret;
1993 :
1994 6743 : std::list<std::string> lAddresses(0);
1995 : {
1996 6743 : LOCK(cs_vAddedNodes);
1997 6743 : ret.reserve(vAddedNodes.size());
1998 6743 : std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
1999 6743 : }
2000 :
2001 :
2002 : // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
2003 6743 : std::map<CService, bool> mapConnected;
2004 6743 : std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2005 : {
2006 6743 : LOCK(cs_vNodes);
2007 15994 : for (const CNode* pnode : vNodes) {
2008 9251 : if (pnode->addr.IsValid()) {
2009 9251 : mapConnected[pnode->addr] = pnode->IsInboundConn();
2010 9251 : }
2011 9251 : std::string addrName = pnode->GetAddrName();
2012 9251 : if (!addrName.empty()) {
2013 9251 : mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(), static_cast<const CService&>(pnode->addr));
2014 9251 : }
2015 9251 : }
2016 6743 : }
2017 :
2018 6745 : for (const std::string& strAddNode : lAddresses) {
2019 2 : CService service(LookupNumeric(strAddNode, Params().GetDefaultPort()));
2020 2 : AddedNodeInfo addedNode{strAddNode, CService(), false, false};
2021 2 : if (service.IsValid()) {
2022 : // strAddNode is an IP:port
2023 1 : auto it = mapConnected.find(service);
2024 1 : if (it != mapConnected.end()) {
2025 0 : addedNode.resolvedAddress = service;
2026 0 : addedNode.fConnected = true;
2027 0 : addedNode.fInbound = it->second;
2028 0 : }
2029 1 : } else {
2030 : // strAddNode is a name
2031 1 : auto it = mapConnectedByName.find(strAddNode);
2032 1 : if (it != mapConnectedByName.end()) {
2033 0 : addedNode.resolvedAddress = it->second.second;
2034 0 : addedNode.fConnected = true;
2035 0 : addedNode.fInbound = it->second.first;
2036 0 : }
2037 1 : }
2038 2 : ret.emplace_back(std::move(addedNode));
2039 2 : }
2040 :
2041 : return ret;
2042 6743 : }
2043 :
2044 492 : void CConnman::ThreadOpenAddedConnections()
2045 : {
2046 492 : while (true)
2047 : {
2048 6739 : CSemaphoreGrant grant(*semAddnode);
2049 6739 : std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
2050 13478 : bool tried = false;
2051 6740 : for (const AddedNodeInfo& info : vInfo) {
2052 1 : if (!info.fConnected) {
2053 1 : if (!grant.TryAcquire()) {
2054 : // If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
2055 : // the addednodeinfo state might change.
2056 0 : break;
2057 : }
2058 : tried = true;
2059 1 : CAddress addr(CService(), NODE_NONE);
2060 1 : OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
2061 1 : if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
2062 1 : return;
2063 1 : }
2064 0 : }
2065 : // Retry every 60 seconds if a connection was attempted, otherwise two seconds
2066 6738 : if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
2067 491 : return;
2068 6739 : }
2069 492 : }
2070 :
2071 : // if successful, this moves the passed grant to the constructed node
2072 258 : void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
2073 : {
2074 258 : assert(conn_type != ConnectionType::INBOUND);
2075 :
2076 : //
2077 : // Initiate outbound network connection
2078 : //
2079 258 : if (interruptNet) {
2080 : return;
2081 : }
2082 258 : if (!fNetworkActive) {
2083 : return;
2084 : }
2085 258 : if (!pszDest) {
2086 6 : bool banned_or_discouraged = m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect));
2087 6 : if (IsLocal(addrConnect) || FindNode(static_cast<CNetAddr>(addrConnect)) || banned_or_discouraged || FindNode(addrConnect.ToStringIPPort())) {
2088 0 : return;
2089 : }
2090 258 : } else if (FindNode(std::string(pszDest)))
2091 : return;
2092 :
2093 256 : CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2094 :
2095 256 : if (!pnode)
2096 8 : return;
2097 248 : if (grantOutbound)
2098 0 : grantOutbound->MoveTo(pnode->grantOutbound);
2099 :
2100 248 : m_msgproc->InitializeNode(pnode);
2101 : {
2102 248 : LOCK(cs_vNodes);
2103 248 : vNodes.push_back(pnode);
2104 248 : }
2105 258 : }
2106 :
2107 492 : void CConnman::ThreadMessageHandler()
2108 : {
2109 195132 : while (!flagInterruptMsgProc)
2110 : {
2111 194645 : std::vector<CNode*> vNodesCopy;
2112 : {
2113 194645 : LOCK(cs_vNodes);
2114 194645 : vNodesCopy = vNodes;
2115 483994 : for (CNode* pnode : vNodesCopy) {
2116 289349 : pnode->AddRef();
2117 : }
2118 194645 : }
2119 :
2120 678632 : bool fMoreWork = false;
2121 :
2122 483992 : for (CNode* pnode : vNodesCopy)
2123 : {
2124 289347 : if (pnode->fDisconnect)
2125 14 : continue;
2126 :
2127 : // Receive messages
2128 289333 : bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
2129 289333 : fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2130 289333 : if (flagInterruptMsgProc)
2131 2 : return;
2132 : // Send messages
2133 : {
2134 289331 : LOCK(pnode->cs_sendProcessing);
2135 289331 : m_msgproc->SendMessages(pnode);
2136 289331 : }
2137 :
2138 289331 : if (flagInterruptMsgProc)
2139 3 : return;
2140 578656 : }
2141 :
2142 : {
2143 194640 : LOCK(cs_vNodes);
2144 483981 : for (CNode* pnode : vNodesCopy)
2145 289341 : pnode->Release();
2146 194640 : }
2147 :
2148 194640 : WAIT_LOCK(mutexMsgProc, lock);
2149 194640 : if (!fMoreWork) {
2150 463861 : condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this]() EXCLUSIVE_LOCKS_REQUIRED(mutexMsgProc) { return fMsgProcWake; });
2151 158273 : }
2152 194640 : fMsgProcWake = false;
2153 194645 : }
2154 492 : }
2155 :
2156 493 : bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions)
2157 : {
2158 493 : int nOne = 1;
2159 :
2160 : // Create socket for listening for incoming connections
2161 493 : struct sockaddr_storage sockaddr;
2162 493 : socklen_t len = sizeof(sockaddr);
2163 493 : if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
2164 : {
2165 0 : strError = strprintf(Untranslated("Error: Bind address family for %s not supported"), addrBind.ToString());
2166 0 : LogPrintf("%s\n", strError.original);
2167 0 : return false;
2168 : }
2169 :
2170 493 : SOCKET hListenSocket = CreateSocket(addrBind);
2171 493 : if (hListenSocket == INVALID_SOCKET)
2172 : {
2173 0 : strError = strprintf(Untranslated("Error: Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError()));
2174 0 : LogPrintf("%s\n", strError.original);
2175 0 : return false;
2176 : }
2177 :
2178 : // Allow binding if the port is still in TIME_WAIT state after
2179 : // the program was closed and restarted.
2180 493 : setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int));
2181 :
2182 : // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
2183 : // and enable it by default or not. Try to enable it, if possible.
2184 493 : if (addrBind.IsIPv6()) {
2185 : #ifdef IPV6_V6ONLY
2186 1 : setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
2187 : #endif
2188 : #ifdef WIN32
2189 : int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2190 : setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
2191 : #endif
2192 1 : }
2193 :
2194 493 : if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
2195 : {
2196 0 : int nErr = WSAGetLastError();
2197 0 : if (nErr == WSAEADDRINUSE)
2198 0 : strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
2199 : else
2200 0 : strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
2201 0 : LogPrintf("%s\n", strError.original);
2202 0 : CloseSocket(hListenSocket);
2203 : return false;
2204 0 : }
2205 493 : LogPrintf("Bound to %s\n", addrBind.ToString());
2206 :
2207 : // Listen for incoming connections
2208 493 : if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
2209 : {
2210 0 : strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
2211 0 : LogPrintf("%s\n", strError.original);
2212 0 : CloseSocket(hListenSocket);
2213 0 : return false;
2214 : }
2215 :
2216 493 : vhListenSocket.push_back(ListenSocket(hListenSocket, permissions));
2217 :
2218 493 : if (addrBind.IsRoutable() && fDiscover && (permissions & PF_NOBAN) == 0)
2219 0 : AddLocal(addrBind, LOCAL_BIND);
2220 :
2221 493 : return true;
2222 493 : }
2223 :
2224 495 : void Discover()
2225 : {
2226 495 : if (!fDiscover)
2227 : return;
2228 :
2229 : #ifdef WIN32
2230 : // Get local host IP
2231 : char pszHostName[256] = "";
2232 : if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
2233 : {
2234 : std::vector<CNetAddr> vaddr;
2235 : if (LookupHost(pszHostName, vaddr, 0, true))
2236 : {
2237 : for (const CNetAddr &addr : vaddr)
2238 : {
2239 : if (AddLocal(addr, LOCAL_IF))
2240 : LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2241 : }
2242 : }
2243 : }
2244 : #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2245 : // Get local host ip
2246 0 : struct ifaddrs* myaddrs;
2247 0 : if (getifaddrs(&myaddrs) == 0)
2248 : {
2249 0 : for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
2250 : {
2251 0 : if (ifa->ifa_addr == nullptr) continue;
2252 0 : if ((ifa->ifa_flags & IFF_UP) == 0) continue;
2253 0 : if (strcmp(ifa->ifa_name, "lo") == 0) continue;
2254 0 : if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
2255 0 : if (ifa->ifa_addr->sa_family == AF_INET)
2256 : {
2257 0 : struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
2258 0 : CNetAddr addr(s4->sin_addr);
2259 0 : if (AddLocal(addr, LOCAL_IF))
2260 0 : LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2261 0 : }
2262 0 : else if (ifa->ifa_addr->sa_family == AF_INET6)
2263 : {
2264 0 : struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
2265 0 : CNetAddr addr(s6->sin6_addr);
2266 0 : if (AddLocal(addr, LOCAL_IF))
2267 0 : LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2268 0 : }
2269 : }
2270 0 : freeifaddrs(myaddrs);
2271 0 : }
2272 : #endif
2273 495 : }
2274 :
2275 615 : void CConnman::SetNetworkActive(bool active)
2276 : {
2277 615 : LogPrintf("%s: %s\n", __func__, active);
2278 :
2279 615 : if (fNetworkActive == active) {
2280 : return;
2281 : }
2282 :
2283 8 : fNetworkActive = active;
2284 :
2285 8 : uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
2286 615 : }
2287 :
2288 1219 : CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, bool network_active)
2289 610 : : nSeed0(nSeed0In), nSeed1(nSeed1In)
2290 609 : {
2291 610 : SetTryNewOutboundPeer(false);
2292 :
2293 610 : Options connOptions;
2294 610 : Init(connOptions);
2295 610 : SetNetworkActive(network_active);
2296 1219 : }
2297 :
2298 713 : NodeId CConnman::GetNewNodeId()
2299 : {
2300 713 : return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2301 : }
2302 :
2303 :
2304 493 : bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
2305 493 : if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
2306 0 : return false;
2307 493 : bilingual_str strError;
2308 493 : if (!BindListenPort(addr, strError, permissions)) {
2309 0 : if ((flags & BF_REPORT_ERROR) && clientInterface) {
2310 0 : clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
2311 0 : }
2312 0 : return false;
2313 : }
2314 493 : return true;
2315 493 : }
2316 :
2317 492 : bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds)
2318 : {
2319 : bool fBound = false;
2320 982 : for (const auto& addrBind : binds) {
2321 490 : fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::PF_NONE);
2322 : }
2323 493 : for (const auto& addrBind : whiteBinds) {
2324 1 : fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
2325 : }
2326 492 : if (binds.empty() && whiteBinds.empty()) {
2327 1 : struct in_addr inaddr_any;
2328 1 : inaddr_any.s_addr = INADDR_ANY;
2329 1 : struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2330 1 : fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
2331 1 : fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
2332 1 : }
2333 492 : return fBound;
2334 0 : }
2335 :
2336 492 : bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
2337 : {
2338 492 : Init(connOptions);
2339 :
2340 : {
2341 492 : LOCK(cs_totalBytesRecv);
2342 492 : nTotalBytesRecv = 0;
2343 492 : }
2344 : {
2345 492 : LOCK(cs_totalBytesSent);
2346 492 : nTotalBytesSent = 0;
2347 492 : nMaxOutboundTotalBytesSentInCycle = 0;
2348 492 : nMaxOutboundCycleStartTime = 0;
2349 492 : }
2350 :
2351 492 : if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
2352 0 : if (clientInterface) {
2353 0 : clientInterface->ThreadSafeMessageBox(
2354 0 : _("Failed to listen on any port. Use -listen=0 if you want this."),
2355 0 : "", CClientUIInterface::MSG_ERROR);
2356 0 : }
2357 0 : return false;
2358 : }
2359 :
2360 492 : for (const auto& strDest : connOptions.vSeedNodes) {
2361 0 : AddAddrFetch(strDest);
2362 : }
2363 :
2364 492 : if (clientInterface) {
2365 492 : clientInterface->InitMessage(_("Loading P2P addresses...").translated);
2366 492 : }
2367 : // Load addresses from peers.dat
2368 492 : int64_t nStart = GetTimeMillis();
2369 : {
2370 492 : CAddrDB adb;
2371 492 : if (adb.Read(addrman))
2372 188 : LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
2373 : else {
2374 304 : addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2375 304 : LogPrintf("Invalid or missing peers.dat; recreating\n");
2376 304 : DumpAddresses();
2377 : }
2378 492 : }
2379 :
2380 492 : uiInterface.InitMessage(_("Starting network threads...").translated);
2381 :
2382 492 : fAddressesInitialized = true;
2383 :
2384 492 : if (semOutbound == nullptr) {
2385 : // initialize semaphore
2386 492 : semOutbound = MakeUnique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
2387 492 : }
2388 492 : if (semAddnode == nullptr) {
2389 : // initialize semaphore
2390 492 : semAddnode = MakeUnique<CSemaphore>(nMaxAddnode);
2391 492 : }
2392 :
2393 : //
2394 : // Start threads
2395 : //
2396 492 : assert(m_msgproc);
2397 492 : InterruptSocks5(false);
2398 492 : interruptNet.reset();
2399 492 : flagInterruptMsgProc = false;
2400 :
2401 : {
2402 492 : LOCK(mutexMsgProc);
2403 492 : fMsgProcWake = false;
2404 492 : }
2405 :
2406 : // Send and receive from sockets, accept connections
2407 492 : threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
2408 :
2409 492 : if (!gArgs.GetBoolArg("-dnsseed", true))
2410 492 : LogPrintf("DNS seeding disabled\n");
2411 : else
2412 0 : threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
2413 :
2414 : // Initiate manual connections
2415 492 : threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
2416 :
2417 492 : if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2418 0 : if (clientInterface) {
2419 0 : clientInterface->ThreadSafeMessageBox(
2420 0 : _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
2421 0 : "", CClientUIInterface::MSG_ERROR);
2422 0 : }
2423 0 : return false;
2424 : }
2425 492 : if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty())
2426 492 : threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
2427 :
2428 : // Process messages
2429 492 : threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
2430 :
2431 : // Dump network addresses
2432 495 : scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
2433 :
2434 492 : return true;
2435 492 : }
2436 :
2437 : class CNetCleanup
2438 : {
2439 : public:
2440 1280 : CNetCleanup() {}
2441 :
2442 1280 : ~CNetCleanup()
2443 640 : {
2444 : #ifdef WIN32
2445 : // Shutdown Windows Sockets
2446 : WSACleanup();
2447 : #endif
2448 1280 : }
2449 : };
2450 640 : static CNetCleanup instance_of_cnetcleanup;
2451 :
2452 1117 : void CConnman::Interrupt()
2453 : {
2454 : {
2455 1117 : LOCK(mutexMsgProc);
2456 1117 : flagInterruptMsgProc = true;
2457 1117 : }
2458 1117 : condMsgProc.notify_all();
2459 :
2460 1117 : interruptNet();
2461 1117 : InterruptSocks5(true);
2462 :
2463 1117 : if (semOutbound) {
2464 5904 : for (int i=0; i<m_max_outbound; i++) {
2465 5412 : semOutbound->post();
2466 : }
2467 492 : }
2468 :
2469 1117 : if (semAddnode) {
2470 4428 : for (int i=0; i<nMaxAddnode; i++) {
2471 3936 : semAddnode->post();
2472 : }
2473 492 : }
2474 1117 : }
2475 :
2476 1117 : void CConnman::StopThreads()
2477 : {
2478 1117 : if (threadMessageHandler.joinable())
2479 492 : threadMessageHandler.join();
2480 1117 : if (threadOpenConnections.joinable())
2481 492 : threadOpenConnections.join();
2482 1117 : if (threadOpenAddedConnections.joinable())
2483 492 : threadOpenAddedConnections.join();
2484 1117 : if (threadDNSAddressSeed.joinable())
2485 0 : threadDNSAddressSeed.join();
2486 1117 : if (threadSocketHandler.joinable())
2487 492 : threadSocketHandler.join();
2488 1117 : }
2489 :
2490 1117 : void CConnman::StopNodes()
2491 : {
2492 1117 : if (fAddressesInitialized) {
2493 492 : DumpAddresses();
2494 492 : fAddressesInitialized = false;
2495 492 : }
2496 :
2497 : // Close sockets
2498 1117 : LOCK(cs_vNodes);
2499 1531 : for (CNode* pnode : vNodes)
2500 414 : pnode->CloseSocketDisconnect();
2501 1610 : for (ListenSocket& hListenSocket : vhListenSocket)
2502 493 : if (hListenSocket.socket != INVALID_SOCKET)
2503 493 : if (!CloseSocket(hListenSocket.socket))
2504 0 : LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2505 :
2506 : // clean up some globals (to help leak detection)
2507 1531 : for (CNode* pnode : vNodes) {
2508 414 : DeleteNode(pnode);
2509 : }
2510 1117 : for (CNode* pnode : vNodesDisconnected) {
2511 0 : DeleteNode(pnode);
2512 0 : }
2513 1117 : vNodes.clear();
2514 1117 : vNodesDisconnected.clear();
2515 1117 : vhListenSocket.clear();
2516 1117 : semOutbound.reset();
2517 1117 : semAddnode.reset();
2518 1117 : }
2519 :
2520 713 : void CConnman::DeleteNode(CNode* pnode)
2521 : {
2522 713 : assert(pnode);
2523 713 : bool fUpdateConnectionTime = false;
2524 713 : m_msgproc->FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
2525 713 : if (fUpdateConnectionTime) {
2526 237 : addrman.Connected(pnode->addr);
2527 237 : }
2528 713 : delete pnode;
2529 713 : }
2530 :
2531 1219 : CConnman::~CConnman()
2532 609 : {
2533 610 : Interrupt();
2534 610 : Stop();
2535 1219 : }
2536 :
2537 238 : void CConnman::SetServices(const CService &addr, ServiceFlags nServices)
2538 : {
2539 238 : addrman.SetServices(addr, nServices);
2540 238 : }
2541 :
2542 238 : void CConnman::MarkAddressGood(const CAddress& addr)
2543 : {
2544 238 : addrman.Good(addr);
2545 238 : }
2546 :
2547 10014 : bool CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
2548 : {
2549 10014 : return addrman.Add(vAddr, addrFrom, nTimePenalty);
2550 : }
2551 :
2552 190 : std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct)
2553 : {
2554 190 : std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct);
2555 190 : if (m_banman) {
2556 190 : addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2557 19303 : [this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
2558 190 : addresses.end());
2559 190 : }
2560 : return addresses;
2561 190 : }
2562 :
2563 244 : std::vector<CAddress> CConnman::GetAddresses(Network requestor_network, size_t max_addresses, size_t max_pct)
2564 : {
2565 244 : const auto current_time = GetTime<std::chrono::microseconds>();
2566 244 : if (m_addr_response_caches.find(requestor_network) == m_addr_response_caches.end() ||
2567 59 : m_addr_response_caches[requestor_network].m_update_addr_response < current_time) {
2568 186 : m_addr_response_caches[requestor_network].m_addrs_response_cache = GetAddresses(max_addresses, max_pct);
2569 186 : m_addr_response_caches[requestor_network].m_update_addr_response = current_time + std::chrono::hours(21) + GetRandMillis(std::chrono::hours(6));
2570 186 : }
2571 244 : return m_addr_response_caches[requestor_network].m_addrs_response_cache;
2572 244 : }
2573 :
2574 2 : bool CConnman::AddNode(const std::string& strNode)
2575 : {
2576 2 : LOCK(cs_vAddedNodes);
2577 3 : for (const std::string& it : vAddedNodes) {
2578 1 : if (strNode == it) return false;
2579 0 : }
2580 :
2581 1 : vAddedNodes.push_back(strNode);
2582 1 : return true;
2583 2 : }
2584 :
2585 2 : bool CConnman::RemoveAddedNode(const std::string& strNode)
2586 : {
2587 2 : LOCK(cs_vAddedNodes);
2588 3 : for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2589 1 : if (strNode == *it) {
2590 1 : vAddedNodes.erase(it);
2591 1 : return true;
2592 : }
2593 : }
2594 1 : return false;
2595 2 : }
2596 :
2597 154 : size_t CConnman::GetNodeCount(NumConnections flags)
2598 : {
2599 154 : LOCK(cs_vNodes);
2600 154 : if (flags == CConnman::CONNECTIONS_ALL) // Shortcut if we want total
2601 66 : return vNodes.size();
2602 :
2603 : int nNum = 0;
2604 174 : for (const auto& pnode : vNodes) {
2605 86 : if (flags & (pnode->IsInboundConn() ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
2606 43 : nNum++;
2607 43 : }
2608 : }
2609 :
2610 88 : return nNum;
2611 154 : }
2612 :
2613 4760 : void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
2614 : {
2615 4760 : vstats.clear();
2616 4760 : LOCK(cs_vNodes);
2617 4760 : vstats.reserve(vNodes.size());
2618 13395 : for (CNode* pnode : vNodes) {
2619 8635 : vstats.emplace_back();
2620 8635 : pnode->copyStats(vstats.back(), addrman.m_asmap);
2621 : }
2622 4760 : }
2623 :
2624 2 : bool CConnman::DisconnectNode(const std::string& strNode)
2625 : {
2626 2 : LOCK(cs_vNodes);
2627 2 : if (CNode* pnode = FindNode(strNode)) {
2628 1 : pnode->fDisconnect = true;
2629 1 : return true;
2630 : }
2631 1 : return false;
2632 2 : }
2633 :
2634 17 : bool CConnman::DisconnectNode(const CSubNet& subnet)
2635 : {
2636 : bool disconnected = false;
2637 17 : LOCK(cs_vNodes);
2638 21 : for (CNode* pnode : vNodes) {
2639 4 : if (subnet.Match(pnode->addr)) {
2640 4 : pnode->fDisconnect = true;
2641 : disconnected = true;
2642 4 : }
2643 : }
2644 17 : return disconnected;
2645 17 : }
2646 :
2647 8 : bool CConnman::DisconnectNode(const CNetAddr& addr)
2648 : {
2649 8 : return DisconnectNode(CSubNet(addr));
2650 0 : }
2651 :
2652 25 : bool CConnman::DisconnectNode(NodeId id)
2653 : {
2654 25 : LOCK(cs_vNodes);
2655 62 : for(CNode* pnode : vNodes) {
2656 37 : if (id == pnode->GetId()) {
2657 25 : pnode->fDisconnect = true;
2658 25 : return true;
2659 : }
2660 12 : }
2661 0 : return false;
2662 25 : }
2663 :
2664 104828 : void CConnman::RecordBytesRecv(uint64_t bytes)
2665 : {
2666 104828 : LOCK(cs_totalBytesRecv);
2667 104828 : nTotalBytesRecv += bytes;
2668 104828 : }
2669 :
2670 91140 : void CConnman::RecordBytesSent(uint64_t bytes)
2671 : {
2672 91140 : LOCK(cs_totalBytesSent);
2673 91140 : nTotalBytesSent += bytes;
2674 :
2675 91140 : uint64_t now = GetTime();
2676 91140 : if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
2677 : {
2678 : // timeframe expired, reset cycle
2679 304 : nMaxOutboundCycleStartTime = now;
2680 304 : nMaxOutboundTotalBytesSentInCycle = 0;
2681 304 : }
2682 :
2683 : // TODO, exclude peers with download permission
2684 91140 : nMaxOutboundTotalBytesSentInCycle += bytes;
2685 91140 : }
2686 :
2687 0 : void CConnman::SetMaxOutboundTarget(uint64_t limit)
2688 : {
2689 0 : LOCK(cs_totalBytesSent);
2690 0 : nMaxOutboundLimit = limit;
2691 0 : }
2692 :
2693 8 : uint64_t CConnman::GetMaxOutboundTarget()
2694 : {
2695 8 : LOCK(cs_totalBytesSent);
2696 8 : return nMaxOutboundLimit;
2697 8 : }
2698 :
2699 8 : uint64_t CConnman::GetMaxOutboundTimeframe()
2700 : {
2701 8 : LOCK(cs_totalBytesSent);
2702 8 : return nMaxOutboundTimeframe;
2703 8 : }
2704 :
2705 1110 : uint64_t CConnman::GetMaxOutboundTimeLeftInCycle()
2706 : {
2707 1110 : LOCK(cs_totalBytesSent);
2708 1110 : if (nMaxOutboundLimit == 0)
2709 8 : return 0;
2710 :
2711 1102 : if (nMaxOutboundCycleStartTime == 0)
2712 0 : return nMaxOutboundTimeframe;
2713 :
2714 1102 : uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2715 1102 : uint64_t now = GetTime();
2716 1102 : return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();
2717 1110 : }
2718 :
2719 0 : void CConnman::SetMaxOutboundTimeframe(uint64_t timeframe)
2720 : {
2721 0 : LOCK(cs_totalBytesSent);
2722 0 : if (nMaxOutboundTimeframe != timeframe)
2723 : {
2724 : // reset measure-cycle in case of changing
2725 : // the timeframe
2726 0 : nMaxOutboundCycleStartTime = GetTime();
2727 0 : }
2728 0 : nMaxOutboundTimeframe = timeframe;
2729 0 : }
2730 :
2731 15142 : bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit)
2732 : {
2733 15142 : LOCK(cs_totalBytesSent);
2734 15142 : if (nMaxOutboundLimit == 0)
2735 14040 : return false;
2736 :
2737 1102 : if (historicalBlockServingLimit)
2738 : {
2739 : // keep a large enough buffer to at least relay each block once
2740 1102 : uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
2741 1102 : uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SERIALIZED_SIZE;
2742 1102 : if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2743 823 : return true;
2744 279 : }
2745 0 : else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2746 0 : return true;
2747 :
2748 279 : return false;
2749 15142 : }
2750 :
2751 8 : uint64_t CConnman::GetOutboundTargetBytesLeft()
2752 : {
2753 8 : LOCK(cs_totalBytesSent);
2754 8 : if (nMaxOutboundLimit == 0)
2755 8 : return 0;
2756 :
2757 0 : return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2758 8 : }
2759 :
2760 8 : uint64_t CConnman::GetTotalBytesRecv()
2761 : {
2762 8 : LOCK(cs_totalBytesRecv);
2763 8 : return nTotalBytesRecv;
2764 8 : }
2765 :
2766 8 : uint64_t CConnman::GetTotalBytesSent()
2767 : {
2768 8 : LOCK(cs_totalBytesSent);
2769 8 : return nTotalBytesSent;
2770 8 : }
2771 :
2772 44 : ServiceFlags CConnman::GetLocalServices() const
2773 : {
2774 44 : return nLocalServices;
2775 : }
2776 :
2777 39878 : void CConnman::SetBestHeight(int height)
2778 : {
2779 39878 : nBestHeight.store(height, std::memory_order_release);
2780 39878 : }
2781 :
2782 713 : int CConnman::GetBestHeight() const
2783 : {
2784 713 : return nBestHeight.load(std::memory_order_acquire);
2785 : }
2786 :
2787 82766 : unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
2788 :
2789 2916 : CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in)
2790 729 : : nTimeConnected(GetSystemTimeInSeconds()),
2791 729 : addr(addrIn),
2792 729 : addrBind(addrBindIn),
2793 729 : nKeyedNetGroup(nKeyedNetGroupIn),
2794 : // Don't relay addr messages to peers that we connect to as block-relay-only
2795 : // peers (to prevent adversaries from inferring these links from addr
2796 : // traffic).
2797 729 : id(idIn),
2798 729 : nLocalHostNonce(nLocalHostNonceIn),
2799 729 : m_conn_type(conn_type_in),
2800 729 : nLocalServices(nLocalServicesIn),
2801 729 : nMyStartingHeight(nMyStartingHeightIn)
2802 729 : {
2803 729 : hSocket = hSocketIn;
2804 729 : addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2805 729 : hashContinue = uint256();
2806 729 : if (conn_type_in != ConnectionType::BLOCK_RELAY) {
2807 729 : m_tx_relay = MakeUnique<TxRelay>();
2808 729 : }
2809 :
2810 729 : if (RelayAddrsWithConn()) {
2811 729 : m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
2812 729 : }
2813 :
2814 24057 : for (const std::string &msg : getAllNetMessageTypes())
2815 23328 : mapRecvBytesPerMsgCmd[msg] = 0;
2816 729 : mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
2817 :
2818 729 : if (fLogIPs) {
2819 2 : LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
2820 : } else {
2821 727 : LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
2822 : }
2823 :
2824 729 : m_deserializer = MakeUnique<V1TransportDeserializer>(V1TransportDeserializer(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION));
2825 729 : m_serializer = MakeUnique<V1TransportSerializer>(V1TransportSerializer());
2826 1458 : }
2827 :
2828 1458 : CNode::~CNode()
2829 729 : {
2830 729 : CloseSocket(hSocket);
2831 1458 : }
2832 :
2833 126864 : bool CConnman::NodeFullyConnected(const CNode* pnode)
2834 : {
2835 126864 : return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
2836 : }
2837 :
2838 91268 : void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
2839 : {
2840 91268 : size_t nMessageSize = msg.data.size();
2841 91268 : LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", SanitizeString(msg.m_type), nMessageSize, pnode->GetId());
2842 :
2843 : // make sure we use the appropriate network transport format
2844 91268 : std::vector<unsigned char> serializedHeader;
2845 91268 : pnode->m_serializer->prepareForTransport(msg, serializedHeader);
2846 91268 : size_t nTotalSize = nMessageSize + serializedHeader.size();
2847 :
2848 : size_t nBytesSent = 0;
2849 : {
2850 91268 : LOCK(pnode->cs_vSend);
2851 91268 : bool optimisticSend(pnode->vSendMsg.empty());
2852 :
2853 : //log total amount of bytes per message type
2854 91268 : pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
2855 91268 : pnode->nSendSize += nTotalSize;
2856 :
2857 91268 : if (pnode->nSendSize > nSendBufferMaxSize)
2858 37 : pnode->fPauseSend = true;
2859 91268 : pnode->vSendMsg.push_back(std::move(serializedHeader));
2860 91268 : if (nMessageSize)
2861 88934 : pnode->vSendMsg.push_back(std::move(msg.data));
2862 :
2863 : // If write queue empty, attempt "optimistic write"
2864 91268 : if (optimisticSend == true)
2865 91059 : nBytesSent = SocketSendData(pnode);
2866 91268 : }
2867 91268 : if (nBytesSent)
2868 91046 : RecordBytesSent(nBytesSent);
2869 91268 : }
2870 :
2871 192 : bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
2872 : {
2873 : CNode* found = nullptr;
2874 192 : LOCK(cs_vNodes);
2875 469 : for (auto&& pnode : vNodes) {
2876 277 : if(pnode->GetId() == id) {
2877 190 : found = pnode;
2878 190 : break;
2879 : }
2880 87 : }
2881 192 : return found != nullptr && NodeFullyConnected(found) && func(found);
2882 192 : }
2883 :
2884 13350 : int64_t CConnman::PoissonNextSendInbound(int64_t now, int average_interval_seconds)
2885 : {
2886 13350 : if (m_next_send_inv_to_incoming < now) {
2887 : // If this function were called from multiple threads simultaneously
2888 : // it would possible that both update the next send variable, and return a different result to their caller.
2889 : // This is not possible in practice as only the net processing thread invokes this function.
2890 1584 : m_next_send_inv_to_incoming = PoissonNextSend(now, average_interval_seconds);
2891 1584 : }
2892 13350 : return m_next_send_inv_to_incoming;
2893 : }
2894 :
2895 8500 : int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
2896 : {
2897 8500 : return now + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
2898 : }
2899 :
2900 1436 : CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
2901 : {
2902 1436 : return CSipHasher(nSeed0, nSeed1).Write(id);
2903 : }
2904 :
2905 713 : uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const
2906 : {
2907 713 : std::vector<unsigned char> vchNetGroup(ad.GetGroup(addrman.m_asmap));
2908 :
2909 713 : return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
2910 713 : }
|