Browse Source

Merge pull request #14 from orignal/master

Merge pull request from orignal/master
pull/47/head
chertov 10 years ago
parent
commit
98554be01b
  1. 6
      Garlic.cpp
  2. 33
      HTTPServer.cpp
  3. 2
      HTTPServer.h
  4. 14
      NetDb.cpp
  5. 4
      RouterContext.cpp
  6. 3
      RouterContext.h
  7. 11
      SSU.cpp
  8. 4
      SSU.h
  9. 4
      Streaming.cpp
  10. 1
      Streaming.h
  11. 8
      Tunnel.cpp
  12. 75
      TunnelPool.cpp
  13. 19
      TunnelPool.h

6
Garlic.cpp

@ -5,6 +5,7 @@
#include "RouterContext.h" #include "RouterContext.h"
#include "I2NPProtocol.h" #include "I2NPProtocol.h"
#include "Tunnel.h" #include "Tunnel.h"
#include "TunnelPool.h"
#include "Timestamp.h" #include "Timestamp.h"
#include "Streaming.h" #include "Streaming.h"
#include "Garlic.h" #include "Garlic.h"
@ -288,9 +289,12 @@ namespace garlic
else else
{ {
// new session // new session
i2p::tunnel::TunnelPool * pool = nullptr;
if (msg->from)
pool = msg->from->GetTunnelPool ();
ElGamalBlock elGamal; ElGamalBlock elGamal;
if (i2p::crypto::ElGamalDecrypt ( if (i2p::crypto::ElGamalDecrypt (
msg->from ? i2p::context.GetLeaseSetPrivateKey () : i2p::context.GetPrivateKey (), pool ? pool->GetEncryptionPrivateKey () : i2p::context.GetPrivateKey (),
buf, (uint8_t *)&elGamal, true)) buf, (uint8_t *)&elGamal, true))
{ {
uint8_t iv[32]; // IV is first 16 bytes uint8_t iv[32]; // IV is first 16 bytes

33
HTTPServer.cpp

@ -139,6 +139,8 @@ namespace util
for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ()) for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ())
{ {
it->GetTunnelConfig ()->Print (s); it->GetTunnelConfig ()->Print (s);
if (it->GetTunnelPool ())
s << " " << "Pool";
s << " " << (int)it->GetNumSentBytes () << "<BR>"; s << " " << (int)it->GetNumSentBytes () << "<BR>";
} }
@ -195,14 +197,31 @@ namespace util
s << "<p><a href=\"zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq\">Flibusta</a></p>"; s << "<p><a href=\"zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq\">Flibusta</a></p>";
} }
void HTTPConnection::HandleDestinationRequest (const std::string& b32, const std::string& uri) void HTTPConnection::HandleDestinationRequest (const std::string& address, const std::string& uri)
{ {
uint8_t destination[32]; i2p::data::IdentHash destination;
if (i2p::data::Base32ToByteStream (b32.c_str (), b32.length (), destination, 32) != 32) std::string fullAddress;
{ if (address.find (".i2p") != std::string::npos)
LogPrint ("Invalid Base32 address ", b32); {
return; auto addr = i2p::data::netdb.FindAddress(address);
if (!addr)
{
LogPrint ("Unknown address ", address);
return;
}
destination = *addr;
fullAddress = address;
}
else
{
if (i2p::data::Base32ToByteStream (address.c_str (), address.length (), (uint8_t *)destination, 32) != 32)
{
LogPrint ("Invalid Base32 address ", address);
return;
}
fullAddress = address + ".b32.i2p";
} }
auto leaseSet = i2p::data::netdb.FindLeaseSet (destination); auto leaseSet = i2p::data::netdb.FindLeaseSet (destination);
if (!leaseSet || !leaseSet->HasNonExpiredLeases ()) if (!leaseSet || !leaseSet->HasNonExpiredLeases ())
{ {
@ -223,7 +242,7 @@ namespace util
auto s = i2p::stream::CreateStream (*leaseSet); auto s = i2p::stream::CreateStream (*leaseSet);
if (s) if (s)
{ {
std::string request = "GET " + uri + " HTTP/1.1\n Host:" + b32 + ".b32.i2p\n"; std::string request = "GET " + uri + " HTTP/1.1\n Host:" + fullAddress + "\n";
s->Send ((uint8_t *)request.c_str (), request.length (), 10); s->Send ((uint8_t *)request.c_str (), request.length (), 10);
std::stringstream ss; std::stringstream ss;
uint8_t buf[8192]; uint8_t buf[8192];

2
HTTPServer.h

@ -48,7 +48,7 @@ namespace util
void HandleWrite(const boost::system::error_code& ecode); void HandleWrite(const boost::system::error_code& ecode);
void HandleRequest (); void HandleRequest ();
void HandleDestinationRequest (const std::string& b32, const std::string& uri); void HandleDestinationRequest (const std::string& address, const std::string& uri);
void FillContent (std::stringstream& s); void FillContent (std::stringstream& s);
std::string ExtractAddress (); std::string ExtractAddress ();

14
NetDb.cpp

@ -550,11 +550,15 @@ namespace data
void NetDb::Publish () void NetDb::Publish ()
{ {
std::set<IdentHash> excluded; // TODO: fill up later std::set<IdentHash> excluded; // TODO: fill up later
auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded); for (int i = 0; i < 3; i++)
if (floodfill) {
{ auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded);
LogPrint ("Publishing our RouterInfo to ", floodfill->GetIdentHashAbbreviation ()); if (floodfill)
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg ()); {
LogPrint ("Publishing our RouterInfo to ", floodfill->GetIdentHashAbbreviation ());
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg ());
excluded.insert (floodfill->GetIdentHash ());
}
} }
} }

4
RouterContext.cpp

@ -14,10 +14,6 @@ namespace i2p
if (!Load ()) if (!Load ())
CreateNewRouter (); CreateNewRouter ();
Save (); Save ();
// we generate LeaseSet at every start-up
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg);
dh.GenerateKeyPair(m_Rnd, m_LeaseSetPrivateKey, m_LeaseSetPublicKey);
} }
void RouterContext::CreateNewRouter () void RouterContext::CreateNewRouter ()

