Browse Source

caps per address

pull/1638/head
orignal 4 years ago
parent
commit
1d7639b3f4
  1. 2
      libi2pd/NetDb.cpp
  2. 59
      libi2pd/RouterInfo.cpp
  3. 11
      libi2pd/RouterInfo.h
  4. 8
      libi2pd/SSU.cpp
  5. 2
      libi2pd/SSU.h
  6. 2
      libi2pd/Transports.cpp

2
libi2pd/NetDb.cpp

@ -1150,7 +1150,7 @@ namespace data
return GetRandomRouter ( return GetRandomRouter (
[v4only](std::shared_ptr<const RouterInfo> router)->bool [v4only](std::shared_ptr<const RouterInfo> router)->bool
{ {
return !router->IsHidden () && router->IsPeerTesting () && router->IsSSU (v4only); return !router->IsHidden () && router->IsPeerTesting (v4only);
}); });
} }

59
libi2pd/RouterInfo.cpp

@ -215,6 +215,7 @@ namespace data
} }
else else
address->transportStyle = eTransportUnknown; address->transportStyle = eTransportUnknown;
address->caps = 0;
address->port = 0; address->port = 0;
uint16_t size, r = 0; uint16_t size, r = 0;
s.read ((char *)&size, sizeof (size)); if (!s) return; s.read ((char *)&size, sizeof (size)); if (!s) return;
@ -250,7 +251,7 @@ namespace data
LogPrint (eLogWarning, "RouterInfo: Unexpected field 'key' for NTCP"); LogPrint (eLogWarning, "RouterInfo: Unexpected field 'key' for NTCP");
} }
else if (!strcmp (key, "caps")) else if (!strcmp (key, "caps"))
ExtractCaps (value); address->caps = ExtractCaps (value);
else if (!strcmp (key, "s")) // ntcp2 static key else if (!strcmp (key, "s")) // ntcp2 static key
{ {
Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32); Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32);
@ -353,7 +354,7 @@ namespace data
// extract caps // extract caps
if (!strcmp (key, "caps")) if (!strcmp (key, "caps"))
ExtractCaps (value); m_Caps = ExtractCaps (value);
// extract version // extract version
else if (!strcmp (key, ROUTER_INFO_PROPERTY_VERSION)) else if (!strcmp (key, ROUTER_INFO_PROPERTY_VERSION))
{ {
@ -402,44 +403,46 @@ namespace data
return m_Family == fam; return m_Family == fam;
} }
void RouterInfo::ExtractCaps (const char * value) uint8_t RouterInfo::ExtractCaps (const char * value)
{ {
uint8_t caps = 0;
const char * cap = value; const char * cap = value;
while (*cap) while (*cap)
{ {
switch (*cap) switch (*cap)
{ {
case CAPS_FLAG_FLOODFILL: case CAPS_FLAG_FLOODFILL:
m_Caps |= Caps::eFloodfill; caps |= Caps::eFloodfill;
break; break;
case CAPS_FLAG_HIGH_BANDWIDTH1: case CAPS_FLAG_HIGH_BANDWIDTH1:
case CAPS_FLAG_HIGH_BANDWIDTH2: case CAPS_FLAG_HIGH_BANDWIDTH2:
case CAPS_FLAG_HIGH_BANDWIDTH3: case CAPS_FLAG_HIGH_BANDWIDTH3:
m_Caps |= Caps::eHighBandwidth; caps |= Caps::eHighBandwidth;
break; break;
case CAPS_FLAG_EXTRA_BANDWIDTH1: case CAPS_FLAG_EXTRA_BANDWIDTH1:
case CAPS_FLAG_EXTRA_BANDWIDTH2: case CAPS_FLAG_EXTRA_BANDWIDTH2:
m_Caps |= Caps::eExtraBandwidth | Caps::eHighBandwidth; caps |= Caps::eExtraBandwidth | Caps::eHighBandwidth;
break; break;
case CAPS_FLAG_HIDDEN: case CAPS_FLAG_HIDDEN:
m_Caps |= Caps::eHidden; caps |= Caps::eHidden;
break; break;
case CAPS_FLAG_REACHABLE: case CAPS_FLAG_REACHABLE:
m_Caps |= Caps::eReachable; caps |= Caps::eReachable;
break; break;
case CAPS_FLAG_UNREACHABLE: case CAPS_FLAG_UNREACHABLE:
m_Caps |= Caps::eUnreachable; caps |= Caps::eUnreachable;
break; break;
case CAPS_FLAG_SSU_TESTING: case CAPS_FLAG_SSU_TESTING:
m_Caps |= Caps::eSSUTesting; caps |= Caps::eSSUTesting;
break; break;
case CAPS_FLAG_SSU_INTRODUCER: case CAPS_FLAG_SSU_INTRODUCER:
m_Caps |= Caps::eSSUIntroducer; caps |= Caps::eSSUIntroducer;
break; break;
default: ; default: ;
} }
cap++; cap++;
} }
return caps;
} }
void RouterInfo::UpdateCapsProperty () void RouterInfo::UpdateCapsProperty ()
@ -496,8 +499,8 @@ namespace data
WriteString ("caps", properties); WriteString ("caps", properties);
properties << '='; properties << '=';
std::string caps; std::string caps;
if (IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING; if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING;
if (IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER; if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
WriteString (caps, properties); WriteString (caps, properties);
properties << ';'; properties << ';';
} }
@ -721,7 +724,8 @@ namespace data
addr->host = boost::asio::ip::address::from_string (host); addr->host = boost::asio::ip::address::from_string (host);
addr->port = port; addr->port = port;
addr->transportStyle = eTransportSSU; addr->transportStyle = eTransportSSU;
addr->cost = 10; // NTCP should have priority over SSU addr->cost = 10; // NTCP2 should have priority over SSU
addr->caps = i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // BC;
addr->date = 0; addr->date = 0;
addr->ssu.reset (new SSUExt ()); addr->ssu.reset (new SSUExt ());
addr->ssu->mtu = mtu; addr->ssu->mtu = mtu;
@ -745,6 +749,7 @@ namespace data
addr->port = port; addr->port = port;
addr->transportStyle = eTransportNTCP; addr->transportStyle = eTransportNTCP;
addr->cost = port ? 3 : 14; // override from RouterContext::PublishNTCP2Address addr->cost = port ? 3 : 14; // override from RouterContext::PublishNTCP2Address
addr->caps = 0;
addr->date = 0; addr->date = 0;
addr->ntcp2.reset (new NTCP2Ext ()); addr->ntcp2.reset (new NTCP2Ext ());
if (port) addr->ntcp2->isPublished = true; if (port) addr->ntcp2->isPublished = true;
@ -794,8 +799,7 @@ namespace data
void RouterInfo::SetCaps (const char * caps) void RouterInfo::SetCaps (const char * caps)
{ {
SetProperty ("caps", caps); SetProperty ("caps", caps);
m_Caps = 0; m_Caps = ExtractCaps (caps);
ExtractCaps (caps);
} }
void RouterInfo::SetProperty (const std::string& key, const std::string& value) void RouterInfo::SetProperty (const std::string& key, const std::string& value)
@ -1020,5 +1024,28 @@ namespace data
return IsReachable () && m_Version >= NETDB_MIN_FLOODFILL_VERSION && return IsReachable () && m_Version >= NETDB_MIN_FLOODFILL_VERSION &&
GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1;
} }
bool RouterInfo::IsPeerTesting (bool v4only) const
{
auto supportedTransports = m_SupportedTransports & (eSSUV4 | eSSUV6);
if (!supportedTransports) return false; // no SSU
if (v4only && !(supportedTransports & eSSUV4)) return false; // no SSU v4
return GetAddress (
[](std::shared_ptr<const RouterInfo::Address> address)->bool
{
return (address->transportStyle == eTransportSSU) && address->IsPeerTesting ();
}) != nullptr;
}
bool RouterInfo::IsIntroducer () const
{
// TODO: support ipv6
if (!(m_SupportedTransports & eSSUV4)) return false;
return GetAddress (
[](std::shared_ptr<const RouterInfo::Address> address)->bool
{
return (address->transportStyle == eTransportSSU) && address->IsIntroducer ();
}) != nullptr;
}
} }
} }

