From 9e050d1a23678f0adbe156a33b343d858e8da7e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 23 Mar 2021 15:36:57 -0400 Subject: [PATCH] peer test for ipv6 --- daemon/HTTPServer.cpp | 23 +++++++++---- libi2pd/NetDb.cpp | 6 ++-- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterContext.cpp | 8 ++++- libi2pd/RouterContext.h | 4 ++- libi2pd/RouterInfo.cpp | 12 +++---- libi2pd/RouterInfo.h | 2 +- libi2pd/SSUSession.cpp | 17 ++++++++-- libi2pd/Transports.cpp | 70 +++++++++++++++++---------------------- 9 files changed, 82 insertions(+), 62 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 4741e5cf..c263cea9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -242,13 +242,9 @@ namespace http { s << "ERROR: " << string << "
\r\n"; } - void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) + static void ShowNetworkStatus (std::stringstream& s, RouterStatus status) { - s << "Uptime: "; - ShowUptime(s, i2p::context.GetUptime ()); - s << "
\r\n"; - s << "Network status: "; - switch (i2p::context.GetStatus ()) + switch (status) { case eRouterStatusOK: s << "OK"; break; case eRouterStatusTesting: s << "Testing"; break; @@ -276,7 +272,22 @@ namespace http { } default: s << "Unknown"; } + } + + void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) + { + s << "Uptime: "; + ShowUptime(s, i2p::context.GetUptime ()); + s << "
\r\n"; + s << "Network status: "; + ShowNetworkStatus (s, i2p::context.GetStatus ()); s << "
\r\n"; + if (i2p::context.SupportsV6 ()) + { + s << "Network status 6: "; + ShowNetworkStatus (s, i2p::context.GetStatusV6 ()); + s << "
\r\n"; + } #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (auto remains = Daemon.gracefulShutdownInterval) { s << "Stopping in: "; diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 076a8665..a50a796f 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1149,12 +1149,12 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4only) const + std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4) const { return GetRandomRouter ( - [v4only](std::shared_ptr router)->bool + [v4](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsPeerTesting (v4only); + return !router->IsHidden () && router->IsPeerTesting (v4); }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 5dbef743..891bc35d 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -85,7 +85,7 @@ namespace data std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; - std::shared_ptr GetRandomPeerTestRouter (bool v4only = true) const; + std::shared_ptr GetRandomPeerTestRouter (bool v4) const; std::shared_ptr GetRandomSSUV6Router () const; // TODO: change to v6 peer test later std::shared_ptr GetRandomIntroducer () const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 9451cca5..ff0063a7 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -28,7 +28,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_ShareRatio (100), m_Status (eRouterStatusUnknown), + m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusOK), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -210,6 +210,12 @@ namespace i2p } } + void RouterContext::SetStatusV6 (RouterStatus status) + { + if (status != m_StatusV6) + m_StatusV6 = status; + } + void RouterContext::UpdatePort (int port) { bool updated = false; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ee66a83c..158dd809 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -91,6 +91,8 @@ namespace garlic void SetStatus (RouterStatus status); RouterError GetError () const { return m_Error; }; void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; }; + RouterStatus GetStatusV6 () const { return m_StatusV6; }; + void SetStatusV6 (RouterStatus status); int GetNetID () const { return m_NetID; }; void SetNetID (int netID) { m_NetID = netID; }; bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); @@ -168,7 +170,7 @@ namespace garlic std::chrono::time_point m_StartupTime; uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; - RouterStatus m_Status; + RouterStatus m_Status, m_StatusV6; RouterError m_Error; int m_NetID; std::mutex m_GarlicMutex; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 2157dd37..53077235 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1100,15 +1100,15 @@ namespace data GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } - bool RouterInfo::IsPeerTesting (bool v4only) const + bool RouterInfo::IsPeerTesting (bool v4) const { - auto supportedTransports = m_SupportedTransports & (eSSUV4 | eSSUV6); - if (!supportedTransports) return false; // no SSU - if (v4only && !(supportedTransports & eSSUV4)) return false; // no SSU v4 + auto supportedTransports = m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6); + if (!supportedTransports) return false; return (bool)GetAddress ( - [](std::shared_ptr address)->bool + [v4](std::shared_ptr address)->bool { - return (address->transportStyle == eTransportSSU) && address->IsPeerTesting (); + return (address->transportStyle == eTransportSSU) && address->IsPeerTesting () && + ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())); }); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 93746e95..72818931 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -209,7 +209,7 @@ namespace data bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsEligibleFloodfill () const; - bool IsPeerTesting (bool v4only) const; + bool IsPeerTesting (bool v4) const; bool IsIntroducer () const; uint8_t GetCaps () const { return m_Caps; }; diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index f7d5214e..66579a16 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -970,7 +970,12 @@ namespace transport if (m_Server.GetPeerTestSession (nonce) == shared_from_this ()) // Alice-Bob { LogPrint (eLogDebug, "SSU: peer test from Bob. We are Alice"); - if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK + if (IsV6 ()) + { + if (i2p::context.GetStatusV6 () == eRouterStatusTesting) + i2p::context.SetStatusV6 (eRouterStatusFirewalled); + } + else if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK { i2p::context.SetStatus (eRouterStatusFirewalled); m_Server.RescheduleIntroducersUpdateTimer (); @@ -981,7 +986,10 @@ namespace transport LogPrint (eLogDebug, "SSU: first peer test from Charlie. We are Alice"); if (m_State == eSessionStateEstablished) LogPrint (eLogWarning, "SSU: first peer test from Charlie through established session. We are Alice"); - i2p::context.SetStatus (eRouterStatusOK); + if (IsV6 ()) + i2p::context.SetStatusV6 (eRouterStatusOK); + else + i2p::context.SetStatus (eRouterStatusOK); m_Server.UpdatePeerTest (nonce, ePeerTestParticipantAlice2); SendPeerTest (nonce, senderEndpoint.address (), senderEndpoint.port (), introKey, true, false); // to Charlie } @@ -995,7 +1003,10 @@ namespace transport { // peer test successive LogPrint (eLogDebug, "SSU: second peer test from Charlie. We are Alice"); - i2p::context.SetStatus (eRouterStatusOK); + if (IsV6 ()) + i2p::context.SetStatusV6 (eRouterStatusOK); + else + i2p::context.SetStatus (eRouterStatusOK); m_Server.RemovePeerTest (nonce); } break; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 9f3e75b7..78b45e32 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -576,55 +576,21 @@ namespace transport return; } if (m_SSUServer) - { - bool isv4 = i2p::context.SupportsV4 (); - if (m_IsNAT && isv4) - i2p::context.SetStatus (eRouterStatusTesting); - for (int i = 0; i < 5; i++) - { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4 - if (router) - m_SSUServer->CreateSession (router, true, isv4); // peer test - else - { - // if not peer test capable routers found pick any - router = i2p::data::netdb.GetRandomRouter (); - if (router && router->IsSSU ()) - m_SSUServer->CreateSession (router); // no peer test - } - } - if (i2p::context.SupportsV6 ()) - { - // try to connect to few v6 addresses to get our address back - for (int i = 0; i < 3; i++) - { - auto router = i2p::data::netdb.GetRandomSSUV6Router (); - if (router) - { - auto addr = router->GetSSUV6Address (); - if (addr) - m_SSUServer->GetService ().post ([this, router, addr] - { - m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); - }); - } - } - } - } + PeerTest (); else LogPrint (eLogError, "Transports: Can't detect external IP. SSU is not available"); } void Transports::PeerTest () { - if (RoutesRestricted() || !i2p::context.SupportsV4 ()) return; - if (m_SSUServer) + if (RoutesRestricted() || !m_SSUServer) return; + if (i2p::context.SupportsV4 ()) { - LogPrint (eLogInfo, "Transports: Started peer test"); + LogPrint (eLogInfo, "Transports: Started peer test ipv4"); bool statusChanged = false; for (int i = 0; i < 5; i++) { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 only + auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 if (router) { if (!statusChanged) @@ -636,8 +602,32 @@ namespace transport } } if (!statusChanged) - LogPrint (eLogWarning, "Transports: Can't find routers for peer test"); + LogPrint (eLogWarning, "Transports: Can't find routers for peer test ipv4"); } + if (i2p::context.SupportsV6 ()) + { + LogPrint (eLogInfo, "Transports: Started peer test ipv6"); + bool statusChanged = false; + for (int i = 0; i < 5; i++) + { + auto router = i2p::data::netdb.GetRandomPeerTestRouter (false); // v6 + if (router) + { + auto addr = router->GetSSUV6Address (); + if (addr) + { + if (!statusChanged) + { + statusChanged = true; + i2p::context.SetStatusV6 (eRouterStatusTesting); // first time only + } + m_SSUServer->CreateSession (router, addr, true); // peer test v6 + } + } + } + if (!statusChanged) + LogPrint (eLogWarning, "Transports: Can't find routers for peer test ipv6"); + } } std::shared_ptr Transports::GetNextX25519KeysPair ()