Browse Source

recognize symmetric NAT from peer test msg 7

pull/2108/head
orignal 1 month ago
parent
commit
1419745a5d
  1. 29
      libi2pd/SSU2OutOfSession.cpp
  2. 2
      libi2pd/SSU2OutOfSession.h
  3. 5
      libi2pd/SSU2Session.h

29
libi2pd/SSU2OutOfSession.cpp

@ -65,6 +65,12 @@ namespace transport
return true; return true;
} }
void SSU2PeerTestSession::HandleAddress (const uint8_t * buf, size_t len)
{
if (!ExtractEndpoint (buf, len, m_OurEndpoint))
LogPrint (eLogWarning, "SSU2: Can't hanlde address block from peer test message");
}
void SSU2PeerTestSession::HandlePeerTest (const uint8_t * buf, size_t len) void SSU2PeerTestSession::HandlePeerTest (const uint8_t * buf, size_t len)
{ {
// msgs 5-7 // msgs 5-7
@ -112,6 +118,29 @@ namespace transport
case 7: // Alice from Charlie 2 case 7: // Alice from Charlie 2
{ {
m_PeerTestResendTimer.cancel (); // no more msg 6 resends m_PeerTestResendTimer.cancel (); // no more msg 6 resends
if (m_MsgNumReceived < 5 && m_OurEndpoint.port ()) // msg 5 was not received
{
if (m_OurEndpoint.address ().is_v4 ()) // ipv4
{
if (i2p::context.GetStatus () == eRouterStatusFirewalled)
{
if (m_OurEndpoint.port () != GetServer ().GetPort (true))
i2p::context.SetError (eRouterErrorSymmetricNAT);
else if (i2p::context.GetError () == eRouterErrorSymmetricNAT)
i2p::context.SetError (eRouterErrorNone);
}
}
else
{
if (i2p::context.GetStatusV6 () == eRouterStatusFirewalled)
{
if (m_OurEndpoint.port () != GetServer ().GetPort (false))
i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT);
else if (i2p::context.GetErrorV6 () == eRouterErrorSymmetricNAT)
i2p::context.SetErrorV6 (eRouterErrorNone);
}
}
}
GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ()); GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ());
GetServer ().RequestRemoveSession (GetConnID ()); GetServer ().RequestRemoveSession (GetConnID ());
break; break;

2
libi2pd/SSU2OutOfSession.h

@ -41,6 +41,7 @@ namespace transport
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, bool delayed = false); // PeerTest message void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, bool delayed = false); // PeerTest message
void SendPeerTest (uint8_t msg); // send or resend m_SignedData void SendPeerTest (uint8_t msg); // send or resend m_SignedData
void HandlePeerTest (const uint8_t * buf, size_t len) override; void HandlePeerTest (const uint8_t * buf, size_t len) override;
void HandleAddress (const uint8_t * buf, size_t len) override;
void ScheduleResend (uint8_t msg); void ScheduleResend (uint8_t msg);
@ -50,6 +51,7 @@ namespace transport
bool m_IsConnectedRecently, m_IsStatusChanged; bool m_IsConnectedRecently, m_IsStatusChanged;
std::vector<uint8_t> m_SignedData; // for resends std::vector<uint8_t> m_SignedData; // for resends
boost::asio::deadline_timer m_PeerTestResendTimer; boost::asio::deadline_timer m_PeerTestResendTimer;
boost::asio::ip::udp::endpoint m_OurEndpoint; // as seen by peer
}; };
const int SSU2_HOLE_PUNCH_RESEND_INTERVAL = 1000; // in milliseconds const int SSU2_HOLE_PUNCH_RESEND_INTERVAL = 1000; // in milliseconds

5
libi2pd/SSU2Session.h

@ -296,6 +296,8 @@ namespace transport
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep); size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0); size_t CreatePaddingBlock (uint8_t * buf, size_t len, size_t minSize = 0);
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen); size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, SSU2PeerTestCode code, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
private: private:
@ -328,8 +330,7 @@ namespace transport
void HandleRouterInfo (const uint8_t * buf, size_t len); void HandleRouterInfo (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); virtual 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); 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;
void AdjustMaxPayloadSize (); void AdjustMaxPayloadSize ();

Loading…
Cancel
Save