send termiation with reason

This commit is contained in:
orignal 2022-07-09 17:05:23 -04:00
parent bb6227281a
commit 3ff3417ff2
4 changed files with 48 additions and 12 deletions

View File

@ -148,7 +148,7 @@ namespace transport
void SSU2Server::Receive (boost::asio::ip::udp::socket& socket)
{
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)));
}
@ -388,7 +388,7 @@ namespace transport
m_LastSession->ProcessPeerTest (buf, len);
break;
case eSSU2SessionStateClosing:
m_LastSession->RequestTermination (); // send termination again
m_LastSession->RequestTermination (eSSU2TerminationReasonIdleTimeout); // send termination again
break;
case eSSU2SessionStateTerminated:
m_LastSession = nullptr;
@ -630,7 +630,7 @@ namespace transport
else if (it.second->IsTerminationTimeoutExpired (ts))
{
if (it.second->IsEstablished ())
it.second->RequestTermination ();
it.second->RequestTermination (eSSU2TerminationReasonIdleTimeout);
else
GetService ().post (std::bind (&SSU2Session::Terminate, it.second));
}

View File

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

View File

@ -25,7 +25,7 @@ namespace transport
m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown),
m_SendPacketNum (0), m_ReceivePacketNum (0), m_IsDataReceived (false),
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);
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)
{
m_State = eSSU2SessionStateClosing;
m_TerminationReason = reason;
SendTermination ();
}
}
@ -329,7 +330,7 @@ namespace transport
LogPrint (eLogInfo, "SSU2: Packet was not Acked after ", it->second->numResends, " attempts. Terminate session");
m_SentPackets.clear ();
m_SendQueue.clear ();
RequestTermination ();
RequestTermination (eSSU2TerminationReasonTimeout);
return;
}
else
@ -2097,6 +2098,15 @@ namespace transport
return CreatePeerTestBlock (buf, len, 1, eSSU2PeerTestCodeAccept, nullptr,
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)
{
@ -2157,10 +2167,7 @@ namespace transport
void SSU2Session::SendTermination ()
{
uint8_t payload[32];
size_t payloadSize = 12;
payload[0] = eSSU2BlkTermination;
htobe16buf (payload + 1, 9);
memset (payload + 3, 0, 9);
size_t payloadSize = CreateTerminationBlock (payload, 32);
payloadSize += CreatePaddingBlock (payload + payloadSize, 32 - payloadSize);
SendData (payload, payloadSize);
}

View File

@ -31,6 +31,7 @@ namespace transport
const int SSU2_TOKEN_EXPIRATION_THRESHOLD = 2; // in seconds
const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in 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_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
const int SSU2_HANDSHAKE_RESEND_INTERVAL = 1; // in seconds
@ -119,6 +120,32 @@ namespace transport
eSSU2RelayResponseCodeCharlieSignatureFailure = 67,
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
{
@ -189,7 +216,7 @@ namespace transport
void WaitForIntroduction ();
void SendPeerTest (); // Alice, Data message
void Terminate ();
void RequestTermination ();
void RequestTermination (SSU2TerminationReason reason);
void CleanUp (uint64_t ts);
void FlushData ();
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 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 CreateTerminationBlock (uint8_t * buf, size_t len);
private:
@ -291,6 +319,7 @@ namespace transport
uint32_t m_RelayTag; // between Bob and Charlie
OnEstablished m_OnEstablished; // callback from Established
boost::asio::deadline_timer m_ConnectTimer;
SSU2TerminationReason m_TerminationReason;
};
inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce)