2013-12-07 00:02:49 +00:00
|
|
|
#ifndef TUNNEL_H__
|
|
|
|
#define TUNNEL_H__
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <map>
|
|
|
|
#include <list>
|
2014-01-20 23:37:51 +00:00
|
|
|
#include <vector>
|
2013-12-07 00:02:49 +00:00
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
2014-04-03 16:19:12 +00:00
|
|
|
#include <mutex>
|
2013-12-07 00:02:49 +00:00
|
|
|
#include "Queue.h"
|
|
|
|
#include "TunnelConfig.h"
|
2014-03-14 16:35:02 +00:00
|
|
|
#include "TunnelPool.h"
|
2013-12-07 00:02:49 +00:00
|
|
|
#include "TransitTunnel.h"
|
|
|
|
#include "TunnelEndpoint.h"
|
|
|
|
#include "TunnelGateway.h"
|
|
|
|
#include "TunnelBase.h"
|
|
|
|
#include "I2NPProtocol.h"
|
|
|
|
|
|
|
|
namespace i2p
|
|
|
|
{
|
|
|
|
namespace tunnel
|
|
|
|
{
|
2014-02-20 02:24:55 +00:00
|
|
|
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
|
2014-08-26 14:31:32 +00:00
|
|
|
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
|
2014-09-26 14:15:34 +00:00
|
|
|
const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds
|
2014-08-16 18:35:35 +00:00
|
|
|
const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message
|
2014-07-27 00:56:42 +00:00
|
|
|
|
|
|
|
enum TunnelState
|
|
|
|
{
|
|
|
|
eTunnelStatePending,
|
2014-09-26 14:15:34 +00:00
|
|
|
eTunnelStateBuildReplyReceived,
|
|
|
|
eTunnelStateBuildFailed,
|
2014-07-27 00:56:42 +00:00
|
|
|
eTunnelStateEstablished,
|
|
|
|
eTunnelStateTestFailed,
|
2014-08-26 14:31:32 +00:00
|
|
|
eTunnelStateFailed,
|
|
|
|
eTunnelStateExpiring
|
2014-07-27 00:56:42 +00:00
|
|
|
};
|
2013-12-07 00:02:49 +00:00
|
|
|
|
|
|
|
class OutboundTunnel;
|
|
|
|
class InboundTunnel;
|
|
|
|
class Tunnel: public TunnelBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
Tunnel (TunnelConfig * config);
|
|
|
|
~Tunnel ();
|
|
|
|
|
|
|
|
void Build (uint32_t replyMsgID, OutboundTunnel * outboundTunnel = 0);
|
|
|
|
|
|
|
|
TunnelConfig * GetTunnelConfig () const { return m_Config; }
|
2014-07-27 00:56:42 +00:00
|
|
|
TunnelState GetState () const { return m_State; };
|
|
|
|
void SetState (TunnelState state) { m_State = state; };
|
|
|
|
bool IsEstablished () const { return m_State == eTunnelStateEstablished; };
|
|
|
|
bool IsFailed () const { return m_State == eTunnelStateFailed; };
|
2014-03-21 19:54:55 +00:00
|
|
|
|
2014-03-14 16:35:02 +00:00
|
|
|
TunnelPool * GetTunnelPool () const { return m_Pool; };
|
|
|
|
void SetTunnelPool (TunnelPool * pool) { m_Pool = pool; };
|
|
|
|
|
2013-12-07 00:02:49 +00:00
|
|
|
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
|
|
|
|
|
|
|
|
// implements TunnelBase
|
|
|
|
void EncryptTunnelMsg (I2NPMessage * tunnelMsg);
|
|
|
|
uint32_t GetNextTunnelID () const { return m_Config->GetFirstHop ()->tunnelID; };
|
|
|
|
const i2p::data::IdentHash& GetNextIdentHash () const { return m_Config->GetFirstHop ()->router->GetIdentHash (); };
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
TunnelConfig * m_Config;
|
2014-03-14 16:35:02 +00:00
|
|
|
TunnelPool * m_Pool; // pool, tunnel belongs to, or null
|
2014-07-27 00:56:42 +00:00
|
|
|
TunnelState m_State;
|
2013-12-07 00:02:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class OutboundTunnel: public Tunnel
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
OutboundTunnel (TunnelConfig * config): Tunnel (config), m_Gateway (this) {};
|
|
|
|
|
|
|
|
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
2014-10-07 14:33:17 +00:00
|
|
|
void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
|
2014-01-26 02:47:01 +00:00
|
|
|
const i2p::data::RouterInfo * GetEndpointRouter () const
|
|
|
|
{ return GetTunnelConfig ()->GetLastHop ()->router; };
|
2013-12-07 00:02:49 +00:00
|
|
|
size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
|
2014-01-04 03:56:28 +00:00
|
|
|
|
|
|
|
// implements TunnelBase
|
|
|
|
uint32_t GetTunnelID () const { return GetNextTunnelID (); };
|
2013-12-07 00:02:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2014-04-03 16:19:12 +00:00
|
|
|
std::mutex m_SendMutex;
|
2013-12-07 00:02:49 +00:00
|
|
|
TunnelGateway m_Gateway;
|
|
|
|
};
|
|
|
|
|
|
|
|
class InboundTunnel: public Tunnel
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2014-07-10 16:44:49 +00:00
|
|
|
InboundTunnel (TunnelConfig * config): Tunnel (config), m_Endpoint (true) {};
|
2013-12-07 00:02:49 +00:00
|
|
|
void HandleTunnelDataMsg (I2NPMessage * msg);
|
2014-01-04 03:56:28 +00:00
|
|
|
size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
2013-12-07 00:02:49 +00:00
|
|
|
|
2014-01-04 03:56:28 +00:00
|
|
|
// implements TunnelBase
|
2013-12-07 00:02:49 +00:00
|
|
|
uint32_t GetTunnelID () const { return GetTunnelConfig ()->GetLastHop ()->nextTunnelID; };
|
|
|
|
private:
|
|
|
|
|
|
|
|
TunnelEndpoint m_Endpoint;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Tunnels
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
Tunnels ();
|
|
|
|
~Tunnels ();
|
|
|
|
void Start ();
|
2014-03-15 00:24:12 +00:00
|
|
|
void Stop ();
|
2013-12-07 00:02:49 +00:00
|
|
|
|
|
|
|
InboundTunnel * GetInboundTunnel (uint32_t tunnelID);
|
|
|
|
Tunnel * GetPendingTunnel (uint32_t replyMsgID);
|
|
|
|
InboundTunnel * GetNextInboundTunnel ();
|
|
|
|
OutboundTunnel * GetNextOutboundTunnel ();
|
2014-04-03 20:27:37 +00:00
|
|
|
TunnelPool * GetExploratoryPool () const { return m_ExploratoryPool; };
|
2013-12-07 00:02:49 +00:00
|
|
|
TransitTunnel * GetTransitTunnel (uint32_t tunnelID);
|
|
|
|
void AddTransitTunnel (TransitTunnel * tunnel);
|
|
|
|
void AddOutboundTunnel (OutboundTunnel * newTunnel);
|
|
|
|
void AddInboundTunnel (InboundTunnel * newTunnel);
|
|
|
|
void PostTunnelData (I2NPMessage * msg);
|
|
|
|
template<class TTunnel>
|
|
|
|
TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0);
|
2014-10-07 00:18:18 +00:00
|
|
|
TunnelPool * CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops);
|
2014-03-15 00:51:51 +00:00
|
|
|
void DeleteTunnelPool (TunnelPool * pool);
|
2013-12-07 00:02:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
void Run ();
|
|
|
|
void ManageTunnels ();
|
|
|
|
void ManageOutboundTunnels ();
|
|
|
|
void ManageInboundTunnels ();
|
2014-01-04 03:56:28 +00:00
|
|
|
void ManageTransitTunnels ();
|
2014-10-06 16:50:36 +00:00
|
|
|
void ManagePendingTunnels ();
|
2014-03-15 00:24:12 +00:00
|
|
|
void ManageTunnelPools ();
|
2013-12-07 00:02:49 +00:00
|
|
|
|
|
|
|
void CreateZeroHopsInboundTunnel ();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
bool m_IsRunning;
|
|
|
|
std::thread * m_Thread;
|
2014-10-06 16:50:36 +00:00
|
|
|
std::mutex m_PendingTunnelsMutex;
|
2013-12-07 00:02:49 +00:00
|
|
|
std::map<uint32_t, Tunnel *> m_PendingTunnels; // by replyMsgID
|
2014-08-31 12:56:03 +00:00
|
|
|
std::mutex m_InboundTunnelsMutex;
|
2013-12-07 00:02:49 +00:00
|
|
|
std::map<uint32_t, InboundTunnel *> m_InboundTunnels;
|
2014-08-31 12:56:03 +00:00
|
|
|
std::mutex m_OutboundTunnelsMutex;
|
2013-12-07 00:02:49 +00:00
|
|
|
std::list<OutboundTunnel *> m_OutboundTunnels;
|
2014-09-14 11:50:01 +00:00
|
|
|
std::mutex m_TransitTunnelsMutex;
|
2013-12-07 00:02:49 +00:00
|
|
|
std::map<uint32_t, TransitTunnel *> m_TransitTunnels;
|
2014-10-05 15:01:12 +00:00
|
|
|
std::mutex m_PoolsMutex;
|
2014-04-01 19:08:53 +00:00
|
|
|
std::map<i2p::data::IdentHash, TunnelPool *> m_Pools;
|
2014-04-02 17:14:21 +00:00
|
|
|
TunnelPool * m_ExploratoryPool;
|
2013-12-07 00:02:49 +00:00
|
|
|
i2p::util::Queue<I2NPMessage> m_Queue;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// for HTTP only
|
|
|
|
const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; };
|
|
|
|
const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; };
|
2013-12-10 13:10:49 +00:00
|
|
|
const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; };
|
2013-12-07 00:02:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern Tunnels tunnels;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|