SSUSession.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #ifndef SSU_SESSION_H__
  2. #define SSU_SESSION_H__
  3. #include <inttypes.h>
  4. #include <set>
  5. #include <memory>
  6. #include "Crypto.h"
  7. #include "I2NPProtocol.h"
  8. #include "TransportSession.h"
  9. #include "SSUData.h"
  10. namespace i2p
  11. {
  12. namespace transport
  13. {
  14. const uint8_t SSU_HEADER_EXTENDED_OPTIONS_INCLUDED = 0x04;
  15. struct SSUHeader
  16. {
  17. uint8_t mac[16];
  18. uint8_t iv[16];
  19. uint8_t flag;
  20. uint8_t time[4];
  21. uint8_t GetPayloadType () const { return flag >> 4; };
  22. bool IsExtendedOptions () const { return flag & SSU_HEADER_EXTENDED_OPTIONS_INCLUDED; };
  23. };
  24. const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
  25. const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
  26. const int SSU_CLOCK_SKEW = 60; // in seconds
  27. const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768;
  28. // payload types (4 bits)
  29. const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0;
  30. const uint8_t PAYLOAD_TYPE_SESSION_CREATED = 1;
  31. const uint8_t PAYLOAD_TYPE_SESSION_CONFIRMED = 2;
  32. const uint8_t PAYLOAD_TYPE_RELAY_REQUEST = 3;
  33. const uint8_t PAYLOAD_TYPE_RELAY_RESPONSE = 4;
  34. const uint8_t PAYLOAD_TYPE_RELAY_INTRO = 5;
  35. const uint8_t PAYLOAD_TYPE_DATA = 6;
  36. const uint8_t PAYLOAD_TYPE_PEER_TEST = 7;
  37. const uint8_t PAYLOAD_TYPE_SESSION_DESTROYED = 8;
  38. // extended options
  39. const uint16_t EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG = 0x0001;
  40. enum SessionState
  41. {
  42. eSessionStateUnknown,
  43. eSessionStateIntroduced,
  44. eSessionStateEstablished,
  45. eSessionStateClosed,
  46. eSessionStateFailed
  47. };
  48. enum PeerTestParticipant
  49. {
  50. ePeerTestParticipantUnknown = 0,
  51. ePeerTestParticipantAlice1,
  52. ePeerTestParticipantAlice2,
  53. ePeerTestParticipantBob,
  54. ePeerTestParticipantCharlie
  55. };
  56. class SSUServer;
  57. class SSUSession: public TransportSession, public std::enable_shared_from_this<SSUSession>
  58. {
  59. public:
  60. SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint,
  61. std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, bool peerTest = false);
  62. void ProcessNextMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
  63. ~SSUSession ();
  64. void Connect ();
  65. void WaitForConnect ();
  66. void Introduce (const i2p::data::RouterInfo::Introducer& introducer,
  67. std::shared_ptr<const i2p::data::RouterInfo> to); // Alice to Charlie
  68. void WaitForIntroduction ();
  69. void Close ();
  70. void Done ();
  71. void Failed ();
  72. const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; };
  73. bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); };
  74. void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
  75. void SendPeerTest (); // Alice
  76. SessionState GetState () const { return m_State; };
  77. size_t GetNumSentBytes () const { return m_NumSentBytes; };
  78. size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
  79. void SendKeepAlive ();
  80. uint32_t GetRelayTag () const { return m_RelayTag; };
  81. const i2p::data::RouterInfo::IntroKey& GetIntroKey () const { return m_IntroKey; };
  82. uint32_t GetCreationTime () const { return m_CreationTime; };
  83. void FlushData ();
  84. private:
  85. boost::asio::io_service& GetService ();
  86. void CreateAESandMacKey (const uint8_t * pubKey);
  87. size_t GetSSUHeaderSize (const uint8_t * buf) const;
  88. void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
  89. void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session
  90. void ProcessSessionRequest (const uint8_t * buf, size_t len);
  91. void SendSessionRequest ();
  92. void SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce);
  93. void ProcessSessionCreated (uint8_t * buf, size_t len);
  94. void SendSessionCreated (const uint8_t * x, bool sendRelayTag = true);
  95. void ProcessSessionConfirmed (const uint8_t * buf, size_t len);
  96. void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen);
  97. void ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from);
  98. void SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from,
  99. const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to);
  100. void SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from);
  101. void ProcessRelayResponse (const uint8_t * buf, size_t len);
  102. void ProcessRelayIntro (const uint8_t * buf, size_t len);
  103. void Established ();
  104. void ScheduleConnectTimer ();
  105. void HandleConnectTimer (const boost::system::error_code& ecode);
  106. void ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
  107. void SendPeerTest (uint32_t nonce, const boost::asio::ip::address& address, uint16_t port, const uint8_t * introKey, bool toAddress = true, bool sendAddress = true);
  108. void ProcessData (uint8_t * buf, size_t len);
  109. void SendSessionDestroyed ();
  110. void Send (uint8_t type, const uint8_t * payload, size_t len); // with session key
  111. void Send (const uint8_t * buf, size_t size);
  112. void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey,
  113. const uint8_t * iv, const i2p::crypto::MACKey& macKey, uint8_t flag = 0);
  114. void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len); // with session key
  115. void Decrypt (uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey);
  116. void DecryptSessionKey (uint8_t * buf, size_t len);
  117. bool Validate (uint8_t * buf, size_t len, const i2p::crypto::MACKey& macKey);
  118. void Reset ();
  119. private:
  120. friend class SSUData; // TODO: change in later
  121. SSUServer& m_Server;
  122. const boost::asio::ip::udp::endpoint m_RemoteEndpoint;
  123. boost::asio::deadline_timer m_ConnectTimer;
  124. bool m_IsPeerTest;
  125. SessionState m_State;
  126. bool m_IsSessionKey;
  127. uint32_t m_RelayTag; // received from peer
  128. uint32_t m_SentRelayTag; // sent by us
  129. i2p::crypto::CBCEncryption m_SessionKeyEncryption;
  130. i2p::crypto::CBCDecryption m_SessionKeyDecryption;
  131. i2p::crypto::AESKey m_SessionKey;
  132. i2p::crypto::MACKey m_MacKey;
  133. i2p::data::RouterInfo::IntroKey m_IntroKey;
  134. uint32_t m_CreationTime; // seconds since epoch
  135. SSUData m_Data;
  136. bool m_IsDataReceived;
  137. std::unique_ptr<SignedData> m_SignedData; // we need it for SessionConfirmed only
  138. std::map<uint32_t, std::shared_ptr<const i2p::data::RouterInfo> > m_RelayRequests; // nonce->Charlie
  139. };
  140. }
  141. }
  142. #endif