Browse Source

Merge pull request #13 from orignal/master

Merge pull request from orignal/master
pull/47/head
chertov 10 years ago
parent
commit
bab581ebb5
  1. 73
      AddressBook.h
  2. 2
      Garlic.cpp
  3. 17
      HTTPServer.cpp
  4. 7
      Identity.h
  5. 2
      Makefile
  6. 7
      NetDb.cpp
  7. 6
      NetDb.h
  8. 30
      RouterContext.cpp
  9. 3
      SSU.cpp
  10. 34
      Streaming.cpp
  11. 17
      Streaming.h
  12. 41
      Tunnel.cpp
  13. 13
      Tunnel.h
  14. 11
      TunnelBase.h
  15. 73
      TunnelPool.cpp
  16. 46
      TunnelPool.h
  17. 3
      i2p.cpp
  18. 12
      util.cpp
  19. 1
      util.h

73
AddressBook.h

@ -0,0 +1,73 @@
#ifndef ADDRESS_BOOK_H__
#define ADDRESS_BOOK_H__
#include <string.h>
#include <string>
#include <map>
#include "base64.h"
#include "util.h"
#include "Identity.h"
#include "Log.h"
namespace i2p
{
namespace data
{
class AddressBook
{
public:
AddressBook (): m_IsLoaded (false) {};
const IdentHash * FindAddress (const std::string& address)
{
if (!m_IsLoaded)
LoadHosts ();
auto it = m_Addresses.find (address);
if (it != m_Addresses.end ())
return &it->second;
else
return nullptr;
}
private:
void LoadHosts ()
{
m_IsLoaded = true;
std::ifstream f (i2p::util::filesystem::GetFullPath ("hosts.txt").c_str (), std::ofstream::in); // in text mode
if (!f.is_open ())
{
LogPrint ("hosts.txt not found");
return;
}
int numAddresses = 0;
char str[1024];
while (!f.eof ())
{
f.getline (str, 1024);
char * key = strchr (str, '=');
if (key)
{
*key = 0;
key++;
Identity ident;
Base64ToByteStream (key, strlen(key), (uint8_t *)&ident, sizeof (ident));
m_Addresses[str] = CalculateIdentHash (ident);
numAddresses++;
}
}
LogPrint (numAddresses, " addresses loaded");
}
private:
std::map<std::string, IdentHash> m_Addresses;
bool m_IsLoaded;
};
}
}
#endif

2
Garlic.cpp

@ -218,7 +218,7 @@ namespace garlic
} }
GarlicRouting routing; GarlicRouting routing;
GarlicRouting::GarlicRouting () GarlicRouting::GarlicRouting (): m_IsRunning (false), m_Thread (nullptr)
{ {
} }

17
HTTPServer.cpp

@ -121,13 +121,16 @@ namespace util
s << "Our external address:" << "<BR>" << "<BR>"; s << "Our external address:" << "<BR>" << "<BR>";
for (auto& address : i2p::context.GetRouterInfo().GetAddresses()) for (auto& address : i2p::context.GetRouterInfo().GetAddresses())
{ {
switch (address.transportStyle) { switch (address.transportStyle)
case i2p::data::RouterInfo::eTransportNTCP: {
s << "NTCP&nbsp;&nbsp;"; case i2p::data::RouterInfo::eTransportNTCP:
s << "NTCP&nbsp;&nbsp;";
break; break;
case i2p::data::RouterInfo::eTransportSSU: case i2p::data::RouterInfo::eTransportSSU:
s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
break; break;
default:
s << "Unknown&nbsp;&nbsp;";
} }
s << address.host.to_string() << ":" << address.port << "<BR>"; s << address.host.to_string() << ":" << address.port << "<BR>";
} }
@ -142,9 +145,11 @@ namespace util
for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ())
{ {
it.second->GetTunnelConfig ()->Print (s); it.second->GetTunnelConfig ()->Print (s);
if (it.second->GetTunnelPool ())
s << " " << "Pool";
s << " " << (int)it.second->GetNumReceivedBytes () << "<BR>"; s << " " << (int)it.second->GetNumReceivedBytes () << "<BR>";
} }
s << "<P>Transit tunnels</P>"; s << "<P>Transit tunnels</P>";
for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ())
{ {

7
Identity.h

@ -104,6 +104,13 @@ namespace data
mutable i2p::crypto::ElGamalEncryption * m_ElGamalEncryption; // use lazy initialization mutable i2p::crypto::ElGamalEncryption * m_ElGamalEncryption; // use lazy initialization
}; };
class LocalDestination
{
public:
virtual void UpdateLeaseSet () = 0; // LeaseSet must be update
};
} }
} }

