Browse Source

SSU2 connect timer

pull/1769/head
orignal 3 years ago
parent
commit
2a5cf3e4a8
  1. 2
      libi2pd/SSU2.cpp
  2. 39
      libi2pd/SSU2Session.cpp
  3. 4
      libi2pd/SSU2Session.h

2
libi2pd/SSU2.cpp

@ -433,7 +433,7 @@ namespace transport
if (!session) return; if (!session) return;
auto address = session->GetAddress (); auto address = session->GetAddress ();
if (!address) return; if (!address) return;
session->SetState (eSSU2SessionStateIntroduced); session->WaitForIntroduction ();
// try to find existing session first // try to find existing session first
for (auto& it: address->ssu->introducers) for (auto& it: address->ssu->introducers)
{ {

39
libi2pd/SSU2Session.cpp

@ -25,7 +25,8 @@ namespace transport
m_Server (server), m_Address (addr), m_RemoteTransports (0), m_Server (server), m_Address (addr), m_RemoteTransports (0),
m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown), m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown),
m_SendPacketNum (0), m_ReceivePacketNum (0), m_IsDataReceived (false), m_SendPacketNum (0), m_ReceivePacketNum (0), m_IsDataReceived (false),
m_WindowSize (SSU2_MAX_WINDOW_SIZE), m_RelayTag (0) m_WindowSize (SSU2_MAX_WINDOW_SIZE), m_RelayTag (0),
m_ConnectTimer (server.GetService ())
{ {
m_NoiseState.reset (new i2p::crypto::NoiseSymmetricState); m_NoiseState.reset (new i2p::crypto::NoiseSymmetricState);
if (in_RemoteRouter && m_Address) if (in_RemoteRouter && m_Address)
@ -50,12 +51,34 @@ namespace transport
void SSU2Session::Connect () void SSU2Session::Connect ()
{ {
if (m_State == eSSU2SessionStateUnknown)
{
ScheduleConnectTimer ();
auto token = m_Server.FindOutgoingToken (m_RemoteEndpoint); auto token = m_Server.FindOutgoingToken (m_RemoteEndpoint);
if (token) if (token)
SendSessionRequest (token); SendSessionRequest (token);
else else
SendTokenRequest (); SendTokenRequest ();
} }
}
void SSU2Session::ScheduleConnectTimer ()
{
m_ConnectTimer.cancel ();
m_ConnectTimer.expires_from_now (boost::posix_time::seconds(SSU2_CONNECT_TIMEOUT));
m_ConnectTimer.async_wait (std::bind (&SSU2Session::HandleConnectTimer,
shared_from_this (), std::placeholders::_1));
}
void SSU2Session::HandleConnectTimer (const boost::system::error_code& ecode)
{
if (!ecode)
{
// timeout expired
LogPrint (eLogWarning, "SSU2: Session with ", m_RemoteEndpoint, " was not established after ", SSU2_CONNECT_TIMEOUT, " seconds");
Terminate ();
}
}
bool SSU2Session::Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag) bool SSU2Session::Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag)
{ {
@ -100,6 +123,12 @@ namespace transport
return true; return true;
} }
void SSU2Session::WaitForIntroduction ()
{
m_State = eSSU2SessionStateIntroduced;
ScheduleConnectTimer ();
}
void SSU2Session::SendPeerTest () void SSU2Session::SendPeerTest ()
{ {
// we are Alice // we are Alice
@ -125,6 +154,7 @@ namespace transport
if (m_State != eSSU2SessionStateTerminated) if (m_State != eSSU2SessionStateTerminated)
{ {
m_State = eSSU2SessionStateTerminated; m_State = eSSU2SessionStateTerminated;
m_ConnectTimer.cancel ();
transports.PeerDisconnected (shared_from_this ()); transports.PeerDisconnected (shared_from_this ());
m_OnEstablished = nullptr; m_OnEstablished = nullptr;
m_Server.RemoveSession (m_SourceConnID); m_Server.RemoveSession (m_SourceConnID);
@ -147,6 +177,7 @@ namespace transport
m_EphemeralKeys = nullptr; m_EphemeralKeys = nullptr;
m_NoiseState.reset (nullptr); m_NoiseState.reset (nullptr);
m_SessionConfirmedFragment1.reset (nullptr); m_SessionConfirmedFragment1.reset (nullptr);
m_ConnectTimer.cancel ();
SetTerminationTimeout (SSU2_TERMINATION_TIMEOUT); SetTerminationTimeout (SSU2_TERMINATION_TIMEOUT);
transports.PeerConnected (shared_from_this ()); transports.PeerConnected (shared_from_this ());
if (m_OnEstablished) if (m_OnEstablished)
@ -1354,10 +1385,16 @@ namespace transport
} }
} }
else else
{
LogPrint (eLogWarning, "SSU2: RelayResponse signature verification failed"); LogPrint (eLogWarning, "SSU2: RelayResponse signature verification failed");
m_Server.GetService ().post (std::bind (&SSU2Session::Terminate, it->second.first));
}
} }
else else
{
LogPrint (eLogInfo, "SSU2: RelayResponse status code=", (int)buf[1]); LogPrint (eLogInfo, "SSU2: RelayResponse status code=", (int)buf[1]);
m_Server.GetService ().post (std::bind (&SSU2Session::Terminate, it->second.first));
}
} }
m_RelaySessions.erase (it); m_RelaySessions.erase (it);
} }

4
libi2pd/SSU2Session.h

@ -175,6 +175,7 @@ namespace transport
void Connect (); void Connect ();
bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag); bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
void WaitForIntroduction ();
void SendPeerTest (); // Alice, Data message void SendPeerTest (); // Alice, Data message
void Terminate (); void Terminate ();
void TerminateByTimeout (); void TerminateByTimeout ();
@ -201,6 +202,8 @@ namespace transport
private: private:
void Established (); void Established ();
void ScheduleConnectTimer ();
void HandleConnectTimer (const boost::system::error_code& ecode);
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs); void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
bool SendQueue (); bool SendQueue ();
void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg); void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg);
@ -274,6 +277,7 @@ namespace transport
size_t m_WindowSize; size_t m_WindowSize;
uint32_t m_RelayTag; // between Bob and Charlie uint32_t m_RelayTag; // between Bob and Charlie
OnEstablished m_OnEstablished; // callback from Established OnEstablished m_OnEstablished; // callback from Established
boost::asio::deadline_timer m_ConnectTimer;
}; };
inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce) inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce)

Loading…
Cancel
Save