mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-21 23:54:14 +00:00
Merge pull request #14 from orignal/master
Merge pull request from orignal/master
This commit is contained in:
commit
98554be01b
@ -5,6 +5,7 @@
|
||||
#include "RouterContext.h"
|
||||
#include "I2NPProtocol.h"
|
||||
#include "Tunnel.h"
|
||||
#include "TunnelPool.h"
|
||||
#include "Timestamp.h"
|
||||
#include "Streaming.h"
|
||||
#include "Garlic.h"
|
||||
@ -288,9 +289,12 @@ namespace garlic
|
||||
else
|
||||
{
|
||||
// new session
|
||||
i2p::tunnel::TunnelPool * pool = nullptr;
|
||||
if (msg->from)
|
||||
pool = msg->from->GetTunnelPool ();
|
||||
ElGamalBlock elGamal;
|
||||
if (i2p::crypto::ElGamalDecrypt (
|
||||
msg->from ? i2p::context.GetLeaseSetPrivateKey () : i2p::context.GetPrivateKey (),
|
||||
pool ? pool->GetEncryptionPrivateKey () : i2p::context.GetPrivateKey (),
|
||||
buf, (uint8_t *)&elGamal, true))
|
||||
{
|
||||
uint8_t iv[32]; // IV is first 16 bytes
|
||||
|
@ -139,6 +139,8 @@ namespace util
|
||||
for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ())
|
||||
{
|
||||
it->GetTunnelConfig ()->Print (s);
|
||||
if (it->GetTunnelPool ())
|
||||
s << " " << "Pool";
|
||||
s << " " << (int)it->GetNumSentBytes () << "<BR>";
|
||||
}
|
||||
|
||||
@ -195,14 +197,31 @@ namespace util
|
||||
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];
|
||||
if (i2p::data::Base32ToByteStream (b32.c_str (), b32.length (), destination, 32) != 32)
|
||||
{
|
||||
LogPrint ("Invalid Base32 address ", b32);
|
||||
return;
|
||||
i2p::data::IdentHash destination;
|
||||
std::string fullAddress;
|
||||
if (address.find (".i2p") != std::string::npos)
|
||||
{
|
||||
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);
|
||||
if (!leaseSet || !leaseSet->HasNonExpiredLeases ())
|
||||
{
|
||||
@ -223,7 +242,7 @@ namespace util
|
||||
auto s = i2p::stream::CreateStream (*leaseSet);
|
||||
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);
|
||||
std::stringstream ss;
|
||||
uint8_t buf[8192];
|
||||
|
@ -48,7 +48,7 @@ namespace util
|
||||
void HandleWrite(const boost::system::error_code& ecode);
|
||||
|
||||
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);
|
||||
std::string ExtractAddress ();
|
||||
|
||||
|
14
NetDb.cpp
14
NetDb.cpp
@ -550,11 +550,15 @@ namespace data
|
||||
void NetDb::Publish ()
|
||||
{
|
||||
std::set<IdentHash> excluded; // TODO: fill up later
|
||||
auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded);
|
||||
if (floodfill)
|
||||
{
|
||||
LogPrint ("Publishing our RouterInfo to ", floodfill->GetIdentHashAbbreviation ());
|
||||
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg ());
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded);
|
||||
if (floodfill)
|
||||
{
|
||||
LogPrint ("Publishing our RouterInfo to ", floodfill->GetIdentHashAbbreviation ());
|
||||
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg ());
|
||||
excluded.insert (floodfill->GetIdentHash ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,6 @@ namespace i2p
|
||||
if (!Load ())
|
||||
CreateNewRouter ();
|
||||
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 ()
|
||||
|
@ -20,8 +20,6 @@ namespace i2p
|
||||
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
|
||||
const uint8_t * GetPrivateKey () const { return m_Keys.privateKey; };
|
||||
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 (); };
|
||||
CryptoPP::RandomNumberGenerator& GetRandomNumberGenerator () { return m_Rnd; };
|
||||
|
||||
@ -42,7 +40,6 @@ namespace i2p
|
||||
i2p::data::RouterInfo m_RouterInfo;
|
||||
i2p::data::Keys m_Keys;
|
||||
CryptoPP::DSA::PrivateKey m_SigningPrivateKey;
|
||||
uint8_t m_LeaseSetPublicKey[256], m_LeaseSetPrivateKey[256];
|
||||
CryptoPP::AutoSeededRandomPool m_Rnd;
|
||||
};
|
||||
|
||||
|
11
SSU.cpp
11
SSU.cpp
@ -418,7 +418,10 @@ namespace ssu
|
||||
LogPrint ("Unexpected payload type ", (int)(header->flag >> 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("MAC verification failed");
|
||||
Failed ();
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint ("SSU is not supported");
|
||||
@ -511,6 +514,14 @@ namespace ssu
|
||||
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
|
||||
{
|
||||
|
4
SSU.h
4
SSU.h
@ -58,7 +58,8 @@ namespace ssu
|
||||
eSessionRelayRequestSent,
|
||||
eSessionRelayRequestReceived,
|
||||
eSessionRelayResponseReceived,
|
||||
eSessionStateEstablished
|
||||
eSessionStateEstablished,
|
||||
eSessionStateFailed
|
||||
};
|
||||
|
||||
class SSUServer;
|
||||
@ -91,6 +92,7 @@ namespace ssu
|
||||
void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag);
|
||||
void ProcessRelayResponse (uint8_t * buf, size_t len);
|
||||
void Established ();
|
||||
void Failed ();
|
||||
void ProcessData (uint8_t * buf, size_t len);
|
||||
void SendMsgAck (uint32_t msgID);
|
||||
void SendSesionDestroyed ();
|
||||
|
@ -171,7 +171,7 @@ namespace stream
|
||||
CreateDataMessage (this, packet, size), m_LocalDestination->GetLeaseSet ());
|
||||
|
||||
if (!m_OutboundTunnel)
|
||||
m_OutboundTunnel = i2p::tunnel::tunnels.GetNextOutboundTunnel ();
|
||||
m_OutboundTunnel = m_LocalDestination->GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||
auto leases = m_RemoteLeaseSet.GetNonExpiredLeases ();
|
||||
if (m_OutboundTunnel && !leases.empty ())
|
||||
{
|
||||
@ -377,7 +377,7 @@ namespace stream
|
||||
size_t size = 0;
|
||||
memcpy (buf + size, &m_Identity, sizeof (m_Identity));
|
||||
size += sizeof (m_Identity); // destination
|
||||
memcpy (buf + size, i2p::context.GetLeaseSetPublicKey (), 256);
|
||||
memcpy (buf + size, m_Pool->GetEncryptionPublicKey (), 256);
|
||||
size += 256; // encryption key
|
||||
memset (buf + size, 0, 128);
|
||||
size += 128; // signing key
|
||||
|
@ -108,6 +108,7 @@ namespace stream
|
||||
const i2p::data::Keys& GetKeys () const { return m_Keys; };
|
||||
const i2p::data::Identity& GetIdentity () const { return m_Identity; };
|
||||
I2NPMessage * GetLeaseSet ();
|
||||
i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; };
|
||||
void Sign (uint8_t * buf, int len, uint8_t * signature) const;
|
||||
|
||||
Stream * CreateNewStream (const i2p::data::LeaseSet& remote);
|
||||
|
@ -390,13 +390,16 @@ namespace tunnel
|
||||
if (ts > (*it)->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
LogPrint ("Tunnel ", (*it)->GetTunnelID (), " expired");
|
||||
auto pool = (*it)->GetTunnelPool ();
|
||||
if (pool)
|
||||
pool->TunnelExpired (*it);
|
||||
it = m_OutboundTunnels.erase (it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
|
||||
if (m_OutboundTunnels.size () < 10)
|
||||
if (m_OutboundTunnels.size () < 15) // TODO: store exploratory tunnels explicitly
|
||||
{
|
||||
// trying to create one more oubound tunnel
|
||||
if (m_InboundTunnels.empty ()) return;
|
||||
@ -520,6 +523,9 @@ namespace tunnel
|
||||
void Tunnels::AddOutboundTunnel (OutboundTunnel * newTunnel)
|
||||
{
|
||||
m_OutboundTunnels.push_back (newTunnel);
|
||||
auto pool = newTunnel->GetTunnelPool ();
|
||||
if (pool)
|
||||
pool->TunnelCreated (newTunnel);
|
||||
}
|
||||
|
||||
void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel)
|
||||
|
@ -1,36 +1,54 @@
|
||||
#include <cryptopp/dh.h>
|
||||
#include "CryptoConst.h"
|
||||
#include "Tunnel.h"
|
||||
#include "NetDb.h"
|
||||
#include "Timestamp.h"
|
||||
#include "RouterContext.h"
|
||||
#include "TunnelPool.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace tunnel
|
||||
{
|
||||
TunnelPool::TunnelPool (i2p::data::LocalDestination * owner, int numTunnels):
|
||||
m_Owner (owner), m_NumTunnels (numTunnels)
|
||||
TunnelPool::TunnelPool (i2p::data::LocalDestination * localDestination, int 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 ()
|
||||
{
|
||||
for (auto it: m_InboundTunnels)
|
||||
it->SetTunnelPool (nullptr);
|
||||
for (auto it: m_OutboundTunnels)
|
||||
it->SetTunnelPool (nullptr);
|
||||
}
|
||||
|
||||
void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel)
|
||||
{
|
||||
m_InboundTunnels.insert (createdTunnel);
|
||||
if (m_Owner)
|
||||
m_Owner->UpdateLeaseSet ();
|
||||
if (m_LocalDestination)
|
||||
m_LocalDestination->UpdateLeaseSet ();
|
||||
}
|
||||
|
||||
void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel)
|
||||
{
|
||||
m_InboundTunnels.erase (expiredTunnel);
|
||||
if (m_Owner)
|
||||
m_Owner->UpdateLeaseSet ();
|
||||
if (m_LocalDestination)
|
||||
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
|
||||
{
|
||||
@ -45,16 +63,37 @@ namespace tunnel
|
||||
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 ()
|
||||
{
|
||||
int num = m_InboundTunnels.size ();
|
||||
for (int i = num; i < m_NumTunnels; i++)
|
||||
CreateInboundTunnel ();
|
||||
num = m_OutboundTunnels.size ();
|
||||
for (int i = num; i < m_NumTunnels; i++)
|
||||
CreateOutboundTunnel ();
|
||||
}
|
||||
|
||||
void TunnelPool::CreateInboundTunnel ()
|
||||
{
|
||||
OutboundTunnel * outboundTunnel = tunnels.GetNextOutboundTunnel ();
|
||||
OutboundTunnel * outboundTunnel = m_OutboundTunnels.size () > 0 ?
|
||||
*m_OutboundTunnels.begin () : tunnels.GetNextOutboundTunnel ();
|
||||
LogPrint ("Creating destination inbound tunnel...");
|
||||
auto firstHop = i2p::data::netdb.GetRandomRouter (outboundTunnel ? outboundTunnel->GetEndpointRouter () : nullptr);
|
||||
auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop);
|
||||
@ -63,11 +102,31 @@ namespace tunnel
|
||||
{
|
||||
firstHop,
|
||||
secondHop
|
||||
// TODO: swithc to 3-hops later
|
||||
// TODO: switch to 3-hops later
|
||||
/*i2p::data::netdb.GetRandomRouter (secondHop) */
|
||||
}),
|
||||
outboundTunnel);
|
||||
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
19
TunnelPool.h
@ -20,24 +20,33 @@ namespace tunnel
|
||||
{
|
||||
public:
|
||||
|
||||
TunnelPool (i2p::data::LocalDestination * owner, int numTunnels = 5);
|
||||
TunnelPool (i2p::data::LocalDestination * localDestination, int numTunnels = 5);
|
||||
~TunnelPool ();
|
||||
|
||||
const uint8_t * GetEncryptionPrivateKey () const { return m_EncryptionPrivateKey; };
|
||||
const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; };
|
||||
|
||||
void CreateTunnels ();
|
||||
void TunnelCreated (InboundTunnel * createdTunnel);
|
||||
void TunnelExpired (InboundTunnel * expiredTunnel);
|
||||
void TunnelCreated (OutboundTunnel * createdTunnel);
|
||||
void TunnelExpired (OutboundTunnel * expiredTunnel);
|
||||
std::vector<InboundTunnel *> GetInboundTunnels (int num) const;
|
||||
|
||||
OutboundTunnel * GetNextOutboundTunnel ();
|
||||
|
||||
private:
|
||||
|
||||
void CreateInboundTunnel ();
|
||||
|
||||
void CreateOutboundTunnel ();
|
||||
|
||||
private:
|
||||
|
||||
i2p::data::LocalDestination * m_Owner;
|
||||
uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
|
||||
i2p::data::LocalDestination * m_LocalDestination;
|
||||
int m_NumTunnels;
|
||||
std::set<InboundTunnel *, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
|
||||
|
||||
std::set<OutboundTunnel *, TunnelCreationTimeCmp> m_OutboundTunnels;
|
||||
OutboundTunnel * m_LastOutboundTunnel;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user