6 #if defined(HAVE_CONFIG_H) 43 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS 56 #include <unordered_map> 125 m_addr_fetches.push_back(strDest);
131 for (
const std::string& bind_arg :
gArgs.
GetArgs(
"-bind")) {
133 constexpr uint16_t dummy_port = 0;
135 if (
Lookup(bind_arg, bind_addr, dummy_port,
false)) {
136 if (bind_addr.
GetPort() != dummy_port) {
144 for (
const std::string& whitebind_arg :
gArgs.
GetArgs(
"-whitebind")) {
165 int nBestReachability = -1;
168 for (
const auto& entry : mapLocalHost)
170 int nScore = entry.second.nScore;
171 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
172 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
174 addr =
CService(entry.first, entry.second.nPort);
175 nBestReachability = nReachability;
180 return nBestScore >= 0;
184 static std::vector<CAddress>
ConvertSeeds(
const std::vector<uint8_t> &vSeedsIn)
190 const auto one_week{7 * 24h};
191 std::vector<CAddress> vSeedsOut;
200 vSeedsOut.push_back(addr);
221 const auto it = mapLocalHost.find(addr);
222 return (it != mapLocalHost.end()) ? it->second.nScore : 0;
247 if (
node.IsInboundConn()) {
256 addrLocal.SetIP(
node.GetAddrLocal());
289 if (!addr.IsRoutable())
298 LogPrintf(
"AddLocal(%s,%i)\n", addr.ToString(), nScore);
302 const auto [it, is_newly_added] = mapLocalHost.emplace(addr,
LocalServiceInfo());
304 if (is_newly_added || nScore >= info.
nScore) {
305 info.
nScore = nScore + (is_newly_added ? 0 : 1);
306 info.
nPort = addr.GetPort();
322 mapLocalHost.erase(addr);
330 vfLimited[net] = !reachable;
336 return !vfLimited[net];
348 const auto it = mapLocalHost.find(addr);
349 if (it == mapLocalHost.end())
return false;
359 return mapLocalHost.count(addr) > 0;
365 for (
CNode* pnode : m_nodes) {
366 if (static_cast<CNetAddr>(pnode->addr) ==
ip) {
376 for (
CNode* pnode : m_nodes) {
377 if (subNet.
Match(static_cast<CNetAddr>(pnode->addr))) {
387 for (
CNode* pnode : m_nodes) {
388 if (pnode->m_addr_name == addrName) {
398 for (
CNode* pnode : m_nodes) {
399 if (static_cast<CService>(pnode->addr) == addr) {
414 for (
const CNode* pnode : m_nodes) {
415 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() ==
nonce)
425 struct sockaddr_storage sockaddr_bind;
426 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
428 if (!sock.
GetSockName((
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
429 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
442 if (pszDest ==
nullptr) {
450 LogPrintf(
"Failed to open new connection, already connected\n");
456 pszDest ? pszDest : addrConnect.
ToString(),
457 Ticks<HoursDouble>(pszDest ? 0h : Now<NodeSeconds>() - addrConnect.
nTime));
463 std::vector<CService> resolved;
476 LogPrintf(
"Failed to open new connection, already connected\n");
483 bool connected =
false;
484 std::unique_ptr<Sock> sock;
488 std::unique_ptr<i2p::sam::Session> i2p_transient_session;
492 bool proxyConnectionFailed =
false;
498 connected =
m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed);
502 if (m_unused_i2p_sessions.empty()) {
503 i2p_transient_session =
506 i2p_transient_session.swap(m_unused_i2p_sessions.front());
507 m_unused_i2p_sessions.pop();
510 connected = i2p_transient_session->Connect(addrConnect, conn, proxyConnectionFailed);
514 m_unused_i2p_sessions.emplace(i2p_transient_session.release());
520 sock = std::move(conn.
sock);
523 }
else if (use_proxy) {
539 if (!proxyConnectionFailed) {
550 uint16_t port{default_port};
552 bool proxyConnectionFailed;
554 proxyConnectionFailed);
572 pszDest ? pszDest :
"",
592 m_i2p_sam_session.reset();
611 if (addrLocal.IsValid()) {
612 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
614 addrLocal = addrLocalIn;
624 #define X(name) stats.name = name 648 X(mapSendBytesPerMsgType);
653 X(mapRecvBytesPerMsgType);
672 const auto time = GetTime<std::chrono::microseconds>();
674 m_last_recv = std::chrono::duration_cast<std::chrono::seconds>(time);
675 nRecvBytes += msg_bytes.
size();
676 while (msg_bytes.
size() > 0) {
686 bool reject_message{
false};
688 if (reject_message) {
697 auto i = mapRecvBytesPerMsgType.find(msg.
m_type);
698 if (i == mapRecvBytesPerMsgType.end()) {
701 assert(i != mapRecvBytesPerMsgType.end());
718 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
731 catch (
const std::exception&) {
757 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
782 reject_message =
false;
799 LogPrint(
BCLog::NET,
"Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
804 reject_message =
true;
808 reject_message =
true;
832 auto it =
node.vSendMsg.begin();
833 size_t nSentSize = 0;
835 while (it !=
node.vSendMsg.end()) {
836 const auto& data = *it;
847 node.m_last_send = GetTime<std::chrono::seconds>();
848 node.nSendBytes += nBytes;
849 node.nSendOffset += nBytes;
851 if (
node.nSendOffset == data.size()) {
852 node.nSendOffset = 0;
853 node.nSendSize -= data.size();
866 node.CloseSocketDisconnect();
874 if (it ==
node.vSendMsg.end()) {
878 node.vSendMsg.erase(
node.vSendMsg.begin(), it);
892 std::vector<NodeEvictionCandidate> vEvictionCandidates;
897 if (
node->fDisconnect)
901 .m_connected =
node->m_connected,
902 .m_min_ping_time =
node->m_min_ping_time,
903 .m_last_block_time =
node->m_last_block_time,
904 .m_last_tx_time =
node->m_last_tx_time,
905 .fRelevantServices =
node->m_has_all_wanted_services,
906 .m_relay_txs =
node->m_relays_txs.load(),
907 .fBloomFilter =
node->m_bloom_filter_loaded.load(),
908 .nKeyedNetGroup =
node->nKeyedNetGroup,
909 .prefer_evict =
node->m_prefer_evict,
910 .m_is_local =
node->addr.IsLocal(),
911 .m_network =
node->ConnectedThroughNetwork(),
913 .m_conn_type =
node->m_conn_type,
915 vEvictionCandidates.push_back(candidate);
918 const std::optional<NodeId> node_id_to_evict =
SelectNodeToEvict(std::move(vEvictionCandidates));
919 if (!node_id_to_evict) {
923 for (
CNode* pnode : m_nodes) {
924 if (pnode->GetId() == *node_id_to_evict) {
925 LogPrint(
BCLog::NET,
"selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId());
926 pnode->fDisconnect =
true;
934 struct sockaddr_storage sockaddr;
935 socklen_t len =
sizeof(sockaddr);
936 auto sock = hListenSocket.
sock->Accept((
struct sockaddr*)&sockaddr, &len);
947 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
980 for (
const CNode* pnode : m_nodes) {
981 if (pnode->IsInboundConn()) nInbound++;
992 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
999 if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on,
sizeof(on)) ==
SOCKET_ERROR) {
1000 LogPrint(
BCLog::NET,
"connection from %s: unable to set TCP_NODELAY, continuing anyway\n",
1020 if (nInbound >= nMaxInbound)
1024 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1049 .prefer_evict = discouraged,
1052 m_msgproc->InitializeNode(*pnode, nodeServices);
1058 m_nodes.push_back(pnode);
1068 std::optional<int> max_connections;
1069 switch (conn_type) {
1089 return std::count_if(m_nodes.begin(), m_nodes.end(), [conn_type](
CNode*
node) {
return node->m_conn_type == conn_type; }););
1092 if (max_connections != std::nullopt && existing_connections >= max_connections)
return false;
1096 if (!grant)
return false;
1109 for (
CNode* pnode : m_nodes) {
1110 if (!pnode->fDisconnect) {
1112 pnode->fDisconnect =
true;
1118 std::vector<CNode*> nodes_copy = m_nodes;
1119 for (
CNode* pnode : nodes_copy)
1121 if (pnode->fDisconnect)
1124 m_nodes.erase(
remove(m_nodes.begin(), m_nodes.end(), pnode), m_nodes.end());
1127 pnode->grantOutbound.Release();
1130 pnode->CloseSocketDisconnect();
1141 for (
CNode* pnode : nodes_disconnected_copy)
1144 if (pnode->GetRefCount() <= 0) {
1157 nodes_size = m_nodes.size();
1176 const auto now{GetTime<std::chrono::seconds>()};
1177 const auto last_send{
node.m_last_send.load()};
1178 const auto last_recv{
node.m_last_recv.load()};
1182 if (last_recv.count() == 0 || last_send.count() == 0) {
1197 if (!
node.fSuccessfullyConnected) {
1210 events_per_sock.emplace(hListenSocket.sock,
Sock::Events{Sock::RECV});
1213 for (
CNode* pnode : nodes) {
1225 bool select_recv = !pnode->fPauseRecv;
1228 LOCK(pnode->cs_vSend);
1229 select_send = !pnode->vSendMsg.empty();
1232 LOCK(pnode->m_sock_mutex);
1233 if (!pnode->m_sock) {
1240 }
else if (select_recv) {
1244 events_per_sock.emplace(pnode->m_sock,
Sock::Events{requested});
1247 return events_per_sock;
1266 if (events_per_sock.empty() || !events_per_sock.begin()->first->WaitMany(timeout, events_per_sock)) {
1283 for (
CNode* pnode : nodes) {
1290 bool recvSet =
false;
1291 bool sendSet =
false;
1292 bool errorSet =
false;
1294 LOCK(pnode->m_sock_mutex);
1295 if (!pnode->m_sock) {
1298 const auto it = events_per_sock.find(pnode->m_sock);
1299 if (it != events_per_sock.end()) {
1302 errorSet = it->second.occurred &
Sock::ERR;
1305 if (recvSet || errorSet)
1308 uint8_t pchBuf[0x10000];
1311 LOCK(pnode->m_sock_mutex);
1312 if (!pnode->m_sock) {
1315 nBytes = pnode->m_sock->Recv(pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1319 bool notify =
false;
1320 if (!pnode->ReceiveMsgBytes({pchBuf, (size_t)nBytes}, notify)) {
1321 pnode->CloseSocketDisconnect();
1325 size_t nSizeAdded = 0;
1326 auto it(pnode->vRecvMsg.begin());
1327 for (; it != pnode->vRecvMsg.end(); ++it) {
1330 nSizeAdded += it->m_raw_message_size;
1333 LOCK(pnode->cs_vProcessMsg);
1334 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1335 pnode->nProcessQueueSize += nSizeAdded;
1341 else if (nBytes == 0)
1344 if (!pnode->fDisconnect) {
1347 pnode->CloseSocketDisconnect();
1349 else if (nBytes < 0)
1355 if (!pnode->fDisconnect) {
1358 pnode->CloseSocketDisconnect();
1379 const auto it = events_per_sock.find(listen_socket.sock);
1380 if (it != events_per_sock.end() && it->second.occurred &
Sock::RECV) {
1403 fMsgProcWake =
true;
1413 Shuffle(seeds.begin(), seeds.end(), rng);
1414 int seeds_right_now = 0;
1419 seeds_right_now = seeds.size();
1424 seeds_right_now = seeds.size();
1441 for (
const std::string& seed : seeds) {
1442 if (seeds_right_now == 0) {
1446 LogPrintf(
"Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1447 std::chrono::seconds to_wait = seeds_wait_time;
1448 while (to_wait.count() > 0) {
1459 for (
const CNode* pnode : m_nodes) {
1460 if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant;
1463 if (nRelevant >= 2) {
1465 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1466 LogPrintf(
"P2P peers available. Finished DNS seeding.\n");
1468 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1480 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
1486 LogPrintf(
"Loading addresses from DNS seed %s\n", seed);
1490 std::vector<CNetAddr> vIPs;
1491 std::vector<CAddress> vAdd;
1493 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
1498 unsigned int nMaxIPs = 256;
1503 vAdd.push_back(addr);
1515 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1520 const auto start{SteadyClock::now()};
1525 addrman.
size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
1531 std::string strDest;
1534 if (m_addr_fetches.empty())
1536 strDest = m_addr_fetches.front();
1537 m_addr_fetches.pop_front();
1554 LogPrint(
BCLog::NET,
"setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1571 int full_outbound_peers = 0;
1574 for (
const CNode* pnode : m_nodes) {
1575 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsFullOutboundConn()) {
1576 ++full_outbound_peers;
1585 int block_relay_peers = 0;
1588 for (
const CNode* pnode : m_nodes) {
1589 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsBlockOnlyConn()) {
1590 ++block_relay_peers;
1603 if (!connect.empty())
1605 for (int64_t nLoop = 0;; nLoop++)
1608 for (
const std::string& strAddr : connect)
1612 for (
int i = 0; i < 10 && i < nLoop; i++)
1624 auto start = GetTime<std::chrono::microseconds>();
1632 if (!add_fixed_seeds) {
1633 LogPrintf(
"Fixed seeds are disabled\n");
1652 bool add_fixed_seeds_now =
false;
1654 if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
1655 add_fixed_seeds_now =
true;
1656 LogPrintf(
"Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
1660 if (!add_fixed_seeds_now && !dnsseed) {
1663 add_fixed_seeds_now =
true;
1664 LogPrintf(
"Adding fixed seeds as -dnsseed=0 (or IPv4/IPv6 connections are disabled via -onlynet), -addnode is not provided and all -seednode(s) attempted\n");
1668 if (add_fixed_seeds_now) {
1678 seed_addrs.erase(std::remove_if(seed_addrs.begin(), seed_addrs.end(),
1684 add_fixed_seeds =
false;
1685 LogPrintf(
"Added %d fixed seeds from reachable networks.\n", seed_addrs.size());
1695 int nOutboundFullRelay = 0;
1696 int nOutboundBlockRelay = 0;
1697 std::set<std::vector<unsigned char> > setConnected;
1701 for (
const CNode* pnode : m_nodes) {
1702 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1703 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1710 switch (pnode->m_conn_type) {
1724 auto now = GetTime<std::chrono::microseconds>();
1725 bool anchor =
false;
1726 bool fFeeler =
false;
1772 }
else if (now > next_feeler) {
1846 if (current_time - addr_last_try < 10min && nTries < 30) {
1884 std::vector<CAddress>
ret;
1886 for (
const CNode* pnode : m_nodes) {
1887 if (pnode->IsBlockOnlyConn()) {
1888 ret.push_back(pnode->addr);
1897 std::vector<AddedNodeInfo>
ret;
1899 std::list<std::string> lAddresses(0);
1908 std::map<CService, bool> mapConnected;
1909 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
1912 for (
const CNode* pnode : m_nodes) {
1913 if (pnode->addr.IsValid()) {
1914 mapConnected[pnode->addr] = pnode->IsInboundConn();
1916 std::string addrName{pnode->m_addr_name};
1917 if (!addrName.empty()) {
1918 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(),
static_cast<const CService&
>(pnode->addr));
1923 for (
const std::string& strAddNode : lAddresses) {
1928 auto it = mapConnected.find(service);
1929 if (it != mapConnected.end()) {
1930 addedNode.resolvedAddress = service;
1931 addedNode.fConnected =
true;
1932 addedNode.fInbound = it->second;
1936 auto it = mapConnectedByName.find(strAddNode);
1937 if (it != mapConnectedByName.end()) {
1938 addedNode.resolvedAddress = it->second.second;
1939 addedNode.fConnected =
true;
1940 addedNode.fInbound = it->second.first;
1943 ret.emplace_back(std::move(addedNode));
1959 if (!info.fConnected) {
1994 bool banned_or_discouraged =
m_banman && (
m_banman->IsDiscouraged(addrConnect) ||
m_banman->IsBanned(addrConnect));
1998 }
else if (
FindNode(std::string(pszDest)))
2001 CNode* pnode =
ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2011 m_nodes.push_back(pnode);
2020 bool fMoreWork =
false;
2028 for (
CNode* pnode : snap.Nodes()) {
2029 if (pnode->fDisconnect)
2034 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2039 LOCK(pnode->cs_sendProcessing);
2052 fMsgProcWake =
false;
2058 static constexpr
auto err_wait_begin = 1s;
2059 static constexpr
auto err_wait_cap = 5min;
2060 auto err_wait = err_wait_begin;
2062 bool advertising_listen_addr =
false;
2068 if (advertising_listen_addr && conn.
me.
IsValid()) {
2070 advertising_listen_addr =
false;
2074 if (err_wait < err_wait_cap) {
2081 if (!advertising_listen_addr) {
2083 advertising_listen_addr =
true;
2100 struct sockaddr_storage sockaddr;
2101 socklen_t len =
sizeof(sockaddr);
2102 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2109 std::unique_ptr<Sock> sock =
CreateSock(addrBind);
2133 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2134 if (sock->SetSockOpt(IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int)) ==
SOCKET_ERROR) {
2141 if (sock->Bind(reinterpret_cast<struct sockaddr*>(&sockaddr), len) ==
SOCKET_ERROR) {
2171 char pszHostName[256] =
"";
2172 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2174 std::vector<CNetAddr> vaddr;
2180 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2184 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) 2186 struct ifaddrs* myaddrs;
2187 if (getifaddrs(&myaddrs) == 0)
2189 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2191 if (ifa->ifa_addr ==
nullptr)
continue;
2192 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2193 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2194 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2195 if (ifa->ifa_addr->sa_family == AF_INET)
2197 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2202 else if (ifa->ifa_addr->sa_family == AF_INET6)
2204 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2210 freeifaddrs(myaddrs);
2217 LogPrintf(
"%s: %s\n", __func__, active);
2232 : addrman(addrman_in)
2233 , m_netgroupman{netgroupman}
2237 SetTryNewOutboundPeer(
false);
2239 Options connOptions;
2241 SetNetworkActive(network_active);
2246 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2274 bool fBound =
false;
2275 for (
const auto& addrBind : options.
vBinds) {
2278 for (
const auto& addrBind : options.
vWhiteBinds) {
2281 for (
const auto& addr_bind : options.
onion_binds) {
2285 struct in_addr inaddr_any;
2286 inaddr_any.s_addr = htonl(INADDR_ANY);
2287 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2302 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2314 for (
const auto& strDest : connOptions.
vSeedNodes) {
2324 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
2352 fMsgProcWake =
false;
2369 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same time."),
2467 std::vector<CNode*> nodes;
2469 for (
CNode* pnode : nodes) {
2470 pnode->CloseSocketDisconnect();
2498 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct, network);
2500 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2512 .Write(local_socket_bytes.data(), local_socket_bytes.size())
2517 const auto current_time = GetTime<std::chrono::microseconds>();
2555 if (strNode == it)
return false;
2566 if (strNode == *it) {
2578 return m_nodes.size();
2581 for (
const auto& pnode : m_nodes) {
2594 vstats.reserve(m_nodes.size());
2595 for (
CNode* pnode : m_nodes) {
2596 vstats.emplace_back();
2597 pnode->CopyStats(vstats.back());
2607 pnode->fDisconnect =
true;
2615 bool disconnected =
false;
2617 for (
CNode* pnode : m_nodes) {
2618 if (subnet.
Match(pnode->addr)) {
2620 pnode->fDisconnect =
true;
2621 disconnected =
true;
2624 return disconnected;
2635 for(
CNode* pnode : m_nodes) {
2636 if (
id == pnode->GetId()) {
2638 pnode->fDisconnect =
true;
2655 nTotalBytesSent += bytes;
2657 const auto now = GetTime<std::chrono::seconds>();
2661 nMaxOutboundCycleStartTime = now;
2662 nMaxOutboundTotalBytesSentInCycle = 0;
2665 nMaxOutboundTotalBytesSentInCycle += bytes;
2694 if (nMaxOutboundCycleStartTime.count() == 0)
2698 const auto now = GetTime<std::chrono::seconds>();
2699 return (cycleEndTime < now) ? 0s : cycleEndTime - now;
2709 if (historicalBlockServingLimit)
2742 return nTotalBytesSent;
2753 std::shared_ptr<Sock> sock,
2755 uint64_t nKeyedNetGroupIn,
2756 uint64_t nLocalHostNonceIn,
2758 const std::string& addrNameIn,
2764 m_permission_flags{node_opts.permission_flags},
2766 m_connected{GetTime<std::chrono::seconds>()},
2768 addrBind{addrBindIn},
2769 m_addr_name{addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn},
2770 m_inbound_onion{inbound_onion},
2771 m_prefer_evict{node_opts.prefer_evict},
2772 nKeyedNetGroup{nKeyedNetGroupIn},
2774 nLocalHostNonce{nLocalHostNonceIn},
2775 m_conn_type{conn_type_in},
2776 m_i2p_sam_session{std::move(node_opts.i2p_sam_session)}
2781 mapRecvBytesPerMsgType[msg] = 0;
2799 size_t nMessageSize = msg.data.size();
2805 TRACE6(net, outbound_message,
2815 std::vector<unsigned char> serializedHeader;
2816 pnode->
m_serializer->prepareForTransport(msg, serializedHeader);
2817 size_t nTotalSize = nMessageSize + serializedHeader.size();
2819 size_t nBytesSent = 0;
2822 bool optimisticSend(pnode->vSendMsg.empty());
2825 pnode->mapSendBytesPerMsgType[msg.m_type] += nTotalSize;
2826 pnode->nSendSize += nTotalSize;
2829 pnode->vSendMsg.push_back(std::move(serializedHeader));
2830 if (nMessageSize) pnode->vSendMsg.push_back(std::move(msg.data));
2840 CNode* found =
nullptr;
2842 for (
auto&& pnode : m_nodes) {
2843 if(pnode->
GetId() == id) {
2864 const std::string& msg_type,
2872 auto now = GetTime<std::chrono::microseconds>();
2875 std::string clean_addr = addr.
ToString();
2876 std::replace(clean_addr.begin(), clean_addr.end(),
':',
'_');
2881 fs::path path = base_path / (is_incoming ?
"msgs_recv.dat" :
"msgs_sent.dat");
2889 uint32_t size = data.
size();
2894 std::function<void(
const CAddress& addr,
2895 const std::string& msg_type,
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
bool RemoveAddedNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
std::vector< CService > vBinds
std::atomic< bool > flagInterruptMsgProc
std::vector< unsigned char > GetGroup(const CNetAddr &address) const
Get the canonical identifier of the network group for address.
std::vector< CAddress > m_addrs_response_cache
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
static constexpr auto FEELER_SLEEP_WINDOW
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
void MoveTo(CSemaphoreGrant &grant)
std::atomic_bool fPauseSend
CNetMessage GetMessage(std::chrono::microseconds time, bool &reject_message) override
AddrFetch connections are short lived connections used to solicit addresses from peers.
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
bool m_i2p_accept_incoming
void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
std::atomic< bool > fNetworkActive
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ServiceFlags
nServices flags
void Finalize(Span< unsigned char > output)
#define LogPrint(category,...)
Inbound connections are those initiated by a peer.
int readData(Span< const uint8_t > msg_bytes)
FILE * fopen(const fs::path &p, const char *mode)
A set of addresses that represent the hash of a string or FQDN.
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
Dummy value to indicate the number of NET_* constants.
static bool IsSelectableSocket(const SOCKET &s)
void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
Check connected and listening sockets for IO readiness and process them accordingly.
NetPermissionFlags permission_flags
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
bool OutboundTargetReached(bool historicalBlockServingLimit) const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
check if the outbound target is reached if param historicalBlockServingLimit is set true...
Feeler connections are short-lived connections made to check that a node is alive.
Mutex m_total_bytes_sent_mutex
std::shared_ptr< Sock > sock
std::list< CNode * > m_nodes_disconnected
void ser_writedata64(Stream &s, uint64_t obj)
bool sleep_for(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut)
static constexpr size_t MAX_UNUSED_I2P_SESSIONS_SIZE
Cap on the size of m_unused_i2p_sessions, to ensure it does not unexpectedly use too much memory...
const std::chrono::seconds m_connected
Unix epoch time at peer connection.
const std::unique_ptr< TransportDeserializer > m_deserializer
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
const std::string NET_MESSAGE_TYPE_OTHER
std::vector< unsigned char > data
const ConnectionType m_conn_type
uint64_t GetTotalBytesRecv() const
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
constexpr auto GetRandMillis
bool GetProxy(enum Network net, Proxy &proxyInfoOut)
bool ConnectThroughProxy(const Proxy &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...
void ser_writedata32(Stream &s, uint32_t obj)
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
constexpr std::size_t size() const noexcept
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.
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
RAII-style semaphore lock.
void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
CService me
Our I2P address.
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
uint32_t m_message_size
size of the payload
bool DumpPeerAddresses(const ArgsManager &args, const AddrMan &addr)
void Discover()
Look up IP addresses from all interfaces on the machine and add them to the list of local addresses t...
Double ended buffer combining vector and stream-like interfaces.
std::chrono::seconds GetMaxOutboundTimeLeftInCycle_() const EXCLUSIVE_LOCKS_REQUIRED(m_total_bytes_sent_mutex)
returns the time left in the current max outbound cycle in case of no limit, it will always return 0 ...
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void SetTryNewOutboundPeer(bool flag)
void RecordBytesSent(uint64_t bytes) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
std::string ToString() const
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
bool SeenLocal(const CService &addr)
vote for a local address
An established connection with another peer.
Network GetNetClass() const
m_max_outbound_block_relay
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.
bool AddNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
static std::vector< CAddress > ConvertSeeds(const std::vector< uint8_t > &vSeedsIn)
Convert the serialized seeds into usable address objects.
These are the default connections that we use to connect with the network.
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.
void GetNodeStats(std::vector< CNodeStats > &vstats) const
Non-refcounted RAII wrapper for FILE*.
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.
#define WSAGetLastError()
static constexpr std::chrono::minutes TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
std::list< CNetMessage > vRecvMsg
bool GetTryNewOutboundPeer() const
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
void NotifyNumConnectionsChanged()
enum Network GetNetwork() const
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
void Init(const Options &connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
uint64_t GetMaxOutboundTarget() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
static constexpr Event SEND
If passed to Wait(), then it will wait for readiness to send to the socket.
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
Stochastic address manager.
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
uint16_t GetDefaultPort() const
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv)
Receive bytes from the buffer and deserialize them into messages.
Mutex m_unused_i2p_sessions_mutex
Mutex protecting m_i2p_sam_sessions.
bool DisconnectNode(const std::string &node)
std::pair< CAddress, NodeSeconds > Select(bool newOnly=false) const
Choose an address to connect to.
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
std::function< void(const CAddress &addr, const std::string &msg_type, Span< const unsigned char > data, bool is_incoming)> CaptureMessage
Defaults to CaptureMessageToFile(), but can be overridden by unit tests.
int GetExtraBlockRelayCount() const
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
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...
void RecordBytesRecv(uint64_t bytes)
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
std::chrono::steady_clock Clock
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
std::thread threadI2PAcceptIncoming
bool IsBadPort(uint16_t port)
Determine if a port is "bad" from the perspective of attempting to connect to a node on that port...
void SetAddrLocal(const CService &addrLocalIn) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
May not be called more than once.
std::optional< CService > GetLocalAddrForPeer(CNode &node)
Returns a local address that we should advertise to this peer.
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.
std::chrono::microseconds m_cache_entry_expiration
static bool NodeFullyConnected(const CNode *pnode)
unsigned int nPrevNodeCount
static const uint64_t RANDOMIZER_ID_NETGROUP
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::condition_variable condMsgProc
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
void resize(size_type n, value_type c=value_type{})
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
std::vector< AddedNodeInfo > GetAddedNodeInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Mutex m_added_nodes_mutex
std::unordered_map< std::shared_ptr< const Sock >, Events, HashSharedPtrSock, EqualSharedPtrSock > EventsPerSock
On which socket to wait for what events in WaitMany().
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
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.wikipedia.org/wiki/Exponential_distribution).
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services)...
std::thread threadOpenAddedConnections
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
std::string ToStringIP() const
void StartExtraBlockRelayPeers()
CNode * FindNode(const CNetAddr &ip)
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection. ...
bilingual_str _(const char *psz)
Translation function.
bool IsPeerAddrLocalGood(CNode *pnode)
bool AddLocal(const CService &addr_, int nScore)
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
void SocketHandlerListening(const Sock::EventsPerSock &events_per_sock)
Accept incoming connections, one from each read-ready listening socket.
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
A combination of a network address (CNetAddr) and a (TCP) port.
Transport protocol agnostic message container.
std::vector< std::string > vSeedNodes
std::vector< std::string > m_specified_outgoing
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) const override
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
std::unique_ptr< CSemaphore > semOutbound
std::thread threadMessageHandler
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as connection attempted to.
bool AddConnection(const std::string &address, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
Attempts to open a connection.
const uint256 & GetMessageHash() const
int GetExtraFullOutboundCount() const
A CService with information about it as peer.
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
static int GetnScore(const CService &addr)
const std::vector< std::string > & getAllNetMessageTypes()
static constexpr bool DEFAULT_FIXEDSEEDS
uint32_t GetMappedAS(const CNetAddr &address) const
Get the autonomous system on the BGP path to address.
#define LogPrintLevel(category, level,...)
static CService ip(uint32_t i)
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections, to prevent gossiping them over the network.
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay This t...
const CMessageHeader::MessageStartChars & MessageStart() const
bool InitBinds(const Options &options)
void SetNetworkActive(bool active)
#define WAIT_LOCK(cs, name)
static constexpr bool DEFAULT_DNSSEED
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
CService GetLocalAddress(const CNetAddr &addrPeer)
void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
std::atomic< bool > m_bip152_highbandwidth_to
const NetPermissionFlags m_permission_flags
NodeSeconds nTime
Always included in serialization. The behavior is unspecified if the value is not representable as ui...
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e. connected via our Tor onion service.
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...
std::atomic_bool fDisconnect
void CreateNodeFromAcceptedSocket(std::unique_ptr< Sock > &&sock, NetPermissionFlags permission_flags, 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...
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
void AddAddrFetch(const std::string &strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex)
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...
NetPermissionFlags m_flags
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.
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
RecursiveMutex m_nodes_mutex
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB...
unsigned int GetReceiveFloodSize() const
constexpr int64_t count_seconds(std::chrono::seconds t)
void DeleteNode(CNode *pnode)
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
static constexpr Event ERR
Ignored if passed to Wait(), but could be set in the occurred events if an exceptional condition has ...
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
bool CheckIncomingNonce(uint64_t nonce)
void CloseSocketDisconnect() EXCLUSIVE_LOCKS_REQUIRED(!m_sock_mutex)
void ThreadOpenConnections(std::vector< std::string > connect) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
bool Complete() const override
void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
bool Match(const CNetAddr &addr) const
Mutex m_addr_fetches_mutex
std::atomic< std::chrono::seconds > m_last_send
std::atomic< NodeId > nLastNodeId
bool GetNameProxy(Proxy &nameProxyOut)
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
std::vector< CService > onion_binds
static time_point now() noexcept
Return current system time or mocked time, if set.
size_t GetNodeCount(ConnectionDirection) const
CService MaybeFlipIPv6toCJDNS(const CService &service)
If an IPv6 address belongs to the address range used by the CJDNS network and the CJDNS network is re...
bool IsReachable(enum Network net)
void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
std::pair< CAddress, NodeSeconds > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict...
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
static constexpr Event RECV
If passed to Wait(), then it will wait for readiness to read from the socket.
std::string ToString() const
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
std::thread threadOpenConnections
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
uint64_t GetTotalBytesSent() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
int readHeader(Span< const uint8_t > msg_bytes)
constexpr C * data() const noexcept
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
const CChainParams & m_chain_params
virtual SOCKET Get() const
Get the value of the contained socket.
void SocketHandlerConnected(const std::vector< CNode *> &nodes, const Sock::EventsPerSock &events_per_sock) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
Do the read/write for connected sockets that are ready for IO.
static const int PROTOCOL_VERSION
network protocol versioning
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
CConnman(uint64_t seed0, uint64_t seed1, AddrMan &addrman, const NetGroupManager &netgroupman, bool network_active=true)
GlobalMutex g_maplocalhost_mutex
std::atomic< std::chrono::seconds > m_last_recv
bool fAddressesInitialized
static CAddress GetBindAddress(const Sock &sock)
Get the bind address for a socket as CAddress.
std::thread threadDNSAddressSeed
#define TRACE6(context, event, a, b, c, d, e, f)
std::string ToStringIPPort() const
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
bool Start(CScheduler &scheduler, const Options &options) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
Span< const std::byte > MakeByteSpan(V &&v) noexcept
std::vector< ListenSocket > vhListenSocket
std::chrono::seconds GetMaxOutboundTimeframe() const
static const uint64_t RANDOMIZER_ID_ADDRCACHE
CService GetAddrLocal() const EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
static uint32_t ReadLE32(const unsigned char *ptr)
std::atomic< int64_t > nTimeOffset
static constexpr bool DEFAULT_FORCEDNSSEED
Span< const std::byte > AsBytes(Span< T > s) noexcept
const std::unique_ptr< const TransportSerializer > m_serializer
std::atomic_bool fSuccessfullyConnected
fSuccessfullyConnected is set to true on receiving VERACK from the peer.
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
#define AssertLockNotHeld(cs)
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
std::atomic< int > nVersion
size_t size() const
Return the number of (unique) addresses in all tables.
void CaptureMessageToFile(const CAddress &addr, const std::string &msg_type, Span< const unsigned char > data, bool is_incoming)
Dump binary message to file, with timestamp.
Sock::EventsPerSock GenerateWaitSockets(Span< CNode *const > nodes)
Generate a collection of sockets to check for IO readiness.
void InterruptSocks5(bool interrupt)
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
std::string ConnectionTypeAsString() const
ConnectionType
Different types of connections to a peer.
bool ShouldRunInactivityChecks(const CNode &node, std::chrono::seconds now) const
Return true if we should disconnect the peer for failing an inactivity check.
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
std::string ToString() const
std::atomic< bool > m_bip152_highbandwidth_from
void ThreadI2PAcceptIncoming()
RAII helper class that manages a socket.
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range)
Return the time point advanced by a uniform random duration.
CNode(NodeId id, std::shared_ptr< Sock > sock, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion, CNodeOptions &&node_opts={})
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
RAII helper to atomically create a copy of m_nodes and add a reference to each of the nodes...
BindFlags
Used to pass flags to the Bind() function.
void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
void AcceptConnection(const ListenSocket &hListenSocket)
A Span is an object that can refer to a contiguous sequence of objects.
static bool TryParse(const std::string &str, NetWhitebindPermissions &output, bilingual_str &error)
Different type to mark Mutex at global scope.
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Information about a peer.
static CNetCleanup instance_of_cnetcleanup
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...
bool SetSockAddr(const struct sockaddr *paddr)
std::thread threadSocketHandler
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct, difficult-to-forge characteristics.
Simple class for background tasks that should be run periodically or once "after a while"...
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(g_maplocalhost_mutex)
Network ConnectedThroughNetwork() const
Get network the peer connected through.
bool Good(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
Mark an address record as accessible and attempt to move it to addrman's tried table.
std::chrono::microseconds m_time
time of message receipt
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
static path u8path(const std::string &utf8_str)
virtual int GetSockName(sockaddr *name, socklen_t *name_len) const
getsockname(2) wrapper.
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
const NetGroupManager & m_netgroupman
std::atomic< uint64_t > nTotalBytesRecv
Auxiliary requested/occurred events to wait for in WaitMany().
const std::string m_addr_name
std::unique_ptr< CSemaphore > semAddnode
std::unique_ptr< Sock > sock
Connected socket.
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
bool IsInboundConn() const
bool m_use_addrman_outgoing
std::vector< NetWhitebindPermissions > vWhiteBinds
bool error(const char *fmt, const Args &... args)
CHash256 & Write(Span< const unsigned char > input)
void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat f until the scheduler is stopped.
std::unique_ptr< i2p::sam::Session > i2p_sam_session
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0...
Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive).
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
uint64_t GetOutboundTargetBytesLeft() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
m_max_outbound_full_relay
Cache responses to addr requests to minimize privacy leak.
std::vector< unsigned char > GetAddrBytes() const
void RemoveLocal(const CService &addr)
We use block-relay-only connections to help prevent against partition attacks.
bool IsLocal(const CService &addr)
check whether a given address is potentially local
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
void CopyStats(CNodeStats &stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
Addresses from these networks are not publicly routable on the global Internet.
void SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)