diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 3e5e789b..2e69b514 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -250,6 +250,7 @@ namespace client void Stop () override; const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; + void SetPrivateKeys (const i2p::data::PrivateKeys& keys) { m_Keys = keys; }; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; // ref counter diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c46f8067..b45c4690 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -739,7 +739,10 @@ namespace client } uint64_t closeIdleTime = section.second.get(I2P_CLIENT_TUNNEL_CLOSE_IDLE_TIME, 0); if (closeIdleTime) + { clientTunnel->SetCloseIdleTime(closeIdleTime); + clientTunnel->SetNewDestOnResume(section.second.get(I2P_CLIENT_TUNNEL_NEW_DEST_ON_RESUME, false)); + } 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 d51868d5..bcc99ea3 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -50,6 +50,7 @@ namespace client 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_CLIENT_TUNNEL_NEW_DEST_ON_RESUME[] = "i2cp.newDestOnResume"; const char I2P_SERVER_TUNNEL_HOST[] = "host"; const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride"; const char I2P_SERVER_TUNNEL_I2P_HEADERS[] = "i2pheaders"; diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 186368f4..4678c690 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -22,7 +22,7 @@ namespace client 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_CloseIdleTime (0), m_LastActivityTime (0), + m_ConnectTimeout(0), m_CloseIdleTime (0), m_NewDestOnResume (false), m_LastActivityTime (0), isUpdated (true) { m_LocalDestination->Acquire (); @@ -71,13 +71,26 @@ namespace client { m_LastActivityTime = i2p::util::GetMonotonicMilliseconds (); if (m_LocalDestination->IsIdling ()) - { - m_LocalDestination->SetIsIdling (false); - ScheduleIdleCheckTimer (); - } + Resume (); } } + void I2PService::Resume () + { + if (m_CloseIdleTime) + { + if (m_NewDestOnResume) + { + auto ident = m_LocalDestination->GetPrivateKeys ().GetPublic (); + if (ident) + m_LocalDestination->SetPrivateKeys (i2p::data::PrivateKeys::CreateRandomKeys ( + ident->GetSigningKeyType (), ident->GetCryptoKeyType (), true)); + } + ScheduleIdleCheckTimer (); + } + m_LocalDestination->SetIsIdling (false); + } + void I2PService::AddReadyCallback(ReadyCallback cb) { uint64_t now = i2p::util::GetMonotonicSeconds (); diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index ff4d98fe..c2136e3d 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -52,6 +52,7 @@ namespace client void SetConnectTimeout(uint64_t timeout); void SetCloseIdleTime (uint64_t idleTime); + void SetNewDestOnResume (bool newDestOnResume) { m_NewDestOnResume = newDestOnResume; } void UpdateLastActivityTime (); void AddReadyCallback(ReadyCallback cb); @@ -79,6 +80,7 @@ namespace client void HandleReadyCheckTimer(const boost::system::error_code & ec); void ScheduleIdleCheckTimer (); void HandleIdleCheckTimer(const boost::system::error_code & ec); + void Resume (); private: @@ -90,6 +92,7 @@ namespace client bool m_ReadyTimerTriggered; uint64_t m_ConnectTimeout; // in seconds uint64_t m_CloseIdleTime; // in milliseconds + bool m_NewDestOnResume; uint64_t m_LastActivityTime; // monotonic milliseconds std::unique_ptr m_IdleCheckTimer;