From 39de43dfedf6a7731d76919b39fb2c1525ff531b Mon Sep 17 00:00:00 2001 From: parsebulb <268619375+parsebulb@users.noreply.github.com> Date: Tue, 17 Mar 2026 13:08:01 +0100 Subject: [PATCH] Don't preserve session lifetime in handlers This is an issue because i2pd does not wait for all handlers queued for execution inside io_context to execute before it's destroyed. Because these handlers preserve lifetime of IO objects via a shared pointer we get into a situation where destroying io_context will invoke destructors on those IO objects which in turn will attempt to access io_context and the app will crash. More info here https://github.com/PurpleI2P/i2pd/issues/2354 --- libi2pd/Transports.cpp | 12 ++++++++---- libi2pd/Transports.h | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 505c96be..2d840e78 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -896,10 +896,12 @@ namespace transport m_X25519KeysPairSupplier.Return (pair); } - void Transports::PeerConnected (std::shared_ptr session) + void Transports::PeerConnected (std::weak_ptr session) { - boost::asio::post (*m_Service, [session, this]() + boost::asio::post (*m_Service, [weakSession = std::move(session), this]() { + auto session = weakSession.lock(); + if (!session) return; auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; auto ident = remoteIdentity->GetIdentHash (); @@ -973,10 +975,12 @@ namespace transport }); } - void Transports::PeerDisconnected (std::shared_ptr session) + void Transports::PeerDisconnected (std::weak_ptr session) { - boost::asio::post (*m_Service, [session, this]() + boost::asio::post (*m_Service, [weakSession = std::move(session), this]() { + auto session = weakSession.lock(); + if (!session) return; auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; auto ident = remoteIdentity->GetIdentHash (); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index b0c5bee4..3e5a96e8 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -156,8 +156,8 @@ namespace transport std::future > SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); std::future > SendMessages (const i2p::data::IdentHash& ident, std::list >&& msgs); - void PeerConnected (std::shared_ptr session); - void PeerDisconnected (std::shared_ptr session); + void PeerConnected (std::weak_ptr session); + void PeerDisconnected (std::weak_ptr session); bool IsConnected (const i2p::data::IdentHash& ident) const; void UpdatePeerParams (std::shared_ptr r);