Skip to content

Commit a0ab1c7

Browse files
achow101vijaydasmp
authored andcommitted
Merge bitcoin#28464: net: improve max-connection limits code
df69b22 doc: improve documentation around connection limit maximums (Amiti Uttarwar) adc171e scripted-diff: Rename connection limit variables (Amiti Uttarwar) e9fd9c0 net: add m_max_inbound to connman (Amiti Uttarwar) c25e0e0 net, refactor: move calculations for connection type limits into connman (Amiti Uttarwar) Pull request description: This is joint work with amitiuttarwar. This has the first few commits of bitcoin#28463. It is not strictly a prerequisite for that, but has changes that in our opinion make sense on their own. It improves the handling of maximum numbers for different connection types (that are set during init and don’t change after) by: * moving all calculations into one place, `CConnMan::Init()`. Before, they were dispersed between `Init`, `CConnman::Init` and other parts of `CConnman`, resulting in some duplicated test code. * removing the possibility of having a negative maximum of inbound connections, which is hard to argue about * renaming of variables and doc improvements ACKs for top commit: amitiuttarwar: co-author review ACK df69b22 naumenkogs: ACK df69b22 achow101: ACK df69b22 Tree-SHA512: 913d56136bc1df739978de50db67302f88bac2a9d34748ae96763288d97093e998fc0f94f9b6eff12867712d7e86225af6128f4170bf2b5b8ab76f024870a22c
1 parent b41a35f commit a0ab1c7

File tree

4 files changed

+35
-36
lines changed

4 files changed

+35
-36
lines changed

