From: Arne Schwabe Date: Wed, 9 Nov 2022 15:48:10 +0000 (+0100) Subject: Push server mtu to client when supported and support occ mtu X-Git-Tag: v2.6_beta1~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=761575cb7b49e94f361c6aaf4bb43d7c7baa5b38;p=thirdparty%2Fopenvpn.git Push server mtu to client when supported and support occ mtu To maximise compatibility allow to lie our MTU in the default OCC message. Patch v2: improve documentation Patch v3: split changing default MTU into its own patch Patch v5: remove leftover mentions to default MTU Signed-off-by: Arne Schwabe Acked-by: Gert Doering Message-Id: <20221109154810.1268403-2-arne@rfc2549.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25499.html Signed-off-by: Gert Doering --- diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 4b2c4a7be..8e3c92ee1 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -524,10 +524,23 @@ routing. arguments of ``--ifconfig`` to mean "address netmask", no longer "local remote". ---tun-mtu n - Take the TUN device MTU to be **n** and derive the link MTU from it - (default :code:`1500`). In most cases, you will probably want to leave - this parameter set to its default value. +--tun-mtu args + + Valid syntaxes: + :: + + tun-mtu tun-mtu + tun-mtu tun-mtu occ-mtu + + Take the TUN device MTU to be ``tun-mtu`` and derive the link MTU from it. + In most cases, you will probably want to leave this parameter set to + its default value. + + The default for :code:`tun-mtu` is 1500. + + The OCC MTU can be used to avoid warnings about mismatched MTU from + clients. If :code:`occ-mtu` is not specified, it will to default to the + tun-mtu. The MTU (Maximum Transmission Units) is the maximum datagram size in bytes that can be sent unfragmented over a particular network path. @@ -540,6 +553,10 @@ routing. It's best to use the ``--fragment`` and/or ``--mssfix`` options to deal with MTU sizing issues. + Note: Depending on the platform, the operating system allows to receive + packets larger than ``tun-mtu`` (e.g. Linux and FreeBSD) but other platforms + (like macOS) limit received packets to the same size as the MTU. + --tun-max-mtu maxmtu This configures the maximum MTU size that a server can push to ``maxmtu``, by configuring the internal buffers to allow at least this packet size. diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 334fc4118..b7b34c9cc 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -825,6 +825,7 @@ init_options(struct options *o, const bool init_gc) o->status_file_version = 1; o->ce.bind_local = true; o->ce.tun_mtu = TUN_MTU_DEFAULT; + o->ce.occ_mtu = 0; o->ce.link_mtu = LINK_MTU_DEFAULT; o->ce.tls_mtu = TLS_MTU_DEFAULT; o->ce.mtu_discover_type = -1; @@ -4193,7 +4194,15 @@ options_string(const struct options *o, buf_printf(&out, ",link-mtu %u", (unsigned int) calc_options_string_link_mtu(o, frame)); - buf_printf(&out, ",tun-mtu %d", frame->tun_mtu); + if (o->ce.occ_mtu != 0) + { + buf_printf(&out, ",tun-mtu %d", o->ce.occ_mtu); + } + else + { + buf_printf(&out, ",tun-mtu %d", frame->tun_mtu); + } + buf_printf(&out, ",proto %s", proto_remote(o->ce.proto, remote)); bool p2p_nopull = o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o); @@ -6447,11 +6456,19 @@ add_option(struct options *options, options->ce.link_mtu = positive_atoi(p[1]); options->ce.link_mtu_defined = true; } - else if (streq(p[0], "tun-mtu") && p[1] && !p[2]) + else if (streq(p[0], "tun-mtu") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_PUSH_MTU|OPT_P_CONNECTION); options->ce.tun_mtu = positive_atoi(p[1]); options->ce.tun_mtu_defined = true; + if (p[2]) + { + options->ce.occ_mtu = positive_atoi(p[2]); + } + else + { + options->ce.occ_mtu = 0; + } } else if (streq(p[0], "tun-mtu-max") && p[1] && !p[3]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index a2bc13a1c..68ad0cacb 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -118,6 +118,7 @@ struct connection_entry const char *socks_proxy_authfile; int tun_mtu; /* MTU of tun device */ + int occ_mtu; /* if non-null, this is the MTU we announce to peers in OCC */ int tun_mtu_max; /* maximum MTU that can be pushed */ bool tun_mtu_defined; /* true if user overriding parm with command line option */ diff --git a/src/openvpn/push.c b/src/openvpn/push.c index 1bad00605..92a0bc2d9 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -673,6 +673,22 @@ prepare_push_reply(struct context *c, struct gc_arena *gc, push_option_fmt(gc, push_list, M_USAGE, "protocol-flags%s", buf_str(&proto_flags)); } + /* Push our mtu to the peer if it supports pushable MTUs */ + int client_max_mtu = 0; + const char *iv_mtu = extract_var_peer_info(tls_multi->peer_info, "IV_MTU=", gc); + + if (iv_mtu && sscanf(iv_mtu, "%d", &client_max_mtu) == 1) + { + push_option_fmt(gc, push_list, M_USAGE, "tun-mtu %d", o->ce.tun_mtu); + if (client_max_mtu < o->ce.tun_mtu) + { + msg(M_WARN, "Warning: reported maximum MTU from client (%d) is lower " + "than MTU used on the server (%d). Add tun-max-mtu %d " + "to client configuration.", client_max_mtu, + o->ce.tun_mtu, o->ce.tun_mtu); + } + } + return true; }