diff --git a/openvpn/client/cliproto.hpp b/openvpn/client/cliproto.hpp index 428f43e4..3fa1b461 100644 --- a/openvpn/client/cliproto.hpp +++ b/openvpn/client/cliproto.hpp @@ -443,12 +443,27 @@ class Session : ProtoContextCallbackInterface, if (buf.size()) { const ProtoContext::ProtoConfig &c = proto_context.conf(); + + const uint8_t* packet_data = buf.data(); + bool df = true; + + // Check if the packet is IPv4 + if (IPCommon::version(packet_data[0]) == IPCommon::IPv4 && buf.size() >= sizeof(struct IPv4Header)) + { + // The Flags field is in the 6th byte (starting from index 6) of the IPv4 header + uint16_t flags_and_fragment_offset = ntohs(*(uint16_t*)&packet_data[6]); + + // The DF bit is the 2nd bit in the Flags field (0x4000 in big-endian) + df = (flags_and_fragment_offset & 0x4000) != 0; + } + // 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);