Bitcoin ABC  0.26.3
P2P Digital Currency
net.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
7 #include <config/bitcoin-config.h>
8 #endif
9 
10 #include <net.h>
11 
12 #include <addrdb.h>
13 #include <addrman.h>
14 #include <avalanche/avalanche.h>
15 #include <banman.h>
16 #include <clientversion.h>
17 #include <compat.h>
18 #include <config.h>
19 #include <consensus/consensus.h>
20 #include <crypto/sha256.h>
21 #include <dnsseeds.h>
22 #include <fs.h>
23 #include <i2p.h>
24 #include <netaddress.h>
25 #include <netbase.h>
26 #include <node/ui_interface.h>
27 #include <protocol.h>
28 #include <random.h>
29 #include <scheduler.h>
30 #include <util/sock.h>
31 #include <util/strencodings.h>
32 #include <util/system.h>
33 #include <util/thread.h>
34 #include <util/trace.h>
35 #include <util/translation.h>
36 
37 #ifdef WIN32
38 #include <cstring>
39 #else
40 #include <fcntl.h>
41 #endif
42 
43 #ifdef USE_POLL
44 #include <poll.h>
45 #endif
46 
47 #include <algorithm>
48 #include <array>
49 #include <cmath>
50 #include <cstdint>
51 #include <functional>
52 #include <limits>
53 #include <optional>
54 #include <unordered_map>
55 
57 static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS = 2;
58 static_assert(MAX_BLOCK_RELAY_ONLY_ANCHORS <=
59  static_cast<size_t>(MAX_BLOCK_RELAY_ONLY_CONNECTIONS),
60  "MAX_BLOCK_RELAY_ONLY_ANCHORS must not exceed "
61  "MAX_BLOCK_RELAY_ONLY_CONNECTIONS.");
63 const char *const ANCHORS_DATABASE_FILENAME = "anchors.dat";
64 
65 // How often to dump addresses to peers.dat
66 static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
67 
71 static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
72 
83 static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
84 static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
85 // "many" vs "few" peers
86 static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000;
87 
89 static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME{60 * 60 * 24};
90 
91 // We add a random period time (0 to 1 seconds) to feeler connections to prevent
92 // synchronization.
93 #define FEELER_SLEEP_WINDOW 1
94 
96 enum BindFlags {
97  BF_NONE = 0,
98  BF_EXPLICIT = (1U << 0),
99  BF_REPORT_ERROR = (1U << 1),
104  BF_DONT_ADVERTISE = (1U << 2),
105 };
106 
107 // The set of sockets cannot be modified while waiting
108 // The sleep time needs to be small to avoid new sockets stalling
109 static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
110 
111 const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
112 
113 // SHA256("netgroup")[0:8]
114 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
115 // SHA256("localhostnonce")[0:8]
116 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
117 // SHA256("localhostnonce")[8:16]
118 static const uint64_t RANDOMIZER_ID_EXTRAENTROPY = 0x94b05d41679a4ff7ULL;
119 // SHA256("addrcache")[0:8]
120 static const uint64_t RANDOMIZER_ID_ADDRCACHE = 0x1cf2e4ddd306dda9ULL;
121 //
122 // Global state variables
123 //
124 bool fDiscover = true;
125 bool fListen = true;
127 std::map<CNetAddr, LocalServiceInfo>
129 static bool vfLimited[NET_MAX] GUARDED_BY(g_maplocalhost_mutex) = {};
130 
131 void CConnman::AddAddrFetch(const std::string &strDest) {
133  m_addr_fetches.push_back(strDest);
134 }
135 
136 uint16_t GetListenPort() {
137  // If -bind= is provided with ":port" part, use that (first one if multiple
138  // are provided).
139  for (const std::string &bind_arg : gArgs.GetArgs("-bind")) {
140  CService bind_addr;
141  constexpr uint16_t dummy_port = 0;
142 
143  if (Lookup(bind_arg, bind_addr, dummy_port, /*fAllowLookup=*/false)) {
144  if (bind_addr.GetPort() != dummy_port) {
145  return bind_addr.GetPort();
146  }
147  }
148  }
149 
150  // Otherwise, if -whitebind= without NetPermissionFlags::NoBan is provided,
151  // use that
152  // (-whitebind= is required to have ":port").
153  for (const std::string &whitebind_arg : gArgs.GetArgs("-whitebind")) {
154  NetWhitebindPermissions whitebind;
156  if (NetWhitebindPermissions::TryParse(whitebind_arg, whitebind,
157  error)) {
158  if (!NetPermissions::HasFlag(whitebind.m_flags,
160  return whitebind.m_service.GetPort();
161  }
162  }
163  }
164 
165  // Otherwise, if -port= is provided, use that. Otherwise use the default
166  // port.
167  return static_cast<uint16_t>(
168  gArgs.GetIntArg("-port", Params().GetDefaultPort()));
169 }
170 
171 // find 'best' local address for a particular peer
172 bool GetLocal(CService &addr, const CNetAddr *paddrPeer) {
173  if (!fListen) {
174  return false;
175  }
176 
177  int nBestScore = -1;
178  int nBestReachability = -1;
179  {
181  for (const auto &entry : mapLocalHost) {
182  int nScore = entry.second.nScore;
183  int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
184  if (nReachability > nBestReachability ||
185  (nReachability == nBestReachability && nScore > nBestScore)) {
186  addr = CService(entry.first, entry.second.nPort);
187  nBestReachability = nReachability;
188  nBestScore = nScore;
189  }
190  }
191  }
192  return nBestScore >= 0;
193 }
194 
196 static std::vector<CAddress>
197 convertSeed6(const std::vector<SeedSpec6> &vSeedsIn) {
198  // It'll only connect to one or two seed nodes because once it connects,
199  // it'll get a pile of addresses with newer timestamps. Seed nodes are given
200  // a random 'last seen time' of between one and two weeks ago.
201  const auto one_week{7 * 24h};
202  std::vector<CAddress> vSeedsOut;
203  vSeedsOut.reserve(vSeedsIn.size());
204  FastRandomContext rng;
205  for (const auto &seed_in : vSeedsIn) {
206  struct in6_addr ip;
207  memcpy(&ip, seed_in.addr, sizeof(ip));
208  CAddress addr(CService(ip, seed_in.port),
210  addr.nTime =
211  rng.rand_uniform_delay(Now<NodeSeconds>() - one_week, -one_week);
212  vSeedsOut.push_back(addr);
213  }
214  return vSeedsOut;
215 }
216 
217 // Get best local address for a particular peer as a CService. Otherwise, return
218 // the unroutable 0.0.0.0 but filled in with the normal parameters, since the IP
219 // may be changed to a useful one by discovery.
221  CService ret{CNetAddr(), GetListenPort()};
222  CService addr;
223  if (GetLocal(addr, &addrPeer)) {
224  ret = CService{addr};
225  }
226  return ret;
227 }
228 
229 static int GetnScore(const CService &addr) {
231  const auto it = mapLocalHost.find(addr);
232  return (it != mapLocalHost.end()) ? it->second.nScore : 0;
233 }
234 
235 // Is our peer's addrLocal potentially useful as an external IP source?
237  CService addrLocal = pnode->GetAddrLocal();
238  return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
239  IsReachable(addrLocal.GetNetwork());
240 }
241 
242 std::optional<CService> GetLocalAddrForPeer(CNode &node) {
243  CService addrLocal{GetLocalAddress(node.addr)};
244  if (gArgs.GetBoolArg("-addrmantest", false)) {
245  // use IPv4 loopback during addrmantest
246  addrLocal = CService(LookupNumeric("127.0.0.1", GetListenPort()));
247  }
248  // If discovery is enabled, sometimes give our peer the address it
249  // tells us that it sees us as in case it has a better idea of our
250  // address than we do.
251  FastRandomContext rng;
252  if (IsPeerAddrLocalGood(&node) &&
253  (!addrLocal.IsRoutable() ||
254  rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0)) {
255  if (node.IsInboundConn()) {
256  // For inbound connections, assume both the address and the port
257  // as seen from the peer.
258  addrLocal = CService{node.GetAddrLocal()};
259  } else {
260  // For outbound connections, assume just the address as seen from
261  // the peer and leave the port in `addrLocal` as returned by
262  // `GetLocalAddress()` above. The peer has no way to observe our
263  // listening port when we have initiated the connection.
264  addrLocal.SetIP(node.GetAddrLocal());
265  }
266  }
267  if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false)) {
268  LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n",
269  addrLocal.ToString(), node.GetId());
270  return addrLocal;
271  }
272  // Address is unroutable. Don't advertise.
273  return std::nullopt;
274 }
275 
276 // Learn a new local address.
277 bool AddLocal(const CService &addr, int nScore) {
278  if (!addr.IsRoutable()) {
279  return false;
280  }
281 
282  if (!fDiscover && nScore < LOCAL_MANUAL) {
283  return false;
284  }
285 
286  if (!IsReachable(addr)) {
287  return false;
288  }
289 
290  LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
291 
292  {
294  const auto [it, is_newly_added] =
295  mapLocalHost.emplace(addr, LocalServiceInfo());
296  LocalServiceInfo &info = it->second;
297  if (is_newly_added || nScore >= info.nScore) {
298  info.nScore = nScore + !is_newly_added;
299  info.nPort = addr.GetPort();
300  }
301  }
302 
303  return true;
304 }
305 
306 bool AddLocal(const CNetAddr &addr, int nScore) {
307  return AddLocal(CService(addr, GetListenPort()), nScore);
308 }
309 
310 void RemoveLocal(const CService &addr) {
312  LogPrintf("RemoveLocal(%s)\n", addr.ToString());
313  mapLocalHost.erase(addr);
314 }
315 
316 void SetReachable(enum Network net, bool reachable) {
317  if (net == NET_UNROUTABLE || net == NET_INTERNAL) {
318  return;
319  }
321  vfLimited[net] = !reachable;
322 }
323 
324 bool IsReachable(enum Network net) {
326  return !vfLimited[net];
327 }
328 
329 bool IsReachable(const CNetAddr &addr) {
330  return IsReachable(addr.GetNetwork());
331 }
332 
334 bool SeenLocal(const CService &addr) {
336  const auto it = mapLocalHost.find(addr);
337  if (it == mapLocalHost.end()) {
338  return false;
339  }
340  ++it->second.nScore;
341  return true;
342 }
343 
345 bool IsLocal(const CService &addr) {
347  return mapLocalHost.count(addr) > 0;
348 }
349 
352  for (CNode *pnode : m_nodes) {
353  if (static_cast<CNetAddr>(pnode->addr) == ip) {
354  return pnode;
355  }
356  }
357  return nullptr;
358 }
359 
362  for (CNode *pnode : m_nodes) {
363  if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
364  return pnode;
365  }
366  }
367  return nullptr;
368 }
369 
370 CNode *CConnman::FindNode(const std::string &addrName) {
372  for (CNode *pnode : m_nodes) {
373  if (pnode->m_addr_name == addrName) {
374  return pnode;
375  }
376  }
377  return nullptr;
378 }
379 
382  for (CNode *pnode : m_nodes) {
383  if (static_cast<CService>(pnode->addr) == addr) {
384  return pnode;
385  }
386  }
387  return nullptr;
388 }
389 
391  return FindNode(static_cast<CNetAddr>(addr)) ||
392  FindNode(addr.ToStringIPPort());
393 }
394 
395 bool CConnman::CheckIncomingNonce(uint64_t nonce) {
397  for (const CNode *pnode : m_nodes) {
398  if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() &&
399  pnode->GetLocalNonce() == nonce) {
400  return false;
401  }
402  }
403  return true;
404 }
405 
408  CAddress addr_bind;
409  struct sockaddr_storage sockaddr_bind;
410  socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
411  if (sock != INVALID_SOCKET) {
412  if (!getsockname(sock, (struct sockaddr *)&sockaddr_bind,
413  &sockaddr_bind_len)) {
414  addr_bind.SetSockAddr((const struct sockaddr *)&sockaddr_bind);
415  } else {
416  LogPrint(BCLog::NET, "Warning: getsockname failed\n");
417  }
418  }
419  return addr_bind;
420 }
421 
422 CNode *CConnman::ConnectNode(CAddress addrConnect, const char *pszDest,
423  bool fCountFailure, ConnectionType conn_type) {
424  assert(conn_type != ConnectionType::INBOUND);
425 
426  if (pszDest == nullptr) {
427  if (IsLocal(addrConnect)) {
428  return nullptr;
429  }
430 
431  // Look for an existing connection
432  CNode *pnode = FindNode(static_cast<CService>(addrConnect));
433  if (pnode) {
434  LogPrintf("Failed to open new connection, already connected\n");
435  return nullptr;
436  }
437  }
438 
439  LogPrint(
440  BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
441  pszDest ? pszDest : addrConnect.ToString(),
442  Ticks<HoursDouble>(pszDest ? 0h : AdjustedTime() - addrConnect.nTime));
443 
444  // Resolve
445  const uint16_t default_port{pszDest != nullptr
446  ? Params().GetDefaultPort(pszDest)
447  : Params().GetDefaultPort()};
448  if (pszDest) {
449  std::vector<CService> resolved;
450  if (Lookup(pszDest, resolved, default_port,
451  fNameLookup && !HaveNameProxy(), 256) &&
452  !resolved.empty()) {
453  addrConnect =
454  CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
455  if (!addrConnect.IsValid()) {
457  "Resolver returned invalid address %s for %s\n",
458  addrConnect.ToString(), pszDest);
459  return nullptr;
460  }
461  // It is possible that we already have a connection to the IP/port
462  // pszDest resolved to. In that case, drop the connection that was
463  // just created.
465  CNode *pnode = FindNode(static_cast<CService>(addrConnect));
466  if (pnode) {
467  LogPrintf("Failed to open new connection, already connected\n");
468  return nullptr;
469  }
470  }
471  }
472 
473  // Connect
474  bool connected = false;
475  std::unique_ptr<Sock> sock;
476  proxyType proxy;
477  CAddress addr_bind;
478  assert(!addr_bind.IsValid());
479 
480  if (addrConnect.IsValid()) {
481  bool proxyConnectionFailed = false;
482 
483  if (addrConnect.GetNetwork() == NET_I2P &&
484  m_i2p_sam_session.get() != nullptr) {
485  i2p::Connection conn;
486  if (m_i2p_sam_session->Connect(addrConnect, conn,
487  proxyConnectionFailed)) {
488  connected = true;
489  sock = std::move(conn.sock);
490  addr_bind = CAddress{conn.me, NODE_NONE};
491  }
492  } else if (GetProxy(addrConnect.GetNetwork(), proxy)) {
493  sock = CreateSock(proxy.proxy);
494  if (!sock) {
495  return nullptr;
496  }
497  connected = ConnectThroughProxy(
498  proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), *sock,
499  nConnectTimeout, proxyConnectionFailed);
500  } else {
501  // no proxy needed (none set for target network)
502  sock = CreateSock(addrConnect);
503  if (!sock) {
504  return nullptr;
505  }
506  connected =
507  ConnectSocketDirectly(addrConnect, *sock, nConnectTimeout,
508  conn_type == ConnectionType::MANUAL);
509  }
510  if (!proxyConnectionFailed) {
511  // If a connection to the node was attempted, and failure (if any)
512  // is not caused by a problem connecting to the proxy, mark this as
513  // an attempt.
514  addrman.Attempt(addrConnect, fCountFailure);
515  }
516  } else if (pszDest && GetNameProxy(proxy)) {
517  sock = CreateSock(proxy.proxy);
518  if (!sock) {
519  return nullptr;
520  }
521  std::string host;
522  uint16_t port{default_port};
523  SplitHostPort(std::string(pszDest), port, host);
524  bool proxyConnectionFailed;
525  connected = ConnectThroughProxy(proxy, host, port, *sock,
526  nConnectTimeout, proxyConnectionFailed);
527  }
528  if (!connected) {
529  return nullptr;
530  }
531 
532  // Add node
533  NodeId id = GetNewNodeId();
535  .Write(id)
536  .Finalize();
537  uint64_t extra_entropy =
539  .Write(id)
540  .Finalize();
541  if (!addr_bind.IsValid()) {
542  addr_bind = GetBindAddress(sock->Get());
543  }
544  CNode *pnode = new CNode(
545  id, sock->Release(), addrConnect, CalculateKeyedNetGroup(addrConnect),
546  nonce, extra_entropy, addr_bind, pszDest ? pszDest : "", conn_type,
547  /* inbound_onion */ false);
548  pnode->AddRef();
549 
550  // We're making a new connection, harvest entropy from the time (and our
551  // peer count)
552  RandAddEvent(uint32_t(id));
553 
554  return pnode;
555 }
556 
558  fDisconnect = true;
559  LOCK(cs_hSocket);
560  if (hSocket != INVALID_SOCKET) {
561  LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
562  CloseSocket(hSocket);
563  }
564 }
565 
567  const CNetAddr &addr) const {
568  for (const auto &subnet : vWhitelistedRange) {
569  if (subnet.m_subnet.Match(addr)) {
570  NetPermissions::AddFlag(flags, subnet.m_flags);
571  }
572  }
573 }
574 
575 std::string ConnectionTypeAsString(ConnectionType conn_type) {
576  switch (conn_type) {
578  return "inbound";
580  return "manual";
582  return "feeler";
584  return "outbound-full-relay";
586  return "block-relay-only";
588  return "addr-fetch";
590  return "avalanche";
591  } // no default case, so the compiler can warn about missing cases
592 
593  assert(false);
594 }
595 
599  return addrLocal;
600 }
601 
602 void CNode::SetAddrLocal(const CService &addrLocalIn) {
605  if (addrLocal.IsValid()) {
606  error("Addr local already set for node: %i. Refusing to change from %s "
607  "to %s",
608  id, addrLocal.ToString(), addrLocalIn.ToString());
609  } else {
610  addrLocal = addrLocalIn;
611  }
612 }
613 
616 }
617 
619  stats.nodeid = this->GetId();
620  stats.addr = addr;
621  stats.addrBind = addrBind;
623  stats.m_last_send = m_last_send;
624  stats.m_last_recv = m_last_recv;
628  stats.m_connected = m_connected;
629  stats.nTimeOffset = nTimeOffset;
630  stats.m_addr_name = m_addr_name;
631  stats.nVersion = nVersion;
632  {
634  stats.cleanSubVer = cleanSubVer;
635  }
636  stats.fInbound = IsInboundConn();
639  {
640  LOCK(cs_vSend);
641  stats.mapSendBytesPerMsgCmd = mapSendBytesPerMsgCmd;
642  stats.nSendBytes = nSendBytes;
643  }
644  {
645  LOCK(cs_vRecv);
646  stats.mapRecvBytesPerMsgCmd = mapRecvBytesPerMsgCmd;
647  stats.nRecvBytes = nRecvBytes;
648  }
650 
653 
654  // Leave string empty if addrLocal invalid (not filled in yet)
655  CService addrLocalUnlocked = GetAddrLocal();
656  stats.addrLocal =
657  addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
658 
659  stats.m_conn_type = m_conn_type;
660 
662  ? std::make_optional(getAvailabilityScore())
663  : std::nullopt;
664 }
665 
666 bool CNode::ReceiveMsgBytes(const Config &config, Span<const uint8_t> msg_bytes,
667  bool &complete) {
668  complete = false;
669  const auto time = GetTime<std::chrono::microseconds>();
670  LOCK(cs_vRecv);
671  m_last_recv = std::chrono::duration_cast<std::chrono::seconds>(time);
672  nRecvBytes += msg_bytes.size();
673  while (msg_bytes.size() > 0) {
674  // Absorb network data.
675  int handled = m_deserializer->Read(config, msg_bytes);
676  if (handled < 0) {
677  return false;
678  }
679 
680  if (m_deserializer->Complete()) {
681  // decompose a transport agnostic CNetMessage from the deserializer
682  CNetMessage msg = m_deserializer->GetMessage(config, time);
683 
684  // Store received bytes per message command to prevent a memory DOS,
685  // only allow valid commands.
686  mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.m_type);
687  if (i == mapRecvBytesPerMsgCmd.end()) {
688  i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
689  }
690 
691  assert(i != mapRecvBytesPerMsgCmd.end());
692  i->second += msg.m_raw_message_size;
693 
694  // push the message to the process queue,
695  vRecvMsg.push_back(std::move(msg));
696 
697  complete = true;
698  }
699  }
700 
701  return true;
702 }
703 
705  Span<const uint8_t> msg_bytes) {
706  // copy data to temporary parsing buffer
707  uint32_t nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
708  uint32_t nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
709 
710  memcpy(&hdrbuf[nHdrPos], msg_bytes.data(), nCopy);
711  nHdrPos += nCopy;
712 
713  // if header incomplete, exit
715  return nCopy;
716  }
717 
718  // deserialize to CMessageHeader
719  try {
720  hdrbuf >> hdr;
721  } catch (const std::exception &) {
722  return -1;
723  }
724 
725  // Reject oversized messages
726  if (hdr.IsOversized(config)) {
727  LogPrint(BCLog::NET, "Oversized header detected\n");
728  return -1;
729  }
730 
731  // switch state to reading message data
732  in_data = true;
733 
734  return nCopy;
735 }
736 
738  unsigned int nRemaining = hdr.nMessageSize - nDataPos;
739  unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
740 
741  if (vRecv.size() < nDataPos + nCopy) {
742  // Allocate up to 256 KiB ahead, but never more than the total message
743  // size.
744  vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
745  }
746 
747  hasher.Write(msg_bytes.first(nCopy));
748  memcpy(&vRecv[nDataPos], msg_bytes.data(), nCopy);
749  nDataPos += nCopy;
750 
751  return nCopy;
752 }
753 
755  assert(Complete());
756  if (data_hash.IsNull()) {
758  }
759  return data_hash;
760 }
761 
764  const std::chrono::microseconds time) {
765  // decompose a single CNetMessage from the TransportDeserializer
766  CNetMessage msg(std::move(vRecv));
767 
768  // store state about valid header, netmagic and checksum
769  msg.m_valid_header = hdr.IsValid(config);
770  // FIXME Split CheckHeaderMagicAndCommand() into CheckHeaderMagic() and
771  // CheckCommand() to prevent the net magic check code duplication.
772  msg.m_valid_netmagic =
773  (memcmp(std::begin(hdr.pchMessageStart),
774  std::begin(config.GetChainParams().NetMagic()),
776  uint256 hash = GetMessageHash();
777 
778  // store command string, payload size
779  msg.m_type = hdr.GetCommand();
782 
783  // We just received a message off the wire, harvest entropy from the time
784  // (and the message checksum)
785  RandAddEvent(ReadLE32(hash.begin()));
786 
787  msg.m_valid_checksum = (memcmp(hash.begin(), hdr.pchChecksum,
789 
790  if (!msg.m_valid_checksum) {
792  "CHECKSUM ERROR (%s, %u bytes), expected %s was %s\n",
796  }
797 
798  // store receive time
799  msg.m_time = time;
800 
801  // reset the network deserializer (prepare for the next message)
802  Reset();
803  return msg;
804 }
805 
807  CSerializedNetMsg &msg,
808  std::vector<uint8_t> &header) {
809  // create dbl-sha256 checksum
810  uint256 hash = Hash(msg.data);
811 
812  // create header
813  CMessageHeader hdr(config.GetChainParams().NetMagic(), msg.m_type.c_str(),
814  msg.data.size());
815  memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
816 
817  // serialize header
818  header.reserve(CMessageHeader::HEADER_SIZE);
819  CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, header, 0, hdr};
820 }
821 
823  size_t nSentSize = 0;
824  size_t nMsgCount = 0;
825 
826  for (const auto &data : node.vSendMsg) {
827  assert(data.size() > node.nSendOffset);
828  int nBytes = 0;
829 
830  {
831  LOCK(node.cs_hSocket);
832  if (node.hSocket == INVALID_SOCKET) {
833  break;
834  }
835 
836  nBytes = send(
837  node.hSocket,
838  reinterpret_cast<const char *>(data.data()) + node.nSendOffset,
839  data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
840  }
841 
842  if (nBytes == 0) {
843  // couldn't send anything at all
844  break;
845  }
846 
847  if (nBytes < 0) {
848  // error
849  int nErr = WSAGetLastError();
850  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE &&
851  nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
852  LogPrint(BCLog::NET, "socket send error for peer=%d: %s\n",
853  node.GetId(), NetworkErrorString(nErr));
854  node.CloseSocketDisconnect();
855  }
856 
857  break;
858  }
859 
860  assert(nBytes > 0);
861  node.m_last_send = GetTime<std::chrono::seconds>();
862  node.nSendBytes += nBytes;
863  node.nSendOffset += nBytes;
864  nSentSize += nBytes;
865  if (node.nSendOffset != data.size()) {
866  // could not send full message; stop sending more
867  break;
868  }
869 
870  node.nSendOffset = 0;
871  node.nSendSize -= data.size();
872  node.fPauseSend = node.nSendSize > nSendBufferMaxSize;
873  nMsgCount++;
874  }
875 
876  node.vSendMsg.erase(node.vSendMsg.begin(),
877  node.vSendMsg.begin() + nMsgCount);
878 
879  if (node.vSendMsg.empty()) {
880  assert(node.nSendOffset == 0);
881  assert(node.nSendSize == 0);
882  }
883 
884  return nSentSize;
885 }
886 
888  const NodeEvictionCandidate &b) {
889  return a.m_min_ping_time > b.m_min_ping_time;
890 }
891 
893  const NodeEvictionCandidate &b) {
894  return a.m_connected > b.m_connected;
895 }
896 
898  const NodeEvictionCandidate &b) {
899  return a.nKeyedNetGroup < b.nKeyedNetGroup;
900 }
901 
903  const NodeEvictionCandidate &b) {
904  // There is a fall-through here because it is common for a node to have many
905  // peers which have not yet relayed a block.
908  }
909 
911  return b.fRelevantServices;
912  }
913 
914  return a.m_connected > b.m_connected;
915 }
916 
918  const NodeEvictionCandidate &b) {
919  // There is a fall-through here because it is common for a node to have more
920  // than a few peers that have not yet relayed txn.
921  if (a.m_last_tx_time != b.m_last_tx_time) {
922  return a.m_last_tx_time < b.m_last_tx_time;
923  }
924 
925  if (a.m_relay_txs != b.m_relay_txs) {
926  return b.m_relay_txs;
927  }
928 
929  if (a.fBloomFilter != b.fBloomFilter) {
930  return a.fBloomFilter;
931  }
932 
933  return a.m_connected > b.m_connected;
934 }
935 
937  const NodeEvictionCandidate &b) {
938  // There is a fall-through here because it is common for a node to have more
939  // than a few peers that have not yet relayed proofs. This fallback is also
940  // used in the case avalanche is not enabled.
943  }
944 
945  return a.m_connected > b.m_connected;
946 }
947 
948 // Pick out the potential block-relay only peers, and sort them by last block
949 // time.
951  const NodeEvictionCandidate &b) {
952  if (a.m_relay_txs != b.m_relay_txs) {
953  return a.m_relay_txs;
954  }
955 
958  }
959 
961  return b.fRelevantServices;
962  }
963 
964  return a.m_connected > b.m_connected;
965 }
966 
968  const NodeEvictionCandidate &b) {
969  // Equality can happen if the nodes have no score or it has not been
970  // computed yet.
973  }
974 
975  return a.m_connected > b.m_connected;
976 }
977 
989  const bool m_is_local;
991  CompareNodeNetworkTime(bool is_local, Network network)
992  : m_is_local(is_local), m_network(network) {}
994  const NodeEvictionCandidate &b) const {
995  if (m_is_local && a.m_is_local != b.m_is_local) {
996  return b.m_is_local;
997  }
998  if ((a.m_network == m_network) != (b.m_network == m_network)) {
999  return b.m_network == m_network;
1000  }
1001  return a.m_connected > b.m_connected;
1002  };
1003 };
1004 
1007 template <typename T, typename Comparator>
1009  std::vector<T> &elements, Comparator comparator, size_t k,
1010  std::function<bool(const NodeEvictionCandidate &)> predicate =
1011  [](const NodeEvictionCandidate &n) { return true; }) {
1012  std::sort(elements.begin(), elements.end(), comparator);
1013  size_t eraseSize = std::min(k, elements.size());
1014  elements.erase(
1015  std::remove_if(elements.end() - eraseSize, elements.end(), predicate),
1016  elements.end());
1017 }
1018 
1020  std::vector<NodeEvictionCandidate> &eviction_candidates) {
1021  // Protect the half of the remaining nodes which have been connected the
1022  // longest. This replicates the non-eviction implicit behavior, and
1023  // precludes attacks that start later.
1024  // To promote the diversity of our peer connections, reserve up to half of
1025  // these protected spots for Tor/onion, localhost and I2P peers, even if
1026  // they're not the longest uptime overall. This helps protect these
1027  // higher-latency peers that tend to be otherwise disadvantaged under our
1028  // eviction criteria.
1029  const size_t initial_size = eviction_candidates.size();
1030  const size_t total_protect_size{initial_size / 2};
1031 
1032  // Disadvantaged networks to protect: I2P, localhost and Tor/onion. In case
1033  // of equal counts, earlier array members have first opportunity to recover
1034  // unused slots from the previous iteration.
1035  struct Net {
1036  bool is_local;
1037  Network id;
1038  size_t count;
1039  };
1040  std::array<Net, 3> networks{{{false, NET_I2P, 0},
1041  {/* localhost */ true, NET_MAX, 0},
1042  {false, NET_ONION, 0}}};
1043 
1044  // Count and store the number of eviction candidates per network.
1045  for (Net &n : networks) {
1046  n.count = std::count_if(
1047  eviction_candidates.cbegin(), eviction_candidates.cend(),
1048  [&n](const NodeEvictionCandidate &c) {
1049  return n.is_local ? c.m_is_local : c.m_network == n.id;
1050  });
1051  }
1052  // Sort `networks` by ascending candidate count, to give networks having
1053  // fewer candidates the first opportunity to recover unused protected slots
1054  // from the previous iteration.
1055  std::stable_sort(networks.begin(), networks.end(),
1056  [](Net a, Net b) { return a.count < b.count; });
1057 
1058  // Protect up to 25% of the eviction candidates by disadvantaged network.
1059  const size_t max_protect_by_network{total_protect_size / 2};
1060  size_t num_protected{0};
1061 
1062  while (num_protected < max_protect_by_network) {
1063  // Count the number of disadvantaged networks from which we have peers
1064  // to protect.
1065  auto num_networks = std::count_if(networks.begin(), networks.end(),
1066  [](const Net &n) { return n.count; });
1067  if (num_networks == 0) {
1068  break;
1069  }
1070  const size_t disadvantaged_to_protect{max_protect_by_network -
1071  num_protected};
1072  const size_t protect_per_network{std::max(
1073  disadvantaged_to_protect / num_networks, static_cast<size_t>(1))};
1074 
1075  // Early exit flag if there are no remaining candidates by disadvantaged
1076  // network.
1077  bool protected_at_least_one{false};
1078 
1079  for (Net &n : networks) {
1080  if (n.count == 0) {
1081  continue;
1082  }
1083  const size_t before = eviction_candidates.size();
1085  eviction_candidates, CompareNodeNetworkTime(n.is_local, n.id),
1086  protect_per_network, [&n](const NodeEvictionCandidate &c) {
1087  return n.is_local ? c.m_is_local : c.m_network == n.id;
1088  });
1089  const size_t after = eviction_candidates.size();
1090  if (before > after) {
1091  protected_at_least_one = true;
1092  const size_t delta{before - after};
1093  num_protected += delta;
1094  if (num_protected >= max_protect_by_network) {
1095  break;
1096  }
1097  n.count -= delta;
1098  }
1099  }
1100  if (!protected_at_least_one) {
1101  break;
1102  }
1103  }
1104 
1105  // Calculate how many we removed, and update our total number of peers that
1106  // we want to protect based on uptime accordingly.
1107  assert(num_protected == initial_size - eviction_candidates.size());
1108  const size_t remaining_to_protect{total_protect_size - num_protected};
1110  remaining_to_protect);
1111 }
1112 
1113 [[nodiscard]] std::optional<NodeId>
1114 SelectNodeToEvict(std::vector<NodeEvictionCandidate> &&vEvictionCandidates) {
1115  // Protect connections with certain characteristics
1116 
1117  // Deterministically select 4 peers to protect by netgroup.
1118  // An attacker cannot predict which netgroups will be protected
1119  EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
1120  // Protect the 8 nodes with the lowest minimum ping time.
1121  // An attacker cannot manipulate this metric without physically moving nodes
1122  // closer to the target.
1123  EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
1124  // Protect 4 nodes that most recently sent us novel transactions accepted
1125  // into our mempool. An attacker cannot manipulate this metric without
1126  // performing useful work.
1127  EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
1128  // Protect 4 nodes that most recently sent us novel proofs accepted
1129  // into our proof pool. An attacker cannot manipulate this metric without
1130  // performing useful work.
1131  // TODO this filter must happen before the last tx time once avalanche is
1132  // enabled for pre-consensus.
1133  EraseLastKElements(vEvictionCandidates, CompareNodeProofTime, 4);
1134  // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
1135  EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
1136  [](const NodeEvictionCandidate &n) {
1137  return !n.m_relay_txs && n.fRelevantServices;
1138  });
1139 
1140  // Protect 4 nodes that most recently sent us novel blocks.
1141  // An attacker cannot manipulate this metric without performing useful work.
1142  EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
1143 
1144  // Protect up to 128 nodes that have the highest avalanche availability
1145  // score.
1146  EraseLastKElements(vEvictionCandidates, CompareNodeAvailabilityScore, 128,
1147  [](NodeEvictionCandidate const &n) {
1148  return n.availabilityScore > 0.;
1149  });
1150 
1151  // Protect some of the remaining eviction candidates by ratios of desirable
1152  // or disadvantaged characteristics.
1153  ProtectEvictionCandidatesByRatio(vEvictionCandidates);
1154 
1155  if (vEvictionCandidates.empty()) {
1156  return std::nullopt;
1157  }
1158 
1159  // If any remaining peers are preferred for eviction consider only them.
1160  // This happens after the other preferences since if a peer is really the
1161  // best by other criteria (esp relaying blocks)
1162  // then we probably don't want to evict it no matter what.
1163  if (std::any_of(
1164  vEvictionCandidates.begin(), vEvictionCandidates.end(),
1165  [](NodeEvictionCandidate const &n) { return n.prefer_evict; })) {
1166  vEvictionCandidates.erase(
1167  std::remove_if(
1168  vEvictionCandidates.begin(), vEvictionCandidates.end(),
1169  [](NodeEvictionCandidate const &n) { return !n.prefer_evict; }),
1170  vEvictionCandidates.end());
1171  }
1172 
1173  // Identify the network group with the most connections and youngest member.
1174  // (vEvictionCandidates is already sorted by reverse connect time)
1175  uint64_t naMostConnections;
1176  unsigned int nMostConnections = 0;
1177  std::chrono::seconds nMostConnectionsTime{0};
1178  std::map<uint64_t, std::vector<NodeEvictionCandidate>> mapNetGroupNodes;
1179  for (const NodeEvictionCandidate &node : vEvictionCandidates) {
1180  std::vector<NodeEvictionCandidate> &group =
1181  mapNetGroupNodes[node.nKeyedNetGroup];
1182  group.push_back(node);
1183  const auto grouptime{group[0].m_connected};
1184  size_t group_size = group.size();
1185  if (group_size > nMostConnections ||
1186  (group_size == nMostConnections &&
1187  grouptime > nMostConnectionsTime)) {
1188  nMostConnections = group_size;
1189  nMostConnectionsTime = grouptime;
1190  naMostConnections = node.nKeyedNetGroup;
1191  }
1192  }
1193 
1194  // Reduce to the network group with the most connections
1195  vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1196 
1197  // Disconnect from the network group with the most connections
1198  return vEvictionCandidates.front().id;
1199 }
1200 
1210  std::vector<NodeEvictionCandidate> vEvictionCandidates;
1211  {
1213  for (const CNode *node : m_nodes) {
1214  if (node->HasPermission(NetPermissionFlags::NoBan)) {
1215  continue;
1216  }
1217  if (!node->IsInboundConn()) {
1218  continue;
1219  }
1220  if (node->fDisconnect) {
1221  continue;
1222  }
1223 
1224  NodeEvictionCandidate candidate = {
1225  node->GetId(),
1226  node->m_connected,
1227  node->m_min_ping_time,
1228  node->m_last_block_time,
1229  node->m_last_proof_time,
1230  node->m_last_tx_time,
1231  node->m_has_all_wanted_services,
1232  node->m_relays_txs.load(),
1233  node->m_bloom_filter_loaded.load(),
1234  node->nKeyedNetGroup,
1235  node->m_prefer_evict,
1236  node->addr.IsLocal(),
1237  node->ConnectedThroughNetwork(),
1238  node->m_avalanche_enabled
1239  ? node->getAvailabilityScore()
1240  : -std::numeric_limits<double>::infinity()};
1241  vEvictionCandidates.push_back(candidate);
1242  }
1243  }
1244  const std::optional<NodeId> node_id_to_evict =
1245  SelectNodeToEvict(std::move(vEvictionCandidates));
1246  if (!node_id_to_evict) {
1247  return false;
1248  }
1250  for (CNode *pnode : m_nodes) {
1251  if (pnode->GetId() == *node_id_to_evict) {
1252  LogPrint(
1253  BCLog::NET,
1254  "selected %s connection for eviction peer=%d; disconnecting\n",
1255  pnode->ConnectionTypeAsString(), pnode->GetId());
1256  pnode->fDisconnect = true;
1257  return true;
1258  }
1259  }
1260  return false;
1261 }
1262 
1263 void CConnman::AcceptConnection(const ListenSocket &hListenSocket) {
1264  struct sockaddr_storage sockaddr;
1265  socklen_t len = sizeof(sockaddr);
1266  SOCKET hSocket =
1267  accept(hListenSocket.socket, (struct sockaddr *)&sockaddr, &len);
1268  CAddress addr;
1269 
1270  if (hSocket == INVALID_SOCKET) {
1271  const int nErr = WSAGetLastError();
1272  if (nErr != WSAEWOULDBLOCK) {
1273  LogPrintf("socket error accept failed: %s\n",
1274  NetworkErrorString(nErr));
1275  }
1276  return;
1277  }
1278 
1279  if (!addr.SetSockAddr((const struct sockaddr *)&sockaddr)) {
1280  LogPrintf("Warning: Unknown socket family\n");
1281  }
1282 
1283  const CAddress addr_bind = GetBindAddress(hSocket);
1284 
1285  NetPermissionFlags permissionFlags = NetPermissionFlags::None;
1286  hListenSocket.AddSocketPermissionFlags(permissionFlags);
1287 
1288  CreateNodeFromAcceptedSocket(hSocket, permissionFlags, addr_bind, addr);
1289 }
1290 
1292  NetPermissionFlags permissionFlags,
1293  const CAddress &addr_bind,
1294  const CAddress &addr) {
1295  int nInbound = 0;
1296  int nMaxInbound = nMaxConnections - m_max_outbound;
1297 
1298  AddWhitelistPermissionFlags(permissionFlags, addr);
1299  if (NetPermissions::HasFlag(permissionFlags,
1301  NetPermissions::ClearFlag(permissionFlags,
1303  if (gArgs.GetBoolArg("-whitelistforcerelay",
1305  NetPermissions::AddFlag(permissionFlags,
1307  }
1308  if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) {
1310  }
1313  }
1314 
1315  {
1317  for (const CNode *pnode : m_nodes) {
1318  if (pnode->IsInboundConn()) {
1319  nInbound++;
1320  }
1321  }
1322  }
1323 
1324  if (!fNetworkActive) {
1326  "connection from %s dropped: not accepting new connections\n",
1327  addr.ToString());
1328  CloseSocket(hSocket);
1329  return;
1330  }
1331 
1332  if (!IsSelectableSocket(hSocket)) {
1333  LogPrintf("connection from %s dropped: non-selectable socket\n",
1334  addr.ToString());
1335  CloseSocket(hSocket);
1336  return;
1337  }
1338 
1339  // According to the internet TCP_NODELAY is not carried into accepted
1340  // sockets on all platforms. Set it again here just to be sure.
1341  SetSocketNoDelay(hSocket);
1342 
1343  // Don't accept connections from banned peers.
1344  bool banned = m_banman && m_banman->IsBanned(addr);
1345  if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) &&
1346  banned) {
1347  LogPrint(BCLog::NET, "connection from %s dropped (banned)\n",
1348  addr.ToString());
1349  CloseSocket(hSocket);
1350  return;
1351  }
1352 
1353  // Only accept connections from discouraged peers if our inbound slots
1354  // aren't (almost) full.
1355  bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1356  if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) &&
1357  nInbound + 1 >= nMaxInbound && discouraged) {
1358  LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n",
1359  addr.ToString());
1360  CloseSocket(hSocket);
1361  return;
1362  }
1363 
1364  if (nInbound >= nMaxInbound) {
1365  if (!AttemptToEvictConnection()) {
1366  // No connection to evict, disconnect the new connection
1367  LogPrint(BCLog::NET, "failed to find an eviction candidate - "
1368  "connection dropped (full)\n");
1369  CloseSocket(hSocket);
1370  return;
1371  }
1372  }
1373 
1374  NodeId id = GetNewNodeId();
1376  .Write(id)
1377  .Finalize();
1378  uint64_t extra_entropy =
1380  .Write(id)
1381  .Finalize();
1382 
1383  ServiceFlags nodeServices = nLocalServices;
1384  if (NetPermissions::HasFlag(permissionFlags,
1386  nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
1387  }
1388 
1389  const bool inbound_onion =
1390  std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) !=
1391  m_onion_binds.end();
1392  CNode *pnode = new CNode(id, hSocket, addr, CalculateKeyedNetGroup(addr),
1393  nonce, extra_entropy, addr_bind, "",
1394  ConnectionType::INBOUND, inbound_onion);
1395  pnode->AddRef();
1396  pnode->m_permissionFlags = permissionFlags;
1397  pnode->m_prefer_evict = discouraged;
1398  for (auto interface : m_msgproc) {
1399  interface->InitializeNode(*config, *pnode, nodeServices);
1400  }
1401 
1402  LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1403 
1404  {
1406  m_nodes.push_back(pnode);
1407  }
1408 
1409  // We received a new connection, harvest entropy from the time (and our peer
1410  // count)
1411  RandAddEvent(uint32_t(id));
1412 }
1413 
1414 bool CConnman::AddConnection(const std::string &address,
1415  ConnectionType conn_type) {
1416  std::optional<int> max_connections;
1417  switch (conn_type) {
1420  return false;
1422  max_connections = m_max_outbound_full_relay;
1423  break;
1425  max_connections = m_max_outbound_block_relay;
1426  break;
1427  // no limit for ADDR_FETCH because -seednode has no limit either
1429  break;
1430  // no limit for FEELER connections since they're short-lived
1432  break;
1434  max_connections = m_max_avalanche_outbound;
1435  break;
1436  } // no default case, so the compiler can warn about missing cases
1437 
1438  // Count existing connections
1439  int existing_connections =
1441  return std::count_if(
1442  m_nodes.begin(), m_nodes.end(), [conn_type](CNode *node) {
1443  return node->m_conn_type == conn_type;
1444  }););
1445 
1446  // Max connections of specified type already exist
1447  if (max_connections != std::nullopt &&
1448  existing_connections >= max_connections) {
1449  return false;
1450  }
1451 
1452  // Max total outbound connections already exist
1453  CSemaphoreGrant grant(*semOutbound, true);
1454  if (!grant) {
1455  return false;
1456  }
1457 
1458  OpenNetworkConnection(CAddress(), false, &grant, address.c_str(),
1459  conn_type);
1460  return true;
1461 }
1462 
1464  {
1466 
1467  if (!fNetworkActive) {
1468  // Disconnect any connected nodes
1469  for (CNode *pnode : m_nodes) {
1470  if (!pnode->fDisconnect) {
1472  "Network not active, dropping peer=%d\n",
1473  pnode->GetId());
1474  pnode->fDisconnect = true;
1475  }
1476  }
1477  }
1478 
1479  // Disconnect unused nodes
1480  std::vector<CNode *> nodes_copy = m_nodes;
1481  for (CNode *pnode : nodes_copy) {
1482  if (pnode->fDisconnect) {
1483  // remove from m_nodes
1484  m_nodes.erase(remove(m_nodes.begin(), m_nodes.end(), pnode),
1485  m_nodes.end());
1486 
1487  // release outbound grant (if any)
1488  pnode->grantOutbound.Release();
1489 
1490  // close socket and cleanup
1491  pnode->CloseSocketDisconnect();
1492 
1493  // hold in disconnected pool until all refs are released
1494  pnode->Release();
1495  m_nodes_disconnected.push_back(pnode);
1496  }
1497  }
1498  }
1499  {
1500  // Delete disconnected nodes
1501  std::list<CNode *> nodes_disconnected_copy = m_nodes_disconnected;
1502  for (CNode *pnode : nodes_disconnected_copy) {
1503  // Destroy the object only after other threads have stopped using
1504  // it.
1505  if (pnode->GetRefCount() <= 0) {
1506  m_nodes_disconnected.remove(pnode);
1507  DeleteNode(pnode);
1508  }
1509  }
1510  }
1511 }
1512 
1514  size_t nodes_size;
1515  {
1517  nodes_size = m_nodes.size();
1518  }
1519  if (nodes_size != nPrevNodeCount) {
1520  nPrevNodeCount = nodes_size;
1521  if (m_client_interface) {
1522  m_client_interface->NotifyNumConnectionsChanged(nodes_size);
1523  }
1524  }
1525 }
1526 
1528  std::chrono::seconds now) const {
1529  return node.m_connected + m_peer_connect_timeout < now;
1530 }
1531 
1533  // Tests that see disconnects after using mocktime can start nodes with a
1534  // large timeout. For example, -peertimeout=999999999.
1535  const auto now{GetTime<std::chrono::seconds>()};
1536  const auto last_send{node.m_last_send.load()};
1537  const auto last_recv{node.m_last_recv.load()};
1538 
1539  if (!ShouldRunInactivityChecks(node, now)) {
1540  return false;
1541  }
1542 
1543  if (last_recv.count() == 0 || last_send.count() == 0) {
1545  "socket no message in first %i seconds, %d %d peer=%d\n",
1546  count_seconds(m_peer_connect_timeout), last_recv.count() != 0,
1547  last_send.count() != 0, node.GetId());
1548  return true;
1549  }
1550 
1551  if (now > last_send + TIMEOUT_INTERVAL) {
1552  LogPrint(BCLog::NET, "socket sending timeout: %is peer=%d\n",
1553  count_seconds(now - last_send), node.GetId());
1554  return true;
1555  }
1556 
1557  if (now > last_recv + TIMEOUT_INTERVAL) {
1558  LogPrint(BCLog::NET, "socket receive timeout: %is peer=%d\n",
1559  count_seconds(now - last_recv), node.GetId());
1560  return true;
1561  }
1562 
1563  if (!node.fSuccessfullyConnected) {
1564  LogPrint(BCLog::NET, "version handshake timeout peer=%d\n",
1565  node.GetId());
1566  return true;
1567  }
1568 
1569  return false;
1570 }
1571 
1572 bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set,
1573  std::set<SOCKET> &send_set,
1574  std::set<SOCKET> &error_set) {
1575  for (const ListenSocket &hListenSocket : vhListenSocket) {
1576  recv_set.insert(hListenSocket.socket);
1577  }
1578 
1579  {
1581  for (CNode *pnode : m_nodes) {
1582  // Implement the following logic:
1583  // * If there is data to send, select() for sending data. As this
1584  // only happens when optimistic write failed, we choose to first
1585  // drain the write buffer in this case before receiving more. This
1586  // avoids needlessly queueing received data, if the remote peer is
1587  // not themselves receiving data. This means properly utilizing
1588  // TCP flow control signalling.
1589  // * Otherwise, if there is space left in the receive buffer,
1590  // select() for receiving data.
1591  // * Hand off all complete messages to the processor, to be handled
1592  // without blocking here.
1593 
1594  bool select_recv = !pnode->fPauseRecv;
1595  bool select_send;
1596  {
1597  LOCK(pnode->cs_vSend);
1598  select_send = !pnode->vSendMsg.empty();
1599  }
1600 
1601  LOCK(pnode->cs_hSocket);
1602  if (pnode->hSocket == INVALID_SOCKET) {
1603  continue;
1604  }
1605 
1606  error_set.insert(pnode->hSocket);
1607  if (select_send) {
1608  send_set.insert(pnode->hSocket);
1609  continue;
1610  }
1611  if (select_recv) {
1612  recv_set.insert(pnode->hSocket);
1613  }
1614  }
1615  }
1616 
1617  return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1618 }
1619 
1620 #ifdef USE_POLL
1621 void CConnman::SocketEvents(std::set<SOCKET> &recv_set,
1622  std::set<SOCKET> &send_set,
1623  std::set<SOCKET> &error_set) {
1624  std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1625  if (!GenerateSelectSet(recv_select_set, send_select_set,
1626  error_select_set)) {
1628  std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1629  return;
1630  }
1631 
1632  std::unordered_map<SOCKET, struct pollfd> pollfds;
1633  for (SOCKET socket_id : recv_select_set) {
1634  pollfds[socket_id].fd = socket_id;
1635  pollfds[socket_id].events |= POLLIN;
1636  }
1637 
1638  for (SOCKET socket_id : send_select_set) {
1639  pollfds[socket_id].fd = socket_id;
1640  pollfds[socket_id].events |= POLLOUT;
1641  }
1642 
1643  for (SOCKET socket_id : error_select_set) {
1644  pollfds[socket_id].fd = socket_id;
1645  // These flags are ignored, but we set them for clarity
1646  pollfds[socket_id].events |= POLLERR | POLLHUP;
1647  }
1648 
1649  std::vector<struct pollfd> vpollfds;
1650  vpollfds.reserve(pollfds.size());
1651  for (auto it : pollfds) {
1652  vpollfds.push_back(std::move(it.second));
1653  }
1654 
1655  if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) <
1656  0) {
1657  return;
1658  }
1659 
1660  if (interruptNet) {
1661  return;
1662  }
1663 
1664  for (struct pollfd pollfd_entry : vpollfds) {
1665  if (pollfd_entry.revents & POLLIN) {
1666  recv_set.insert(pollfd_entry.fd);
1667  }
1668  if (pollfd_entry.revents & POLLOUT) {
1669  send_set.insert(pollfd_entry.fd);
1670  }
1671  if (pollfd_entry.revents & (POLLERR | POLLHUP)) {
1672  error_set.insert(pollfd_entry.fd);
1673  }
1674  }
1675 }
1676 #else
1677 void CConnman::SocketEvents(std::set<SOCKET> &recv_set,
1678  std::set<SOCKET> &send_set,
1679  std::set<SOCKET> &error_set) {
1680  std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1681  if (!GenerateSelectSet(recv_select_set, send_select_set,
1682  error_select_set)) {
1684  std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1685  return;
1686  }
1687 
1688  //
1689  // Find which sockets have data to receive
1690  //
1691  struct timeval timeout;
1692  timeout.tv_sec = 0;
1693  // frequency to poll pnode->vSend
1694  timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000;
1695 
1696  fd_set fdsetRecv;
1697  fd_set fdsetSend;
1698  fd_set fdsetError;
1699  FD_ZERO(&fdsetRecv);
1700  FD_ZERO(&fdsetSend);
1701  FD_ZERO(&fdsetError);
1702  SOCKET hSocketMax = 0;
1703 
1704  for (SOCKET hSocket : recv_select_set) {
1705  FD_SET(hSocket, &fdsetRecv);
1706  hSocketMax = std::max(hSocketMax, hSocket);
1707  }
1708 
1709  for (SOCKET hSocket : send_select_set) {
1710  FD_SET(hSocket, &fdsetSend);
1711  hSocketMax = std::max(hSocketMax, hSocket);
1712  }
1713 
1714  for (SOCKET hSocket : error_select_set) {
1715  FD_SET(hSocket, &fdsetError);
1716  hSocketMax = std::max(hSocketMax, hSocket);
1717  }
1718 
1719  int nSelect =
1720  select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1721 
1722  if (interruptNet) {
1723  return;
1724  }
1725 
1726  if (nSelect == SOCKET_ERROR) {
1727  int nErr = WSAGetLastError();
1728  LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1729  for (unsigned int i = 0; i <= hSocketMax; i++) {
1730  FD_SET(i, &fdsetRecv);
1731  }
1732  FD_ZERO(&fdsetSend);
1733  FD_ZERO(&fdsetError);
1734  if (!interruptNet.sleep_for(
1735  std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS))) {
1736  return;
1737  }
1738  }
1739 
1740  for (SOCKET hSocket : recv_select_set) {
1741  if (FD_ISSET(hSocket, &fdsetRecv)) {
1742  recv_set.insert(hSocket);
1743  }
1744  }
1745 
1746  for (SOCKET hSocket : send_select_set) {
1747  if (FD_ISSET(hSocket, &fdsetSend)) {
1748  send_set.insert(hSocket);
1749  }
1750  }
1751 
1752  for (SOCKET hSocket : error_select_set) {
1753  if (FD_ISSET(hSocket, &fdsetError)) {
1754  error_set.insert(hSocket);
1755  }
1756  }
1757 }
1758 #endif
1759 
1761  std::set<SOCKET> recv_set, send_set, error_set;
1762  SocketEvents(recv_set, send_set, error_set);
1763 
1764  if (interruptNet) {
1765  return;
1766  }
1767 
1768  //
1769  // Accept new connections
1770  //
1771  for (const ListenSocket &hListenSocket : vhListenSocket) {
1772  if (hListenSocket.socket != INVALID_SOCKET &&
1773  recv_set.count(hListenSocket.socket) > 0) {
1774  AcceptConnection(hListenSocket);
1775  }
1776  }
1777 
1778  //
1779  // Service each socket
1780  //
1781  std::vector<CNode *> nodes_copy;
1782  {
1784  nodes_copy = m_nodes;
1785  for (CNode *pnode : nodes_copy) {
1786  pnode->AddRef();
1787  }
1788  }
1789  for (CNode *pnode : nodes_copy) {
1790  if (interruptNet) {
1791  return;
1792  }
1793 
1794  //
1795  // Receive
1796  //
1797  bool recvSet = false;
1798  bool sendSet = false;
1799  bool errorSet = false;
1800  {
1801  LOCK(pnode->cs_hSocket);
1802  if (pnode->hSocket == INVALID_SOCKET) {
1803  continue;
1804  }
1805  recvSet = recv_set.count(pnode->hSocket) > 0;
1806  sendSet = send_set.count(pnode->hSocket) > 0;
1807  errorSet = error_set.count(pnode->hSocket) > 0;
1808  }
1809  if (recvSet || errorSet) {
1810  // typical socket buffer is 8K-64K
1811  uint8_t pchBuf[0x10000];
1812  int32_t nBytes = 0;
1813  {
1814  LOCK(pnode->cs_hSocket);
1815  if (pnode->hSocket == INVALID_SOCKET) {
1816  continue;
1817  }
1818  nBytes = recv(pnode->hSocket, (char *)pchBuf, sizeof(pchBuf),
1819  MSG_DONTWAIT);
1820  }
1821  if (nBytes > 0) {
1822  bool notify = false;
1823  if (!pnode->ReceiveMsgBytes(*config, {pchBuf, (size_t)nBytes},
1824  notify)) {
1825  pnode->CloseSocketDisconnect();
1826  }
1827  RecordBytesRecv(nBytes);
1828  if (notify) {
1829  size_t nSizeAdded = 0;
1830  auto it(pnode->vRecvMsg.begin());
1831  for (; it != pnode->vRecvMsg.end(); ++it) {
1832  // vRecvMsg contains only completed CNetMessage
1833  // the single possible partially deserialized message
1834  // are held by TransportDeserializer
1835  nSizeAdded += it->m_raw_message_size;
1836  }
1837  {
1838  LOCK(pnode->cs_vProcessMsg);
1839  pnode->vProcessMsg.splice(pnode->vProcessMsg.end(),
1840  pnode->vRecvMsg,
1841  pnode->vRecvMsg.begin(), it);
1842  pnode->nProcessQueueSize += nSizeAdded;
1843  pnode->fPauseRecv =
1844  pnode->nProcessQueueSize > nReceiveFloodSize;
1845  }
1847  }
1848  } else if (nBytes == 0) {
1849  // socket closed gracefully
1850  if (!pnode->fDisconnect) {
1851  LogPrint(BCLog::NET, "socket closed for peer=%d\n",
1852  pnode->GetId());
1853  }
1854  pnode->CloseSocketDisconnect();
1855  } else if (nBytes < 0) {
1856  // error
1857  int nErr = WSAGetLastError();
1858  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE &&
1859  nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
1860  if (!pnode->fDisconnect) {
1862  "socket recv error for peer=%d: %s\n",
1863  pnode->GetId(), NetworkErrorString(nErr));
1864  }
1865  pnode->CloseSocketDisconnect();
1866  }
1867  }
1868  }
1869 
1870  if (sendSet) {
1871  // Send data
1872  size_t bytes_sent =
1873  WITH_LOCK(pnode->cs_vSend, return SocketSendData(*pnode));
1874  if (bytes_sent) {
1875  RecordBytesSent(bytes_sent);
1876  }
1877  }
1878 
1879  if (InactivityCheck(*pnode)) {
1880  pnode->fDisconnect = true;
1881  }
1882  }
1883  {
1885  for (CNode *pnode : nodes_copy) {
1886  pnode->Release();
1887  }
1888  }
1889 }
1890 
1892  while (!interruptNet) {
1893  DisconnectNodes();
1895  SocketHandler();
1896  }
1897 }
1898 
1900  {
1901  LOCK(mutexMsgProc);
1902  fMsgProcWake = true;
1903  }
1904  condMsgProc.notify_one();
1905 }
1906 
1908  FastRandomContext rng;
1909  std::vector<std::string> seeds =
1911  // Number of seeds left before testing if we have enough connections
1912  int seeds_right_now = 0;
1913  int found = 0;
1914 
1915  if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
1916  // When -forcednsseed is provided, query all.
1917  seeds_right_now = seeds.size();
1918  } else if (addrman.size() == 0) {
1919  // If we have no known peers, query all.
1920  // This will occur on the first run, or if peers.dat has been
1921  // deleted.
1922  seeds_right_now = seeds.size();
1923  }
1924 
1925  // goal: only query DNS seed if address need is acute
1926  // * If we have a reasonable number of peers in addrman, spend
1927  // some time trying them first. This improves user privacy by
1928  // creating fewer identifying DNS requests, reduces trust by
1929  // giving seeds less influence on the network topology, and
1930  // reduces traffic to the seeds.
1931  // * When querying DNS seeds query a few at once, this ensures
1932  // that we don't give DNS seeds the ability to eclipse nodes
1933  // that query them.
1934  // * If we continue having problems, eventually query all the
1935  // DNS seeds, and if that fails too, also try the fixed seeds.
1936  // (done in ThreadOpenConnections)
1937  const std::chrono::seconds seeds_wait_time =
1941 
1942  for (const std::string &seed : seeds) {
1943  if (seeds_right_now == 0) {
1944  seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1945 
1946  if (addrman.size() > 0) {
1947  LogPrintf("Waiting %d seconds before querying DNS seeds.\n",
1948  seeds_wait_time.count());
1949  std::chrono::seconds to_wait = seeds_wait_time;
1950  while (to_wait.count() > 0) {
1951  // if sleeping for the MANY_PEERS interval, wake up
1952  // early to see if we have enough peers and can stop
1953  // this thread entirely freeing up its resources
1954  std::chrono::seconds w =
1955  std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
1956  if (!interruptNet.sleep_for(w)) {
1957  return;
1958  }
1959  to_wait -= w;
1960 
1961  int nRelevant = 0;
1962  {
1964  for (const CNode *pnode : m_nodes) {
1965  if (pnode->fSuccessfullyConnected &&
1966  pnode->IsFullOutboundConn()) {
1967  ++nRelevant;
1968  }
1969  }
1970  }
1971  if (nRelevant >= 2) {
1972  if (found > 0) {
1973  LogPrintf("%d addresses found from DNS seeds\n",
1974  found);
1975  LogPrintf(
1976  "P2P peers available. Finished DNS seeding.\n");
1977  } else {
1978  LogPrintf(
1979  "P2P peers available. Skipped DNS seeding.\n");
1980  }
1981  return;
1982  }
1983  }
1984  }
1985  }
1986 
1987  if (interruptNet) {
1988  return;
1989  }
1990 
1991  // hold off on querying seeds if P2P network deactivated
1992  if (!fNetworkActive) {
1993  LogPrintf("Waiting for network to be reactivated before querying "
1994  "DNS seeds.\n");
1995  do {
1996  if (!interruptNet.sleep_for(std::chrono::seconds{1})) {
1997  return;
1998  }
1999  } while (!fNetworkActive);
2000  }
2001 
2002  LogPrintf("Loading addresses from DNS seed %s\n", seed);
2003  if (HaveNameProxy()) {
2004  AddAddrFetch(seed);
2005  } else {
2006  std::vector<CNetAddr> vIPs;
2007  std::vector<CAddress> vAdd;
2008  ServiceFlags requiredServiceBits =
2010  std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
2011  CNetAddr resolveSource;
2012  if (!resolveSource.SetInternal(host)) {
2013  continue;
2014  }
2015 
2016  // Limits number of IPs learned from a DNS seed
2017  unsigned int nMaxIPs = 256;
2018  if (LookupHost(host, vIPs, nMaxIPs, true)) {
2019  for (const CNetAddr &ip : vIPs) {
2020  CAddress addr = CAddress(
2022  requiredServiceBits);
2023  // Use a random age between 3 and 7 days old.
2024  addr.nTime = rng.rand_uniform_delay(
2025  Now<NodeSeconds>() - 3 * 24h, -4 * 24h);
2026  vAdd.push_back(addr);
2027  found++;
2028  }
2029  addrman.Add(vAdd, resolveSource);
2030  } else {
2031  // We now avoid directly using results from DNS Seeds which do
2032  // not support service bit filtering, instead using them as a
2033  // addrfetch to get nodes with our desired service bits.
2034  AddAddrFetch(seed);
2035  }
2036  }
2037  --seeds_right_now;
2038  }
2039  LogPrintf("%d addresses found from DNS seeds\n", found);
2040 }
2041 
2043  int64_t nStart = GetTimeMillis();
2044 
2046 
2047  LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
2048  addrman.size(), GetTimeMillis() - nStart);
2049 }
2050 
2052  std::string strDest;
2053  {
2055  if (m_addr_fetches.empty()) {
2056  return;
2057  }
2058  strDest = m_addr_fetches.front();
2059  m_addr_fetches.pop_front();
2060  }
2061  CAddress addr;
2062  CSemaphoreGrant grant(*semOutbound, true);
2063  if (grant) {
2064  OpenNetworkConnection(addr, false, &grant, strDest.c_str(),
2066  }
2067 }
2068 
2071 }
2072 
2075  LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n",
2076  flag ? "true" : "false");
2077 }
2078 
2079 // Return the number of peers we have over our outbound connection limit.
2080 // Exclude peers that are marked for disconnect, or are going to be disconnected
2081 // soon (eg ADDR_FETCH and FEELER).
2082 // Also exclude peers that haven't finished initial connection handshake yet (so
2083 // that we don't decide we're over our desired connection limit, and then evict
2084 // some peer that has finished the handshake).
2086  int full_outbound_peers = 0;
2087  {
2089  for (const CNode *pnode : m_nodes) {
2090  if (pnode->fSuccessfullyConnected && !pnode->fDisconnect &&
2091  pnode->IsFullOutboundConn()) {
2092  ++full_outbound_peers;
2093  }
2094  }
2095  }
2096  return std::max(full_outbound_peers - m_max_outbound_full_relay -
2098  0);
2099 }
2100 
2102  int block_relay_peers = 0;
2103  {
2105  for (const CNode *pnode : m_nodes) {
2106  if (pnode->fSuccessfullyConnected && !pnode->fDisconnect &&
2107  pnode->IsBlockOnlyConn()) {
2108  ++block_relay_peers;
2109  }
2110  }
2111  }
2112  return std::max(block_relay_peers - m_max_outbound_block_relay, 0);
2113 }
2114 
2116  const std::vector<std::string> connect,
2117  std::function<void(const CAddress &, ConnectionType)> mockOpenConnection) {
2118  // Connect to specific addresses
2119  if (!connect.empty()) {
2120  for (int64_t nLoop = 0;; nLoop++) {
2121  ProcessAddrFetch();
2122  for (const std::string &strAddr : connect) {
2123  CAddress addr(CService(), NODE_NONE);
2124  OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(),
2126  for (int i = 0; i < 10 && i < nLoop; i++) {
2127  if (!interruptNet.sleep_for(
2128  std::chrono::milliseconds(500))) {
2129  return;
2130  }
2131  }
2132  }
2133  if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
2134  return;
2135  }
2136  }
2137  }
2138 
2139  // Initiate network connections
2140  auto start = GetTime<std::chrono::microseconds>();
2141 
2142  // Minimum time before next feeler connection (in microseconds).
2143  auto next_feeler = GetExponentialRand(start, FEELER_INTERVAL);
2144  auto next_extra_block_relay =
2146  const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
2147  bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
2148 
2149  if (!add_fixed_seeds) {
2150  LogPrintf("Fixed seeds are disabled\n");
2151  }
2152 
2153  while (!interruptNet) {
2154  ProcessAddrFetch();
2155 
2156  // No need to sleep the thread if we are mocking the network connection
2157  if (!mockOpenConnection &&
2158  !interruptNet.sleep_for(std::chrono::milliseconds(500))) {
2159  return;
2160  }
2161 
2162  CSemaphoreGrant grant(*semOutbound);
2163  if (interruptNet) {
2164  return;
2165  }
2166 
2167  if (add_fixed_seeds && addrman.size() == 0) {
2168  // When the node starts with an empty peers.dat, there are a few
2169  // other sources of peers before we fallback on to fixed seeds:
2170  // -dnsseed, -seednode, -addnode If none of those are available, we
2171  // fallback on to fixed seeds immediately, else we allow 60 seconds
2172  // for any of those sources to populate addrman.
2173  bool add_fixed_seeds_now = false;
2174  // It is cheapest to check if enough time has passed first.
2175  if (GetTime<std::chrono::seconds>() >
2176  start + std::chrono::minutes{1}) {
2177  add_fixed_seeds_now = true;
2178  LogPrintf("Adding fixed seeds as 60 seconds have passed and "
2179  "addrman is empty\n");
2180  }
2181 
2182  // Checking !dnsseed is cheaper before locking 2 mutexes.
2183  if (!add_fixed_seeds_now && !dnsseed) {
2185  if (m_addr_fetches.empty() && m_added_nodes.empty()) {
2186  add_fixed_seeds_now = true;
2187  LogPrintf(
2188  "Adding fixed seeds as -dnsseed=0, -addnode is not "
2189  "provided and all -seednode(s) attempted\n");
2190  }
2191  }
2192 
2193  if (add_fixed_seeds_now) {
2194  CNetAddr local;
2195  local.SetInternal("fixedseeds");
2197  local);
2198  add_fixed_seeds = false;
2199  }
2200  }
2201 
2202  //
2203  // Choose an address to connect to based on most recently seen
2204  //
2205  CAddress addrConnect;
2206 
2207  // Only connect out to one peer per network group (/16 for IPv4).
2208  int nOutboundFullRelay = 0;
2209  int nOutboundBlockRelay = 0;
2210  int nOutboundAvalanche = 0;
2211  std::set<std::vector<uint8_t>> setConnected;
2212 
2213  {
2215  for (const CNode *pnode : m_nodes) {
2216  if (pnode->IsAvalancheOutboundConnection()) {
2217  nOutboundAvalanche++;
2218  } else if (pnode->IsFullOutboundConn()) {
2219  nOutboundFullRelay++;
2220  } else if (pnode->IsBlockOnlyConn()) {
2221  nOutboundBlockRelay++;
2222  }
2223 
2224  // Netgroups for inbound and manual peers are not excluded
2225  // because our goal here is to not use multiple of our
2226  // limited outbound slots on a single netgroup but inbound
2227  // and manual peers do not use our outbound slots. Inbound
2228  // peers also have the added issue that they could be attacker
2229  // controlled and could be used to prevent us from connecting
2230  // to particular hosts if we used them here.
2231  switch (pnode->m_conn_type) {
2234  break;
2240  setConnected.insert(
2241  pnode->addr.GetGroup(addrman.GetAsmap()));
2242  } // no default case, so the compiler can warn about missing
2243  // cases
2244  }
2245  }
2246 
2248  auto now = GetTime<std::chrono::microseconds>();
2249  bool anchor = false;
2250  bool fFeeler = false;
2251 
2252  // Determine what type of connection to open. Opening
2253  // BLOCK_RELAY connections to addresses from anchors.dat gets the
2254  // highest priority. Then we open AVALANCHE_OUTBOUND connection until we
2255  // hit our avalanche outbound peer limit, which is 0 if avalanche is not
2256  // enabled. We fallback after 50 retries to OUTBOUND_FULL_RELAY if the
2257  // peer is not avalanche capable until we meet our full-relay capacity.
2258  // Then we open BLOCK_RELAY connection until we hit our block-relay-only
2259  // peer limit.
2260  // GetTryNewOutboundPeer() gets set when a stale tip is detected, so we
2261  // try opening an additional OUTBOUND_FULL_RELAY connection. If none of
2262  // these conditions are met, check to see if it's time to try an extra
2263  // block-relay-only peer (to confirm our tip is current, see below) or
2264  // the next_feeler timer to decide if we should open a FEELER.
2265 
2266  if (!m_anchors.empty() &&
2267  (nOutboundBlockRelay < m_max_outbound_block_relay)) {
2268  conn_type = ConnectionType::BLOCK_RELAY;
2269  anchor = true;
2270  } else if (g_avalanche &&
2271  (nOutboundAvalanche < m_max_avalanche_outbound)) {
2273  } else if (nOutboundFullRelay < m_max_outbound_full_relay) {
2274  // OUTBOUND_FULL_RELAY
2275  } else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
2276  conn_type = ConnectionType::BLOCK_RELAY;
2277  } else if (GetTryNewOutboundPeer()) {
2278  // OUTBOUND_FULL_RELAY
2279  } else if (now > next_extra_block_relay &&
2281  // Periodically connect to a peer (using regular outbound selection
2282  // methodology from addrman) and stay connected long enough to sync
2283  // headers, but not much else.
2284  //
2285  // Then disconnect the peer, if we haven't learned anything new.
2286  //
2287  // The idea is to make eclipse attacks very difficult to pull off,
2288  // because every few minutes we're finding a new peer to learn
2289  // headers from.
2290  //
2291  // This is similar to the logic for trying extra outbound
2292  // (full-relay) peers, except:
2293  // - we do this all the time on an exponential timer, rather than
2294  // just when our tip is stale
2295  // - we potentially disconnect our next-youngest block-relay-only
2296  // peer, if our newest block-relay-only peer delivers a block more
2297  // recently.
2298  // See the eviction logic in net_processing.cpp.
2299  //
2300  // Because we can promote these connections to block-relay-only
2301  // connections, they do not get their own ConnectionType enum
2302  // (similar to how we deal with extra outbound peers).
2303  next_extra_block_relay =
2305  conn_type = ConnectionType::BLOCK_RELAY;
2306  } else if (now > next_feeler) {
2307  next_feeler = GetExponentialRand(now, FEELER_INTERVAL);
2308  conn_type = ConnectionType::FEELER;
2309  fFeeler = true;
2310  } else {
2311  // skip to next iteration of while loop
2312  continue;
2313  }
2314 
2316 
2317  const auto nANow{AdjustedTime()};
2318  int nTries = 0;
2319  while (!interruptNet) {
2320  if (anchor && !m_anchors.empty()) {
2321  const CAddress addr = m_anchors.back();
2322  m_anchors.pop_back();
2323  if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) ||
2325  setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2326  continue;
2327  }
2328  addrConnect = addr;
2330  "Trying to make an anchor connection to %s\n",
2331  addrConnect.ToString());
2332  break;
2333  }
2334  // If we didn't find an appropriate destination after trying 100
2335  // addresses fetched from addrman, stop this loop, and let the outer
2336  // loop run again (which sleeps, adds seed nodes, recalculates
2337  // already-connected network ranges, ...) before trying new addrman
2338  // addresses.
2339  nTries++;
2340  if (nTries > 100) {
2341  break;
2342  }
2343 
2344  CAddress addr;
2345  NodeSeconds addr_last_try{0s};
2346 
2347  if (fFeeler) {
2348  // First, try to get a tried table collision address. This
2349  // returns an empty (invalid) address if there are no collisions
2350  // to try.
2351  std::tie(addr, addr_last_try) = addrman.SelectTriedCollision();
2352 
2353  if (!addr.IsValid()) {
2354  // No tried table collisions. Select a new table address
2355  // for our feeler.
2356  std::tie(addr, addr_last_try) = addrman.Select(true);
2357  } else if (AlreadyConnectedToAddress(addr)) {
2358  // If test-before-evict logic would have us connect to a
2359  // peer that we're already connected to, just mark that
2360  // address as Good(). We won't be able to initiate the
2361  // connection anyway, so this avoids inadvertently evicting
2362  // a currently-connected peer.
2363  addrman.Good(addr);
2364  // Select a new table address for our feeler instead.
2365  std::tie(addr, addr_last_try) = addrman.Select(true);
2366  }
2367  } else {
2368  // Not a feeler
2369  std::tie(addr, addr_last_try) = addrman.Select();
2370  }
2371 
2372  // Require outbound connections, other than feelers and avalanche,
2373  // to be to distinct network groups
2374  if (!fFeeler && conn_type != ConnectionType::AVALANCHE_OUTBOUND &&
2375  setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2376  break;
2377  }
2378 
2379  // if we selected an invalid or local address, restart
2380  if (!addr.IsValid() || IsLocal(addr)) {
2381  break;
2382  }
2383 
2384  if (!IsReachable(addr)) {
2385  continue;
2386  }
2387 
2388  // only consider very recently tried nodes after 30 failed attempts
2389  if (nANow - addr_last_try < 10min && nTries < 30) {
2390  continue;
2391  }
2392 
2393  // for non-feelers, require all the services we'll want,
2394  // for feelers, only require they be a full node (only because most
2395  // SPV clients don't have a good address DB available)
2396  if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
2397  continue;
2398  }
2399 
2400  if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
2401  continue;
2402  }
2403 
2404  // Do not connect to bad ports, unless 50 invalid addresses have
2405  // been selected already.
2406  if (nTries < 50 && (addr.IsIPv4() || addr.IsIPv6()) &&
2407  IsBadPort(addr.GetPort())) {
2408  continue;
2409  }
2410 
2411  // For avalanche peers, check they have the avalanche service bit
2412  // set.
2413  if (conn_type == ConnectionType::AVALANCHE_OUTBOUND &&
2414  !(addr.nServices & NODE_AVALANCHE)) {
2415  // If this peer is not suitable as an avalanche one and we tried
2416  // over 50 addresses already, see if we can fallback to a non
2417  // avalanche full outbound.
2418  if (nTries < 50 ||
2419  nOutboundFullRelay >= m_max_outbound_full_relay ||
2420  setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2421  // Fallback is not desirable or possible, try another one
2422  continue;
2423  }
2424 
2425  // Fallback is possible, update the connection type accordingly
2427  }
2428 
2429  addrConnect = addr;
2430  break;
2431  }
2432 
2433  if (addrConnect.IsValid()) {
2434  if (fFeeler) {
2435  // Add small amount of random noise before connection to avoid
2436  // synchronization.
2437  int randsleep = GetRand<int>(FEELER_SLEEP_WINDOW * 1000);
2438  if (!interruptNet.sleep_for(
2439  std::chrono::milliseconds(randsleep))) {
2440  return;
2441  }
2442  LogPrint(BCLog::NET, "Making feeler connection to %s\n",
2443  addrConnect.ToString());
2444  }
2445 
2446  // This mock is for testing purpose only. It prevents the thread
2447  // from attempting the connection which is useful for testing.
2448  if (mockOpenConnection) {
2449  mockOpenConnection(addrConnect, conn_type);
2450  } else {
2451  OpenNetworkConnection(addrConnect,
2452  int(setConnected.size()) >=
2453  std::min(nMaxConnections - 1, 2),
2454  &grant, nullptr, conn_type);
2455  }
2456  }
2457  }
2458 }
2459 
2460 std::vector<CAddress> CConnman::GetCurrentBlockRelayOnlyConns() const {
2461  std::vector<CAddress> ret;
2463  for (const CNode *pnode : m_nodes) {
2464  if (pnode->IsBlockOnlyConn()) {
2465  ret.push_back(pnode->addr);
2466  }
2467  }
2468 
2469  return ret;
2470 }
2471 
2472 std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() const {
2473  std::vector<AddedNodeInfo> ret;
2474 
2475  std::list<std::string> lAddresses(0);
2476  {
2478  ret.reserve(m_added_nodes.size());
2479  std::copy(m_added_nodes.cbegin(), m_added_nodes.cend(),
2480  std::back_inserter(lAddresses));
2481  }
2482 
2483  // Build a map of all already connected addresses (by IP:port and by name)
2484  // to inbound/outbound and resolved CService
2485  std::map<CService, bool> mapConnected;
2486  std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2487  {
2489  for (const CNode *pnode : m_nodes) {
2490  if (pnode->addr.IsValid()) {
2491  mapConnected[pnode->addr] = pnode->IsInboundConn();
2492  }
2493  std::string addrName{pnode->m_addr_name};
2494  if (!addrName.empty()) {
2495  mapConnectedByName[std::move(addrName)] =
2496  std::make_pair(pnode->IsInboundConn(),
2497  static_cast<const CService &>(pnode->addr));
2498  }
2499  }
2500  }
2501 
2502  for (const std::string &strAddNode : lAddresses) {
2503  CService service(
2504  LookupNumeric(strAddNode, Params().GetDefaultPort(strAddNode)));
2505  AddedNodeInfo addedNode{strAddNode, CService(), false, false};
2506  if (service.IsValid()) {
2507  // strAddNode is an IP:port
2508  auto it = mapConnected.find(service);
2509  if (it != mapConnected.end()) {
2510  addedNode.resolvedAddress = service;
2511  addedNode.fConnected = true;
2512  addedNode.fInbound = it->second;
2513  }
2514  } else {
2515  // strAddNode is a name
2516  auto it = mapConnectedByName.find(strAddNode);
2517  if (it != mapConnectedByName.end()) {
2518  addedNode.resolvedAddress = it->second.second;
2519  addedNode.fConnected = true;
2520  addedNode.fInbound = it->second.first;
2521  }
2522  }
2523  ret.emplace_back(std::move(addedNode));
2524  }
2525 
2526  return ret;
2527 }
2528 
2530  while (true) {
2531  CSemaphoreGrant grant(*semAddnode);
2532  std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
2533  bool tried = false;
2534  for (const AddedNodeInfo &info : vInfo) {
2535  if (!info.fConnected) {
2536  if (!grant.TryAcquire()) {
2537  // If we've used up our semaphore and need a new one, let's
2538  // not wait here since while we are waiting the
2539  // addednodeinfo state might change.
2540  break;
2541  }
2542  tried = true;
2543  CAddress addr(CService(), NODE_NONE);
2544  OpenNetworkConnection(addr, false, &grant,
2545  info.strAddedNode.c_str(),
2547  if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
2548  return;
2549  }
2550  }
2551  }
2552  // Retry every 60 seconds if a connection was attempted, otherwise two
2553  // seconds.
2554  if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2))) {
2555  return;
2556  }
2557  }
2558 }
2559 
2560 // If successful, this moves the passed grant to the constructed node.
2562  bool fCountFailure,
2563  CSemaphoreGrant *grantOutbound,
2564  const char *pszDest,
2565  ConnectionType conn_type) {
2566  assert(conn_type != ConnectionType::INBOUND);
2567 
2568  //
2569  // Initiate outbound network connection
2570  //
2571  if (interruptNet) {
2572  return;
2573  }
2574  if (!fNetworkActive) {
2575  return;
2576  }
2577  if (!pszDest) {
2578  bool banned_or_discouraged =
2579  m_banman && (m_banman->IsDiscouraged(addrConnect) ||
2580  m_banman->IsBanned(addrConnect));
2581  if (IsLocal(addrConnect) || banned_or_discouraged ||
2582  AlreadyConnectedToAddress(addrConnect)) {
2583  return;
2584  }
2585  } else if (FindNode(std::string(pszDest))) {
2586  return;
2587  }
2588 
2589  CNode *pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2590 
2591  if (!pnode) {
2592  return;
2593  }
2594  if (grantOutbound) {
2595  grantOutbound->MoveTo(pnode->grantOutbound);
2596  }
2597 
2598  for (auto interface : m_msgproc) {
2599  interface->InitializeNode(*config, *pnode, nLocalServices);
2600  }
2601 
2602  {
2604  m_nodes.push_back(pnode);
2605  }
2606 }
2607 
2609 
2612 
2613  FastRandomContext rng;
2614  while (!flagInterruptMsgProc) {
2615  std::vector<CNode *> nodes_copy;
2616  {
2618  nodes_copy = m_nodes;
2619  for (CNode *pnode : nodes_copy) {
2620  pnode->AddRef();
2621  }
2622  }
2623 
2624  bool fMoreWork = false;
2625 
2626  // Randomize the order in which we process messages from/to our peers.
2627  // This prevents attacks in which an attacker exploits having multiple
2628  // consecutive connections in the m_nodes list.
2629  Shuffle(nodes_copy.begin(), nodes_copy.end(), rng);
2630 
2631  for (CNode *pnode : nodes_copy) {
2632  if (pnode->fDisconnect) {
2633  continue;
2634  }
2635 
2636  bool fMoreNodeWork = false;
2637  // Receive messages
2638  for (auto interface : m_msgproc) {
2639  fMoreNodeWork |= interface->ProcessMessages(
2640  *config, pnode, flagInterruptMsgProc);
2641  }
2642  fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2643  if (flagInterruptMsgProc) {
2644  return;
2645  }
2646 
2647  // Send messages
2648  for (auto interface : m_msgproc) {
2649  interface->SendMessages(*config, pnode);
2650  }
2651 
2652  if (flagInterruptMsgProc) {
2653  return;
2654  }
2655  }
2656 
2657  {
2659  for (CNode *pnode : nodes_copy) {
2660  pnode->Release();
2661  }
2662  }
2663 
2664  WAIT_LOCK(mutexMsgProc, lock);
2665  if (!fMoreWork) {
2666  condMsgProc.wait_until(lock,
2667  std::chrono::steady_clock::now() +
2668  std::chrono::milliseconds(100),
2669  [this]() EXCLUSIVE_LOCKS_REQUIRED(
2670  mutexMsgProc) { return fMsgProcWake; });
2671  }
2672  fMsgProcWake = false;
2673  }
2674 }
2675 
2677  static constexpr auto err_wait_begin = 1s;
2678  static constexpr auto err_wait_cap = 5min;
2679  auto err_wait = err_wait_begin;
2680 
2681  bool advertising_listen_addr = false;
2682  i2p::Connection conn;
2683 
2684  while (!interruptNet) {
2685  if (!m_i2p_sam_session->Listen(conn)) {
2686  if (advertising_listen_addr && conn.me.IsValid()) {
2687  RemoveLocal(conn.me);
2688  advertising_listen_addr = false;
2689  }
2690 
2691  interruptNet.sleep_for(err_wait);
2692  if (err_wait < err_wait_cap) {
2693  err_wait *= 2;
2694  }
2695 
2696  continue;
2697  }
2698 
2699  if (!advertising_listen_addr) {
2700  AddLocal(conn.me, LOCAL_MANUAL);
2701  advertising_listen_addr = true;
2702  }
2703 
2704  if (!m_i2p_sam_session->Accept(conn)) {
2705  continue;
2706  }
2707 
2709  conn.sock->Release(), NetPermissionFlags::None,
2710  CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
2711  }
2712 }
2713 
2714 bool CConnman::BindListenPort(const CService &addrBind, bilingual_str &strError,
2715  NetPermissionFlags permissions) {
2716  int nOne = 1;
2717 
2718  // Create socket for listening for incoming connections
2719  struct sockaddr_storage sockaddr;
2720  socklen_t len = sizeof(sockaddr);
2721  if (!addrBind.GetSockAddr((struct sockaddr *)&sockaddr, &len)) {
2722  strError = strprintf(
2723  Untranslated("Error: Bind address family for %s not supported"),
2724  addrBind.ToString());
2725  LogPrintf("%s\n", strError.original);
2726  return false;
2727  }
2728 
2729  std::unique_ptr<Sock> sock = CreateSock(addrBind);
2730  if (!sock) {
2731  strError =
2732  strprintf(Untranslated("Error: Couldn't open socket for incoming "
2733  "connections (socket returned error %s)"),
2735  LogPrintf("%s\n", strError.original);
2736  return false;
2737  }
2738 
2739  // Allow binding if the port is still in TIME_WAIT state after
2740  // the program was closed and restarted.
2741  setsockopt(sock->Get(), SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne,
2742  sizeof(int));
2743 
2744  // Some systems don't have IPV6_V6ONLY but are always v6only; others do have
2745  // the option and enable it by default or not. Try to enable it, if
2746  // possible.
2747  if (addrBind.IsIPv6()) {
2748 #ifdef IPV6_V6ONLY
2749  setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_V6ONLY,
2750  (sockopt_arg_type)&nOne, sizeof(int));
2751 #endif
2752 #ifdef WIN32
2753  int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2754  setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_PROTECTION_LEVEL,
2755  (sockopt_arg_type)&nProtLevel, sizeof(int));
2756 #endif
2757  }
2758 
2759  if (::bind(sock->Get(), (struct sockaddr *)&sockaddr, len) ==
2760  SOCKET_ERROR) {
2761  int nErr = WSAGetLastError();
2762  if (nErr == WSAEADDRINUSE) {
2763  strError = strprintf(_("Unable to bind to %s on this computer. %s "
2764  "is probably already running."),
2765  addrBind.ToString(), PACKAGE_NAME);
2766  } else {
2767  strError = strprintf(_("Unable to bind to %s on this computer "
2768  "(bind returned error %s)"),
2769  addrBind.ToString(), NetworkErrorString(nErr));
2770  }
2771  LogPrintf("%s\n", strError.original);
2772  return false;
2773  }
2774  LogPrintf("Bound to %s\n", addrBind.ToString());
2775 
2776  // Listen for incoming connections
2777  if (listen(sock->Get(), SOMAXCONN) == SOCKET_ERROR) {
2778  strError = strprintf(_("Error: Listening for incoming connections "
2779  "failed (listen returned error %s)"),
2781  LogPrintf("%s\n", strError.original);
2782  return false;
2783  }
2784 
2785  vhListenSocket.push_back(ListenSocket(sock->Release(), permissions));
2786  return true;
2787 }
2788 
2789 void Discover() {
2790  if (!fDiscover) {
2791  return;
2792  }
2793 
2794 #ifdef WIN32
2795  // Get local host IP
2796  char pszHostName[256] = "";
2797  if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) {
2798  std::vector<CNetAddr> vaddr;
2799  if (LookupHost(pszHostName, vaddr, 0, true)) {
2800  for (const CNetAddr &addr : vaddr) {
2801  if (AddLocal(addr, LOCAL_IF)) {
2802  LogPrintf("%s: %s - %s\n", __func__, pszHostName,
2803  addr.ToString());
2804  }
2805  }
2806  }
2807  }
2808 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2809  // Get local host ip
2810  struct ifaddrs *myaddrs;
2811  if (getifaddrs(&myaddrs) == 0) {
2812  for (struct ifaddrs *ifa = myaddrs; ifa != nullptr;
2813  ifa = ifa->ifa_next) {
2814  if (ifa->ifa_addr == nullptr || (ifa->ifa_flags & IFF_UP) == 0 ||
2815  strcmp(ifa->ifa_name, "lo") == 0 ||
2816  strcmp(ifa->ifa_name, "lo0") == 0) {
2817  continue;
2818  }
2819  if (ifa->ifa_addr->sa_family == AF_INET) {
2820  struct sockaddr_in *s4 =
2821  reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr);
2822  CNetAddr addr(s4->sin_addr);
2823  if (AddLocal(addr, LOCAL_IF)) {
2824  LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name,
2825  addr.ToString());
2826  }
2827  } else if (ifa->ifa_addr->sa_family == AF_INET6) {
2828  struct sockaddr_in6 *s6 =
2829  reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_addr);
2830  CNetAddr addr(s6->sin6_addr);
2831  if (AddLocal(addr, LOCAL_IF)) {
2832  LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name,
2833  addr.ToString());
2834  }
2835  }
2836  }
2837  freeifaddrs(myaddrs);
2838  }
2839 #endif
2840 }
2841 
2842 void CConnman::SetNetworkActive(bool active) {
2843  LogPrintf("%s: %s\n", __func__, active);
2844 
2845  if (fNetworkActive == active) {
2846  return;
2847  }
2848 
2849  fNetworkActive = active;
2850 
2851  if (m_client_interface) {
2852  m_client_interface->NotifyNetworkActiveChanged(fNetworkActive);
2853  }
2854 }
2855 
2856 CConnman::CConnman(const Config &configIn, uint64_t nSeed0In, uint64_t nSeed1In,
2857  AddrMan &addrmanIn, bool network_active)
2858  : config(&configIn), addrman(addrmanIn), nSeed0(nSeed0In),
2859  nSeed1(nSeed1In) {
2860  SetTryNewOutboundPeer(false);
2861 
2862  Options connOptions;
2863  Init(connOptions);
2864  SetNetworkActive(network_active);
2865 }
2866 
2868  return nLastNodeId.fetch_add(1);
2869 }
2870 
2871 bool CConnman::Bind(const CService &addr, unsigned int flags,
2872  NetPermissionFlags permissions) {
2873  if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
2874  return false;
2875  }
2876  bilingual_str strError;
2877  if (!BindListenPort(addr, strError, permissions)) {
2879  m_client_interface->ThreadSafeMessageBox(
2880  strError, "", CClientUIInterface::MSG_ERROR);
2881  }
2882  return false;
2883  }
2884 
2885  if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) &&
2887  AddLocal(addr, LOCAL_BIND);
2888  }
2889 
2890  return true;
2891 }
2892 
2893 bool CConnman::InitBinds(const Options &options) {
2894  bool fBound = false;
2895  for (const auto &addrBind : options.vBinds) {
2896  fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR),
2898  }
2899  for (const auto &addrBind : options.vWhiteBinds) {
2900  fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR),
2901  addrBind.m_flags);
2902  }
2903  for (const auto &addr_bind : options.onion_binds) {
2904  fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE,
2906  }
2907  if (options.bind_on_any) {
2908  struct in_addr inaddr_any;
2909  inaddr_any.s_addr = htonl(INADDR_ANY);
2910  struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2911  fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE,
2913  fBound |=
2914  Bind(CService(inaddr_any, GetListenPort()),
2916  }
2917  return fBound;
2918 }
2919 
2920 bool CConnman::Start(CScheduler &scheduler, const Options &connOptions) {
2921  Init(connOptions);
2922 
2923  if (fListen && !InitBinds(connOptions)) {
2924  if (m_client_interface) {
2925  m_client_interface->ThreadSafeMessageBox(
2926  _("Failed to listen on any port. Use -listen=0 if you want "
2927  "this."),
2929  }
2930  return false;
2931  }
2932 
2933  proxyType i2p_sam;
2934  if (GetProxy(NET_I2P, i2p_sam)) {
2935  m_i2p_sam_session = std::make_unique<i2p::sam::Session>(
2936  gArgs.GetDataDirNet() / "i2p_private_key", i2p_sam.proxy,
2937  &interruptNet);
2938  }
2939 
2940  for (const auto &strDest : connOptions.vSeedNodes) {
2941  AddAddrFetch(strDest);
2942  }
2943 
2944  if (m_use_addrman_outgoing) {
2945  // Load addresses from anchors.dat
2946  m_anchors =
2949  if (m_anchors.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) {
2951  }
2952  LogPrintf(
2953  "%i block-relay-only anchors will be tried for connections.\n",
2954  m_anchors.size());
2955  }
2956 
2957  if (m_client_interface) {
2958  m_client_interface->InitMessage(
2959  _("Starting network threads...").translated);
2960  }
2961 
2962  fAddressesInitialized = true;
2963 
2964  if (semOutbound == nullptr) {
2965  // initialize semaphore
2966  semOutbound = std::make_unique<CSemaphore>(
2967  std::min(m_max_outbound, nMaxConnections));
2968  }
2969  if (semAddnode == nullptr) {
2970  // initialize semaphore
2971  semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
2972  }
2973 
2974  //
2975  // Start threads
2976  //
2977  assert(m_msgproc.size() > 0);
2978  InterruptSocks5(false);
2979  interruptNet.reset();
2980  flagInterruptMsgProc = false;
2981 
2982  {
2983  LOCK(mutexMsgProc);
2984  fMsgProcWake = false;
2985  }
2986 
2987  // Send and receive from sockets, accept connections
2988  threadSocketHandler = std::thread(&util::TraceThread, "net",
2989  [this] { ThreadSocketHandler(); });
2990 
2991  if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED)) {
2992  LogPrintf("DNS seeding disabled\n");
2993  } else {
2994  threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed",
2995  [this] { ThreadDNSAddressSeed(); });
2996  }
2997 
2998  // Initiate manual connections
2999  threadOpenAddedConnections = std::thread(
3000  &util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); });
3001 
3002  if (connOptions.m_use_addrman_outgoing &&
3003  !connOptions.m_specified_outgoing.empty()) {
3004  if (m_client_interface) {
3005  m_client_interface->ThreadSafeMessageBox(
3006  _("Cannot provide specific connections and have addrman find "
3007  "outgoing connections at the same."),
3009  }
3010  return false;
3011  }
3012  if (connOptions.m_use_addrman_outgoing ||
3013  !connOptions.m_specified_outgoing.empty()) {
3015  std::thread(&util::TraceThread, "opencon",
3016  [this, connect = connOptions.m_specified_outgoing] {
3017  ThreadOpenConnections(connect, nullptr);
3018  });
3019  }
3020 
3021  // Process messages
3022  threadMessageHandler = std::thread(&util::TraceThread, "msghand",
3023  [this] { ThreadMessageHandler(); });
3024 
3025  if (connOptions.m_i2p_accept_incoming &&
3026  m_i2p_sam_session.get() != nullptr) {
3028  std::thread(&util::TraceThread, "i2paccept",
3029  [this] { ThreadI2PAcceptIncoming(); });
3030  }
3031 
3032  // Dump network addresses
3033  scheduler.scheduleEvery(
3034  [this]() {
3035  this->DumpAddresses();
3036  return true;
3037  },
3039 
3040  return true;
3041 }
3042 
3044 public:
3046 
3048 #ifdef WIN32
3049  // Shutdown Windows Sockets
3050  WSACleanup();
3051 #endif
3052  }
3053 };
3055 
3057  {
3058  LOCK(mutexMsgProc);
3059  flagInterruptMsgProc = true;
3060  }
3061  condMsgProc.notify_all();
3062 
3063  interruptNet();
3064  InterruptSocks5(true);
3065 
3066  if (semOutbound) {
3067  for (int i = 0; i < m_max_outbound; i++) {
3068  semOutbound->post();
3069  }
3070  }
3071 
3072  if (semAddnode) {
3073  for (int i = 0; i < nMaxAddnode; i++) {
3074  semAddnode->post();
3075  }
3076  }
3077 }
3078 
3080  if (threadI2PAcceptIncoming.joinable()) {
3081  threadI2PAcceptIncoming.join();
3082  }
3083  if (threadMessageHandler.joinable()) {
3084  threadMessageHandler.join();
3085  }
3086  if (threadOpenConnections.joinable()) {
3087  threadOpenConnections.join();
3088  }
3089  if (threadOpenAddedConnections.joinable()) {
3091  }
3092  if (threadDNSAddressSeed.joinable()) {
3093  threadDNSAddressSeed.join();
3094  }
3095  if (threadSocketHandler.joinable()) {
3096  threadSocketHandler.join();
3097  }
3098 }
3099 
3101  if (fAddressesInitialized) {
3102  DumpAddresses();
3103  fAddressesInitialized = false;
3104 
3105  if (m_use_addrman_outgoing) {
3106  // Anchor connections are only dumped during clean shutdown.
3107  std::vector<CAddress> anchors_to_dump =
3109  if (anchors_to_dump.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) {
3110  anchors_to_dump.resize(MAX_BLOCK_RELAY_ONLY_ANCHORS);
3111  }
3114  anchors_to_dump);
3115  }
3116  }
3117 
3118  // Delete peer connections.
3119  std::vector<CNode *> nodes;
3120  WITH_LOCK(m_nodes_mutex, nodes.swap(m_nodes));
3121  for (CNode *pnode : nodes) {
3122  pnode->CloseSocketDisconnect();
3123  DeleteNode(pnode);
3124  }
3125 
3126  // Close listening sockets.
3127  for (ListenSocket &hListenSocket : vhListenSocket) {
3128  if (hListenSocket.socket != INVALID_SOCKET) {
3129  if (!CloseSocket(hListenSocket.socket)) {
3130  LogPrintf("CloseSocket(hListenSocket) failed with error %s\n",
3132  }
3133  }
3134  }
3135 
3136  for (CNode *pnode : m_nodes_disconnected) {
3137  DeleteNode(pnode);
3138  }
3139  m_nodes_disconnected.clear();
3140  vhListenSocket.clear();
3141  semOutbound.reset();
3142  semAddnode.reset();
3143 }
3144 
3146  assert(pnode);
3147  for (auto interface : m_msgproc) {
3148  interface->FinalizeNode(*config, *pnode);
3149  }
3150  delete pnode;
3151 }
3152 
3154  Interrupt();
3155  Stop();
3156 }
3157 
3158 std::vector<CAddress>
3159 CConnman::GetAddresses(size_t max_addresses, size_t max_pct,
3160  std::optional<Network> network) const {
3161  std::vector<CAddress> addresses =
3162  addrman.GetAddr(max_addresses, max_pct, network);
3163  if (m_banman) {
3164  addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
3165  [this](const CAddress &addr) {
3166  return m_banman->IsDiscouraged(
3167  addr) ||
3168  m_banman->IsBanned(addr);
3169  }),
3170  addresses.end());
3171  }
3172  return addresses;
3173 }
3174 
3175 std::vector<CAddress>
3176 CConnman::GetAddresses(CNode &requestor, size_t max_addresses, size_t max_pct) {
3177  auto local_socket_bytes = requestor.addrBind.GetAddrBytes();
3178  uint64_t cache_id =
3180  .Write(requestor.addr.GetNetwork())
3181  .Write(local_socket_bytes.data(), local_socket_bytes.size())
3182  .Finalize();
3183  const auto current_time = GetTime<std::chrono::microseconds>();
3184  auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
3185  CachedAddrResponse &cache_entry = r.first->second;
3186  // New CachedAddrResponse have expiration 0.
3187  if (cache_entry.m_cache_entry_expiration < current_time) {
3188  cache_entry.m_addrs_response_cache =
3189  GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);
3190  // Choosing a proper cache lifetime is a trade-off between the privacy
3191  // leak minimization and the usefulness of ADDR responses to honest
3192  // users.
3193  //
3194  // Longer cache lifetime makes it more difficult for an attacker to
3195  // scrape enough AddrMan data to maliciously infer something useful. By
3196  // the time an attacker scraped enough AddrMan records, most of the
3197  // records should be old enough to not leak topology info by e.g.
3198  // analyzing real-time changes in timestamps.
3199  //
3200  // It takes only several hundred requests to scrape everything from an
3201  // AddrMan containing 100,000 nodes, so ~24 hours of cache lifetime
3202  // indeed makes the data less inferable by the time most of it could be
3203  // scraped (considering that timestamps are updated via ADDR
3204  // self-announcements and when nodes communicate). We also should be
3205  // robust to those attacks which may not require scraping *full*
3206  // victim's AddrMan (because even several timestamps of the same handful
3207  // of nodes may leak privacy).
3208  //
3209  // On the other hand, longer cache lifetime makes ADDR responses
3210  // outdated and less useful for an honest requestor, e.g. if most nodes
3211  // in the ADDR response are no longer active.
3212  //
3213  // However, the churn in the network is known to be rather low. Since we
3214  // consider nodes to be "terrible" (see IsTerrible()) if the timestamps
3215  // are older than 30 days, max. 24 hours of "penalty" due to cache
3216  // shouldn't make any meaningful difference in terms of the freshness of
3217  // the response.
3218  cache_entry.m_cache_entry_expiration =
3219  current_time + std::chrono::hours(21) +
3220  GetRandMillis(std::chrono::hours(6));
3221  }
3222  return cache_entry.m_addrs_response_cache;
3223 }
3224 
3225 bool CConnman::AddNode(const std::string &strNode) {
3227  for (const std::string &it : m_added_nodes) {
3228  if (strNode == it) {
3229  return false;
3230  }
3231  }
3232 
3233  m_added_nodes.push_back(strNode);
3234  return true;
3235 }
3236 
3237 bool CConnman::RemoveAddedNode(const std::string &strNode) {
3239  for (std::vector<std::string>::iterator it = m_added_nodes.begin();
3240  it != m_added_nodes.end(); ++it) {
3241  if (strNode == *it) {
3242  m_added_nodes.erase(it);
3243  return true;
3244  }
3245  }
3246  return false;
3247 }
3248 
3251  // Shortcut if we want total
3253  return m_nodes.size();
3254  }
3255 
3256  int nNum = 0;
3257  for (const auto &pnode : m_nodes) {
3258  if (flags &
3259  (pnode->IsInboundConn() ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
3260  nNum++;
3261  }
3262  }
3263 
3264  return nNum;
3265 }
3266 
3267 void CConnman::GetNodeStats(std::vector<CNodeStats> &vstats) const {
3268  vstats.clear();
3270  vstats.reserve(m_nodes.size());
3271  for (CNode *pnode : m_nodes) {
3272  vstats.emplace_back();
3273  pnode->copyStats(vstats.back());
3274  vstats.back().m_mapped_as = pnode->addr.GetMappedAS(addrman.GetAsmap());
3275  }
3276 }
3277 
3278 bool CConnman::DisconnectNode(const std::string &strNode) {
3280  if (CNode *pnode = FindNode(strNode)) {
3282  "disconnect by address%s matched peer=%d; disconnecting\n",
3283  (fLogIPs ? strprintf("=%s", strNode) : ""), pnode->GetId());
3284  pnode->fDisconnect = true;
3285  return true;
3286  }
3287  return false;
3288 }
3289 
3290 bool CConnman::DisconnectNode(const CSubNet &subnet) {
3291  bool disconnected = false;
3293  for (CNode *pnode : m_nodes) {
3294  if (subnet.Match(pnode->addr)) {
3296  "disconnect by subnet%s matched peer=%d; disconnecting\n",
3297  (fLogIPs ? strprintf("=%s", subnet.ToString()) : ""),
3298  pnode->GetId());
3299  pnode->fDisconnect = true;
3300  disconnected = true;
3301  }
3302  }
3303  return disconnected;
3304 }
3305 
3307  return DisconnectNode(CSubNet(addr));
3308 }
3309 
3312  for (CNode *pnode : m_nodes) {
3313  if (id == pnode->GetId()) {
3314  LogPrint(BCLog::NET, "disconnect by id peer=%d; disconnecting\n",
3315  pnode->GetId());
3316  pnode->fDisconnect = true;
3317  return true;
3318  }
3319  }
3320  return false;
3321 }
3322 
3323 void CConnman::RecordBytesRecv(uint64_t bytes) {
3324  nTotalBytesRecv += bytes;
3325 }
3326 
3327 void CConnman::RecordBytesSent(uint64_t bytes) {
3329  nTotalBytesSent += bytes;
3330 
3331  const auto now = GetTime<std::chrono::seconds>();
3332  if (nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME < now) {
3333  // timeframe expired, reset cycle
3334  nMaxOutboundCycleStartTime = now;
3335  nMaxOutboundTotalBytesSentInCycle = 0;
3336  }
3337 
3338  // TODO, exclude peers with download permission
3339  nMaxOutboundTotalBytesSentInCycle += bytes;
3340 }
3341 
3344  return nMaxOutboundLimit;
3345 }
3346 
3347 std::chrono::seconds CConnman::GetMaxOutboundTimeframe() const {
3348  return MAX_UPLOAD_TIMEFRAME;
3349 }
3350 
3351 std::chrono::seconds CConnman::GetMaxOutboundTimeLeftInCycle() const {
3353  if (nMaxOutboundLimit == 0) {
3354  return 0s;
3355  }
3356 
3357  if (nMaxOutboundCycleStartTime.count() == 0) {
3358  return MAX_UPLOAD_TIMEFRAME;
3359  }
3360 
3361  const std::chrono::seconds cycleEndTime =
3362  nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME;
3363  const auto now = GetTime<std::chrono::seconds>();
3364  return (cycleEndTime < now) ? 0s : cycleEndTime - now;
3365 }
3366 
3367 bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit) const {
3369  if (nMaxOutboundLimit == 0) {
3370  return false;
3371  }
3372 
3373  if (historicalBlockServingLimit) {
3374  // keep a large enough buffer to at least relay each block once.
3375  const std::chrono::seconds timeLeftInCycle =
3377  const uint64_t buffer =
3378  timeLeftInCycle / std::chrono::minutes{10} * ONE_MEGABYTE;
3379  if (buffer >= nMaxOutboundLimit ||
3380  nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) {
3381  return true;
3382  }
3383  } else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) {
3384  return true;
3385  }
3386 
3387  return false;
3388 }
3389 
3392  if (nMaxOutboundLimit == 0) {
3393  return 0;
3394  }
3395 
3396  return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
3397  ? 0
3398  : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
3399 }
3400 
3402  return nTotalBytesRecv;
3403 }
3404 
3407  return nTotalBytesSent;
3408 }
3409 
3411  return nLocalServices;
3412 }
3413 
3414 unsigned int CConnman::GetReceiveFloodSize() const {
3415  return nReceiveFloodSize;
3416 }
3417 
3418 void CNode::invsPolled(uint32_t count) {
3419  invCounters += count;
3420 }
3421 
3422 void CNode::invsVoted(uint32_t count) {
3423  invCounters += uint64_t(count) << 32;
3424 }
3425 
3426 void CNode::updateAvailabilityScore(double decayFactor) {
3427  if (!m_avalanche_enabled) {
3428  return;
3429  }
3430 
3431  uint64_t windowInvCounters = invCounters.exchange(0);
3432  double previousScore = availabilityScore;
3433 
3434  int64_t polls = windowInvCounters & std::numeric_limits<uint32_t>::max();
3435  int64_t votes = windowInvCounters >> 32;
3436 
3438  decayFactor * (2 * votes - polls) + (1. - decayFactor) * previousScore;
3439 }
3440 
3442  // The score is set atomically so there is no need to lock the statistics
3443  // when reading.
3444  return availabilityScore;
3445 }
3446 
3447 CNode::CNode(NodeId idIn, SOCKET hSocketIn, const CAddress &addrIn,
3448  uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
3449  uint64_t nLocalExtraEntropyIn, const CAddress &addrBindIn,
3450  const std::string &addrNameIn, ConnectionType conn_type_in,
3451  bool inbound_onion)
3452  : m_connected(GetTime<std::chrono::seconds>()), addr(addrIn),
3453  addrBind(addrBindIn), m_addr_name{addrNameIn.empty()
3454  ? addr.ToStringIPPort()
3455  : addrNameIn},
3456  m_inbound_onion(inbound_onion), nKeyedNetGroup(nKeyedNetGroupIn),
3457  // Don't relay addr messages to peers that we connect to as
3458  // block-relay-only peers (to prevent adversaries from inferring these
3459  // links from addr traffic).
3460  id(idIn), nLocalHostNonce(nLocalHostNonceIn),
3461  nLocalExtraEntropy(nLocalExtraEntropyIn), m_conn_type(conn_type_in) {
3462  if (inbound_onion) {
3463  assert(conn_type_in == ConnectionType::INBOUND);
3464  }
3465  hSocket = hSocketIn;
3466 
3467  for (const std::string &msg : getAllNetMessageTypes()) {
3468  mapRecvBytesPerMsgCmd[msg] = 0;
3469  }
3470  mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
3471 
3472  if (fLogIPs) {
3473  LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", m_addr_name,
3474  id);
3475  } else {
3476  LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
3477  }
3478 
3479  m_deserializer = std::make_unique<V1TransportDeserializer>(
3480  V1TransportDeserializer(GetConfig().GetChainParams().NetMagic(),
3482  m_serializer =
3483  std::make_unique<V1TransportSerializer>(V1TransportSerializer());
3484 }
3485 
3487  CloseSocket(hSocket);
3488 }
3489 
3491  return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
3492 }
3493 
3495  size_t nMessageSize = msg.data.size();
3496  LogPrint(BCLog::NETDEBUG, "sending %s (%d bytes) peer=%d\n", msg.m_type,
3497  nMessageSize, pnode->GetId());
3498  if (gArgs.GetBoolArg("-capturemessages", false)) {
3499  CaptureMessage(pnode->addr, msg.m_type, msg.data,
3500  /*is_incoming=*/false);
3501  }
3502 
3503  TRACE6(net, outbound_message, pnode->GetId(), pnode->m_addr_name.c_str(),
3504  pnode->ConnectionTypeAsString().c_str(), msg.m_type.c_str(),
3505  msg.data.size(), msg.data.data());
3506 
3507  // make sure we use the appropriate network transport format
3508  std::vector<uint8_t> serializedHeader;
3509  pnode->m_serializer->prepareForTransport(*config, msg, serializedHeader);
3510  size_t nTotalSize = nMessageSize + serializedHeader.size();
3511 
3512  size_t nBytesSent = 0;
3513  {
3514  LOCK(pnode->cs_vSend);
3515  bool optimisticSend(pnode->vSendMsg.empty());
3516 
3517  // log total amount of bytes per message type
3518  pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
3519  pnode->nSendSize += nTotalSize;
3520 
3521  if (pnode->nSendSize > nSendBufferMaxSize) {
3522  pnode->fPauseSend = true;
3523  }
3524  pnode->vSendMsg.push_back(std::move(serializedHeader));
3525  if (nMessageSize) {
3526  pnode->vSendMsg.push_back(std::move(msg.data));
3527  }
3528 
3529  // If write queue empty, attempt "optimistic write"
3530  if (optimisticSend == true) {
3531  nBytesSent = SocketSendData(*pnode);
3532  }
3533  }
3534  if (nBytesSent) {
3535  RecordBytesSent(nBytesSent);
3536  }
3537 }
3538 
3539 bool CConnman::ForNode(NodeId id, std::function<bool(CNode *pnode)> func) {
3540  CNode *found = nullptr;
3542  for (auto &&pnode : m_nodes) {
3543  if (pnode->GetId() == id) {
3544  found = pnode;
3545  break;
3546  }
3547  }
3548  return found != nullptr && NodeFullyConnected(found) && func(found);
3549 }
3550 
3552  return CSipHasher(nSeed0, nSeed1).Write(id);
3553 }
3554 
3555 uint64_t CConnman::CalculateKeyedNetGroup(const CAddress &ad) const {
3556  std::vector<uint8_t> vchNetGroup(ad.GetGroup(addrman.GetAsmap()));
3557 
3559  .Write(vchNetGroup.data(), vchNetGroup.size())
3560  .Finalize();
3561 }
3562 
3577 std::string getSubVersionEB(uint64_t MaxBlockSize) {
3578  // Prepare EB string we are going to add to SubVer:
3579  // 1) translate from byte to MB and convert to string
3580  // 2) limit the EB string to the first decimal digit (floored)
3581  std::stringstream ebMBs;
3582  ebMBs << (MaxBlockSize / (ONE_MEGABYTE / 10));
3583  std::string eb = ebMBs.str();
3584  eb.insert(eb.size() - 1, ".", 1);
3585  if (eb.substr(0, 1) == ".") {
3586  eb = "0" + eb;
3587  }
3588  return eb;
3589 }
3590 
3591 std::string userAgent(const Config &config) {
3592  // format excessive blocksize value
3593  std::string eb = getSubVersionEB(config.GetMaxBlockSize());
3594  std::vector<std::string> uacomments;
3595  uacomments.push_back("EB" + eb);
3596 
3597  // Comments are checked for char compliance at startup, it is safe to add
3598  // them to the user agent string
3599  for (const std::string &cmt : gArgs.GetArgs("-uacomment")) {
3600  uacomments.push_back(cmt);
3601  }
3602 
3603  const std::string client_name = gArgs.GetArg("-uaclientname", CLIENT_NAME);
3604  const std::string client_version =
3605  gArgs.GetArg("-uaclientversion", FormatVersion(CLIENT_VERSION));
3606 
3607  // Size compliance is checked at startup, it is safe to not check it again
3608  return FormatUserAgent(client_name, client_version, uacomments);
3609 }
3610 
3611 void CaptureMessageToFile(const CAddress &addr, const std::string &msg_type,
3612  Span<const uint8_t> data, bool is_incoming) {
3613  // Note: This function captures the message at the time of processing,
3614  // not at socket receive/send time.
3615  // This ensures that the messages are always in order from an application
3616  // layer (processing) perspective.
3617  auto now = GetTime<std::chrono::microseconds>();
3618 
3619  // Windows folder names can not include a colon
3620  std::string clean_addr = addr.ToString();
3621  std::replace(clean_addr.begin(), clean_addr.end(), ':', '_');
3622 
3623  fs::path base_path = gArgs.GetDataDirNet() / "message_capture" / clean_addr;
3624  fs::create_directories(base_path);
3625 
3626  fs::path path =
3627  base_path / (is_incoming ? "msgs_recv.dat" : "msgs_sent.dat");
3628  AutoFile f{fsbridge::fopen(path, "ab")};
3629 
3630  ser_writedata64(f, now.count());
3631  f.write(msg_type.data(), msg_type.length());
3632  for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
3633  f << '\0';
3634  }
3635  uint32_t size = data.size();
3636  ser_writedata32(f, size);
3637  f.write((const char *)data.data(), data.size());
3638 }
3639 
3640 std::function<void(const CAddress &addr, const std::string &msg_type,
3641  Span<const uint8_t> data, bool is_incoming)>
bool DumpPeerAddresses(const CChainParams &chainParams, const ArgsManager &args, const AddrMan &addr)
Definition: addrdb.cpp:150
std::vector< CAddress > ReadAnchors(const CChainParams &chainParams, const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:223
void DumpAnchors(const CChainParams &chainParams, const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:213
std::unique_ptr< avalanche::Processor > g_avalanche
Global avalanche instance.
Definition: processor.cpp:38
int flags
Definition: bitcoin-tx.cpp:533
const CChainParams & Params()
Return the currently selected parameters.
Stochastic address manager.
Definition: addrman.h:69
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
Definition: addrman.cpp:1347
void Good(const CService &addr, bool test_before_evict=true, NodeSeconds time=AdjustedTime())
Mark an entry as accessible, possibly moving it from "new" to "tried".
Definition: addrman.cpp:1325
const std::vector< bool > & GetAsmap() const
Definition: addrman.cpp:1360
std::pair< CAddress, NodeSeconds > Select(bool newOnly=false) const
Choose an address to connect to.
Definition: addrman.cpp:1343
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.cpp:1335
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.cpp:1316
std::pair< CAddress, NodeSeconds > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict.
Definition: addrman.cpp:1339
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty=0s)
Attempt to add one or more addresses to addrman's new table.
Definition: addrman.cpp:1320
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time=AdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.cpp:1330
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:479
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:268
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:634
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:602
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:664
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:545
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
Definition: banman.cpp:89
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
Definition: banman.cpp:84
A CService with information about it as peer.
Definition: protocol.h:442
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
Definition: protocol.h:546
NodeSeconds nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
Definition: protocol.h:544
const CMessageHeader::MessageMagic & NetMagic() const
Definition: chainparams.h:88
uint16_t GetDefaultPort() const
Definition: chainparams.h:89
const std::vector< SeedSpec6 > & FixedSeeds() const
Definition: chainparams.h:127
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 m_nodes membe...
Definition: net.cpp:1291
std::condition_variable condMsgProc
Definition: net.h:1298
size_t GetNodeCount(NumConnections num) const
Definition: net.cpp:3249
std::thread threadMessageHandler
Definition: net.h:1320
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time in second left in the current max outbound cycle in case of no limit,...
Definition: net.cpp:3351
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached.
Definition: net.cpp:3367
CClientUIInterface * m_client_interface
Definition: net.h:1277
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
Definition: net.cpp:822
void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:2610
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
Definition: net.cpp:3539
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
Definition: net.cpp:1414
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
Definition: net.cpp:422
void DeleteNode(CNode *pnode)
Definition: net.cpp:3145
bool RemoveAddedNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:3237
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
Definition: net.cpp:1209
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
Definition: net.cpp:390
int m_max_outbound
Definition: net.h:1275
ServiceFlags nLocalServices
Services this node offers.
Definition: net.h:1257
bool GetTryNewOutboundPeer() const
Definition: net.cpp:2069
void Stop()
Definition: net.h:932
int m_max_outbound_block_relay
Definition: net.h:1268
std::thread threadI2PAcceptIncoming
Definition: net.h:1321
void SetTryNewOutboundPeer(bool flag)
Definition: net.cpp:2073
std::atomic< bool > flagInterruptMsgProc
Definition: net.h:1300
unsigned int GetReceiveFloodSize() const
Definition: net.cpp:3414
void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:2529
void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:3056
void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
Definition: net.cpp:1907
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Definition: net.cpp:1677
NodeId GetNewNodeId()
Definition: net.cpp:2867
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
Definition: net.h:1308
std::unique_ptr< CSemaphore > semAddnode
Definition: net.h:1260
bool Start(CScheduler &scheduler, const Options &options) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
Definition: net.cpp:2920
std::atomic< NodeId > nLastNodeId
Definition: net.h:1217
void RecordBytesSent(uint64_t bytes)
Definition: net.cpp:3327
int GetExtraBlockRelayCount() const
Definition: net.cpp:2101
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:1899
BanMan * m_banman
Pointer to this node's banman.
Definition: net.h:1284
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:3390
std::thread threadDNSAddressSeed
Definition: net.h:1316
void ThreadI2PAcceptIncoming()
Definition: net.cpp:2676
const uint64_t nSeed1
Definition: net.h:1293
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
Definition: net.h:1290
std::chrono::seconds GetMaxOutboundTimeframe() const
Definition: net.cpp:3347
unsigned int nPrevNodeCount
Definition: net.h:1218
void NotifyNumConnectionsChanged()
Definition: net.cpp:1513
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
Definition: net.cpp:3410
bool DisconnectNode(const std::string &node)
Definition: net.cpp:3278
std::chrono::seconds m_peer_connect_timeout
Definition: net.h:1197
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.
Definition: net.h:1327
bool InitBinds(const Options &options)
Definition: net.cpp:2893
void AddAddrFetch(const std::string &strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex)
Definition: net.cpp:131
std::vector< ListenSocket > vhListenSocket
Definition: net.h:1206
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
Definition: net.cpp:2460
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
Definition: net.cpp:3551
uint64_t GetMaxOutboundTarget() const
Definition: net.cpp:3342
std::unique_ptr< CSemaphore > semOutbound
Definition: net.h:1259
std::vector< NetWhitelistPermissions > vWhitelistedRange
Definition: net.h:1201
RecursiveMutex cs_totalBytesSent
Definition: net.h:1186
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
Definition: net.cpp:2871
std::thread threadOpenConnections
Definition: net.h:1319
NumConnections
Definition: net.h:847
@ CONNECTIONS_IN
Definition: net.h:849
@ CONNECTIONS_ALL
Definition: net.h:851
@ CONNECTIONS_OUT
Definition: net.h:850
Mutex m_addr_fetches_mutex
Definition: net.h:1211
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
Definition: net.cpp:1532
CNode * FindNode(const CNetAddr &ip)
Definition: net.cpp:350
void GetNodeStats(std::vector< CNodeStats > &vstats) const
Definition: net.cpp:3267
std::vector< AddedNodeInfo > GetAddedNodeInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:2472
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
Definition: net.h:1293
unsigned int nReceiveFloodSize
Definition: net.h:1204
int GetExtraFullOutboundCount() const
Definition: net.cpp:2085
uint64_t GetTotalBytesRecv() const
Definition: net.cpp:3401
RecursiveMutex m_nodes_mutex
Definition: net.h:1216
static bool NodeFullyConnected(const CNode *pnode)
Definition: net.cpp:3490
void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex)
Definition: net.cpp:2051
int nMaxConnections
Definition: net.h:1261
CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1, AddrMan &addrmanIn, bool network_active=true)
Definition: net.cpp:2856
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:3159
void SetNetworkActive(bool active)
Definition: net.cpp:2842
std::list< CNode * > m_nodes_disconnected
Definition: net.h:1215
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
Definition: net.cpp:2561
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
Definition: net.cpp:566
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Definition: net.cpp:1572
AddrMan & addrman
Definition: net.h:1209
void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:1760
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
Definition: net.cpp:3555
Mutex mutexMsgProc
Definition: net.h:1299
bool fAddressesInitialized
Definition: net.h:1208
~CConnman()
Definition: net.cpp:3153
void StopThreads()
Definition: net.cpp:3079
bool AddNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:3225
std::thread threadOpenAddedConnections
Definition: net.h:1318
Mutex m_added_nodes_mutex
Definition: net.h:1213
const Config * config
Definition: net.h:1183
void Init(const Options &connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.h:883
bool CheckIncomingNonce(uint64_t nonce)
Definition: net.cpp:395
int m_max_outbound_full_relay
Definition: net.h:1264
int nMaxAddnode
Definition: net.h:1273
void RecordBytesRecv(uint64_t bytes)
Definition: net.cpp:3323
bool ShouldRunInactivityChecks(const CNode &node, std::chrono::seconds now) const
Return true if we should disconnect the peer for failing an inactivity check.
Definition: net.cpp:1527
void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:1891
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
Definition: net.cpp:3494
void StopNodes()
Definition: net.cpp:3100
unsigned int nSendBufferMaxSize
Definition: net.h:1203
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
Definition: net.h:1314
bool m_use_addrman_outgoing
Definition: net.h:1276
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:1245
std::atomic< uint64_t > nTotalBytesRecv
Definition: net.h:1187
std::atomic< bool > fNetworkActive
Definition: net.h:1207
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
Definition: net.h:1334
void DisconnectNodes()
Definition: net.cpp:1463
void DumpAddresses()
Definition: net.cpp:2042
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:1340
std::vector< NetEventsInterface * > m_msgproc
Definition: net.h:1279
std::thread threadSocketHandler
Definition: net.h:1317
uint64_t GetTotalBytesSent() const
Definition: net.cpp:3405
void ThreadOpenConnections(std::vector< std::string > connect, std::function< void(const CAddress &, ConnectionType)> mockOpenConnection) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
Definition: net.cpp:2115
void AcceptConnection(const ListenSocket &hListenSocket)
Definition: net.cpp:1263
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
Definition: net.cpp:2714
int m_max_avalanche_outbound
Definition: net.h:1271
void resize(size_type n, value_type c=0)
Definition: streams.h:248
size_type size() const
Definition: streams.h:246
void Finalize(Span< uint8_t > output)
Definition: hash.h:29
CHash256 & Write(Span< const uint8_t > input)
Definition: hash.h:36
Message header.
Definition: protocol.h:34
bool IsValid(const Config &config) const
Definition: protocol.cpp:150
static constexpr size_t CHECKSUM_SIZE
Definition: protocol.h:39
MessageMagic pchMessageStart
Definition: protocol.h:69
bool IsOversized(const Config &config) const
Definition: protocol.cpp:191
static constexpr size_t HEADER_SIZE
Definition: protocol.h:44
uint8_t pchChecksum[CHECKSUM_SIZE]
Definition: protocol.h:72
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:36
std::string GetCommand() const
Definition: protocol.cpp:115
static constexpr size_t COMMAND_SIZE
Definition: protocol.h:37
uint32_t nMessageSize
Definition: protocol.h:71
Network address.
Definition: netaddress.h:121
Network GetNetClass() const
Definition: netaddress.cpp:746
std::string ToStringIP() const
Definition: netaddress.cpp:628
std::string ToString() const
Definition: netaddress.cpp:673
bool IsRoutable() const
Definition: netaddress.cpp:514
bool IsValid() const
Definition: netaddress.cpp:479
bool IsIPv4() const
Definition: netaddress.cpp:342
bool IsIPv6() const
Definition: netaddress.cpp:346
std::vector< uint8_t > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
Definition: netaddress.cpp:808
std::vector< uint8_t > GetAddrBytes() const
Definition: netaddress.cpp:863
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:188
enum Network GetNetwork() const
Definition: netaddress.cpp:551
~CNetCleanup()
Definition: net.cpp:3047
CNetCleanup()
Definition: net.cpp:3045
Transport protocol agnostic message container.
Definition: net.h:331
uint32_t m_message_size
size of the payload
Definition: net.h:341
std::chrono::microseconds m_time
time of message receipt
Definition: net.h:336
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
Definition: net.h:343
std::string m_type
Definition: net.h:344
bool m_valid_checksum
Definition: net.h:339
bool m_valid_header
Definition: net.h:338
bool m_valid_netmagic
Definition: net.h:337
Information about a peer.
Definition: net.h:456
const CAddress addrBind
Definition: net.h:490
const std::chrono::seconds m_connected
Unix epoch time at peer connection.
Definition: net.h:485
bool m_prefer_evict
Definition: net.h:507
std::atomic< int > nVersion
Definition: net.h:495
std::atomic< double > availabilityScore
The last computed score.
Definition: net.h:785
bool IsInboundConn() const
Definition: net.h:555
NodeId GetId() const
Definition: net.h:712
std::atomic< int64_t > nTimeOffset
Definition: net.h:486
const std::string m_addr_name
Definition: net.h:491
std::string ConnectionTypeAsString() const
Definition: net.h:758
std::atomic< bool > m_bip152_highbandwidth_to
Definition: net.h:593
std::list< CNetMessage > vRecvMsg
Definition: net.h:771
std::atomic< bool > m_bip152_highbandwidth_from
Definition: net.h:595
std::atomic_bool fSuccessfullyConnected
Definition: net.h:511
const CAddress addr
Definition: net.h:488
void SetAddrLocal(const CService &addrLocalIn) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
May not be called more than once.
Definition: net.cpp:602
CSemaphoreGrant grantOutbound
Definition: net.h:515
Mutex cs_hSocket
Definition: net.h:473
std::unique_ptr< TransportSerializer > m_serializer
Definition: net.h:462
Mutex m_subver_mutex
cleanSubVer is a sanitized string of the user agent byte array we read from the wire.
Definition: net.h:504
Mutex cs_vSend
Definition: net.h:472
std::atomic_bool fPauseSend
Definition: net.h:520
void CloseSocketDisconnect() EXCLUSIVE_LOCKS_REQUIRED(!cs_hSocket)
Definition: net.cpp:557
std::unique_ptr< TransportDeserializer > m_deserializer
Definition: net.h:461
double getAvailabilityScore() const
Definition: net.cpp:3441
NetPermissionFlags m_permissionFlags
Definition: net.h:769
const ConnectionType m_conn_type
Definition: net.h:766
Network ConnectedThroughNetwork() const
Get network the peer connected through.
Definition: net.cpp:614
void copyStats(CNodeStats &stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex
Definition: net.cpp:618
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
Definition: net.h:685
void updateAvailabilityScore(double decayFactor)
The availability score is calculated using an exponentially weighted average.
Definition: net.cpp:3426
bool ReceiveMsgBytes(const Config &config, Span< const uint8_t > msg_bytes, bool &complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv)
Receive bytes from the buffer and deserialize them into messages.
Definition: net.cpp:666
void invsPolled(uint32_t count)
The node was polled for count invs.
Definition: net.cpp:3418
Mutex m_addr_local_mutex
Definition: net.h:774
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e.
Definition: net.h:494
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
Definition: net.h:691
std::atomic< std::chrono::seconds > m_last_proof_time
UNIX epoch time of the last proof received from this peer that we had not yet seen (e....
Definition: net.h:682
Mutex cs_vRecv
Definition: net.h:474
std::atomic< bool > m_avalanche_enabled
Definition: net.h:618
std::atomic< std::chrono::seconds > m_last_block_time
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
Definition: net.h:666
~CNode()
Definition: net.cpp:3486
std::atomic< uint64_t > invCounters
The inventories polled and voted counters since last score computation, stored as a pair of uint32_t ...
Definition: net.h:782
std::atomic_bool fDisconnect
Definition: net.h:514
std::atomic< std::chrono::seconds > m_last_recv
Definition: net.h:483
CNode(NodeId id, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, uint64_t nLocalExtraEntropyIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
Definition: net.cpp:3447
std::atomic< std::chrono::seconds > m_last_tx_time
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
Definition: net.h:674
CService GetAddrLocal() const EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
Definition: net.cpp:596
void invsVoted(uint32_t count)
The node voted for count invs.
Definition: net.cpp:3422
std::atomic< std::chrono::seconds > m_last_send
Definition: net.h:482
CNode * AddRef()
Definition: net.h:745
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:41
void scheduleEvery(Predicate p, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat p until it return false.
Definition: scheduler.cpp:114
RAII-style semaphore lock.
Definition: sync.h:397
bool TryAcquire()
Definition: sync.h:419
void MoveTo(CSemaphoreGrant &grant)
Definition: sync.h:426
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:545
std::string ToStringIPPort() const
std::string ToString() const
uint16_t GetPort() const
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:995
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
SipHash-2-4.
Definition: siphash.h:13
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:82
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
Definition: siphash.cpp:36
std::string ToString() const
bool Match(const CNetAddr &addr) const
bool sleep_for(std::chrono::milliseconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut)
Minimal stream for overwriting and/or appending to an existing byte vector.
Definition: streams.h:65
Definition: config.h:17
virtual uint64_t GetMaxBlockSize() const =0
virtual const CChainParams & GetChainParams() const =0
Fast randomness source.
Definition: random.h:156
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range)
Return the time point advanced by a uniform random duration.
Definition: random.h:260
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:211
Different type to mark Mutex at global scope.
Definition: sync.h:144
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
Definition: net.h:799
NetPermissionFlags m_flags
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
static bool TryParse(const std::string &str, NetWhitebindPermissions &output, bilingual_str &error)
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr std::size_t size() const noexcept
Definition: span.h:209
constexpr C * data() const noexcept
Definition: span.h:198
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:224
CNetMessage GetMessage(const Config &config, std::chrono::microseconds time) override
Definition: net.cpp:763
CDataStream vRecv
Definition: net.h:382
CMessageHeader hdr
Definition: net.h:380
const uint256 & GetMessageHash() const
Definition: net.cpp:754
uint32_t nDataPos
Definition: net.h:384
uint32_t nHdrPos
Definition: net.h:383
int readData(Span< const uint8_t > msg_bytes)
Definition: net.cpp:737
bool Complete() const override
Definition: net.h:410
int readHeader(const Config &config, Span< const uint8_t > msg_bytes)
Definition: net.cpp:704
CHash256 hasher
Definition: net.h:372
CDataStream hdrbuf
Definition: net.h:378
uint256 data_hash
Definition: net.h:373
void prepareForTransport(const Config &config, CSerializedNetMsg &msg, std::vector< uint8_t > &header) override
Definition: net.cpp:806
uint8_t * begin()
Definition: uint256.h:83
bool IsNull() const
Definition: uint256.h:30
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:29
CService proxy
Definition: netbase.h:40
256-bit opaque blob.
Definition: uint256.h:127
std::string FormatVersion(int nVersion)
std::string FormatUserAgent(const std::string &name, const std::string &version, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec.
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
const std::string CLIENT_NAME
#define INVALID_SOCKET
Definition: compat.h:52
#define WSAEWOULDBLOCK
Definition: compat.h:45
#define SOCKET_ERROR
Definition: compat.h:53
#define WSAGetLastError()
Definition: compat.h:42
static bool IsSelectableSocket(const SOCKET &s)
Definition: compat.h:102
#define WSAEMSGSIZE
Definition: compat.h:47
#define MSG_NOSIGNAL
Definition: compat.h:113
#define MSG_DONTWAIT
Definition: compat.h:119
unsigned int SOCKET
Definition: compat.h:40
void * sockopt_arg_type
Definition: compat.h:87
#define WSAEINPROGRESS
Definition: compat.h:49
#define WSAEADDRINUSE
Definition: compat.h:50
#define WSAEINTR
Definition: compat.h:48
const Config & GetConfig()
Definition: config.cpp:34
static const uint64_t ONE_MEGABYTE
1MB
Definition: consensus.h:12
static uint32_t ReadLE32(const uint8_t *ptr)
Definition: common.h:23
const std::vector< std::string > GetRandomizedDNSSeeds(const CChainParams &params)
Return the list of hostnames to look up for DNS seeds.
Definition: dnsseeds.cpp:11
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:74
bool fLogIPs
Definition: logging.cpp:17
#define LogPrint(category,...)
Definition: logging.h:210
#define LogPrintf(...)
Definition: logging.h:206
static unsigned char elements[DATACOUNT][DATALEN]
Definition: tests_impl.h:36
@ NETDEBUG
Definition: logging.h:69
@ NET
Definition: logging.h:40
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
Definition: fs.h:178
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:28
Definition: init.h:28
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:257
void TraceThread(const char *thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
Definition: thread.cpp:13
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:902
bool IsPeerAddrLocalGood(CNode *pnode)
Definition: net.cpp:236
uint16_t GetListenPort()
Definition: net.cpp:136
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:1008
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
Definition: net.cpp:71
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:345
static const uint64_t RANDOMIZER_ID_NETGROUP
Definition: net.cpp:114
CService GetLocalAddress(const CNetAddr &addrPeer)
Definition: net.cpp:220
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
Definition: net.cpp:109
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:950
void RemoveLocal(const CService &addr)
Definition: net.cpp:310
std::optional< CService > GetLocalAddrForPeer(CNode &node)
Returns a local address that we should advertise to this peer.
Definition: net.cpp:242
BindFlags
Used to pass flags to the Bind() function.
Definition: net.cpp:96
@ BF_REPORT_ERROR
Definition: net.cpp:99
@ BF_NONE
Definition: net.cpp:97
@ BF_EXPLICIT
Definition: net.cpp:98
@ BF_DONT_ADVERTISE
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections,...
Definition: net.cpp:104
bool fDiscover
Definition: net.cpp:124
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
Definition: net.cpp:116
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
Definition: net.cpp:66
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
Definition: net.cpp:86
bool fListen
Definition: net.cpp:125
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
Definition: net.cpp:57
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
Definition: net.cpp:172
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:892
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(g_maplocalhost_mutex)
static bool CompareNodeAvailabilityScore(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:967
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:897
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
Definition: net.cpp:407
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
Definition: net.cpp:83
static const uint64_t RANDOMIZER_ID_ADDRCACHE
Definition: net.cpp:120
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
Definition: net.cpp:1019
const std::string NET_MESSAGE_COMMAND_OTHER
Definition: net.cpp:111
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:316
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:917
std::function< void(const CAddress &addr, const std::string &msg_type, Span< const uint8_t > data, bool is_incoming)> CaptureMessage
Defaults to CaptureMessageToFile(), but can be overridden by unit tests.
Definition: net.cpp:3642
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
Definition: net.cpp:63
std::string getSubVersionEB(uint64_t MaxBlockSize)
This function convert MaxBlockSize from byte to MB with a decimal precision one digit rounded down E....
Definition: net.cpp:3577
GlobalMutex g_maplocalhost_mutex
Definition: net.cpp:126
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:277
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
Definition: net.cpp:1114
static bool CompareNodeProofTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:936
#define FEELER_SLEEP_WINDOW
Definition: net.cpp:93
void CaptureMessageToFile(const CAddress &addr, const std::string &msg_type, Span< const uint8_t > data, bool is_incoming)
Dump binary message to file, with timestamp.
Definition: net.cpp:3611
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
Definition: net.cpp:84
static int GetnScore(const CService &addr)
Definition: net.cpp:229
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
Definition: net.cpp:575
static std::vector< CAddress > convertSeed6(const std::vector< SeedSpec6 > &vSeedsIn)
Convert the pnSeed6 array into usable address objects.
Definition: net.cpp:197
static const uint64_t RANDOMIZER_ID_EXTRAENTROPY
Definition: net.cpp:118
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:887
static CNetCleanup instance_of_cnetcleanup
Definition: net.cpp:3054
std::string userAgent(const Config &config)
Definition: net.cpp:3591
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
Definition: net.cpp:89
void Discover()
Look up IP addresses from all interfaces on the machine and add them to the list of local addresses t...
Definition: net.cpp:2789
bool IsReachable(enum Network net)
Definition: net.cpp:324
bool SeenLocal(const CService &addr)
vote for a local address
Definition: net.cpp:334
static constexpr std::chrono::minutes TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
Definition: net.h:63
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
Definition: net.h:57
static const bool DEFAULT_FORCEDNSSEED
Definition: net.h:103
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
Definition: net.h:55
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
Definition: net.h:67
static const bool DEFAULT_FIXEDSEEDS
Definition: net.h:105
ConnectionType
Different types of connections to a peer.
Definition: net.h:151
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly inputted via the addnode RPC,...
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
@ INBOUND
Inbound connections are those initiated by a peer.
@ AVALANCHE_OUTBOUND
Special case of connection to a full relay outbound with avalanche service enabled.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
Definition: net.h:65
static const bool DEFAULT_DNSSEED
Definition: net.h:104
@ LOCAL_MANUAL
Definition: net.h:242
@ LOCAL_BIND
Definition: net.h:238
@ LOCAL_IF
Definition: net.h:236
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
Definition: net.h:78
NetPermissionFlags
Network
A network type.
Definition: netaddress.h:44
@ NET_I2P
I2P.
Definition: netaddress.h:59
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:69
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:47
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:66
bool GetNameProxy(proxyType &nameProxyOut)
Definition: netbase.cpp:739
bool HaveNameProxy()
Definition: netbase.cpp:748
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:720
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
Definition: netbase.cpp:848
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:763
void InterruptSocks5(bool interrupt)
Definition: netbase.cpp:855
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:634
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
Definition: netbase.cpp:620
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:222
bool fNameLookup
Definition: netbase.cpp:38
int nConnectTimeout
Definition: netbase.cpp:37
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:260
bool IsBadPort(uint16_t port)
Determine if a port is "bad" from the perspective of attempting to connect to a node on that port.
Definition: netbase.cpp:859
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:190
int64_t NodeId
Definition: nodeid.h:10
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
Definition: protocol.cpp:207
const std::vector< std::string > & getAllNetMessageTypes()
Get a vector of all valid message types (see above)
Definition: protocol.cpp:246
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
Definition: protocol.h:427
ServiceFlags
nServices flags.
Definition: protocol.h:335
@ NODE_NONE
Definition: protocol.h:338
@ NODE_BLOOM
Definition: protocol.h:352
@ NODE_AVALANCHE
Definition: protocol.h:380
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:435
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en....
Definition: random.cpp:794
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:649
constexpr auto GetRandMillis
Definition: random.h:107
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:291
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition: random.h:85
static RPCHelpMan send()
Definition: rpcwallet.cpp:4228
static uint16_t GetDefaultPort()
Definition: bitcoin.h:18
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:84
@ SER_NETWORK
Definition: serialize.h:166
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:94
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: sock.cpp:331
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
Definition: sock.cpp:353
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
Cache responses to addr requests to minimize privacy leak.
Definition: net.h:1226
std::chrono::microseconds m_cache_entry_expiration
Definition: net.h:1228
std::vector< CAddress > m_addrs_response_cache
Definition: net.h:1227
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
Definition: net.h:1086
std::vector< NetWhitebindPermissions > vWhiteBinds
Definition: net.h:871
std::vector< CService > onion_binds
Definition: net.h:873
std::vector< std::string > m_specified_outgoing
Definition: net.h:878
std::vector< CService > vBinds
Definition: net.h:872
bool m_i2p_accept_incoming
Definition: net.h:880
std::vector< std::string > vSeedNodes
Definition: net.h:869
bool m_use_addrman_outgoing
Definition: net.h:877
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0....
Definition: net.h:876
POD that contains various stats about a node.
Definition: net.h:290
std::string addrLocal
Definition: net.h:314
CAddress addrBind
Definition: net.h:318
uint64_t nRecvBytes
Definition: net.h:308
mapMsgCmdSize mapSendBytesPerMsgCmd
Definition: net.h:307
std::chrono::microseconds m_last_ping_time
Definition: net.h:311
bool fInbound
Definition: net.h:302
uint64_t nSendBytes
Definition: net.h:306
std::chrono::seconds m_last_recv
Definition: net.h:293
std::optional< double > m_availabilityScore
Definition: net.h:323
std::chrono::seconds m_last_proof_time
Definition: net.h:295
ConnectionType m_conn_type
Definition: net.h:322
std::chrono::seconds m_last_send
Definition: net.h:292
std::chrono::seconds m_last_tx_time
Definition: net.h:294
CAddress addr
Definition: net.h:316
std::chrono::microseconds m_min_ping_time
Definition: net.h:312
int64_t nTimeOffset
Definition: net.h:298
std::chrono::seconds m_connected
Definition: net.h:297
bool m_bip152_highbandwidth_from
Definition: net.h:304
bool m_bip152_highbandwidth_to
Definition: net.h:303
std::string m_addr_name
Definition: net.h:299
mapMsgCmdSize mapRecvBytesPerMsgCmd
Definition: net.h:309
int nVersion
Definition: net.h:300
std::chrono::seconds m_last_block_time
Definition: net.h:296
Network m_network
Definition: net.h:320
NodeId nodeid
Definition: net.h:291
NetPermissionFlags m_permissionFlags
Definition: net.h:310
std::string cleanSubVer
Definition: net.h:301
std::vector< uint8_t > data
Definition: net.h:134
std::string m_type
Definition: net.h:135
Sort eviction candidates by network/localhost and connection uptime.
Definition: net.cpp:988
CompareNodeNetworkTime(bool is_local, Network network)
Definition: net.cpp:991
const Network m_network
Definition: net.cpp:990
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) const
Definition: net.cpp:993
const bool m_is_local
Definition: net.cpp:989
uint16_t nPort
Definition: net.h:274
int nScore
Definition: net.h:273
std::chrono::seconds m_last_tx_time
Definition: net.h:1366
Network m_network
Definition: net.h:1373
double availabilityScore
Definition: net.h:1374
std::chrono::seconds m_connected
Definition: net.h:1362
std::chrono::seconds m_last_block_time
Definition: net.h:1364
bool fRelevantServices
Definition: net.h:1367
std::chrono::microseconds m_min_ping_time
Definition: net.h:1363
std::chrono::seconds m_last_proof_time
Definition: net.h:1365
uint64_t nKeyedNetGroup
Definition: net.h:1370
Bilingual messages:
Definition: translation.h:17
std::string original
Definition: translation.h:18
An established connection with another peer.
Definition: i2p.h:31
std::unique_ptr< Sock > sock
Connected socket.
Definition: i2p.h:33
CService me
Our I2P address.
Definition: i2p.h:36
#define WAIT_LOCK(cs, name)
Definition: sync.h:317
#define AssertLockNotHeld(cs)
Definition: sync.h:163
#define LOCK2(cs1, cs2)
Definition: sync.h:309
#define LOCK(cs)
Definition: sync.h:306
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
ArgsManager gArgs
Definition: system.cpp:79
bool error(const char *fmt, const Args &...args)
Definition: system.h:45
static int count
Definition: tests.c:31
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:101
int64_t GetTime()
Definition: time.cpp:109
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:54
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
Definition: time.h:25
NodeSeconds AdjustedTime()
Definition: timedata.h:70
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
#define TRACE6(context, event, a, b, c, d, e, f)
Definition: trace.h:45
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:55
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
assert(!tx.IsCoinBase())
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:14