net: store an optional I2P session in CNode

and destroy it when `CNode::m_sock` is closed.

I2P transient sessions are created per connection (i.e. per `CNode`) and
should be destroyed when the connection is closed. Storing the session
in `CNode` is a convenient way to destroy it together with the connection
socket (`CNode::m_sock`).

An alternative approach would be to store a list of all I2P sessions in
`CConnman` and from `CNode::CloseSocketDisconnect()` to somehow ask the
`CConnman` to destroy the relevant session.
This commit is contained in:
Vasil Dimov 2022-06-08 17:26:24 +02:00
parent 2b781ad66e
commit a1580a04f5
No known key found for this signature in database
GPG Key ID: 54DF06F64B55CBBF
2 changed files with 41 additions and 15 deletions

View File

@ -564,6 +564,7 @@ void CNode::CloseSocketDisconnect()
LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
m_sock.reset();
}
m_i2p_sam_session.reset();
}
void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const {
@ -2702,20 +2703,27 @@ ServiceFlags CConnman::GetLocalServices() const
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
CNode::CNode(NodeId idIn, std::shared_ptr<Sock> sock, const CAddress& addrIn,
uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
const CAddress& addrBindIn, const std::string& addrNameIn,
ConnectionType conn_type_in, bool inbound_onion)
CNode::CNode(NodeId idIn,
std::shared_ptr<Sock> sock,
const CAddress& addrIn,
uint64_t nKeyedNetGroupIn,
uint64_t nLocalHostNonceIn,
const CAddress& addrBindIn,
const std::string& addrNameIn,
ConnectionType conn_type_in,
bool inbound_onion,
std::unique_ptr<i2p::sam::Session>&& i2p_sam_session)
: m_sock{sock},
m_connected{GetTime<std::chrono::seconds>()},
addr(addrIn),
addrBind(addrBindIn),
addr{addrIn},
addrBind{addrBindIn},
m_addr_name{addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn},
m_inbound_onion(inbound_onion),
nKeyedNetGroup(nKeyedNetGroupIn),
id(idIn),
nLocalHostNonce(nLocalHostNonceIn),
m_conn_type(conn_type_in)
m_inbound_onion{inbound_onion},
nKeyedNetGroup{nKeyedNetGroupIn},
id{idIn},
nLocalHostNonce{nLocalHostNonceIn},
m_conn_type{conn_type_in},
m_i2p_sam_session{std::move(i2p_sam_session)}
{
if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND);

View File

@ -513,10 +513,16 @@ public:
* criterium in CConnman::AttemptToEvictConnection. */
std::atomic<std::chrono::microseconds> m_min_ping_time{std::chrono::microseconds::max()};
CNode(NodeId id, std::shared_ptr<Sock> sock, const CAddress& addrIn,
uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
const CAddress& addrBindIn, const std::string& addrNameIn,
ConnectionType conn_type_in, bool inbound_onion);
CNode(NodeId id,
std::shared_ptr<Sock> sock,
const CAddress& addrIn,
uint64_t nKeyedNetGroupIn,
uint64_t nLocalHostNonceIn,
const CAddress& addrBindIn,
const std::string& addrNameIn,
ConnectionType conn_type_in,
bool inbound_onion,
std::unique_ptr<i2p::sam::Session>&& i2p_sam_session = nullptr);
CNode(const CNode&) = delete;
CNode& operator=(const CNode&) = delete;
@ -596,6 +602,18 @@ private:
mapMsgTypeSize mapSendBytesPerMsgType GUARDED_BY(cs_vSend);
mapMsgTypeSize mapRecvBytesPerMsgType GUARDED_BY(cs_vRecv);
/**
* If an I2P session is created per connection (for outbound transient I2P
* connections) then it is stored here so that it can be destroyed when the
* socket is closed. I2P sessions involve a data/transport socket (in `m_sock`)
* and a control socket (in `m_i2p_sam_session`). For transient sessions, once
* the data socket is closed, the control socket is not going to be used anymore
* and is just taking up resources. So better close it as soon as `m_sock` is
* closed.
* Otherwise this unique_ptr is empty.
*/
std::unique_ptr<i2p::sam::Session> m_i2p_sam_session GUARDED_BY(m_sock_mutex);
};
/**