diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index a3048f4d..c9e4972c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -461,6 +461,20 @@ namespace i2p UpdateRouterInfo (); } + bool RouterContext::AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4) + { + bool ret = m_RouterInfo.AddSSU2Introducer (introducer, v4); + if (ret) + UpdateRouterInfo (); + return ret; + } + + void RouterContext::RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4) + { + if (m_RouterInfo.RemoveSSU2Introducer (h, v4)) + UpdateRouterInfo (); + } + void RouterContext::SetFloodfill (bool floodfill) { m_IsFloodfill = floodfill; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 7a878c7d..6d575912 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -123,6 +123,8 @@ namespace garlic void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); + bool AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4); + void RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4); bool IsUnreachable () const; void SetUnreachable (bool v4, bool v6); void SetReachable (bool v4, bool v6); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 26351a0b..4dae397e 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1478,5 +1478,40 @@ namespace data { return std::make_shared (); } + + bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4) + { + for (auto& addr : GetAddresses ()) + { + if (addr->IsSSU2 () && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) + { + for (auto& intro: addr->ssu->introducers) + if (intro.iTag == introducer.iTag) return false; // already presented + addr->ssu->introducers.push_back (introducer); + SetReachableTransports (GetReachableTransports () | ((addr->IsV4 () ? eSSU2V4 : eSSU2V6))); + return true; + } + } + return false; + } + + bool LocalRouterInfo::RemoveSSU2Introducer (const IdentHash& h, bool v4) + { + for (auto& addr: GetAddresses ()) + { + 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) + { + addr->ssu->introducers.erase (it); + if (addr->ssu->introducers.empty ()) + SetReachableTransports (GetReachableTransports () & ~(addr->IsV4 () ? eSSU2V4 : eSSU2V6)); + return true; + } + } + } + return false; + } } } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index fca6352a..6bc66b35 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -275,6 +275,8 @@ namespace data 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; }; private: @@ -317,6 +319,9 @@ namespace data std::string GetProperty (const std::string& key) const; void ClearProperties () override { m_Properties.clear (); }; + bool AddSSU2Introducer (const Introducer& introducer, bool v4); + bool RemoveSSU2Introducer (const IdentHash& h, bool v4); + private: void WriteToStream (std::ostream& s) const; diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 62ae7358..e667b337 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -770,8 +770,11 @@ namespace transport newList.push_back (it); excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ()); } - // TODO: remove introducer + else + i2p::context.RemoveSSU2Introducer (it->GetRemoteIdentity ()->GetIdentHash (), it->GetAddress ()->IsV4 ()); } + else + i2p::context.RemoveSSU2Introducer (it->GetRemoteIdentity ()->GetIdentHash (), it->GetAddress ()->IsV4 ()); } if (newList.size () < SSU2_MAX_NUM_INTRODUCERS) { @@ -789,9 +792,16 @@ namespace transport for (const auto& it : sessions) { - // TODO: add introducer - newList.push_back (it); - if (newList.size () >= SSU2_MAX_NUM_INTRODUCERS) break; + i2p::data::RouterInfo::Introducer introducer; + introducer.iTag = it->GetRelayTag (); + introducer.iKey = it->GetRemoteIdentity ()->GetIdentHash (); + introducer.iExp = it->GetCreationTime () + SSU2_TO_INTRODUCER_SESSION_EXPIRATION; + excluded.insert (it->GetRemoteIdentity ()->GetIdentHash ()); + if (i2p::context.AddSSU2Introducer (introducer, it->GetAddress ()->IsV4 ())) + { + newList.push_back (it); + if (newList.size () >= SSU2_MAX_NUM_INTRODUCERS) break; + } } } introducers = newList;