11
libi2pd/RouterInfo.h

@ -111,7 +111,7 @@ namespace data
boost::asio::ip::address host; boost::asio::ip::address host;
int port; int port;
uint64_t date; uint64_t date;
uint8_t cost; uint8_t cost, caps;
std::unique_ptr<SSUExt> ssu; // not null for SSU std::unique_ptr<SSUExt> ssu; // not null for SSU
std::unique_ptr<NTCP2Ext> ntcp2; // not null for NTCP2 std::unique_ptr<NTCP2Ext> ntcp2; // not null for NTCP2
@ -134,6 +134,9 @@ namespace data
bool IsNTCP2 () const { return (bool)ntcp2; }; bool IsNTCP2 () const { return (bool)ntcp2; };
bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; };
bool IsIntroducer () const { return caps & eSSUIntroducer; };
bool IsPeerTesting () const { return caps & eSSUTesting; };
}; };
typedef std::list<std::shared_ptr<Address> > Addresses; typedef std::list<std::shared_ptr<Address> > Addresses;
@ -183,12 +186,12 @@ namespace data
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 HasValidAddresses () const { return m_SupportedTransports; }; bool HasValidAddresses () const { return m_SupportedTransports; };
bool UsesIntroducer () const; bool UsesIntroducer () const;
bool IsIntroducer () const { return m_Caps & eSSUIntroducer; };
bool IsPeerTesting () const { return m_Caps & eSSUTesting; };
bool IsHidden () const { return m_Caps & eHidden; }; bool IsHidden () const { return m_Caps & eHidden; };
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; };
bool IsEligibleFloodfill () const; bool IsEligibleFloodfill () const;
bool IsPeerTesting (bool v4only) const;
bool IsIntroducer () const;
uint8_t GetCaps () const { return m_Caps; }; uint8_t GetCaps () const { return m_Caps; };
void SetCaps (uint8_t caps); void SetCaps (uint8_t caps);
@ -231,7 +234,7 @@ namespace data
void WriteToStream (std::ostream& s) const; void WriteToStream (std::ostream& s) const;
size_t ReadString (char* str, size_t len, std::istream& s) const; size_t ReadString (char* str, size_t len, std::istream& s) const;
void WriteString (const std::string& str, std::ostream& s) const; void WriteString (const std::string& str, std::ostream& s) const;
void ExtractCaps (const char * value); uint8_t ExtractCaps (const char * value);
template<typename Filter> template<typename Filter>
std::shared_ptr<const Address> GetAddress (Filter filter) const; std::shared_ptr<const Address> GetAddress (Filter filter) const;
void UpdateCapsProperty (); void UpdateCapsProperty ();

