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 <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
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 <gert@greenie.muc.de>
| ... | ... |
@@ -524,10 +524,23 @@ routing. |
| 524 | 524 |
arguments of ``--ifconfig`` to mean "address netmask", no longer "local |
| 525 | 525 |
remote". |
| 526 | 526 |
|
| 527 |
- Take the TUN device MTU to be **n** and derive the link MTU from it |
|
| 528 |
- (default :code:`1500`). In most cases, you will probably want to leave |
|
| 529 |
- this parameter set to its default value. |
|
| 527 |
+--tun-mtu args |
|
| 528 |
+ |
|
| 529 |
+ Valid syntaxes: |
|
| 530 |
+ :: |
|
| 531 |
+ |
|
| 532 |
+ tun-mtu tun-mtu |
|
| 533 |
+ tun-mtu tun-mtu occ-mtu |
|
| 534 |
+ |
|
| 535 |
+ Take the TUN device MTU to be ``tun-mtu`` and derive the link MTU from it. |
|
| 536 |
+ In most cases, you will probably want to leave this parameter set to |
|
| 537 |
+ its default value. |
|
| 538 |
+ |
|
| 539 |
+ The default for :code:`tun-mtu` is 1500. |
|
| 540 |
+ |
|
| 541 |
+ The OCC MTU can be used to avoid warnings about mismatched MTU from |
|
| 542 |
+ clients. If :code:`occ-mtu` is not specified, it will to default to the |
|
| 543 |
+ tun-mtu. |
|
| 530 | 544 |
|
| 531 | 545 |
The MTU (Maximum Transmission Units) is the maximum datagram size in |
| 532 | 546 |
bytes that can be sent unfragmented over a particular network path. |
| ... | ... |
@@ -540,6 +553,10 @@ routing. |
| 540 | 540 |
It's best to use the ``--fragment`` and/or ``--mssfix`` options to deal |
| 541 | 541 |
with MTU sizing issues. |
| 542 | 542 |
|
| 543 |
+ Note: Depending on the platform, the operating system allows to receive |
|
| 544 |
+ packets larger than ``tun-mtu`` (e.g. Linux and FreeBSD) but other platforms |
|
| 545 |
+ (like macOS) limit received packets to the same size as the MTU. |
|
| 546 |
+ |
|
| 543 | 547 |
--tun-max-mtu maxmtu |
| 544 | 548 |
This configures the maximum MTU size that a server can push to ``maxmtu``, |
| 545 | 549 |
by configuring the internal buffers to allow at least this packet size. |
| ... | ... |
@@ -825,6 +825,7 @@ init_options(struct options *o, const bool init_gc) |
| 825 | 825 |
o->status_file_version = 1; |
| 826 | 826 |
o->ce.bind_local = true; |
| 827 | 827 |
o->ce.tun_mtu = TUN_MTU_DEFAULT; |
| 828 |
+ o->ce.occ_mtu = 0; |
|
| 828 | 829 |
o->ce.link_mtu = LINK_MTU_DEFAULT; |
| 829 | 830 |
o->ce.tls_mtu = TLS_MTU_DEFAULT; |
| 830 | 831 |
o->ce.mtu_discover_type = -1; |
| ... | ... |
@@ -4193,7 +4194,15 @@ options_string(const struct options *o, |
| 4193 | 4193 |
buf_printf(&out, ",link-mtu %u", |
| 4194 | 4194 |
(unsigned int) calc_options_string_link_mtu(o, frame)); |
| 4195 | 4195 |
|
| 4196 |
- buf_printf(&out, ",tun-mtu %d", frame->tun_mtu); |
|
| 4196 |
+ if (o->ce.occ_mtu != 0) |
|
| 4197 |
+ {
|
|
| 4198 |
+ buf_printf(&out, ",tun-mtu %d", o->ce.occ_mtu); |
|
| 4199 |
+ } |
|
| 4200 |
+ else |
|
| 4201 |
+ {
|
|
| 4202 |
+ buf_printf(&out, ",tun-mtu %d", frame->tun_mtu); |
|
| 4203 |
+ } |
|
| 4204 |
+ |
|
| 4197 | 4205 |
buf_printf(&out, ",proto %s", proto_remote(o->ce.proto, remote)); |
| 4198 | 4206 |
|
| 4199 | 4207 |
bool p2p_nopull = o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o); |
| ... | ... |
@@ -6447,11 +6456,19 @@ add_option(struct options *options, |
| 6447 | 6447 |
options->ce.link_mtu = positive_atoi(p[1]); |
| 6448 | 6448 |
options->ce.link_mtu_defined = true; |
| 6449 | 6449 |
} |
| 6450 |
- else if (streq(p[0], "tun-mtu") && p[1] && !p[2]) |
|
| 6450 |
+ else if (streq(p[0], "tun-mtu") && p[1] && !p[3]) |
|
| 6451 | 6451 |
{
|
| 6452 | 6452 |
VERIFY_PERMISSION(OPT_P_PUSH_MTU|OPT_P_CONNECTION); |
| 6453 | 6453 |
options->ce.tun_mtu = positive_atoi(p[1]); |
| 6454 | 6454 |
options->ce.tun_mtu_defined = true; |
| 6455 |
+ if (p[2]) |
|
| 6456 |
+ {
|
|
| 6457 |
+ options->ce.occ_mtu = positive_atoi(p[2]); |
|
| 6458 |
+ } |
|
| 6459 |
+ else |
|
| 6460 |
+ {
|
|
| 6461 |
+ options->ce.occ_mtu = 0; |
|
| 6462 |
+ } |
|
| 6455 | 6463 |
} |
| 6456 | 6464 |
else if (streq(p[0], "tun-mtu-max") && p[1] && !p[3]) |
| 6457 | 6465 |
{
|
| ... | ... |
@@ -118,6 +118,7 @@ struct connection_entry |
| 118 | 118 |
const char *socks_proxy_authfile; |
| 119 | 119 |
|
| 120 | 120 |
int tun_mtu; /* MTU of tun device */ |
| 121 |
+ int occ_mtu; /* if non-null, this is the MTU we announce to peers in OCC */ |
|
| 121 | 122 |
int tun_mtu_max; /* maximum MTU that can be pushed */ |
| 122 | 123 |
|
| 123 | 124 |
bool tun_mtu_defined; /* true if user overriding parm with command line option */ |
| ... | ... |
@@ -673,6 +673,22 @@ prepare_push_reply(struct context *c, struct gc_arena *gc, |
| 673 | 673 |
push_option_fmt(gc, push_list, M_USAGE, "protocol-flags%s", buf_str(&proto_flags)); |
| 674 | 674 |
} |
| 675 | 675 |
|
| 676 |
+ /* Push our mtu to the peer if it supports pushable MTUs */ |
|
| 677 |
+ int client_max_mtu = 0; |
|
| 678 |
+ const char *iv_mtu = extract_var_peer_info(tls_multi->peer_info, "IV_MTU=", gc); |
|
| 679 |
+ |
|
| 680 |
+ if (iv_mtu && sscanf(iv_mtu, "%d", &client_max_mtu) == 1) |
|
| 681 |
+ {
|
|
| 682 |
+ push_option_fmt(gc, push_list, M_USAGE, "tun-mtu %d", o->ce.tun_mtu); |
|
| 683 |
+ if (client_max_mtu < o->ce.tun_mtu) |
|
| 684 |
+ {
|
|
| 685 |
+ msg(M_WARN, "Warning: reported maximum MTU from client (%d) is lower " |
|
| 686 |
+ "than MTU used on the server (%d). Add tun-max-mtu %d " |
|
| 687 |
+ "to client configuration.", client_max_mtu, |
|
| 688 |
+ o->ce.tun_mtu, o->ce.tun_mtu); |
|
| 689 |
+ } |
|
| 690 |
+ } |
|
| 691 |
+ |
|
| 676 | 692 |
return true; |
| 677 | 693 |
} |
| 678 | 694 |
|