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