Tunnel.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #ifndef TUNNEL_H__
  2. #define TUNNEL_H__
  3. #include <inttypes.h>
  4. #include <map>
  5. #include <unordered_map>
  6. #include <list>
  7. #include <vector>
  8. #include <string>
  9. #include <thread>
  10. #include <mutex>
  11. #include <memory>
  12. #include "Queue.h"
  13. #include "Crypto.h"
  14. #include "TunnelConfig.h"
  15. #include "TunnelPool.h"
  16. #include "TransitTunnel.h"
  17. #include "TunnelEndpoint.h"
  18. #include "TunnelGateway.h"
  19. #include "TunnelBase.h"
  20. #include "I2NPProtocol.h"
  21. #include "Event.h"
  22. namespace i2p
  23. {
  24. namespace tunnel
  25. {
  26. template<typename TunnelT>
  27. static void EmitTunnelEvent(const std::string & ev, const TunnelT & t)
  28. {
  29. #ifdef WITH_EVENTS
  30. EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}});
  31. #else
  32. (void) ev;
  33. (void) t;
  34. #endif
  35. }
  36. template<typename TunnelT, typename T>
  37. static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val)
  38. {
  39. #ifdef WITH_EVENTS
  40. EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", std::to_string(val)}, {"inbound", std::to_string(t->IsInbound())}});
  41. #else
  42. (void) ev;
  43. (void) t;
  44. (void) val;
  45. #endif
  46. }
  47. template<typename TunnelT>
  48. static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val)
  49. {
  50. #ifdef WITH_EVENTS
  51. EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", val}, {"inbound", std::to_string(t->IsInbound())}});
  52. #else
  53. (void) ev;
  54. (void) t;
  55. (void) val;
  56. #endif
  57. }
  58. const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
  59. const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
  60. const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes
  61. const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds
  62. const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message
  63. enum TunnelState
  64. {
  65. eTunnelStatePending,
  66. eTunnelStateBuildReplyReceived,
  67. eTunnelStateBuildFailed,
  68. eTunnelStateEstablished,
  69. eTunnelStateTestFailed,
  70. eTunnelStateFailed,
  71. eTunnelStateExpiring
  72. };
  73. class OutboundTunnel;
  74. class InboundTunnel;
  75. class Tunnel: public TunnelBase
  76. {
  77. struct TunnelHop
  78. {
  79. std::shared_ptr<const i2p::data::IdentityEx> ident;
  80. i2p::crypto::TunnelDecryption decryption;
  81. };
  82. public:
  83. Tunnel (std::shared_ptr<const TunnelConfig> config);
  84. ~Tunnel ();
  85. void Build (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
  86. std::shared_ptr<const TunnelConfig> GetTunnelConfig () const { return m_Config; }
  87. std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetPeers () const;
  88. std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetInvertedPeers () const;
  89. TunnelState GetState () const { return m_State; };
  90. void SetState (TunnelState state);
  91. bool IsEstablished () const { return m_State == eTunnelStateEstablished; };
  92. bool IsFailed () const { return m_State == eTunnelStateFailed; };
  93. bool IsRecreated () const { return m_IsRecreated; };
  94. void SetIsRecreated () { m_IsRecreated = true; };
  95. int GetNumHops () const { return m_Hops.size (); };
  96. virtual bool IsInbound() const = 0;
  97. std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
  98. void SetTunnelPool (std::shared_ptr<TunnelPool> pool) { m_Pool = pool; };
  99. bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
  100. virtual void Print (std::stringstream&) const {};
  101. // implements TunnelBase
  102. void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
  103. void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
  104. /** @brief add latency sample */
  105. void AddLatencySample(const uint64_t ms) { m_Latency = (m_Latency + ms) >> 1; }
  106. /** @brief get this tunnel's estimated latency */
  107. uint64_t GetMeanLatency() const { return m_Latency; }
  108. /** @brief return true if this tunnel's latency fits in range [lowerbound, upperbound] */
  109. bool LatencyFitsRange(uint64_t lowerbound, uint64_t upperbound) const;
  110. bool LatencyIsKnown() const { return m_Latency > 0; }
  111. protected:
  112. void PrintHops (std::stringstream& s) const;
  113. private:
  114. std::shared_ptr<const TunnelConfig> m_Config;
  115. std::vector<std::unique_ptr<TunnelHop> > m_Hops;
  116. std::shared_ptr<TunnelPool> m_Pool; // pool, tunnel belongs to, or null
  117. TunnelState m_State;
  118. bool m_IsRecreated;
  119. uint64_t m_Latency; // in milliseconds
  120. };
  121. class OutboundTunnel: public Tunnel
  122. {
  123. public:
  124. OutboundTunnel (std::shared_ptr<const TunnelConfig> config):
  125. Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {};
  126. void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg);
  127. virtual void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
  128. const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
  129. virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
  130. void Print (std::stringstream& s) const;
  131. // implements TunnelBase
  132. void HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg);
  133. bool IsInbound() const { return false; }
  134. private:
  135. std::mutex m_SendMutex;
  136. TunnelGateway m_Gateway;
  137. i2p::data::IdentHash m_EndpointIdentHash;
  138. };
  139. class InboundTunnel: public Tunnel, public std::enable_shared_from_this<InboundTunnel>
  140. {
  141. public:
  142. InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
  143. void HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg);
  144. virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
  145. void Print (std::stringstream& s) const;
  146. bool IsInbound() const { return true; }
  147. // override TunnelBase
  148. void Cleanup () { m_Endpoint.Cleanup (); };
  149. private:
  150. TunnelEndpoint m_Endpoint;
  151. };
  152. class ZeroHopsInboundTunnel: public InboundTunnel
  153. {
  154. public:
  155. ZeroHopsInboundTunnel ();
  156. void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
  157. void Print (std::stringstream& s) const;
  158. size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
  159. private:
  160. size_t m_NumReceivedBytes;
  161. };
  162. class ZeroHopsOutboundTunnel: public OutboundTunnel
  163. {
  164. public:
  165. ZeroHopsOutboundTunnel ();
  166. void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs);
  167. void Print (std::stringstream& s) const;
  168. size_t GetNumSentBytes () const { return m_NumSentBytes; };
  169. private:
  170. size_t m_NumSentBytes;
  171. };
  172. class Tunnels
  173. {
  174. public:
  175. Tunnels ();
  176. ~Tunnels ();
  177. void Start ();
  178. void Stop ();
  179. std::shared_ptr<InboundTunnel> GetPendingInboundTunnel (uint32_t replyMsgID);
  180. std::shared_ptr<OutboundTunnel> GetPendingOutboundTunnel (uint32_t replyMsgID);
  181. std::shared_ptr<InboundTunnel> GetNextInboundTunnel ();
  182. std::shared_ptr<OutboundTunnel> GetNextOutboundTunnel ();
  183. std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; };
  184. std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID);
  185. int GetTransitTunnelsExpirationTimeout ();
  186. void AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel);
  187. void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel);
  188. void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel);
  189. std::shared_ptr<InboundTunnel> CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<OutboundTunnel> outboundTunnel);
  190. std::shared_ptr<OutboundTunnel> CreateOutboundTunnel (std::shared_ptr<TunnelConfig> config);
  191. void PostTunnelData (std::shared_ptr<I2NPMessage> msg);
  192. void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
  193. void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
  194. void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
  195. std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops,
  196. int numOuboundHops, int numInboundTunnels, int numOutboundTunnels);
  197. void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
  198. void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
  199. private:
  200. template<class TTunnel>
  201. std::shared_ptr<TTunnel> CreateTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
  202. template<class TTunnel>
  203. std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);
  204. void HandleTunnelGatewayMsg (std::shared_ptr<TunnelBase> tunnel, std::shared_ptr<I2NPMessage> msg);
  205. void Run ();
  206. void ManageTunnels ();
  207. void ManageOutboundTunnels ();
  208. void ManageInboundTunnels ();
  209. void ManageTransitTunnels ();
  210. void ManagePendingTunnels ();
  211. template<class PendingTunnels>
  212. void ManagePendingTunnels (PendingTunnels& pendingTunnels);
  213. void ManageTunnelPools ();
  214. std::shared_ptr<ZeroHopsInboundTunnel> CreateZeroHopsInboundTunnel ();
  215. std::shared_ptr<ZeroHopsOutboundTunnel> CreateZeroHopsOutboundTunnel ();
  216. private:
  217. bool m_IsRunning;
  218. std::thread * m_Thread;
  219. std::map<uint32_t, std::shared_ptr<InboundTunnel> > m_PendingInboundTunnels; // by replyMsgID
  220. std::map<uint32_t, std::shared_ptr<OutboundTunnel> > m_PendingOutboundTunnels; // by replyMsgID
  221. std::list<std::shared_ptr<InboundTunnel> > m_InboundTunnels;
  222. std::list<std::shared_ptr<OutboundTunnel> > m_OutboundTunnels;
  223. std::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
  224. std::unordered_map<uint32_t, std::shared_ptr<TunnelBase> > m_Tunnels; // tunnelID->tunnel known by this id
  225. std::mutex m_PoolsMutex;
  226. std::list<std::shared_ptr<TunnelPool>> m_Pools;
  227. std::shared_ptr<TunnelPool> m_ExploratoryPool;
  228. i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue;
  229. // some stats
  230. int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations;
  231. public:
  232. // for HTTP only
  233. const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; };
  234. const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; };
  235. const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; };
  236. size_t CountTransitTunnels() const;
  237. size_t CountInboundTunnels() const;
  238. size_t CountOutboundTunnels() const;
  239. int GetQueueSize () { return m_Queue.GetSize (); };
  240. int GetTunnelCreationSuccessRate () const // in percents
  241. {
  242. int totalNum = m_NumSuccesiveTunnelCreations + m_NumFailedTunnelCreations;
  243. return totalNum ? m_NumSuccesiveTunnelCreations*100/totalNum : 0;
  244. }
  245. };
  246. extern Tunnels tunnels;
  247. }
  248. }
  249. #endif