2
Makefile

@ -5,7 +5,7 @@ OBJECTS = obj/i2p.o obj/base64.o obj/NTCPSession.o obj/RouterInfo.o obj/Transpor
obj/RouterContext.o obj/NetDb.o obj/LeaseSet.o obj/Tunnel.o obj/TunnelEndpoint.o \ obj/RouterContext.o obj/NetDb.o obj/LeaseSet.o obj/Tunnel.o obj/TunnelEndpoint.o \
obj/TunnelGateway.o obj/TransitTunnel.o obj/I2NPProtocol.o obj/Log.o obj/Garlic.o \ obj/TunnelGateway.o obj/TransitTunnel.o obj/I2NPProtocol.o obj/Log.o obj/Garlic.o \
obj/HTTPServer.o obj/Streaming.o obj/Identity.o obj/SSU.o obj/util.o obj/Reseed.o \ obj/HTTPServer.o obj/Streaming.o obj/Identity.o obj/SSU.o obj/util.o obj/Reseed.o \
obj/UPnP.o obj/UPnP.o obj/TunnelPool.o
INCFLAGS = INCFLAGS =
LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem -lboost_regex -lboost_program_options -lpthread LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
LIBS = LIBS =

7
NetDb.cpp

@ -318,13 +318,6 @@ namespace data
LogPrint (deletedCount," routers deleted"); LogPrint (deletedCount," routers deleted");
} }
void NetDb::RequestDestination (const char * b32)
{
uint8_t destination[32];
Base32ToByteStream (b32, strlen(b32), destination, 32);
RequestDestination (destination, true);
}
void NetDb::RequestDestination (const IdentHash& destination, bool isLeaseSet) void NetDb::RequestDestination (const IdentHash& destination, bool isLeaseSet)
{ {
if (isLeaseSet) // we request LeaseSet through tunnels if (isLeaseSet) // we request LeaseSet through tunnels

6
NetDb.h

@ -12,6 +12,7 @@
#include "RouterInfo.h" #include "RouterInfo.h"
#include "LeaseSet.h" #include "LeaseSet.h"
#include "Tunnel.h" #include "Tunnel.h"
#include "AddressBook.h"
namespace i2p namespace i2p
{ {
@ -63,10 +64,10 @@ namespace data
void AddLeaseSet (uint8_t * buf, int len); void AddLeaseSet (uint8_t * buf, int len);
RouterInfo * FindRouter (const IdentHash& ident) const; RouterInfo * FindRouter (const IdentHash& ident) const;
LeaseSet * FindLeaseSet (const IdentHash& destination) const; LeaseSet * FindLeaseSet (const IdentHash& destination) const;
const IdentHash * FindAddress (const std::string& address) { return m_AddressBook.FindAddress (address); }; // TODO: move AddressBook away from NetDb
void Subscribe (const IdentHash& ident); // keep LeaseSets upto date void Subscribe (const IdentHash& ident); // keep LeaseSets upto date
void Unsubscribe (const IdentHash& ident); void Unsubscribe (const IdentHash& ident);
void RequestDestination (const char * b32); // in base32
void RequestDestination (const IdentHash& destination, bool isLeaseSet = false); void RequestDestination (const IdentHash& destination, bool isLeaseSet = false);
void HandleDatabaseStoreMsg (uint8_t * buf, size_t len); void HandleDatabaseStoreMsg (uint8_t * buf, size_t len);
@ -104,6 +105,7 @@ namespace data
int m_ReseedRetries; int m_ReseedRetries;
std::thread * m_Thread; std::thread * m_Thread;
i2p::util::Queue<I2NPMessage> m_Queue; // of I2NPDatabaseStoreMsg i2p::util::Queue<I2NPMessage> m_Queue; // of I2NPDatabaseStoreMsg
AddressBook m_AddressBook;
static const char m_NetDbPath[]; static const char m_NetDbPath[];
}; };

30
RouterContext.cpp

@ -76,49 +76,27 @@ namespace i2p
bool RouterContext::Load () bool RouterContext::Load ()
{ {
std::string dataDir = i2p::util::filesystem::GetDataDir ().string (); std::ifstream fk (i2p::util::filesystem::GetFullPath (ROUTER_KEYS).c_str (), std::ifstream::binary | std::ofstream::in);
#ifndef _WIN32
dataDir.append ("/");
#else
dataDir.append ("\\");
#endif
std::string router_keys = dataDir;
router_keys.append (ROUTER_KEYS);
std::string router_info = dataDir;
router_info.append (ROUTER_INFO);
std::ifstream fk (router_keys.c_str (), std::ifstream::binary | std::ofstream::in);
if (!fk.is_open ()) return false; if (!fk.is_open ()) return false;
fk.read ((char *)&m_Keys, sizeof (m_Keys)); fk.read ((char *)&m_Keys, sizeof (m_Keys));
m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag,
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
m_RouterInfo = i2p::data::RouterInfo (router_info.c_str ()); // TODO m_RouterInfo = i2p::data::RouterInfo (i2p::util::filesystem::GetFullPath (ROUTER_INFO).c_str ()); // TODO
return true; return true;
} }
void RouterContext::Save (bool infoOnly) void RouterContext::Save (bool infoOnly)
{ {
std::string dataDir = i2p::util::filesystem::GetDataDir ().string ();
#ifndef _WIN32
dataDir.append ("/");
#else
dataDir.append ("\\");
#endif
std::string router_keys = dataDir;
router_keys.append (ROUTER_KEYS);
std::string router_info = dataDir;
router_info.append (ROUTER_INFO);
if (!infoOnly) if (!infoOnly)
{ {
std::ofstream fk (router_keys.c_str (), std::ofstream::binary | std::ofstream::out); std::ofstream fk (i2p::util::filesystem::GetFullPath (ROUTER_KEYS).c_str (), std::ofstream::binary | std::ofstream::out);
fk.write ((char *)&m_Keys, sizeof (m_Keys)); fk.write ((char *)&m_Keys, sizeof (m_Keys));
} }
std::ofstream fi (router_info.c_str (), std::ofstream::binary | std::ofstream::out); std::ofstream fi (i2p::util::filesystem::GetFullPath (ROUTER_INFO).c_str (), std::ofstream::binary | std::ofstream::out);
fi.write ((char *)m_RouterInfo.GetBuffer (), m_RouterInfo.GetBufferLen ()); fi.write ((char *)m_RouterInfo.GetBuffer (), m_RouterInfo.GetBufferLen ());
} }
} }

