diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index e32bd459..2ac636ce 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -826,7 +826,7 @@ namespace http { if (i2p::tunnel::tunnels.CountTransitTunnels()) { s << "" << tr("Transit Tunnels") << ":
\r\n"; - s << ""; + s << "
ID" << tr("Amount") << "
"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { if (std::dynamic_pointer_cast(it)) @@ -836,7 +836,7 @@ namespace http { else s << "\r\n"; + s << "\r\n"; } s << "
ID" << tr("Amount") << "" << tr("Next") << "
" << it->GetTunnelID () << ""; ShowTraffic(s, it->GetNumTransmittedBytes ()); - s << "
" << it->GetNextPeerName () << "
\r\n"; } diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 76b056cf..5ab577c0 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1435,6 +1435,12 @@ namespace transport boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::SendRouterInfo, shared_from_this ())); } + i2p::data::RouterInfo::SupportedTransports NTCP2Session::GetTransportType () const + { + if (m_RemoteEndpoint.address ().is_v4 ()) return i2p::data::RouterInfo::eNTCP2V4; + return i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? i2p::data::RouterInfo::eNTCP2V6Mesh : i2p::data::RouterInfo::eNTCP2V6; + } + NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), m_ProxyType(eNoProxy), m_Resolver(GetService ()), diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 5df4de6e..47354f32 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -147,6 +147,7 @@ namespace transport void SetRemoteEndpoint (const boost::asio::ip::tcp::endpoint& ep) { m_RemoteEndpoint = ep; }; bool IsEstablished () const override { return m_IsEstablished; }; + i2p::data::RouterInfo::SupportedTransports GetTransportType () const override; bool IsTerminated () const { return m_IsTerminated; }; void ClientLogin (); // Alice diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0d53f6cd..3c074031 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1195,6 +1195,19 @@ namespace data return false; } } + + std::string RouterInfo::GetTransportName (SupportedTransports tr) + { + switch (tr) + { + case eNTCP2V4: return "NTCP2V4"; + case eNTCP2V6: return "NTCP2V6"; + case eSSU2V4: return "SSU2V4"; + case eSSU2V6: return "SSU2V6"; + case eNTCP2V6Mesh: return "Mesh"; + default: return ""; + } + } void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) { diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index beeba5bf..8d11f661 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -363,6 +363,10 @@ namespace data int m_Version; Congestion m_Congestion; mutable std::shared_ptr m_Profile; + + public: + + static std::string GetTransportName (SupportedTransports tr); }; class LocalRouterInfo: public RouterInfo diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index 4196e785..284ab4d8 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -3114,5 +3114,10 @@ namespace transport else if (!sent && !m_SentPackets.empty ()) // if only acks received, nothing sent and we still have something to resend Resend (i2p::util::GetMillisecondsSinceEpoch ()); // than right time to resend } + + i2p::data::RouterInfo::SupportedTransports SSU2Session::GetTransportType () const + { + return m_RemoteEndpoint.address ().is_v4 () ? i2p::data::RouterInfo::eSSU2V4 : i2p::data::RouterInfo::eSSU2V6; + } } } diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index 4b3139a7..acd46dd1 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -267,6 +267,7 @@ namespace transport size_t Resend (uint64_t ts); // return number of resent packets uint64_t GetLastResendTime () const { return m_LastResendTime; }; bool IsEstablished () const override { return m_State == eSSU2SessionStateEstablished; }; + i2p::data::RouterInfo::SupportedTransports GetTransportType () const override; uint64_t GetConnID () const { return m_SourceConnID; }; SSU2SessionState GetState () const { return m_State; }; void SetState (SSU2SessionState state) { m_State = state; }; diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 7dbed003..3d3f20f2 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -10,6 +10,8 @@ #include "I2PEndian.h" #include "Crypto.h" #include "Log.h" +#include "Identity.h" +#include "RouterInfo.h" #include "RouterContext.h" #include "I2NPProtocol.h" #include "Garlic.h" @@ -41,6 +43,21 @@ namespace tunnel i2p::transport::transports.UpdateTotalTransitTransmittedBytes (TUNNEL_DATA_MSG_SIZE); } + std::string TransitTunnel::GetNextPeerName () const + { + return i2p::data::GetIdentHashAbbreviation (GetNextIdentHash ()); + } + + void TransitTunnel::SendTunnelDataMsg (std::shared_ptr msg) + { + LogPrint (eLogError, "TransitTunnel: We are not a gateway for ", GetTunnelID ()); + } + + void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) + { + LogPrint (eLogError, "TransitTunnel: Incoming tunnel message is not supported ", GetTunnelID ()); + } + TransitTunnelParticipant::~TransitTunnelParticipant () { } @@ -67,16 +84,18 @@ namespace tunnel } } - void TransitTunnel::SendTunnelDataMsg (std::shared_ptr msg) + std::string TransitTunnelParticipant::GetNextPeerName () const { - LogPrint (eLogError, "TransitTunnel: We are not a gateway for ", GetTunnelID ()); - } - - void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) - { - LogPrint (eLogError, "TransitTunnel: Incoming tunnel message is not supported ", GetTunnelID ()); - } - + if (m_Sender) + { + auto transport = m_Sender->GetCurrentTransport (); + if (transport) + return TransitTunnel::GetNextPeerName () + "-" + + i2p::data::RouterInfo::GetTransportName (transport->GetTransportType ()); + } + return TransitTunnel::GetNextPeerName (); + } + void TransitTunnelGateway::SendTunnelDataMsg (std::shared_ptr msg) { TunnelMessageBlock block; @@ -92,6 +111,19 @@ namespace tunnel m_Gateway.SendBuffer (); } + std::string TransitTunnelGateway::GetNextPeerName () const + { + const auto& sender = m_Gateway.GetSender (); + if (sender) + { + auto transport = sender->GetCurrentTransport (); + if (transport) + return TransitTunnel::GetNextPeerName () + "-" + + i2p::data::RouterInfo::GetTransportName (transport->GetTransportType ()); + } + return TransitTunnel::GetNextPeerName (); + } + void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { auto newMsg = CreateEmptyTunnelDataMsg (true); diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index 89653931..58aba35b 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -33,11 +33,13 @@ namespace tunnel const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey); virtual size_t GetNumTransmittedBytes () const { return 0; }; + virtual std::string GetNextPeerName () const; // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg) override; void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) override; + private: i2p::crypto::AESKey m_LayerKey, m_IVKey; @@ -56,6 +58,7 @@ namespace tunnel ~TransitTunnelParticipant (); size_t GetNumTransmittedBytes () const override { return m_NumTransmittedBytes; }; + std::string GetNextPeerName () const override; void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; void FlushTunnelDataMsgs () override; @@ -79,7 +82,8 @@ namespace tunnel void SendTunnelDataMsg (std::shared_ptr msg) override; void FlushTunnelDataMsgs () override; size_t GetNumTransmittedBytes () const override { return m_Gateway.GetNumSentBytes (); }; - + std::string GetNextPeerName () const override; + private: std::mutex m_SendMutex; @@ -97,10 +101,11 @@ namespace tunnel m_Endpoint (false) {}; // transit endpoint is always outbound void Cleanup () override { m_Endpoint.Cleanup (); } - + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; size_t GetNumTransmittedBytes () const override { return m_Endpoint.GetNumReceivedBytes (); } - + std::string GetNextPeerName () const override { return ""; } + private: TunnelEndpoint m_Endpoint; diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 6c878d11..ef0044c0 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -151,6 +151,7 @@ namespace transport }; virtual void SendI2NPMessages (std::list >& msgs) = 0; virtual bool IsEstablished () const = 0; + virtual i2p::data::RouterInfo::SupportedTransports GetTransportType () const = 0; private: diff --git a/libi2pd/TunnelBase.cpp b/libi2pd/TunnelBase.cpp index 031988a6..1f437758 100644 --- a/libi2pd/TunnelBase.cpp +++ b/libi2pd/TunnelBase.cpp @@ -60,5 +60,11 @@ namespace tunnel msgs.swap (msgs1); SendMessagesTo (to, std::move (msgs1)); } + + void TunnelTransportSender::Reset () + { + m_CurrentTransport.reset (); + m_PendingTransport = std::future >(); + } } } diff --git a/libi2pd/TunnelBase.h b/libi2pd/TunnelBase.h index 91d0fafc..39d6e780 100644 --- a/libi2pd/TunnelBase.h +++ b/libi2pd/TunnelBase.h @@ -93,6 +93,9 @@ namespace tunnel void SendMessagesTo (const i2p::data::IdentHash& to, std::list >&& msgs); void SendMessagesTo (const i2p::data::IdentHash& to, std::list >& msgs); // send and clear + + std::shared_ptr GetCurrentTransport () const { return m_CurrentTransport.lock (); } + void Reset (); private: diff --git a/libi2pd/TunnelGateway.h b/libi2pd/TunnelGateway.h index 292392ae..75f27581 100644 --- a/libi2pd/TunnelGateway.h +++ b/libi2pd/TunnelGateway.h @@ -51,6 +51,7 @@ namespace tunnel void PutTunnelDataMsg (const TunnelMessageBlock& block); void SendBuffer (); size_t GetNumSentBytes () const { return m_NumSentBytes; }; + const std::unique_ptr& GetSender () const { return m_Sender; }; private: