From 410d2c2fa95a921921ad0e8886c52d4144116df7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Dec 2022 19:21:51 -0500 Subject: [PATCH] use shared pointer for RouterInfo's addreses list --- daemon/HTTPServer.cpp | 63 ++++++++------- libi2pd/NTCP2.cpp | 5 +- libi2pd/RouterContext.cpp | 162 ++++++++++++++++++++++---------------- libi2pd/RouterInfo.cpp | 26 ++++-- libi2pd/RouterInfo.h | 3 +- libi2pd/SSU2.cpp | 5 +- 6 files changed, 156 insertions(+), 108 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 77254e61..374b1d29 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -299,44 +299,49 @@ namespace http { if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { s << "\r\n\r\n
\r\n"; } - if (includeHiddenContent) { + if (includeHiddenContent) + { s << "" << tr("Router Ident") << ": " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; if (!i2p::context.GetRouterInfo().GetProperty("family").empty()) s << "" << tr("Router Family") << ": " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; s << "" << tr("Router Caps") << ": " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; s << "" << tr("Version") << ": " VERSION "
\r\n"; s << ""<< tr("Our external address") << ":" << "
\r\n\r\n"; - for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) - { - s << "\r\n\r\n"; - if (address->published) - s << "\r\n"; - else - { - s << "\r\n\r\n"; + if (address->published) + s << "\r\n"; + else + { + s << "\r\n"; + } + s << "\r\n"; } - s << "\r\n"; - } + } s << "
"; - switch (address->transportStyle) - { - case i2p::data::RouterInfo::eTransportNTCP2: - s << "NTCP2"; - break; - case i2p::data::RouterInfo::eTransportSSU2: - s << "SSU2"; - break; - default: - s << tr("Unknown"); - } - if (address->IsV6 ()) + auto addresses = i2p::context.GetRouterInfo().GetAddresses (); + if (addresses) + { + for (const auto& address : *addresses) { - if (address->IsV4 ()) s << "v4"; - s << "v6"; - } - s << "" << address->host.to_string() << ":" << address->port << "" << tr("supported"); - if (address->port) - s << " :" << address->port; + s << "
"; + switch (address->transportStyle) + { + 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 << "v6"; + } s << "" << address->host.to_string() << ":" << address->port << "" << tr("supported"); + if (address->port) + s << " :" << address->port; + s << "
\r\n"; } s << "
\r\n\r\n"; diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 37553ceb..953fe333 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1210,8 +1210,9 @@ namespace transport else LogPrint(eLogInfo, "NTCP2: Proxy is not used"); // start acceptors - auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (const auto& address: addresses) + auto addresses = context.GetRouterInfo ().GetAddresses (); + if (!addresses) return; + for (const auto& address: *addresses) { if (!address) continue; if (address->IsPublishedNTCP2 () && address->port) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index c8000e2e..8928fc7f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -267,8 +267,10 @@ namespace i2p void RouterContext::UpdatePort (int port) { + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; bool updated = false; - for (auto& address : m_RouterInfo.GetAddresses ()) + for (auto& address : *addresses) { 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) { if (!m_NTCP2Keys) return; + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; bool updated = false; - for (auto& address : m_RouterInfo.GetAddresses ()) + for (auto& address : *addresses) { if (address->IsNTCP2 () && (address->port != port || address->published != publish)) { @@ -312,9 +316,10 @@ namespace i2p void RouterContext::UpdateNTCP2Address (bool enable) { - auto& addresses = m_RouterInfo.GetAddresses (); + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; bool found = false, updated = false; - for (auto it = addresses.begin (); it != addresses.end ();) + for (auto it = addresses->begin (); it != addresses->end ();) { if ((*it)->IsNTCP2 ()) { @@ -326,7 +331,7 @@ namespace i2p it++; } else - it = addresses.erase (it); + it = addresses->erase (it); updated = true; } else @@ -344,10 +349,12 @@ namespace i2p void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6) { if (!m_SSU2Keys) return; + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; int newPort = 0; if (!port) { - for (const auto& address : m_RouterInfo.GetAddresses ()) + for (const auto& address : *addresses) if (address->port) { newPort = address->port; @@ -356,7 +363,7 @@ namespace i2p if (!newPort) newPort = SelectRandomPort (); } bool updated = false; - for (auto& address : m_RouterInfo.GetAddresses ()) + for (auto& address : *addresses) { if (address->IsSSU2 () && (!address->port || address->port != port || address->published != publish) && ((v4 && address->IsV4 ()) || (v6 && address->IsV6 ()))) @@ -377,9 +384,10 @@ namespace i2p void RouterContext::UpdateSSU2Address (bool enable) { - auto& addresses = m_RouterInfo.GetAddresses (); + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; bool found = false, updated = false; - for (auto it = addresses.begin (); it != addresses.end ();) + for (auto it = addresses->begin (); it != addresses->end ();) { if ((*it)->IsSSU2 ()) { @@ -391,7 +399,7 @@ namespace i2p it++; } else - it = addresses.erase (it); + it = addresses->erase (it); updated = true; } else @@ -422,8 +430,10 @@ namespace i2p void RouterContext::UpdateAddress (const boost::asio::ip::address& host) { + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; bool updated = false; - for (auto& address : m_RouterInfo.GetAddresses ()) + for (auto& address : *addresses) { if (address->host != host && address->IsCompatible (host) && !i2p::util::net::IsYggdrasilAddress (address->host)) @@ -472,9 +482,10 @@ namespace i2p void RouterContext::ClearSSU2Introducers (bool v4) { + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; 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 ())) && addr->ssu && !addr->ssu->introducers.empty ()) { @@ -597,15 +608,18 @@ namespace i2p } uint16_t port = 0; // delete previous introducers - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr : addresses) - if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) - { - addr->published = false; - addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer - addr->ssu->introducers.clear (); - port = addr->port; - } + auto addresses = m_RouterInfo.GetAddresses (); + if (addresses) + { + for (auto& addr : *addresses) + if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) + { + addr->published = false; + addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer + addr->ssu->introducers.clear (); + port = addr->port; + } + } // unpublish NTCP2 addreeses bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) @@ -630,15 +644,18 @@ namespace i2p uint16_t port = 0; // delete previous introducers bool isSSU2Published; i2p::config::GetOption ("ssu2.published", isSSU2Published); - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr : addresses) - if (addr->ssu && isSSU2Published && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) - { - addr->published = true; - addr->caps |= i2p::data::RouterInfo::eSSUIntroducer; - addr->ssu->introducers.clear (); - if (addr->port) port = addr->port; - } + auto addresses = m_RouterInfo.GetAddresses (); + if (addresses) + { + for (auto& addr : *addresses) + if (addr->ssu && isSSU2Published && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) + { + addr->published = true; + addr->caps |= i2p::data::RouterInfo::eSSUIntroducer; + addr->ssu->introducers.clear (); + if (addr->port) port = addr->port; + } + } // publish NTCP2 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) @@ -663,23 +680,26 @@ namespace i2p // insert v6 addresses if necessary bool foundNTCP2 = false, foundSSU2 = false; uint16_t port = 0; - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) + auto addresses = m_RouterInfo.GetAddresses (); + 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: - foundNTCP2 = true; - break; - case i2p::data::RouterInfo::eTransportSSU2: - foundSSU2 = true; - break; - default: ; + switch (addr->transportStyle) + { + case i2p::data::RouterInfo::eTransportNTCP2: + foundNTCP2 = true; + break; + case i2p::data::RouterInfo::eTransportSSU2: + foundSSU2 = true; + break; + default: ; + } } + port = addr->port; } - port = addr->port; } if (!port) { @@ -743,24 +763,27 @@ namespace i2p bool foundNTCP2 = false, foundSSU2 = false; std::string host = "127.0.0.1"; uint16_t port = 0; - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) + auto addresses = m_RouterInfo.GetAddresses (); + if (addresses) { - if (addr->IsV4 ()) + for (auto& addr: *addresses) { - switch (addr->transportStyle) + if (addr->IsV4 ()) { - case i2p::data::RouterInfo::eTransportNTCP2: - foundNTCP2 = true; - break; - case i2p::data::RouterInfo::eTransportSSU2: - foundSSU2 = true; - break; - default: ; + switch (addr->transportStyle) + { + case i2p::data::RouterInfo::eTransportNTCP2: + foundNTCP2 = true; + break; + case i2p::data::RouterInfo::eTransportSSU2: + foundSSU2 = true; + break; + default: ; + } } + if (addr->port) port = addr->port; } - if (addr->port) port = addr->port; - } + } if (!port) { i2p::config::GetOption("port", port); @@ -816,16 +839,19 @@ namespace i2p i2p::config::GetOption ("ntcp2.port", port); if (!port) i2p::config::GetOption("port", port); bool foundMesh = false; - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) + auto addresses = m_RouterInfo.GetAddresses (); + if (addresses) { - if (!port) port = addr->port; - if (i2p::util::net::IsYggdrasilAddress (addr->host)) + for (auto& addr: *addresses) { - foundMesh = true; - break; + if (!port) port = addr->port; + if (i2p::util::net::IsYggdrasilAddress (addr->host)) + { + foundMesh = true; + break; + } } - } + } if (!foundMesh) m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); } @@ -837,8 +863,9 @@ namespace i2p void RouterContext::SetMTU (int mtu, bool v4) { if (mtu < 1280 || mtu > 1500) return; - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; + for (auto& addr: *addresses) { if (addr->ssu && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) { @@ -852,8 +879,9 @@ namespace i2p { bool isYgg = i2p::util::net::IsYggdrasilAddress (host); bool updated = false; - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) + auto addresses = m_RouterInfo.GetAddresses (); + if (!addresses) return; + for (auto& addr: *addresses) { if (addr->IsPublishedNTCP2 ()) { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 270e86c2..7ca72a63 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -826,6 +826,15 @@ namespace data return nullptr; } + boost::shared_ptr RouterInfo::GetAddresses () const + { +#if (BOOST_VERSION >= 105300) + return boost::atomic_load (&m_Addresses); +#else + return m_Addresses; +#endif + } + template std::shared_ptr RouterInfo::GetAddress (Filter filter) const { @@ -1048,14 +1057,15 @@ namespace data void LocalRouterInfo::WriteToStream (std::ostream& s) const { + auto addresses = GetAddresses (); + if (!addresses) return; + uint64_t ts = htobe64 (GetTimestamp ()); s.write ((const char *)&ts, sizeof (ts)); - // addresses - const Addresses& addresses = GetAddresses (); - uint8_t numAddresses = addresses.size (); + uint8_t numAddresses = addresses->size (); s.write ((char *)&numAddresses, sizeof (numAddresses)); - for (const auto& addr_ptr : addresses) + for (const auto& addr_ptr : *addresses) { const Address& address = *addr_ptr; // calculate cost @@ -1257,7 +1267,9 @@ namespace data 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 ()))) { @@ -1273,7 +1285,9 @@ namespace data 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 ()))) { diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 6e122d95..18e2b336 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -176,7 +176,7 @@ namespace data int GetVersion () const { return m_Version; }; virtual void SetProperty (const std::string& key, const std::string& value) {}; virtual void ClearProperties () {}; - Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr + boost::shared_ptr GetAddresses () const; // should be called for local RI only, otherwise must return shared_ptr std::shared_ptr GetNTCP2AddressWithStaticKey (const uint8_t * key) const; std::shared_ptr GetSSU2AddressWithStaticKey (const uint8_t * key, bool isV6) const; std::shared_ptr GetPublishedNTCP2V4Address () const; @@ -258,7 +258,6 @@ namespace data void UpdateBuffer (const uint8_t * buf, size_t len); void SetBufferLen (size_t len) { m_BufferLen = len; }; void RefreshTimestamp (); - const Addresses& GetAddresses () const { return *m_Addresses; }; CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; }; void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; }; diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index adb27847..dba29fff 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -36,8 +36,9 @@ namespace transport i2p::config::GetOption ("ssu2.published", m_IsPublished); i2p::config::GetOption("nettime.frompeers", m_IsSyncClockFromPeers); bool found = false; - auto& addresses = i2p::context.GetRouterInfo ().GetAddresses (); - for (const auto& address: addresses) + auto addresses = i2p::context.GetRouterInfo ().GetAddresses (); + if (!addresses) return; + for (const auto& address: *addresses) { if (!address) continue; if (address->transportStyle == i2p::data::RouterInfo::eTransportSSU2)