3
RouterContext.h

@ -20,8 +20,6 @@ namespace i2p
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; }; i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
const uint8_t * GetPrivateKey () const { return m_Keys.privateKey; }; const uint8_t * GetPrivateKey () const { return m_Keys.privateKey; };
const uint8_t * GetSigningPrivateKey () const { return m_Keys.signingPrivateKey; }; const uint8_t * GetSigningPrivateKey () const { return m_Keys.signingPrivateKey; };
const uint8_t * GetLeaseSetPrivateKey () const { return m_LeaseSetPrivateKey; };
const uint8_t * GetLeaseSetPublicKey () const { return m_LeaseSetPublicKey; };
const i2p::data::Identity& GetRouterIdentity () const { return m_RouterInfo.GetRouterIdentity (); }; const i2p::data::Identity& GetRouterIdentity () const { return m_RouterInfo.GetRouterIdentity (); };
CryptoPP::RandomNumberGenerator& GetRandomNumberGenerator () { return m_Rnd; }; CryptoPP::RandomNumberGenerator& GetRandomNumberGenerator () { return m_Rnd; };
@ -42,7 +40,6 @@ namespace i2p
i2p::data::RouterInfo m_RouterInfo; i2p::data::RouterInfo m_RouterInfo;
i2p::data::Keys m_Keys; i2p::data::Keys m_Keys;
CryptoPP::DSA::PrivateKey m_SigningPrivateKey; CryptoPP::DSA::PrivateKey m_SigningPrivateKey;
uint8_t m_LeaseSetPublicKey[256], m_LeaseSetPrivateKey[256];
CryptoPP::AutoSeededRandomPool m_Rnd; CryptoPP::AutoSeededRandomPool m_Rnd;
}; };

