From 620e51abbc92ca259b112ceebba33f681852c732 Mon Sep 17 00:00:00 2001 From: PobreGato <315121269+pobregat0@users.noreply.github.com> Date: Wed, 2 Sep 2026 03:46:25 +0300 Subject: [PATCH] don't reset shared receivers from a tunnel that was never started --- libi2pd_client/UDPTunnel.cpp | 9 +++++++++ libi2pd_client/UDPTunnel.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/libi2pd_client/UDPTunnel.cpp b/libi2pd_client/UDPTunnel.cpp index 0749b37e..a2076df3 100644 --- a/libi2pd_client/UDPTunnel.cpp +++ b/libi2pd_client/UDPTunnel.cpp @@ -483,6 +483,7 @@ namespace client void I2PUDPServerTunnel::Start () { + m_IsStarted = true; m_LocalDest->Start (); auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip); @@ -553,6 +554,11 @@ namespace client void I2PUDPServerTunnel::Stop () { + // a config reload builds a second tunnel object and drops it when the same + // one is already there. Its destructor must not reset the receiver of the + // live tunnel: they share the datagram destination + if (!m_IsStarted) return; + m_IsStarted = false; if (m_StatsTimer) m_StatsTimer->cancel (); if (m_CleanupTimer) m_CleanupTimer->cancel (); auto dgram = m_LocalDest->GetDatagramDestination (); @@ -609,6 +615,7 @@ namespace client void I2PUDPClientTunnel::Start () { + m_IsStarted = true; UDPConnection::Start (); // Reset flag in case of tunnel reload if (m_cancel_resolve) m_cancel_resolve = false; @@ -643,6 +650,8 @@ namespace client void I2PUDPClientTunnel::Stop () { + if (!m_IsStarted) return; // see the comment in I2PUDPServerTunnel::Stop + m_IsStarted = false; if (m_KeepAliveTimer) m_KeepAliveTimer->cancel (); if (m_StatsTimer) m_StatsTimer->cancel (); diff --git a/libi2pd_client/UDPTunnel.h b/libi2pd_client/UDPTunnel.h index 3b77615f..8c0e522d 100644 --- a/libi2pd_client/UDPTunnel.h +++ b/libi2pd_client/UDPTunnel.h @@ -194,6 +194,7 @@ namespace client UDPSessionPtr m_LastSession; uint16_t m_inPort; bool m_Gzip; + bool m_IsStarted = false; // a tunnel that never started shares nothing to tear down uint32_t m_NumRawNoSession = 0; size_t m_MaxWindow = I2P_UDP_MIN_MAX_NUM_UNACKED_DATAGRAMS; std::unique_ptr m_StatsTimer; @@ -264,6 +265,7 @@ namespace client uint16_t RemotePort, m_LastPort; bool m_cancel_resolve; bool m_Gzip; + bool m_IsStarted = false; // see the comment in I2PUDPServerTunnel i2p::datagram::DatagramVersion m_DatagramVersion; std::shared_ptr m_LastSession; uint32_t m_KeepAliveInterval = 0;