use shared pointer for RouterInfo's addreses list

pull/1825/head
orignal 1 year ago
parent 6a743f66e8
commit 410d2c2fa9

@ -299,44 +299,49 @@ namespace http {
if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) {
s << "<label for=\"slide-info\">" << tr("Hidden content. Press on text to see.") << "</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n"; s << "<label for=\"slide-info\">" << tr("Hidden content. Press on text to see.") << "</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
} }
if (includeHiddenContent) { if (includeHiddenContent)
{
s << "<b>" << tr("Router Ident") << ":</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n"; s << "<b>" << tr("Router Ident") << ":</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
if (!i2p::context.GetRouterInfo().GetProperty("family").empty()) if (!i2p::context.GetRouterInfo().GetProperty("family").empty())
s << "<b>" << tr("Router Family") << ":</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n"; s << "<b>" << tr("Router Family") << ":</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
s << "<b>" << tr("Router Caps") << ":</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n"; s << "<b>" << tr("Router Caps") << ":</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n";
s << "<b>" << tr("Version") << ":</b> " VERSION "<br>\r\n"; s << "<b>" << tr("Version") << ":</b> " VERSION "<br>\r\n";
s << "<b>"<< tr("Our external address") << ":</b>" << "<br>\r\n<table class=\"extaddr\"><tbody>\r\n"; s << "<b>"<< tr("Our external address") << ":</b>" << "<br>\r\n<table class=\"extaddr\"><tbody>\r\n";
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) auto addresses = i2p::context.GetRouterInfo().GetAddresses ();
{ if (addresses)
s << "<tr>\r\n<td>"; {
switch (address->transportStyle) for (const auto& address : *addresses)
{
case i2p::data::RouterInfo::eTransportNTCP2:
s << "NTCP2";
break;
case i2p::data::RouterInfo::eTransportSSU2:
s << "SSU2";
break;
default:
s << tr("Unknown");
}
if (address->IsV6 ())
{ {
if (address->IsV4 ()) s << "v4"; s << "<tr>\r\n<td>";
s << "v6"; switch (address->transportStyle)
} {
s << "</td>\r\n"; case i2p::data::RouterInfo::eTransportNTCP2:
if (address->published) s << "NTCP2";
s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n"; break;
else case i2p::data::RouterInfo::eTransportSSU2:
{ s << "SSU2";
s << "<td>" << tr("supported"); break;
if (address->port) default:
s << " :" << address->port; s << tr("Unknown");
}
if (address->IsV6 ())
{
if (address->IsV4 ()) s << "v4";
s << "v6";
}
s << "</td>\r\n"; s << "</td>\r\n";
if (address->published)
s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n";
else
{
s << "<td>" << tr("supported");
if (address->port)
s << " :" << address->port;
s << "</td>\r\n";
}
s << "</tr>\r\n";
} }
s << "</tr>\r\n"; }
}
s << "</tbody></table>\r\n"; s << "</tbody></table>\r\n";
} }
s << "</div>\r\n</div>\r\n"; s << "</div>\r\n</div>\r\n";

