mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2024-11-19 21:25:30 +00:00
Merge pull request #17 from orignal/master
Merge pull request from orignal/master
This commit is contained in:
commit
ef0e7235c1
10
Garlic.cpp
10
Garlic.cpp
@ -43,7 +43,7 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg, I2NPMessage * leaseSet)
|
I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg, const I2NPMessage * leaseSet)
|
||||||
{
|
{
|
||||||
I2NPMessage * m = NewI2NPMessage ();
|
I2NPMessage * m = NewI2NPMessage ();
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
@ -89,7 +89,7 @@ namespace garlic
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet)
|
size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, const I2NPMessage * msg, const I2NPMessage * leaseSet)
|
||||||
{
|
{
|
||||||
size_t blockSize = 0;
|
size_t blockSize = 0;
|
||||||
*(uint16_t *)buf = m_NextTag < 0 ? htobe16 (m_NumTags) : 0; // tag count
|
*(uint16_t *)buf = m_NextTag < 0 ? htobe16 (m_NumTags) : 0; // tag count
|
||||||
@ -116,7 +116,7 @@ namespace garlic
|
|||||||
return blockSize;
|
return blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet)
|
size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, const I2NPMessage * leaseSet)
|
||||||
{
|
{
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
|
||||||
uint32_t msgID = m_Rnd.GenerateWord32 ();
|
uint32_t msgID = m_Rnd.GenerateWord32 ();
|
||||||
@ -153,7 +153,7 @@ namespace garlic
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, I2NPMessage * msg, bool isDestination)
|
size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, const I2NPMessage * msg, bool isDestination)
|
||||||
{
|
{
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
@ -245,7 +245,7 @@ namespace garlic
|
|||||||
}
|
}
|
||||||
|
|
||||||
I2NPMessage * GarlicRouting::WrapMessage (const i2p::data::RoutingDestination& destination,
|
I2NPMessage * GarlicRouting::WrapMessage (const i2p::data::RoutingDestination& destination,
|
||||||
I2NPMessage * msg, I2NPMessage * leaseSet)
|
I2NPMessage * msg, const I2NPMessage * leaseSet)
|
||||||
{
|
{
|
||||||
auto it = m_Sessions.find (destination.GetIdentHash ());
|
auto it = m_Sessions.find (destination.GetIdentHash ());
|
||||||
GarlicRoutingSession * session = nullptr;
|
GarlicRoutingSession * session = nullptr;
|
||||||
|
10
Garlic.h
10
Garlic.h
@ -42,7 +42,7 @@ namespace garlic
|
|||||||
|
|
||||||
GarlicRoutingSession (const i2p::data::RoutingDestination& destination, int numTags);
|
GarlicRoutingSession (const i2p::data::RoutingDestination& destination, int numTags);
|
||||||
~GarlicRoutingSession ();
|
~GarlicRoutingSession ();
|
||||||
I2NPMessage * WrapSingleMessage (I2NPMessage * msg, I2NPMessage * leaseSet);
|
I2NPMessage * WrapSingleMessage (I2NPMessage * msg, const I2NPMessage * leaseSet);
|
||||||
int GetNextTag () const { return m_NextTag; };
|
int GetNextTag () const { return m_NextTag; };
|
||||||
uint32_t GetFirstMsgID () const { return m_FirstMsgID; };
|
uint32_t GetFirstMsgID () const { return m_FirstMsgID; };
|
||||||
|
|
||||||
@ -51,9 +51,9 @@ namespace garlic
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet);
|
size_t CreateAESBlock (uint8_t * buf, const I2NPMessage * msg, const I2NPMessage * leaseSet);
|
||||||
size_t CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet);
|
size_t CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, const I2NPMessage * leaseSet);
|
||||||
size_t CreateGarlicClove (uint8_t * buf, I2NPMessage * msg, bool isDestination);
|
size_t CreateGarlicClove (uint8_t * buf, const I2NPMessage * msg, bool isDestination);
|
||||||
size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID);
|
size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID);
|
||||||
|
|
||||||
void GenerateSessionTags ();
|
void GenerateSessionTags ();
|
||||||
@ -86,7 +86,7 @@ namespace garlic
|
|||||||
|
|
||||||
I2NPMessage * WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg);
|
I2NPMessage * WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg);
|
||||||
I2NPMessage * WrapMessage (const i2p::data::RoutingDestination& destination,
|
I2NPMessage * WrapMessage (const i2p::data::RoutingDestination& destination,
|
||||||
I2NPMessage * msg, I2NPMessage * leaseSet = nullptr);
|
I2NPMessage * msg, const I2NPMessage * leaseSet = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -31,17 +31,17 @@ namespace i2p
|
|||||||
delete msg;
|
delete msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t I2NPmsgID = 0; // TODO: create class
|
||||||
void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID)
|
void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID)
|
||||||
{
|
{
|
||||||
static uint32_t msgID = 0;
|
|
||||||
I2NPHeader * header = msg->GetHeader ();
|
I2NPHeader * header = msg->GetHeader ();
|
||||||
header->typeID = msgType;
|
header->typeID = msgType;
|
||||||
if (replyMsgID) // for tunnel creation
|
if (replyMsgID) // for tunnel creation
|
||||||
header->msgID = htobe32 (replyMsgID);
|
header->msgID = htobe32 (replyMsgID);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
header->msgID = htobe32 (msgID);
|
header->msgID = htobe32 (I2NPmsgID);
|
||||||
msgID++;
|
I2NPmsgID++;
|
||||||
}
|
}
|
||||||
header->expiration = htobe64 (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number
|
header->expiration = htobe64 (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number
|
||||||
int len = msg->GetLength () - sizeof (I2NPHeader);
|
int len = msg->GetLength () - sizeof (I2NPHeader);
|
||||||
@ -51,6 +51,17 @@ namespace i2p
|
|||||||
header->chks = hash[0];
|
header->chks = hash[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenewI2NPMessageHeader (I2NPMessage * msg)
|
||||||
|
{
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
I2NPHeader * header = msg->GetHeader ();
|
||||||
|
header->msgID = htobe32 (I2NPmsgID);
|
||||||
|
I2NPmsgID++;
|
||||||
|
header->expiration = htobe64 (i2p::util::GetMillisecondsSinceEpoch () + 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID)
|
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID)
|
||||||
{
|
{
|
||||||
I2NPMessage * msg = NewI2NPMessage ();
|
I2NPMessage * msg = NewI2NPMessage ();
|
||||||
|
@ -103,9 +103,10 @@ namespace tunnel
|
|||||||
size_t len, offset;
|
size_t len, offset;
|
||||||
i2p::tunnel::InboundTunnel * from;
|
i2p::tunnel::InboundTunnel * from;
|
||||||
|
|
||||||
I2NPHeader * GetHeader () { return (I2NPHeader *)(buf + offset); };
|
I2NPHeader * GetHeader () { return (I2NPHeader *)GetBuffer (); };
|
||||||
uint8_t * GetPayload () { return buf + offset + sizeof(I2NPHeader); };
|
uint8_t * GetPayload () { return GetBuffer () + sizeof(I2NPHeader); };
|
||||||
uint8_t * GetBuffer () { return buf + offset; };
|
uint8_t * GetBuffer () { return buf + offset; };
|
||||||
|
const uint8_t * GetBuffer () const { return buf + offset; };
|
||||||
size_t GetLength () const { return len - offset; };
|
size_t GetLength () const { return len - offset; };
|
||||||
|
|
||||||
I2NPMessage& operator=(const I2NPMessage& other)
|
I2NPMessage& operator=(const I2NPMessage& other)
|
||||||
@ -141,6 +142,7 @@ namespace tunnel
|
|||||||
I2NPMessage * NewI2NPMessage ();
|
I2NPMessage * NewI2NPMessage ();
|
||||||
void DeleteI2NPMessage (I2NPMessage * msg);
|
void DeleteI2NPMessage (I2NPMessage * msg);
|
||||||
void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID = 0);
|
void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID = 0);
|
||||||
|
void RenewI2NPMessageHeader (I2NPMessage * msg);
|
||||||
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0);
|
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0);
|
||||||
I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len);
|
I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len);
|
||||||
|
|
||||||
|
@ -19,6 +19,13 @@ namespace data
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrivateKeys& PrivateKeys::operator=(const Keys& keys)
|
||||||
|
{
|
||||||
|
pub = keys;
|
||||||
|
memcpy (privateKey, keys.privateKey, 276); // 256 + 20
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
IdentHash CalculateIdentHash (const Identity& identity)
|
IdentHash CalculateIdentHash (const Identity& identity)
|
||||||
{
|
{
|
||||||
IdentHash hash;
|
IdentHash hash;
|
||||||
|
@ -28,6 +28,15 @@ namespace data
|
|||||||
Identity& operator=(const Keys& keys);
|
Identity& operator=(const Keys& keys);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PrivateKeys // for eepsites
|
||||||
|
{
|
||||||
|
Identity pub;
|
||||||
|
uint8_t privateKey[256];
|
||||||
|
uint8_t signingPrivateKey[20];
|
||||||
|
|
||||||
|
PrivateKeys& operator=(const Keys& keys);
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
class IdentHash
|
class IdentHash
|
||||||
|
36
NetDb.cpp
36
NetDb.cpp
@ -160,6 +160,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
LogPrint ("New RouterInfo added");
|
LogPrint ("New RouterInfo added");
|
||||||
m_RouterInfos[r->GetIdentHash ()] = r;
|
m_RouterInfos[r->GetIdentHash ()] = r;
|
||||||
|
if (r->IsFloodfill ())
|
||||||
|
m_Floodfills.push_back (r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +239,7 @@ namespace data
|
|||||||
for (auto r: m_RouterInfos)
|
for (auto r: m_RouterInfos)
|
||||||
delete r.second;
|
delete r.second;
|
||||||
m_RouterInfos.clear ();
|
m_RouterInfos.clear ();
|
||||||
|
m_Floodfills.clear ();
|
||||||
|
|
||||||
// load routers now
|
// load routers now
|
||||||
int numRouters = 0;
|
int numRouters = 0;
|
||||||
@ -253,11 +256,14 @@ namespace data
|
|||||||
RouterInfo * r = new RouterInfo(it1->path().c_str());
|
RouterInfo * r = new RouterInfo(it1->path().c_str());
|
||||||
#endif
|
#endif
|
||||||
m_RouterInfos[r->GetIdentHash ()] = r;
|
m_RouterInfos[r->GetIdentHash ()] = r;
|
||||||
|
if (r->IsFloodfill ())
|
||||||
|
m_Floodfills.push_back (r);
|
||||||
numRouters++;
|
numRouters++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogPrint (numRouters, " routers loaded");
|
LogPrint (numRouters, " routers loaded");
|
||||||
|
LogPrint (m_Floodfills.size (), " floodfills loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::SaveUpdated (const char * directory)
|
void NetDb::SaveUpdated (const char * directory)
|
||||||
@ -595,23 +601,7 @@ namespace data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RouterInfo * NetDb::GetRandomNTCPRouter (bool floodfillOnly) const
|
const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith, uint8_t caps) const
|
||||||
{
|
|
||||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
|
||||||
uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1), i = 0;
|
|
||||||
RouterInfo * last = nullptr;
|
|
||||||
for (auto it: m_RouterInfos)
|
|
||||||
{
|
|
||||||
if (it.second->IsNTCP () && !it.second->IsUnreachable () &&
|
|
||||||
(!floodfillOnly || it.second->IsFloodfill ()))
|
|
||||||
last = it.second;
|
|
||||||
if (i >= ind) break;
|
|
||||||
else i++;
|
|
||||||
}
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith, bool floodfillOnly) const
|
|
||||||
{
|
{
|
||||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||||
uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1);
|
uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1);
|
||||||
@ -624,7 +614,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
if (!it.second->IsUnreachable () &&
|
if (!it.second->IsUnreachable () &&
|
||||||
(!compatibleWith || it.second->IsCompatible (*compatibleWith)) &&
|
(!compatibleWith || it.second->IsCompatible (*compatibleWith)) &&
|
||||||
(!floodfillOnly || it.second->IsFloodfill ()))
|
(!caps || (it.second->GetCaps () & caps) == caps))
|
||||||
return it.second;
|
return it.second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -633,7 +623,7 @@ namespace data
|
|||||||
// we couldn't find anything, try second pass
|
// we couldn't find anything, try second pass
|
||||||
ind = 0;
|
ind = 0;
|
||||||
}
|
}
|
||||||
return nullptr; // seem we have too few routers
|
return nullptr; // seems we have too few routers
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::PostI2NPMsg (I2NPMessage * msg)
|
void NetDb::PostI2NPMsg (I2NPMessage * msg)
|
||||||
@ -648,15 +638,15 @@ namespace data
|
|||||||
XORMetric minMetric;
|
XORMetric minMetric;
|
||||||
RoutingKey destKey = CreateRoutingKey (destination);
|
RoutingKey destKey = CreateRoutingKey (destination);
|
||||||
minMetric.SetMax ();
|
minMetric.SetMax ();
|
||||||
for (auto it: m_RouterInfos)
|
for (auto it: m_Floodfills)
|
||||||
{
|
{
|
||||||
if (it.second->IsFloodfill () &&! it.second->IsUnreachable () && !excluded.count (it.first))
|
if (!it->IsUnreachable () && !excluded.count (it->GetIdentHash ()))
|
||||||
{
|
{
|
||||||
XORMetric m = destKey ^ it.second->GetRoutingKey ();
|
XORMetric m = destKey ^ it->GetRoutingKey ();
|
||||||
if (m < minMetric)
|
if (m < minMetric)
|
||||||
{
|
{
|
||||||
minMetric = m;
|
minMetric = m;
|
||||||
r = it.second;
|
r = it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
NetDb.h
5
NetDb.h
@ -4,6 +4,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
@ -73,8 +74,7 @@ namespace data
|
|||||||
void HandleDatabaseStoreMsg (uint8_t * buf, size_t len);
|
void HandleDatabaseStoreMsg (uint8_t * buf, size_t len);
|
||||||
void HandleDatabaseSearchReplyMsg (I2NPMessage * msg);
|
void HandleDatabaseSearchReplyMsg (I2NPMessage * msg);
|
||||||
|
|
||||||
const RouterInfo * GetRandomNTCPRouter (bool floodfillOnly = false) const;
|
const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith = nullptr, uint8_t caps = 0) const;
|
||||||
const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith = nullptr, bool floodfillOnly = false) const;
|
|
||||||
|
|
||||||
void PostI2NPMsg (I2NPMessage * msg);
|
void PostI2NPMsg (I2NPMessage * msg);
|
||||||
|
|
||||||
@ -98,6 +98,7 @@ namespace data
|
|||||||
|
|
||||||
std::map<IdentHash, LeaseSet *> m_LeaseSets;
|
std::map<IdentHash, LeaseSet *> m_LeaseSets;
|
||||||
std::map<IdentHash, RouterInfo *> m_RouterInfos;
|
std::map<IdentHash, RouterInfo *> m_RouterInfos;
|
||||||
|
std::vector<RouterInfo *> m_Floodfills;
|
||||||
std::map<IdentHash, RequestedDestination *> m_RequestedDestinations;
|
std::map<IdentHash, RequestedDestination *> m_RequestedDestinations;
|
||||||
std::set<IdentHash> m_Subscriptions;
|
std::set<IdentHash> m_Subscriptions;
|
||||||
|
|
||||||
|
@ -18,13 +18,13 @@ namespace i2p
|
|||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
RouterInfo::RouterInfo (const char * filename):
|
RouterInfo::RouterInfo (const char * filename):
|
||||||
m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0)
|
m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
|
||||||
{
|
{
|
||||||
ReadFromFile (filename);
|
ReadFromFile (filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterInfo::RouterInfo (const uint8_t * buf, int len):
|
RouterInfo::RouterInfo (const uint8_t * buf, int len):
|
||||||
m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0)
|
m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
|
||||||
{
|
{
|
||||||
memcpy (m_Buffer, buf, len);
|
memcpy (m_Buffer, buf, len);
|
||||||
m_BufferLen = len;
|
m_BufferLen = len;
|
||||||
@ -175,6 +175,10 @@ namespace data
|
|||||||
r += ReadString (value, s);
|
r += ReadString (value, s);
|
||||||
s.seekg (1, std::ios_base::cur); r++; // ;
|
s.seekg (1, std::ios_base::cur); r++; // ;
|
||||||
m_Properties[key] = value;
|
m_Properties[key] = value;
|
||||||
|
|
||||||
|
// extract caps
|
||||||
|
if (!strcmp (key, "caps"))
|
||||||
|
ExtractCaps (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&m_RouterIdentity, sizeof (m_RouterIdentity));
|
CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&m_RouterIdentity, sizeof (m_RouterIdentity));
|
||||||
@ -185,6 +189,31 @@ namespace data
|
|||||||
SetUnreachable (true);
|
SetUnreachable (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterInfo::ExtractCaps (const char * value)
|
||||||
|
{
|
||||||
|
m_Caps = 0;
|
||||||
|
const char * cap = value;
|
||||||
|
while (*cap)
|
||||||
|
{
|
||||||
|
switch (*cap)
|
||||||
|
{
|
||||||
|
case 'f':
|
||||||
|
m_Caps |= Caps::eFloodfill;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
case 'N':
|
||||||
|
case 'O':
|
||||||
|
m_Caps |= Caps::eHighBandwidth;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
m_Caps |= Caps::eReachable;
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
cap++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RouterInfo::UpdateIdentHashBase64 ()
|
void RouterInfo::UpdateIdentHashBase64 ()
|
||||||
{
|
{
|
||||||
size_t l = i2p::data::ByteStreamToBase64 (m_IdentHash, 32, m_IdentHashBase64, 48);
|
size_t l = i2p::data::ByteStreamToBase64 (m_IdentHash, 32, m_IdentHashBase64, 48);
|
||||||
@ -337,10 +366,7 @@ namespace data
|
|||||||
|
|
||||||
bool RouterInfo::IsFloodfill () const
|
bool RouterInfo::IsFloodfill () const
|
||||||
{
|
{
|
||||||
const char * caps = GetProperty ("caps");
|
return m_Caps & Caps::eFloodfill;
|
||||||
if (caps)
|
|
||||||
return strchr (caps, 'f');
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::IsNTCP (bool v4only) const
|
bool RouterInfo::IsNTCP (bool v4only) const
|
||||||
@ -361,9 +387,7 @@ namespace data
|
|||||||
|
|
||||||
bool RouterInfo::UsesIntroducer () const
|
bool RouterInfo::UsesIntroducer () const
|
||||||
{
|
{
|
||||||
if (!IsSSU ()) return false;
|
return !(m_Caps & Caps::eReachable); // non-reachable
|
||||||
auto address = GetSSUAddress (true); // no introducers for v6
|
|
||||||
return address && !address->introducers.empty ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) const
|
const RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) const
|
||||||
|
17
RouterInfo.h
17
RouterInfo.h
@ -20,9 +20,16 @@ namespace data
|
|||||||
enum SupportedTranports
|
enum SupportedTranports
|
||||||
{
|
{
|
||||||
eNTCPV4 = 0x01,
|
eNTCPV4 = 0x01,
|
||||||
eNTCPV6 = 0x20,
|
eNTCPV6 = 0x02,
|
||||||
eSSUV4 = 0x40,
|
eSSUV4 = 0x04,
|
||||||
eSSUV6 = 0x80
|
eSSUV6 = 0x08
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Caps
|
||||||
|
{
|
||||||
|
eFloodfill = 0x01,
|
||||||
|
eHighBandwidth = 0x02,
|
||||||
|
eReachable = 0x04
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TransportStyle
|
enum TransportStyle
|
||||||
@ -77,6 +84,7 @@ namespace data
|
|||||||
bool IsSSU (bool v4only = true) const;
|
bool IsSSU (bool v4only = true) const;
|
||||||
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
|
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
|
||||||
bool UsesIntroducer () const;
|
bool UsesIntroducer () const;
|
||||||
|
uint8_t GetCaps () const { return m_Caps; };
|
||||||
|
|
||||||
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
|
||||||
bool IsUnreachable () const { return m_IsUnreachable; };
|
bool IsUnreachable () const { return m_IsUnreachable; };
|
||||||
@ -102,6 +110,7 @@ namespace data
|
|||||||
void WriteToStream (std::ostream& s);
|
void WriteToStream (std::ostream& s);
|
||||||
size_t ReadString (char * str, std::istream& s);
|
size_t ReadString (char * str, std::istream& s);
|
||||||
void WriteString (const std::string& str, std::ostream& s);
|
void WriteString (const std::string& str, std::ostream& s);
|
||||||
|
void ExtractCaps (const char * value);
|
||||||
void UpdateIdentHashBase64 ();
|
void UpdateIdentHashBase64 ();
|
||||||
const Address * GetAddress (TransportStyle s, bool v4only) const;
|
const Address * GetAddress (TransportStyle s, bool v4only) const;
|
||||||
|
|
||||||
@ -117,7 +126,7 @@ namespace data
|
|||||||
std::vector<Address> m_Addresses;
|
std::vector<Address> m_Addresses;
|
||||||
std::map<std::string, std::string> m_Properties;
|
std::map<std::string, std::string> m_Properties;
|
||||||
bool m_IsUpdated, m_IsUnreachable;
|
bool m_IsUpdated, m_IsUnreachable;
|
||||||
uint8_t m_SupportedTransports;
|
uint8_t m_SupportedTransports, m_Caps;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
SSU.cpp
21
SSU.cpp
@ -822,14 +822,19 @@ namespace ssu
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// connect to introducer
|
// connect through introducer
|
||||||
auto& introducer = address->introducers[0]; // TODO:
|
if (address->introducers.size () > 0)
|
||||||
boost::asio::ip::udp::endpoint introducerEndpoint (introducer.iHost, introducer.iPort);
|
{
|
||||||
session = new SSUSession (this, introducerEndpoint, router);
|
auto& introducer = address->introducers[0]; // TODO:
|
||||||
m_Sessions[introducerEndpoint] = session;
|
boost::asio::ip::udp::endpoint introducerEndpoint (introducer.iHost, introducer.iPort);
|
||||||
LogPrint ("New SSU session to [", router->GetIdentHashAbbreviation (),
|
session = new SSUSession (this, introducerEndpoint, router);
|
||||||
"] created through introducer ", introducerEndpoint.address ().to_string (), ":", introducerEndpoint.port ());
|
m_Sessions[introducerEndpoint] = session;
|
||||||
session->ConnectThroughIntroducer (introducer);
|
LogPrint ("New SSU session to [", router->GetIdentHashAbbreviation (),
|
||||||
|
"] through introducer ", introducerEndpoint.address ().to_string (), ":", introducerEndpoint.port ());
|
||||||
|
session->ConnectThroughIntroducer (introducer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint ("Router is unreachable, but not introducers presentd. Ignored");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <string>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cryptopp/gzip.h>
|
#include <cryptopp/gzip.h>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
@ -264,7 +264,7 @@ namespace stream
|
|||||||
|
|
||||||
bool Stream::SendPacket (uint8_t * packet, size_t size)
|
bool Stream::SendPacket (uint8_t * packet, size_t size)
|
||||||
{
|
{
|
||||||
I2NPMessage * leaseSet = nullptr;
|
const I2NPMessage * leaseSet = nullptr;
|
||||||
if (m_LeaseSetUpdated)
|
if (m_LeaseSetUpdated)
|
||||||
{
|
{
|
||||||
leaseSet = m_LocalDestination->GetLeaseSet ();
|
leaseSet = m_LocalDestination->GetLeaseSet ();
|
||||||
@ -301,15 +301,23 @@ namespace stream
|
|||||||
|
|
||||||
StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr)
|
StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr)
|
||||||
{
|
{
|
||||||
// TODO: read from file later
|
|
||||||
m_Keys = i2p::data::CreateRandomKeys ();
|
m_Keys = i2p::data::CreateRandomKeys ();
|
||||||
m_Identity = m_Keys;
|
m_IdentHash = i2p::data::CalculateIdentHash (m_Keys.pub);
|
||||||
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);
|
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StreamingDestination::StreamingDestination (const std::string& fullPath): m_LeaseSet (nullptr)
|
||||||
|
{
|
||||||
|
std::ifstream s(fullPath.c_str (), std::ifstream::binary);
|
||||||
|
if (s.is_open ())
|
||||||
|
s.read ((char *)&m_Keys, sizeof (m_Keys));
|
||||||
|
else
|
||||||
|
LogPrint ("Can't open file ", fullPath);
|
||||||
|
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this);
|
||||||
|
}
|
||||||
|
|
||||||
StreamingDestination::~StreamingDestination ()
|
StreamingDestination::~StreamingDestination ()
|
||||||
{
|
{
|
||||||
if (m_LeaseSet)
|
if (m_LeaseSet)
|
||||||
@ -359,10 +367,12 @@ namespace stream
|
|||||||
it.second->SetLeaseSetUpdated ();
|
it.second->SetLeaseSetUpdated ();
|
||||||
}
|
}
|
||||||
|
|
||||||
I2NPMessage * StreamingDestination::GetLeaseSet ()
|
const I2NPMessage * StreamingDestination::GetLeaseSet ()
|
||||||
{
|
{
|
||||||
if (!m_LeaseSet)
|
if (!m_LeaseSet)
|
||||||
m_LeaseSet = CreateLeaseSet ();
|
m_LeaseSet = CreateLeaseSet ();
|
||||||
|
else
|
||||||
|
RenewI2NPMessageHeader (m_LeaseSet);
|
||||||
return m_LeaseSet;
|
return m_LeaseSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,8 +386,8 @@ namespace stream
|
|||||||
|
|
||||||
uint8_t * buf = m->GetPayload () + sizeof (I2NPDatabaseStoreMsg);
|
uint8_t * buf = m->GetPayload () + sizeof (I2NPDatabaseStoreMsg);
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
memcpy (buf + size, &m_Identity, sizeof (m_Identity));
|
memcpy (buf + size, &m_Keys.pub, sizeof (m_Keys.pub));
|
||||||
size += sizeof (m_Identity); // destination
|
size += sizeof (m_Keys.pub); // destination
|
||||||
memcpy (buf + size, m_Pool->GetEncryptionPublicKey (), 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);
|
||||||
|
11
Streaming.h
11
Streaming.h
@ -2,6 +2,7 @@
|
|||||||
#define STREAMING_H__
|
#define STREAMING_H__
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <cryptopp/dsa.h>
|
#include <cryptopp/dsa.h>
|
||||||
@ -106,11 +107,12 @@ namespace stream
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
StreamingDestination ();
|
StreamingDestination ();
|
||||||
|
StreamingDestination (const std::string& fullPath);
|
||||||
~StreamingDestination ();
|
~StreamingDestination ();
|
||||||
|
|
||||||
const i2p::data::Keys& GetKeys () const { return m_Keys; };
|
const i2p::data::PrivateKeys& GetKeys () const { return m_Keys; };
|
||||||
const i2p::data::Identity& GetIdentity () const { return m_Identity; };
|
const i2p::data::Identity& GetIdentity () const { return m_Keys.pub; };
|
||||||
I2NPMessage * GetLeaseSet ();
|
const I2NPMessage * GetLeaseSet ();
|
||||||
i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; };
|
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;
|
||||||
|
|
||||||
@ -128,8 +130,7 @@ namespace stream
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<uint32_t, Stream *> m_Streams;
|
std::map<uint32_t, Stream *> m_Streams;
|
||||||
i2p::data::Keys m_Keys;
|
i2p::data::PrivateKeys m_Keys;
|
||||||
i2p::data::Identity m_Identity;
|
|
||||||
i2p::data::IdentHash m_IdentHash;
|
i2p::data::IdentHash m_IdentHash;
|
||||||
|
|
||||||
i2p::tunnel::TunnelPool * m_Pool;
|
i2p::tunnel::TunnelPool * m_Pool;
|
||||||
|
@ -107,7 +107,7 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<I2NPMessage *> TunnelGatewayBuffer::GetTunnelDataMsgs ()
|
const std::vector<I2NPMessage *> TunnelGatewayBuffer::GetTunnelDataMsgs ()
|
||||||
{
|
{
|
||||||
CompleteCurrentTunnelDataMessage ();
|
CompleteCurrentTunnelDataMessage ();
|
||||||
std::vector<I2NPMessage *> ret = m_TunnelDataMsgs; // TODO: implement it better
|
std::vector<I2NPMessage *> ret = m_TunnelDataMsgs; // TODO: implement it better
|
||||||
|
@ -16,7 +16,7 @@ namespace tunnel
|
|||||||
TunnelGatewayBuffer (uint32_t tunnelID): m_TunnelID (tunnelID),
|
TunnelGatewayBuffer (uint32_t tunnelID): m_TunnelID (tunnelID),
|
||||||
m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0) {};
|
m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0) {};
|
||||||
void PutI2NPMsg (const TunnelMessageBlock& block);
|
void PutI2NPMsg (const TunnelMessageBlock& block);
|
||||||
std::vector<I2NPMessage *> GetTunnelDataMsgs ();
|
const std::vector<I2NPMessage *> GetTunnelDataMsgs ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user