UDP over v6: payload truncated at 1024 bytes

Fredrik Thulin ft@REDACTED
Mon Apr 5 15:21:19 CEST 2004

On Monday 05 April 2004 14.35, Luke Gorrie wrote:
> Fredrik Thulin <ft@REDACTED> writes:
> > I've started using IPv6 in my Erlang application and have encountered a
> > problem. I open a listening socket like this :
> [...]
> > Packet is truncated at 1024 bytes. If I don't use inet6, and send the
> > same sized packet over ordinary IPv4 UDP then it does not get truncated.
> I don't know anything about the actual problem, but I think the next
> step is to run 'strace' on the beam process to see the system call it
> makes to receive the packet and what that returns.

Good idea, didn't think of that. Please read all of this message, it gets 
interesting near the end.

On the sending side, I did (using the erl prompt) :

	Data = lists:duplicate(1300, " ").
	{ok, S} = gen_udp:open(5000, [{reuseaddr, true}, inet6]).
	gen_udp:send(S, "2001:6b0:5:987:210:dcff:fe2a:65ab", 5060, Data).

on the receiving host, this was seen using tcpdump as :

15:03:42.439704 2001:6b0:5:987:210:dcff:fe2a:618a.5000 > 
	2001:6b0:5:987:210:dcff:fe2a:65ab.5060: udp 1300

My application once again received 1024 bytes of data, and the strace shows 
the following interesting output :

recvfrom(16, "                                "..., 1024, 0, 
	{sin_family=AF_INET6, sin6_port=htons(5000), inet_pton(AF_INET6, 
	"2001:6b0:5:987:210:dcff:fe2a:618a", &sin6_addr), sin6_flowinfo=0, 
	sin6_scope_id=0}, [28]) = 1024
recvfrom(16, 0x81b7db8, 1024, 0, 0xbffff060, 0xbffff03c) = -1 EAGAIN 
	(Resource temporarily unavailable)

It seems to me like Erlang is reading data in 1024 byte chunks using 
recvfrom(). My recvfrom(2) man-page says

>If a message is too long to fit  in  the  supplied  buffer,  excess
>bytes may be discarded depending on the type of socket the message is 
>received from (see socket(2)).

If that is the problem here, then I guess Erlang should recvfrom() into a 
buffer of 64kb to not loose any data. Of course, it is not very wise to send 
that large UDP packets...

When I did the same test (sending and receiving hosts are the same) using v4, 
this is what the strace shows me :

recvfrom(15, "                                "..., 8192, 0, 
	{sin_family=AF_INET, sin_port=htons(5001), 
	sin_addr=inet_addr("")}}, [16]) = 1300
recvfrom(15, 0x81b7db8, 8192, 0, 0xbffff060, 0xbffff03c) = -1 EAGAIN 
	(Resource temporarily unavailable)

So it seems Erlang uses a 8k buffer for v4 and 1k buffer for v6. That does not 
seem right. In fact, since the biggest UDP datagram size is 64k I think the 
buffer ought to be 64k for both v4 and v6.


More information about the erlang-questions mailing list