mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 14:38:29 +01:00
i2p: reuse created I2P sessions if not used
In the case of `i2pacceptincoming=0` we use transient addresses (destinations) for ourselves for each outbound connection. It may happen that we * create the session (and thus our address/destination too) * fail to connect to the particular peer (e.g. if they are offline) * dispose the unused session. This puts unnecessary load on the I2P network because session creation is not cheap. Is exaggerated if `onlynet=i2p` is used in which case we will be trying to connect to I2P peers more often. To help with this, save the created but unused sessions and pick them later instead of creating new ones. Alleviates: https://github.com/bitcoin/bitcoin/issues/26754
This commit is contained in:
23
src/net.cpp
23
src/net.cpp
@@ -436,6 +436,7 @@ static CAddress GetBindAddress(const Sock& sock)
|
||||
|
||||
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
assert(conn_type != ConnectionType::INBOUND);
|
||||
|
||||
if (pszDest == nullptr) {
|
||||
@@ -496,8 +497,23 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||
if (m_i2p_sam_session) {
|
||||
connected = m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed);
|
||||
} else {
|
||||
i2p_transient_session = std::make_unique<i2p::sam::Session>(proxy.proxy, &interruptNet);
|
||||
{
|
||||
LOCK(m_unused_i2p_sessions_mutex);
|
||||
if (m_unused_i2p_sessions.empty()) {
|
||||
i2p_transient_session =
|
||||
std::make_unique<i2p::sam::Session>(proxy.proxy, &interruptNet);
|
||||
} else {
|
||||
i2p_transient_session.swap(m_unused_i2p_sessions.front());
|
||||
m_unused_i2p_sessions.pop();
|
||||
}
|
||||
}
|
||||
connected = i2p_transient_session->Connect(addrConnect, conn, proxyConnectionFailed);
|
||||
if (!connected) {
|
||||
LOCK(m_unused_i2p_sessions_mutex);
|
||||
if (m_unused_i2p_sessions.size() < MAX_UNUSED_I2P_SESSIONS_SIZE) {
|
||||
m_unused_i2p_sessions.emplace(i2p_transient_session.release());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connected) {
|
||||
@@ -1047,6 +1063,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
||||
|
||||
bool CConnman::AddConnection(const std::string& address, ConnectionType conn_type)
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
std::optional<int> max_connections;
|
||||
switch (conn_type) {
|
||||
case ConnectionType::INBOUND:
|
||||
@@ -1509,6 +1526,7 @@ void CConnman::DumpAddresses()
|
||||
|
||||
void CConnman::ProcessAddrFetch()
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
std::string strDest;
|
||||
{
|
||||
LOCK(m_addr_fetches_mutex);
|
||||
@@ -1577,6 +1595,7 @@ int CConnman::GetExtraBlockRelayCount() const
|
||||
|
||||
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
SetSyscallSandboxPolicy(SyscallSandboxPolicy::NET_OPEN_CONNECTION);
|
||||
FastRandomContext rng;
|
||||
// Connect to specific addresses
|
||||
@@ -1928,6 +1947,7 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() const
|
||||
|
||||
void CConnman::ThreadOpenAddedConnections()
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
SetSyscallSandboxPolicy(SyscallSandboxPolicy::NET_ADD_CONNECTION);
|
||||
while (true)
|
||||
{
|
||||
@@ -1957,6 +1977,7 @@ void CConnman::ThreadOpenAddedConnections()
|
||||
// if successful, this moves the passed grant to the constructed node
|
||||
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
assert(conn_type != ConnectionType::INBOUND);
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user