diff --git a/SSU.cpp b/SSU.cpp index cc125ae0..c7b180ef 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -84,6 +84,11 @@ namespace ssu else { ScheduleTermination (); + // check for duplicate + const uint8_t * iv = ((SSUHeader *)buf)->iv; + if (m_ReceivedIVs.count (iv)) return; // duplicate detected + m_ReceivedIVs.insert (iv); + if (m_IsSessionKey && Validate (buf, len, m_MacKey)) // try session key first DecryptSessionKey (buf, len); else diff --git a/SSU.h b/SSU.h index e39a4e2e..b0930370 100644 --- a/SSU.h +++ b/SSU.h @@ -2,6 +2,7 @@ #define SSU_H__ #include +#include #include #include #include @@ -112,7 +113,21 @@ namespace ssu void HandleTerminationTimer (const boost::system::error_code& ecode); private: - + + union IV + { + uint8_t buf[16]; + uint64_t ll[2]; + + IV (const IV&) = default; + IV (const uint8_t * iv) { memcpy (buf, iv, 16); }; + bool operator< (const IV& other) const + { + if (ll[0] != other.ll[0]) return ll[0] < other.ll[0]; + return ll[1] < other.ll[1]; + }; + }; + friend class SSUData; // TODO: change in later SSUServer& m_Server; boost::asio::ip::udp::endpoint m_RemoteEndpoint; @@ -128,6 +143,7 @@ namespace ssu i2p::crypto::CBCDecryption m_SessionKeyDecryption; uint8_t m_SessionKey[32], m_MacKey[32]; std::list m_DelayedMessages; + std::set m_ReceivedIVs; SSUData m_Data; };