v31.1-roots.1 · Commit 5: [PATCH 05/17] feat(net): preserve Roots peer controls and health view on v31
src/net.cpp
Before: src/net.cpp · After: src/net.cpp
File metadata
index 5c28efade891a8e412d358280e815fad2e367935..930fdc93475c267ab4f93f6839376dcddcec0226 100644
Download original patch · Release notes
Diff rows 1–137 of 137. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
src/net.cpp
CHANGED
|
@@ -320,7 +320,7 @@ bool SeenLocal(const CService& addr)
|
|
|
320
320
|
LOCK(g_maplocalhost_mutex);
|
|
321
321
|
const auto it = mapLocalHost.find(addr);
|
|
322
322
|
if (it == mapLocalHost.end()) return false;
|
|
323
|
-
++it->second.nScore;
|
|
323
|
+
if (it->second.nScore < std::numeric_limits<int>::max()) ++it->second.nScore;
|
|
324
324
|
return true;
|
|
325
325
|
}
|
|
326
326
|
|
|
@@ -440,6 +440,10 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
|
|
|
440
440
|
std::unique_ptr<i2p::sam::Session> i2p_transient_session;
|
|
441
441
|
|
|
442
442
|
for (auto& target_addr: connect_to) {
|
|
443
|
+
if (!use_v2transport && DisableV1OnClearnet(target_addr.GetNetClass())) {
|
|
444
|
+
LogDebug(BCLog::NET, "outbound v1 disabled on clearnet\n");
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
443
447
|
if (target_addr.IsValid()) {
|
|
444
448
|
bool use_proxy;
|
|
445
449
|
if (proxy_override.has_value()) {
|
|
@@ -511,8 +515,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
|
|
|
511
515
|
}
|
|
512
516
|
|
|
513
517
|
NetPermissionFlags permission_flags = NetPermissionFlags::None;
|
|
514
|
-
std::vector<NetWhitelistPermissions> whitelist_permissions = conn_type == ConnectionType::MANUAL ? vWhitelistedRangeOutgoing : std::vector<NetWhitelistPermissions>{};
|
|
515
|
-
AddWhitelistPermissionFlags(permission_flags, target_addr, whitelist_permissions);
|
|
518
|
+
AddWhitelistPermissionFlags(permission_flags, target_addr, vWhitelistedRangeOutgoing);
|
|
516
519
|
|
|
517
520
|
// Add node
|
|
518
521
|
NodeId id = GetNewNodeId();
|
|
@@ -585,6 +588,7 @@ void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, std::optio
|
|
|
585
588
|
if (whitelist_relay) NetPermissions::AddFlag(flags, NetPermissionFlags::Relay);
|
|
586
589
|
NetPermissions::AddFlag(flags, NetPermissionFlags::Mempool);
|
|
587
590
|
NetPermissions::AddFlag(flags, NetPermissionFlags::NoBan);
|
|
591
|
+
NetPermissions::AddFlag(flags, NetPermissionFlags::Addr);
|
|
588
592
|
}
|
|
589
593
|
}
|
|
590
594
|
|
|
@@ -658,6 +662,8 @@ void CNode::CopyStats(CNodeStats& stats)
|
|
|
658
662
|
stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToStringAddrPort() : "";
|
|
659
663
|
|
|
660
664
|
X(m_conn_type);
|
|
665
|
+
X(m_forced_inbound);
|
|
666
|
+
stats.m_cpu_time = std::chrono::nanoseconds{m_cpu_time.load()};
|
|
661
667
|
}
|
|
662
668
|
#undef X
|
|
663
669
|
|
|
@@ -1685,7 +1691,7 @@ std::pair<size_t, bool> CConnman::SocketSendData(CNode& node) const
|
|
|
1685
1691
|
* to forge. In order to partition a node the attacker must be
|
|
1686
1692
|
* simultaneously better at all of them than honest peers.
|
|
1687
1693
|
*/
|
|
1688
|
-
bool CConnman::AttemptToEvictConnection()
|
|
1694
|
+
bool CConnman::AttemptToEvictConnection(bool force)
|
|
1689
1695
|
{
|
|
1690
1696
|
std::vector<NodeEvictionCandidate> vEvictionCandidates;
|
|
1691
1697
|
{
|
|
@@ -1713,7 +1719,7 @@ bool CConnman::AttemptToEvictConnection()
|
|
|
1713
1719
|
vEvictionCandidates.push_back(candidate);
|
|
1714
1720
|
}
|
|
1715
1721
|
}
|
|
1716
|
-
const std::optional<NodeId> node_id_to_evict = SelectNodeToEvict(std::move(vEvictionCandidates));
|
|
1722
|
+
const std::optional<NodeId> node_id_to_evict = SelectNodeToEvict(std::move(vEvictionCandidates), force);
|
|
1717
1723
|
if (!node_id_to_evict) {
|
|
1718
1724
|
return false;
|
|
1719
1725
|
}
|
|
@@ -1769,7 +1775,14 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
|
|
1769
1775
|
{
|
|
1770
1776
|
int nInbound = 0;
|
|
1771
1777
|
|
|
1772
|
-
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
|
|
1778
|
+
const bool inbound_onion = [this, &addr, &addr_bind] {
|
|
1779
|
+
if (!m_onion_binds.empty()) {
|
|
1780
|
+
return std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
|
|
1781
|
+
}
|
|
1782
|
+
if (!m_listenonion || m_normal_binds.empty() || addr_bind != m_normal_binds.front()) return false;
|
|
1783
|
+
// A wildcard first bind shares Tor only with local proxy connections.
|
|
1784
|
+
return !addr_bind.IsBindAny() || addr.IsLocal();
|
|
1785
|
+
}();
|
|
1773
1786
|
|
|
1774
1787
|
// Tor inbound connections do not reveal the peer's actual network address.
|
|
1775
1788
|
// Therefore do not apply address-based whitelist permissions to them.
|
|
@@ -1816,13 +1829,15 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
|
|
1816
1829
|
return;
|
|
1817
1830
|
}
|
|
1818
1831
|
|
|
1832
|
+
bool forced{false};
|
|
1819
1833
|
if (nInbound >= m_max_inbound)
|
|
1820
1834
|
{
|
|
1821
|
-
if (!AttemptToEvictConnection()) {
|
|
1835
|
+
if (!AttemptToEvictConnection(NetPermissions::HasFlag(permission_flags, NetPermissionFlags::ForceInbound))) {
|
|
1822
1836
|
// No connection to evict, disconnect the new connection
|
|
1823
1837
|
LogDebug(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
|
|
1824
1838
|
return;
|
|
1825
1839
|
}
|
|
1840
|
+
forced = true;
|
|
1826
1841
|
}
|
|
1827
1842
|
|
|
1828
1843
|
NodeId id = GetNewNodeId();
|
|
@@ -1851,6 +1866,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
|
|
1851
1866
|
CNodeOptions{
|
|
1852
1867
|
.permission_flags = permission_flags,
|
|
1853
1868
|
.prefer_evict = discouraged,
|
|
1869
|
+
.forced_inbound = forced,
|
|
1854
1870
|
.recv_flood_size = nReceiveFloodSize,
|
|
1855
1871
|
.use_v2transport = use_v2transport,
|
|
1856
1872
|
});
|
|
@@ -1951,7 +1967,7 @@ void CConnman::DisconnectNodes()
|
|
|
1951
1967
|
// Add to reconnection list if appropriate. We don't reconnect right here, because
|
|
1952
1968
|
// the creation of a connection is a blocking operation (up to several seconds),
|
|
1953
1969
|
// and we don't want to hold up the socket handler thread for that long.
|
|
1954
|
-
if (network_active && pnode->m_transport->ShouldReconnectV1()) {
|
|
1970
|
+
if (network_active && pnode->m_transport->ShouldReconnectV1() && !DisableV1OnClearnet(pnode->addr.GetNetClass())) {
|
|
1955
1971
|
reconnections_to_add.push_back({
|
|
1956
1972
|
.proxy_override = pnode->m_proxy_override,
|
|
1957
1973
|
.addr_connect = pnode->addr,
|
|
@@ -3172,6 +3188,8 @@ void CConnman::ThreadMessageHandler()
|
|
|
3172
3188
|
if (pnode->fDisconnect)
|
|
3173
3189
|
continue;
|
|
3174
3190
|
|
|
3191
|
+
CpuTimer timer{[pnode](std::chrono::nanoseconds elapsed) { pnode->m_cpu_time.fetch_add(elapsed.count(), std::memory_order_relaxed); }};
|
|
3192
|
+
|
|
3175
3193
|
// Receive messages
|
|
3176
3194
|
bool fMoreNodeWork{m_msgproc->ProcessMessages(*pnode, flagInterruptMsgProc)};
|
|
3177
3195
|
fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
|
|
@@ -3764,12 +3782,14 @@ std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addres
|
|
|
3764
3782
|
|
|
3765
3783
|
bool CConnman::AddNode(const AddedNodeParams& add)
|
|
3766
3784
|
{
|
|
3767
|
-
const CService resolved(LookupNumeric(add.m_added_node, GetDefaultPort(add.m_added_node)));
|
|
3768
|
-
const bool resolved_is_valid{resolved.IsValid()};
|
|
3769
|
-
|
|
3785
|
+
const CService resolved{MaybeFlipIPv6toCJDNS(LookupNumeric(add.m_added_node, GetDefaultPort(add.m_added_node)))};
|
|
3770
3786
|
LOCK(m_added_nodes_mutex);
|
|
3771
3787
|
for (const auto& it : m_added_node_params) {
|
|
3772
|
-
if (add.m_added_node == it.m_added_node || (resolved_is_valid && resolved == LookupNumeric(it.m_added_node, GetDefaultPort(it.m_added_node)))) return false;
|
|
3788
|
+
if (add.m_added_node == it.m_added_node) return false;
|
|
3789
|
+
if (!resolved.IsValid()) continue;
|
|
3790
|
+
const CService service{MaybeFlipIPv6toCJDNS(LookupNumeric(it.m_added_node, GetDefaultPort(it.m_added_node)))};
|
|
3791
|
+
if (resolved == service) return false;
|
|
3792
|
+
if (resolved.IsCJDNS() && static_cast<CNetAddr>(resolved) == static_cast<CNetAddr>(service)) return false;
|
|
3773
3793
|
}
|
|
3774
3794
|
|
|
3775
3795
|
m_added_node_params.push_back(add);
|
|
@@ -4019,6 +4039,7 @@ CNode::CNode(NodeId idIn,
|
|
|
4019
4039
|
m_addr_name{addrNameIn.empty() ? addr.ToStringAddrPort() : addrNameIn},
|
|
4020
4040
|
m_dest(addrNameIn),
|
|
4021
4041
|
m_inbound_onion{inbound_onion},
|
|
4042
|
+
m_forced_inbound{node_opts.forced_inbound},
|
|
4022
4043
|
m_prefer_evict{node_opts.prefer_evict},
|
|
4023
4044
|
nKeyedNetGroup{nKeyedNetGroupIn},
|
|
4024
4045
|
m_network_key{network_key},
|