Browse Source

recgnize symmetric NAT from SSU2

pull/1786/head
orignal 2 years ago
parent
commit
ed5c533982
  1. 8
      daemon/HTTPServer.cpp
  2. 3
      libi2pd/RouterContext.cpp
  3. 4
      libi2pd/RouterContext.h
  4. 8
      libi2pd/SSU2.cpp
  5. 1
      libi2pd/SSU2.h
  6. 54
      libi2pd/SSU2Session.cpp
  7. 1
      libi2pd/SSU2Session.h

8
daemon/HTTPServer.cpp

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

3
libi2pd/RouterContext.cpp

@ -29,7 +29,7 @@ namespace i2p
RouterContext::RouterContext (): RouterContext::RouterContext ():
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), 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) if (status != m_StatusV6)
{ {
m_StatusV6 = status; m_StatusV6 = status;
m_ErrorV6 = eRouterErrorNone;
switch (m_StatusV6) switch (m_StatusV6)
{ {
case eRouterStatusOK: case eRouterStatusOK:

4
libi2pd/RouterContext.h

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

8
libi2pd/SSU2.cpp

@ -155,6 +155,14 @@ namespace transport
} }
return false; 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) boost::asio::ip::udp::socket& SSU2Server::OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint)
{ {

1
libi2pd/SSU2.h

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

54
libi2pd/SSU2Session.cpp

@ -1370,16 +1370,9 @@ namespace transport
HandleAck (buf + offset, size); HandleAck (buf + offset, size);
break; break;
case eSSU2BlkAddress: case eSSU2BlkAddress:
{ LogPrint (eLogDebug, "SSU2: Address");
boost::asio::ip::udp::endpoint ep; HandleAddress (buf + offset, size);
if (ExtractEndpoint (buf + offset, size, ep)) break;
{
LogPrint (eLogInfo, "SSU2: Our external address is ", ep);
if (!i2p::util::net::IsInReservedRange (ep.address ()))
i2p::context.UpdateAddress (ep.address ());
}
break;
}
case eSSU2BlkIntroKey: case eSSU2BlkIntroKey:
break; break;
case eSSU2BlkRelayTagRequest: 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) void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len)
{ {
uint32_t msgID; memcpy (&msgID, buf + 1, 4); uint32_t msgID; memcpy (&msgID, buf + 1, 4);

1
libi2pd/SSU2Session.h

@ -278,6 +278,7 @@ namespace transport
void HandlePayload (const uint8_t * buf, size_t len); void HandlePayload (const uint8_t * buf, size_t len);
void HandleAck (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 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); 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); 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; std::shared_ptr<const i2p::data::RouterInfo::Address> FindLocalAddress () const;

Loading…
Cancel
Save