2020-05-22 16:18:41 +03:00
|
|
|
/*
|
2024-02-04 15:45:22 -05:00
|
|
|
* Copyright (c) 2013-2024, The PurpleI2P Project
|
2020-05-22 16:18:41 +03:00
|
|
|
*
|
|
|
|
* This file is part of Purple i2pd project and licensed under BSD3
|
|
|
|
*
|
|
|
|
* See full license text in LICENSE file at top of project tree
|
|
|
|
*/
|
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
#ifndef TUNNEL_H__
|
|
|
|
#define TUNNEL_H__
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <map>
|
2016-03-01 20:48:56 -05:00
|
|
|
#include <unordered_map>
|
2013-12-06 19:02:49 -05:00
|
|
|
#include <list>
|
2014-01-20 18:37:51 -05:00
|
|
|
#include <vector>
|
2013-12-06 19:02:49 -05:00
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
2014-04-03 12:19:12 -04:00
|
|
|
#include <mutex>
|
2015-01-19 22:28:13 -05:00
|
|
|
#include <memory>
|
2024-10-27 22:19:06 -04:00
|
|
|
#include <random>
|
2021-10-20 21:05:22 -04:00
|
|
|
#include "util.h"
|
2013-12-06 19:02:49 -05:00
|
|
|
#include "Queue.h"
|
2015-11-03 09:15:49 -05:00
|
|
|
#include "Crypto.h"
|
2013-12-06 19:02:49 -05:00
|
|
|
#include "TunnelConfig.h"
|
2014-03-14 12:35:02 -04:00
|
|
|
#include "TunnelPool.h"
|
2013-12-06 19:02:49 -05:00
|
|
|
#include "TransitTunnel.h"
|
|
|
|
#include "TunnelEndpoint.h"
|
|
|
|
#include "TunnelGateway.h"
|
|
|
|
#include "TunnelBase.h"
|
|
|
|
#include "I2NPProtocol.h"
|
|
|
|
|
|
|
|
namespace i2p
|
|
|
|
{
|
|
|
|
namespace tunnel
|
2016-10-20 12:14:32 -04:00
|
|
|
{
|
2018-01-06 11:48:51 +08:00
|
|
|
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
|
|
|
|
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
|
|
|
|
const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes
|
2014-09-26 10:15:34 -04:00
|
|
|
const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds
|
2020-09-21 19:22:53 -04:00
|
|
|
const int STANDARD_NUM_RECORDS = 4; // in VariableTunnelBuild message
|
2021-01-14 11:24:03 -05:00
|
|
|
const int MAX_NUM_RECORDS = 8;
|
2024-02-25 22:57:57 +02:00
|
|
|
const int UNKNOWN_LATENCY = -1;
|
2024-03-04 13:41:50 +02:00
|
|
|
const int HIGH_LATENCY_PER_HOP = 250000; // in microseconds
|
2022-12-30 18:06:47 -05:00
|
|
|
const int MAX_TUNNEL_MSGS_BATCH_SIZE = 100; // handle messages without interrupt
|
2023-03-05 20:08:15 -05:00
|
|
|
const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 5000;
|
2022-12-29 17:26:57 -05:00
|
|
|
const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds
|
|
|
|
const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds
|
|
|
|
const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds
|
2023-05-03 15:59:35 +02:00
|
|
|
|
2021-10-22 19:18:45 -04:00
|
|
|
const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12
|
2021-11-27 23:30:35 +03:00
|
|
|
const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6
|
|
|
|
|
2023-01-03 03:07:07 +03:00
|
|
|
const double TCSR_SMOOTHING_CONSTANT = 0.0005; // smoothing constant in exponentially weighted moving average
|
|
|
|
const double TCSR_START_VALUE = 0.1; // start value of tunnel creation success rate
|
|
|
|
|
2014-07-26 20:56:42 -04:00
|
|
|
enum TunnelState
|
|
|
|
{
|
|
|
|
eTunnelStatePending,
|
2014-09-26 10:15:34 -04:00
|
|
|
eTunnelStateBuildReplyReceived,
|
|
|
|
eTunnelStateBuildFailed,
|
2014-07-26 20:56:42 -04:00
|
|
|
eTunnelStateEstablished,
|
|
|
|
eTunnelStateTestFailed,
|
2014-08-26 10:31:32 -04:00
|
|
|
eTunnelStateFailed,
|
|
|
|
eTunnelStateExpiring
|
2018-01-06 11:48:51 +08:00
|
|
|
};
|
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
class OutboundTunnel;
|
|
|
|
class InboundTunnel;
|
2024-02-04 15:45:22 -05:00
|
|
|
class Tunnel: public TunnelBase,
|
|
|
|
public std::enable_shared_from_this<Tunnel>
|
2013-12-06 19:02:49 -05:00
|
|
|
{
|
2015-11-03 09:15:49 -05:00
|
|
|
struct TunnelHop
|
|
|
|
{
|
|
|
|
std::shared_ptr<const i2p::data::IdentityEx> ident;
|
|
|
|
i2p::crypto::TunnelDecryption decryption;
|
2018-01-06 11:48:51 +08:00
|
|
|
};
|
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
public:
|
|
|
|
|
2022-05-01 23:40:00 +03:00
|
|
|
/** function for visiting a hops stored in a tunnel */
|
|
|
|
typedef std::function<void(std::shared_ptr<const i2p::data::IdentityEx>)> TunnelHopVisitor;
|
|
|
|
|
2015-05-06 16:17:48 -04:00
|
|
|
Tunnel (std::shared_ptr<const TunnelConfig> config);
|
2021-11-01 05:03:34 +03:00
|
|
|
~Tunnel ();
|
2013-12-06 19:02:49 -05:00
|
|
|
|
2015-01-27 14:55:46 -05:00
|
|
|
void Build (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2015-05-06 16:17:48 -04:00
|
|
|
std::shared_ptr<const TunnelConfig> GetTunnelConfig () const { return m_Config; }
|
2018-01-06 11:48:51 +08:00
|
|
|
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetPeers () const;
|
|
|
|
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetInvertedPeers () const;
|
2021-10-05 19:38:33 -04:00
|
|
|
bool IsShortBuildMessage () const { return m_IsShortBuildMessage; };
|
2021-11-05 14:51:24 -04:00
|
|
|
i2p::data::RouterInfo::CompatibleTransports GetFarEndTransports () const { return m_FarEndTransports; };
|
2014-07-26 20:56:42 -04:00
|
|
|
TunnelState GetState () const { return m_State; };
|
2016-11-01 10:26:40 -04:00
|
|
|
void SetState (TunnelState state);
|
2024-02-15 19:29:33 -05:00
|
|
|
bool IsEstablished () const { return m_State == eTunnelStateEstablished || m_State == eTunnelStateTestFailed; };
|
2014-07-26 20:56:42 -04:00
|
|
|
bool IsFailed () const { return m_State == eTunnelStateFailed; };
|
2015-04-17 11:36:42 -04:00
|
|
|
bool IsRecreated () const { return m_IsRecreated; };
|
2021-09-10 19:57:38 -04:00
|
|
|
void SetRecreated (bool recreated) { m_IsRecreated = recreated; };
|
2018-02-26 19:41:24 -05:00
|
|
|
int GetNumHops () const { return m_Hops.size (); };
|
2016-11-01 10:46:07 -04:00
|
|
|
virtual bool IsInbound() const = 0;
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2015-01-19 22:28:13 -05:00
|
|
|
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
2018-01-06 11:48:51 +08:00
|
|
|
void SetTunnelPool (std::shared_ptr<TunnelPool> pool) { m_Pool = pool; };
|
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
|
2016-03-02 22:41:53 -05:00
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
// implements TunnelBase
|
2023-04-03 21:35:10 -04:00
|
|
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
|
|
|
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out) override;
|
2015-12-09 19:07:12 -05:00
|
|
|
|
2017-01-01 14:29:39 -05:00
|
|
|
/** @brief add latency sample */
|
2024-02-27 10:15:15 +02:00
|
|
|
void AddLatencySample(const int us) { m_Latency = LatencyIsKnown() ? (m_Latency + us) >> 1 : us; }
|
2017-01-01 14:29:39 -05:00
|
|
|
/** @brief get this tunnel's estimated latency */
|
2024-02-27 10:15:15 +02:00
|
|
|
int GetMeanLatency() const { return (m_Latency + 500) / 1000; }
|
2017-07-08 16:53:33 +03:00
|
|
|
/** @brief return true if this tunnel's latency fits in range [lowerbound, upperbound] */
|
2024-02-25 22:57:57 +02:00
|
|
|
bool LatencyFitsRange(int lowerbound, int upperbound) const;
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2024-02-25 22:57:57 +02:00
|
|
|
bool LatencyIsKnown() const { return m_Latency != UNKNOWN_LATENCY; }
|
|
|
|
bool IsSlow () const { return LatencyIsKnown() && m_Latency > HIGH_LATENCY_PER_HOP*GetNumHops (); }
|
2021-11-27 23:30:35 +03:00
|
|
|
|
2022-05-01 23:25:08 +03:00
|
|
|
/** visit all hops we currently store */
|
|
|
|
void VisitTunnelHops(TunnelHopVisitor v);
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
private:
|
|
|
|
|
2015-05-06 16:17:48 -04:00
|
|
|
std::shared_ptr<const TunnelConfig> m_Config;
|
2021-11-13 15:11:59 -05:00
|
|
|
std::vector<TunnelHop> m_Hops;
|
2021-10-05 19:38:33 -04:00
|
|
|
bool m_IsShortBuildMessage;
|
2015-01-19 22:28:13 -05:00
|
|
|
std::shared_ptr<TunnelPool> m_Pool; // pool, tunnel belongs to, or null
|
2014-07-26 20:56:42 -04:00
|
|
|
TunnelState m_State;
|
2021-10-05 19:38:33 -04:00
|
|
|
i2p::data::RouterInfo::CompatibleTransports m_FarEndTransports;
|
2021-11-27 23:30:35 +03:00
|
|
|
bool m_IsRecreated; // if tunnel is replaced by new, or new tunnel requested to replace
|
2024-02-27 10:15:15 +02:00
|
|
|
int m_Latency; // in microseconds
|
2018-01-06 11:48:51 +08:00
|
|
|
};
|
2013-12-06 19:02:49 -05:00
|
|
|
|
2018-01-06 11:48:51 +08:00
|
|
|
class OutboundTunnel: public Tunnel
|
2013-12-06 19:02:49 -05:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2018-01-06 11:48:51 +08:00
|
|
|
OutboundTunnel (std::shared_ptr<const TunnelConfig> config):
|
2024-11-29 11:31:13 -05:00
|
|
|
Tunnel (config), m_Gateway (*this), m_EndpointIdentHash (config->GetLastIdentHash ()) {};
|
2013-12-06 19:02:49 -05:00
|
|
|
|
2023-04-04 13:48:00 -04:00
|
|
|
void SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg);
|
2023-04-04 13:19:08 -04:00
|
|
|
virtual void SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
2018-01-06 11:48:51 +08:00
|
|
|
const i2p::data::IdentHash& GetEndpointIdentHash () const { return m_EndpointIdentHash; };
|
2016-03-03 16:24:13 -05:00
|
|
|
virtual size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2014-01-03 22:56:28 -05:00
|
|
|
// implements TunnelBase
|
2023-04-03 21:35:10 -04:00
|
|
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
2016-11-01 10:46:07 -04:00
|
|
|
|
2023-04-03 21:35:10 -04:00
|
|
|
bool IsInbound() const override { return false; }
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
private:
|
|
|
|
|
2014-04-03 12:19:12 -04:00
|
|
|
std::mutex m_SendMutex;
|
2018-01-06 11:48:51 +08:00
|
|
|
TunnelGateway m_Gateway;
|
2015-11-03 09:15:49 -05:00
|
|
|
i2p::data::IdentHash m_EndpointIdentHash;
|
2013-12-06 19:02:49 -05:00
|
|
|
};
|
2016-03-02 22:41:53 -05:00
|
|
|
|
2024-02-04 15:45:22 -05:00
|
|
|
class InboundTunnel: public Tunnel
|
2013-12-06 19:02:49 -05:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2015-05-06 16:17:48 -04:00
|
|
|
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
|
2023-04-03 21:35:10 -04:00
|
|
|
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg) override;
|
2016-03-03 07:30:38 -05:00
|
|
|
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
2023-04-03 21:35:10 -04:00
|
|
|
bool IsInbound() const override { return true; }
|
2016-11-09 14:51:55 -05:00
|
|
|
|
|
|
|
// override TunnelBase
|
2023-04-03 22:50:31 -04:00
|
|
|
void Cleanup () override { m_Endpoint.Cleanup (); };
|
2016-11-09 14:51:55 -05:00
|
|
|
|
2024-02-04 15:45:22 -05:00
|
|
|
protected:
|
|
|
|
|
|
|
|
std::shared_ptr<InboundTunnel> GetSharedFromThis ()
|
|
|
|
{
|
|
|
|
return std::static_pointer_cast<InboundTunnel>(shared_from_this ());
|
|
|
|
}
|
|
|
|
|
2016-03-03 07:30:38 -05:00
|
|
|
private:
|
2013-12-06 19:02:49 -05:00
|
|
|
|
2018-01-06 11:48:51 +08:00
|
|
|
TunnelEndpoint m_Endpoint;
|
|
|
|
};
|
|
|
|
|
2016-03-02 22:41:53 -05:00
|
|
|
class ZeroHopsInboundTunnel: public InboundTunnel
|
|
|
|
{
|
|
|
|
public:
|
2013-12-06 19:02:49 -05:00
|
|
|
|
2016-03-02 22:41:53 -05:00
|
|
|
ZeroHopsInboundTunnel ();
|
2023-04-03 21:35:10 -04:00
|
|
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
|
|
|
size_t GetNumReceivedBytes () const override { return m_NumReceivedBytes; };
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2016-03-03 07:30:38 -05:00
|
|
|
private:
|
|
|
|
|
|
|
|
size_t m_NumReceivedBytes;
|
2018-01-06 11:48:51 +08:00
|
|
|
};
|
|
|
|
|
2016-03-03 16:24:13 -05:00
|
|
|
class ZeroHopsOutboundTunnel: public OutboundTunnel
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
ZeroHopsOutboundTunnel ();
|
2023-04-04 13:19:08 -04:00
|
|
|
void SendTunnelDataMsgs (const std::vector<TunnelMessageBlock>& msgs) override;
|
2023-04-03 21:35:10 -04:00
|
|
|
size_t GetNumSentBytes () const override { return m_NumSentBytes; };
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2016-03-03 16:24:13 -05:00
|
|
|
private:
|
|
|
|
|
|
|
|
size_t m_NumSentBytes;
|
2018-01-06 11:48:51 +08:00
|
|
|
};
|
2016-03-03 16:24:13 -05:00
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
class Tunnels
|
2018-01-06 11:48:51 +08:00
|
|
|
{
|
2013-12-06 19:02:49 -05:00
|
|
|
public:
|
|
|
|
|
|
|
|
Tunnels ();
|
|
|
|
~Tunnels ();
|
|
|
|
void Start ();
|
2018-01-06 11:48:51 +08:00
|
|
|
void Stop ();
|
|
|
|
|
|
|
|
std::shared_ptr<InboundTunnel> GetPendingInboundTunnel (uint32_t replyMsgID);
|
|
|
|
std::shared_ptr<OutboundTunnel> GetPendingOutboundTunnel (uint32_t replyMsgID);
|
2015-01-27 14:55:46 -05:00
|
|
|
std::shared_ptr<InboundTunnel> GetNextInboundTunnel ();
|
|
|
|
std::shared_ptr<OutboundTunnel> GetNextOutboundTunnel ();
|
2015-01-19 22:28:13 -05:00
|
|
|
std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; };
|
2016-03-01 20:48:56 -05:00
|
|
|
std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID);
|
2024-11-16 20:56:35 -05:00
|
|
|
bool AddTunnel (std::shared_ptr<TunnelBase> tunnel);
|
|
|
|
void RemoveTunnel (uint32_t tunnelID);
|
2015-01-09 22:27:52 -05:00
|
|
|
int GetTransitTunnelsExpirationTimeout ();
|
2015-01-27 14:55:46 -05:00
|
|
|
void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel);
|
|
|
|
void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel);
|
2021-07-21 13:08:12 -04:00
|
|
|
std::shared_ptr<InboundTunnel> CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel);
|
|
|
|
std::shared_ptr<OutboundTunnel> CreateOutboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<TunnelPool> pool);
|
2015-06-19 14:38:31 -04:00
|
|
|
void PostTunnelData (std::shared_ptr<I2NPMessage> msg);
|
2024-10-12 17:51:26 -04:00
|
|
|
void PostTunnelData (std::list<std::shared_ptr<I2NPMessage> >& msgs); // and cleanup msgs
|
2015-01-27 14:55:46 -05:00
|
|
|
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
|
|
|
|
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
|
2024-09-19 21:16:16 -04:00
|
|
|
std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops,
|
|
|
|
int numOuboundHops, int numInboundTunnels, int numOutboundTunnels,
|
|
|
|
int inboundVariance, int outboundVariance, bool isHighBandwidth);
|
2015-01-19 22:28:13 -05:00
|
|
|
void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
|
|
|
|
void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2021-10-22 19:18:45 -04:00
|
|
|
std::shared_ptr<I2NPMessage> NewI2NPTunnelMessage (bool endpoint);
|
2021-11-27 23:30:35 +03:00
|
|
|
|
2024-02-22 14:22:11 -05:00
|
|
|
void SetMaxNumTransitTunnels (uint32_t maxNumTransitTunnels);
|
|
|
|
uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; };
|
2024-11-16 20:56:35 -05:00
|
|
|
int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.GetNumTransitTunnels () / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; }
|
2023-05-03 15:59:35 +02:00
|
|
|
|
2024-10-27 22:19:06 -04:00
|
|
|
std::mt19937& GetRng () { return m_Rng; };
|
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
private:
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2016-06-29 11:26:46 -04:00
|
|
|
template<class TTunnel>
|
2021-11-27 23:30:35 +03:00
|
|
|
std::shared_ptr<TTunnel> CreateTunnel (std::shared_ptr<TunnelConfig> config,
|
2022-05-20 19:56:05 +03:00
|
|
|
std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
|
2016-06-29 11:26:46 -04:00
|
|
|
|
2015-01-26 11:56:10 -05:00
|
|
|
template<class TTunnel>
|
2018-01-06 11:48:51 +08:00
|
|
|
std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);
|
2015-01-26 11:56:10 -05:00
|
|
|
|
2016-03-01 15:22:36 -05:00
|
|
|
void HandleTunnelGatewayMsg (std::shared_ptr<TunnelBase> tunnel, std::shared_ptr<I2NPMessage> msg);
|
2024-11-09 17:25:43 -05:00
|
|
|
void HandleShortTunnelBuildMsg (std::shared_ptr<I2NPMessage> msg);
|
|
|
|
void HandleVariableTunnelBuildMsg (std::shared_ptr<I2NPMessage> msg);
|
|
|
|
void HandleTunnelBuildReplyMsg (std::shared_ptr<I2NPMessage> msg, bool isShort);
|
|
|
|
|
2018-01-06 11:48:51 +08:00
|
|
|
void Run ();
|
2023-02-09 18:32:18 -05:00
|
|
|
void ManageTunnels (uint64_t ts);
|
|
|
|
void ManageOutboundTunnels (uint64_t ts);
|
|
|
|
void ManageInboundTunnels (uint64_t ts);
|
|
|
|
void ManagePendingTunnels (uint64_t ts);
|
2015-01-26 11:56:10 -05:00
|
|
|
template<class PendingTunnels>
|
2023-02-09 18:32:18 -05:00
|
|
|
void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts);
|
2020-11-15 19:38:34 -05:00
|
|
|
void ManageTunnelPools (uint64_t ts);
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2021-07-30 14:12:50 -04:00
|
|
|
std::shared_ptr<ZeroHopsInboundTunnel> CreateZeroHopsInboundTunnel (std::shared_ptr<TunnelPool> pool);
|
|
|
|
std::shared_ptr<ZeroHopsOutboundTunnel> CreateZeroHopsOutboundTunnel (std::shared_ptr<TunnelPool> pool);
|
2016-03-03 16:24:13 -05:00
|
|
|
|
2023-02-01 21:28:05 -05:00
|
|
|
// Calculating of tunnel creation success rate
|
2023-02-11 09:41:51 +03:00
|
|
|
void SuccesiveTunnelCreation()
|
2023-02-01 21:28:05 -05:00
|
|
|
{
|
|
|
|
// total TCSR
|
|
|
|
m_TotalNumSuccesiveTunnelCreations++;
|
|
|
|
// A modified version of the EWMA algorithm, where alpha is increased at the beginning to accelerate similarity
|
|
|
|
double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum;
|
|
|
|
m_TunnelCreationSuccessRate = alpha * 1 + (1 - alpha) * m_TunnelCreationSuccessRate;
|
|
|
|
|
|
|
|
}
|
2023-02-11 09:41:51 +03:00
|
|
|
void FailedTunnelCreation()
|
2023-02-01 21:28:05 -05:00
|
|
|
{
|
|
|
|
m_TotalNumFailedTunnelCreations++;
|
2023-02-11 09:41:51 +03:00
|
|
|
|
2023-02-01 21:28:05 -05:00
|
|
|
double alpha = TCSR_SMOOTHING_CONSTANT + (1 - TCSR_SMOOTHING_CONSTANT)/++m_TunnelCreationAttemptsNum;
|
|
|
|
m_TunnelCreationSuccessRate = alpha * 0 + (1 - alpha) * m_TunnelCreationSuccessRate;
|
|
|
|
}
|
2023-02-11 09:41:51 +03:00
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
private:
|
|
|
|
|
|
|
|
bool m_IsRunning;
|
2018-01-06 11:48:51 +08:00
|
|
|
std::thread * m_Thread;
|
2024-12-18 14:22:05 -05:00
|
|
|
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool;
|
|
|
|
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
|
2015-01-27 14:55:46 -05:00
|
|
|
std::map<uint32_t, std::shared_ptr<InboundTunnel> > m_PendingInboundTunnels; // by replyMsgID
|
|
|
|
std::map<uint32_t, std::shared_ptr<OutboundTunnel> > m_PendingOutboundTunnels; // by replyMsgID
|
2016-03-02 11:58:52 -05:00
|
|
|
std::list<std::shared_ptr<InboundTunnel> > m_InboundTunnels;
|
2015-01-27 14:55:46 -05:00
|
|
|
std::list<std::shared_ptr<OutboundTunnel> > m_OutboundTunnels;
|
2024-11-19 19:11:09 -05:00
|
|
|
mutable std::mutex m_TunnelsMutex;
|
2016-03-01 20:48:56 -05:00
|
|
|
std::unordered_map<uint32_t, std::shared_ptr<TunnelBase> > m_Tunnels; // tunnelID->tunnel known by this id
|
2024-11-19 19:11:09 -05:00
|
|
|
mutable std::mutex m_PoolsMutex;
|
2015-01-19 22:28:13 -05:00
|
|
|
std::list<std::shared_ptr<TunnelPool>> m_Pools;
|
|
|
|
std::shared_ptr<TunnelPool> m_ExploratoryPool;
|
2015-06-19 14:38:31 -04:00
|
|
|
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue;
|
2024-02-22 14:22:11 -05:00
|
|
|
uint32_t m_MaxNumTransitTunnels;
|
2023-02-01 19:14:56 +03:00
|
|
|
// count of tunnels for total TCSR algorithm
|
2023-02-11 09:41:51 +03:00
|
|
|
int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
|
2023-01-03 03:07:07 +03:00
|
|
|
double m_TunnelCreationSuccessRate;
|
|
|
|
int m_TunnelCreationAttemptsNum;
|
2024-10-27 22:19:06 -04:00
|
|
|
std::mt19937 m_Rng;
|
2024-11-16 20:56:35 -05:00
|
|
|
TransitTunnels m_TransitTunnels;
|
2024-11-16 16:05:46 -05:00
|
|
|
|
2013-12-06 19:02:49 -05:00
|
|
|
public:
|
|
|
|
|
|
|
|
// for HTTP only
|
|
|
|
const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; };
|
|
|
|
const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; };
|
2024-11-19 19:11:09 -05:00
|
|
|
const auto& GetTransitTunnels () const { return m_TransitTunnels.GetTransitTunnels (); };
|
2016-03-02 09:41:37 -05:00
|
|
|
|
2016-03-02 11:58:52 -05:00
|
|
|
size_t CountTransitTunnels() const;
|
|
|
|
size_t CountInboundTunnels() const;
|
|
|
|
size_t CountOutboundTunnels() const;
|
2018-01-06 11:48:51 +08:00
|
|
|
|
2024-11-20 13:28:01 -05:00
|
|
|
size_t GetQueueSize () const { return m_Queue.GetSize (); };
|
|
|
|
size_t GetTBMQueueSize () const { return m_TransitTunnels.GetTunnelBuildMsgQueueSize (); };
|
2023-01-03 03:07:07 +03:00
|
|
|
int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents
|
2023-05-03 15:59:35 +02:00
|
|
|
double GetPreciseTunnelCreationSuccessRate () const { return m_TunnelCreationSuccessRate * 100; } // in percents
|
2023-02-01 19:14:56 +03:00
|
|
|
int GetTotalTunnelCreationSuccessRate () const // in percents
|
2023-02-01 14:06:28 +03:00
|
|
|
{
|
2023-02-01 19:14:56 +03:00
|
|
|
int totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations;
|
|
|
|
return totalNum ? m_TotalNumSuccesiveTunnelCreations*100/totalNum : 0;
|
2023-02-01 14:06:28 +03:00
|
|
|
}
|
2018-01-06 11:48:51 +08:00
|
|
|
};
|
2013-12-06 19:02:49 -05:00
|
|
|
|
|
|
|
extern Tunnels tunnels;
|
2018-01-06 11:48:51 +08:00
|
|
|
}
|
2013-12-06 19:02:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|