@ -1210,8 +1210,9 @@ namespace transport
else else
LogPrint(eLogInfo, "NTCP2: Proxy is not used"); LogPrint(eLogInfo, "NTCP2: Proxy is not used");
// start acceptors // start acceptors
auto& addresses = context.GetRouterInfo ().GetAddresses (); auto addresses = context.GetRouterInfo ().GetAddresses ();
for (const auto& address: addresses) if (!addresses) return;
for (const auto& address: *addresses)
{ {
if (!address) continue; if (!address) continue;
if (address->IsPublishedNTCP2 () && address->port) if (address->IsPublishedNTCP2 () && address->port)

@ -267,8 +267,10 @@ namespace i2p
void RouterContext::UpdatePort (int port) void RouterContext::UpdatePort (int port)
{ {
auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
bool updated = false; bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ()) for (auto& address : *addresses)
{ {
if (address->port != port && address->transportStyle == i2p::data::RouterInfo::eTransportSSU2) if (address->port != port && address->transportStyle == i2p::data::RouterInfo::eTransportSSU2)
{ {
@ -283,8 +285,10 @@ namespace i2p
void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg) void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg)
{ {
if (!m_NTCP2Keys) return; if (!m_NTCP2Keys) return;
auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
bool updated = false; bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ()) for (auto& address : *addresses)
{ {
if (address->IsNTCP2 () && (address->port != port || address->published != publish)) if (address->IsNTCP2 () && (address->port != port || address->published != publish))
{ {
@ -312,9 +316,10 @@ namespace i2p
void RouterContext::UpdateNTCP2Address (bool enable) void RouterContext::UpdateNTCP2Address (bool enable)
{ {
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
bool found = false, updated = false; bool found = false, updated = false;
for (auto it = addresses.begin (); it != addresses.end ();) for (auto it = addresses->begin (); it != addresses->end ();)
{ {
if ((*it)->IsNTCP2 ()) if ((*it)->IsNTCP2 ())
{ {
@ -326,7 +331,7 @@ namespace i2p
it++; it++;
} }
else else
it = addresses.erase (it); it = addresses->erase (it);
updated = true; updated = true;
} }
else else
@ -344,10 +349,12 @@ namespace i2p
void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6) void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6)
{ {
if (!m_SSU2Keys) return; if (!m_SSU2Keys) return;
auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
int newPort = 0; int newPort = 0;
if (!port) if (!port)
{ {
for (const auto& address : m_RouterInfo.GetAddresses ()) for (const auto& address : *addresses)
if (address->port) if (address->port)
{ {
newPort = address->port; newPort = address->port;
@ -356,7 +363,7 @@ namespace i2p
if (!newPort) newPort = SelectRandomPort (); if (!newPort) newPort = SelectRandomPort ();
} }
bool updated = false; bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ()) for (auto& address : *addresses)
{ {
if (address->IsSSU2 () && (!address->port || address->port != port || address->published != publish) && if (address->IsSSU2 () && (!address->port || address->port != port || address->published != publish) &&
((v4 && address->IsV4 ()) || (v6 && address->IsV6 ()))) ((v4 && address->IsV4 ()) || (v6 && address->IsV6 ())))
@ -377,9 +384,10 @@ namespace i2p
void RouterContext::UpdateSSU2Address (bool enable) void RouterContext::UpdateSSU2Address (bool enable)
{ {
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
bool found = false, updated = false; bool found = false, updated = false;
for (auto it = addresses.begin (); it != addresses.end ();) for (auto it = addresses->begin (); it != addresses->end ();)
{ {
if ((*it)->IsSSU2 ()) if ((*it)->IsSSU2 ())
{ {
@ -391,7 +399,7 @@ namespace i2p
it++; it++;
} }
else else
it = addresses.erase (it); it = addresses->erase (it);
updated = true; updated = true;
} }
else else
@ -422,8 +430,10 @@ namespace i2p
void RouterContext::UpdateAddress (const boost::asio::ip::address& host) void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
{ {
auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
bool updated = false; bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ()) for (auto& address : *addresses)
{ {
if (address->host != host && address->IsCompatible (host) && if (address->host != host && address->IsCompatible (host) &&
!i2p::util::net::IsYggdrasilAddress (address->host)) !i2p::util::net::IsYggdrasilAddress (address->host))
@ -472,9 +482,10 @@ namespace i2p
void RouterContext::ClearSSU2Introducers (bool v4) void RouterContext::ClearSSU2Introducers (bool v4)
{ {
auto addresses = m_RouterInfo.GetAddresses ();
if (!addresses) return;
bool updated = false; bool updated = false;
auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr : *addresses)
for (auto& addr : addresses)
if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())) && if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())) &&
addr->ssu && !addr->ssu->introducers.empty ()) addr->ssu && !addr->ssu->introducers.empty ())
{ {
@ -597,15 +608,18 @@ namespace i2p
} }
uint16_t port = 0; uint16_t port = 0;
// delete previous introducers // delete previous introducers
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr : addresses) if (addresses)
if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) {
{ for (auto& addr : *addresses)
addr->published = false; if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer {
addr->ssu->introducers.clear (); addr->published = false;
port = addr->port; addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer
} addr->ssu->introducers.clear ();
port = addr->port;
}
}
// unpublish NTCP2 addreeses // unpublish NTCP2 addreeses
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2) if (ntcp2)
@ -630,15 +644,18 @@ namespace i2p
uint16_t port = 0; uint16_t port = 0;
// delete previous introducers // delete previous introducers
bool isSSU2Published; i2p::config::GetOption ("ssu2.published", isSSU2Published); bool isSSU2Published; i2p::config::GetOption ("ssu2.published", isSSU2Published);
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr : addresses) if (addresses)
if (addr->ssu && isSSU2Published && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) {
{ for (auto& addr : *addresses)
addr->published = true; if (addr->ssu && isSSU2Published && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
addr->caps |= i2p::data::RouterInfo::eSSUIntroducer; {
addr->ssu->introducers.clear (); addr->published = true;
if (addr->port) port = addr->port; addr->caps |= i2p::data::RouterInfo::eSSUIntroducer;
} addr->ssu->introducers.clear ();
if (addr->port) port = addr->port;
}
}
// publish NTCP2 // publish NTCP2
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2) if (ntcp2)
@ -663,23 +680,26 @@ namespace i2p
// insert v6 addresses if necessary // insert v6 addresses if necessary
bool foundNTCP2 = false, foundSSU2 = false; bool foundNTCP2 = false, foundSSU2 = false;
uint16_t port = 0; uint16_t port = 0;
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses) if (addresses)
{ {
if (addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host)) for (auto& addr: *addresses)
{ {
switch (addr->transportStyle) if (addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host))
{ {
case i2p::data::RouterInfo::eTransportNTCP2: switch (addr->transportStyle)
foundNTCP2 = true; {
break; case i2p::data::RouterInfo::eTransportNTCP2:
case i2p::data::RouterInfo::eTransportSSU2: foundNTCP2 = true;
foundSSU2 = true; break;
break; case i2p::data::RouterInfo::eTransportSSU2:
default: ; foundSSU2 = true;
break;
default: ;
}
} }
port = addr->port;
} }
port = addr->port;
} }
if (!port) if (!port)
{ {
@ -743,24 +763,27 @@ namespace i2p
bool foundNTCP2 = false, foundSSU2 = false; bool foundNTCP2 = false, foundSSU2 = false;
std::string host = "127.0.0.1"; std::string host = "127.0.0.1";
uint16_t port = 0; uint16_t port = 0;
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses) if (addresses)
{ {
if (addr->IsV4 ()) for (auto& addr: *addresses)
{ {
switch (addr->transportStyle) if (addr->IsV4 ())
{ {
case i2p::data::RouterInfo::eTransportNTCP2: switch (addr->transportStyle)
foundNTCP2 = true; {
break; case i2p::data::RouterInfo::eTransportNTCP2:
case i2p::data::RouterInfo::eTransportSSU2: foundNTCP2 = true;
foundSSU2 = true; break;
break; case i2p::data::RouterInfo::eTransportSSU2:
default: ; foundSSU2 = true;
break;
default: ;
}
} }
if (addr->port) port = addr->port;
} }
if (addr->port) port = addr->port; }
}
if (!port) if (!port)
{ {
i2p::config::GetOption("port", port); i2p::config::GetOption("port", port);
@ -816,16 +839,19 @@ namespace i2p
i2p::config::GetOption ("ntcp2.port", port); i2p::config::GetOption ("ntcp2.port", port);
if (!port) i2p::config::GetOption("port", port); if (!port) i2p::config::GetOption("port", port);
bool foundMesh = false; bool foundMesh = false;
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses) if (addresses)
{ {
if (!port) port = addr->port; for (auto& addr: *addresses)
if (i2p::util::net::IsYggdrasilAddress (addr->host))
{ {
foundMesh = true; if (!port) port = addr->port;
break; if (i2p::util::net::IsYggdrasilAddress (addr->host))
{
foundMesh = true;
break;
}
} }
} }
if (!foundMesh) if (!foundMesh)
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port);
} }
@ -837,8 +863,9 @@ namespace i2p
void RouterContext::SetMTU (int mtu, bool v4) void RouterContext::SetMTU (int mtu, bool v4)
{ {
if (mtu < 1280 || mtu > 1500) return; if (mtu < 1280 || mtu > 1500) return;
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses) if (!addresses) return;
for (auto& addr: *addresses)
{ {
if (addr->ssu && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) if (addr->ssu && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())))
{ {
@ -852,8 +879,9 @@ namespace i2p
{ {
bool isYgg = i2p::util::net::IsYggdrasilAddress (host); bool isYgg = i2p::util::net::IsYggdrasilAddress (host);
bool updated = false; bool updated = false;
auto& addresses = m_RouterInfo.GetAddresses (); auto addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses) if (!addresses) return;
for (auto& addr: *addresses)
{ {
if (addr->IsPublishedNTCP2 ()) if (addr->IsPublishedNTCP2 ())
{ {

@ -826,6 +826,15 @@ namespace data
return nullptr; return nullptr;
} }
boost::shared_ptr<RouterInfo::Addresses> RouterInfo::GetAddresses () const
{
#if (BOOST_VERSION >= 105300)
return boost::atomic_load (&m_Addresses);
#else
return m_Addresses;
#endif
}
template<typename Filter> template<typename Filter>
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const
{ {
@ -1048,14 +1057,15 @@ namespace data
void LocalRouterInfo::WriteToStream (std::ostream& s) const void LocalRouterInfo::WriteToStream (std::ostream& s) const
{ {
auto addresses = GetAddresses ();
if (!addresses) return;
uint64_t ts = htobe64 (GetTimestamp ()); uint64_t ts = htobe64 (GetTimestamp ());
s.write ((const char *)&ts, sizeof (ts)); s.write ((const char *)&ts, sizeof (ts));
// addresses // addresses
const Addresses& addresses = GetAddresses (); uint8_t numAddresses = addresses->size ();
uint8_t numAddresses = addresses.size ();
s.write ((char *)&numAddresses, sizeof (numAddresses)); s.write ((char *)&numAddresses, sizeof (numAddresses));
for (const auto& addr_ptr : addresses) for (const auto& addr_ptr : *addresses)
{ {
const Address& address = *addr_ptr; const Address& address = *addr_ptr;
// calculate cost // calculate cost
@ -1257,7 +1267,9 @@ namespace data
bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4) bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4)
{ {
for (auto& addr : GetAddresses ()) auto addresses = GetAddresses ();
if (!addresses) return false;
for (auto& addr : *addresses)
{ {
if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())))
{ {
@ -1273,7 +1285,9 @@ namespace data
bool LocalRouterInfo::RemoveSSU2Introducer (const IdentHash& h, bool v4) bool LocalRouterInfo::RemoveSSU2Introducer (const IdentHash& h, bool v4)
{ {
for (auto& addr: GetAddresses ()) auto addresses = GetAddresses ();
if (!addresses) return false;
for (auto& addr: *addresses)
{ {
if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())))
{ {

@ -176,7 +176,7 @@ namespace data
int GetVersion () const { return m_Version; }; int GetVersion () const { return m_Version; };
virtual void SetProperty (const std::string& key, const std::string& value) {}; virtual void SetProperty (const std::string& key, const std::string& value) {};
virtual void ClearProperties () {}; virtual void ClearProperties () {};
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr boost::shared_ptr<Addresses> GetAddresses () const; // should be called for local RI only, otherwise must return shared_ptr
std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const; std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
std::shared_ptr<const Address> GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const; 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> GetPublishedNTCP2V4Address () const;
@ -258,7 +258,6 @@ namespace data
void UpdateBuffer (const uint8_t * buf, size_t len); void UpdateBuffer (const uint8_t * buf, size_t len);
void SetBufferLen (size_t len) { m_BufferLen = len; }; void SetBufferLen (size_t len) { m_BufferLen = len; };
void RefreshTimestamp (); void RefreshTimestamp ();
const Addresses& GetAddresses () const { return *m_Addresses; };
CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; }; CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; };
void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; }; void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; };

@ -36,8 +36,9 @@ namespace transport
i2p::config::GetOption ("ssu2.published", m_IsPublished); i2p::config::GetOption ("ssu2.published", m_IsPublished);
i2p::config::GetOption("nettime.frompeers", m_IsSyncClockFromPeers); i2p::config::GetOption("nettime.frompeers", m_IsSyncClockFromPeers);
bool found = false; bool found = false;
auto& addresses = i2p::context.GetRouterInfo ().GetAddresses (); auto addresses = i2p::context.GetRouterInfo ().GetAddresses ();
for (const auto& address: addresses) if (!addresses) return;
for (const auto& address: *addresses)
{ {
if (!address) continue; if (!address) continue;
if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2) if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2)

Loading…
Cancel
Save