mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
SSU2 only introducers
This commit is contained in:
parent
ccfeca728e
commit
a298588943
@ -1229,15 +1229,6 @@ namespace data
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomSSUV6Router () const
|
||||
{
|
||||
return GetRandomRouter (
|
||||
[](std::shared_ptr<const RouterInfo> router)->bool
|
||||
{
|
||||
return !router->IsHidden () && router->IsECIES () && router->IsSSUV6 ();
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomIntroducer (bool v4, const std::set<IdentHash>& excluded) const
|
||||
{
|
||||
return GetRandomRouter (
|
||||
|
@ -91,7 +91,6 @@ namespace data
|
||||
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomSSU2PeerTestRouter (bool v4, const std::set<IdentHash>& excluded) const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later
|
||||
std::shared_ptr<const RouterInfo> GetRandomIntroducer (bool v4, const std::set<IdentHash>& excluded) const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomSSU2Introducer (bool v4, const std::set<IdentHash>& excluded) const;
|
||||
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
||||
|
@ -330,21 +330,9 @@ namespace data
|
||||
}
|
||||
Introducer& introducer = address->ssu->introducers.at (index);
|
||||
if (!strcmp (key, "ihost"))
|
||||
{
|
||||
boost::system::error_code ecode;
|
||||
introducer.iHost = boost::asio::ip::address::from_string (value, ecode);
|
||||
}
|
||||
introducer.isH = false; // SSU1
|
||||
else if (!strcmp (key, "iport"))
|
||||
{
|
||||
try
|
||||
{
|
||||
introducer.iPort = boost::lexical_cast<int>(value);
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogWarning, "RouterInfo: 'iport' exception ", ex.what ());
|
||||
}
|
||||
}
|
||||
introducer.isH = false; // SSU1
|
||||
else if (!strcmp (key, "itag"))
|
||||
{
|
||||
try
|
||||
@ -356,8 +344,11 @@ namespace data
|
||||
LogPrint (eLogWarning, "RouterInfo: 'itag' exception ", ex.what ());
|
||||
}
|
||||
}
|
||||
else if (!strcmp (key, "ikey") || !strcmp (key, "ih"))
|
||||
Base64ToByteStream (value, strlen (value), introducer.iKey, 32);
|
||||
else if (!strcmp (key, "ih"))
|
||||
{
|
||||
Base64ToByteStream (value, strlen (value), introducer.iH, 32);
|
||||
introducer.isH = true;
|
||||
}
|
||||
else if (!strcmp (key, "iexp"))
|
||||
{
|
||||
try
|
||||
@ -413,7 +404,7 @@ namespace data
|
||||
int numValid = 0;
|
||||
for (auto& it: address->ssu->introducers)
|
||||
{
|
||||
if (it.iTag && ts < it.iExp && !it.iPort && it.iHost.is_unspecified ()) // SSU2 only
|
||||
if (it.iTag && ts < it.iExp && it.isH)
|
||||
numValid++;
|
||||
else
|
||||
it.iTag = 0;
|
||||
@ -625,29 +616,6 @@ namespace data
|
||||
return l+1;
|
||||
}
|
||||
|
||||
|
||||
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
|
||||
{
|
||||
auto addr = std::make_shared<Address>();
|
||||
addr->host = boost::asio::ip::address::from_string (host);
|
||||
addr->port = port;
|
||||
addr->transportStyle = eTransportSSU;
|
||||
addr->published = true;
|
||||
addr->caps = i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // BC;
|
||||
addr->date = 0;
|
||||
addr->ssu.reset (new SSUExt ());
|
||||
addr->ssu->mtu = mtu;
|
||||
if (key)
|
||||
memcpy (addr->i, key, 32);
|
||||
else
|
||||
RAND_bytes (addr->i, 32);
|
||||
for (const auto& it: *m_Addresses) // don't insert same address twice
|
||||
if (*it == *addr) return;
|
||||
m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
||||
m_ReachableTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
||||
m_Addresses->push_back(std::move(addr));
|
||||
}
|
||||
|
||||
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||
const boost::asio::ip::address& host, int port, uint8_t caps)
|
||||
{
|
||||
@ -716,51 +684,6 @@ namespace data
|
||||
m_Addresses->push_back(std::move(addr));
|
||||
}
|
||||
|
||||
bool RouterInfo::AddIntroducer (const Introducer& introducer)
|
||||
{
|
||||
for (auto& addr : *m_Addresses)
|
||||
{
|
||||
if (addr->transportStyle == eTransportSSU &&
|
||||
((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ())))
|
||||
{
|
||||
for (auto& intro: addr->ssu->introducers)
|
||||
if (intro.iTag == introducer.iTag) return false; // already presented
|
||||
addr->ssu->introducers.push_back (introducer);
|
||||
m_ReachableTransports |= (addr->IsV4 () ? eSSUV4 : eSSUV6);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
|
||||
{
|
||||
for (auto& addr: *m_Addresses)
|
||||
{
|
||||
if (addr->transportStyle == eTransportSSU &&
|
||||
((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ())))
|
||||
{
|
||||
for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
|
||||
if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
|
||||
{
|
||||
addr->ssu->introducers.erase (it);
|
||||
if (addr->ssu->introducers.empty ())
|
||||
m_ReachableTransports &= ~(addr->IsV4 () ? eSSUV4 : eSSUV6);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RouterInfo::IsSSU (bool v4only) const
|
||||
{
|
||||
if (v4only)
|
||||
return m_SupportedTransports & eSSUV4;
|
||||
else
|
||||
return m_SupportedTransports & (eSSUV4 | eSSUV6);
|
||||
}
|
||||
|
||||
bool RouterInfo::IsNTCP2 (bool v4only) const
|
||||
{
|
||||
if (v4only)
|
||||
@ -867,15 +790,6 @@ namespace data
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const
|
||||
{
|
||||
return GetAddress (
|
||||
[v4only](std::shared_ptr<const RouterInfo::Address> address)->bool
|
||||
{
|
||||
return (address->transportStyle == eTransportSSU) && (!v4only || address->IsV4 ());
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUV6Address () const
|
||||
{
|
||||
return GetAddress (
|
||||
@ -1051,7 +965,6 @@ namespace data
|
||||
{
|
||||
for (auto& addr: *m_Addresses)
|
||||
{
|
||||
// TODO: implement SSU
|
||||
if (!addr->published && (addr->transportStyle == eTransportNTCP || addr->transportStyle == eTransportSSU2))
|
||||
{
|
||||
addr->caps &= ~(eV4 | eV6);
|
||||
@ -1076,12 +989,6 @@ namespace data
|
||||
if (addr->IsPublishedNTCP2 ())
|
||||
m_ReachableTransports |= transports;
|
||||
break;
|
||||
case eTransportSSU:
|
||||
if (addr->IsV4 ()) transports |= eSSUV4;
|
||||
if (addr->IsV6 ()) transports |= eSSUV6;
|
||||
if (addr->IsReachableSSU ())
|
||||
m_ReachableTransports |= transports;
|
||||
break;
|
||||
case eTransportSSU2:
|
||||
if (addr->IsV4 ()) transports |= eSSU2V4;
|
||||
if (addr->IsV6 ()) transports |= eSSU2V6;
|
||||
@ -1183,8 +1090,6 @@ namespace data
|
||||
uint8_t cost = 0x7f;
|
||||
if (address.transportStyle == eTransportNTCP)
|
||||
cost = address.published ? COST_NTCP2_PUBLISHED : COST_NTCP2_NON_PUBLISHED;
|
||||
else if (address.transportStyle == eTransportSSU)
|
||||
cost = address.published ? COST_SSU_DIRECT : COST_SSU_THROUGH_INTRODUCERS;
|
||||
else if (address.transportStyle == eTransportSSU2)
|
||||
cost = address.published ? COST_SSU2_DIRECT : COST_SSU2_NON_PUBLISHED;
|
||||
s.write ((const char *)&cost, sizeof (cost));
|
||||
@ -1213,43 +1118,6 @@ namespace data
|
||||
else
|
||||
continue; // don't write NTCP address
|
||||
}
|
||||
else if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
WriteString ("SSU", s);
|
||||
// caps
|
||||
WriteString ("caps", properties);
|
||||
properties << '=';
|
||||
std::string caps;
|
||||
if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING;
|
||||
if (address.host.is_v4 ())
|
||||
{
|
||||
if (address.published)
|
||||
{
|
||||
isPublished = true;
|
||||
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
||||
}
|
||||
else
|
||||
caps += CAPS_FLAG_V4;
|
||||
}
|
||||
else if (address.host.is_v6 ())
|
||||
{
|
||||
if (address.published)
|
||||
{
|
||||
isPublished = true;
|
||||
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
||||
}
|
||||
else
|
||||
caps += CAPS_FLAG_V6;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
||||
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
|
||||
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
||||
}
|
||||
WriteString (caps, properties);
|
||||
properties << ';';
|
||||
}
|
||||
else if (address.transportStyle == eTransportSSU2)
|
||||
{
|
||||
WriteString ("SSU2", s);
|
||||
@ -1292,7 +1160,7 @@ namespace data
|
||||
size_t len = address.IsSSU2 () ? 32 : 16;
|
||||
WriteString (address.i.ToBase64 (len), properties); properties << ';';
|
||||
}
|
||||
if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
|
||||
if (address.transportStyle == eTransportSSU2)
|
||||
{
|
||||
// write introducers if any
|
||||
if (address.ssu && !address.ssu->introducers.empty())
|
||||
@ -1309,45 +1177,18 @@ namespace data
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
i = 0;
|
||||
for (const auto& introducer: address.ssu->introducers)
|
||||
{
|
||||
WriteString ("ihost" + boost::lexical_cast<std::string>(i), properties);
|
||||
properties << '=';
|
||||
WriteString (introducer.iHost.to_string (), properties);
|
||||
properties << ';';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
for (const auto& introducer: address.ssu->introducers)
|
||||
{
|
||||
if (address.IsSSU2 ())
|
||||
WriteString ("ih" + boost::lexical_cast<std::string>(i), properties);
|
||||
else
|
||||
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
|
||||
WriteString ("ih" + boost::lexical_cast<std::string>(i), properties);
|
||||
properties << '=';
|
||||
char value[64];
|
||||
size_t l = ByteStreamToBase64 (introducer.iKey, 32, value, 64);
|
||||
size_t l = ByteStreamToBase64 (introducer.iH, 32, value, 64);
|
||||
value[l] = 0;
|
||||
WriteString (value, properties);
|
||||
properties << ';';
|
||||
i++;
|
||||
}
|
||||
if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
i = 0;
|
||||
for (const auto& introducer: address.ssu->introducers)
|
||||
{
|
||||
WriteString ("iport" + boost::lexical_cast<std::string>(i), properties);
|
||||
properties << '=';
|
||||
WriteString (boost::lexical_cast<std::string>(introducer.iPort), properties);
|
||||
properties << ';';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
for (const auto& introducer: address.ssu->introducers)
|
||||
{
|
||||
@ -1359,18 +1200,8 @@ namespace data
|
||||
}
|
||||
}
|
||||
}
|
||||
if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
// write intro key
|
||||
WriteString ("key", properties);
|
||||
properties << '=';
|
||||
char value[64];
|
||||
size_t l = ByteStreamToBase64 (address.i, 32, value, 64);
|
||||
value[l] = 0;
|
||||
WriteString (value, properties);
|
||||
properties << ';';
|
||||
}
|
||||
if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
|
||||
|
||||
if (address.transportStyle == eTransportSSU2)
|
||||
{
|
||||
// write mtu
|
||||
if (address.ssu && address.ssu->mtu)
|
||||
@ -1381,7 +1212,7 @@ namespace data
|
||||
properties << ';';
|
||||
}
|
||||
}
|
||||
if ((isPublished || (address.ssu && !address.IsSSU2 ())) && address.port)
|
||||
if (isPublished && address.port)
|
||||
{
|
||||
WriteString ("port", properties);
|
||||
properties << '=';
|
||||
@ -1473,7 +1304,7 @@ namespace data
|
||||
if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())))
|
||||
{
|
||||
for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
|
||||
if (h == it->iKey)
|
||||
if (h == it->iH)
|
||||
{
|
||||
addr->ssu->introducers.erase (it);
|
||||
if (addr->ssu->introducers.empty ())
|
||||
|
@ -101,15 +101,13 @@ namespace data
|
||||
eTransportSSU2
|
||||
};
|
||||
|
||||
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
|
||||
struct Introducer
|
||||
{
|
||||
Introducer (): iPort (0), iExp (0) {};
|
||||
boost::asio::ip::address iHost;
|
||||
int iPort;
|
||||
IntroKey iKey; // or ih for SSU2
|
||||
Introducer (): iTag (0), iExp (0), isH (false) {};
|
||||
uint32_t iTag;
|
||||
uint32_t iExp;
|
||||
IdentHash iH;
|
||||
bool isH; // TODO: remove later
|
||||
};
|
||||
|
||||
struct SSUExt
|
||||
@ -188,28 +186,22 @@ namespace data
|
||||
std::shared_ptr<const Address> GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const;
|
||||
std::shared_ptr<const Address> GetPublishedNTCP2V4Address () const;
|
||||
std::shared_ptr<const Address> GetPublishedNTCP2V6Address () const;
|
||||
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
|
||||
std::shared_ptr<const Address> GetSSUV6Address () const;
|
||||
std::shared_ptr<const Address> GetYggdrasilAddress () const;
|
||||
std::shared_ptr<const Address> GetSSU2V4Address () const;
|
||||
std::shared_ptr<const Address> GetSSU2V6Address () const;
|
||||
std::shared_ptr<const Address> GetSSU2Address (bool v4) const;
|
||||
|
||||
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
|
||||
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||
const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0);
|
||||
void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps = 0); // non published
|
||||
void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
|
||||
const boost::asio::ip::address& host, int port); // published
|
||||
bool AddIntroducer (const Introducer& introducer);
|
||||
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
||||
void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps
|
||||
void UpdateSupportedTransports ();
|
||||
bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
|
||||
bool IsReachable () const { return m_Caps & Caps::eReachable; };
|
||||
bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
|
||||
bool IsSSU (bool v4only = true) const;
|
||||
bool IsSSUV6 () const { return m_SupportedTransports & eSSUV6; };
|
||||
bool IsNTCP2 (bool v4only = true) const;
|
||||
bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; };
|
||||
bool IsSSU2V4 () const { return m_SupportedTransports & eSSU2V4; };
|
||||
|
@ -641,7 +641,7 @@ namespace transport
|
||||
// try to find existing session first
|
||||
for (auto& it: address->ssu->introducers)
|
||||
{
|
||||
auto it1 = m_SessionsByRouterHash.find (it.iKey);
|
||||
auto it1 = m_SessionsByRouterHash.find (it.iH);
|
||||
if (it1 != m_SessionsByRouterHash.end ())
|
||||
{
|
||||
it1->second->Introduce (session, it.iTag);
|
||||
@ -664,7 +664,7 @@ namespace transport
|
||||
const auto& introducer = address->ssu->introducers[indicies[i]];
|
||||
if (introducer.iTag && ts < introducer.iExp)
|
||||
{
|
||||
r = i2p::data::netdb.FindRouter (introducer.iKey);
|
||||
r = i2p::data::netdb.FindRouter (introducer.iH);
|
||||
if (r && r->IsReachableFrom (i2p::context.GetRouterInfo ()))
|
||||
{
|
||||
relayTag = introducer.iTag;
|
||||
@ -713,7 +713,7 @@ namespace transport
|
||||
// introducers not found, try to request them
|
||||
for (auto& it: address->ssu->introducers)
|
||||
if (it.iTag && ts < it.iExp)
|
||||
i2p::data::netdb.RequestDestination (it.iKey);
|
||||
i2p::data::netdb.RequestDestination (it.iH);
|
||||
}
|
||||
}
|
||||
|
||||
@ -961,7 +961,8 @@ namespace transport
|
||||
{
|
||||
i2p::data::RouterInfo::Introducer introducer;
|
||||
introducer.iTag = it->GetRelayTag ();
|
||||
introducer.iKey = it->GetRemoteIdentity ()->GetIdentHash ();
|
||||
introducer.iH = it->GetRemoteIdentity ()->GetIdentHash ();
|
||||
introducer.isH = true;
|
||||
introducer.iExp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION;
|
||||
excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ());
|
||||
if (i2p::context.AddSSU2Introducer (introducer, v4))
|
||||
|
Loading…
Reference in New Issue
Block a user