From dbb9295063cfd32edb298d828b6cfba96f235230 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Jul 2022 15:24:01 -0400 Subject: [PATCH] set MTU if local address is specified explicitly. update MTU for ipv6 if not set --- libi2pd/RouterContext.cpp | 72 ++++++++++++++++++++++++++++++--------- libi2pd/RouterContext.h | 1 + libi2pd/SSU2.cpp | 13 +++++++ 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 0624ff3e..e9489475 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -420,26 +420,29 @@ namespace i2p if (address->host != host && address->IsCompatible (host) && !i2p::util::net::IsYggdrasilAddress (address->host)) { + // update host address->host = host; - if (host.is_v6 () && (address->transportStyle == i2p::data::RouterInfo::eTransportSSU || address->IsSSU2 ())) + updated = true; + } + if (host.is_v6 () && address->IsV6 () && address->ssu && + (!address->ssu->mtu || updated)) + { + // update MTU + auto mtu = i2p::util::net::GetMTU (host); + if (mtu) { - // update MTU - auto mtu = i2p::util::net::GetMTU (host); - if (mtu) - { - LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); - int maxMTU = i2p::util::net::GetMaxMTU (host.to_v6 ()); - if (mtu > maxMTU) - { - mtu = maxMTU; - LogPrint(eLogWarning, "Router: MTU dropped to upper limit of ", maxMTU, " bytes"); - } - if (mtu && !address->IsSSU2 ()) // SSU1 - mtu = (mtu >> 4) << 4; // round to multiple of 16 - if (address->ssu) address->ssu->mtu = mtu; + LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); + int maxMTU = i2p::util::net::GetMaxMTU (host.to_v6 ()); + if (mtu > maxMTU) + { + mtu = maxMTU; + LogPrint(eLogWarning, "Router: MTU dropped to upper limit of ", maxMTU, " bytes"); } + if (mtu && !address->IsSSU2 ()) // SSU1 + mtu = (mtu >> 4) << 4; // round to multiple of 16 + address->ssu->mtu = mtu; + updated = true; } - updated = true; } } auto ts = i2p::util::GetSecondsSinceEpoch (); @@ -866,6 +869,43 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::SetMTU (int mtu, bool v4) + { + if (mtu < 1280 || mtu > 1500) return; + auto& addresses = m_RouterInfo.GetAddresses (); + for (auto& addr: addresses) + { + if (addr->ssu && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) + { + if (!addr->IsSSU2 ()) // SSU1 + { + // round to multiple of 16 + if (v4) + { + if (mtu > 1484) mtu = 1484; + else + { + mtu -= 12; + mtu = (mtu >> 4) << 4; + mtu += 12; + } + } + else + { + if (mtu > 1488) mtu = 1488; + else + mtu = (mtu >> 4) << 4; + } + } + if (mtu) + { + addr->ssu->mtu = mtu; + LogPrint (eLogDebug, "Router: MTU for ", v4 ? "ipv4" : "ipv6", " address is set to ", mtu); + } + } + } + } + void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) { bool isYgg = i2p::util::net::IsYggdrasilAddress (host); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ad3514bf..4946b7ca 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -144,6 +144,7 @@ namespace garlic void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host); + void SetMTU (int mtu, bool v4); i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; }; void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index de58d728..2c754e6b 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -115,9 +115,22 @@ namespace transport { if (localAddress.is_unspecified ()) return; if (localAddress.is_v4 ()) + { m_AddressV4 = localAddress; + int mtu = i2p::util::net::GetMTU (localAddress); + if (mtu < (int)SSU2_MIN_PACKET_SIZE) mtu = SSU2_MIN_PACKET_SIZE; + if (mtu > (int)SSU2_MAX_PACKET_SIZE) mtu = SSU2_MAX_PACKET_SIZE; + i2p::context.SetMTU (mtu, true); + } else if (localAddress.is_v6 ()) + { m_AddressV6 = localAddress; + int maxMTU = i2p::util::net::GetMaxMTU (localAddress.to_v6 ()); + int mtu = i2p::util::net::GetMTU (localAddress); + if (mtu > maxMTU) mtu = maxMTU; + if (mtu < (int)SSU2_MIN_PACKET_SIZE) mtu = SSU2_MIN_PACKET_SIZE; + i2p::context.SetMTU (mtu, false); + } } bool SSU2Server::IsSupported (const boost::asio::ip::address& addr) const