Browse Source

send termiation with reason

pull/1774/head
orignal 2 years ago
parent
commit
3ff3417ff2
  1. 6
      libi2pd/SSU2.cpp
  2. 2
      libi2pd/SSU2.h
  3. 21
      libi2pd/SSU2Session.cpp
  4. 31
      libi2pd/SSU2Session.h

6
libi2pd/SSU2.cpp

@ -148,7 +148,7 @@ namespace transport
void SSU2Server::Receive (boost::asio::ip::udp::socket& socket) void SSU2Server::Receive (boost::asio::ip::udp::socket& socket)
{ {
Packet * packet = m_PacketsPool.AcquireMt (); Packet * packet = m_PacketsPool.AcquireMt ();
socket.async_receive_from (boost::asio::buffer (packet->buf, SSU2_MTU), packet->from, socket.async_receive_from (boost::asio::buffer (packet->buf, SSU2_MAX_PACKET_SIZE), packet->from,
std::bind (&SSU2Server::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet, std::ref (socket))); std::bind (&SSU2Server::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet, std::ref (socket)));
} }
@ -388,7 +388,7 @@ namespace transport
m_LastSession->ProcessPeerTest (buf, len); m_LastSession->ProcessPeerTest (buf, len);
break; break;
case eSSU2SessionStateClosing: case eSSU2SessionStateClosing:
m_LastSession->RequestTermination (); // send termination again m_LastSession->RequestTermination (eSSU2TerminationReasonIdleTimeout); // send termination again
break; break;
case eSSU2SessionStateTerminated: case eSSU2SessionStateTerminated:
m_LastSession = nullptr; m_LastSession = nullptr;
@ -630,7 +630,7 @@ namespace transport
else if (it.second->IsTerminationTimeoutExpired (ts)) else if (it.second->IsTerminationTimeoutExpired (ts))
{ {
if (it.second->IsEstablished ()) if (it.second->IsEstablished ())
it.second->RequestTermination (); it.second->RequestTermination (eSSU2TerminationReasonIdleTimeout);
else else
GetService ().post (std::bind (&SSU2Session::Terminate, it.second)); GetService ().post (std::bind (&SSU2Session::Terminate, it.second));
} }

2
libi2pd/SSU2.h

@ -25,7 +25,7 @@ namespace transport
{ {
struct Packet struct Packet
{ {
uint8_t buf[SSU2_MTU]; uint8_t buf[SSU2_MAX_PACKET_SIZE];
size_t len; size_t len;
boost::asio::ip::udp::endpoint from; boost::asio::ip::udp::endpoint from;
}; };

21
libi2pd/SSU2Session.cpp

@ -25,7 +25,7 @@ namespace transport
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_ConnectTimer (server.GetService ()), m_TerminationReason (eSSU2TerminationReasonNormalClose)
{ {
m_NoiseState.reset (new i2p::crypto::NoiseSymmetricState); m_NoiseState.reset (new i2p::crypto::NoiseSymmetricState);
if (in_RemoteRouter && m_Address) if (in_RemoteRouter && m_Address)
@ -168,11 +168,12 @@ namespace transport
} }
} }
void SSU2Session::RequestTermination () void SSU2Session::RequestTermination (SSU2TerminationReason reason)
{ {
if (m_State == eSSU2SessionStateEstablished || m_State == eSSU2SessionStateClosing) if (m_State == eSSU2SessionStateEstablished || m_State == eSSU2SessionStateClosing)
{ {
m_State = eSSU2SessionStateClosing; m_State = eSSU2SessionStateClosing;
m_TerminationReason = reason;
SendTermination (); SendTermination ();
} }
} }
@ -329,7 +330,7 @@ namespace transport
LogPrint (eLogInfo, "SSU2: Packet was not Acked after ", it->second->numResends, " attempts. Terminate session"); LogPrint (eLogInfo, "SSU2: Packet was not Acked after ", it->second->numResends, " attempts. Terminate session");
m_SentPackets.clear (); m_SentPackets.clear ();
m_SendQueue.clear (); m_SendQueue.clear ();
RequestTermination (); RequestTermination (eSSU2TerminationReasonTimeout);
return; return;
} }
else else
@ -2098,6 +2099,15 @@ namespace transport
signedData, 10 + asz + i2p::context.GetIdentity ()->GetSignatureLen ()); signedData, 10 + asz + i2p::context.GetIdentity ()->GetSignatureLen ());
} }
size_t SSU2Session::CreateTerminationBlock (uint8_t * buf, size_t len)
{
buf[0] = eSSU2BlkTermination;
htobe16buf (buf + 1, 9);
htobe64buf (buf + 3, m_ReceivePacketNum);
buf[11] = (uint8_t)m_TerminationReason;
return 12;
}
std::shared_ptr<const i2p::data::RouterInfo> SSU2Session::ExtractRouterInfo (const uint8_t * buf, size_t size) std::shared_ptr<const i2p::data::RouterInfo> SSU2Session::ExtractRouterInfo (const uint8_t * buf, size_t size)
{ {
if (size < 2) return nullptr; if (size < 2) return nullptr;
@ -2157,10 +2167,7 @@ namespace transport
void SSU2Session::SendTermination () void SSU2Session::SendTermination ()
{ {
uint8_t payload[32]; uint8_t payload[32];
size_t payloadSize = 12; size_t payloadSize = CreateTerminationBlock (payload, 32);
payload[0] = eSSU2BlkTermination;
htobe16buf (payload + 1, 9);
memset (payload + 3, 0, 9);
payloadSize += CreatePaddingBlock (payload + payloadSize, 32 - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, 32 - payloadSize);
SendData (payload, payloadSize); SendData (payload, payloadSize);
} }

31
libi2pd/SSU2Session.h

@ -31,6 +31,7 @@ namespace transport
const int SSU2_TOKEN_EXPIRATION_THRESHOLD = 2; // in seconds const int SSU2_TOKEN_EXPIRATION_THRESHOLD = 2; // in seconds
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds
const int SSU2_PEER_TEST_EXPIRATION_TIMEOUT = 60; // 60 seconds const int SSU2_PEER_TEST_EXPIRATION_TIMEOUT = 60; // 60 seconds
const size_t SSU2_MAX_PACKET_SIZE = 1500;
const size_t SSU2_MTU = 1440; // TODO: should be 1456 for ipv4 const size_t SSU2_MTU = 1440; // TODO: should be 1456 for ipv4
const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32; const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
const int SSU2_HANDSHAKE_RESEND_INTERVAL = 1; // in seconds const int SSU2_HANDSHAKE_RESEND_INTERVAL = 1; // in seconds
@ -120,6 +121,32 @@ namespace transport
eSSU2RelayResponseCodeCharlieAliceIsUnknown = 70 eSSU2RelayResponseCodeCharlieAliceIsUnknown = 70
}; };
enum SSU2TerminationReason
{
eSSU2TerminationReasonNormalClose = 0,
eSSU2TerminationReasonTerminationReceived = 1,
eSSU2TerminationReasonIdleTimeout = 2,
eSSU2TerminationReasonRouterShutdown = 3,
eSSU2TerminationReasonDataPhaseAEADFailure= 4,
eSSU2TerminationReasonIncompatibleOptions = 5,
eSSU2TerminationReasonTncompatibleSignatureType = 6,
eSSU2TerminationReasonClockSkew = 7,
eSSU2TerminationPaddingViolation = 8,
eSSU2TerminationReasonAEADFramingError = 9,
eSSU2TerminationReasonPayloadFormatError = 10,
eSSU2TerminationReasonSessionRequestError = 11,
eSSU2TerminationReasonSessionCreatedError = 12,
eSSU2TerminationReasonSessionConfirmedError = 13,
eSSU2TerminationReasonTimeout = 14,
eSSU2TerminationReasonRouterInfoSignatureVerificationFail = 15,
eSSU2TerminationReasonInvalidS = 16,
eSSU2TerminationReasonBanned = 17,
eSSU2TerminationReasonBadToken = 18,
eSSU2TerminationReasonConnectionLimits = 19,
eSSU2TerminationReasonIncompatibleVersion = 20,
eSSU2TerminationReasonWrongNetID = 21
};
struct SSU2IncompleteMessage struct SSU2IncompleteMessage
{ {
struct Fragment struct Fragment
@ -189,7 +216,7 @@ namespace transport
void WaitForIntroduction (); void WaitForIntroduction ();
void SendPeerTest (); // Alice, Data message void SendPeerTest (); // Alice, Data message
void Terminate (); void Terminate ();
void RequestTermination (); void RequestTermination (SSU2TerminationReason reason);
void CleanUp (uint64_t ts); void CleanUp (uint64_t ts);
void FlushData (); void FlushData ();
void Done () override; void Done () override;
@ -264,6 +291,7 @@ namespace transport
size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce, bool endpoint, uint64_t token); // add endpoint for Chralie and no endpoint for Bob size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, SSU2RelayResponseCode code, uint32_t nonce, bool endpoint, uint64_t token); // add endpoint for Chralie and no endpoint for Bob
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);
size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint32_t nonce); // Alice size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint32_t nonce); // Alice
size_t CreateTerminationBlock (uint8_t * buf, size_t len);
private: private:
@ -291,6 +319,7 @@ namespace transport
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; boost::asio::deadline_timer m_ConnectTimer;
SSU2TerminationReason m_TerminationReason;
}; };
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