41
41
#include < functional>
42
42
#include < map>
43
43
#include < memory>
44
- #include < thread>
45
44
#include < optional>
46
45
#include < queue>
46
+ #include < thread>
47
47
#include < vector>
48
48
49
49
class CConnman ;
@@ -925,9 +925,9 @@ friend class CNode;
925
925
const char * strDest, ConnectionType conn_type,
926
926
MasternodeConn masternode_connection = MasternodeConn::IsNotConnection,
927
927
MasternodeProbeConn masternode_probe_connection = MasternodeProbeConn::IsNotConnection)
928
- EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
928
+ EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex, ! mutexMsgProc);
929
929
void OpenMasternodeConnection (const CAddress& addrConnect, MasternodeProbeConn probe = MasternodeProbeConn::IsConnection)
930
- EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
930
+ EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex, ! mutexMsgProc);
931
931
bool CheckIncomingNonce (uint64_t nonce);
932
932
933
933
struct CFullyConnectedOnly {
@@ -1125,7 +1125,8 @@ friend class CNode;
1125
1125
* - Max total outbound connection capacity filled
1126
1126
* - Max connection capacity for type is filled
1127
1127
*/
1128
- bool AddConnection (const std::string& address, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
1128
+ bool AddConnection (const std::string& address, ConnectionType conn_type)
1129
+ EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex, !mutexMsgProc);
1129
1130
1130
1131
bool AddPendingMasternode (const uint256& proTxHash);
1131
1132
void SetMasternodeQuorumNodes (Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set<uint256>& proTxHashes);
@@ -1231,11 +1232,13 @@ friend class CNode;
1231
1232
const std::vector<NetWhitebindPermissions>& whiteBinds,
1232
1233
const std::vector<CService>& onion_binds);
1233
1234
1234
- void ThreadOpenAddedConnections () EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !mutexMsgProc);
1235
+ void ThreadOpenAddedConnections ()
1236
+ EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_unused_i2p_sessions_mutex, !mutexMsgProc);
1235
1237
void AddAddrFetch (const std::string& strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex);
1236
- void ProcessAddrFetch () EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !mutexMsgProc);
1238
+ void ProcessAddrFetch ()
1239
+ EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_unused_i2p_sessions_mutex, !mutexMsgProc);
1237
1240
void ThreadOpenConnections (const std::vector<std::string> connect, CDeterministicMNManager& dmnman)
1238
- EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex, !mutexMsgProc);
1241
+ EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex, !m_unused_i2p_sessions_mutex, ! mutexMsgProc);
1239
1242
void ThreadMessageHandler () EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
1240
1243
void ThreadI2PAcceptIncoming (CMasternodeSync& mn_sync) EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
1241
1244
void AcceptConnection (const ListenSocket& hListenSocket, CMasternodeSync& mn_sync)
@@ -1341,7 +1344,7 @@ friend class CNode;
1341
1344
void ThreadDNSAddressSeed () EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_nodes_mutex);
1342
1345
void ThreadOpenMasternodeConnections (CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman,
1343
1346
CMasternodeSync& mn_sync)
1344
- EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_nodes_mutex, !mutexMsgProc);
1347
+ EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_nodes_mutex, !m_unused_i2p_sessions_mutex, ! mutexMsgProc);
1345
1348
1346
1349
uint64_t CalculateKeyedNetGroup (const CAddress& ad) const ;
1347
1350
@@ -1357,7 +1360,8 @@ friend class CNode;
1357
1360
bool AlreadyConnectedToAddress (const CAddress& addr);
1358
1361
1359
1362
bool AttemptToEvictConnection ();
1360
- CNode* ConnectNode (CAddress addrConnect, const char *pszDest = nullptr , bool fCountFailure = false , ConnectionType conn_type = ConnectionType::OUTBOUND_FULL_RELAY);
1363
+ CNode* ConnectNode (CAddress addrConnect, const char *pszDest = nullptr , bool fCountFailure = false , ConnectionType conn_type = ConnectionType::OUTBOUND_FULL_RELAY)
1364
+ EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
1361
1365
void AddWhitelistPermissionFlags (NetPermissionFlags& flags, const CNetAddr &addr) const ;
1362
1366
1363
1367
void DeleteNode (CNode* pnode);
@@ -1563,6 +1567,26 @@ friend class CNode;
1563
1567
*/
1564
1568
std::vector<CService> m_onion_binds;
1565
1569
1570
+ /* *
1571
+ * Mutex protecting m_i2p_sam_sessions.
1572
+ */
1573
+ Mutex m_unused_i2p_sessions_mutex;
1574
+
1575
+ /* *
1576
+ * A pool of created I2P SAM transient sessions that should be used instead
1577
+ * of creating new ones in order to reduce the load on the I2P network.
1578
+ * Creating a session in I2P is not cheap, thus if this is not empty, then
1579
+ * pick an entry from it instead of creating a new session. If connecting to
1580
+ * a host fails, then the created session is put to this pool for reuse.
1581
+ */
1582
+ std::queue<std::unique_ptr<i2p::sam::Session>> m_unused_i2p_sessions GUARDED_BY (m_unused_i2p_sessions_mutex);
1583
+
1584
+ /* *
1585
+ * Cap on the size of `m_unused_i2p_sessions`, to ensure it does not
1586
+ * unexpectedly use too much memory.
1587
+ */
1588
+ static constexpr size_t MAX_UNUSED_I2P_SESSIONS_SIZE{10 };
1589
+
1566
1590
friend struct CConnmanTest ;
1567
1591
friend struct ConnmanTestMsg ;
1568
1592
};
0 commit comments