11
SSU.cpp

@ -418,7 +418,10 @@ namespace ssu
LogPrint ("Unexpected payload type ", (int)(header->flag >> 4)); LogPrint ("Unexpected payload type ", (int)(header->flag >> 4));
} }
else else
{
LogPrint ("MAC verification failed"); LogPrint ("MAC verification failed");
Failed ();
}
} }
else else
LogPrint ("SSU is not supported"); LogPrint ("SSU is not supported");
@ -511,6 +514,14 @@ namespace ssu
m_DelayedMessages.clear (); m_DelayedMessages.clear ();
} }
} }
void SSUSession::Failed ()
{
m_State = eSessionStateFailed;
Close ();
if (m_Server)
m_Server->DeleteSession (this); // delete this
}
const uint8_t * SSUSession::GetIntroKey () const const uint8_t * SSUSession::GetIntroKey () const
{ {

4
SSU.h

@ -58,7 +58,8 @@ namespace ssu
eSessionRelayRequestSent, eSessionRelayRequestSent,
eSessionRelayRequestReceived, eSessionRelayRequestReceived,
eSessionRelayResponseReceived, eSessionRelayResponseReceived,
eSessionStateEstablished eSessionStateEstablished,
eSessionStateFailed
}; };
class SSUServer; class SSUServer;
@ -91,6 +92,7 @@ namespace ssu
void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag); void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag);
void ProcessRelayResponse (uint8_t * buf, size_t len); void ProcessRelayResponse (uint8_t * buf, size_t len);
void Established (); void Established ();
void Failed ();
void ProcessData (uint8_t * buf, size_t len); void ProcessData (uint8_t * buf, size_t len);
void SendMsgAck (uint32_t msgID); void SendMsgAck (uint32_t msgID);
void SendSesionDestroyed (); void SendSesionDestroyed ();

4
Streaming.cpp

@ -171,7 +171,7 @@ namespace stream
CreateDataMessage (this, packet, size), m_LocalDestination->GetLeaseSet ()); CreateDataMessage (this, packet, size), m_LocalDestination->GetLeaseSet ());
if (!m_OutboundTunnel) if (!m_OutboundTunnel)
m_OutboundTunnel = i2p::tunnel::tunnels.GetNextOutboundTunnel (); m_OutboundTunnel = m_LocalDestination->GetTunnelPool ()->GetNextOutboundTunnel ();
auto leases = m_RemoteLeaseSet.GetNonExpiredLeases (); auto leases = m_RemoteLeaseSet.GetNonExpiredLeases ();
if (m_OutboundTunnel && !leases.empty ()) if (m_OutboundTunnel && !leases.empty ())
{ {
@ -377,7 +377,7 @@ namespace stream
size_t size = 0; size_t size = 0;
memcpy (buf + size, &m_Identity, sizeof (m_Identity)); memcpy (buf + size, &m_Identity, sizeof (m_Identity));
size += sizeof (m_Identity); // destination size += sizeof (m_Identity); // destination
memcpy (buf + size, i2p::context.GetLeaseSetPublicKey (), 256); memcpy (buf + size, m_Pool->GetEncryptionPublicKey (), 256);
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

1
Streaming.h

@ -108,6 +108,7 @@ namespace stream
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 ();
i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; };
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);

8
Tunnel.cpp

