[erlang-questions] UDP questions

Andreas Schultz aschultz@REDACTED
Thu Jan 28 09:50:07 CET 2016


Hi,

On 01/28/2016 02:24 AM, Serge Aleynikov wrote:
> In addition to what others have said, the max UDP binary size that can be sent/received is:
> 64k - (sizeof(IPHeader) + sizeof(UDPHeader)) = 65535- (20 + 8) = 65507.  This is the UDP protocol's limitation.  I would say if you use UDP,
> the {packet, N} option makes little sense, since each udp message is delivered as a whole (UDP is message oriented vs. TCP that is
> byte-oriented).
>
> I see between your 3rd and 4th questions there's some confusion. UDP fragmentation may happen at the network layer (IP) when sending a large
> datagram (> MTU size), but it's defragmented by the network stack, and delivered to the transport layer (UDP) and consequently the user
> space as a whole message (preserving message boundaries).

What you describe here is happens when the DF (don't fragment) bit in the IP header is not set.

When the DF bit set, the first hop (which might be your local host) with a MTU smaller that your datagram size, will send an ICMP error with 
the reason set to "fragmentation needed". This ICMP will also include the largest MTU that this host can pass on. This procedure is also 
known as Path MTU discovery (PMTU disc).

Whether your local host actually gets the ICMP error, depends on the (mis-)configuration of firewalls between the reporting hop and your
host. This is what makes PMTU discovery somewhat unreliable.

If your sending host does indeed get the ICMP report, it will usually store the new PMTU for the original destination IP. On Linux you 
should be able to inquire that value through the IP_MTU socket option (see 'man 7 ip' on Linux).

A UDP datagram that was dropped due to a fragmentation needed error, even when your host did get the ICMP error, is not resent and you will 
not get a error from the socket. Only when you attempt to send another packet that is above the PMTU will you get a error from the socket.

Note: The UDP socket error behaviour description above is what Erlang supports. At least on Linux you could configure the socket to report 
errors as OOB data and poll/select for that data. This error data would then need to be decode and forwarded to the socket owner as 
udp_error report. I have no idea if/how this work on other OSes.

On Linux, UDP sockets are opened with systems defaults for the DF bit. In most cases this means the DF will be set on outgoing UDP 
datagrams. So any non localhost communication this will mean, that in the best case, your maximum usable UDP payload size will be 1472 (1500 
- 20 - 8), the guaranteed minimum for IPv4 is 548 (576 - 20 - 8) and for IPv6 around 1200 (minimum MTU is 1280, but IPv6 header size can vary).

It would be absolutely fantastic if Erlang would support proper PMTU discovery and error reporting on all supported OSes. I could contribute 
an Linux only version if there is a chance of having this as an officially supported feature.

Regards,
Andreas

>
> Regards,
>
> Serge
>
> On Wed, Jan 27, 2016 at 10:27 AM, Joe Armstrong <erlang@REDACTED <mailto:erlang@REDACTED>> wrote:
>
>     Hello,
>
>     I have a simple UDP client/server
>
>     The server is on a fixed port 4567 - I open it like this
>
>          {ok, Socket} = gen_udp:open(4567, [binary]),
>
>     then wait for registrations
>          receive
>     {udp, Socket, _Ip, _Port, <<"register">>) ->
>
>
>     Clients do this:
>
>           {ok, Socket} = gen_udp:open(0, [binary]),
>           gen_udp:send(Socket, "localhost", 44567, <<"register">>),
>           ...
>
>     I'm testing on "localhost"
>
>     After registration the processes send binaries to each other
>
>     This works fine for small binaries but gen_udp:send fails  with
>     {error,emsgsize} for large binaries
>
>     So I have a few questions:
>
>          1) Can I find out the max binary size that can be sent/received?
>          2) Can I increase the max size?
>          3) Is there a guaranteed minimum packet length that will not be fragemented?
>          3) Can received packets be fragmented - TCP has a  {packet,N}
>             option and some built-in defragmentation, what's the story for
>             UDP?
>
>     I think I know the answers to these but I'm not really sure - could somebody
>     who really knows enlighten me?
>
>     Thanks
>
>     /Joe
>     _______________________________________________
>     erlang-questions mailing list
>     erlang-questions@REDACTED <mailto:erlang-questions@REDACTED>
>     http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list