diff --git a/HTTPServer.cpp b/HTTPServer.cpp
index adf62298..01907c25 100644
--- a/HTTPServer.cpp
+++ b/HTTPServer.cpp
@@ -650,6 +650,15 @@ namespace util
s << "Uptime: " << boost::posix_time::to_simple_string (
boost::posix_time::time_duration (boost::posix_time::seconds (
i2p::context.GetUptime ()))) << "
";
+ s << "Status: ";
+ switch (i2p::context.GetStatus ())
+ {
+ case eRouterStatusOK: s << "OK"; break;
+ case eRouterStatusTesting: s << "Testing"; break;
+ case eRouterStatusFirewalled: s << "Firewalled"; break;
+ default: s << "Unknown";
+ }
+ s << "
";
s << "Data path: " << i2p::util::filesystem::GetDataDir().string() << "
";
s << "Our external address:" << "
" ;
for (auto& address : i2p::context.GetRouterInfo().GetAddresses())
diff --git a/RouterContext.cpp b/RouterContext.cpp
index d7e20aac..3a894e6b 100644
--- a/RouterContext.cpp
+++ b/RouterContext.cpp
@@ -14,7 +14,7 @@ namespace i2p
RouterContext::RouterContext ():
m_LastUpdateTime (0), m_IsUnreachable (false), m_AcceptsTunnels (true),
- m_IsFloodfill (false), m_StartupTime (0)
+ m_IsFloodfill (false), m_StartupTime (0), m_Status (eRouterStatusOK )
{
}
diff --git a/RouterContext.h b/RouterContext.h
index c2924814..f1e8056c 100644
--- a/RouterContext.h
+++ b/RouterContext.h
@@ -17,6 +17,13 @@ namespace i2p
const char ROUTER_KEYS[] = "router.keys";
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
+ enum RouterStatus
+ {
+ eRouterStatusOK = 0,
+ eRouterStatusTesting = 1,
+ eRouterStatusFirewalled = 2
+ };
+
class RouterContext: public i2p::garlic::GarlicDestination
{
public:
@@ -33,12 +40,14 @@ namespace i2p
CryptoPP::RandomNumberGenerator& GetRandomNumberGenerator () { return m_Rnd; };
uint32_t GetUptime () const;
uint32_t GetStartupTime () const { return m_StartupTime; };
+ RouterStatus GetStatus () const { return m_Status; };
+ void SetStatus (RouterStatus status) { m_Status = status; };
void UpdatePort (int port); // called from Daemon
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
bool AddIntroducer (const i2p::data::RouterInfo& routerInfo, uint32_t tag);
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
- bool IsUnreachable () const { return m_IsUnreachable; };
+ bool IsUnreachable () const { return m_IsUnreachable || m_Status == eRouterStatusFirewalled; };
void SetUnreachable ();
bool IsFloodfill () const { return m_IsFloodfill; };
void SetFloodfill (bool floodfill);
@@ -74,6 +83,7 @@ namespace i2p
uint64_t m_LastUpdateTime;
bool m_IsUnreachable, m_AcceptsTunnels, m_IsFloodfill;
uint64_t m_StartupTime; // in seconds since epoch
+ RouterStatus m_Status;
};
extern RouterContext context;
diff --git a/SSUSession.cpp b/SSUSession.cpp
index 4e6f85f5..7915b65d 100644
--- a/SSUSession.cpp
+++ b/SSUSession.cpp
@@ -902,10 +902,15 @@ namespace transport
case ePeerTestParticipantAlice1:
{
if (m_State == eSessionStateEstablished)
+ {
LogPrint (eLogDebug, "SSU peer test from Bob. We are Alice");
+ if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK
+ i2p::context.SetStatus (eRouterStatusFirewalled);
+ }
else
{
LogPrint (eLogDebug, "SSU first peer test from Charlie. We are Alice");
+ i2p::context.SetStatus (eRouterStatusOK);
m_Server.UpdatePeerTest (nonce, ePeerTestParticipantAlice2);
SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
senderEndpoint.port (), introKey, true, false); // to Charlie
@@ -920,6 +925,7 @@ namespace transport
{
// peer test successive
LogPrint (eLogDebug, "SSU second peer test from Charlie. We are Alice");
+ i2p::context.SetStatus (eRouterStatusOK);
m_Server.RemovePeerTest (nonce);
}
break;
diff --git a/Transports.cpp b/Transports.cpp
index 47839a1c..f54edf0b 100644
--- a/Transports.cpp
+++ b/Transports.cpp
@@ -384,6 +384,7 @@ namespace transport
void Transports::DetectExternalIP ()
{
+ i2p::context.SetStatus (eRouterStatusTesting);
for (int i = 0; i < 5; i++)
{
auto router = i2p::data::netdb.GetRandomRouter ();