diff --git a/contrib/dinit/i2pd b/contrib/dinit/i2pd index 63d877c1f9f..f1b73f53482 100644 --- a/contrib/dinit/i2pd +++ b/contrib/dinit/i2pd @@ -5,4 +5,6 @@ smooth-recovery = true depends-on = ntpd # uncomment if you want to use i2pd with yggdrasil # depends-on = yggdrasil +# uncomment if you want to use i2pd with mycelium +# depends-on = mycelium pid-file = /var/lib/i2pd/i2pd.pid diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 1cc357e2720..1ce4cc2b4fb 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -221,6 +221,12 @@ ipv6 = false ## The address must first be added to the network interface # yggaddress = +## Enable connectivity over the Mycelium network (default: false) +# mycelium = false +## You can bind address from your Mycelium subnet 500::/64 +## The address must first be added to the network interface +# mycaddress = + [reseed] ## Options for bootstrapping into I2P network, aka reseeding ## Enable reseed data verification (default: true) @@ -230,6 +236,8 @@ verify = true # urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/ ## Reseed URLs through the Yggdrasil, separated by comma # yggurls = http://[324:71e:281a:9ed3::ace]:7070/ +## Reseed URLs through the Mycelium, separated by comma +# mycurls = ## Path to local reseed data file (.su3) for manual reseeding # file = /path/to/i2pseeds.su3 ## or HTTPS URL to reseed from @@ -280,4 +288,3 @@ verify = true # profiles = true ## Save full addresses on disk (default: true) # addressbook = true - diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index d87b3ba1688..7a0dfc92c01 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -268,6 +268,9 @@ namespace config { "http://[320:8936:ec1a:31f1::216]/," "http://[316:f9e0:f22e:a74f::216]/" ), "Reseed URLs through the Yggdrasil, separated by comma") + ("reseed.mycurls", value()->default_value( + "" // @TODO + ), "Reseed URLs through the Mycelium, separated by comma") ; options_description addressbook("AddressBook options"); @@ -356,6 +359,8 @@ namespace config { meshnets.add_options() ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)") ("meshnets.yggaddress", value()->default_value(""), "Yggdrasil address to publish") + ("meshnets.mycelium", bool_switch()->default_value(false), "Support transports through the Mycelium (default: false)") + ("meshnets.mycaddress", value()->default_value(""), "Mycelium address to publish") ; #ifdef __linux__ diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 90b478af117..5b025c35716 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -847,7 +847,8 @@ namespace transport } auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri1->GetNTCP2V4Address () : - (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri1->GetYggdrasilAddress () : ri1->GetNTCP2V6Address ()); + (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri1->GetYggdrasilAddress () : ( + i2p::util::net::IsMyceliumAddress (m_RemoteEndpoint.address ()) ? ri1->GetMyceliumAddress () : ri1->GetNTCP2V6Address ())); if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32)) { LogPrint (eLogError, "NTCP2: Wrong static key in SessionConfirmed"); @@ -855,9 +856,10 @@ namespace transport return; } if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && - (!m_RemoteEndpoint.address ().is_v6 () || (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? - memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet - memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address + (!m_RemoteEndpoint.address ().is_v6 () || + (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) || i2p::util::net::IsMyceliumAddress (m_RemoteEndpoint.address ()) ? + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil | mycelium subnet + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address { if (isOlder) // older router? i2p::data::UpdateRouterProfile (ri1->GetIdentHash (), @@ -1469,7 +1471,9 @@ namespace transport i2p::data::RouterInfo::SupportedTransports NTCP2Session::GetTransportType () const { if (m_RemoteEndpoint.address ().is_v4 ()) return i2p::data::RouterInfo::eNTCP2V4; - return i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? i2p::data::RouterInfo::eNTCP2V6Mesh : i2p::data::RouterInfo::eNTCP2V6; + return i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) || + i2p::util::net::IsMyceliumAddress (m_RemoteEndpoint.address ()) ? i2p::data::RouterInfo::eNTCP2V6Mesh + : i2p::data::RouterInfo::eNTCP2V6; } NTCP2Server::NTCP2Server (): @@ -1547,7 +1551,7 @@ namespace transport m_NTCP2V6Acceptor->set_option (boost::asio::ip::v6_only (true)); m_NTCP2V6Acceptor->set_option (boost::asio::socket_base::reuse_address (true)); #if defined(__linux__) && !defined(_NETINET_IN_H) - if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address + if (!m_Address6 && !m_YggdrasilAddress && !m_MyceliumAddress) // only if not binded to address { // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others #if (BOOST_VERSION >= 105500) @@ -1563,6 +1567,8 @@ namespace transport ep = boost::asio::ip::tcp::endpoint (m_Address6->address(), address->port); else if (m_YggdrasilAddress && !context.SupportsV6 ()) ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port); + else if (m_MyceliumAddress && !context.SupportsV6 ()) + ep = boost::asio::ip::tcp::endpoint (m_MyceliumAddress->address(), address->port); m_NTCP2V6Acceptor->bind (ep); m_NTCP2V6Acceptor->listen (); @@ -1687,6 +1693,8 @@ namespace transport { if (i2p::util::net::IsYggdrasilAddress (conn->GetRemoteEndpoint ().address ())) localAddress = m_YggdrasilAddress; + else if (i2p::util::net::IsMyceliumAddress (conn->GetRemoteEndpoint ().address ())) + localAddress = m_MyceliumAddress; else localAddress = m_Address6; conn->GetSocket ().open (boost::asio::ip::tcp::v6 ()); @@ -1783,7 +1791,8 @@ namespace transport { LogPrint (eLogDebug, "NTCP2: Connected from ", ep); if (!i2p::transport::transports.IsInReservedRange(ep.address ()) || - i2p::util::net::IsYggdrasilAddress (ep.address ())) + i2p::util::net::IsYggdrasilAddress (ep.address ()) || + i2p::util::net::IsMyceliumAddress (ep.address ())) { if (m_PendingIncomingSessions.emplace (ep.address (), conn).second) { @@ -2015,6 +2024,8 @@ namespace transport { if (i2p::util::net::IsYggdrasilAddress (localAddress)) m_YggdrasilAddress = addr; + if (i2p::util::net::IsMyceliumAddress (localAddress)) + m_MyceliumAddress = addr; else m_Address6 = addr; } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index b50d9087301..46663b10ab4 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -316,7 +316,7 @@ namespace transport boost::asio::ip::tcp::resolver m_Resolver; std::unique_ptr m_ProxyEndpoint; - std::shared_ptr m_Address4, m_Address6, m_YggdrasilAddress; + std::shared_ptr m_Address4, m_Address6, m_YggdrasilAddress, m_MyceliumAddress; std::mt19937 m_Rng; EstablisherService m_EstablisherService; i2p::crypto::AEADChaCha20Poly1305Encryptor m_Encryptor; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 23dae8ffb53..8fa897fa2fc 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -89,6 +89,7 @@ namespace data bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool yggdrasil; i2p::config::GetOption("meshnets.yggdrasil", yggdrasil); + bool mycelium; i2p::config::GetOption("meshnets.mycelium", mycelium); std::vector httpsReseedHostList; if (ipv4 || ipv6) @@ -98,16 +99,25 @@ namespace data boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); } - std::vector yggReseedHostList; + std::vector meshReseedHostList; + if (yggdrasil && !i2p::util::net::GetYggdrasilAddress ().is_unspecified ()) { LogPrint (eLogInfo, "Reseed: Yggdrasil is supported"); std::string yggReseedURLs; i2p::config::GetOption("reseed.yggurls", yggReseedURLs); if (!yggReseedURLs.empty ()) - boost::split(yggReseedHostList, yggReseedURLs, boost::is_any_of(","), boost::token_compress_on); + boost::split(meshReseedHostList, yggReseedURLs, boost::is_any_of(","), boost::token_compress_on); + } + + if (mycelium && !i2p::util::net::GetMyceliumAddress ().is_unspecified ()) + { + LogPrint (eLogInfo, "Reseed: Mycelium is supported"); + std::string mycReseedURLs; i2p::config::GetOption("reseed.mycurls", mycReseedURLs); + if (!mycReseedURLs.empty ()) + boost::split(meshReseedHostList, mycReseedURLs, boost::is_any_of(","), boost::token_compress_on); } - if (httpsReseedHostList.empty () && yggReseedHostList.empty()) + if (httpsReseedHostList.empty () && meshReseedHostList.empty()) { LogPrint (eLogWarning, "Reseed: No reseed servers specified"); return 0; @@ -116,10 +126,10 @@ namespace data int reseedRetries = 0; while (reseedRetries < 10) { - auto ind = rand () % (httpsReseedHostList.size () + yggReseedHostList.size ()); + auto ind = rand () % (httpsReseedHostList.size () + meshReseedHostList.size ()); bool isHttps = ind < httpsReseedHostList.size (); std::string reseedUrl = isHttps ? httpsReseedHostList[ind] : - yggReseedHostList[ind - httpsReseedHostList.size ()]; + meshReseedHostList[ind - httpsReseedHostList.size ()]; reseedUrl += "i2pseeds.su3"; auto num = ReseedFromSU3Url (reseedUrl, isHttps); if (num > 0) return num; // success @@ -137,7 +147,7 @@ namespace data int Reseeder::ReseedFromSU3Url (const std::string& url, bool isHttps) { LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url); - std::string su3 = isHttps ? HttpsRequest (url) : YggdrasilRequest (url); + std::string su3 = isHttps ? HttpsRequest (url) : MeshRequest (url); if (su3.length () > 0) { std::stringstream s(su3); @@ -669,7 +679,7 @@ namespace data if (ep.address ().is_v4 ()) supported = i2p::context.SupportsV4 (); else if (ep.address ().is_v6 ()) - supported = i2p::util::net::IsYggdrasilAddress (ep.address ()) ? + supported = i2p::util::net::IsYggdrasilAddress (ep.address ()) || i2p::util::net::IsMyceliumAddress (ep.address ()) ? i2p::context.SupportsMesh () : i2p::context.SupportsV6 (); } if (supported) @@ -749,7 +759,7 @@ namespace data return data; } - std::string Reseeder::YggdrasilRequest (const std::string& address) + std::string Reseeder::MeshRequest (const std::string& address) { i2p::http::URL url; if (!url.parse(address)) @@ -772,11 +782,11 @@ namespace data { boost::asio::ip::tcp::endpoint ep = it; if ( - i2p::util::net::IsYggdrasilAddress (ep.address ()) && - i2p::context.SupportsMesh () + (i2p::util::net::IsYggdrasilAddress (ep.address ()) || + i2p::util::net::IsMyceliumAddress (ep.address ())) && i2p::context.SupportsMesh () ) { - LogPrint (eLogDebug, "Reseed: Yggdrasil: Resolved to ", ep.address ()); + LogPrint (eLogDebug, "Reseed: Mesh: Resolved to ", ep.address ()); s.connect (ep, ecode); if (!ecode) { @@ -787,18 +797,18 @@ namespace data } if (!connected) { - LogPrint(eLogError, "Reseed: Yggdrasil: Failed to connect to ", url.host); + LogPrint(eLogError, "Reseed: Mesh: Failed to connect to ", url.host); return ""; } } if (!ecode) { - LogPrint (eLogDebug, "Reseed: Yggdrasil: Connected to ", url.host, ":", url.port); + LogPrint (eLogDebug, "Reseed: Mesh: Connected to ", url.host, ":", url.port); return ReseedRequest (s, url.to_string()); } else - LogPrint (eLogError, "Reseed: Yggdrasil: Couldn't connect to ", url.host, ": ", ecode.message ()); + LogPrint (eLogError, "Reseed: Mesh: Couldn't connect to ", url.host, ": ", ecode.message ()); return ""; } diff --git a/libi2pd/Reseed.h b/libi2pd/Reseed.h index a6de6fa48ca..7d37d7be1a8 100644 --- a/libi2pd/Reseed.h +++ b/libi2pd/Reseed.h @@ -47,7 +47,7 @@ namespace data bool FindZipDataDescriptor (std::istream& s); std::string HttpsRequest (const std::string& address); - std::string YggdrasilRequest (const std::string& address); + std::string MeshRequest (const std::string& address); template std::string ReseedRequest (Stream& s, const std::string& uri); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 38fd46ce6e0..a634f567a5b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -106,9 +106,10 @@ namespace i2p bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + bool myc; i2p::config::GetOption("meshnets.mycelium", myc); bool nat; i2p::config::GetOption("nat", nat); - if ((ntcp2 || ygg) && !m_NTCP2Keys) + if ((ntcp2 || ygg || myc) && !m_NTCP2Keys) NewNTCP2Keys (); if (ssu2 && !m_SSU2Keys) NewSSU2Keys (); @@ -235,6 +236,12 @@ namespace i2p if (!yggaddr.is_unspecified ()) routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); } + if (myc) + { + auto mycaddr = i2p::util::net::GetMyceliumAddress (); + if (!mycaddr.is_unspecified ()) + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, mycaddr, port); + } routerInfo.UpdateCaps (caps); // caps + L routerInfo.SetProperty ("netId", std::to_string (m_NetID)); @@ -415,7 +422,7 @@ namespace i2p memcpy (address->i, m_NTCP2Keys->iv, 16); } - 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 mesh) { if (!m_NTCP2Keys) return; auto addresses = m_RouterInfo.GetAddresses (); @@ -439,7 +446,7 @@ namespace i2p updated = true; } } - if (ygg) + if (mesh) { auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; if (addr && (addr->port != port || addr->published != publish)) @@ -796,7 +803,9 @@ namespace i2p { for (auto& addr: *addresses) { - if (addr && addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host)) + if (addr && addr->IsV6 () && + !i2p::util::net::IsYggdrasilAddress (addr->host) && + !i2p::util::net::IsMyceliumAddress (addr->host)) { switch (addr->transportStyle) { @@ -1036,7 +1045,7 @@ namespace i2p auto addresses = m_RouterInfo.GetAddresses (); if (!addresses) return; std::shared_ptr addr; - if (i2p::util::net::IsYggdrasilAddress (host)) // yggdrasil + if (i2p::util::net::IsYggdrasilAddress (host) || i2p::util::net::IsMyceliumAddress (host)) addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; else if (host.is_v6 ()) addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; @@ -1150,7 +1159,8 @@ namespace i2p // create new NTCP2 keys if required bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); - if ((ntcp2 || ygg) && !m_NTCP2Keys) + bool myc; i2p::config::GetOption("meshnets.mycelium", myc); + if ((ntcp2 || ygg || myc) && !m_NTCP2Keys) { NewNTCP2Keys (); UpdateNTCP2Keys (); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 754c49dac77..e1745c2b6f7 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -151,7 +151,7 @@ namespace garlic void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU2 or Daemon - void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); + void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool mesh); void PublishSSU2Address (int port, bool publish, bool v4, bool v6); bool AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4); void RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 4af32f57aa6..caf7bbb8d99 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -254,7 +254,8 @@ namespace data if (!ecode && !address->host.is_unspecified ()) { if (!i2p::transport::transports.IsInReservedRange (address->host) || - i2p::util::net::IsYggdrasilAddress (address->host)) + i2p::util::net::IsYggdrasilAddress (address->host) || + i2p::util::net::IsMyceliumAddress (address->host)) isHost = true; else // we consider such address as invalid @@ -360,7 +361,8 @@ namespace data if (isHost && address->port) { if (address->host.is_v6 ()) - supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6); + supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) || // OR wants review @TODO + i2p::util::net::IsMyceliumAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6); else supportedTransports |= eNTCP2V4; m_PublishedTransports |= supportedTransports; @@ -717,7 +719,7 @@ namespace data } if (addr->IsV6 ()) { - if (i2p::util::net::IsYggdrasilAddress (addr->host)) + if (i2p::util::net::IsYggdrasilAddress (addr->host) || i2p::util::net::IsMyceliumAddress (addr->host)) { m_SupportedTransports |= eNTCP2V6Mesh; m_ReachableTransports |= eNTCP2V6Mesh; @@ -1082,7 +1084,8 @@ namespace data case eTransportNTCP2: if (addr->IsV4 ()) transports |= eNTCP2V4; if (addr->IsV6 ()) - transports |= (i2p::util::net::IsYggdrasilAddress (addr->host) ? eNTCP2V6Mesh : eNTCP2V6); + transports |= (i2p::util::net::IsYggdrasilAddress (addr->host) || // OR wants review @TODO + i2p::util::net::IsMyceliumAddress (addr->host) ? eNTCP2V6Mesh : eNTCP2V6); if (addr->IsPublishedNTCP2 ()) m_ReachableTransports |= transports; break; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index cb3ae499e5d..e113d1948b3 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -229,6 +229,7 @@ namespace data std::shared_ptr GetPublishedNTCP2V4Address () const; std::shared_ptr GetPublishedNTCP2V6Address () const; std::shared_ptr GetYggdrasilAddress () const; + std::shared_ptr GetMyceliumAddress () const; std::shared_ptr GetSSU2V4Address () const; std::shared_ptr GetSSU2V6Address () const; std::shared_ptr GetSSU2Address (bool v4) const; diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index a22e9bde8c4..1267418f2d6 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -78,7 +78,7 @@ namespace util } else if (ep.address ().is_v6 ()) { - if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + if (i2p::util::net::IsYggdrasilAddress (ep.address ()) || i2p::util::net::IsMyceliumAddress (ep.address ())) { if (i2p::context.SupportsMesh ()) found = true; } diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 1840c5ddc25..a70754c247a 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -685,7 +685,7 @@ namespace net if (dwRetVal != NO_ERROR) { - LogPrint(eLogError, "NetIface: GetYggdrasilAddress(): enclosed GetAdaptersAddresses() call has failed"); + LogPrint(eLogError, "NetIface: GetLocalIPV6Address(): enclosed GetAdaptersAddresses() call has failed"); FREE(pAddresses); return boost::asio::ip::address_v6 (); } @@ -747,7 +747,12 @@ namespace net boost::asio::ip::address_v6 GetYggdrasilAddress () { return GetLocalIPV6Address ([](const uint8_t addr[16]) { return IsYggdrasilAddress (addr); }); - } + } + + boost::asio::ip::address_v6 GetMyceliumAddress () + { + return GetLocalIPV6Address ([](const uint8_t addr[16]) { return IsMyceliumAddress (addr); }); + } boost::asio::ip::address_v6 GetClearnetIPV6Address () { @@ -816,7 +821,8 @@ namespace net if (ipv6_address >= it.first && ipv6_address <= it.second) return true; } - if (IsYggdrasilAddress (ipv6_address.data ())) // yggdrasil? + if (IsYggdrasilAddress (ipv6_address.data ()) || + IsMyceliumAddress (ipv6_address.data ())) // yggdrasil or mycelium? return true; } return false; diff --git a/libi2pd/util.h b/libi2pd/util.h index b3705381c31..3a7bd3e4511 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -271,6 +271,7 @@ namespace util int GetMaxMTU (const boost::asio::ip::address_v6& localAddress); // check tunnel broker for ipv6 address const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); boost::asio::ip::address_v6 GetYggdrasilAddress (); + boost::asio::ip::address_v6 GetMyceliumAddress (); boost::asio::ip::address_v6 GetClearnetIPV6Address (); bool IsLocalAddress (const boost::asio::ip::address& addr); bool IsInReservedRange (const boost::asio::ip::address& host); diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 3fea71721d6..dddf8935ed1 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -812,6 +812,11 @@ namespace client if (i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) found = true; } + else if (i2p::util::net::IsMyceliumAddress (ep.address ())) + { + if (i2p::util::net::IsMyceliumAddress (*m_LocalAddress)) + found = true; + } else if (m_LocalAddress->is_v6 ()) found = true; } @@ -960,4 +965,3 @@ namespace client } } } -