3
SSU.cpp

@ -853,8 +853,9 @@ namespace ssu
auto it = m_Sessions.find (oldEndpoint); auto it = m_Sessions.find (oldEndpoint);
if (it != m_Sessions.end ()) if (it != m_Sessions.end ())
{ {
auto session = it->second;
m_Sessions.erase (it); m_Sessions.erase (it);
m_Sessions[newEndpoint] = it->second; m_Sessions[newEndpoint] = session;
LogPrint ("SSU session ressigned from ", oldEndpoint.address ().to_string (), ":", oldEndpoint.port (), LogPrint ("SSU session ressigned from ", oldEndpoint.address ().to_string (), ":", oldEndpoint.port (),
" to ", newEndpoint.address ().to_string (), ":", newEndpoint.port ()); " to ", newEndpoint.address ().to_string (), ":", newEndpoint.port ());
} }

34
Streaming.cpp

@ -308,14 +308,17 @@ namespace stream
m_IdentHash = i2p::data::CalculateIdentHash (m_Identity); m_IdentHash = i2p::data::CalculateIdentHash (m_Identity);
m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag,
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this);
} }
StreamingDestination::~StreamingDestination () StreamingDestination::~StreamingDestination ()
{ {
if (m_LeaseSet) if (m_LeaseSet)
DeleteI2NPMessage (m_LeaseSet); DeleteI2NPMessage (m_LeaseSet);
if (m_Pool)
i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool);
} }
void StreamingDestination::HandleNextPacket (Packet * packet) void StreamingDestination::HandleNextPacket (Packet * packet)
{ {
uint32_t sendStreamID = packet->GetSendStreamID (); uint32_t sendStreamID = packet->GetSendStreamID ();
@ -345,12 +348,20 @@ namespace stream
} }
} }
I2NPMessage * StreamingDestination::GetLeaseSet () void StreamingDestination::UpdateLeaseSet ()
{ {
if (m_LeaseSet) // temporary always create new LeaseSet auto newLeaseSet = CreateLeaseSet ();
DeleteI2NPMessage (m_LeaseSet); // TODO: make it atomic
m_LeaseSet = CreateLeaseSet (); auto oldLeaseSet = m_LeaseSet;
m_LeaseSet = newLeaseSet;
if (oldLeaseSet)
DeleteI2NPMessage (oldLeaseSet);
}
I2NPMessage * StreamingDestination::GetLeaseSet ()
{
if (!m_LeaseSet)
m_LeaseSet = CreateLeaseSet ();
return m_LeaseSet; return m_LeaseSet;
} }
@ -370,7 +381,7 @@ namespace stream
size += 256; // encryption key size += 256; // encryption key
memset (buf + size, 0, 128); memset (buf + size, 0, 128);
size += 128; // signing key size += 128; // signing key
auto tunnels = i2p::tunnel::tunnels.GetInboundTunnels (5); // 5 tunnels maximum auto tunnels = m_Pool->GetInboundTunnels (5); // 5 tunnels maximum
buf[size] = tunnels.size (); // num leases buf[size] = tunnels.size (); // num leases
size++; // num size++; // num
for (auto it: tunnels) for (auto it: tunnels)
@ -411,6 +422,17 @@ namespace stream
if (sharedLocalDestination) if (sharedLocalDestination)
sharedLocalDestination->DeleteStream (stream); sharedLocalDestination->DeleteStream (stream);
} }
void StartStreaming ()
{
if (!sharedLocalDestination)
sharedLocalDestination = new StreamingDestination ();
}
void StopStreaming ()
{
delete sharedLocalDestination;
}
void HandleDataMessage (i2p::data::IdentHash * destination, const uint8_t * buf, size_t len) void HandleDataMessage (i2p::data::IdentHash * destination, const uint8_t * buf, size_t len)
{ {

17
Streaming.h

@ -11,6 +11,7 @@
#include "LeaseSet.h" #include "LeaseSet.h"
#include "I2NPProtocol.h" #include "I2NPProtocol.h"
#include "Tunnel.h" #include "Tunnel.h"
#include "TunnelPool.h"
namespace i2p namespace i2p
{ {
@ -97,22 +98,25 @@ namespace stream
i2p::tunnel::OutboundTunnel * m_OutboundTunnel; i2p::tunnel::OutboundTunnel * m_OutboundTunnel;
}; };
class StreamingDestination class StreamingDestination: public i2p::data::LocalDestination
{ {
public: public:
StreamingDestination (); StreamingDestination ();
~StreamingDestination (); ~StreamingDestination ();
const i2p::data::Keys& GetKeys () const { return m_Keys; }; const i2p::data::Keys& GetKeys () const { return m_Keys; };
const i2p::data::Identity& GetIdentity () const { return m_Identity; }; const i2p::data::Identity& GetIdentity () const { return m_Identity; };
I2NPMessage * GetLeaseSet (); I2NPMessage * GetLeaseSet ();
void Sign (uint8_t * buf, int len, uint8_t * signature) const; void Sign (uint8_t * buf, int len, uint8_t * signature) const;
Stream * CreateNewStream (const i2p::data::LeaseSet& remote); Stream * CreateNewStream (const i2p::data::LeaseSet& remote);
void DeleteStream (Stream * stream); void DeleteStream (Stream * stream);
void HandleNextPacket (Packet * packet); void HandleNextPacket (Packet * packet);
// implements LocalDestination
void UpdateLeaseSet ();
private: private:
I2NPMessage * CreateLeaseSet () const; I2NPMessage * CreateLeaseSet () const;
@ -124,6 +128,7 @@ namespace stream
i2p::data::Identity m_Identity; i2p::data::Identity m_Identity;
i2p::data::IdentHash m_IdentHash; i2p::data::IdentHash m_IdentHash;
i2p::tunnel::TunnelPool * m_Pool;
I2NPMessage * m_LeaseSet; I2NPMessage * m_LeaseSet;
CryptoPP::DSA::PrivateKey m_SigningPrivateKey; CryptoPP::DSA::PrivateKey m_SigningPrivateKey;
@ -131,6 +136,8 @@ namespace stream
Stream * CreateStream (const i2p::data::LeaseSet& remote); Stream * CreateStream (const i2p::data::LeaseSet& remote);
void DeleteStream (Stream * stream); void DeleteStream (Stream * stream);
void StartStreaming ();
void StopStreaming ();
// assuming data is I2CP message // assuming data is I2CP message
void HandleDataMessage (i2p::data::IdentHash * destination, const uint8_t * buf, size_t len); void HandleDataMessage (i2p::data::IdentHash * destination, const uint8_t * buf, size_t len);

41
Tunnel.cpp

@ -14,7 +14,7 @@ namespace i2p
namespace tunnel namespace tunnel
{ {
Tunnel::Tunnel (TunnelConfig * config): m_Config (config), m_IsEstablished (false) Tunnel::Tunnel (TunnelConfig * config): m_Config (config), m_Pool (nullptr), m_IsEstablished (false)
{ {
} }
@ -186,6 +186,10 @@ namespace tunnel
for (auto& it : m_PendingTunnels) for (auto& it : m_PendingTunnels)
delete it.second; delete it.second;
m_PendingTunnels.clear (); m_PendingTunnels.clear ();
for (auto& it: m_Pools)
delete it;
m_Pools.clear ();
} }
InboundTunnel * Tunnels::GetInboundTunnel (uint32_t tunnelID) InboundTunnel * Tunnels::GetInboundTunnel (uint32_t tunnelID)
@ -268,6 +272,19 @@ namespace tunnel
} }
return tunnel;*/ return tunnel;*/
} }
TunnelPool * Tunnels::CreateTunnelPool (i2p::data::LocalDestination * localDestination)
{
auto pool = new TunnelPool (localDestination);
m_Pools.push_back (pool);
return pool;
}
void Tunnels::DeleteTunnelPool (TunnelPool * pool)
{
m_Pools.remove (pool);
delete pool;
}
void Tunnels::AddTransitTunnel (TransitTunnel * tunnel) void Tunnels::AddTransitTunnel (TransitTunnel * tunnel)
{ {
@ -350,6 +367,7 @@ namespace tunnel
ManageInboundTunnels (); ManageInboundTunnels ();
ManageOutboundTunnels (); ManageOutboundTunnels ();
ManageTransitTunnels (); ManageTransitTunnels ();
ManageTunnelPools ();
/* if (!m_IsTunnelCreated) /* if (!m_IsTunnelCreated)
{ {
@ -418,6 +436,9 @@ namespace tunnel
if (ts > it->second->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) if (ts > it->second->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
{ {
LogPrint ("Tunnel ", it->second->GetTunnelID (), " expired"); LogPrint ("Tunnel ", it->second->GetTunnelID (), " expired");
auto pool = it->second->GetTunnelPool ();
if (pool)
pool->TunnelExpired (it->second);
it = m_InboundTunnels.erase (it); it = m_InboundTunnels.erase (it);
} }
else else
@ -431,7 +452,7 @@ namespace tunnel
return; return;
} }
if (m_InboundTunnels.size () < 10) if (m_InboundTunnels.size () < 15) // TODO: store exploratory tunnels explicitly
{ {
// trying to create one more inbound tunnel // trying to create one more inbound tunnel
if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3) if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3)
@ -474,6 +495,12 @@ namespace tunnel
it++; it++;
} }
} }
void Tunnels::ManageTunnelPools ()
{
for (auto& it: m_Pools)
it->CreateTunnels ();
}
void Tunnels::PostTunnelData (I2NPMessage * msg) void Tunnels::PostTunnelData (I2NPMessage * msg)
{ {
@ -498,8 +525,14 @@ namespace tunnel
void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel) void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel)
{ {
m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel;
// build symmetric outbound tunnel auto pool = newTunnel->GetTunnelPool ();
CreateTunnel<OutboundTunnel> (newTunnel->GetTunnelConfig ()->Invert (), GetNextOutboundTunnel ()); if (!pool)
{
// build symmetric outbound tunnel
CreateTunnel<OutboundTunnel> (newTunnel->GetTunnelConfig ()->Invert (), GetNextOutboundTunnel ());
}
else
pool->TunnelCreated (newTunnel);
} }

13
Tunnel.h

@ -11,6 +11,7 @@
#include <cryptopp/aes.h> #include <cryptopp/aes.h>
#include "Queue.h" #include "Queue.h"
#include "TunnelConfig.h" #include "TunnelConfig.h"
#include "TunnelPool.h"
#include "TransitTunnel.h" #include "TransitTunnel.h"
#include "TunnelEndpoint.h" #include "TunnelEndpoint.h"
#include "TunnelGateway.h" #include "TunnelGateway.h"
@ -36,7 +37,9 @@ namespace tunnel
TunnelConfig * GetTunnelConfig () const { return m_Config; } TunnelConfig * GetTunnelConfig () const { return m_Config; }
bool IsEstablished () const { return m_IsEstablished; }; bool IsEstablished () const { return m_IsEstablished; };
TunnelPool * GetTunnelPool () const { return m_Pool; };
void SetTunnelPool (TunnelPool * pool) { m_Pool = pool; };
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
// implements TunnelBase // implements TunnelBase
@ -53,6 +56,7 @@ namespace tunnel
private: private:
TunnelConfig * m_Config; TunnelConfig * m_Config;
TunnelPool * m_Pool; // pool, tunnel belongs to, or null
bool m_IsEstablished; bool m_IsEstablished;
CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption m_ECBDecryption; CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption m_ECBDecryption;
@ -101,9 +105,8 @@ namespace tunnel
Tunnels (); Tunnels ();
~Tunnels (); ~Tunnels ();
void Start (); void Start ();
void Stop (); void Stop ();
InboundTunnel * GetInboundTunnel (uint32_t tunnelID); InboundTunnel * GetInboundTunnel (uint32_t tunnelID);
Tunnel * GetPendingTunnel (uint32_t replyMsgID); Tunnel * GetPendingTunnel (uint32_t replyMsgID);
@ -117,6 +120,8 @@ namespace tunnel
void PostTunnelData (I2NPMessage * msg); void PostTunnelData (I2NPMessage * msg);
template<class TTunnel> template<class TTunnel>
TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0); TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0);
TunnelPool * CreateTunnelPool (i2p::data::LocalDestination * localDestination);
void DeleteTunnelPool (TunnelPool * pool);
OutboundTunnel * CreateOneHopOutboundTestTunnel (InboundTunnel * replyTunnel); OutboundTunnel * CreateOneHopOutboundTestTunnel (InboundTunnel * replyTunnel);
InboundTunnel * CreateOneHopInboundTestTunnel (OutboundTunnel * outboundTunnel = 0); InboundTunnel * CreateOneHopInboundTestTunnel (OutboundTunnel * outboundTunnel = 0);
@ -130,6 +135,7 @@ namespace tunnel
void ManageOutboundTunnels (); void ManageOutboundTunnels ();
void ManageInboundTunnels (); void ManageInboundTunnels ();
void ManageTransitTunnels (); void ManageTransitTunnels ();
void ManageTunnelPools ();
void CreateZeroHopsInboundTunnel (); void CreateZeroHopsInboundTunnel ();
@ -143,6 +149,7 @@ namespace tunnel
std::map<uint32_t, InboundTunnel *> m_InboundTunnels; std::map<uint32_t, InboundTunnel *> m_InboundTunnels;
std::list<OutboundTunnel *> m_OutboundTunnels; std::list<OutboundTunnel *> m_OutboundTunnels;
std::map<uint32_t, TransitTunnel *> m_TransitTunnels; std::map<uint32_t, TransitTunnel *> m_TransitTunnels;
std::list<TunnelPool *> m_Pools;
i2p::util::Queue<I2NPMessage> m_Queue; i2p::util::Queue<I2NPMessage> m_Queue;
public: public:

11
TunnelBase.h

@ -48,6 +48,17 @@ namespace tunnel
uint32_t m_CreationTime; // seconds since epoch uint32_t m_CreationTime; // seconds since epoch
}; };
struct TunnelCreationTimeCmp
{
bool operator() (const TunnelBase * t1, const TunnelBase * t2) const
{
if (t1->GetCreationTime () != t2->GetCreationTime ())
return t1->GetCreationTime () > t2->GetCreationTime ();
else
return t1 < t2;
};
};
} }
} }

73
TunnelPool.cpp

@ -0,0 +1,73 @@
#include "Tunnel.h"
#include "NetDb.h"
#include "Timestamp.h"
#include "TunnelPool.h"
namespace i2p
{
namespace tunnel
{
TunnelPool::TunnelPool (i2p::data::LocalDestination * owner, int numTunnels):
m_Owner (owner), m_NumTunnels (numTunnels)
{
}
TunnelPool::~TunnelPool ()
{
for (auto it: m_InboundTunnels)
it->SetTunnelPool (nullptr);
}
void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel)
{
m_InboundTunnels.insert (createdTunnel);
if (m_Owner)
m_Owner->UpdateLeaseSet ();
}
void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel)
{
m_InboundTunnels.erase (expiredTunnel);
if (m_Owner)
m_Owner->UpdateLeaseSet ();
}
std::vector<InboundTunnel *> TunnelPool::GetInboundTunnels (int num) const
{
std::vector<InboundTunnel *> v;
int i = 0;
for (auto it : m_InboundTunnels)
{
if (i >= num) break;
v.push_back (it);
i++;
}
return v;
}
void TunnelPool::CreateTunnels ()
{
int num = m_InboundTunnels.size ();
for (int i = num; i < m_NumTunnels; i++)
CreateInboundTunnel ();
}
void TunnelPool::CreateInboundTunnel ()
{
OutboundTunnel * outboundTunnel = tunnels.GetNextOutboundTunnel ();
LogPrint ("Creating destination inbound tunnel...");
auto firstHop = i2p::data::netdb.GetRandomRouter (outboundTunnel ? outboundTunnel->GetEndpointRouter () : nullptr);
auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop);
auto * tunnel = tunnels.CreateTunnel<InboundTunnel> (
new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
{
firstHop,
secondHop
// TODO: swithc to 3-hops later
/*i2p::data::netdb.GetRandomRouter (secondHop) */
}),
outboundTunnel);
tunnel->SetTunnelPool (this);
}
}
}

