> Arne Schwabe <arne@rfc2549.org> hat am 07.12.2021 18:01 geschrieben:
[...]
> diff --git a/src/openvpn/mss.c b/src/openvpn/mss.c
> index aa5b68ce9..56dea0292 100644
> --- a/src/openvpn/mss.c
> +++ b/src/openvpn/mss.c
> @@ -30,6 +30,8 @@
> #include "syshead.h"
> #include "error.h"
> #include "mss.h"
> +#include "crypto.h"
> +#include "ssl_common.h"
> #include "memdbg.h"
>
> /*
> @@ -204,3 +206,41 @@ mss_fixup_dowork(struct buffer *buf, uint16_t maxmss)
> }
> }
> }
> +
> +void
> +frame_calculate_mssfix(struct frame *frame, struct key_type *kt,
> + const struct options *options)
> +{
> + if (options->ce.mssfix == 0)
> + {
> + return;
> + }
> +
> + unsigned int payload_size;
> + unsigned int overhead;
> +
> +
> + payload_size = frame_calculate_payload_size(frame, options);
> +
> + overhead = frame_calculate_protocol_header_size(kt, options,
> + payload_size, false);
> +
> + /* Calculate the number of bytes that the payload differs from the payload
> + * MTU. This are fragment/compression/ethernet headers */
> + unsigned payload_overhead = frame_calculate_payload_overhead(frame, options, true);
> +
> + /* We are in a "liberal" position with respect to MSS,
> + * i.e. we assume that MSS can be calculated from MTU
> + * by subtracting out only the IP and TCP header sizes
> + * without options.
> + *
> + * (RFC 879, section 7). */
> +
> + /* Add 20 bytes for the IPv4 header and TCP header of the payload,
"20 bytes each" would make the sentence much easier to parse, IMHO.
> + * the mssfix routes will add 20 extra if payload is IPv6 */
> + overhead += 20 + 20;
> +
> + /* Calculate the maximum MSS value from the max link layer size specified
> + * by ce.mssfix */
> + frame->mss_fix = options->ce.mssfix - overhead - payload_overhead;
> +}
Regards,
Frank
--
Frank Lichtenheld
> Arne Schwabe <arne@rfc2549.org> hat am 07.12.2021 18:01 geschrieben:
[...]
> diff --git a/src/openvpn/mss.c b/src/openvpn/mss.c
> index aa5b68ce9..56dea0292 100644
> --- a/src/openvpn/mss.c
> +++ b/src/openvpn/mss.c
[...]
> @@ -204,3 +206,41 @@ mss_fixup_dowork(struct buffer *buf, uint16_t maxmss)
> }
> }
> }
> +
> +void
> +frame_calculate_mssfix(struct frame *frame, struct key_type *kt,
> + const struct options *options)
> +{
> + if (options->ce.mssfix == 0)
> + {
> + return;
> + }
Wouldn't an ASSERT be better here? This essentially should never happen because ce.mssfix is initialized
to MSSFIX_DEFAULT, anyway. If you handle this without an error here it looks like this will just explode
later in mss_fixup_dowork. An ASSERT might be easier and cleaner.
> + unsigned int payload_size;
> + unsigned int overhead;
> +
> +
> + payload_size = frame_calculate_payload_size(frame, options);
> +
> + overhead = frame_calculate_protocol_header_size(kt, options,
> + payload_size, false);
> +
> + /* Calculate the number of bytes that the payload differs from the payload
> + * MTU. This are fragment/compression/ethernet headers */
> + unsigned payload_overhead = frame_calculate_payload_overhead(frame, options, true);
> +
> + /* We are in a "liberal" position with respect to MSS,
> + * i.e. we assume that MSS can be calculated from MTU
> + * by subtracting out only the IP and TCP header sizes
> + * without options.
> + *
> + * (RFC 879, section 7). */
> +
> + /* Add 20 bytes for the IPv4 header and TCP header of the payload,
> + * the mssfix routes will add 20 extra if payload is IPv6 */
> + overhead += 20 + 20;
> +
> + /* Calculate the maximum MSS value from the max link layer size specified
> + * by ce.mssfix */
> + frame->mss_fix = options->ce.mssfix - overhead - payload_overhead;
> +}
> \ No newline at end of file
Regards,
--
Frank Lichtenheld
@@ -1493,7 +1493,7 @@ process_ip_header(struct context *c, unsigned int flags, struct buffer *buf)
/* possibly alter the TCP MSS */
if (flags & PIP_MSSFIX)
{
- mss_fixup_ipv4(&ipbuf, MTU_TO_MSS(TUN_MTU_SIZE_DYNAMIC(&c->c2.frame)));
+ mss_fixup_ipv4(&ipbuf, c->c2.frame.mss_fix);
}
/* possibly do NAT on packet */
@@ -1517,8 +1517,7 @@ process_ip_header(struct context *c, unsigned int flags, struct buffer *buf)
/* possibly alter the TCP MSS */
if (flags & PIP_MSSFIX)
{
- mss_fixup_ipv6(&ipbuf,
- MTU_TO_MSS(TUN_MTU_SIZE_DYNAMIC(&c->c2.frame)));
+ mss_fixup_ipv6(&ipbuf, c->c2.frame.mss_fix);
}
if (!(flags & PIP_OUTGOING) && (flags
&(PIPV6_IMCP_NOHOST_CLIENT | PIPV6_IMCP_NOHOST_SERVER)))
@@ -53,6 +53,7 @@
#include "tls_crypt.h"
#include "forward.h"
#include "auth_token.h"
+#include "mss.h"
#include "memdbg.h"
@@ -4156,7 +4157,7 @@ init_instance(struct context *c, const struct env_set *env, const unsigned int f
#endif
/* initialize dynamic MTU variable */
- frame_init_mssfix(&c->c2.frame, &c->options);
+ frame_calculate_mssfix(&c->c2.frame, &c->c1.ks.key_type, &c->options);
/* bind the TCP/UDP socket */
if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
@@ -30,6 +30,8 @@
#include "syshead.h"
#include "error.h"
#include "mss.h"
+#include "crypto.h"
+#include "ssl_common.h"
#include "memdbg.h"
/*
@@ -204,3 +206,41 @@ mss_fixup_dowork(struct buffer *buf, uint16_t maxmss)
}
}
}
+
+void
+frame_calculate_mssfix(struct frame *frame, struct key_type *kt,
+ const struct options *options)
+{
+ if (options->ce.mssfix == 0)
+ {
+ return;
+ }
+
+ unsigned int payload_size;
+ unsigned int overhead;
+
+
+ payload_size = frame_calculate_payload_size(frame, options);
+
+ overhead = frame_calculate_protocol_header_size(kt, options,
+ payload_size, false);
+
+ /* Calculate the number of bytes that the payload differs from the payload
+ * MTU. This are fragment/compression/ethernet headers */
+ unsigned payload_overhead = frame_calculate_payload_overhead(frame, options, true);
+
+ /* We are in a "liberal" position with respect to MSS,
+ * i.e. we assume that MSS can be calculated from MTU
+ * by subtracting out only the IP and TCP header sizes
+ * without options.
+ *
+ * (RFC 879, section 7). */
+
+ /* Add 20 bytes for the IPv4 header and TCP header of the payload,
+ * the mssfix routes will add 20 extra if payload is IPv6 */
+ overhead += 20 + 20;
+
+ /* Calculate the maximum MSS value from the max link layer size specified
+ * by ce.mssfix */
+ frame->mss_fix = options->ce.mssfix - overhead - payload_overhead;
+}
\ No newline at end of file
@@ -26,6 +26,8 @@
#include "proto.h"
#include "error.h"
+#include "mtu.h"
+#include "ssl_common.h"
void mss_fixup_ipv4(struct buffer *buf, int maxmss);
@@ -33,4 +35,8 @@ void mss_fixup_ipv6(struct buffer *buf, int maxmss);
void mss_fixup_dowork(struct buffer *buf, uint16_t maxmss);
+/** Set the --mssfix option. */
+void frame_calculate_mssfix(struct frame *frame, struct key_type *kt,
+ const struct options *options);
+
#endif
@@ -205,15 +205,6 @@ frame_subtract_extra(struct frame *frame, const struct frame *src)
frame->extra_tun += src->extra_frame;
}
-void
-frame_init_mssfix(struct frame *frame, const struct options *options)
-{
- if (options->ce.mssfix)
- {
- frame_set_mtu_dynamic(frame, options->ce.mssfix, SET_MTU_UPPER_BOUND);
- }
-}
-
void
frame_print(const struct frame *frame,
int level,
@@ -94,6 +94,12 @@ struct frame {
int link_mtu; /**< Maximum packet size to be sent over
* the external network interface. */
+ unsigned int mss_fix; /**< The actual MSS value that should be
+ * written to the payload packets. This
+ * is the value for IPv4 TCP packets. For
+ * IPv6 packets another 20 bytes must
+ * be subtracted */
+
int link_mtu_dynamic; /**< Dynamic MTU value for the external
* network interface. */
@@ -152,7 +158,6 @@ struct options;
* This is the size to "ifconfig" the tun or tap device.
*/
#define TUN_MTU_SIZE(f) ((f)->link_mtu - TUN_LINK_DELTA(f))
-#define TUN_MTU_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - TUN_LINK_DELTA(f))
/*
* This is the maximum packet size that we need to be able to
@@ -291,9 +296,6 @@ void alloc_buf_sock_tun(struct buffer *buf,
const struct frame *frame,
const bool tuntap_buffer);
-/** Set the --mssfix option. */
-void frame_init_mssfix(struct frame *frame, const struct options *options);
-
/*
* EXTENDED_SOCKET_ERROR_CAPABILITY functions -- print extra error info
* on socket errors, such as PMTU size. As of 2003.05.11, only works
@@ -247,17 +247,6 @@ struct ip_tcp_udp_hdr {
acc -= (u32) >> 16; \
}
-/*
- * We are in a "liberal" position with respect to MSS,
- * i.e. we assume that MSS can be calculated from MTU
- * by subtracting out only the IP and TCP header sizes
- * without options.
- *
- * (RFC 879, section 7).
- */
-#define MTU_TO_MSS(mtu) (mtu - sizeof(struct openvpn_iphdr) \
- - sizeof(struct openvpn_tcphdr))
-
/*
* This returns an ip protocol version of packet inside tun
* and offset of IP header (via parameter).
@@ -62,6 +62,7 @@
#include "ssl_ncp.h"
#include "ssl_util.h"
#include "auth_token.h"
+#include "mss.h"
#include "memdbg.h"
@@ -1893,7 +1894,7 @@ tls_session_update_crypto_params_do_work(struct tls_session *session,
options->replay, packet_id_long_form);
frame_finalize(frame, options->ce.link_mtu_defined, options->ce.link_mtu,
options->ce.tun_mtu_defined, options->ce.tun_mtu);
- frame_init_mssfix(frame, options);
+ frame_calculate_mssfix(frame, &session->opt->key_type, options);
frame_print(frame, D_MTU_INFO, "Data Channel MTU parms");
/*