recgnize symmetric NAT from SSU2

This commit is contained in:
orignal 2022-08-02 20:02:55 -04:00
parent 98d2ce5845
commit ed5c533982
7 changed files with 63 additions and 16 deletions

View File

@ -222,7 +222,7 @@ namespace http {
s << "<b>" << tr("ERROR") << ":</b>&nbsp;" << string << "<br>\r\n";
}
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status)
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status, RouterError error)
{
switch (status)
{
@ -235,7 +235,7 @@ namespace http {
case eRouterStatusError:
{
s << tr("Error");
switch (i2p::context.GetError ())
switch (error)
{
case eRouterErrorClockSkew:
s << " - " << tr("Clock skew");
@ -260,12 +260,12 @@ namespace http {
ShowUptime(s, i2p::context.GetUptime ());
s << "<br>\r\n";
s << "<b>" << tr("Network status") << ":</b> ";
ShowNetworkStatus (s, i2p::context.GetStatus ());
ShowNetworkStatus (s, i2p::context.GetStatus (), i2p::context.GetError ());
s << "<br>\r\n";
if (i2p::context.SupportsV6 ())
{
s << "<b>" << tr("Network status v6") << ":</b> ";
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
ShowNetworkStatus (s, i2p::context.GetStatusV6 (), i2p::context.GetErrorV6 ());
s << "<br>\r\n";
}
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))

View File

@ -29,7 +29,7 @@ namespace i2p
RouterContext::RouterContext ():
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID)
m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), m_NetID (I2PD_NET_ID)
{
}
@ -263,6 +263,7 @@ namespace i2p
if (status != m_StatusV6)
{
m_StatusV6 = status;
m_ErrorV6 = eRouterErrorNone;
switch (m_StatusV6)
{
case eRouterStatusOK:

View File

@ -109,6 +109,8 @@ namespace garlic
RouterStatus GetStatusV6 () const { return m_StatusV6; };
void SetStatusV6 (RouterStatus status);
void SetStatusV6SSU2 (RouterStatus status);
RouterError GetErrorV6 () const { return m_ErrorV6; };
void SetErrorV6 (RouterError error) { m_StatusV6 = eRouterStatusError; m_ErrorV6 = error; };
int GetNetID () const { return m_NetID; };
void SetNetID (int netID) { m_NetID = netID; };
bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data);
@ -197,7 +199,7 @@ namespace garlic
uint64_t m_BandwidthLimit; // allowed bandwidth
int m_ShareRatio;
RouterStatus m_Status, m_StatusV6;
RouterError m_Error;
RouterError m_Error, m_ErrorV6;
int m_NetID;
std::mutex m_GarlicMutex;
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;

View File

@ -155,6 +155,14 @@ namespace transport
}
return false;
}
uint16_t SSU2Server::GetPort (bool v4) const
{
boost::system::error_code ec;
boost::asio::ip::udp::endpoint ep = v4 ? m_SocketV4.local_endpoint (ec) : m_SocketV6.local_endpoint (ec);
if (ec) return 0;
return ep.port ();
}
boost::asio::ip::udp::socket& SSU2Server::OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint)
{

View File

@ -55,6 +55,7 @@ namespace transport
boost::asio::io_service& GetService () { return GetIOService (); };
void SetLocalAddress (const boost::asio::ip::address& localAddress);
bool IsSupported (const boost::asio::ip::address& addr) const;
uint16_t GetPort (bool v4) const;
void AddSession (std::shared_ptr<SSU2Session> session);
void RemoveSession (uint64_t connID);

View File

@ -1370,16 +1370,9 @@ namespace transport
HandleAck (buf + offset, size);
break;
case eSSU2BlkAddress:
{
boost::asio::ip::udp::endpoint ep;
if (ExtractEndpoint (buf + offset, size, ep))
{
LogPrint (eLogInfo, "SSU2: Our external address is ", ep);
if (!i2p::util::net::IsInReservedRange (ep.address ()))
i2p::context.UpdateAddress (ep.address ());
}
break;
}
LogPrint (eLogDebug, "SSU2: Address");
HandleAddress (buf + offset, size);
break;
case eSSU2BlkIntroKey:
break;
case eSSU2BlkRelayTagRequest:
@ -1482,6 +1475,47 @@ namespace transport
}
}
void SSU2Session::HandleAddress (const uint8_t * buf, size_t len)
{
boost::asio::ip::udp::endpoint ep;
if (ExtractEndpoint (buf, len, ep))
{
LogPrint (eLogInfo, "SSU2: Our external address is ", ep);
if (!i2p::util::net::IsInReservedRange (ep.address ()))
{
i2p::context.UpdateAddress (ep.address ());
// check our port
bool isV4 = ep.address ().is_v4 ();
if (ep.port () != m_Server.GetPort (isV4))
{
if (isV4)
{
if (i2p::context.GetStatus () == eRouterStatusTesting)
i2p::context.SetError (eRouterErrorSymmetricNAT);
}
else
{
if (i2p::context.GetStatusV6 () == eRouterStatusTesting)
i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT);
}
}
else
{
if (isV4)
{
if (i2p::context.GetStatus () == eRouterStatusError && i2p::context.GetError () == eRouterErrorSymmetricNAT)
i2p::context.SetStatus (eRouterStatusTesting);
}
else
{
if (i2p::context.GetStatusV6 () == eRouterStatusError && i2p::context.GetErrorV6 () == eRouterErrorSymmetricNAT)
i2p::context.SetStatusV6 (eRouterStatusTesting);
}
}
}
}
}
void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len)
{
uint32_t msgID; memcpy (&msgID, buf + 1, 4);

View File

@ -278,6 +278,7 @@ namespace transport
void HandlePayload (const uint8_t * buf, size_t len);
void HandleAck (const uint8_t * buf, size_t len);
void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum, uint64_t ts);
void HandleAddress (const uint8_t * buf, size_t len);
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
size_t CreateEndpoint (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
std::shared_ptr<const i2p::data::RouterInfo::Address> FindLocalAddress () const;