diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 556b226b..07ab2f20 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2023, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -45,7 +45,7 @@ namespace config { ("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)") ("family", value()->default_value(""), "Specify a family, router belongs to") ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") - ("host", value()->default_value("0.0.0.0"), "External IP") + ("host", value()->default_value(""), "External IP") ("ifname", value()->default_value(""), "Network interface to bind to") ("ifname4", value()->default_value(""), "Network interface to bind to for ipv4") ("ifname6", value()->default_value(""), "Network interface to bind to for ipv6") diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 86a0e915..d37bd440 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -88,92 +88,115 @@ namespace i2p uint8_t caps = 0, addressCaps = 0; if (ipv4) { - std::string host = "127.0.0.1"; - if (!i2p::config::IsDefault("host")) - i2p::config::GetOption("host", host); - else if (!nat) - { + std::string host; + if (!nat) // we have no NAT so set external address from local address - std::string address4; i2p::config::GetOption("address4", address4); - if (!address4.empty ()) host = address4; - } + i2p::config::GetOption("address4", host); + if (host.empty ()) i2p::config::GetOption("host", host); if (ntcp2) { - if (ntcp2Published) - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v4::from_string (host), port); - else // add non-published NTCP2 address + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + bool added = false; + if (ntcp2Published && ntcp2Port) + { + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } + } + } + if (!added) { + // add non-published NTCP2 address addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV4); } } if (ssu2) { - if (ssu2Published) - { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), ssu2Port); - } - else + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; + bool added = false; + if (ssu2Published && ssu2Port) + { + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } + } + if (!added) { addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro); + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV4); } } } if (ipv6) { - std::string host; - if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only - i2p::config::GetOption("host", host); - else - { - std::string address6; i2p::config::GetOption("address6", address6); - if (!address6.empty ()) host = address6; - } + std::string host; i2p::config::GetOption("address6", host); + if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented if (ntcp2) { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; bool added = false; - if (ntcp2Published) + if (ntcp2Published && ntcp2Port) { std::string ntcp2Host; if (!i2p::config::IsDefault ("ntcp2.addressv6")) i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); else ntcp2Host = host; - if (!ntcp2Host.empty () && port) + if (!ntcp2Host.empty ()) { - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port); - added = true; + auto addr = boost::asio::ip::address::from_string (ntcp2Host); + if (addr.is_v6 ()) + { + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } } } if (!added) { if (!ipv4) // no other ntcp2 addresses yet - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV6); addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; } } if (ssu2) { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; bool added = false; - if (ssu2Published) + if (ssu2Published && ssu2Port) { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - if (!host.empty () && ssu2Port) - { - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), ssu2Port); - added = true; - } + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v6 ()) + { + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } } if (!added) { if (!ipv4) // no other ssu2 addresses yet - routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro); + routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV6); addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; } } @@ -286,7 +309,7 @@ namespace i2p bool updated = false; for (auto& address : *addresses) { - if (address && address->port != port && address->transportStyle == i2p::data::RouterInfo::eTransportSSU2) + if (address && address->port != port) { address->port = port; updated = true; @@ -707,6 +730,9 @@ namespace i2p { if (!foundNTCP2) { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + bool added = false; bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published) { @@ -714,13 +740,19 @@ namespace i2p if (!i2p::config::IsDefault ("ntcp2.addressv6")) i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); else - ntcp2Host = "::1"; - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); + i2p::config::GetOption("host", ntcp2Host); + if (!ntcp2Host.empty () && ntcp2Port) + { + auto addr = boost::asio::ip::address::from_string (ntcp2Host); + if (addr.is_v6 ()) + { + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } + } } - else - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6); + if (!added) + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV6); } } else @@ -731,15 +763,25 @@ namespace i2p { if (!foundSSU2) { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; + bool added = false; bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); - if (ssu2Published) + if (ssu2Published && ssu2Port) { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - 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); + std::string host; i2p::config::GetOption("host", host); + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v6 ()) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } + } + if (!added) + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV6); } } else @@ -757,7 +799,6 @@ namespace i2p if (supportsV4) { bool foundNTCP2 = false, foundSSU2 = false; - std::string host = "127.0.0.1"; uint16_t port = 0; auto addresses = m_RouterInfo.GetAddresses (); if (addresses) @@ -791,15 +832,25 @@ namespace i2p { if (!foundNTCP2) { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + bool added = false; bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); - if (ntcp2Published) - { - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port); - } - else - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4); + if (ntcp2Published && ntcp2Port) + { + std::string host; i2p::config::GetOption("host", host); + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); + added = true; + } + } + } + if (!added) + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV4); } } else @@ -810,15 +861,26 @@ namespace i2p { if (!foundSSU2) { + uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); + if (!ssu2Port) ssu2Port = port; + bool added = false; bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); - if (ssu2Published) - { - uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); - if (!ssu2Port) ssu2Port = port; - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port); - } - else - m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV4); + std::string host; i2p::config::GetOption("host", host); + if (ssu2Published && ssu2Port) + { + std::string host; i2p::config::GetOption("host", host); + if (!host.empty ()) + { + auto addr = boost::asio::ip::address::from_string (host); + if (addr.is_v4 ()) + { + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); + added = true; + } + } + } + if (!added) + m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV4); } } else diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9e4701d3..ff86fb51 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -620,22 +620,44 @@ namespace data return l+1; } + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,int port, uint8_t caps) + { + auto addr = std::make_shared
(); + addr->port = port; + addr->transportStyle = eTransportNTCP2; + addr->caps = caps; + addr->date = 0; + addr->published = false; + memcpy (addr->s, staticKey, 32); + memcpy (addr->i, iv, 16); + if (addr->IsV4 ()) + { + m_SupportedTransports |= eNTCP2V4; + (*m_Addresses)[eNTCP2V4Idx] = addr; + } + if (addr->IsV6 ()) + { + m_SupportedTransports |= eNTCP2V6; + (*m_Addresses)[eNTCP2V6Idx] = addr; + } + } + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, - const boost::asio::ip::address& host, int port, uint8_t caps) + const boost::asio::ip::address& host, int port) { auto addr = std::make_shared
(); addr->host = host; addr->port = port; addr->transportStyle = eTransportNTCP2; - addr->caps = caps; + addr->caps = 0; addr->date = 0; - if (port) addr->published = true; + addr->published = true; memcpy (addr->s, staticKey, 32); memcpy (addr->i, iv, 16); if (addr->IsV4 ()) { m_SupportedTransports |= eNTCP2V4; - if (addr->published) m_ReachableTransports |= eNTCP2V4; + m_ReachableTransports |= eNTCP2V4; (*m_Addresses)[eNTCP2V4Idx] = addr; } if (addr->IsV6 ()) @@ -649,7 +671,7 @@ namespace data else { m_SupportedTransports |= eNTCP2V6; - if (addr->published) m_ReachableTransports |= eNTCP2V6; + m_ReachableTransports |= eNTCP2V6; (*m_Addresses)[eNTCP2V6Idx] = addr; } } @@ -672,11 +694,11 @@ namespace data UpdateSupportedTransports (); } - void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, uint8_t caps) + void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, int port, uint8_t caps) { auto addr = std::make_shared
(); addr->transportStyle = eTransportSSU2; - addr->port = 0; + addr->port = port; addr->caps = caps; addr->date = 0; addr->ssu.reset (new SSUExt ()); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 10405a0a..7d004a33 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -198,10 +198,11 @@ namespace data std::shared_ptr GetSSU2V6Address () const; std::shared_ptr GetSSU2Address (bool v4) const; + void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,int port, uint8_t caps); // non published 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); + const boost::asio::ip::address& host, int port); // published void RemoveNTCP2Address (bool v4); - 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, int port, uint8_t caps); // non published void AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, const boost::asio::ip::address& host, int port); // published void RemoveSSU2Address (bool v4);