@ -390,13 +390,16 @@ namespace tunnel
if (ts > (*it)->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) if (ts > (*it)->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
{ {
LogPrint ("Tunnel ", (*it)->GetTunnelID (), " expired"); LogPrint ("Tunnel ", (*it)->GetTunnelID (), " expired");
auto pool = (*it)->GetTunnelPool ();
if (pool)
pool->TunnelExpired (*it);
it = m_OutboundTunnels.erase (it); it = m_OutboundTunnels.erase (it);
} }
else else
it++; it++;
} }
if (m_OutboundTunnels.size () < 10) if (m_OutboundTunnels.size () < 15) // TODO: store exploratory tunnels explicitly
{ {
// trying to create one more oubound tunnel // trying to create one more oubound tunnel
if (m_InboundTunnels.empty ()) return; if (m_InboundTunnels.empty ()) return;
@ -520,6 +523,9 @@ namespace tunnel
void Tunnels::AddOutboundTunnel (OutboundTunnel * newTunnel) void Tunnels::AddOutboundTunnel (OutboundTunnel * newTunnel)
{ {
m_OutboundTunnels.push_back (newTunnel); m_OutboundTunnels.push_back (newTunnel);
auto pool = newTunnel->GetTunnelPool ();
if (pool)
pool->TunnelCreated (newTunnel);
} }
void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel) void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel)

75
TunnelPool.cpp

@ -1,36 +1,54 @@
#include <cryptopp/dh.h>
#include "CryptoConst.h"
#include "Tunnel.h" #include "Tunnel.h"
#include "NetDb.h" #include "NetDb.h"
#include "Timestamp.h" #include "Timestamp.h"
#include "RouterContext.h"
#include "TunnelPool.h" #include "TunnelPool.h"
namespace i2p namespace i2p
{ {
namespace tunnel namespace tunnel
{ {
TunnelPool::TunnelPool (i2p::data::LocalDestination * owner, int numTunnels): TunnelPool::TunnelPool (i2p::data::LocalDestination * localDestination, int numTunnels):
m_Owner (owner), m_NumTunnels (numTunnels) m_LocalDestination (localDestination), m_NumTunnels (numTunnels), m_LastOutboundTunnel (nullptr)
{ {
CryptoPP::AutoSeededRandomPool rnd;
CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg);
dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey);
} }
TunnelPool::~TunnelPool () TunnelPool::~TunnelPool ()
{ {
for (auto it: m_InboundTunnels) for (auto it: m_InboundTunnels)
it->SetTunnelPool (nullptr); it->SetTunnelPool (nullptr);
for (auto it: m_OutboundTunnels)
it->SetTunnelPool (nullptr);
} }
void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel) void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel)
{ {
m_InboundTunnels.insert (createdTunnel); m_InboundTunnels.insert (createdTunnel);
if (m_Owner) if (m_LocalDestination)
m_Owner->UpdateLeaseSet (); m_LocalDestination->UpdateLeaseSet ();
} }
void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel) void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel)
{ {
m_InboundTunnels.erase (expiredTunnel); m_InboundTunnels.erase (expiredTunnel);
if (m_Owner) if (m_LocalDestination)
m_Owner->UpdateLeaseSet (); m_LocalDestination->UpdateLeaseSet ();
} }
void TunnelPool::TunnelCreated (OutboundTunnel * createdTunnel)
{
m_OutboundTunnels.insert (createdTunnel);
}
void TunnelPool::TunnelExpired (OutboundTunnel * expiredTunnel)
{
m_OutboundTunnels.erase (expiredTunnel);
}
std::vector<InboundTunnel *> TunnelPool::GetInboundTunnels (int num) const std::vector<InboundTunnel *> TunnelPool::GetInboundTunnels (int num) const
{ {
@ -45,16 +63,37 @@ namespace tunnel
return v; return v;
} }
OutboundTunnel * TunnelPool::GetNextOutboundTunnel ()
{
if (m_OutboundTunnels.empty ()) return nullptr;
auto tunnel = *m_OutboundTunnels.begin ();
if (m_LastOutboundTunnel && tunnel == m_LastOutboundTunnel)
{
for (auto it: m_OutboundTunnels)
if (it != m_LastOutboundTunnel)
{
tunnel = it;
break;
}
}
m_LastOutboundTunnel = tunnel;
return tunnel;
}
void TunnelPool::CreateTunnels () void TunnelPool::CreateTunnels ()
{ {
int num = m_InboundTunnels.size (); int num = m_InboundTunnels.size ();
for (int i = num; i < m_NumTunnels; i++) for (int i = num; i < m_NumTunnels; i++)
CreateInboundTunnel (); CreateInboundTunnel ();
num = m_OutboundTunnels.size ();
for (int i = num; i < m_NumTunnels; i++)
CreateOutboundTunnel ();
} }
void TunnelPool::CreateInboundTunnel () void TunnelPool::CreateInboundTunnel ()
{ {
OutboundTunnel * outboundTunnel = tunnels.GetNextOutboundTunnel (); OutboundTunnel * outboundTunnel = m_OutboundTunnels.size () > 0 ?
*m_OutboundTunnels.begin () : tunnels.GetNextOutboundTunnel ();
LogPrint ("Creating destination inbound tunnel..."); LogPrint ("Creating destination inbound tunnel...");
auto firstHop = i2p::data::netdb.GetRandomRouter (outboundTunnel ? outboundTunnel->GetEndpointRouter () : nullptr); auto firstHop = i2p::data::netdb.GetRandomRouter (outboundTunnel ? outboundTunnel->GetEndpointRouter () : nullptr);
auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop); auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop);
@ -63,11 +102,31 @@ namespace tunnel
{ {
firstHop, firstHop,
secondHop secondHop
// TODO: swithc to 3-hops later // TODO: switch to 3-hops later
/*i2p::data::netdb.GetRandomRouter (secondHop) */ /*i2p::data::netdb.GetRandomRouter (secondHop) */
}), }),
outboundTunnel); outboundTunnel);
tunnel->SetTunnelPool (this); tunnel->SetTunnelPool (this);
} }
void TunnelPool::CreateOutboundTunnel ()
{
InboundTunnel * inboundTunnel = m_InboundTunnels.size () > 0 ?
*m_InboundTunnels.begin () : tunnels.GetNextInboundTunnel ();
if (inboundTunnel)
{
LogPrint ("Creating destination outbound tunnel...");
auto firstHop = i2p::data::netdb.GetRandomRouter (&i2p::context.GetRouterInfo ());
auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop);
auto * tunnel = tunnels.CreateTunnel<OutboundTunnel> (
new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
{
firstHop,
secondHop
},
inboundTunnel->GetTunnelConfig ()));
tunnel->SetTunnelPool (this);
}
}
} }
} }

