mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-09 15:50:26 +03:00
check if we connected recently to an endpoint before sending peer test
This commit is contained in:
parent
ca4db7aab2
commit
f20391d460
@ -210,6 +210,22 @@ namespace transport
|
||||
return ep.port ();
|
||||
}
|
||||
|
||||
bool SSU2Server::IsConnectedRecently (const boost::asio::ip::udp::endpoint& ep) const
|
||||
{
|
||||
if (!ep.port () || ep.address ().is_unspecified ()) return false;
|
||||
auto it = m_ConnectedRecently.find (ep);
|
||||
if (it != m_ConnectedRecently.end ())
|
||||
return i2p::util::GetSecondsSinceEpoch () <= it->second + SSU2_HOLE_PUNCH_EXPIRATION;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SSU2Server::AddConnectedRecently (const boost::asio::ip::udp::endpoint& ep, uint64_t ts)
|
||||
{
|
||||
if (!ep.port () || ep.address ().is_unspecified () ||
|
||||
i2p::util::GetSecondsSinceEpoch () > ts + SSU2_HOLE_PUNCH_EXPIRATION) return;
|
||||
m_ConnectedRecently.try_emplace (ep, ts);
|
||||
}
|
||||
|
||||
void SSU2Server::AdjustTimeOffset (int64_t offset, std::shared_ptr<const i2p::data::IdentityEx> from)
|
||||
{
|
||||
if (offset)
|
||||
@ -1001,6 +1017,14 @@ namespace transport
|
||||
it++;
|
||||
}
|
||||
|
||||
for (auto it = m_ConnectedRecently.begin (); it != m_ConnectedRecently.end (); )
|
||||
{
|
||||
if (ts > it->second + SSU2_HOLE_PUNCH_EXPIRATION)
|
||||
it = m_ConnectedRecently.erase (it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
|
||||
m_PacketsPool.CleanUpMt ();
|
||||
m_SentPacketsPool.CleanUp ();
|
||||
m_IncompleteMessagesPool.CleanUp ();
|
||||
|
@ -39,6 +39,7 @@ namespace transport
|
||||
const int SSU2_KEEP_ALIVE_INTERVAL = 15; // in seconds
|
||||
const int SSU2_KEEP_ALIVE_INTERVAL_VARIANCE = 4; // in seconds
|
||||
const int SSU2_PROXY_CONNECT_RETRY_TIMEOUT = 30; // in seconds
|
||||
const int SSU2_HOLE_PUNCH_EXPIRATION = 20; // in seconds
|
||||
|
||||
class SSU2Server: private i2p::util::RunnableServiceWithWork
|
||||
{
|
||||
@ -72,6 +73,8 @@ namespace transport
|
||||
bool UsesProxy () const { return m_IsThroughProxy; };
|
||||
bool IsSupported (const boost::asio::ip::address& addr) const;
|
||||
uint16_t GetPort (bool v4) const;
|
||||
bool IsConnectedRecently (const boost::asio::ip::udp::endpoint& ep) const;
|
||||
void AddConnectedRecently (const boost::asio::ip::udp::endpoint& ep, uint64_t ts);
|
||||
std::mt19937& GetRng () { return m_Rng; }
|
||||
bool IsMaxNumIntroducers (bool v4) const { return (v4 ? m_Introducers.size () : m_IntroducersV6.size ()) >= SSU2_MAX_NUM_INTRODUCERS; }
|
||||
bool IsSyncClockFromPeers () const { return m_IsSyncClockFromPeers; };
|
||||
@ -160,7 +163,7 @@ namespace transport
|
||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions;
|
||||
mutable std::mutex m_PendingOutgoingSessionsMutex;
|
||||
std::map<boost::asio::ip::udp::endpoint, std::pair<uint64_t, uint32_t> > m_IncomingTokens, m_OutgoingTokens; // remote endpoint -> (token, expires in seconds)
|
||||
std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
|
||||
std::unordered_map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
|
||||
std::list<i2p::data::IdentHash> m_Introducers, m_IntroducersV6; // introducers we are connected to
|
||||
i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
|
||||
i2p::util::MemoryPool<SSU2SentPacket> m_SentPacketsPool;
|
||||
@ -174,7 +177,8 @@ namespace transport
|
||||
int64_t m_PendingTimeOffset; // during peer test
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_PendingTimeOffsetFrom;
|
||||
std::mt19937 m_Rng;
|
||||
|
||||
std::map<boost::asio::ip::udp::endpoint, uint64_t> m_ConnectedRecently; // endpoint -> last activity time in seconds
|
||||
|
||||
// proxy
|
||||
bool m_IsThroughProxy;
|
||||
uint8_t m_UDPRequestHeader[SOCKS5_UDP_IPV6_REQUEST_HEADER_SIZE];
|
||||
|
@ -265,6 +265,7 @@ namespace transport
|
||||
m_OnEstablished = nullptr;
|
||||
if (m_RelayTag)
|
||||
m_Server.RemoveRelay (m_RelayTag);
|
||||
m_Server.AddConnectedRecently (m_RemoteEndpoint, GetLastActivityTimestamp ());
|
||||
m_SentHandshakePacket.reset (nullptr);
|
||||
m_SessionConfirmedFragment.reset (nullptr);
|
||||
m_PathChallenge.reset (nullptr);
|
||||
@ -281,14 +282,10 @@ namespace transport
|
||||
transports.PeerDisconnected (shared_from_this ());
|
||||
auto remoteIdentity = GetRemoteIdentity ();
|
||||
if (remoteIdentity)
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU2: Session with ", GetRemoteEndpoint (),
|
||||
" (", i2p::data::GetIdentHashAbbreviation (remoteIdentity->GetIdentHash ()), ") terminated");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU2: Session with ", GetRemoteEndpoint (), " terminated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1153,7 +1150,7 @@ namespace transport
|
||||
if (profile) // older router?
|
||||
profile->Duplicated (); // mark router as duplicated in profile
|
||||
else
|
||||
LogPrint (eLogError, "SSU2: Host mismatch between published address ", m_Address->host,
|
||||
LogPrint (eLogInfo, "SSU2: Host mismatch between published address ", m_Address->host,
|
||||
" and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ()));
|
||||
return false;
|
||||
}
|
||||
@ -2276,14 +2273,19 @@ namespace transport
|
||||
if (addr && m_Server.IsSupported (ep.address ()) &&
|
||||
i2p::context.GetRouterInfo ().IsSSU2PeerTesting (ep.address ().is_v4 ()))
|
||||
{
|
||||
// send msg 5 to Alice
|
||||
auto session = std::make_shared<SSU2Session> (m_Server, r, addr);
|
||||
session->SetState (eSSU2SessionStatePeerTest);
|
||||
session->m_RemoteEndpoint = ep; // might be different
|
||||
session->m_DestConnID = htobe64 (((uint64_t)nonce << 32) | nonce);
|
||||
session->m_SourceConnID = ~session->m_DestConnID;
|
||||
m_Server.AddSession (session);
|
||||
session->SendPeerTest (5, newSignedData.data (), newSignedData.size (), addr->i);
|
||||
if (!m_Server.IsConnectedRecently (ep)) // no alive hole punch
|
||||
{
|
||||
// send msg 5 to Alice
|
||||
auto session = std::make_shared<SSU2Session> (m_Server, r, addr);
|
||||
session->SetState (eSSU2SessionStatePeerTest);
|
||||
session->m_RemoteEndpoint = ep; // might be different
|
||||
session->m_DestConnID = htobe64 (((uint64_t)nonce << 32) | nonce);
|
||||
session->m_SourceConnID = ~session->m_DestConnID;
|
||||
m_Server.AddSession (session);
|
||||
session->SendPeerTest (5, newSignedData.data (), newSignedData.size (), addr->i);
|
||||
}
|
||||
else
|
||||
code = eSSU2PeerTestCodeCharlieAliceIsAlreadyConnected;
|
||||
}
|
||||
else
|
||||
code = eSSU2PeerTestCodeCharlieUnsupportedAddress;
|
||||
|
Loading…
Reference in New Issue
Block a user