From 583cb2e6d1b915b61edc90543aca607d0e0d8508 Mon Sep 17 00:00:00 2001 From: Marco Baffo Date: Tue, 3 Sep 2024 22:18:22 +0200 Subject: [PATCH] tun_recv: removed mssfix limit for IPv4 traffic if DF is not set Signed-off-by: Marco Baffo --- openvpn/client/cliproto.hpp | 11 ++++++++++- openvpn/ip/ip4.hpp | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/openvpn/client/cliproto.hpp b/openvpn/client/cliproto.hpp index 428f43e40..2fa39c913 100644 --- a/openvpn/client/cliproto.hpp +++ b/openvpn/client/cliproto.hpp @@ -443,12 +443,21 @@ class Session : ProtoContextCallbackInterface, if (buf.size()) { const ProtoContext::ProtoConfig &c = proto_context.conf(); + + bool df = true; + + if (IPCommon::version(buf[0]) == IPCommon::IPv4 && buf.size() >= sizeof(struct IPv4Header)) + { + df = IPv4Header::is_df_set(buf.c_data()); + } + // when calculating mss, we take IPv4 and TCP headers into account // here we need to add it back since we check the whole IP packet size, not just TCP payload constexpr size_t MinTcpHeader = 20; constexpr size_t MinIpHeader = 20; size_t mss_no_tcp_ip_encap = c.mss_fix + (MinTcpHeader + MinIpHeader); - if (c.mss_fix > 0 && buf.size() > mss_no_tcp_ip_encap) + + if (df && c.mss_fix > 0 && buf.size() > mss_no_tcp_ip_encap) { Ptb::generate_icmp_ptb(buf, clamp_to_typerange(mss_no_tcp_ip_encap)); tun->tun_send(buf); diff --git a/openvpn/ip/ip4.hpp b/openvpn/ip/ip4.hpp index d77ef0009..e8f64cf28 100644 --- a/openvpn/ip/ip4.hpp +++ b/openvpn/ip/ip4.hpp @@ -43,6 +43,12 @@ struct IPv4Header return static_cast(((len >> 2) & 0x0F) | (version & 0x0F) << 4); } + static bool is_df_set(const unsigned char *data) + { + auto *hdr = reinterpret_cast(data); + return ntohs(hdr->frag_off) & IPv4Header::DF; + } + std::uint8_t version_len; std::uint8_t tos; @@ -52,6 +58,7 @@ struct IPv4Header enum { OFFMASK = 0x1fff, + DF = 0x4000, }; std::uint16_t frag_off;