19
TunnelPool.h

@ -20,24 +20,33 @@ namespace tunnel
{ {
public: public:
TunnelPool (i2p::data::LocalDestination * owner, int numTunnels = 5); TunnelPool (i2p::data::LocalDestination * localDestination, int numTunnels = 5);
~TunnelPool (); ~TunnelPool ();
const uint8_t * GetEncryptionPrivateKey () const { return m_EncryptionPrivateKey; };
const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; };
void CreateTunnels (); void CreateTunnels ();
void TunnelCreated (InboundTunnel * createdTunnel); void TunnelCreated (InboundTunnel * createdTunnel);
void TunnelExpired (InboundTunnel * expiredTunnel); void TunnelExpired (InboundTunnel * expiredTunnel);
void TunnelCreated (OutboundTunnel * createdTunnel);
void TunnelExpired (OutboundTunnel * expiredTunnel);
std::vector<InboundTunnel *> GetInboundTunnels (int num) const; std::vector<InboundTunnel *> GetInboundTunnels (int num) const;
OutboundTunnel * GetNextOutboundTunnel ();
private: private:
void CreateInboundTunnel (); void CreateInboundTunnel ();
void CreateOutboundTunnel ();
private: private:
i2p::data::LocalDestination * m_Owner; uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
i2p::data::LocalDestination * m_LocalDestination;
int m_NumTunnels; int m_NumTunnels;
std::set<InboundTunnel *, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first std::set<InboundTunnel *, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
std::set<OutboundTunnel *, TunnelCreationTimeCmp> m_OutboundTunnels;
OutboundTunnel * m_LastOutboundTunnel;
}; };
} }
} }

Loading…
Cancel
Save