8
libi2pd/SSU.cpp

@ -442,21 +442,21 @@ namespace transport
{ {
auto address = router->GetSSUAddress (v4only || !context.SupportsV6 ()); auto address = router->GetSSUAddress (v4only || !context.SupportsV6 ());
if (address) if (address)
CreateSession (router, address->host, address->port, peerTest); CreateSession (router, address, peerTest);
else else
LogPrint (eLogWarning, "SSU: Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address"); LogPrint (eLogWarning, "SSU: Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address");
} }
void SSUServer::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, void SSUServer::CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
const boost::asio::ip::address& addr, int port, bool peerTest) std::shared_ptr<const i2p::data::RouterInfo::Address> address, bool peerTest)
{ {
if (router) if (router && address)
{ {
if (router->UsesIntroducer ()) if (router->UsesIntroducer ())
m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, peerTest)); // always V4 thread m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, peerTest)); // always V4 thread
else else
{ {
boost::asio::ip::udp::endpoint remoteEndpoint (addr, port); boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port);
m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest)); m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest));
} }
} }

2
libi2pd/SSU.h

@ -54,7 +54,7 @@ namespace transport
void Stop (); void Stop ();
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false, bool v4only = false); void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false, bool v4only = false);
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
const boost::asio::ip::address& addr, int port, bool peerTest = false); std::shared_ptr<const i2p::data::RouterInfo::Address> address, bool peerTest = false);
void CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest); void CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest);
std::shared_ptr<SSUSession> FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const; std::shared_ptr<SSUSession> FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const;
std::shared_ptr<SSUSession> FindSession (const boost::asio::ip::udp::endpoint& e) const; std::shared_ptr<SSUSession> FindSession (const boost::asio::ip::udp::endpoint& e) const;

2
libi2pd/Transports.cpp

@ -455,7 +455,7 @@ namespace transport
} }
if (address) if (address)
{ {
m_SSUServer->CreateSession (peer.router, address->host, address->port); m_SSUServer->CreateSession (peer.router, address);
return true; return true;
} }
} }

Loading…
Cancel
Save