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 ()