diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e881aa7b..c46f8067 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -737,6 +737,9 @@ namespace client clientTunnel->SetConnectTimeout(timeout); LogPrint(eLogInfo, "Clients: I2P Client tunnel connect timeout set to ", timeout); } + uint64_t closeIdleTime = section.second.get(I2P_CLIENT_TUNNEL_CLOSE_IDLE_TIME, 0); + if (closeIdleTime) + clientTunnel->SetCloseIdleTime(closeIdleTime); auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, clientTunnel)); if (ins.second) diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 546e669b..d51868d5 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2025, The PurpleI2P Project +* Copyright (c) 2013-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -49,6 +49,7 @@ namespace client const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels"; const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout"; const char I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL[] = "keepaliveinterval"; + const char I2P_CLIENT_TUNNEL_CLOSE_IDLE_TIME[] = "i2cp.closeIdleTime"; const char I2P_SERVER_TUNNEL_HOST[] = "host"; const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride"; const char I2P_SERVER_TUNNEL_I2P_HEADERS[] = "i2pheaders"; @@ -64,7 +65,7 @@ namespace client const char I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL[] = "enableuniquelocal"; const char I2P_SERVER_TUNNEL_SSL[] = "ssl"; const char UDP_CLIENT_TUNNEL_DATAGRAM_VERSION[] = "datagramversion"; - + class ClientContext { public: diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 01914b52..11b200f7 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -21,20 +21,16 @@ namespace client I2PService::I2PService (std::shared_ptr localDestination): m_LocalDestination (localDestination ? localDestination : i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)), - m_ReadyTimer(m_LocalDestination->GetService()), - m_ReadyTimerTriggered(false), - m_ConnectTimeout(0), + m_ReadyTimer(m_LocalDestination->GetService()), m_ReadyTimerTriggered(false), + m_ConnectTimeout(0), m_CloseIdleTime (0), m_LastActivityTime (0), isUpdated (true) { m_LocalDestination->Acquire (); } I2PService::I2PService (i2p::data::SigningKeyType kt): - m_LocalDestination (i2p::client::context.CreateNewLocalDestination (false, kt)), - m_ReadyTimer(m_LocalDestination->GetService()), - m_ConnectTimeout(0), isUpdated (true) + I2PService (i2p::client::context.CreateNewLocalDestination (false, kt)) { - m_LocalDestination->Acquire (); } I2PService::~I2PService () @@ -58,6 +54,12 @@ namespace client m_ConnectTimeout = timeout; } + void I2PService::UpdateLastActivityTime () + { + if (m_CloseIdleTime) + m_LastActivityTime = i2p::util::GetMonotonicMilliseconds (); + } + void I2PService::AddReadyCallback(ReadyCallback cb) { uint64_t now = i2p::util::GetMonotonicSeconds (); diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index 07230550..20fecc7d 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -50,6 +50,8 @@ namespace client void ClearHandlers (); void SetConnectTimeout(uint64_t timeout); + void SetCloseIdleTime (uint64_t idleTime) { m_CloseIdleTime = idleTime; }; + void UpdateLastActivityTime (); void AddReadyCallback(ReadyCallback cb); @@ -83,9 +85,11 @@ namespace client std::vector > m_ReadyCallbacks; boost::asio::steady_timer m_ReadyTimer; bool m_ReadyTimerTriggered; - uint64_t m_ConnectTimeout; + uint64_t m_ConnectTimeout; // in seconds + uint64_t m_CloseIdleTime; // in milliseconds + uint64_t m_LastActivityTime; // monotonic milliseconds - const size_t NEVER_TIMES_OUT = 0; + static constexpr size_t NEVER_TIMES_OUT = 0; public: diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index a37d4665..0140a506 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -244,7 +244,8 @@ namespace client else s->Terminate (); }); - } + GetOwner ()->UpdateLastActivityTime (); + } } void I2PTunnelConnection::HandleWrite (const boost::system::error_code& ecode) @@ -312,6 +313,7 @@ namespace client else boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, len), boost::asio::transfer_all (), std::bind (&I2PTunnelConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); + GetOwner ()->UpdateLastActivityTime (); } void I2PTunnelConnection::HandleConnect (const boost::system::error_code& ecode)