46
TunnelPool.h

@ -0,0 +1,46 @@
#ifndef TUNNEL_POOL__
#define TUNNEL_POOL__
#include <set>
#include <vector>
#include "Identity.h"
#include "LeaseSet.h"
#include "I2NPProtocol.h"
#include "TunnelBase.h"
namespace i2p
{
namespace tunnel
{
class Tunnel;
class InboundTunnel;
class OutboundTunnel;
class TunnelPool // per local destination
{
public:
TunnelPool (i2p::data::LocalDestination * owner, int numTunnels = 5);
~TunnelPool ();
void CreateTunnels ();
void TunnelCreated (InboundTunnel * createdTunnel);
void TunnelExpired (InboundTunnel * expiredTunnel);
std::vector<InboundTunnel *> GetInboundTunnels (int num) const;
private:
void CreateInboundTunnel ();
private:
i2p::data::LocalDestination * m_Owner;
int m_NumTunnels;
std::set<InboundTunnel *, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
};
}
}
#endif

3
i2p.cpp

@ -24,6 +24,7 @@
#include "HTTPServer.h" #include "HTTPServer.h"
#include "Garlic.h" #include "Garlic.h"
#include "util.h" #include "util.h"
#include "Streaming.h"
// Global // Global
@ -154,6 +155,7 @@ int main( int argc, char* argv[] )
i2p::transports.Start (); i2p::transports.Start ();
i2p::tunnel::tunnels.Start (); i2p::tunnel::tunnels.Start ();
i2p::garlic::routing.Start (); i2p::garlic::routing.Start ();
i2p::stream::StartStreaming ();
while (running) while (running)
{ {
@ -162,6 +164,7 @@ int main( int argc, char* argv[] )
} }
LogPrint("Shutdown started."); LogPrint("Shutdown started.");
i2p::stream::StopStreaming ();
i2p::garlic::routing.Stop (); i2p::garlic::routing.Stop ();
i2p::tunnel::tunnels.Stop (); i2p::tunnel::tunnels.Stop ();
i2p::transports.Stop (); i2p::transports.Stop ();

12
util.cpp

@ -121,6 +121,18 @@ namespace filesystem
return path; return path;
} }
std::string GetFullPath (const std::string& filename)
{
std::string fullPath = GetDataDir ().string ();
#ifndef _WIN32
fullPath.append ("/");
#else
fullPath.append ("\\");
#endif
fullPath.append (filename);
return fullPath;
}
boost::filesystem::path GetConfigFile() boost::filesystem::path GetConfigFile()
{ {
boost::filesystem::path pathConfigFile(i2p::util::config::GetArg("-conf", "i2p.conf")); boost::filesystem::path pathConfigFile(i2p::util::config::GetArg("-conf", "i2p.conf"));

1
util.h

@ -25,6 +25,7 @@ namespace util
namespace filesystem namespace filesystem
{ {
const boost::filesystem::path &GetDataDir(); const boost::filesystem::path &GetDataDir();
std::string GetFullPath (const std::string& filename);
boost::filesystem::path GetDefaultDataDir(); boost::filesystem::path GetDefaultDataDir();
boost::filesystem::path GetConfigFile(); boost::filesystem::path GetConfigFile();
void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet,

Loading…
Cancel
Save