From 1738d118f70a9a34b8f2e7e619534b7ce00f8d68 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 Oct 2022 14:06:45 -0400 Subject: [PATCH] recconnect to proxy --- libi2pd/SSU2.cpp | 29 ++++++++++++++++++++++++++++- libi2pd/SSU2.h | 7 +++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 90139c10..ee6fe53c 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1157,6 +1157,7 @@ namespace transport { LogPrint (eLogError, "SSU2: Can't connect to proxy ", *m_ProxyEndpoint, " ", ecode.message ()); m_UDPAssociateSocket.reset (nullptr); + ReconnectToProxy (); } else HandshakeWithProxy (); @@ -1177,6 +1178,7 @@ namespace transport { LogPrint(eLogError, "SSU2: Proxy write error ", ecode.message()); m_UDPAssociateSocket.reset (nullptr); + ReconnectToProxy (); } else ReadHandshakeWithProxyReply (); @@ -1194,6 +1196,7 @@ namespace transport { LogPrint(eLogError, "SSU2: Proxy read error ", ecode.message()); m_UDPAssociateSocket.reset (nullptr); + ReconnectToProxy (); } else { @@ -1224,6 +1227,7 @@ namespace transport { LogPrint(eLogError, "SSU2: Proxy write error ", ecode.message()); m_UDPAssociateSocket.reset (nullptr); + ReconnectToProxy (); } else ReadUDPAssociateReply (); @@ -1241,6 +1245,7 @@ namespace transport { LogPrint(eLogError, "SSU2: Proxy read error ", ecode.message()); m_UDPAssociateSocket.reset (nullptr); + ReconnectToProxy (); } else { @@ -1280,14 +1285,36 @@ namespace transport (void) bytes_transferred; if (ecode) { - LogPrint(eLogError, "SSU2: Proxy UDP Associate socket error ", ecode.message()); + LogPrint(eLogWarning, "SSU2: Proxy UDP Associate socket error ", ecode.message()); m_UDPAssociateSocket.reset (nullptr); + m_ProxyRelayEndpoint.reset (nullptr); + ConnectToProxy (); // try to reconnect immediately } else ReadUDPAssociateSocket (); }); } + void SSU2Server::ReconnectToProxy () + { + LogPrint(eLogInfo, "SSU2: Reconnect to proxy after ", SSU2_PROXY_CONNECT_RETRY_TIMEOUT, " seconds"); + if (m_ProxyConnectRetryTimer) + m_ProxyConnectRetryTimer->cancel (); + else + m_ProxyConnectRetryTimer.reset (new boost::asio::deadline_timer (m_ReceiveService.GetService ())); + m_ProxyConnectRetryTimer->expires_from_now (boost::posix_time::seconds (SSU2_PROXY_CONNECT_RETRY_TIMEOUT)); + m_ProxyConnectRetryTimer->async_wait ( + [this](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + m_UDPAssociateSocket.reset (nullptr); + m_ProxyRelayEndpoint.reset (nullptr); + ConnectToProxy (); + } + }); + } + bool SSU2Server::SetProxy (const std::string& address, uint16_t port) { boost::system::error_code ecode; diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index fb2925cb..c5c2c140 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -27,8 +27,9 @@ namespace transport const size_t SSU2_MAX_NUM_INTRODUCERS = 3; const int SSU2_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour const int SSU2_TO_INTRODUCER_SESSION_EXPIRATION = 4800; // 80 minutes - const int SSU2_KEEP_ALIVE_INTERVAL = 30; // 30 seconds - + const int SSU2_KEEP_ALIVE_INTERVAL = 30; // in seconds + const int SSU2_PROXY_CONNECT_RETRY_TIMEOUT = 30; // in seconds + class SSU2Server: private i2p::util::RunnableServiceWithWork { struct Packet @@ -124,6 +125,7 @@ namespace transport const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to); void ProcessNextPacketFromProxy (uint8_t * buf, size_t len); void ConnectToProxy (); + void ReconnectToProxy (); void HandshakeWithProxy (); void ReadHandshakeWithProxyReply (); void SendUDPAssociateRequest (); @@ -155,6 +157,7 @@ namespace transport std::unique_ptr m_ProxyEndpoint; std::unique_ptr m_UDPAssociateSocket; std::unique_ptr m_ProxyRelayEndpoint; + std::unique_ptr m_ProxyConnectRetryTimer; public: