willardf / Hazel-Networking

Hazel Networking is a low level networking library for C# providing connection-oriented, message-based communication via RUDP.
MIT License
391 stars 60 forks source link

Add fragmentation support #36

Open js6pak opened 2 years ago

js6pak commented 2 years ago

Fragments all reliable packets with sizes over the connection MTU, trying to send an unreliable packet that is too big simply throws an exception.

Fragmented message protocol is very simple:

byte = UdpSendOption.Fragment // 11
ushort = fragments count
ushort = fragmented message id
... // remaining fragmented data to be reconstructed

Then it gets stored on the receiving end and is reconstructed when received fragmentsCount fragments Currently SendOption.Reliable is assumed for all fragmented messages but maybe it should be specified explictly in case SendOption.ReliableOrdered or something was ever added? e90317b13263d84c6ff56507c20364c74b70a7d7

MTU discovery is somewhat inspired by LiteNetLib, it uses just a few MTU values to discover MTU very quickly and the value is good enough in most cases: https://github.com/willardf/Hazel-Networking/blob/c238a8b51d2e311644027eb38505cc0c3c59c44d/Hazel/Udp/UdpConnection.Fragmented.cs#L15-L25 It works by sending a reliable packet with the size of the tested MTU, if we get an ACK back it means that the MTU is fine and attempt higher MTU, if not we get an ACPI error back in form of a SocketException and cancel the ACK.

MTU changing (both higher and lower) during connection isn't handled (yet).

This also doesn't take DTLS in account at all, I guess we could subtract DTLS application data header from the MTU when DTLS is used?