Bitcoin Core  22.99.0
P2P Digital Currency
net.cpp
Go to the documentation of this file.
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)
8 #endif
9 
10 #include <net.h>
11 
12 #include <banman.h>
13 #include <clientversion.h>
14 #include <compat.h>
15 #include <consensus/consensus.h>
16 #include <crypto/sha256.h>
17 #include <i2p.h>
18 #include <net_permissions.h>
19 #include <netaddress.h>
20 #include <netbase.h>
21 #include <node/ui_interface.h>
22 #include <protocol.h>
23 #include <random.h>
24 #include <scheduler.h>
25 #include <util/sock.h>
26 #include <util/strencodings.h>
27 #include <util/thread.h>
28 #include <util/trace.h>
29 #include <util/translation.h>
30 
31 #ifdef WIN32
32 #include <string.h>
33 #else
34 #include <fcntl.h>
35 #endif
36 
37 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
38 #include <ifaddrs.h>
39 #endif
40 
41 #ifdef USE_POLL
42 #include <poll.h>
43 #endif
44 
45 #include <algorithm>
46 #include <array>
47 #include <cstdint>
48 #include <functional>
49 #include <optional>
50 #include <unordered_map>
51 
52 #include <math.h>
53 
55 static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS = 2;
56 static_assert (MAX_BLOCK_RELAY_ONLY_ANCHORS <= static_cast<size_t>(MAX_BLOCK_RELAY_ONLY_CONNECTIONS), "MAX_BLOCK_RELAY_ONLY_ANCHORS must not exceed MAX_BLOCK_RELAY_ONLY_CONNECTIONS.");
58 const char* const ANCHORS_DATABASE_FILENAME = "anchors.dat";
59 
60 // How often to dump addresses to peers.dat
61 static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
62 
64 static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
65 
75 static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
76 static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
77 static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000; // "many" vs "few" peers
78 
80 static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME{60 * 60 * 24};
81 
82 // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
83 #define FEELER_SLEEP_WINDOW 1
84 
86 enum BindFlags {
87  BF_NONE = 0,
88  BF_EXPLICIT = (1U << 0),
89  BF_REPORT_ERROR = (1U << 1),
94  BF_DONT_ADVERTISE = (1U << 2),
95 };
96 
97 // The set of sockets cannot be modified while waiting
98 // The sleep time needs to be small to avoid new sockets stalling
99 static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
100 
101 const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
102 
103 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
104 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
105 static const uint64_t RANDOMIZER_ID_ADDRCACHE = 0x1cf2e4ddd306dda9ULL; // SHA256("addrcache")[0:8]
106 //
107 // Global state variables
108 //
109 bool fDiscover = true;
110 bool fListen = true;
112 std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
113 static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
114 std::string strSubVersion;
115 
116 void CConnman::AddAddrFetch(const std::string& strDest)
117 {
119  m_addr_fetches.push_back(strDest);
120 }
121 
122 uint16_t GetListenPort()
123 {
124  return static_cast<uint16_t>(gArgs.GetArg("-port", Params().GetDefaultPort()));
125 }
126 
127 // find 'best' local address for a particular peer
128 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
129 {
130  if (!fListen)
131  return false;
132 
133  int nBestScore = -1;
134  int nBestReachability = -1;
135  {
137  for (const auto& entry : mapLocalHost)
138  {
139  int nScore = entry.second.nScore;
140  int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
141  if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
142  {
143  addr = CService(entry.first, entry.second.nPort);
144  nBestReachability = nReachability;
145  nBestScore = nScore;
146  }
147  }
148  }
149  return nBestScore >= 0;
150 }
151 
153 static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
154 {
155  // It'll only connect to one or two seed nodes because once it connects,
156  // it'll get a pile of addresses with newer timestamps.
157  // Seed nodes are given a random 'last seen time' of between one and two
158  // weeks ago.
159  const int64_t nOneWeek = 7*24*60*60;
160  std::vector<CAddress> vSeedsOut;
161  FastRandomContext rng;
163  while (!s.eof()) {
164  CService endpoint;
165  s >> endpoint;
167  addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
168  LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString());
169  vSeedsOut.push_back(addr);
170  }
171  return vSeedsOut;
172 }
173 
174 // get best local address for a particular peer as a CAddress
175 // Otherwise, return the unroutable 0.0.0.0 but filled in with
176 // the normal parameters, since the IP may be changed to a useful
177 // one by discovery.
178 CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
179 {
180  CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices);
181  CService addr;
182  if (GetLocal(addr, paddrPeer))
183  {
184  ret = CAddress(addr, nLocalServices);
185  }
186  ret.nTime = GetAdjustedTime();
187  return ret;
188 }
189 
190 static int GetnScore(const CService& addr)
191 {
193  if (mapLocalHost.count(addr) == 0) return 0;
194  return mapLocalHost[addr].nScore;
195 }
196 
197 // Is our peer's addrLocal potentially useful as an external IP source?
199 {
200  CService addrLocal = pnode->GetAddrLocal();
201  return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
202  IsReachable(addrLocal.GetNetwork());
203 }
204 
205 std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode)
206 {
207  CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
208  if (gArgs.GetBoolArg("-addrmantest", false)) {
209  // use IPv4 loopback during addrmantest
210  addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
211  }
212  // If discovery is enabled, sometimes give our peer the address it
213  // tells us that it sees us as in case it has a better idea of our
214  // address than we do.
215  FastRandomContext rng;
216  if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
217  rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0))
218  {
219  addrLocal.SetIP(pnode->GetAddrLocal());
220  }
221  if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
222  {
223  LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n", addrLocal.ToString(), pnode->GetId());
224  return addrLocal;
225  }
226  // Address is unroutable. Don't advertise.
227  return std::nullopt;
228 }
229 
230 // learn a new local address
231 bool AddLocal(const CService& addr, int nScore)
232 {
233  if (!addr.IsRoutable())
234  return false;
235 
236  if (!fDiscover && nScore < LOCAL_MANUAL)
237  return false;
238 
239  if (!IsReachable(addr))
240  return false;
241 
242  LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
243 
244  {
246  bool fAlready = mapLocalHost.count(addr) > 0;
247  LocalServiceInfo &info = mapLocalHost[addr];
248  if (!fAlready || nScore >= info.nScore) {
249  info.nScore = nScore + (fAlready ? 1 : 0);
250  info.nPort = addr.GetPort();
251  }
252  }
253 
254  return true;
255 }
256 
257 bool AddLocal(const CNetAddr &addr, int nScore)
258 {
259  return AddLocal(CService(addr, GetListenPort()), nScore);
260 }
261 
262 void RemoveLocal(const CService& addr)
263 {
265  LogPrintf("RemoveLocal(%s)\n", addr.ToString());
266  mapLocalHost.erase(addr);
267 }
268 
269 void SetReachable(enum Network net, bool reachable)
270 {
271  if (net == NET_UNROUTABLE || net == NET_INTERNAL)
272  return;
274  vfLimited[net] = !reachable;
275 }
276 
277 bool IsReachable(enum Network net)
278 {
280  return !vfLimited[net];
281 }
282 
283 bool IsReachable(const CNetAddr &addr)
284 {
285  return IsReachable(addr.GetNetwork());
286 }
287 
289 bool SeenLocal(const CService& addr)
290 {
291  {
293  if (mapLocalHost.count(addr) == 0)
294  return false;
295  mapLocalHost[addr].nScore++;
296  }
297  return true;
298 }
299 
300 
302 bool IsLocal(const CService& addr)
303 {
305  return mapLocalHost.count(addr) > 0;
306 }
307 
309 {
310  LOCK(cs_vNodes);
311  for (CNode* pnode : vNodes) {
312  if (static_cast<CNetAddr>(pnode->addr) == ip) {
313  return pnode;
314  }
315  }
316  return nullptr;
317 }
318 
320 {
321  LOCK(cs_vNodes);
322  for (CNode* pnode : vNodes) {
323  if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
324  return pnode;
325  }
326  }
327  return nullptr;
328 }
329 
330 CNode* CConnman::FindNode(const std::string& addrName)
331 {
332  LOCK(cs_vNodes);
333  for (CNode* pnode : vNodes) {
334  if (pnode->GetAddrName() == addrName) {
335  return pnode;
336  }
337  }
338  return nullptr;
339 }
340 
342 {
343  LOCK(cs_vNodes);
344  for (CNode* pnode : vNodes) {
345  if (static_cast<CService>(pnode->addr) == addr) {
346  return pnode;
347  }
348  }
349  return nullptr;
350 }
351 
353 {
354  return FindNode(static_cast<CNetAddr>(addr)) || FindNode(addr.ToStringIPPort());
355 }
356 
358 {
359  LOCK(cs_vNodes);
360  for (const CNode* pnode : vNodes) {
361  if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
362  return false;
363  }
364  return true;
365 }
366 
369 {
370  CAddress addr_bind;
371  struct sockaddr_storage sockaddr_bind;
372  socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
373  if (sock != INVALID_SOCKET) {
374  if (!getsockname(sock, (struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
375  addr_bind.SetSockAddr((const struct sockaddr*)&sockaddr_bind);
376  } else {
377  LogPrint(BCLog::NET, "Warning: getsockname failed\n");
378  }
379  }
380  return addr_bind;
381 }
382 
383 CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
384 {
385  assert(conn_type != ConnectionType::INBOUND);
386 
387  if (pszDest == nullptr) {
388  if (IsLocal(addrConnect))
389  return nullptr;
390 
391  // Look for an existing connection
392  CNode* pnode = FindNode(static_cast<CService>(addrConnect));
393  if (pnode)
394  {
395  LogPrintf("Failed to open new connection, already connected\n");
396  return nullptr;
397  }
398  }
399 
401  LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
402  pszDest ? pszDest : addrConnect.ToString(),
403  pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
404 
405  // Resolve
406  const uint16_t default_port{pszDest != nullptr ? Params().GetDefaultPort(pszDest) :
407  Params().GetDefaultPort()};
408  if (pszDest) {
409  std::vector<CService> resolved;
410  if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
411  addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
412  if (!addrConnect.IsValid()) {
413  LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
414  return nullptr;
415  }
416  // It is possible that we already have a connection to the IP/port pszDest resolved to.
417  // In that case, drop the connection that was just created, and return the existing CNode instead.
418  // Also store the name we used to connect in that CNode, so that future FindNode() calls to that
419  // name catch this early.
420  LOCK(cs_vNodes);
421  CNode* pnode = FindNode(static_cast<CService>(addrConnect));
422  if (pnode)
423  {
424  pnode->MaybeSetAddrName(std::string(pszDest));
425  LogPrintf("Failed to open new connection, already connected\n");
426  return nullptr;
427  }
428  }
429  }
430 
431  // Connect
432  bool connected = false;
433  std::unique_ptr<Sock> sock;
434  proxyType proxy;
435  CAddress addr_bind;
436  assert(!addr_bind.IsValid());
437 
438  if (addrConnect.IsValid()) {
439  bool proxyConnectionFailed = false;
440 
441  if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) {
442  i2p::Connection conn;
443  if (m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed)) {
444  connected = true;
445  sock = std::move(conn.sock);
446  addr_bind = CAddress{conn.me, NODE_NONE};
447  }
448  } else if (GetProxy(addrConnect.GetNetwork(), proxy)) {
449  sock = CreateSock(proxy.proxy);
450  if (!sock) {
451  return nullptr;
452  }
453  connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(),
454  *sock, nConnectTimeout, proxyConnectionFailed);
455  } else {
456  // no proxy needed (none set for target network)
457  sock = CreateSock(addrConnect);
458  if (!sock) {
459  return nullptr;
460  }
461  connected = ConnectSocketDirectly(addrConnect, *sock, nConnectTimeout,
462  conn_type == ConnectionType::MANUAL);
463  }
464  if (!proxyConnectionFailed) {
465  // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
466  // the proxy, mark this as an attempt.
467  addrman.Attempt(addrConnect, fCountFailure);
468  }
469  } else if (pszDest && GetNameProxy(proxy)) {
470  sock = CreateSock(proxy.proxy);
471  if (!sock) {
472  return nullptr;
473  }
474  std::string host;
475  uint16_t port{default_port};
476  SplitHostPort(std::string(pszDest), port, host);
477  bool proxyConnectionFailed;
478  connected = ConnectThroughProxy(proxy, host, port, *sock, nConnectTimeout,
479  proxyConnectionFailed);
480  }
481  if (!connected) {
482  return nullptr;
483  }
484 
485  // Add node
486  NodeId id = GetNewNodeId();
488  if (!addr_bind.IsValid()) {
489  addr_bind = GetBindAddress(sock->Get());
490  }
491  CNode* pnode = new CNode(id, nLocalServices, sock->Release(), addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type, /* inbound_onion */ false);
492  pnode->AddRef();
493 
494  // We're making a new connection, harvest entropy from the time (and our peer count)
495  RandAddEvent((uint32_t)id);
496 
497  return pnode;
498 }
499 
501 {
502  fDisconnect = true;
503  LOCK(cs_hSocket);
504  if (hSocket != INVALID_SOCKET)
505  {
506  LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
507  CloseSocket(hSocket);
508  }
509 }
510 
512  for (const auto& subnet : vWhitelistedRange) {
513  if (subnet.m_subnet.Match(addr)) NetPermissions::AddFlag(flags, subnet.m_flags);
514  }
515 }
516 
518 {
519  switch (conn_type) {
521  return "inbound";
523  return "manual";
525  return "feeler";
527  return "outbound-full-relay";
529  return "block-relay-only";
531  return "addr-fetch";
532  } // no default case, so the compiler can warn about missing cases
533 
534  assert(false);
535 }
536 
537 std::string CNode::GetAddrName() const {
538  LOCK(cs_addrName);
539  return addrName;
540 }
541 
542 void CNode::MaybeSetAddrName(const std::string& addrNameIn) {
543  LOCK(cs_addrName);
544  if (addrName.empty()) {
545  addrName = addrNameIn;
546  }
547 }
548 
551  return addrLocal;
552 }
553 
554 void CNode::SetAddrLocal(const CService& addrLocalIn) {
556  if (addrLocal.IsValid()) {
557  error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
558  } else {
559  addrLocal = addrLocalIn;
560  }
561 }
562 
564 {
566 }
567 
568 #undef X
569 #define X(name) stats.name = name
570 void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
571 {
572  stats.nodeid = this->GetId();
573  X(nServices);
574  X(addr);
575  X(addrBind);
577  stats.m_mapped_as = addr.GetMappedAS(m_asmap);
578  if (m_tx_relay != nullptr) {
579  LOCK(m_tx_relay->cs_filter);
580  stats.fRelayTxes = m_tx_relay->fRelayTxes;
581  } else {
582  stats.fRelayTxes = false;
583  }
584  X(nLastSend);
585  X(nLastRecv);
586  X(nLastTXTime);
587  X(nLastBlockTime);
588  X(nTimeConnected);
589  X(nTimeOffset);
590  stats.addrName = GetAddrName();
591  X(nVersion);
592  {
593  LOCK(cs_SubVer);
594  X(cleanSubVer);
595  }
596  stats.fInbound = IsInboundConn();
599  {
600  LOCK(cs_vSend);
601  X(mapSendBytesPerMsgCmd);
602  X(nSendBytes);
603  }
604  {
605  LOCK(cs_vRecv);
606  X(mapRecvBytesPerMsgCmd);
607  X(nRecvBytes);
608  }
610  if (m_tx_relay != nullptr) {
611  stats.minFeeFilter = m_tx_relay->minFeeFilter;
612  } else {
613  stats.minFeeFilter = 0;
614  }
615 
618 
619  // Leave string empty if addrLocal invalid (not filled in yet)
620  CService addrLocalUnlocked = GetAddrLocal();
621  stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
622 
623  X(m_conn_type);
624 }
625 #undef X
626 
627 bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
628 {
629  complete = false;
630  const auto time = GetTime<std::chrono::microseconds>();
631  LOCK(cs_vRecv);
632  nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count();
633  nRecvBytes += msg_bytes.size();
634  while (msg_bytes.size() > 0) {
635  // absorb network data
636  int handled = m_deserializer->Read(msg_bytes);
637  if (handled < 0) {
638  // Serious header problem, disconnect from the peer.
639  return false;
640  }
641 
642  if (m_deserializer->Complete()) {
643  // decompose a transport agnostic CNetMessage from the deserializer
644  uint32_t out_err_raw_size{0};
645  std::optional<CNetMessage> result{m_deserializer->GetMessage(time, out_err_raw_size)};
646  if (!result) {
647  // Message deserialization failed. Drop the message but don't disconnect the peer.
648  // store the size of the corrupt message
649  mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER)->second += out_err_raw_size;
650  continue;
651  }
652 
653  //store received bytes per message command
654  //to prevent a memory DOS, only allow valid commands
655  mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(result->m_command);
656  if (i == mapRecvBytesPerMsgCmd.end())
657  i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
658  assert(i != mapRecvBytesPerMsgCmd.end());
659  i->second += result->m_raw_message_size;
660 
661  // push the message to the process queue,
662  vRecvMsg.push_back(std::move(*result));
663 
664  complete = true;
665  }
666  }
667 
668  return true;
669 }
670 
672 {
673  // copy data to temporary parsing buffer
674  unsigned int nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
675  unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
676 
677  memcpy(&hdrbuf[nHdrPos], msg_bytes.data(), nCopy);
678  nHdrPos += nCopy;
679 
680  // if header incomplete, exit
682  return nCopy;
683 
684  // deserialize to CMessageHeader
685  try {
686  hdrbuf >> hdr;
687  }
688  catch (const std::exception&) {
689  LogPrint(BCLog::NET, "Header error: Unable to deserialize, peer=%d\n", m_node_id);
690  return -1;
691  }
692 
693  // Check start string, network magic
695  LogPrint(BCLog::NET, "Header error: Wrong MessageStart %s received, peer=%d\n", HexStr(hdr.pchMessageStart), m_node_id);
696  return -1;
697  }
698 
699  // reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH
701  LogPrint(BCLog::NET, "Header error: Size too large (%s, %u bytes), peer=%d\n", SanitizeString(hdr.GetCommand()), hdr.nMessageSize, m_node_id);
702  return -1;
703  }
704 
705  // switch state to reading message data
706  in_data = true;
707 
708  return nCopy;
709 }
710 
712 {
713  unsigned int nRemaining = hdr.nMessageSize - nDataPos;
714  unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
715 
716  if (vRecv.size() < nDataPos + nCopy) {
717  // Allocate up to 256 KiB ahead, but never more than the total message size.
718  vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
719  }
720 
721  hasher.Write(msg_bytes.first(nCopy));
722  memcpy(&vRecv[nDataPos], msg_bytes.data(), nCopy);
723  nDataPos += nCopy;
724 
725  return nCopy;
726 }
727 
729 {
730  assert(Complete());
731  if (data_hash.IsNull())
733  return data_hash;
734 }
735 
736 std::optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::microseconds time, uint32_t& out_err_raw_size)
737 {
738  // decompose a single CNetMessage from the TransportDeserializer
739  std::optional<CNetMessage> msg(std::move(vRecv));
740 
741  // store command string, time, and sizes
742  msg->m_command = hdr.GetCommand();
743  msg->m_time = time;
744  msg->m_message_size = hdr.nMessageSize;
745  msg->m_raw_message_size = hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
746 
747  uint256 hash = GetMessageHash();
748 
749  // We just received a message off the wire, harvest entropy from the time (and the message checksum)
750  RandAddEvent(ReadLE32(hash.begin()));
751 
752  // Check checksum and header command string
753  if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
754  LogPrint(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
755  SanitizeString(msg->m_command), msg->m_message_size,
758  m_node_id);
759  out_err_raw_size = msg->m_raw_message_size;
760  msg = std::nullopt;
761  } else if (!hdr.IsCommandValid()) {
762  LogPrint(BCLog::NET, "Header error: Invalid message type (%s, %u bytes), peer=%d\n",
763  SanitizeString(hdr.GetCommand()), msg->m_message_size, m_node_id);
764  out_err_raw_size = msg->m_raw_message_size;
765  msg.reset();
766  }
767 
768  // Always reset the network deserializer (prepare for the next message)
769  Reset();
770  return msg;
771 }
772 
773 void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) {
774  // create dbl-sha256 checksum
775  uint256 hash = Hash(msg.data);
776 
777  // create header
778  CMessageHeader hdr(Params().MessageStart(), msg.m_type.c_str(), msg.data.size());
779  memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
780 
781  // serialize header
782  header.reserve(CMessageHeader::HEADER_SIZE);
783  CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, header, 0, hdr};
784 }
785 
787 {
788  auto it = node.vSendMsg.begin();
789  size_t nSentSize = 0;
790 
791  while (it != node.vSendMsg.end()) {
792  const auto& data = *it;
793  assert(data.size() > node.nSendOffset);
794  int nBytes = 0;
795  {
796  LOCK(node.cs_hSocket);
797  if (node.hSocket == INVALID_SOCKET)
798  break;
799  nBytes = send(node.hSocket, reinterpret_cast<const char*>(data.data()) + node.nSendOffset, data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
800  }
801  if (nBytes > 0) {
802  node.nLastSend = GetTimeSeconds();
803  node.nSendBytes += nBytes;
804  node.nSendOffset += nBytes;
805  nSentSize += nBytes;
806  if (node.nSendOffset == data.size()) {
807  node.nSendOffset = 0;
808  node.nSendSize -= data.size();
809  node.fPauseSend = node.nSendSize > nSendBufferMaxSize;
810  it++;
811  } else {
812  // could not send full message; stop sending more
813  break;
814  }
815  } else {
816  if (nBytes < 0) {
817  // error
818  int nErr = WSAGetLastError();
819  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
820  LogPrint(BCLog::NET, "socket send error for peer=%d: %s\n", node.GetId(), NetworkErrorString(nErr));
821  node.CloseSocketDisconnect();
822  }
823  }
824  // couldn't send anything at all
825  break;
826  }
827  }
828 
829  if (it == node.vSendMsg.end()) {
830  assert(node.nSendOffset == 0);
831  assert(node.nSendSize == 0);
832  }
833  node.vSendMsg.erase(node.vSendMsg.begin(), it);
834  return nSentSize;
835 }
836 
838 {
839  return a.m_min_ping_time > b.m_min_ping_time;
840 }
841 
843 {
844  return a.nTimeConnected > b.nTimeConnected;
845 }
846 
848  return a.nKeyedNetGroup < b.nKeyedNetGroup;
849 }
850 
852 {
853  // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
856  return a.nTimeConnected > b.nTimeConnected;
857 }
858 
860 {
861  // 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.
862  if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime;
863  if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes;
864  if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
865  return a.nTimeConnected > b.nTimeConnected;
866 }
867 
868 // Pick out the potential block-relay only peers, and sort them by last block time.
870 {
871  if (a.fRelayTxes != b.fRelayTxes) return a.fRelayTxes;
874  return a.nTimeConnected > b.nTimeConnected;
875 }
876 
886  const bool m_is_local;
888  CompareNodeNetworkTime(bool is_local, Network network) : m_is_local(is_local), m_network(network) {}
890  {
891  if (m_is_local && a.m_is_local != b.m_is_local) return b.m_is_local;
892  if ((a.m_network == m_network) != (b.m_network == m_network)) return b.m_network == m_network;
893  return a.nTimeConnected > b.nTimeConnected;
894  };
895 };
896 
898 template <typename T, typename Comparator>
899 static void EraseLastKElements(
900  std::vector<T>& elements, Comparator comparator, size_t k,
901  std::function<bool(const NodeEvictionCandidate&)> predicate = [](const NodeEvictionCandidate& n) { return true; })
902 {
903  std::sort(elements.begin(), elements.end(), comparator);
904  size_t eraseSize = std::min(k, elements.size());
905  elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
906 }
907 
908 void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& eviction_candidates)
909 {
910  // Protect the half of the remaining nodes which have been connected the longest.
911  // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
912  // To favorise the diversity of our peer connections, reserve up to half of these protected
913  // spots for Tor/onion, localhost and I2P peers, even if they're not longest uptime overall.
914  // This helps protect these higher-latency peers that tend to be otherwise
915  // disadvantaged under our eviction criteria.
916  const size_t initial_size = eviction_candidates.size();
917  const size_t total_protect_size{initial_size / 2};
918 
919  // Disadvantaged networks to protect: I2P, localhost, Tor/onion. In case of equal counts, earlier
920  // array members have first opportunity to recover unused slots from the previous iteration.
921  struct Net { bool is_local; Network id; size_t count; };
922  std::array<Net, 3> networks{
923  {{false, NET_I2P, 0}, {/* localhost */ true, NET_MAX, 0}, {false, NET_ONION, 0}}};
924 
925  // Count and store the number of eviction candidates per network.
926  for (Net& n : networks) {
927  n.count = std::count_if(eviction_candidates.cbegin(), eviction_candidates.cend(),
928  [&n](const NodeEvictionCandidate& c) {
929  return n.is_local ? c.m_is_local : c.m_network == n.id;
930  });
931  }
932  // Sort `networks` by ascending candidate count, to give networks having fewer candidates
933  // the first opportunity to recover unused protected slots from the previous iteration.
934  std::stable_sort(networks.begin(), networks.end(), [](Net a, Net b) { return a.count < b.count; });
935 
936  // Protect up to 25% of the eviction candidates by disadvantaged network.
937  const size_t max_protect_by_network{total_protect_size / 2};
938  size_t num_protected{0};
939 
940  while (num_protected < max_protect_by_network) {
941  // Count the number of disadvantaged networks from which we have peers to protect.
942  auto num_networks = std::count_if(networks.begin(), networks.end(), [](const Net& n) { return n.count; });
943  if (num_networks == 0) {
944  break;
945  }
946  const size_t disadvantaged_to_protect{max_protect_by_network - num_protected};
947  const size_t protect_per_network{std::max(disadvantaged_to_protect / num_networks, static_cast<size_t>(1))};
948  // Early exit flag if there are no remaining candidates by disadvantaged network.
949  bool protected_at_least_one{false};
950 
951  for (Net& n : networks) {
952  if (n.count == 0) continue;
953  const size_t before = eviction_candidates.size();
954  EraseLastKElements(eviction_candidates, CompareNodeNetworkTime(n.is_local, n.id),
955  protect_per_network, [&n](const NodeEvictionCandidate& c) {
956  return n.is_local ? c.m_is_local : c.m_network == n.id;
957  });
958  const size_t after = eviction_candidates.size();
959  if (before > after) {
960  protected_at_least_one = true;
961  const size_t delta{before - after};
962  num_protected += delta;
963  if (num_protected >= max_protect_by_network) {
964  break;
965  }
966  n.count -= delta;
967  }
968  }
969  if (!protected_at_least_one) {
970  break;
971  }
972  }
973 
974  // Calculate how many we removed, and update our total number of peers that
975  // we want to protect based on uptime accordingly.
976  assert(num_protected == initial_size - eviction_candidates.size());
977  const size_t remaining_to_protect{total_protect_size - num_protected};
978  EraseLastKElements(eviction_candidates, ReverseCompareNodeTimeConnected, remaining_to_protect);
979 }
980 
981 [[nodiscard]] std::optional<NodeId> SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates)
982 {
983  // Protect connections with certain characteristics
984 
985  // Deterministically select 4 peers to protect by netgroup.
986  // An attacker cannot predict which netgroups will be protected
987  EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
988  // Protect the 8 nodes with the lowest minimum ping time.
989  // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
990  EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
991  // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
992  // An attacker cannot manipulate this metric without performing useful work.
993  EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
994  // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
995  EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
996  [](const NodeEvictionCandidate& n) { return !n.fRelayTxes && n.fRelevantServices; });
997 
998  // Protect 4 nodes that most recently sent us novel blocks.
999  // An attacker cannot manipulate this metric without performing useful work.
1000  EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
1001 
1002  // Protect some of the remaining eviction candidates by ratios of desirable
1003  // or disadvantaged characteristics.
1004  ProtectEvictionCandidatesByRatio(vEvictionCandidates);
1005 
1006  if (vEvictionCandidates.empty()) return std::nullopt;
1007 
1008  // If any remaining peers are preferred for eviction consider only them.
1009  // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
1010  // then we probably don't want to evict it no matter what.
1011  if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
1012  vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1013  [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
1014  }
1015 
1016  // Identify the network group with the most connections and youngest member.
1017  // (vEvictionCandidates is already sorted by reverse connect time)
1018  uint64_t naMostConnections;
1019  unsigned int nMostConnections = 0;
1020  int64_t nMostConnectionsTime = 0;
1021  std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1022  for (const NodeEvictionCandidate &node : vEvictionCandidates) {
1023  std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
1024  group.push_back(node);
1025  const int64_t grouptime = group[0].nTimeConnected;
1026 
1027  if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1028  nMostConnections = group.size();
1029  nMostConnectionsTime = grouptime;
1030  naMostConnections = node.nKeyedNetGroup;
1031  }
1032  }
1033 
1034  // Reduce to the network group with the most connections
1035  vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1036 
1037  // Disconnect from the network group with the most connections
1038  return vEvictionCandidates.front().id;
1039 }
1040 
1050 {
1051  std::vector<NodeEvictionCandidate> vEvictionCandidates;
1052  {
1053 
1054  LOCK(cs_vNodes);
1055  for (const CNode* node : vNodes) {
1056  if (node->HasPermission(NetPermissionFlags::NoBan))
1057  continue;
1058  if (!node->IsInboundConn())
1059  continue;
1060  if (node->fDisconnect)
1061  continue;
1062  bool peer_relay_txes = false;
1063  bool peer_filter_not_null = false;
1064  if (node->m_tx_relay != nullptr) {
1065  LOCK(node->m_tx_relay->cs_filter);
1066  peer_relay_txes = node->m_tx_relay->fRelayTxes;
1067  peer_filter_not_null = node->m_tx_relay->pfilter != nullptr;
1068  }
1069  NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->m_min_ping_time,
1070  node->nLastBlockTime, node->nLastTXTime,
1071  HasAllDesirableServiceFlags(node->nServices),
1072  peer_relay_txes, peer_filter_not_null, node->nKeyedNetGroup,
1073  node->m_prefer_evict, node->addr.IsLocal(),
1074  node->ConnectedThroughNetwork()};
1075  vEvictionCandidates.push_back(candidate);
1076  }
1077  }
1078  const std::optional<NodeId> node_id_to_evict = SelectNodeToEvict(std::move(vEvictionCandidates));
1079  if (!node_id_to_evict) {
1080  return false;
1081  }
1082  LOCK(cs_vNodes);
1083  for (CNode* pnode : vNodes) {
1084  if (pnode->GetId() == *node_id_to_evict) {
1085  LogPrint(BCLog::NET, "selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId());
1086  pnode->fDisconnect = true;
1087  return true;
1088  }
1089  }
1090  return false;
1091 }
1092 
1093 void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
1094  struct sockaddr_storage sockaddr;
1095  socklen_t len = sizeof(sockaddr);
1096  SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
1097  CAddress addr;
1098 
1099  if (hSocket == INVALID_SOCKET) {
1100  const int nErr = WSAGetLastError();
1101  if (nErr != WSAEWOULDBLOCK) {
1102  LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
1103  }
1104  return;
1105  }
1106 
1107  if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
1108  LogPrintf("Warning: Unknown socket family\n");
1109  }
1110 
1111  const CAddress addr_bind = GetBindAddress(hSocket);
1112 
1113  NetPermissionFlags permissionFlags = NetPermissionFlags::None;
1114  hListenSocket.AddSocketPermissionFlags(permissionFlags);
1115 
1116  CreateNodeFromAcceptedSocket(hSocket, permissionFlags, addr_bind, addr);
1117 }
1118 
1120  NetPermissionFlags permissionFlags,
1121  const CAddress& addr_bind,
1122  const CAddress& addr)
1123 {
1124  int nInbound = 0;
1125  int nMaxInbound = nMaxConnections - m_max_outbound;
1126 
1127  AddWhitelistPermissionFlags(permissionFlags, addr);
1128  if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::Implicit)) {
1134  }
1135 
1136  {
1137  LOCK(cs_vNodes);
1138  for (const CNode* pnode : vNodes) {
1139  if (pnode->IsInboundConn()) nInbound++;
1140  }
1141  }
1142 
1143  if (!fNetworkActive) {
1144  LogPrint(BCLog::NET, "connection from %s dropped: not accepting new connections\n", addr.ToString());
1145  CloseSocket(hSocket);
1146  return;
1147  }
1148 
1149  if (!IsSelectableSocket(hSocket))
1150  {
1151  LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
1152  CloseSocket(hSocket);
1153  return;
1154  }
1155 
1156  // According to the internet TCP_NODELAY is not carried into accepted sockets
1157  // on all platforms. Set it again here just to be sure.
1158  SetSocketNoDelay(hSocket);
1159 
1160  // Don't accept connections from banned peers.
1161  bool banned = m_banman && m_banman->IsBanned(addr);
1162  if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && banned)
1163  {
1164  LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
1165  CloseSocket(hSocket);
1166  return;
1167  }
1168 
1169  // Only accept connections from discouraged peers if our inbound slots aren't (almost) full.
1170  bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1171  if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && nInbound + 1 >= nMaxInbound && discouraged)
1172  {
1173  LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString());
1174  CloseSocket(hSocket);
1175  return;
1176  }
1177 
1178  if (nInbound >= nMaxInbound)
1179  {
1180  if (!AttemptToEvictConnection()) {
1181  // No connection to evict, disconnect the new connection
1182  LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
1183  CloseSocket(hSocket);
1184  return;
1185  }
1186  }
1187 
1188  NodeId id = GetNewNodeId();
1190 
1191  ServiceFlags nodeServices = nLocalServices;
1193  nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
1194  }
1195 
1196  const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1197  CNode* pnode = new CNode(id, nodeServices, hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND, inbound_onion);
1198  pnode->AddRef();
1199  pnode->m_permissionFlags = permissionFlags;
1200  pnode->m_prefer_evict = discouraged;
1201  m_msgproc->InitializeNode(pnode);
1202 
1203  LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1204 
1205  {
1206  LOCK(cs_vNodes);
1207  vNodes.push_back(pnode);
1208  }
1209 
1210  // We received a new connection, harvest entropy from the time (and our peer count)
1211  RandAddEvent((uint32_t)id);
1212 }
1213 
1214 bool CConnman::AddConnection(const std::string& address, ConnectionType conn_type)
1215 {
1216  std::optional<int> max_connections;
1217  switch (conn_type) {
1221  return false;
1223  max_connections = m_max_outbound_full_relay;
1224  break;
1226  max_connections = m_max_outbound_block_relay;
1227  break;
1228  // no limit for ADDR_FETCH because -seednode has no limit either
1230  break;
1231  } // no default case, so the compiler can warn about missing cases
1232 
1233  // Count existing connections
1234  int existing_connections = WITH_LOCK(cs_vNodes,
1235  return std::count_if(vNodes.begin(), vNodes.end(), [conn_type](CNode* node) { return node->m_conn_type == conn_type; }););
1236 
1237  // Max connections of specified type already exist
1238  if (max_connections != std::nullopt && existing_connections >= max_connections) return false;
1239 
1240  // Max total outbound connections already exist
1241  CSemaphoreGrant grant(*semOutbound, true);
1242  if (!grant) return false;
1243 
1244  OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type);
1245  return true;
1246 }
1247 
1249 {
1250  {
1251  LOCK(cs_vNodes);
1252 
1253  if (!fNetworkActive) {
1254  // Disconnect any connected nodes
1255  for (CNode* pnode : vNodes) {
1256  if (!pnode->fDisconnect) {
1257  LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
1258  pnode->fDisconnect = true;
1259  }
1260  }
1261  }
1262 
1263  // Disconnect unused nodes
1264  std::vector<CNode*> vNodesCopy = vNodes;
1265  for (CNode* pnode : vNodesCopy)
1266  {
1267  if (pnode->fDisconnect)
1268  {
1269  // remove from vNodes
1270  vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1271 
1272  // release outbound grant (if any)
1273  pnode->grantOutbound.Release();
1274 
1275  // close socket and cleanup
1276  pnode->CloseSocketDisconnect();
1277 
1278  // hold in disconnected pool until all refs are released
1279  pnode->Release();
1280  vNodesDisconnected.push_back(pnode);
1281  }
1282  }
1283  }
1284  {
1285  // Delete disconnected nodes
1286  std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1287  for (CNode* pnode : vNodesDisconnectedCopy)
1288  {
1289  // Destroy the object only after other threads have stopped using it.
1290  if (pnode->GetRefCount() <= 0) {
1291  vNodesDisconnected.remove(pnode);
1292  DeleteNode(pnode);
1293  }
1294  }
1295  }
1296 }
1297 
1299 {
1300  size_t vNodesSize;
1301  {
1302  LOCK(cs_vNodes);
1303  vNodesSize = vNodes.size();
1304  }
1305  if(vNodesSize != nPrevNodeCount) {
1306  nPrevNodeCount = vNodesSize;
1307  if(clientInterface)
1308  clientInterface->NotifyNumConnectionsChanged(vNodesSize);
1309  }
1310 }
1311 
1312 bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::optional<int64_t> now_in) const
1313 {
1314  const int64_t now = now_in ? now_in.value() : GetTimeSeconds();
1315  return node.nTimeConnected + m_peer_connect_timeout < now;
1316 }
1317 
1319 {
1320  // Use non-mockable system time (otherwise these timers will pop when we
1321  // use setmocktime in the tests).
1322  int64_t now = GetTimeSeconds();
1323 
1324  if (!ShouldRunInactivityChecks(node, now)) return false;
1325 
1326  if (node.nLastRecv == 0 || node.nLastSend == 0) {
1327  LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d peer=%d\n", m_peer_connect_timeout, node.nLastRecv != 0, node.nLastSend != 0, node.GetId());
1328  return true;
1329  }
1330 
1331  if (now > node.nLastSend + TIMEOUT_INTERVAL) {
1332  LogPrint(BCLog::NET, "socket sending timeout: %is peer=%d\n", now - node.nLastSend, node.GetId());
1333  return true;
1334  }
1335 
1336  if (now > node.nLastRecv + TIMEOUT_INTERVAL) {
1337  LogPrint(BCLog::NET, "socket receive timeout: %is peer=%d\n", now - node.nLastRecv, node.GetId());
1338  return true;
1339  }
1340 
1341  if (!node.fSuccessfullyConnected) {
1342  LogPrint(BCLog::NET, "version handshake timeout peer=%d\n", node.GetId());
1343  return true;
1344  }
1345 
1346  return false;
1347 }
1348 
1349 bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1350 {
1351  for (const ListenSocket& hListenSocket : vhListenSocket) {
1352  recv_set.insert(hListenSocket.socket);
1353  }
1354 
1355  {
1356  LOCK(cs_vNodes);
1357  for (CNode* pnode : vNodes)
1358  {
1359  // Implement the following logic:
1360  // * If there is data to send, select() for sending data. As this only
1361  // happens when optimistic write failed, we choose to first drain the
1362  // write buffer in this case before receiving more. This avoids
1363  // needlessly queueing received data, if the remote peer is not themselves
1364  // receiving data. This means properly utilizing TCP flow control signalling.
1365  // * Otherwise, if there is space left in the receive buffer, select() for
1366  // receiving data.
1367  // * Hand off all complete messages to the processor, to be handled without
1368  // blocking here.
1369 
1370  bool select_recv = !pnode->fPauseRecv;
1371  bool select_send;
1372  {
1373  LOCK(pnode->cs_vSend);
1374  select_send = !pnode->vSendMsg.empty();
1375  }
1376 
1377  LOCK(pnode->cs_hSocket);
1378  if (pnode->hSocket == INVALID_SOCKET)
1379  continue;
1380 
1381  error_set.insert(pnode->hSocket);
1382  if (select_send) {
1383  send_set.insert(pnode->hSocket);
1384  continue;
1385  }
1386  if (select_recv) {
1387  recv_set.insert(pnode->hSocket);
1388  }
1389  }
1390  }
1391 
1392  return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1393 }
1394 
1395 #ifdef USE_POLL
1396 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1397 {
1398  std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1399  if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1400  interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1401  return;
1402  }
1403 
1404  std::unordered_map<SOCKET, struct pollfd> pollfds;
1405  for (SOCKET socket_id : recv_select_set) {
1406  pollfds[socket_id].fd = socket_id;
1407  pollfds[socket_id].events |= POLLIN;
1408  }
1409 
1410  for (SOCKET socket_id : send_select_set) {
1411  pollfds[socket_id].fd = socket_id;
1412  pollfds[socket_id].events |= POLLOUT;
1413  }
1414 
1415  for (SOCKET socket_id : error_select_set) {
1416  pollfds[socket_id].fd = socket_id;
1417  // These flags are ignored, but we set them for clarity
1418  pollfds[socket_id].events |= POLLERR|POLLHUP;
1419  }
1420 
1421  std::vector<struct pollfd> vpollfds;
1422  vpollfds.reserve(pollfds.size());
1423  for (auto it : pollfds) {
1424  vpollfds.push_back(std::move(it.second));
1425  }
1426 
1427  if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
1428 
1429  if (interruptNet) return;
1430 
1431  for (struct pollfd pollfd_entry : vpollfds) {
1432  if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1433  if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1434  if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1435  }
1436 }
1437 #else
1438 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1439 {
1440  std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1441  if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1442  interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1443  return;
1444  }
1445 
1446  //
1447  // Find which sockets have data to receive
1448  //
1449  struct timeval timeout;
1450  timeout.tv_sec = 0;
1451  timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
1452 
1453  fd_set fdsetRecv;
1454  fd_set fdsetSend;
1455  fd_set fdsetError;
1456  FD_ZERO(&fdsetRecv);
1457  FD_ZERO(&fdsetSend);
1458  FD_ZERO(&fdsetError);
1459  SOCKET hSocketMax = 0;
1460 
1461  for (SOCKET hSocket : recv_select_set) {
1462  FD_SET(hSocket, &fdsetRecv);
1463  hSocketMax = std::max(hSocketMax, hSocket);
1464  }
1465 
1466  for (SOCKET hSocket : send_select_set) {
1467  FD_SET(hSocket, &fdsetSend);
1468  hSocketMax = std::max(hSocketMax, hSocket);
1469  }
1470 
1471  for (SOCKET hSocket : error_select_set) {
1472  FD_SET(hSocket, &fdsetError);
1473  hSocketMax = std::max(hSocketMax, hSocket);
1474  }
1475 
1476  int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1477 
1478  if (interruptNet)
1479  return;
1480 
1481  if (nSelect == SOCKET_ERROR)
1482  {
1483  int nErr = WSAGetLastError();
1484  LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1485  for (unsigned int i = 0; i <= hSocketMax; i++)
1486  FD_SET(i, &fdsetRecv);
1487  FD_ZERO(&fdsetSend);
1488  FD_ZERO(&fdsetError);
1489  if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1490  return;
1491  }
1492 
1493  for (SOCKET hSocket : recv_select_set) {
1494  if (FD_ISSET(hSocket, &fdsetRecv)) {
1495  recv_set.insert(hSocket);
1496  }
1497  }
1498 
1499  for (SOCKET hSocket : send_select_set) {
1500  if (FD_ISSET(hSocket, &fdsetSend)) {
1501  send_set.insert(hSocket);
1502  }
1503  }
1504 
1505  for (SOCKET hSocket : error_select_set) {
1506  if (FD_ISSET(hSocket, &fdsetError)) {
1507  error_set.insert(hSocket);
1508  }
1509  }
1510 }
1511 #endif
1512 
1514 {
1515  std::set<SOCKET> recv_set, send_set, error_set;
1516  SocketEvents(recv_set, send_set, error_set);
1517 
1518  if (interruptNet) return;
1519 
1520  //
1521  // Accept new connections
1522  //
1523  for (const ListenSocket& hListenSocket : vhListenSocket)
1524  {
1525  if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1526  {
1527  AcceptConnection(hListenSocket);
1528  }
1529  }
1530 
1531  //
1532  // Service each socket
1533  //
1534  std::vector<CNode*> vNodesCopy;
1535  {
1536  LOCK(cs_vNodes);
1537  vNodesCopy = vNodes;
1538  for (CNode* pnode : vNodesCopy)
1539  pnode->AddRef();
1540  }
1541  for (CNode* pnode : vNodesCopy)
1542  {
1543  if (interruptNet)
1544  return;
1545 
1546  //
1547  // Receive
1548  //
1549  bool recvSet = false;
1550  bool sendSet = false;
1551  bool errorSet = false;
1552  {
1553  LOCK(pnode->cs_hSocket);
1554  if (pnode->hSocket == INVALID_SOCKET)
1555  continue;
1556  recvSet = recv_set.count(pnode->hSocket) > 0;
1557  sendSet = send_set.count(pnode->hSocket) > 0;
1558  errorSet = error_set.count(pnode->hSocket) > 0;
1559  }
1560  if (recvSet || errorSet)
1561  {
1562  // typical socket buffer is 8K-64K
1563  uint8_t pchBuf[0x10000];
1564  int nBytes = 0;
1565  {
1566  LOCK(pnode->cs_hSocket);
1567  if (pnode->hSocket == INVALID_SOCKET)
1568  continue;
1569  nBytes = recv(pnode->hSocket, (char*)pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1570  }
1571  if (nBytes > 0)
1572  {
1573  bool notify = false;
1574  if (!pnode->ReceiveMsgBytes(Span<const uint8_t>(pchBuf, nBytes), notify))
1575  pnode->CloseSocketDisconnect();
1576  RecordBytesRecv(nBytes);
1577  if (notify) {
1578  size_t nSizeAdded = 0;
1579  auto it(pnode->vRecvMsg.begin());
1580  for (; it != pnode->vRecvMsg.end(); ++it) {
1581  // vRecvMsg contains only completed CNetMessage
1582  // the single possible partially deserialized message are held by TransportDeserializer
1583  nSizeAdded += it->m_raw_message_size;
1584  }
1585  {
1586  LOCK(pnode->cs_vProcessMsg);
1587  pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1588  pnode->nProcessQueueSize += nSizeAdded;
1589  pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1590  }
1592  }
1593  }
1594  else if (nBytes == 0)
1595  {
1596  // socket closed gracefully
1597  if (!pnode->fDisconnect) {
1598  LogPrint(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
1599  }
1600  pnode->CloseSocketDisconnect();
1601  }
1602  else if (nBytes < 0)
1603  {
1604  // error
1605  int nErr = WSAGetLastError();
1606  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1607  {
1608  if (!pnode->fDisconnect) {
1609  LogPrint(BCLog::NET, "socket recv error for peer=%d: %s\n", pnode->GetId(), NetworkErrorString(nErr));
1610  }
1611  pnode->CloseSocketDisconnect();
1612  }
1613  }
1614  }
1615 
1616  if (sendSet) {
1617  // Send data
1618  size_t bytes_sent = WITH_LOCK(pnode->cs_vSend, return SocketSendData(*pnode));
1619  if (bytes_sent) RecordBytesSent(bytes_sent);
1620  }
1621 
1622  if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
1623  }
1624  {
1625  LOCK(cs_vNodes);
1626  for (CNode* pnode : vNodesCopy)
1627  pnode->Release();
1628  }
1629 }
1630 
1632 {
1633  while (!interruptNet)
1634  {
1635  DisconnectNodes();
1637  SocketHandler();
1638  }
1639 }
1640 
1642 {
1643  {
1644  LOCK(mutexMsgProc);
1645  fMsgProcWake = true;
1646  }
1647  condMsgProc.notify_one();
1648 }
1649 
1651 {
1652  FastRandomContext rng;
1653  std::vector<std::string> seeds = Params().DNSSeeds();
1654  Shuffle(seeds.begin(), seeds.end(), rng);
1655  int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
1656  int found = 0;
1657 
1658  if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
1659  // When -forcednsseed is provided, query all.
1660  seeds_right_now = seeds.size();
1661  } else if (addrman.size() == 0) {
1662  // If we have no known peers, query all.
1663  // This will occur on the first run, or if peers.dat has been
1664  // deleted.
1665  seeds_right_now = seeds.size();
1666  }
1667 
1668  // goal: only query DNS seed if address need is acute
1669  // * If we have a reasonable number of peers in addrman, spend
1670  // some time trying them first. This improves user privacy by
1671  // creating fewer identifying DNS requests, reduces trust by
1672  // giving seeds less influence on the network topology, and
1673  // reduces traffic to the seeds.
1674  // * When querying DNS seeds query a few at once, this ensures
1675  // that we don't give DNS seeds the ability to eclipse nodes
1676  // that query them.
1677  // * If we continue having problems, eventually query all the
1678  // DNS seeds, and if that fails too, also try the fixed seeds.
1679  // (done in ThreadOpenConnections)
1680  const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
1681 
1682  for (const std::string& seed : seeds) {
1683  if (seeds_right_now == 0) {
1684  seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1685 
1686  if (addrman.size() > 0) {
1687  LogPrintf("Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1688  std::chrono::seconds to_wait = seeds_wait_time;
1689  while (to_wait.count() > 0) {
1690  // if sleeping for the MANY_PEERS interval, wake up
1691  // early to see if we have enough peers and can stop
1692  // this thread entirely freeing up its resources
1693  std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
1694  if (!interruptNet.sleep_for(w)) return;
1695  to_wait -= w;
1696 
1697  int nRelevant = 0;
1698  {
1699  LOCK(cs_vNodes);
1700  for (const CNode* pnode : vNodes) {
1701  if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant;
1702  }
1703  }
1704  if (nRelevant >= 2) {
1705  if (found > 0) {
1706  LogPrintf("%d addresses found from DNS seeds\n", found);
1707  LogPrintf("P2P peers available. Finished DNS seeding.\n");
1708  } else {
1709  LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1710  }
1711  return;
1712  }
1713  }
1714  }
1715  }
1716 
1717  if (interruptNet) return;
1718 
1719  // hold off on querying seeds if P2P network deactivated
1720  if (!fNetworkActive) {
1721  LogPrintf("Waiting for network to be reactivated before querying DNS seeds.\n");
1722  do {
1723  if (!interruptNet.sleep_for(std::chrono::seconds{1})) return;
1724  } while (!fNetworkActive);
1725  }
1726 
1727  LogPrintf("Loading addresses from DNS seed %s\n", seed);
1728  if (HaveNameProxy()) {
1729  AddAddrFetch(seed);
1730  } else {
1731  std::vector<CNetAddr> vIPs;
1732  std::vector<CAddress> vAdd;
1733  ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
1734  std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
1735  CNetAddr resolveSource;
1736  if (!resolveSource.SetInternal(host)) {
1737  continue;
1738  }
1739  unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
1740  if (LookupHost(host, vIPs, nMaxIPs, true)) {
1741  for (const CNetAddr& ip : vIPs) {
1742  int nOneDay = 24*3600;
1743  CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1744  addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
1745  vAdd.push_back(addr);
1746  found++;
1747  }
1748  addrman.Add(vAdd, resolveSource);
1749  } else {
1750  // We now avoid directly using results from DNS Seeds which do not support service bit filtering,
1751  // instead using them as a addrfetch to get nodes with our desired service bits.
1752  AddAddrFetch(seed);
1753  }
1754  }
1755  --seeds_right_now;
1756  }
1757  LogPrintf("%d addresses found from DNS seeds\n", found);
1758 }
1759 
1761 {
1762  int64_t nStart = GetTimeMillis();
1763 
1764  CAddrDB adb;
1765  adb.Write(addrman);
1766 
1767  LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1768  addrman.size(), GetTimeMillis() - nStart);
1769 }
1770 
1772 {
1773  std::string strDest;
1774  {
1776  if (m_addr_fetches.empty())
1777  return;
1778  strDest = m_addr_fetches.front();
1779  m_addr_fetches.pop_front();
1780  }
1781  CAddress addr;
1782  CSemaphoreGrant grant(*semOutbound, true);
1783  if (grant) {
1784  OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
1785  }
1786 }
1787 
1789 {
1791 }
1792 
1794 {
1796  LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
1797 }
1798 
1799 // Return the number of peers we have over our outbound connection limit
1800 // Exclude peers that are marked for disconnect, or are going to be
1801 // disconnected soon (eg ADDR_FETCH and FEELER)
1802 // Also exclude peers that haven't finished initial connection handshake yet
1803 // (so that we don't decide we're over our desired connection limit, and then
1804 // evict some peer that has finished the handshake)
1806 {
1807  int full_outbound_peers = 0;
1808  {
1809  LOCK(cs_vNodes);
1810  for (const CNode* pnode : vNodes) {
1811  if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsFullOutboundConn()) {
1812  ++full_outbound_peers;
1813  }
1814  }
1815  }
1816  return std::max(full_outbound_peers - m_max_outbound_full_relay, 0);
1817 }
1818 
1820 {
1821  int block_relay_peers = 0;
1822  {
1823  LOCK(cs_vNodes);
1824  for (const CNode* pnode : vNodes) {
1825  if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsBlockOnlyConn()) {
1826  ++block_relay_peers;
1827  }
1828  }
1829  }
1830  return std::max(block_relay_peers - m_max_outbound_block_relay, 0);
1831 }
1832 
1833 void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
1834 {
1835  // Connect to specific addresses
1836  if (!connect.empty())
1837  {
1838  for (int64_t nLoop = 0;; nLoop++)
1839  {
1840  ProcessAddrFetch();
1841  for (const std::string& strAddr : connect)
1842  {
1843  CAddress addr(CService(), NODE_NONE);
1844  OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
1845  for (int i = 0; i < 10 && i < nLoop; i++)
1846  {
1847  if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1848  return;
1849  }
1850  }
1851  if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1852  return;
1853  }
1854  }
1855 
1856  // Initiate network connections
1857  auto start = GetTime<std::chrono::microseconds>();
1858 
1859  // Minimum time before next feeler connection (in microseconds).
1860  auto next_feeler = PoissonNextSend(start, FEELER_INTERVAL);
1861  auto next_extra_block_relay = PoissonNextSend(start, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
1862  const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
1863  bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
1864 
1865  if (!add_fixed_seeds) {
1866  LogPrintf("Fixed seeds are disabled\n");
1867  }
1868 
1869  while (!interruptNet)
1870  {
1871  ProcessAddrFetch();
1872 
1873  if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1874  return;
1875 
1876  CSemaphoreGrant grant(*semOutbound);
1877  if (interruptNet)
1878  return;
1879 
1880  if (add_fixed_seeds && addrman.size() == 0) {
1881  // When the node starts with an empty peers.dat, there are a few other sources of peers before
1882  // we fallback on to fixed seeds: -dnsseed, -seednode, -addnode
1883  // If none of those are available, we fallback on to fixed seeds immediately, else we allow
1884  // 60 seconds for any of those sources to populate addrman.
1885  bool add_fixed_seeds_now = false;
1886  // It is cheapest to check if enough time has passed first.
1887  if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
1888  add_fixed_seeds_now = true;
1889  LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
1890  }
1891 
1892  // Checking !dnsseed is cheaper before locking 2 mutexes.
1893  if (!add_fixed_seeds_now && !dnsseed) {
1895  if (m_addr_fetches.empty() && vAddedNodes.empty()) {
1896  add_fixed_seeds_now = true;
1897  LogPrintf("Adding fixed seeds as -dnsseed=0, -addnode is not provided and all -seednode(s) attempted\n");
1898  }
1899  }
1900 
1901  if (add_fixed_seeds_now) {
1902  CNetAddr local;
1903  local.SetInternal("fixedseeds");
1904  addrman.Add(ConvertSeeds(Params().FixedSeeds()), local);
1905  add_fixed_seeds = false;
1906  }
1907  }
1908 
1909  //
1910  // Choose an address to connect to based on most recently seen
1911  //
1912  CAddress addrConnect;
1913 
1914  // Only connect out to one peer per network group (/16 for IPv4).
1915  int nOutboundFullRelay = 0;
1916  int nOutboundBlockRelay = 0;
1917  std::set<std::vector<unsigned char> > setConnected;
1918 
1919  {
1920  LOCK(cs_vNodes);
1921  for (const CNode* pnode : vNodes) {
1922  if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1923  if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1924 
1925  // Netgroups for inbound and manual peers are not excluded because our goal here
1926  // is to not use multiple of our limited outbound slots on a single netgroup
1927  // but inbound and manual peers do not use our outbound slots. Inbound peers
1928  // also have the added issue that they could be attacker controlled and used
1929  // to prevent us from connecting to particular hosts if we used them here.
1930  switch (pnode->m_conn_type) {
1933  break;
1938  setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
1939  } // no default case, so the compiler can warn about missing cases
1940  }
1941  }
1942 
1944  auto now = GetTime<std::chrono::microseconds>();
1945  bool anchor = false;
1946  bool fFeeler = false;
1947 
1948  // Determine what type of connection to open. Opening
1949  // BLOCK_RELAY connections to addresses from anchors.dat gets the highest
1950  // priority. Then we open OUTBOUND_FULL_RELAY priority until we
1951  // meet our full-relay capacity. Then we open BLOCK_RELAY connection
1952  // until we hit our block-relay-only peer limit.
1953  // GetTryNewOutboundPeer() gets set when a stale tip is detected, so we
1954  // try opening an additional OUTBOUND_FULL_RELAY connection. If none of
1955  // these conditions are met, check to see if it's time to try an extra
1956  // block-relay-only peer (to confirm our tip is current, see below) or the next_feeler
1957  // timer to decide if we should open a FEELER.
1958 
1959  if (!m_anchors.empty() && (nOutboundBlockRelay < m_max_outbound_block_relay)) {
1960  conn_type = ConnectionType::BLOCK_RELAY;
1961  anchor = true;
1962  } else if (nOutboundFullRelay < m_max_outbound_full_relay) {
1963  // OUTBOUND_FULL_RELAY
1964  } else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
1965  conn_type = ConnectionType::BLOCK_RELAY;
1966  } else if (GetTryNewOutboundPeer()) {
1967  // OUTBOUND_FULL_RELAY
1968  } else if (now > next_extra_block_relay && m_start_extra_block_relay_peers) {
1969  // Periodically connect to a peer (using regular outbound selection
1970  // methodology from addrman) and stay connected long enough to sync
1971  // headers, but not much else.
1972  //
1973  // Then disconnect the peer, if we haven't learned anything new.
1974  //
1975  // The idea is to make eclipse attacks very difficult to pull off,
1976  // because every few minutes we're finding a new peer to learn headers
1977  // from.
1978  //
1979  // This is similar to the logic for trying extra outbound (full-relay)
1980  // peers, except:
1981  // - we do this all the time on a poisson timer, rather than just when
1982  // our tip is stale
1983  // - we potentially disconnect our next-youngest block-relay-only peer, if our
1984  // newest block-relay-only peer delivers a block more recently.
1985  // See the eviction logic in net_processing.cpp.
1986  //
1987  // Because we can promote these connections to block-relay-only
1988  // connections, they do not get their own ConnectionType enum
1989  // (similar to how we deal with extra outbound peers).
1990  next_extra_block_relay = PoissonNextSend(now, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
1991  conn_type = ConnectionType::BLOCK_RELAY;
1992  } else if (now > next_feeler) {
1993  next_feeler = PoissonNextSend(now, FEELER_INTERVAL);
1994  conn_type = ConnectionType::FEELER;
1995  fFeeler = true;
1996  } else {
1997  // skip to next iteration of while loop
1998  continue;
1999  }
2000 
2002 
2003  int64_t nANow = GetAdjustedTime();
2004  int nTries = 0;
2005  while (!interruptNet)
2006  {
2007  if (anchor && !m_anchors.empty()) {
2008  const CAddress addr = m_anchors.back();
2009  m_anchors.pop_back();
2010  if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) ||
2012  setConnected.count(addr.GetGroup(addrman.m_asmap))) continue;
2013  addrConnect = addr;
2014  LogPrint(BCLog::NET, "Trying to make an anchor connection to %s\n", addrConnect.ToString());
2015  break;
2016  }
2017 
2018  // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
2019  // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
2020  // already-connected network ranges, ...) before trying new addrman addresses.
2021  nTries++;
2022  if (nTries > 100)
2023  break;
2024 
2025  CAddrInfo addr;
2026 
2027  if (fFeeler) {
2028  // First, try to get a tried table collision address. This returns
2029  // an empty (invalid) address if there are no collisions to try.
2030  addr = addrman.SelectTriedCollision();
2031 
2032  if (!addr.IsValid()) {
2033  // No tried table collisions. Select a new table address
2034  // for our feeler.
2035  addr = addrman.Select(true);
2036  } else if (AlreadyConnectedToAddress(addr)) {
2037  // If test-before-evict logic would have us connect to a
2038  // peer that we're already connected to, just mark that
2039  // address as Good(). We won't be able to initiate the
2040  // connection anyway, so this avoids inadvertently evicting
2041  // a currently-connected peer.
2042  addrman.Good(addr);
2043  // Select a new table address for our feeler instead.
2044  addr = addrman.Select(true);
2045  }
2046  } else {
2047  // Not a feeler
2048  addr = addrman.Select();
2049  }
2050 
2051  // Require outbound connections, other than feelers, to be to distinct network groups
2052  if (!fFeeler && setConnected.count(addr.GetGroup(addrman.m_asmap))) {
2053  break;
2054  }
2055 
2056  // if we selected an invalid or local address, restart
2057  if (!addr.IsValid() || IsLocal(addr)) {
2058  break;
2059  }
2060 
2061  if (!IsReachable(addr))
2062  continue;
2063 
2064  // only consider very recently tried nodes after 30 failed attempts
2065  if (nANow - addr.nLastTry < 600 && nTries < 30)
2066  continue;
2067 
2068  // for non-feelers, require all the services we'll want,
2069  // for feelers, only require they be a full node (only because most
2070  // SPV clients don't have a good address DB available)
2071  if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
2072  continue;
2073  } else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
2074  continue;
2075  }
2076 
2077  // Do not allow non-default ports, unless after 50 invalid
2078  // addresses selected already. This is to prevent malicious peers
2079  // from advertising themselves as a service on another host and
2080  // port, causing a DoS attack as nodes around the network attempt
2081  // to connect to it fruitlessly.
2082  if (addr.GetPort() != Params().GetDefaultPort(addr.GetNetwork()) && nTries < 50) {
2083  continue;
2084  }
2085 
2086  addrConnect = addr;
2087  break;
2088  }
2089 
2090  if (addrConnect.IsValid()) {
2091 
2092  if (fFeeler) {
2093  // Add small amount of random noise before connection to avoid synchronization.
2094  int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
2095  if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
2096  return;
2097  LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
2098  }
2099 
2100  OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
2101  }
2102  }
2103 }
2104 
2105 std::vector<CAddress> CConnman::GetCurrentBlockRelayOnlyConns() const
2106 {
2107  std::vector<CAddress> ret;
2108  LOCK(cs_vNodes);
2109  for (const CNode* pnode : vNodes) {
2110  if (pnode->IsBlockOnlyConn()) {
2111  ret.push_back(pnode->addr);
2112  }
2113  }
2114 
2115  return ret;
2116 }
2117 
2118 std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() const
2119 {
2120  std::vector<AddedNodeInfo> ret;
2121 
2122  std::list<std::string> lAddresses(0);
2123  {
2125  ret.reserve(vAddedNodes.size());
2126  std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
2127  }
2128 
2129 
2130  // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
2131  std::map<CService, bool> mapConnected;
2132  std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2133  {
2134  LOCK(cs_vNodes);
2135  for (const CNode* pnode : vNodes) {
2136  if (pnode->addr.IsValid()) {
2137  mapConnected[pnode->addr] = pnode->IsInboundConn();
2138  }
2139  std::string addrName = pnode->GetAddrName();
2140  if (!addrName.empty()) {
2141  mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(), static_cast<const CService&>(pnode->addr));
2142  }
2143  }
2144  }
2145 
2146  for (const std::string& strAddNode : lAddresses) {
2147  CService service(LookupNumeric(strAddNode, Params().GetDefaultPort(strAddNode)));
2148  AddedNodeInfo addedNode{strAddNode, CService(), false, false};
2149  if (service.IsValid()) {
2150  // strAddNode is an IP:port
2151  auto it = mapConnected.find(service);
2152  if (it != mapConnected.end()) {
2153  addedNode.resolvedAddress = service;
2154  addedNode.fConnected = true;
2155  addedNode.fInbound = it->second;
2156  }
2157  } else {
2158  // strAddNode is a name
2159  auto it = mapConnectedByName.find(strAddNode);
2160  if (it != mapConnectedByName.end()) {
2161  addedNode.resolvedAddress = it->second.second;
2162  addedNode.fConnected = true;
2163  addedNode.fInbound = it->second.first;
2164  }
2165  }
2166  ret.emplace_back(std::move(addedNode));
2167  }
2168 
2169  return ret;
2170 }
2171 
2173 {
2174  while (true)
2175  {
2176  CSemaphoreGrant grant(*semAddnode);
2177  std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
2178  bool tried = false;
2179  for (const AddedNodeInfo& info : vInfo) {
2180  if (!info.fConnected) {
2181  if (!grant.TryAcquire()) {
2182  // If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
2183  // the addednodeinfo state might change.
2184  break;
2185  }
2186  tried = true;
2187  CAddress addr(CService(), NODE_NONE);
2188  OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
2189  if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
2190  return;
2191  }
2192  }
2193  // Retry every 60 seconds if a connection was attempted, otherwise two seconds
2194  if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
2195  return;
2196  }
2197 }
2198 
2199 // if successful, this moves the passed grant to the constructed node
2200 void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
2201 {
2202  assert(conn_type != ConnectionType::INBOUND);
2203 
2204  //
2205  // Initiate outbound network connection
2206  //
2207  if (interruptNet) {
2208  return;
2209  }
2210  if (!fNetworkActive) {
2211  return;
2212  }
2213  if (!pszDest) {
2214  bool banned_or_discouraged = m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect));
2215  if (IsLocal(addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress(addrConnect)) {
2216  return;
2217  }
2218  } else if (FindNode(std::string(pszDest)))
2219  return;
2220 
2221  CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2222 
2223  if (!pnode)
2224  return;
2225  if (grantOutbound)
2226  grantOutbound->MoveTo(pnode->grantOutbound);
2227 
2228  m_msgproc->InitializeNode(pnode);
2229  {
2230  LOCK(cs_vNodes);
2231  vNodes.push_back(pnode);
2232  }
2233 }
2234 
2236 {
2237  FastRandomContext rng;
2238  while (!flagInterruptMsgProc)
2239  {
2240  std::vector<CNode*> vNodesCopy;
2241  {
2242  LOCK(cs_vNodes);
2243  vNodesCopy = vNodes;
2244  for (CNode* pnode : vNodesCopy) {
2245  pnode->AddRef();
2246  }
2247  }
2248 
2249  bool fMoreWork = false;
2250 
2251  // Randomize the order in which we process messages from/to our peers.
2252  // This prevents attacks in which an attacker exploits having multiple
2253  // consecutive connections in the vNodes list.
2254  Shuffle(vNodesCopy.begin(), vNodesCopy.end(), rng);
2255 
2256  for (CNode* pnode : vNodesCopy)
2257  {
2258  if (pnode->fDisconnect)
2259  continue;
2260 
2261  // Receive messages
2262  bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
2263  fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2265  return;
2266  // Send messages
2267  {
2268  LOCK(pnode->cs_sendProcessing);
2269  m_msgproc->SendMessages(pnode);
2270  }
2271 
2273  return;
2274  }
2275 
2276  {
2277  LOCK(cs_vNodes);
2278  for (CNode* pnode : vNodesCopy)
2279  pnode->Release();
2280  }
2281 
2282  WAIT_LOCK(mutexMsgProc, lock);
2283  if (!fMoreWork) {
2284  condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this]() EXCLUSIVE_LOCKS_REQUIRED(mutexMsgProc) { return fMsgProcWake; });
2285  }
2286  fMsgProcWake = false;
2287  }
2288 }
2289 
2291 {
2292  static constexpr auto err_wait_begin = 1s;
2293  static constexpr auto err_wait_cap = 5min;
2294  auto err_wait = err_wait_begin;
2295 
2296  bool advertising_listen_addr = false;
2297  i2p::Connection conn;
2298 
2299  while (!interruptNet) {
2300 
2301  if (!m_i2p_sam_session->Listen(conn)) {
2302  if (advertising_listen_addr && conn.me.IsValid()) {
2303  RemoveLocal(conn.me);
2304  advertising_listen_addr = false;
2305  }
2306 
2307  interruptNet.sleep_for(err_wait);
2308  if (err_wait < err_wait_cap) {
2309  err_wait *= 2;
2310  }
2311 
2312  continue;
2313  }
2314 
2315  if (!advertising_listen_addr) {
2316  AddLocal(conn.me, LOCAL_MANUAL);
2317  advertising_listen_addr = true;
2318  }
2319 
2320  if (!m_i2p_sam_session->Accept(conn)) {
2321  continue;
2322  }
2323 
2325  CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
2326  }
2327 }
2328 
2329 bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions)
2330 {
2331  int nOne = 1;
2332 
2333  // Create socket for listening for incoming connections
2334  struct sockaddr_storage sockaddr;
2335  socklen_t len = sizeof(sockaddr);
2336  if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
2337  {
2338  strError = strprintf(Untranslated("Error: Bind address family for %s not supported"), addrBind.ToString());
2339  LogPrintf("%s\n", strError.original);
2340  return false;
2341  }
2342 
2343  std::unique_ptr<Sock> sock = CreateSock(addrBind);
2344  if (!sock) {
2345  strError = strprintf(Untranslated("Error: Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError()));
2346  LogPrintf("%s\n", strError.original);
2347  return false;
2348  }
2349 
2350  // Allow binding if the port is still in TIME_WAIT state after
2351  // the program was closed and restarted.
2352  setsockopt(sock->Get(), SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int));
2353 
2354  // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
2355  // and enable it by default or not. Try to enable it, if possible.
2356  if (addrBind.IsIPv6()) {
2357 #ifdef IPV6_V6ONLY
2358  setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
2359 #endif
2360 #ifdef WIN32
2361  int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2362  setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
2363 #endif
2364  }
2365 
2366  if (::bind(sock->Get(), (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
2367  {
2368  int nErr = WSAGetLastError();
2369  if (nErr == WSAEADDRINUSE)
2370  strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
2371  else
2372  strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
2373  LogPrintf("%s\n", strError.original);
2374  return false;
2375  }
2376  LogPrintf("Bound to %s\n", addrBind.ToString());
2377 
2378  // Listen for incoming connections
2379  if (listen(sock->Get(), SOMAXCONN) == SOCKET_ERROR)
2380  {
2381  strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
2382  LogPrintf("%s\n", strError.original);
2383  return false;
2384  }
2385 
2386  vhListenSocket.push_back(ListenSocket(sock->Release(), permissions));
2387  return true;
2388 }
2389 
2390 void Discover()
2391 {
2392  if (!fDiscover)
2393  return;
2394 
2395 #ifdef WIN32
2396  // Get local host IP
2397  char pszHostName[256] = "";
2398  if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
2399  {
2400  std::vector<CNetAddr> vaddr;
2401  if (LookupHost(pszHostName, vaddr, 0, true))
2402  {
2403  for (const CNetAddr &addr : vaddr)
2404  {
2405  if (AddLocal(addr, LOCAL_IF))
2406  LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2407  }
2408  }
2409  }
2410 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2411  // Get local host ip
2412  struct ifaddrs* myaddrs;
2413  if (getifaddrs(&myaddrs) == 0)
2414  {
2415  for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
2416  {
2417  if (ifa->ifa_addr == nullptr) continue;
2418  if ((ifa->ifa_flags & IFF_UP) == 0) continue;
2419  if (strcmp(ifa->ifa_name, "lo") == 0) continue;
2420  if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
2421  if (ifa->ifa_addr->sa_family == AF_INET)
2422  {
2423  struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
2424  CNetAddr addr(s4->sin_addr);
2425  if (AddLocal(addr, LOCAL_IF))
2426  LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2427  }
2428  else if (ifa->ifa_addr->sa_family == AF_INET6)
2429  {
2430  struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
2431  CNetAddr addr(s6->sin6_addr);
2432  if (AddLocal(addr, LOCAL_IF))
2433  LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2434  }
2435  }
2436  freeifaddrs(myaddrs);
2437  }
2438 #endif
2439 }
2440 
2442 {
2443  LogPrintf("%s: %s\n", __func__, active);
2444 
2445  if (fNetworkActive == active) {
2446  return;
2447  }
2448 
2449  fNetworkActive = active;
2450 
2451  uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
2452 }
2453 
2454 CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, CAddrMan& addrman_in, bool network_active)
2455  : addrman(addrman_in), nSeed0(nSeed0In), nSeed1(nSeed1In)
2456 {
2457  SetTryNewOutboundPeer(false);
2458 
2459  Options connOptions;
2460  Init(connOptions);
2461  SetNetworkActive(network_active);
2462 }
2463 
2465 {
2466  return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2467 }
2468 
2469 
2470 bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
2471  if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
2472  return false;
2473  }
2474  bilingual_str strError;
2475  if (!BindListenPort(addr, strError, permissions)) {
2476  if ((flags & BF_REPORT_ERROR) && clientInterface) {
2477  clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
2478  }
2479  return false;
2480  }
2481 
2483  AddLocal(addr, LOCAL_BIND);
2484  }
2485 
2486  return true;
2487 }
2488 
2489 bool CConnman::InitBinds(const Options& options)
2490 {
2491  bool fBound = false;
2492  for (const auto& addrBind : options.vBinds) {
2493  fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::None);
2494  }
2495  for (const auto& addrBind : options.vWhiteBinds) {
2496  fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
2497  }
2498  for (const auto& addr_bind : options.onion_binds) {
2500  }
2501  if (options.bind_on_any) {
2502  struct in_addr inaddr_any;
2503  inaddr_any.s_addr = htonl(INADDR_ANY);
2504  struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2505  fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::None);
2506  fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::None);
2507  }
2508  return fBound;
2509 }
2510 
2511 bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
2512 {
2513  Init(connOptions);
2514 
2515  if (fListen && !InitBinds(connOptions)) {
2516  if (clientInterface) {
2517  clientInterface->ThreadSafeMessageBox(
2518  _("Failed to listen on any port. Use -listen=0 if you want this."),
2520  }
2521  return false;
2522  }
2523 
2524  proxyType i2p_sam;
2525  if (GetProxy(NET_I2P, i2p_sam)) {
2526  m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key",
2527  i2p_sam.proxy, &interruptNet);
2528  }
2529 
2530  for (const auto& strDest : connOptions.vSeedNodes) {
2531  AddAddrFetch(strDest);
2532  }
2533 
2534  if (clientInterface) {
2535  clientInterface->InitMessage(_("Loading P2P addresses…").translated);
2536  }
2537  // Load addresses from peers.dat
2538  int64_t nStart = GetTimeMillis();
2539  {
2540  CAddrDB adb;
2541  if (adb.Read(addrman))
2542  LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
2543  else {
2544  addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2545  LogPrintf("Recreating peers.dat\n");
2546  DumpAddresses();
2547  }
2548  }
2549 
2550  if (m_use_addrman_outgoing) {
2551  // Load addresses from anchors.dat
2553  if (m_anchors.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) {
2555  }
2556  LogPrintf("%i block-relay-only anchors will be tried for connections.\n", m_anchors.size());
2557  }
2558 
2559  uiInterface.InitMessage(_("Starting network threads…").translated);
2560 
2561  fAddressesInitialized = true;
2562 
2563  if (semOutbound == nullptr) {
2564  // initialize semaphore
2565  semOutbound = std::make_unique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
2566  }
2567  if (semAddnode == nullptr) {
2568  // initialize semaphore
2569  semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
2570  }
2571 
2572  //
2573  // Start threads
2574  //
2575  assert(m_msgproc);
2576  InterruptSocks5(false);
2577  interruptNet.reset();
2578  flagInterruptMsgProc = false;
2579 
2580  {
2581  LOCK(mutexMsgProc);
2582  fMsgProcWake = false;
2583  }
2584 
2585  // Send and receive from sockets, accept connections
2586  threadSocketHandler = std::thread(&util::TraceThread, "net", [this] { ThreadSocketHandler(); });
2587 
2588  if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED))
2589  LogPrintf("DNS seeding disabled\n");
2590  else
2591  threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed", [this] { ThreadDNSAddressSeed(); });
2592 
2593  // Initiate manual connections
2594  threadOpenAddedConnections = std::thread(&util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); });
2595 
2596  if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2597  if (clientInterface) {
2598  clientInterface->ThreadSafeMessageBox(
2599  _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
2601  }
2602  return false;
2603  }
2604  if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) {
2605  threadOpenConnections = std::thread(
2606  &util::TraceThread, "opencon",
2607  [this, connect = connOptions.m_specified_outgoing] { ThreadOpenConnections(connect); });
2608  }
2609 
2610  // Process messages
2611  threadMessageHandler = std::thread(&util::TraceThread, "msghand", [this] { ThreadMessageHandler(); });
2612 
2613  if (connOptions.m_i2p_accept_incoming && m_i2p_sam_session.get() != nullptr) {
2615  std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); });
2616  }
2617 
2618  // Dump network addresses
2619  scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
2620 
2621  return true;
2622 }
2623 
2625 {
2626 public:
2628 
2630  {
2631 #ifdef WIN32
2632  // Shutdown Windows Sockets
2633  WSACleanup();
2634 #endif
2635  }
2636 };
2638 
2640 {
2641  {
2642  LOCK(mutexMsgProc);
2643  flagInterruptMsgProc = true;
2644  }
2645  condMsgProc.notify_all();
2646 
2647  interruptNet();
2648  InterruptSocks5(true);
2649 
2650  if (semOutbound) {
2651  for (int i=0; i<m_max_outbound; i++) {
2652  semOutbound->post();
2653  }
2654  }
2655 
2656  if (semAddnode) {
2657  for (int i=0; i<nMaxAddnode; i++) {
2658  semAddnode->post();
2659  }
2660  }
2661 }
2662 
2664 {
2665  if (threadI2PAcceptIncoming.joinable()) {
2666  threadI2PAcceptIncoming.join();
2667  }
2668  if (threadMessageHandler.joinable())
2669  threadMessageHandler.join();
2670  if (threadOpenConnections.joinable())
2671  threadOpenConnections.join();
2672  if (threadOpenAddedConnections.joinable())
2674  if (threadDNSAddressSeed.joinable())
2675  threadDNSAddressSeed.join();
2676  if (threadSocketHandler.joinable())
2677  threadSocketHandler.join();
2678 }
2679 
2681 {
2682  if (fAddressesInitialized) {
2683  DumpAddresses();
2684  fAddressesInitialized = false;
2685 
2686  if (m_use_addrman_outgoing) {
2687  // Anchor connections are only dumped during clean shutdown.
2688  std::vector<CAddress> anchors_to_dump = GetCurrentBlockRelayOnlyConns();
2689  if (anchors_to_dump.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) {
2690  anchors_to_dump.resize(MAX_BLOCK_RELAY_ONLY_ANCHORS);
2691  }
2693  }
2694  }
2695 
2696  // Delete peer connections.
2697  std::vector<CNode*> nodes;
2698  WITH_LOCK(cs_vNodes, nodes.swap(vNodes));
2699  for (CNode* pnode : nodes) {
2700  pnode->CloseSocketDisconnect();
2701  DeleteNode(pnode);
2702  }
2703 
2704  // Close listening sockets.
2705  for (ListenSocket& hListenSocket : vhListenSocket) {
2706  if (hListenSocket.socket != INVALID_SOCKET) {
2707  if (!CloseSocket(hListenSocket.socket)) {
2708  LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2709  }
2710  }
2711  }
2712 
2713  for (CNode* pnode : vNodesDisconnected) {
2714  DeleteNode(pnode);
2715  }
2716  vNodesDisconnected.clear();
2717  vhListenSocket.clear();
2718  semOutbound.reset();
2719  semAddnode.reset();
2720 }
2721 
2723 {
2724  assert(pnode);
2725  m_msgproc->FinalizeNode(*pnode);
2726  delete pnode;
2727 }
2728 
2730 {
2731  Interrupt();
2732  Stop();
2733 }
2734 
2735 std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
2736 {
2737  std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct, network);
2738  if (m_banman) {
2739  addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2740  [this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
2741  addresses.end());
2742  }
2743  return addresses;
2744 }
2745 
2746 std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addresses, size_t max_pct)
2747 {
2748  auto local_socket_bytes = requestor.addrBind.GetAddrBytes();
2750  .Write(requestor.addr.GetNetwork())
2751  .Write(local_socket_bytes.data(), local_socket_bytes.size())
2752  .Finalize();
2753  const auto current_time = GetTime<std::chrono::microseconds>();
2754  auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
2755  CachedAddrResponse& cache_entry = r.first->second;
2756  if (cache_entry.m_cache_entry_expiration < current_time) { // If emplace() added new one it has expiration 0.
2757  cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);
2758  // Choosing a proper cache lifetime is a trade-off between the privacy leak minimization
2759  // and the usefulness of ADDR responses to honest users.
2760  //
2761  // Longer cache lifetime makes it more difficult for an attacker to scrape
2762  // enough AddrMan data to maliciously infer something useful.
2763  // By the time an attacker scraped enough AddrMan records, most of
2764  // the records should be old enough to not leak topology info by
2765  // e.g. analyzing real-time changes in timestamps.
2766  //
2767  // It takes only several hundred requests to scrape everything from an AddrMan containing 100,000 nodes,
2768  // so ~24 hours of cache lifetime indeed makes the data less inferable by the time
2769  // most of it could be scraped (considering that timestamps are updated via
2770  // ADDR self-announcements and when nodes communicate).
2771  // We also should be robust to those attacks which may not require scraping *full* victim's AddrMan
2772  // (because even several timestamps of the same handful of nodes may leak privacy).
2773  //
2774  // On the other hand, longer cache lifetime makes ADDR responses
2775  // outdated and less useful for an honest requestor, e.g. if most nodes
2776  // in the ADDR response are no longer active.
2777  //
2778  // However, the churn in the network is known to be rather low. Since we consider
2779  // nodes to be "terrible" (see IsTerrible()) if the timestamps are older than 30 days,
2780  // max. 24 hours of "penalty" due to cache shouldn't make any meaningful difference
2781  // in terms of the freshness of the response.
2782  cache_entry.m_cache_entry_expiration = current_time + std::chrono::hours(21) + GetRandMillis(std::chrono::hours(6));
2783  }
2784  return cache_entry.m_addrs_response_cache;
2785 }
2786 
2787 bool CConnman::AddNode(const std::string& strNode)
2788 {
2790  for (const std::string& it : vAddedNodes) {
2791  if (strNode == it) return false;
2792  }
2793 
2794  vAddedNodes.push_back(strNode);
2795  return true;
2796 }
2797 
2798 bool CConnman::RemoveAddedNode(const std::string& strNode)
2799 {
2801  for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2802  if (strNode == *it) {
2803  vAddedNodes.erase(it);
2804  return true;
2805  }
2806  }
2807  return false;
2808 }
2809 
2811 {
2812  LOCK(cs_vNodes);
2813  if (flags == ConnectionDirection::Both) // Shortcut if we want total
2814  return vNodes.size();
2815 
2816  int nNum = 0;
2817  for (const auto& pnode : vNodes) {
2818  if (flags & (pnode->IsInboundConn() ? ConnectionDirection::In : ConnectionDirection::Out)) {
2819  nNum++;
2820  }
2821  }
2822 
2823  return nNum;
2824 }
2825 
2826 void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
2827 {
2828  vstats.clear();
2829  LOCK(cs_vNodes);
2830  vstats.reserve(vNodes.size());
2831  for (CNode* pnode : vNodes) {
2832  vstats.emplace_back();
2833  pnode->copyStats(vstats.back(), addrman.m_asmap);
2834  }
2835 }
2836 
2837 bool CConnman::DisconnectNode(const std::string& strNode)
2838 {
2839  LOCK(cs_vNodes);
2840  if (CNode* pnode = FindNode(strNode)) {
2841  LogPrint(BCLog::NET, "disconnect by address%s matched peer=%d; disconnecting\n", (fLogIPs ? strprintf("=%s", strNode) : ""), pnode->GetId());
2842  pnode->fDisconnect = true;
2843  return true;
2844  }
2845  return false;
2846 }
2847 
2849 {
2850  bool disconnected = false;
2851  LOCK(cs_vNodes);
2852  for (CNode* pnode : vNodes) {
2853  if (subnet.Match(pnode->addr)) {
2854  LogPrint(BCLog::NET, "disconnect by subnet%s matched peer=%d; disconnecting\n", (fLogIPs ? strprintf("=%s", subnet.ToString()) : ""), pnode->GetId());
2855  pnode->fDisconnect = true;
2856  disconnected = true;
2857  }
2858  }
2859  return disconnected;
2860 }
2861 
2863 {
2864  return DisconnectNode(CSubNet(addr));
2865 }
2866 
2868 {
2869  LOCK(cs_vNodes);
2870  for(CNode* pnode : vNodes) {
2871  if (id == pnode->GetId()) {
2872  LogPrint(BCLog::NET, "disconnect by id peer=%d; disconnecting\n", pnode->GetId());
2873  pnode->fDisconnect = true;
2874  return true;
2875  }
2876  }
2877  return false;
2878 }
2879 
2880 void CConnman::RecordBytesRecv(uint64_t bytes)
2881 {
2883  nTotalBytesRecv += bytes;
2884 }
2885 
2886 void CConnman::RecordBytesSent(uint64_t bytes)
2887 {
2889  nTotalBytesSent += bytes;
2890 
2891  const auto now = GetTime<std::chrono::seconds>();
2892  if (nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME < now)
2893  {
2894  // timeframe expired, reset cycle
2895  nMaxOutboundCycleStartTime = now;
2896  nMaxOutboundTotalBytesSentInCycle = 0;
2897  }
2898 
2899  // TODO, exclude peers with download permission
2900  nMaxOutboundTotalBytesSentInCycle += bytes;
2901 }
2902 
2904 {
2906  return nMaxOutboundLimit;
2907 }
2908 
2909 std::chrono::seconds CConnman::GetMaxOutboundTimeframe() const
2910 {
2911  return MAX_UPLOAD_TIMEFRAME;
2912 }
2913 
2914 std::chrono::seconds CConnman::GetMaxOutboundTimeLeftInCycle() const
2915 {
2917  if (nMaxOutboundLimit == 0)
2918  return 0s;
2919 
2920  if (nMaxOutboundCycleStartTime.count() == 0)
2921  return MAX_UPLOAD_TIMEFRAME;
2922 
2923  const std::chrono::seconds cycleEndTime = nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME;
2924  const auto now = GetTime<std::chrono::seconds>();
2925  return (cycleEndTime < now) ? 0s : cycleEndTime - now;
2926 }
2927 
2928 bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit) const
2929 {
2931  if (nMaxOutboundLimit == 0)
2932  return false;
2933 
2934  if (historicalBlockServingLimit)
2935  {
2936  // keep a large enough buffer to at least relay each block once
2937  const std::chrono::seconds timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
2938  const uint64_t buffer = timeLeftInCycle / std::chrono::minutes{10} * MAX_BLOCK_SERIALIZED_SIZE;
2939  if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2940  return true;
2941  }
2942  else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2943  return true;
2944 
2945  return false;
2946 }
2947 
2949 {
2951  if (nMaxOutboundLimit == 0)
2952  return 0;
2953 
2954  return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2955 }
2956 
2958 {
2960  return nTotalBytesRecv;
2961 }
2962 
2964 {
2966  return nTotalBytesSent;
2967 }
2968 
2970 {
2971  return nLocalServices;
2972 }
2973 
2974 unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
2975 
2976 CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
2977  : nTimeConnected(GetTimeSeconds()),
2978  addr(addrIn),
2979  addrBind(addrBindIn),
2980  m_inbound_onion(inbound_onion),
2981  nKeyedNetGroup(nKeyedNetGroupIn),
2982  id(idIn),
2983  nLocalHostNonce(nLocalHostNonceIn),
2984  m_conn_type(conn_type_in),
2985  nLocalServices(nLocalServicesIn)
2986 {
2987  if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND);
2988  hSocket = hSocketIn;
2989  addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2990  if (conn_type_in != ConnectionType::BLOCK_RELAY) {
2991  m_tx_relay = std::make_unique<TxRelay>();
2992  }
2993 
2994  for (const std::string &msg : getAllNetMessageTypes())
2995  mapRecvBytesPerMsgCmd[msg] = 0;
2996  mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
2997 
2998  if (fLogIPs) {
2999  LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
3000  } else {
3001  LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
3002  }
3003 
3004  m_deserializer = std::make_unique<V1TransportDeserializer>(V1TransportDeserializer(Params(), GetId(), SER_NETWORK, INIT_PROTO_VERSION));
3005  m_serializer = std::make_unique<V1TransportSerializer>(V1TransportSerializer());
3006 }
3007 
3009 {
3010  CloseSocket(hSocket);
3011 }
3012 
3014 {
3015  return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
3016 }
3017 
3019 {
3020  size_t nMessageSize = msg.data.size();
3021  LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", msg.m_type, nMessageSize, pnode->GetId());
3022  if (gArgs.GetBoolArg("-capturemessages", false)) {
3023  CaptureMessage(pnode->addr, msg.m_type, msg.data, /* incoming */ false);
3024  }
3025 
3026  TRACE6(net, outbound_message,
3027  pnode->GetId(),
3028  pnode->GetAddrName().c_str(),
3029  pnode->ConnectionTypeAsString().c_str(),
3030  msg.m_type.c_str(),
3031  msg.data.size(),
3032  msg.data.data()
3033  );
3034 
3035  // make sure we use the appropriate network transport format
3036  std::vector<unsigned char> serializedHeader;
3037  pnode->m_serializer->prepareForTransport(msg, serializedHeader);
3038  size_t nTotalSize = nMessageSize + serializedHeader.size();
3039 
3040  size_t nBytesSent = 0;
3041  {
3042  LOCK(pnode->cs_vSend);
3043  bool optimisticSend(pnode->vSendMsg.empty());
3044 
3045  //log total amount of bytes per message type
3046  pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
3047  pnode->nSendSize += nTotalSize;
3048 
3049  if (pnode->nSendSize > nSendBufferMaxSize) pnode->fPauseSend = true;
3050  pnode->vSendMsg.push_back(std::move(serializedHeader));
3051  if (nMessageSize) pnode->vSendMsg.push_back(std::move(msg.data));
3052 
3053  // If write queue empty, attempt "optimistic write"
3054  if (optimisticSend) nBytesSent = SocketSendData(*pnode);
3055  }
3056  if (nBytesSent) RecordBytesSent(nBytesSent);
3057 }
3058 
3059 bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
3060 {
3061  CNode* found = nullptr;
3062  LOCK(cs_vNodes);
3063  for (auto&& pnode : vNodes) {
3064  if(pnode->GetId() == id) {
3065  found = pnode;
3066  break;
3067  }
3068  }
3069  return found != nullptr && NodeFullyConnected(found) && func(found);
3070 }
3071 
3072 std::chrono::microseconds CConnman::PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
3073 {
3074  if (m_next_send_inv_to_incoming.load() < now) {
3075  // If this function were called from multiple threads simultaneously
3076  // it would possible that both update the next send variable, and return a different result to their caller.
3077  // This is not possible in practice as only the net processing thread invokes this function.
3078  m_next_send_inv_to_incoming = PoissonNextSend(now, average_interval);
3079  }
3081 }
3082 
3083 std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
3084 {
3085  double unscaled = -log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */);
3086  return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);
3087 }
3088 
3090 {
3091  return CSipHasher(nSeed0, nSeed1).Write(id);
3092 }
3093 
3095 {
3096  std::vector<unsigned char> vchNetGroup(ad.GetGroup(addrman.m_asmap));
3097 
3098  return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
3099 }
3100 
3101 void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Span<const unsigned char>& data, bool is_incoming)
3102 {
3103  // Note: This function captures the message at the time of processing,
3104  // not at socket receive/send time.
3105  // This ensures that the messages are always in order from an application
3106  // layer (processing) perspective.
3107  auto now = GetTime<std::chrono::microseconds>();
3108 
3109  // Windows folder names can not include a colon
3110  std::string clean_addr = addr.ToString();
3111  std::replace(clean_addr.begin(), clean_addr.end(), ':', '_');
3112 
3113  fs::path base_path = gArgs.GetDataDirNet() / "message_capture" / clean_addr;
3114  fs::create_directories(base_path);
3115 
3116  fs::path path = base_path / (is_incoming ? "msgs_recv.dat" : "msgs_sent.dat");
3118 
3119  ser_writedata64(f, now.count());
3120  f.write(msg_type.data(), msg_type.length());
3121  for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
3122  f << uint8_t{'\0'};
3123  }
3124  uint32_t size = data.size();
3125  ser_writedata32(f, size);
3126  f.write((const char*)data.data(), data.size());
3127 }
CNetAddr::IsIPv6
bool IsIPv6() const
Definition: netaddress.cpp:320
NodeEvictionCandidate::m_network
Network m_network
Definition: net.h:1213
V1TransportSerializer
Definition: net.h:388
CNodeStats::addrName
std::string addrName
Definition: net.h:251
ADDRV2_FORMAT
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
Definition: netaddress.h:34
CConnman::SetTryNewOutboundPeer
void SetTryNewOutboundPeer(bool flag)
Definition: net.cpp:1793
NodeId
int64_t NodeId
Definition: net.h:88
CConnman::cs_totalBytesRecv
RecursiveMutex cs_totalBytesRecv
Definition: net.h:1039
WSAEADDRINUSE
#define WSAEADDRINUSE
Definition: compat.h:51
LOCK2
#define LOCK2(cs1, cs2)
Definition: sync.h:233
CConnman::DisconnectNode
bool DisconnectNode(const std::string &node)
Definition: net.cpp:2837
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:539
CService::GetSockAddr
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
Definition: netaddress.cpp:982
CConnman::m_max_outbound
int m_max_outbound
Definition: net.h:1127
CompareNodeBlockRelayOnlyTime
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:869
CConnman::m_anchors
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
Definition: net.h:1138
CConnman::ConnectNode
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
Definition: net.cpp:383
CScheduler
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:33
CConnman::Options::vSeedNodes
std::vector< std::string > vSeedNodes
Definition: net.h:766
LookupHost
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
Definition: netbase.cpp:169
fLogIPs
bool fLogIPs
Definition: logging.cpp:38
CConnman::vhListenSocket
std::vector< ListenSocket > vhListenSocket
Definition: net.h:1059
V1TransportDeserializer::Complete
bool Complete() const override
Definition: net.h:355
CNodeStats::fInbound
bool fInbound
Definition: net.h:254
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:600
BanMan::IsBanned
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
Definition: banman.cpp:75
_
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:57
SELECT_TIMEOUT_MILLISECONDS
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
Definition: net.cpp:99
GetnScore
static int GetnScore(const CService &addr)
Definition: net.cpp:190
NET_UNROUTABLE
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:47
CConnman::ThreadMessageHandler
void ThreadMessageHandler()
Definition: net.cpp:2235
CNetAddr::GetGroup
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
Definition: netaddress.cpp:766
count
static int count
Definition: tests.c:41
ReadLE32
static uint32_t ReadLE32(const unsigned char *ptr)
Definition: common.h:24
RemoveLocal
void RemoveLocal(const CService &addr)
Definition: net.cpp:262
NodeEvictionCandidate::m_min_ping_time
std::chrono::microseconds m_min_ping_time
Definition: net.h:1204
BanMan::IsDiscouraged
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
Definition: banman.cpp:69
CNodeStats::m_network
Network m_network
Definition: net.h:273
CConnman::nSendBufferMaxSize
unsigned int nSendBufferMaxSize
Definition: net.h:1056
NetPermissionFlags::None
@ None
SER_DISK
@ SER_DISK
Definition: serialize.h:139
CConnman::AttemptToEvictConnection
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
Definition: net.cpp:1049
ConnectionDirection::Out
@ Out
CNode::cs_vSend
Mutex cs_vSend
Definition: net.h:412
CNode::nLastSend
std::atomic< int64_t > nLastSend
Definition: net.h:424
CNodeStats::addrLocal
std::string addrLocal
Definition: net.h:267
PoissonNextSend
std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
Definition: net.cpp:3083
CConnman::Interrupt
void Interrupt()
Definition: net.cpp:2639
CNode::GetId
NodeId GetId() const
Definition: net.h:585
CConnman::condMsgProc
std::condition_variable condMsgProc
Definition: net.h:1146
CConnman::nReceiveFloodSize
unsigned int nReceiveFloodSize
Definition: net.h:1057
NodeEvictionCandidate::fBloomFilter
bool fBloomFilter
Definition: net.h:1209
CompareNodeNetworkTime::operator()
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) const
Definition: net.cpp:889
CNodeStats::nodeid
NodeId nodeid
Definition: net.h:242
util::TraceThread
void TraceThread(const char *thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
Definition: thread.cpp:13
CHash256::Write
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:37
CVectorWriter
Definition: streams.h:72
CThreadInterrupt::sleep_for
bool sleep_for(std::chrono::milliseconds rel_time)
Definition: threadinterrupt.cpp:31
CMessageHeader::nMessageSize
uint32_t nMessageSize
Definition: protocol.h:56
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:24
flags
int flags
Definition: bitcoin-tx.cpp:512
ArgsManager::GetDataDirNet
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:282
CConnman::ThreadDNSAddressSeed
void ThreadDNSAddressSeed()
Definition: net.cpp:1650
CNetAddr::GetAddrBytes
std::vector< unsigned char > GetAddrBytes() const
Definition: netaddress.cpp:820
CConnman::Options::vBinds
std::vector< CService > vBinds
Definition: net.h:769
WSAEMSGSIZE
#define WSAEMSGSIZE
Definition: compat.h:48
CSerializedNetMsg::data
std::vector< unsigned char > data
Definition: net.h:110
CNode::copyStats
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
Definition: net.cpp:570
CConnman::CreateNodeFromAcceptedSocket
void CreateNodeFromAcceptedSocket(SOCKET hSocket, NetPermissionFlags permissionFlags, const CAddress &addr_bind, const CAddress &addr)
Create a CNode object from a socket that has just been accepted and add the node to the vNodes member...
Definition: net.cpp:1119
CNetAddr::GetNetClass
Network GetNetClass() const
Definition: netaddress.cpp:707
CConnman::RecordBytesRecv
void RecordBytesRecv(uint64_t bytes)
Definition: net.cpp:2880
CConnman::GetMaxOutboundTimeframe
std::chrono::seconds GetMaxOutboundTimeframe() const
Definition: net.cpp:2909
uiInterface
CClientUIInterface uiInterface
Definition: ui_interface.cpp:12
NET_INTERNAL
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:66
CConnman::WakeMessageHandler
void WakeMessageHandler()
Definition: net.cpp:1641
CNode::m_bip152_highbandwidth_from
std::atomic< bool > m_bip152_highbandwidth_from
Definition: net.h:529
CConnman::Bind
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
Definition: net.cpp:2470
CConnman::Options::m_i2p_accept_incoming
bool m_i2p_accept_incoming
Definition: net.h:778
NET_MESSAGE_COMMAND_OTHER
const std::string NET_MESSAGE_COMMAND_OTHER
Definition: net.cpp:101
CConnman::SocketEvents
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Definition: net.cpp:1438
WSAEINPROGRESS
#define WSAEINPROGRESS
Definition: compat.h:50
CConnman::m_max_outbound_full_relay
int m_max_outbound_full_relay
Definition: net.h:1119
CNode::nLastRecv
std::atomic< int64_t > nLastRecv
Definition: net.h:425
ser_writedata64
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:84
string.h
CConnman::m_onion_binds
std::vector< CService > m_onion_binds
A vector of -bind=<address>:<port>=onion arguments each of which is an address and port that are desi...
Definition: net.h:1188
bilingual_str
Bilingual messages:
Definition: translation.h:16
CAddrMan::Select
CAddrInfo Select(bool newOnly=false) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
Choose an address to connect to.
Definition: addrman.h:588
CNetAddr
Network address.
Definition: netaddress.h:118
DumpAnchors
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:255
CConnman::OutboundTargetReached
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
Definition: net.cpp:2928
NET_MAX
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:69
CConnman::ProcessAddrFetch
void ProcessAddrFetch()
Definition: net.cpp:1771
NodeEvictionCandidate::fRelayTxes
bool fRelayTxes
Definition: net.h:1208
NetPermissionFlags::NoBan
@ NoBan
ConnectionType::OUTBOUND_FULL_RELAY
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
CNode
Information about a peer.
Definition: net.h:394
CConnman::Options::bind_on_any
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0....
Definition: net.h:773
nConnectTimeout
int nConnectTimeout
Definition: netbase.cpp:38
ConnectionDirection::Both
@ Both
CSemaphoreGrant::MoveTo
void MoveTo(CSemaphoreGrant &grant)
Definition: sync.h:345
GetDesirableServiceFlags
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
Definition: protocol.cpp:127
CConnman::cs_vAddedNodes
RecursiveMutex cs_vAddedNodes
Definition: net.h:1066
CConnman::AddConnection
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
Definition: net.cpp:1214
SeenLocal
bool SeenLocal(const CService &addr)
vote for a local address
Definition: net.cpp:289
CNode::m_serializer
std::unique_ptr< TransportSerializer > m_serializer
Definition: net.h:401
CompareNodeBlockTime
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:851
CConnman::AcceptConnection
void AcceptConnection(const ListenSocket &hListenSocket)
Definition: net.cpp:1093
GetTime
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
Definition: time.cpp:26
trace.h
CNode::GetAddrName
std::string GetAddrName() const
Definition: net.cpp:537
GetNameProxy
bool GetNameProxy(proxyType &nameProxyOut)
Definition: netbase.cpp:633
NetPermissions::ClearFlag
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
Definition: net_permissions.h:67
CConnman::GetLocalServices
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
Definition: net.cpp:2969
CNetAddr::ToString
std::string ToString() const
Definition: netaddress.cpp:631
WITH_LOCK
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:276
FEELER_SLEEP_WINDOW
#define FEELER_SLEEP_WINDOW
Definition: net.cpp:83
CAddrMan::GetAddr
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
Return all or many randomly selected addresses, optionally by network.
Definition: addrman.h:605
CConnman::m_addr_fetches_mutex
RecursiveMutex m_addr_fetches_mutex
Definition: net.h:1064
NetPermissions::HasFlag
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
Definition: net_permissions.h:53
AnnotatedMixin< std::recursive_mutex >
CNetCleanup::~CNetCleanup
~CNetCleanup()
Definition: net.cpp:2629
CConnman::cs_totalBytesSent
RecursiveMutex cs_totalBytesSent
Definition: net.h:1040
CSerializedNetMsg::m_type
std::string m_type
Definition: net.h:111
CConnman::CConnman
CConnman(uint64_t seed0, uint64_t seed1, CAddrMan &addrman, bool network_active=true)
Definition: net.cpp:2454
ConnectSocketDirectly
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
Definition: netbase.cpp:540
clientversion.h
ServiceFlags
ServiceFlags
nServices flags
Definition: protocol.h:271
CConnman::CachedAddrResponse::m_addrs_response_cache
std::vector< CAddress > m_addrs_response_cache
Definition: net.h:1080
CMessageHeader::GetCommand
std::string GetCommand() const
Definition: protocol.cpp:102
CAddress::nServices
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
Definition: protocol.h:451
fDiscover
bool fDiscover
Definition: net.cpp:109
CreateSock
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
Definition: netbase.cpp:528
V1TransportDeserializer::vRecv
CDataStream vRecv
Definition: net.h:326
CConnman::ListenSocket::socket
SOCKET socket
Definition: net.h:960
CNode::m_permissionFlags
NetPermissionFlags m_permissionFlags
Definition: net.h:403
CNode::nTimeOffset
std::atomic< int64_t > nTimeOffset
Definition: net.h:428
bitcoin-config.h
CNode::nServices
std::atomic< ServiceFlags > nServices
Definition: net.h:404
WSAGetLastError
#define WSAGetLastError()
Definition: compat.h:43
CConnman::PoissonNextSendInbound
std::chrono::microseconds PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
Attempts to obfuscate tx time through exponentially distributed emitting.
Definition: net.cpp:3072
CConnman::Start
bool Start(CScheduler &scheduler, const Options &options)
Definition: net.cpp:2511
CConnman::CalculateKeyedNetGroup
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
Definition: net.cpp:3094
CAddrDB::Write
bool Write(const CAddrMan &addr)
Definition: addrdb.cpp:235
V1TransportDeserializer::readData
int readData(Span< const uint8_t > msg_bytes)
Definition: net.cpp:711
Network
Network
A network type.
Definition: netaddress.h:45
CAddress::nTime
uint32_t nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
Definition: protocol.h:449
CConnman::GetTryNewOutboundPeer
bool GetTryNewOutboundPeer() const
Definition: net.cpp:1788
CConnman::StopThreads
void StopThreads()
Definition: net.cpp:2663
DEFAULT_FORCEDNSSEED
static constexpr bool DEFAULT_FORCEDNSSEED
Definition: net.h:82
MayHaveUsefulAddressDB
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
Definition: protocol.h:352
CConnman::NotifyNumConnectionsChanged
void NotifyNumConnectionsChanged()
Definition: net.cpp:1298
HasAllDesirableServiceFlags
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
Definition: protocol.h:343
CNode::fDisconnect
std::atomic_bool fDisconnect
Definition: net.h:452
V1TransportDeserializer::data_hash
uint256 data_hash
Definition: net.h:322
proxyType
Definition: netbase.h:48
GetRand
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:591
CService::ToStringIPPort
std::string ToStringIPPort() const
Definition: netaddress.cpp:1028
CSipHasher
SipHash-2-4.
Definition: siphash.h:13
CSubNet::Match
bool Match(const CNetAddr &addr) const
Definition: netaddress.cpp:1147
DNSSEEDS_DELAY_PEER_THRESHOLD
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
Definition: net.cpp:77
CConnman::GetMaxOutboundTimeLeftInCycle
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time left in the current max outbound cycle in case of no limit, it will always return 0
Definition: net.cpp:2914
scheduler.h
NetPermissionFlags
NetPermissionFlags
Definition: net_permissions.h:18
CConnman::nPrevNodeCount
unsigned int nPrevNodeCount
Definition: net.h:1071
ConnectionType::MANUAL
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
CConnman::AddAddrFetch
void AddAddrFetch(const std::string &strDest)
Definition: net.cpp:116
CConnman::InactivityCheck
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
Definition: net.cpp:1318
FastRandomContext::randbits
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:172
MAX_BLOCK_SERIALIZED_SIZE
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
Definition: consensus.h:13
CNetAddr::ToStringIP
std::string ToStringIP() const
Definition: netaddress.cpp:608
ReverseCompareNodeTimeConnected
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:842
CloseSocket
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
Definition: sock.cpp:329
CNode::addr
const CAddress addr
Definition: net.h:430
CConnman::GetNodeStats
void GetNodeStats(std::vector< CNodeStats > &vstats) const
Definition: net.cpp:2826
CConnman::OpenNetworkConnection
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
Definition: net.cpp:2200
CAddrDB
Access to the (IP) address database (peers.dat)
Definition: addrdb.h:68
NodeEvictionCandidate::nKeyedNetGroup
uint64_t nKeyedNetGroup
Definition: net.h:1210
CNode::GetLocalServices
ServiceFlags GetLocalServices() const
Definition: net.h:656
Span::size
constexpr std::size_t size() const noexcept
Definition: span.h:182
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:564
HaveNameProxy
bool HaveNameProxy()
Definition: netbase.cpp:641
Span
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:92
CAddrInfo
Extended statistics about a CAddress.
Definition: addrman.h:32
CNode::nTimeConnected
const int64_t nTimeConnected
Unix epoch time at peer connection, in seconds.
Definition: net.h:427
NetPermissionFlags::BloomFilter
@ BloomFilter
CConnman::FindNode
CNode * FindNode(const CNetAddr &ip)
Definition: net.cpp:308
NetEventsInterface::InitializeNode
virtual void InitializeNode(CNode *pnode)=0
Initialize a peer (setup state, queue any initial messages)
ConnectionType::INBOUND
@ INBOUND
Inbound connections are those initiated by a peer.
CompareNodeNetworkTime::m_is_local
const bool m_is_local
Definition: net.cpp:886
V1TransportDeserializer::hdr
CMessageHeader hdr
Definition: net.h:325
strencodings.h
GUARDED_BY
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(cs_mapLocalHost)
CConnman::m_addr_response_caches
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
Definition: net.h:1098
NET_I2P
@ NET_I2P
I2P.
Definition: netaddress.h:59
CSemaphoreGrant
RAII-style semaphore lock.
Definition: sync.h:315
ReverseCompareNodeMinPingTime
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:837
protocol.h
ConnectionDirection::In
@ In
CNetAddr::GetNetwork
enum Network GetNetwork() const
Definition: netaddress.cpp:524
Hash
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
random.h
banman.h
CService::ToString
std::string ToString() const
Definition: netaddress.cpp:1037
MAX_SIZE
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
Definition: serialize.h:31
GetRandInt
int GetRandInt(int nMax) noexcept
Definition: random.cpp:596
CNode::m_deserializer
std::unique_ptr< TransportDeserializer > m_deserializer
Definition: net.h:400
CConnman::mutexMsgProc
Mutex mutexMsgProc
Definition: net.h:1147
CNodeStats::m_mapped_as
uint32_t m_mapped_as
Definition: net.h:274
CConnman::nLocalServices
ServiceFlags nLocalServices
Services this instance offers.
Definition: net.h:1112
CConnman::ThreadSocketHandler
void ThreadSocketHandler()
Definition: net.cpp:1631
CConnman::ThreadOpenAddedConnections
void ThreadOpenAddedConnections()
Definition: net.cpp:2172
SplitHostPort
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
Definition: strencodings.cpp:110
V1TransportDeserializer::in_data
bool in_data
Definition: net.h:323
IsPeerAddrLocalGood
bool IsPeerAddrLocalGood(CNode *pnode)
Definition: net.cpp:198
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:40
NodeEvictionCandidate
Definition: net.h:1200
CAddrMan::Add
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Add a single address.
Definition: addrman.h:514
LOCAL_MANUAL
@ LOCAL_MANUAL
Definition: net.h:194
GetLocal
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
Definition: net.cpp:128
SelectNodeToEvict
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
Definition: net.cpp:981
CNode::ConnectedThroughNetwork
Network ConnectedThroughNetwork() const
Get network the peer connected through.
Definition: net.cpp:563
CAddrMan::Clear
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!cs)
Definition: addrman.h:470
CompareNodeTXTime
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:859
INVALID_SOCKET
#define INVALID_SOCKET
Definition: compat.h:53
CNode::cs_vRecv
Mutex cs_vRecv
Definition: net.h:414
CConnman::DumpAddresses
void DumpAddresses()
Definition: net.cpp:1760
CConnman::vWhitelistedRange
std::vector< NetWhitelistPermissions > vWhitelistedRange
Definition: net.h:1054
ip
static CService ip(uint32_t i)
Definition: denialofservice_tests.cpp:30
CConnman::m_start_extra_block_relay_peers
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
Definition: net.h:1180
IsReachable
bool IsReachable(enum Network net)
Definition: net.cpp:277
CNode::AddRef
CNode * AddRef()
Definition: net.h:624
CService::SetSockAddr
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:941
CConnman::SocketSendData
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
Definition: net.cpp:786
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:368
CSipHasher::Finalize
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:76
RandAddEvent
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:587
IsSelectableSocket
static bool IsSelectableSocket(const SOCKET &s)
Definition: compat.h:100
CConnman::m_banman
BanMan * m_banman
Pointer to this node's banman.
Definition: net.h:1132
cs_mapLocalHost
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:111
compat.h
CConnman::AlreadyConnectedToAddress
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
Definition: net.cpp:352
send
static RPCHelpMan send()
Definition: rpcwallet.cpp:4031
NetEventsInterface::SendMessages
virtual bool SendMessages(CNode *pnode) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
Send queued protocol messages to a given node.
CNetAddr::IsRoutable
bool IsRoutable() const
Definition: netaddress.cpp:490
DNSSEEDS_DELAY_FEW_PEERS
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
Definition: net.cpp:75
CNodeStats::fRelayTxes
bool fRelayTxes
Definition: net.h:244
CConnman::threadOpenConnections
std::thread threadOpenConnections
Definition: net.h:1167
CNode::m_tx_relay
std::unique_ptr< TxRelay > m_tx_relay
Definition: net.h:558
CSemaphoreGrant::TryAcquire
bool TryAcquire()
Definition: sync.h:338
MAX_PROTOCOL_MESSAGE_LENGTH
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
Definition: net.h:58
CompareNodeNetworkTime
Sort eviction candidates by network/localhost and connection uptime.
Definition: net.cpp:885
netaddress.h
CNode::m_conn_type
const ConnectionType m_conn_type
Definition: net.h:676
CConnman::ForNode
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
Definition: net.cpp:3059
consensus.h
BF_NONE
@ BF_NONE
Definition: net.cpp:87
CSerializedNetMsg
Definition: net.h:101
CNode::fSuccessfullyConnected
std::atomic_bool fSuccessfullyConnected
fSuccessfullyConnected is set to true on receiving VERACK from the peer.
Definition: net.h:449
CConnman::Options::onion_binds
std::vector< CService > onion_binds
Definition: net.h:770
CConnman::CachedAddrResponse
Cache responses to addr requests to minimize privacy leak.
Definition: net.h:1079
CConnman::GetNewNodeId
NodeId GetNewNodeId()
Definition: net.cpp:2464
SetReachable
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:269
CMessageHeader::COMMAND_SIZE
static constexpr size_t COMMAND_SIZE
Definition: protocol.h:34
CConnman::fAddressesInitialized
bool fAddressesInitialized
Definition: net.h:1061
CConnman::ListenSocket
Definition: net.h:958
AddedNodeInfo
Definition: net.h:90
CMessageHeader::IsCommandValid
bool IsCommandValid() const
Definition: protocol.cpp:107
CNetAddr::GetMappedAS
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
Definition: netaddress.cpp:725
CompareNodeNetworkTime::CompareNodeNetworkTime
CompareNodeNetworkTime(bool is_local, Network network)
Definition: net.cpp:888
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:588
NODE_BLOOM
@ NODE_BLOOM
Definition: protocol.h:281
LogPrintf
#define LogPrintf(...)
Definition: logging.h:184
CConnman::addrman
CAddrMan & addrman
Definition: net.h:1062
CNodeStats::minFeeFilter
CAmount minFeeFilter
Definition: net.h:265
CNode::m_bip152_highbandwidth_to
std::atomic< bool > m_bip152_highbandwidth_to
Definition: net.h:527
CConnman::Options::m_use_addrman_outgoing
bool m_use_addrman_outgoing
Definition: net.h:774
CConnman::GetTotalBytesRecv
uint64_t GetTotalBytesRecv() const
Definition: net.cpp:2957
DEFAULT_FIXEDSEEDS
static constexpr bool DEFAULT_FIXEDSEEDS
Definition: net.h:84
CNetAddr::IsValid
bool IsValid() const
Definition: netaddress.cpp:451
fNameLookup
bool fNameLookup
Definition: netbase.cpp:39
Shuffle
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:231
CScheduler::scheduleEvery
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
Definition: scheduler.cpp:110
NetPermissionFlags::ForceRelay
@ ForceRelay
id
static NodeId id
Definition: denialofservice_tests.cpp:37
CSubNet
Definition: netaddress.h:486
CConnman::ListenSocket::AddSocketPermissionFlags
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
Definition: net.h:961
CHash256::Finalize
void Finalize(Span< unsigned char > output)
Definition: hash.h:30
V1TransportDeserializer::hasher
CHash256 hasher
Definition: net.h:321
CAddrMan::ResolveCollisions
void ResolveCollisions() EXCLUSIVE_LOCKS_REQUIRED(!cs)
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.h:565
CNetCleanup
Definition: net.cpp:2624
CConnman::InitBinds
bool InitBinds(const Options &options)
Definition: net.cpp:2489
Discover
void Discover()
Definition: net.cpp:2390
CConnman::m_peer_connect_timeout
int64_t m_peer_connect_timeout
Definition: net.h:1050
CAddrInfo::nLastTry
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:36
NetworkErrorString
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: sock.cpp:311
CNode::cs_hSocket
Mutex cs_hSocket
Definition: net.h:413
CConnman::vNodesDisconnected
std::list< CNode * > vNodesDisconnected
Definition: net.h:1068
SOCKET_ERROR
#define SOCKET_ERROR
Definition: compat.h:54
CConnman::threadMessageHandler
std::thread threadMessageHandler
Definition: net.h:1168
uint256
256-bit opaque blob.
Definition: uint256.h:124
CNode::cs_SubVer
RecursiveMutex cs_SubVer
Definition: net.h:436
LogPrint
#define LogPrint(category,...)
Definition: logging.h:188
CConnman::nSeed0
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
Definition: net.h:1141
ConnectionType::FEELER
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
ser_writedata32
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:74
CMessageHeader::MESSAGE_START_SIZE
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:33
NetPermissionFlags::Relay
@ Relay
WSAEWOULDBLOCK
#define WSAEWOULDBLOCK
Definition: compat.h:46
CConnman::~CConnman
~CConnman()
Definition: net.cpp:2729
CConnman::Options
Definition: net.h:751
CConnman::GetReceiveFloodSize
unsigned int GetReceiveFloodSize() const
Definition: net.cpp:2974
EraseLastKElements
static void EraseLastKElements(std::vector< T > &elements, Comparator comparator, size_t k, std::function< bool(const NodeEvictionCandidate &)> predicate=[](const NodeEvictionCandidate &n) { return true;})
Sort an array by the specified comparator, then erase the last K elements where predicate is true.
Definition: net.cpp:899
CNode::grantOutbound
CSemaphoreGrant grantOutbound
Definition: net.h:453
CConnman::GetMaxOutboundTarget
uint64_t GetMaxOutboundTarget() const
Definition: net.cpp:2903
gArgs
ArgsManager gArgs
Definition: system.cpp:84
CDataStream::size
size_type size() const
Definition: streams.h:255
CService::GetPort
uint16_t GetPort() const
Definition: netaddress.cpp:955
NodeEvictionCandidate::m_is_local
bool m_is_local
Definition: net.h:1212
NetEventsInterface::ProcessMessages
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Process protocol messages received from a given node.
bilingual_str::original
std::string original
Definition: translation.h:17
NODE_NONE
@ NODE_NONE
Definition: protocol.h:274
CChainParams::MessageStart
const CMessageHeader::MessageStartChars & MessageStart() const
Definition: chainparams.h:83
CMessageHeader::CHECKSUM_SIZE
static constexpr size_t CHECKSUM_SIZE
Definition: protocol.h:36
NodeEvictionCandidate::nTimeConnected
int64_t nTimeConnected
Definition: net.h:1203
CChainParams::DNSSeeds
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
Definition: chainparams.h:114
CConnman::nLastNodeId
std::atomic< NodeId > nLastNodeId
Definition: net.h:1070
ui_interface.h
CNode::nLastTXTime
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
Definition: net.h:571
CConnman::RemoveAddedNode
bool RemoveAddedNode(const std::string &node)
Definition: net.cpp:2798
V1TransportDeserializer::hdrbuf
CDataStream hdrbuf
Definition: net.h:324
sha256.h
CConnman::GetExtraFullOutboundCount
int GetExtraFullOutboundCount() const
Definition: net.cpp:1805
InterruptSocks5
void InterruptSocks5(bool interrupt)
Definition: netbase.cpp:753
MAX_UPLOAD_TIMEFRAME
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
Definition: net.cpp:80
CConnman::GetCurrentBlockRelayOnlyConns
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
Definition: net.cpp:2105
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
CClientUIInterface::MSG_ERROR
@ MSG_ERROR
Definition: ui_interface.h:68
ANCHORS_DATABASE_FILENAME
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
Definition: net.cpp:58
CConnman::nSeed1
const uint64_t nSeed1
Definition: net.h:1141
CConnman::threadI2PAcceptIncoming
std::thread threadI2PAcceptIncoming
Definition: net.h:1169
CAddrMan
Stochastical (IP) address manager.
Definition: addrman.h:177
CAddrMan::m_asmap
std::vector< bool > m_asmap
Definition: addrman.h:194
V1TransportDeserializer::Reset
void Reset()
Definition: net.h:334
Span::data
constexpr C * data() const noexcept
Definition: span.h:169
strSubVersion
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:114
CConnman::StopNodes
void StopNodes()
Definition: net.cpp:2680
CConnman::m_try_another_outbound_peer
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay This t...
Definition: net.h:1174
ConnectionTypeAsString
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
Definition: net.cpp:517
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
SanitizeString
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
Definition: strencodings.cpp:27
V1TransportDeserializer::GetMessageHash
const uint256 & GetMessageHash() const
Definition: net.cpp:728
base_blob::IsNull
bool IsNull() const
Definition: uint256.h:31
LocalServiceInfo::nScore
int nScore
Definition: net.h:229
CAddress
A CService with information about it as peer.
Definition: protocol.h:358
MAX_BLOCK_RELAY_ONLY_CONNECTIONS
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
Definition: net.h:66
CMessageHeader
Message header.
Definition: protocol.h:30
NetPermissionFlags::Implicit
@ Implicit
CConnman::SetNetworkActive
void SetNetworkActive(bool active)
Definition: net.cpp:2441
instance_of_cnetcleanup
static CNetCleanup instance_of_cnetcleanup
Definition: net.cpp:2637
CConnman::NodeFullyConnected
static bool NodeFullyConnected(const CNode *pnode)
Definition: net.cpp:3013
DEFAULT_WHITELISTRELAY
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
Definition: net.h:47
LocalServiceInfo
Definition: net.h:228
CNode::cs_addrName
RecursiveMutex cs_addrName
Definition: net.h:698
NetPermissions::AddFlag
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
Definition: net_permissions.h:58
translation.h
SetSocketNoDelay
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
Definition: netbase.cpp:746
CNode::m_inbound_onion
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e. connected via our Tor onion service.
Definition: net.h:434
GetLocalAddrForPeer
std::optional< CAddress > GetLocalAddrForPeer(CNode *pnode)
Returns a local address that we should advertise to this peer.
Definition: net.cpp:205
CNetCleanup::CNetCleanup
CNetCleanup()
Definition: net.cpp:2627
RANDOMIZER_ID_NETGROUP
static const uint64_t RANDOMIZER_ID_NETGROUP
Definition: net.cpp:103
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
CAddrMan::Attempt
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime()) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Mark an entry as connection attempted to.
Definition: addrman.h:555
CSubNet::ToString
std::string ToString() const
Definition: netaddress.cpp:1175
CConnman::cs_vNodes
RecursiveMutex cs_vNodes
Definition: net.h:1069
X
#define X(name)
Definition: net.cpp:569
LOCK
#define LOCK(cs)
Definition: sync.h:232
CNode::m_prefer_evict
bool m_prefer_evict
Definition: net.h:442
ConnectionType::ADDR_FETCH
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
CConnman::GetExtraBlockRelayCount
int GetExtraBlockRelayCount() const
Definition: net.cpp:1819
MSG_DONTWAIT
#define MSG_DONTWAIT
Definition: compat.h:115
i2p.h
NetEventsInterface::FinalizeNode
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
V1TransportDeserializer::GetMessage
std::optional< CNetMessage > GetMessage(std::chrono::microseconds time, uint32_t &out_err_raw_size) override
Definition: net.cpp:736
NET_ONION
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
MSG_NOSIGNAL
#define MSG_NOSIGNAL
Definition: compat.h:110
CAddrMan::Good
void Good(const CService &addr, int64_t nTime=GetAdjustedTime()) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Mark an entry as accessible.
Definition: addrman.h:545
CNode::CloseSocketDisconnect
void CloseSocketDisconnect()
Definition: net.cpp:500
CNode::ConnectionTypeAsString
std::string ConnectionTypeAsString() const
Definition: net.h:665
V1TransportDeserializer
Definition: net.h:316
LOCAL_IF
@ LOCAL_IF
Definition: net.h:191
CLIENT_VERSION
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
RANDOMIZER_ID_ADDRCACHE
static const uint64_t RANDOMIZER_ID_ADDRCACHE
Definition: net.cpp:105
CNode::cs_addrLocal
RecursiveMutex cs_addrLocal
Definition: net.h:703
CConnman::SocketHandler
void SocketHandler()
Definition: net.cpp:1513
ConvertSeeds
static std::vector< CAddress > ConvertSeeds(const std::vector< uint8_t > &vSeedsIn)
Convert the serialized seeds into usable address objects.
Definition: net.cpp:153
CompareNetGroupKeyed
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:847
CNode::m_last_ping_time
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
Definition: net.h:574
CNode::GetAddrLocal
CService GetAddrLocal() const
Definition: net.cpp:549
CConnman::DisconnectNodes
void DisconnectNodes()
Definition: net.cpp:1248
CDataStream::resize
void resize(size_type n, value_type c=0)
Definition: streams.h:257
i2p::Connection
An established connection with another peer.
Definition: i2p.h:31
FEELER_INTERVAL
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
Definition: net.h:54
CConnman::GetAddedNodeInfo
std::vector< AddedNodeInfo > GetAddedNodeInfo() const
Definition: net.cpp:2118
ProtectEvictionCandidatesByRatio
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
Definition: net.cpp:908
CMessageHeader::pchMessageStart
char pchMessageStart[MESSAGE_START_SIZE]
Definition: protocol.h:54
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:536
CMessageHeader::HEADER_SIZE
static constexpr size_t HEADER_SIZE
Definition: protocol.h:39
MAX_BLOCK_RELAY_ONLY_ANCHORS
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
Definition: net.cpp:55
FastRandomContext::randrange
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:190
LocalServiceInfo::nPort
uint16_t nPort
Definition: net.h:230
CAddrDB::Read
bool Read(CAddrMan &addr)
Definition: addrdb.cpp:240
WSAEINTR
#define WSAEINTR
Definition: compat.h:49
CThreadInterrupt::reset
void reset()
Definition: threadinterrupt.cpp:17
CNode::nLastBlockTime
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
Definition: net.h:565
GetProxy
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:616
getAllNetMessageTypes
const std::vector< std::string > & getAllNetMessageTypes()
Definition: protocol.cpp:179
CConnman::Options::m_specified_outgoing
std::vector< std::string > m_specified_outgoing
Definition: net.h:775
CConnman::Stop
void Stop()
Definition: net.h:814
node
Definition: interfaces.cpp:68
assert
assert(s1.IsAddrV1Compatible())
CConnman::AddNode
bool AddNode(const std::string &node)
Definition: net.cpp:2787
CNode::IsInboundConn
bool IsInboundConn() const
Definition: net.h:495
CAutoFile::write
void write(const char *pch, size_t nSize)
Definition: streams.h:638
CNode::vRecvMsg
std::list< CNetMessage > vRecvMsg
Definition: net.h:696
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:204
i2p::Connection::me
CService me
Our I2P address.
Definition: i2p.h:36
ReadAnchors
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:261
sockopt_arg_type
void * sockopt_arg_type
Definition: compat.h:88
V1TransportSerializer::prepareForTransport
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
Definition: net.cpp:773
BF_DONT_ADVERTISE
@ BF_DONT_ADVERTISE
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections,...
Definition: net.cpp:94
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:138
RANDOMIZER_ID_LOCALHOSTNONCE
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
Definition: net.cpp:104
CConnman::threadOpenAddedConnections
std::thread threadOpenAddedConnections
Definition: net.h:1166
CConnman::CachedAddrResponse::m_cache_entry_expiration
std::chrono::microseconds m_cache_entry_expiration
Definition: net.h:1081
CNetAddr::SetInternal
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:173
CNode::SetAddrLocal
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
Definition: net.cpp:554
V1TransportDeserializer::m_node_id
const NodeId m_node_id
Definition: net.h:320
CNode::m_min_ping_time
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
Definition: net.h:578
ConnectionType::BLOCK_RELAY
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
netbase.h
TRACE6
#define TRACE6(context, event, a, b, c, d, e, f)
Definition: trace.h:34
CNode::ReceiveMsgBytes
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
Definition: net.cpp:627
LookupNumeric
CService LookupNumeric(const std::string &name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
Resolve a service string with a numeric IP to its first corresponding service.
Definition: netbase.cpp:229
Span::first
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:199
CConnman::ThreadI2PAcceptIncoming
void ThreadI2PAcceptIncoming()
Definition: net.cpp:2290
GetBindAddress
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
Definition: net.cpp:368
ConnectionDirection
ConnectionDirection
Definition: netbase.h:32
DEFAULT_WHITELISTFORCERELAY
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
Definition: net.h:49
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
CNode::MaybeSetAddrName
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
Definition: net.cpp:542
CConnman::ThreadOpenConnections
void ThreadOpenConnections(std::vector< std::string > connect)
Definition: net.cpp:1833
BF_REPORT_ERROR
@ BF_REPORT_ERROR
Definition: net.cpp:89
CConnman::semOutbound
std::unique_ptr< CSemaphore > semOutbound
Definition: net.h:1114
CNode::nVersion
std::atomic< int > nVersion
Definition: net.h:435
BCLog::NET
@ NET
Definition: logging.h:38
CConnman::semAddnode
std::unique_ptr< CSemaphore > semAddnode
Definition: net.h:1115
CConnman::m_next_send_inv_to_incoming
std::atomic< std::chrono::microseconds > m_next_send_inv_to_incoming
Definition: net.h:1182
Lookup
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:197
CConnman::GetTotalBytesSent
uint64_t GetTotalBytesSent() const
Definition: net.cpp:2963
CConnman::flagInterruptMsgProc
std::atomic< bool > flagInterruptMsgProc
Definition: net.h:1148
fListen
bool fListen
Definition: net.cpp:110
ConnectThroughProxy
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, uint16_t port, const Sock &sock, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
Definition: netbase.cpp:655
CConnman::m_msgproc
NetEventsInterface * m_msgproc
Definition: net.h:1130
CMessageHeader::pchChecksum
uint8_t pchChecksum[CHECKSUM_SIZE]
Definition: protocol.h:57
CConnman::threadDNSAddressSeed
std::thread threadDNSAddressSeed
Definition: net.h:1164
CConnman::Init
void Init(const Options &connOptions)
Definition: net.h:781
CConnman::GenerateSelectSet
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Definition: net.cpp:1349
DEFAULT_DNSSEED
static constexpr bool DEFAULT_DNSSEED
Definition: net.h:83
LOCAL_BIND
@ LOCAL_BIND
Definition: net.h:192
net.h
V1TransportDeserializer::m_chain_params
const CChainParams & m_chain_params
Definition: net.h:319
GetListenPort
uint16_t GetListenPort()
Definition: net.cpp:122
CAddrMan::size
size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs)
Return the number of (unique) addresses in all tables.
Definition: addrman.h:506
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:594
CConnman::m_i2p_sam_session
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
Definition: net.h:1162
CConnman::threadSocketHandler
std::thread threadSocketHandler
Definition: net.h:1165
CConnman::CheckIncomingNonce
bool CheckIncomingNonce(uint64_t nonce)
Definition: net.cpp:357
CConnman::m_max_outbound_block_relay
int m_max_outbound_block_relay
Definition: net.h:1123
IsLocal
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:302
ConnectionType
ConnectionType
Different types of connections to a peer.
Definition: net.h:121
DUMP_PEERS_INTERVAL
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
Definition: net.cpp:61
thread.h
CNode::fPauseSend
std::atomic_bool fPauseSend
Definition: net.h:458
CNodeStats
Definition: net.h:239
nonce
unsigned int nonce
Definition: miner_tests.cpp:53
V1TransportDeserializer::readHeader
int readHeader(Span< const uint8_t > msg_bytes)
Definition: net.cpp:671
sock.h
CConnman::m_use_addrman_outgoing
bool m_use_addrman_outgoing
Definition: net.h:1128
NetPermissionFlags::Mempool
@ Mempool
CConnman::AddWhitelistPermissionFlags
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
Definition: net.cpp:511
CConnman::clientInterface
CClientUIInterface * clientInterface
Definition: net.h:1129
CDataStream::eof
bool eof() const
Definition: streams.h:356
CConnman::Options::vWhiteBinds
std::vector< NetWhitebindPermissions > vWhiteBinds
Definition: net.h:768
CConnman::fNetworkActive
std::atomic< bool > fNetworkActive
Definition: net.h:1060
CConnman::interruptNet
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
Definition: net.h:1156
CAddrMan::SelectTriedCollision
CAddrInfo SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs)
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:575
BF_EXPLICIT
@ BF_EXPLICIT
Definition: net.cpp:88
CConnman::GetDeterministicRandomizer
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
Definition: net.cpp:3089
DNSSEEDS_DELAY_MANY_PEERS
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
Definition: net.cpp:76
CConnman::GetNodeCount
size_t GetNodeCount(ConnectionDirection) const
Definition: net.cpp:2810
CNetAddr::SetIP
void SetIP(const CNetAddr &ip)
Definition: netaddress.cpp:107
CConnman::nMaxAddnode
int nMaxAddnode
Definition: net.h:1125
base_blob::begin
unsigned char * begin()
Definition: uint256.h:58
GetRandMillis
constexpr auto GetRandMillis
Definition: random.h:84
CConnman::nMaxConnections
int nMaxConnections
Definition: net.h:1116
GetLocalAddress
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
Definition: net.cpp:178
FastRandomContext
Fast randomness source.
Definition: random.h:119
GetTimeMillis
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:117
CConnman::GetAddresses
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
Definition: net.cpp:2735
CConnman::PushMessage
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
Definition: net.cpp:3018
CConnman::ShouldRunInactivityChecks
bool ShouldRunInactivityChecks(const CNode &node, std::optional< int64_t > now=std::nullopt) const
Return true if we should disconnect the peer for failing an inactivity check.
Definition: net.cpp:1312
BindFlags
BindFlags
Used to pass flags to the Bind() function.
Definition: net.cpp:86
CNode::~CNode
~CNode()
Definition: net.cpp:3008
CConnman::BindListenPort
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
Definition: net.cpp:2329
WAIT_LOCK
#define WAIT_LOCK(cs, name)
Definition: sync.h:237
TIMEOUT_INTERVAL
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
Definition: net.h:52
V1TransportDeserializer::nDataPos
unsigned int nDataPos
Definition: net.h:328
proxyType::proxy
CService proxy
Definition: netbase.h:56
EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
Definition: net.h:56
i2p::Connection::sock
std::unique_ptr< Sock > sock
Connected socket.
Definition: i2p.h:33
CaptureMessage
void CaptureMessage(const CAddress &addr, const std::string &msg_type, const Span< const unsigned char > &data, bool is_incoming)
Dump binary message to file, with timestamp.
Definition: net.cpp:3101
CNode::CNode
CNode(NodeId id, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
Definition: net.cpp:2976
V1TransportDeserializer::nHdrPos
unsigned int nHdrPos
Definition: net.h:327
INIT_PROTO_VERSION
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:15
CConnman::RecordBytesSent
void RecordBytesSent(uint64_t bytes)
Definition: net.cpp:2886
net_permissions.h
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
CConnman::GetOutboundTargetBytesLeft
uint64_t GetOutboundTargetBytesLeft() const
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
Definition: net.cpp:2948
SOCKET
unsigned int SOCKET
Definition: compat.h:41
DNSSEEDS_TO_QUERY_AT_ONCE
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
Definition: net.cpp:64
CSipHasher::Write
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
Definition: siphash.cpp:28
GetTimeSeconds
int64_t GetTimeSeconds()
Returns the system time (not mockable)
Definition: time.cpp:127
NodeEvictionCandidate::nLastBlockTime
int64_t nLastBlockTime
Definition: net.h:1205
NodeEvictionCandidate::nLastTXTime
int64_t nLastTXTime
Definition: net.h:1206
CConnman::DeleteNode
void DeleteNode(CNode *pnode)
Definition: net.cpp:2722
AddLocal
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:231
CNode::addrBind
const CAddress addrBind
Definition: net.h:432
CompareNodeNetworkTime::m_network
const Network m_network
Definition: net.cpp:887
CChainParams::GetDefaultPort
uint16_t GetDefaultPort() const
Definition: chainparams.h:84
NodeEvictionCandidate::fRelevantServices
bool fRelevantServices
Definition: net.h:1207