Garlic.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #ifndef GARLIC_H__
  2. #define GARLIC_H__
  3. #include <inttypes.h>
  4. #include <map>
  5. #include <list>
  6. #include <string>
  7. #include <thread>
  8. #include <mutex>
  9. #include <memory>
  10. #include "Crypto.h"
  11. #include "I2NPProtocol.h"
  12. #include "LeaseSet.h"
  13. #include "Queue.h"
  14. #include "Identity.h"
  15. namespace i2p
  16. {
  17. namespace tunnel
  18. {
  19. class OutboundTunnel;
  20. }
  21. namespace garlic
  22. {
  23. enum GarlicDeliveryType
  24. {
  25. eGarlicDeliveryTypeLocal = 0,
  26. eGarlicDeliveryTypeDestination = 1,
  27. eGarlicDeliveryTypeRouter = 2,
  28. eGarlicDeliveryTypeTunnel = 3
  29. };
  30. struct ElGamalBlock
  31. {
  32. uint8_t sessionKey[32];
  33. uint8_t preIV[32];
  34. uint8_t padding[158];
  35. };
  36. const int INCOMING_TAGS_EXPIRATION_TIMEOUT = 960; // 16 minutes
  37. const int OUTGOING_TAGS_EXPIRATION_TIMEOUT = 720; // 12 minutes
  38. const int OUTGOING_TAGS_CONFIRMATION_TIMEOUT = 10; // 10 seconds
  39. const int LEASET_CONFIRMATION_TIMEOUT = 4000; // in milliseconds
  40. const int ROUTING_PATH_EXPIRATION_TIMEOUT = 30; // 30 seconds
  41. const int ROUTING_PATH_MAX_NUM_TIMES_USED = 100; // how many times might be used
  42. struct SessionTag: public i2p::data::Tag<32>
  43. {
  44. SessionTag (const uint8_t * buf, uint32_t ts = 0): Tag<32>(buf), creationTime (ts) {};
  45. SessionTag () = default;
  46. SessionTag (const SessionTag& ) = default;
  47. SessionTag& operator= (const SessionTag& ) = default;
  48. #ifndef _WIN32
  49. SessionTag (SessionTag&& ) = default;
  50. SessionTag& operator= (SessionTag&& ) = default;
  51. #endif
  52. uint32_t creationTime; // seconds since epoch
  53. };
  54. // AESDecryption is associated with session tags and store key
  55. class AESDecryption: public i2p::crypto::CBCDecryption
  56. {
  57. public:
  58. AESDecryption (const uint8_t * key): m_Key (key)
  59. {
  60. SetKey (key);
  61. }
  62. const i2p::crypto::AESKey& GetKey () const { return m_Key; };
  63. private:
  64. i2p::crypto::AESKey m_Key;
  65. };
  66. struct GarlicRoutingPath
  67. {
  68. std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
  69. std::shared_ptr<const i2p::data::Lease> remoteLease;
  70. int rtt; // RTT
  71. uint32_t updateTime; // seconds since epoch
  72. int numTimesUsed;
  73. };
  74. class GarlicDestination;
  75. class GarlicRoutingSession: public std::enable_shared_from_this<GarlicRoutingSession>
  76. {
  77. enum LeaseSetUpdateStatus
  78. {
  79. eLeaseSetUpToDate = 0,
  80. eLeaseSetUpdated,
  81. eLeaseSetSubmitted,
  82. eLeaseSetDoNotSend
  83. };
  84. struct UnconfirmedTags
  85. {
  86. UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
  87. ~UnconfirmedTags () { delete[] sessionTags; };
  88. uint32_t msgID;
  89. int numTags;
  90. SessionTag * sessionTags;
  91. uint32_t tagsCreationTime;
  92. };
  93. public:
  94. GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr<const i2p::data::RoutingDestination> destination,
  95. int numTags, bool attachLeaseSet);
  96. GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption
  97. ~GarlicRoutingSession ();
  98. std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
  99. void MessageConfirmed (uint32_t msgID);
  100. bool CleanupExpiredTags (); // returns true if something left
  101. bool CleanupUnconfirmedTags (); // returns true if something has been deleted
  102. void SetLeaseSetUpdated ()
  103. {
  104. if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated;
  105. };
  106. bool IsLeaseSetNonConfirmed () const { return m_LeaseSetUpdateStatus == eLeaseSetSubmitted; };
  107. bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; };
  108. uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; }
  109. std::shared_ptr<GarlicRoutingPath> GetSharedRoutingPath ();
  110. void SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path);
  111. const GarlicDestination * GetOwner () const { return m_Owner; }
  112. void SetOwner (GarlicDestination * owner) { m_Owner = owner; }
  113. private:
  114. size_t CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg);
  115. size_t CreateGarlicPayload (uint8_t * payload, std::shared_ptr<const I2NPMessage> msg, UnconfirmedTags * newTags);
  116. size_t CreateGarlicClove (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg, bool isDestination);
  117. size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID);
  118. void TagsConfirmed (uint32_t msgID);
  119. UnconfirmedTags * GenerateSessionTags ();
  120. private:
  121. GarlicDestination * m_Owner;
  122. std::shared_ptr<const i2p::data::RoutingDestination> m_Destination;
  123. i2p::crypto::AESKey m_SessionKey;
  124. std::list<SessionTag> m_SessionTags;
  125. int m_NumTags;
  126. std::map<uint32_t, std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs; // msgID->tags
  127. LeaseSetUpdateStatus m_LeaseSetUpdateStatus;
  128. uint32_t m_LeaseSetUpdateMsgID;
  129. uint64_t m_LeaseSetSubmissionTime; // in milliseconds
  130. i2p::crypto::CBCEncryption m_Encryption;
  131. std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
  132. public:
  133. // for HTTP only
  134. size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
  135. };
  136. //using GarlicRoutingSessionPtr = std::shared_ptr<GarlicRoutingSession>;
  137. typedef std::shared_ptr<GarlicRoutingSession> GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8
  138. class GarlicDestination: public i2p::data::LocalDestination
  139. {
  140. public:
  141. GarlicDestination ();
  142. ~GarlicDestination ();
  143. void CleanUp ();
  144. void SetNumTags (int numTags) { m_NumTags = numTags; };
  145. std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet);
  146. void CleanupExpiredTags ();
  147. void RemoveDeliveryStatusSession (uint32_t msgID);
  148. std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
  149. std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false);
  150. void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
  151. virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
  152. void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
  153. virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
  154. virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
  155. virtual void SetLeaseSetUpdated ();
  156. virtual std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet () = 0; // TODO
  157. virtual std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const = 0;
  158. virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from) = 0;
  159. protected:
  160. void HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg);
  161. void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
  162. void SaveTags ();
  163. void LoadTags ();
  164. private:
  165. void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
  166. std::shared_ptr<i2p::tunnel::InboundTunnel> from);
  167. void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
  168. private:
  169. BN_CTX * m_Ctx; // incoming
  170. // outgoing sessions
  171. int m_NumTags;
  172. std::mutex m_SessionsMutex;
  173. std::map<i2p::data::IdentHash, GarlicRoutingSessionPtr> m_Sessions;
  174. // incoming
  175. std::map<SessionTag, std::shared_ptr<AESDecryption> > m_Tags;
  176. // DeliveryStatus
  177. std::mutex m_DeliveryStatusSessionsMutex;
  178. std::map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
  179. public:
  180. // for HTTP only
  181. size_t GetNumIncomingTags () const { return m_Tags.size (); }
  182. const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
  183. };
  184. void CleanUpTagsFiles ();
  185. }
  186. }
  187. #endif