forked from PurpleI2P/i2pd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTunnel.h
176 lines (141 loc) · 5.17 KB
/
Tunnel.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#ifndef TUNNEL_H__
#define TUNNEL_H__
#include <inttypes.h>
#include <map>
#include <list>
#include <vector>
#include <string>
#include <thread>
#include <mutex>
#include "Queue.h"
#include "TunnelConfig.h"
#include "TunnelPool.h"
#include "TransitTunnel.h"
#include "TunnelEndpoint.h"
#include "TunnelGateway.h"
#include "TunnelBase.h"
#include "I2NPProtocol.h"
namespace i2p
{
namespace tunnel
{
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds
const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message
enum TunnelState
{
eTunnelStatePending,
eTunnelStateBuildReplyReceived,
eTunnelStateBuildFailed,
eTunnelStateEstablished,
eTunnelStateTestFailed,
eTunnelStateFailed,
eTunnelStateExpiring
};
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; }
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; };
TunnelPool * GetTunnelPool () const { return m_Pool; };
void SetTunnelPool (TunnelPool * pool) { m_Pool = pool; };
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;
TunnelPool * m_Pool; // pool, tunnel belongs to, or null
TunnelState m_State;
};
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);
void SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs); // multiple messages
const i2p::data::RouterInfo * GetEndpointRouter () const
{ return GetTunnelConfig ()->GetLastHop ()->router; };
size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
// implements TunnelBase
uint32_t GetTunnelID () const { return GetNextTunnelID (); };
private:
std::mutex m_SendMutex;
TunnelGateway m_Gateway;
};
class InboundTunnel: public Tunnel
{
public:
InboundTunnel (TunnelConfig * config): Tunnel (config), m_Endpoint (true) {};
void HandleTunnelDataMsg (I2NPMessage * msg);
size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
// implements TunnelBase
uint32_t GetTunnelID () const { return GetTunnelConfig ()->GetLastHop ()->nextTunnelID; };
private:
TunnelEndpoint m_Endpoint;
};
class Tunnels
{
public:
Tunnels ();
~Tunnels ();
void Start ();
void Stop ();
InboundTunnel * GetInboundTunnel (uint32_t tunnelID);
Tunnel * GetPendingTunnel (uint32_t replyMsgID);
InboundTunnel * GetNextInboundTunnel ();
OutboundTunnel * GetNextOutboundTunnel ();
TunnelPool * GetExploratoryPool () const { return m_ExploratoryPool; };
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);
TunnelPool * CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops);
void DeleteTunnelPool (TunnelPool * pool);
void StopTunnelPool (TunnelPool * pool);
private:
void Run ();
void ManageTunnels ();
void ManageOutboundTunnels ();
void ManageInboundTunnels ();
void ManageTransitTunnels ();
void ManagePendingTunnels ();
void ManageTunnelPools ();
void CreateZeroHopsInboundTunnel ();
private:
bool m_IsRunning;
std::thread * m_Thread;
std::map<uint32_t, Tunnel *> m_PendingTunnels; // by replyMsgID
std::mutex m_InboundTunnelsMutex;
std::map<uint32_t, InboundTunnel *> m_InboundTunnels;
std::mutex m_OutboundTunnelsMutex;
std::list<OutboundTunnel *> m_OutboundTunnels;
std::mutex m_TransitTunnelsMutex;
std::map<uint32_t, TransitTunnel *> m_TransitTunnels;
std::mutex m_PoolsMutex;
std::map<i2p::data::IdentHash, TunnelPool *> m_Pools;
TunnelPool * m_ExploratoryPool;
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; };
const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; };
};
extern Tunnels tunnels;
}
}
#endif