diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 4cee3e9b..d011d9d4 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -240,7 +240,19 @@ namespace util if (!ipv4 && !ipv6) i2p::context.SetStatus (eRouterStatusMesh); } - + bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); + if (ssu2) + { + bool published; i2p::config::GetOption("ssu2.published", published); + if (published) + { + uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port); + i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish + } + else + i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish + } + bool transit; i2p::config::GetOption("notransit", transit); i2p::context.SetAcceptsTunnels (!transit); uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 0c90872c..853a3fd2 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -300,7 +300,7 @@ namespace i2p if (updated) UpdateRouterInfo (); } - + void RouterContext::UpdateNTCP2Address (bool enable) { auto& addresses = m_RouterInfo.GetAddresses (); @@ -327,6 +327,24 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6) + { + if (!m_SSU2Keys || (publish && !port)) return; + bool updated = false; + for (auto& address : m_RouterInfo.GetAddresses ()) + { + if (address->IsSSU2 () && (address->port != port || address->published != publish) && + ((v4 && address->IsV4 ()) || (v6 && address->IsV6 ()))) + { + address->port = port; + address->published = publish; + updated = true; + } + } + if (updated) + UpdateRouterInfo (); + } + void RouterContext::UpdateSSU2Address (bool enable) { auto& addresses = m_RouterInfo.GetAddresses (); @@ -594,17 +612,26 @@ namespace i2p if (supportsV6) { // insert v6 addresses if necessary - bool foundSSU = false, foundNTCP2 = false; + bool foundSSU = false, foundNTCP2 = false, foundSSU2 = false; uint16_t port = 0; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) { if (addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host)) { - if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) - foundSSU = true; - else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP) - foundNTCP2 = true; + switch (addr->transportStyle) + { + case i2p::data::RouterInfo::eTransportSSU: + foundSSU = true; + break; + case i2p::data::RouterInfo::eTransportNTCP: + foundNTCP2 = true; + break; + case i2p::data::RouterInfo::eTransportSSU2: + foundSSU2 = true; + break; + default: ; + } } port = addr->port; } @@ -641,6 +668,19 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6); } } + // SSU2 + if (!foundSSU2) + { + bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); + bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); + if (ssu2Published) + { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port); + } + else + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6); + } m_RouterInfo.EnableV6 (); } else diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 93a72211..905fb3b8 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -116,6 +116,7 @@ namespace garlic void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); void UpdateNTCP2Address (bool enable); + void PublishSSU2Address (int port, bool publish, bool v4, bool v6); void UpdateSSU2Address (bool enable); void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index b20f0d07..e9eb1478 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -681,6 +681,33 @@ namespace data addr->date = 0; memcpy (addr->s, staticKey, 32); memcpy (addr->i, introKey, 32); + if (addr->IsV4 ()) m_SupportedTransports |= eSSU2V4; + if (addr->IsV6 ()) m_SupportedTransports |= eSSU2V6; + m_Addresses->push_back(std::move(addr)); + } + + void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, + const boost::asio::ip::address& host, int port) + { + auto addr = std::make_shared
(); + addr->transportStyle = eTransportSSU2; + addr->host = host; + addr->port = port; + addr->published = true; + addr->caps = 0; + addr->date = 0; + memcpy (addr->s, staticKey, 32); + memcpy (addr->i, introKey, 32); + if (addr->IsV4 ()) + { + m_SupportedTransports |= eSSU2V4; + m_ReachableTransports |= eSSU2V4; + } + if (addr->IsV6 ()) + { + m_SupportedTransports |= eSSU2V6; + m_ReachableTransports |= eSSU2V6; + } m_Addresses->push_back(std::move(addr)); } @@ -1175,15 +1202,20 @@ namespace data else if (address.transportStyle == eTransportSSU2) { WriteString ("SSU2", s); - // caps - WriteString ("caps", properties); - properties << '='; - std::string caps; - 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 << ';'; + if (address.published) + isPublished = true; + else + { + // caps + WriteString ("caps", properties); + properties << '='; + std::string caps; + 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 WriteString ("", s); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index c400d7f5..0fdd4478 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -196,7 +196,9 @@ namespace data 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, 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