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("193.11.25.99")}}, [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.
/Fredrik
More information about the erlang-questions
mailing list