fixed #2183. Give more time to close streams after session disconnect if needed
Some checks failed
Build Debian packages / bookworm (push) Has been cancelled
Build Debian packages / bullseye (push) Has been cancelled
Build Debian packages / buster (push) Has been cancelled
Build on FreeBSD / with UPnP (push) Has been cancelled
Build on OSX / With USE_UPNP=no (push) Has been cancelled
Build on OSX / With USE_UPNP=yes (push) Has been cancelled
Build on Windows / clang-x86_64 (push) Has been cancelled
Build on Windows / i686 (push) Has been cancelled
Build on Windows / ucrt-x86_64 (push) Has been cancelled
Build on Windows / x86_64 (push) Has been cancelled
Build on Windows / CMake clang-x86_64 (push) Has been cancelled
Build on Windows / CMake i686 (push) Has been cancelled
Build on Windows / CMake ucrt-x86_64 (push) Has been cancelled
Build on Windows / CMake x86_64 (push) Has been cancelled
Build on Windows / XP (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=no (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=yes (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Has been cancelled
Build containers / Building container for linux/amd64 (push) Has been cancelled
Build containers / Building container for linux/arm64 (push) Has been cancelled
Build containers / Building container for linux/arm/v7 (push) Has been cancelled
Build containers / Building container for linux/386 (push) Has been cancelled
Build containers / Pushing merged manifest (push) Has been cancelled

This commit is contained in:
orignal 2025-04-24 16:37:50 -04:00
parent a5fa4ddb4c
commit 9d44a32e4c
3 changed files with 41 additions and 16 deletions

View file

@ -326,6 +326,7 @@ namespace stream
void SendPing (std::shared_ptr<const i2p::data::LeaseSet> remote); void SendPing (std::shared_ptr<const i2p::data::LeaseSet> remote);
void DeleteStream (std::shared_ptr<Stream> stream); void DeleteStream (std::shared_ptr<Stream> stream);
bool DeleteStream (uint32_t recvStreamID); bool DeleteStream (uint32_t recvStreamID);
size_t GetNumStreams () const { return m_Streams.size (); };
void SetAcceptor (const Acceptor& acceptor); void SetAcceptor (const Acceptor& acceptor);
void ResetAcceptor (); void ResetAcceptor ();
bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; bool IsAcceptorSet () const { return m_Acceptor != nullptr; };

View file

@ -43,23 +43,21 @@ namespace client
m_Stream->AsyncClose (); m_Stream->AsyncClose ();
m_Stream = nullptr; m_Stream = nullptr;
} }
auto Session = m_Owner.FindSession(m_ID);
switch (m_SocketType) switch (m_SocketType)
{ {
case eSAMSocketTypeSession: case eSAMSocketTypeSession:
m_Owner.CloseSession (m_ID); m_Owner.CloseSession (m_ID);
break; break;
case eSAMSocketTypeStream: case eSAMSocketTypeStream:
{ break;
break;
}
case eSAMSocketTypeAcceptor: case eSAMSocketTypeAcceptor:
case eSAMSocketTypeForward: case eSAMSocketTypeForward:
{ {
if (Session) auto session = m_Owner.FindSession(m_ID);
if (session)
{ {
if (m_IsAccepting && Session->GetLocalDestination ()) if (m_IsAccepting && session->GetLocalDestination ())
Session->GetLocalDestination ()->StopAcceptingStreams (); session->GetLocalDestination ()->StopAcceptingStreams ();
} }
break; break;
} }
@ -1479,15 +1477,37 @@ namespace client
session->StopLocalDestination (); session->StopLocalDestination ();
session->Close (); session->Close ();
if (m_IsSingleThread) if (m_IsSingleThread)
ScheduleSessionCleanupTimer (session); // let all session's streams close
}
}
void SAMBridge::ScheduleSessionCleanupTimer (std::shared_ptr<SAMSession> session)
{
auto timer = std::make_shared<boost::asio::deadline_timer>(GetService ());
timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds
timer->async_wait (std::bind (&SAMBridge::HandleSessionCleanupTimer, this, std::placeholders::_1, session, timer));
}
void SAMBridge::HandleSessionCleanupTimer (const boost::system::error_code& ecode,
std::shared_ptr<SAMSession> session, std::shared_ptr<boost::asio::deadline_timer> timer)
{
if (ecode != boost::asio::error::operation_aborted && session)
{
auto dest = session->GetLocalDestination ();
if (dest)
{ {
auto timer = std::make_shared<boost::asio::deadline_timer>(GetService ()); auto streamingDest = dest->GetStreamingDestination ();
timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds auto numStreams = streamingDest->GetNumStreams ();
timer->async_wait ([timer, session](const boost::system::error_code& ecode) if (numStreams > 0)
{ {
// session's destructor is called here LogPrint (eLogInfo, "SAM: Session ", session->Name, " still has ", numStreams, " streams");
}); ScheduleSessionCleanupTimer (session);
}
else
LogPrint (eLogDebug, "SAM: Session ", session->Name, " terminated");
} }
} }
// session's destructor is called here unless rescheduled
} }
std::shared_ptr<SAMSession> SAMBridge::FindSession (const std::string& id) const std::shared_ptr<SAMSession> SAMBridge::FindSession (const std::string& id) const

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2024, The PurpleI2P Project * Copyright (c) 2013-2025, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -271,6 +271,10 @@ namespace client
void ReceiveDatagram (); void ReceiveDatagram ();
void HandleReceivedDatagram (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleReceivedDatagram (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void ScheduleSessionCleanupTimer (std::shared_ptr<SAMSession> session);
void HandleSessionCleanupTimer (const boost::system::error_code& ecode,
std::shared_ptr<SAMSession> session, std::shared_ptr<boost::asio::deadline_timer> timer);
private: private:
bool m_IsSingleThread; bool m_IsSingleThread;