Merge 42f98c9dfab03a4423038884df4f74a7954a3bb6 into 5f4422d68dc3530c353af1f87499de1c864b60ad

This commit is contained in:
Vasil Dimov 2025-03-17 09:50:15 +07:00 committed by GitHub
commit 517a84d3db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 4 deletions

View File

@ -131,6 +131,13 @@ Session::Session(const Proxy& control_host, CThreadInterrupt* interrupt)
m_interrupt{interrupt},
m_transient{true}
{
try {
LOCK(m_mutex);
CreateIfNotCreatedAlready();
} catch (const std::runtime_error&) {
// This was just an eager optimistic attempt to create the session.
// If it fails, then it will be reattempted again when `Connect()` is called.
}
}
Session::~Session()

View File

@ -455,6 +455,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
connect_to.push_back(addrConnect);
}
AddI2PSessionsIfNeeded();
// Connect
std::unique_ptr<Sock> sock;
Proxy proxy;
@ -474,16 +476,18 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (m_i2p_sam_session) {
connected = m_i2p_sam_session->Connect(target_addr, conn, proxyConnectionFailed);
} else {
// Use an existent transient session, if one was created earlier...
{
LOCK(m_unused_i2p_sessions_mutex);
if (m_unused_i2p_sessions.empty()) {
i2p_transient_session =
std::make_unique<i2p::sam::Session>(proxy, &interruptNet);
} else {
if (!m_unused_i2p_sessions.empty()) {
i2p_transient_session.swap(m_unused_i2p_sessions.front());
m_unused_i2p_sessions.pop();
}
}
// ... or create a new one if m_unused_i2p_sessions was empty.
if (!i2p_transient_session) {
i2p_transient_session = std::make_unique<i2p::sam::Session>(proxy, &interruptNet);
}
connected = i2p_transient_session->Connect(target_addr, conn, proxyConnectionFailed);
if (!connected) {
LOCK(m_unused_i2p_sessions_mutex);
@ -3237,6 +3241,28 @@ uint16_t CConnman::GetDefaultPort(const std::string& addr) const
return a.SetSpecial(addr) ? GetDefaultPort(a.GetNetwork()) : m_params.GetDefaultPort();
}
void CConnman::AddI2PSessionsIfNeeded()
{
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
Proxy i2p_proxy;
if (!g_reachable_nets.Contains(NET_I2P) || // Not using I2P at all.
m_i2p_sam_session || // Using a single persistent session, m_unused_i2p_sessions is not used.
WITH_LOCK(m_unused_i2p_sessions_mutex, return m_unused_i2p_sessions.size() >= MAX_UNUSED_I2P_SESSIONS_SIZE) || // Already have enough sessions.
!GetProxy(NET_I2P, i2p_proxy)) {
return;
}
// It is preferable to slightly exceed MAX_UNUSED_I2P_SESSIONS_SIZE compared to holding
// m_unused_i2p_sessions_mutex while creating the session which could take a few seconds.
auto new_session = std::make_unique<i2p::sam::Session>(i2p_proxy, &interruptNet);
LOCK(m_unused_i2p_sessions_mutex);
m_unused_i2p_sessions.emplace(std::move(new_session));
}
bool CConnman::Bind(const CService& addr_, unsigned int flags, NetPermissionFlags permissions)
{
const CService addr{MaybeFlipIPv6toCJDNS(addr_)};

View File

@ -1408,6 +1408,11 @@ private:
uint16_t GetDefaultPort(Network net) const;
uint16_t GetDefaultPort(const std::string& addr) const;
/**
* Add entries to `m_unused_i2p_sessions` if needed.
*/
void AddI2PSessionsIfNeeded() EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
// Network usage totals
mutable Mutex m_total_bytes_sent_mutex;
std::atomic<uint64_t> nTotalBytesRecv{0};