src/init.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ void SetupServerArgs(ArgsManager& argsman)
611611
argsman.AddArg("-forcednsseed", strprintf("Always query for peer addresses via DNS lookup (default: %u)", DEFAULT_FORCEDNSSEED), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
612612
argsman.AddArg("-listen", strprintf("Accept connections from outside (default: %u if no -proxy, -connect or -maxconnections=0)", DEFAULT_LISTEN), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
613613
argsman.AddArg("-listenonion", strprintf("Automatically create Tor onion service (default: %d)", DEFAULT_LISTEN_ONION), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
614-
argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> connections to peers (temporary service connections excluded) (default: %u). This limit does not apply to connections manually added via -addnode or the addnode RPC, which have a separate limit of %u.", DEFAULT_MAX_PEER_CONNECTIONS, MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
614+
argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> automatic connections to peers (temporary service connections excluded) (default: %u). This limit does not apply to connections manually added via -addnode or the addnode RPC, which have a separate limit of %u.", DEFAULT_MAX_PEER_CONNECTIONS, MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
615615
argsman.AddArg("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
616616
argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection memory usage for the send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
617617
argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by outbound peers forward or backward by this amount (default: %u seconds).", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@@ -2532,12 +2532,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
25322532

25332533
CConnman::Options connOptions;
25342534
connOptions.nLocalServices = nLocalServices;
2535-
connOptions.nMaxConnections = nMaxConnections;
2536-
connOptions.m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, connOptions.nMaxConnections);
2537-
connOptions.m_max_outbound_block_relay = std::min(MAX_BLOCK_RELAY_ONLY_CONNECTIONS, connOptions.nMaxConnections-connOptions.m_max_outbound_full_relay);
2538-
connOptions.m_max_outbound_onion = std::min(MAX_DESIRED_ONION_CONNECTIONS, connOptions.nMaxConnections / 2);
2539-
connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
2540-
connOptions.nMaxFeeler = MAX_FEELER_CONNECTIONS;
2535+
connOptions.m_max_outbound_onion = std::min(MAX_DESIRED_ONION_CONNECTIONS, connOptions.m_max_automatic_connections / 2);
2536+
connOptions.m_max_automatic_connections = nMaxConnections;
25412537
connOptions.uiInterface = &uiInterface;
25422538
connOptions.m_banman = node.banman.get();
25432539
connOptions.m_msgproc = node.peerman.get();

src/net.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,6 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
18861886
{
18871887
int nInbound = 0;
18881888
int nVerifiedInboundMasternodes = 0;
1889-
int nMaxInbound = nMaxConnections - m_max_outbound;
18901889

18911890
AddWhitelistPermissionFlags(permission_flags, addr);
18921891
if (NetPermissions::HasFlag(permission_flags, NetPermissionFlags::Implicit)) {
@@ -1945,7 +1944,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
19451944

19461945
// Only accept connections from discouraged peers if our inbound slots aren't (almost) full.
19471946
bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1948-
if (!NetPermissions::HasFlag(permission_flags, NetPermissionFlags::NoBan) && nInbound + 1 >= nMaxInbound && discouraged)
1947+
if (!NetPermissions::HasFlag(permission_flags, NetPermissionFlags::NoBan) && nInbound + 1 >= m_max_inbound && discouraged)
19491948
{
19501949
LogPrint(BCLog::NET_NETCONN, "connection from %s dropped (discouraged)\n", addr.ToStringAddrPort());
19511950
return;
@@ -1956,7 +1955,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
19561955
// We don't evict verified MN connections and also don't take them into account when checking limits. We can do this
19571956
// because we know that such connections are naturally limited by the total number of MNs, so this is not usable
19581957
// for attacks.
1959-
while (nInbound - nVerifiedInboundMasternodes >= nMaxInbound)
1958+
while (nInbound - nVerifiedInboundMasternodes >= m_max_inbound)
19601959
{
19611960
if (!AttemptToEvictConnection()) {
19621961
// No connection to evict, disconnect the new connection
@@ -3276,7 +3275,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
32763275
// different netgroups in ipv4/ipv6 networks + all peers in Tor/I2P/CJDNS networks.
32773276
// Don't record addrman failure attempts when node is offline. This can be identified since all local
32783277
// network connections (if any) belong in the same netgroup, and the size of `outbound_ipv46_peer_netgroups` would only be 1.
3279-
const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(nMaxConnections - 1, 2)};
3278+
const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(m_max_automatic_connections - 1, 2)};
32803279
// Use BIP324 transport when both us and them have NODE_V2_P2P set.
32813280
const bool use_v2transport(addrConnect.nServices & GetLocalServices() & NODE_P2P_V2);
32823281
OpenNetworkConnection(addrConnect, count_failures, std::move(grant), /*strDest=*/nullptr, conn_type, use_v2transport);
@@ -4019,11 +4018,11 @@ bool CConnman::Start(CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_met
40194018

40204019
if (semOutbound == nullptr) {
40214020
// initialize semaphore
4022-
semOutbound = std::make_unique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
4021+
semOutbound = std::make_unique<CSemaphore>(std::min(m_max_automatic_outbound, m_max_automatic_connections));
40234022
}
40244023
if (semAddnode == nullptr) {
40254024
// initialize semaphore
4026-
semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
4025+
semAddnode = std::make_unique<CSemaphore>(m_max_addnode);
40274026
}
40284027

40294028
//
@@ -4125,13 +4124,13 @@ void CConnman::Interrupt()
41254124
g_socks5_interrupt();
41264125

41274126
if (semOutbound) {
4128-
for (int i=0; i<m_max_outbound; i++) {
4127+
for (int i=0; i<m_max_automatic_outbound; i++) {
41294128
semOutbound->post();
41304129
}
41314130
}
41324131

41334132
if (semAddnode) {
4134-
for (int i=0; i<nMaxAddnode; i++) {
4133+
for (int i=0; i<m_max_addnode; i++) {
41354134
semAddnode->post();
41364135
}
41374136
}

src/net.h

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,12 +1185,8 @@ friend class CNode;
11851185
struct Options
11861186
{
11871187
ServiceFlags nLocalServices = NODE_NONE;
1188-
int nMaxConnections = 0;
1189-
int m_max_outbound_full_relay = 0;
1190-
int m_max_outbound_block_relay = 0;
11911188
int m_max_outbound_onion = 0;
1192-
int nMaxAddnode = 0;
1193-
int nMaxFeeler = 0;
1189+
int m_max_automatic_connections = 0;
11941190
CClientUIInterface* uiInterface = nullptr;
11951191
NetEventsInterface* m_msgproc = nullptr;
11961192
BanMan* m_banman = nullptr;
@@ -1219,14 +1215,13 @@ friend class CNode;
12191215
AssertLockNotHeld(m_total_bytes_sent_mutex);
12201216

12211217
nLocalServices = connOptions.nLocalServices;
1222-
nMaxConnections = connOptions.nMaxConnections;
1223-
m_max_outbound_full_relay = std::min(connOptions.m_max_outbound_full_relay, connOptions.nMaxConnections);
1224-
m_max_outbound_block_relay = connOptions.m_max_outbound_block_relay;
1218+
m_max_automatic_connections = connOptions.m_max_automatic_connections;
1219+
m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, m_max_automatic_connections);
1220+
m_max_outbound_block_relay = std::min(MAX_BLOCK_RELAY_ONLY_CONNECTIONS, m_max_automatic_connections - m_max_outbound_full_relay);
1221+
m_max_automatic_outbound = m_max_outbound_full_relay + m_max_outbound_block_relay + m_max_feeler;
1222+
m_max_inbound = std::max(0, m_max_automatic_connections - m_max_automatic_outbound);
12251223
m_max_outbound_onion = connOptions.m_max_outbound_onion;
12261224
m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing;
1227-
nMaxAddnode = connOptions.nMaxAddnode;
1228-
nMaxFeeler = connOptions.nMaxFeeler;
1229-
m_max_outbound = m_max_outbound_full_relay + m_max_outbound_block_relay + nMaxFeeler;
12301225
m_client_interface = connOptions.uiInterface;
12311226
m_banman = connOptions.m_banman;
12321227
m_msgproc = connOptions.m_msgproc;
@@ -1829,7 +1824,18 @@ friend class CNode;
18291824

18301825
std::unique_ptr<CSemaphore> semOutbound;
18311826
std::unique_ptr<CSemaphore> semAddnode;
1832-
int nMaxConnections;
1827+
1828+
/**
1829+
* Maximum number of automatic connections permitted, excluding manual
1830+
* connections but including inbounds. May be changed by the user and is
1831+
* potentially limited by the operating system (number of file descriptors).
1832+
*/
1833+
int m_max_automatic_connections;
1834+
1835+
/*
1836+
* Maximum number of peers by connection type. Might vary from defaults
1837+
* based on -maxconnections init value.
1838+
*/
18331839

18341840
// How many full-relay (tx, block, addr) outbound peers we want
18351841
int m_max_outbound_full_relay;
@@ -1841,9 +1847,11 @@ friend class CNode;
18411847
// How many onion outbound peers we want; don't care if full or block only; does not increase m_max_outbound
18421848
int m_max_outbound_onion;
18431849

1844-
int nMaxAddnode;
1845-
int nMaxFeeler;
1846-
int m_max_outbound;
1850+
int m_max_addnode{MAX_ADDNODE_CONNECTIONS};
1851+
int m_max_feeler{MAX_FEELER_CONNECTIONS};
1852+
int m_max_automatic_outbound;
1853+
int m_max_inbound;
1854+
18471855
bool m_use_addrman_outgoing;
18481856
CClientUIInterface* m_client_interface;
18491857
NetEventsInterface* m_msgproc;

src/test/denialofservice_tests.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
150150

151151
constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
152152
CConnman::Options options;
153-
options.nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
154-
options.m_max_outbound_full_relay = max_outbound_full_relay;
155-
options.nMaxFeeler = MAX_FEELER_CONNECTIONS;
153+
options.m_max_automatic_connections = DEFAULT_MAX_PEER_CONNECTIONS;
156154

157155
const auto time_init{GetTime<std::chrono::seconds>()};
158156
SetMockTime(time_init);
@@ -252,9 +250,7 @@ BOOST_AUTO_TEST_CASE(block_relay_only_eviction)
252250
constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS};
253251
constexpr int64_t MINIMUM_CONNECT_TIME{30};
254252
CConnman::Options options;
255-
options.nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
256-
options.m_max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
257-
options.m_max_outbound_block_relay = max_outbound_block_relay;
253+
options.m_max_automatic_connections = DEFAULT_MAX_PEER_CONNECTIONS;
258254

259255
connman->Init(options);
260256
std::vector<CNode*> vNodes;

0 commit comments

Comments
 (0)