Hi Lev,
On 29/11/18 16:18, Lev Stipakov wrote:
Some background information.
In openvpn3 we decided not to implement fragments, because:
- this is quite a big feature which has to be supported through the
whole stack (client, server, kernel module)
- we assume that it is not used by most of users
However, for those who needs --fragment, we'll implement:
- mssfix support, this should solve problems with tcp-based protocols
- sending icmp "packet too big" for other protocols, we assume that
they'll respect icmp response
I'd thoroughly test this with protocols like Google's QUIC, which uses
UDP underneath. How does it respond to such ICMP messages? what does it
do to throughput?
--fragment is/was very useful on a system where you do not /
cannot change the tun MTU size. Up to Windows XP, this was not
possible without rebooting the OS. Since Vista, it *is* possible
to change the MTU of an adapter on the fly (as explained in my
trusty old cookbook, of course ;))
As James wrote a while ago (13 years ago :)
https://openvpn.net/archive/openvpn-users/2005-10/msg00354.html
> A lot of experience gained during the OpenVPN 1.x releases showed
that it's best to fix the tunnel MTU at
> 1500 and vary the other parameters (and use --mssfix to prevent
fragmentation rather than a lower tunnel MTU).
Don't know if still holds. Assuming that we can change tun-mtu on any
supported platforms, do you think that it is better
to do _that_, rather than have mssfix/icmp ptb workaround?
With that, it would be possible to fix the link-mtu to 1500 (or
whatever is set on the outbound interface) and then subtract the
header size to get a meaningful tun-mtu size.
Do you think 1500 is a safe value? Arne just mentioned today that his
network interface MTU is 1500 and router's MTU is 1492 due to PPPoE,
and openvpn2 works because it assumes that mtu is 1450.
I am not sure what a good default value is - it all depends on the
intermittent networks. What OpenVPN needs is the ability to send a
single UDP packet containing encapsulated data, knowing that that same
single UDP packet arrives at the destination. How the underlying
protocols/networks achieve this, is unknown.
Also, all of this applies only to UDP mode - in TCP mode it is best to
not fragment at all - simply let the TCP stream take care of the
encapsulated data, possible with TCP_NODELAY set.
Having said all that, I do have one gripe with the way the link or
tun mtu is calculated in the current codebase:
In the 2.3 code base, the server tun mtu size was equal to the
client tun-mtu size.
In the 2.4+ code base, the server-side tun mtu size is set to some
ridiculous low level (with link-mtu 1500 set) in order to
accomocate all possible encryption ciphers - *even if I add
ncp-disable* . To me, that does not make a whole lot of sense. If I
add '--ncp-disable' I'd expect the client and the server to behave
pretty much like an OpenVPN 2.3 client (with a possible 3
bytes difference to accomodate for the peer id).
With 2.4 codebase I noticed that what man page says is not what
openvpn2 code does - it does include transport overhead, while
man page says it doesn't (copying my mail here):
Announce to TCP sessions running over the tunnel that
they should limit their send packet sizes such that after OpenVPN has
encapsulated them, the resulting UDP packet size that OpenVPN sends to
its peer will not exceed max bytes. The default value is 1450.
The max parameter is interpreted in the same way as the
--link-mtu parameter, i.e. the UDP packet size after encapsulation
overhead has been added in, but not including the UDP header itself.
Resulting packet would be at most 28 bytes larger for IPv4 and 48
bytes for IPv6 (20/40 bytes for IP header and 8 bytes for UDP header).
So it means that with "mssfix" 1300 resulting IPv4 packet size would
be at most 1328.
This is what I see in Wireshark (server - git master, client 2.4.6):
Internet Protocol Version 4, Src: 128.199.xxx.yyy, Dst: 10.0.200.20
0100 .... = Version: 4
.... 0101 = Header Length: 20 bytes (5)
Total Length: 1300
Protocol: UDP (17)
User Datagram Protocol, Src Port: 1194, Dst Port: 1194
Source Port: 1194
Destination Port: 1194
Length: 1280
OpenVPN Protocol
Type: 0x49 [opcode/key_id]
Peer ID: 0
Data (1268 bytes)
While man page statement is technically correct - UDP packet size is
1300, which is "at most 1328", I think it should say:
> the resulting IP packet size that OpenVPN sends to its peer will not
exceed max bytes
and
> The max parameter is interpreted in the same way as the --link-mtu
parameter, i.e. the IP packet size
after encapsulation overhead has been added in, including UDP and IP
headers.
you seem to be talking about the mssfix size, wheras I am talking about
the tun-mtu size. When you add
link-mtu 1500
ncp-disable
(and no fragment or mssfix)
to a server config file, an OpenVPN 2.4 server starts up using
openvpn 2.4.6 -> mtu = 1379
whereas an OpenVPN 2.3 server starts with
openvpn 2.3.18 -> mtu = 1431
To me, this difference is inexplicable and annoying.
(see the mail thread titled "Overhead TUN vs TAP mode" on Openvpn-users).
When re-thinking all this, I see a large shift in the way OpenVPN 3
approaches the underlying network vs the way OpenVPN 1/2 do: with
OpenVPN 2, you can try to outsmart (or tune) the underlying network by
playing with the fragment parameter *at user level*. In OpenVPN 3, this
is left to the OS (by increasing/decreasing the local tun mtu size -
which says nothing about the MTU sizes further down the network). Most
likely the OS can do a better job than we (or YourAverageUser) can, but
I always like the ability to overrule what the OS is doing (esp at the
Linux level).
Also, would it be possible to implement PMTUD? I found this link to be
informative:
https://www.cisco.com/c/en/us/support/docs/ip/generic-routing-encapsulation-gre/25885-pmtud-ipfrag.html
That might make the underlying fragmentation process more "automagic".
JM2CW,
JJK
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel