On Aug 11, 2009, at 3:47 PM, Daniel Mentz wrote:
Thanks David and Michael for your answers.
I should have pointed out in my original e-mail that I assume that
the DF (Don't Fragment) bit is set at all times. Sure, you could use
IP fragmentation and that works fine under some circumstances. But I
don't want to rely on that due to the reasons outlined in Nagendra
Modadugu's Paper. See also "Fragmentation Considered Harmful" by
Kent and Mogul.
DTLS should do PMTU discovery and provide the result to the application.
Then it is up to the application to respect this value.
The PTMU discovery currently does not work in OpenSSL.
However, if I think if the application sends larger messages,
IP fragmentation should kick in.
OpenSSL's implementation of DTLS always tries to guess the correct
PMTU. If you want to use IP fragmentation you must set this PMTU
estimate to a fake value that is pretty big. By doing so you can
trick OpenSSL into sending UDP messages that are large enough to
trigger IP fragmentation.
To avoid IP fragmentation DTLS has its very own fragmentation
mechanism on and only on the handshake layer. DTLS does not provide
fragmentation for user messages. So what happens if the application
tries to send a user message that is bigger than OpenSSL's PMTU
estimate would allow? OpenSSL cuts it into pieces which is a bug in
my opinion.
We should remove the code from OpenSSL that slices user messages.
I agree with Michael that the DTLS implementation should fail send
calls if the user message does not fit into one DTLS record. If it
fits it should just go ahead and call send(). Just in case the
resulting UDP datagram is too big the send() call will fail and the
error propagates back to the caller. If IP fragmentation kicks in
and the datagram gets lost or dropped on its way because some
firewall dislikes IP fragments then that's fine as well because
that's the same as plain UDP.
Agreed. I'll send a patch which you can test.
-Daniel
Michael Tüxen wrote:
Hi Daniel,
the UDP behaviour is a follows: If a user sends a UDP message which
is
larger than the PMTU, but does fit into the send buffer, it is
accepted
by the kernel, fragmented by the IP layer and transmitted. If the
size is larger than the send buffer, the send call fails since the
send operation for UDP is atomic.
On FreeBSD you can control the maximum UDP message size using the
net.inet.udp.maxdgram sysctl variable.
More comments in-line.
Best regards
Michael
On Aug 10, 2009, at 10:21 AM, Daniel Mentz wrote:
In my understanding DTLS should provide UDP semantics when run
over the later. That is if a user message is too large in terms of
the PMTU it should either be silently discarded or the sender
should be notified by an error message similar to "Message too big".
I think if the UDP accepts the resulting message it should be sent,
if it is too large, an
error should be returned.
In no event should the message be fragmented and delivered to the
receiving application in more than one piece. It might be
acceptable that only a prefix is delivered but other than that
only the message as a whole or no message should be delivered.
The DTLS layer must not do any fragmentation. This is a bug.
But OpenSSL is doing exactly this: dtls1_write_app_data_bytes() in
d1_pkt.c fragments user messages if the (guessed) MTU is too small
to transmit the message in one piece. The receiving application
has no way to figure out if a message received by using SSL_read()
is a complete message or only a fragment of a message. Also, it's
impossible to find out which fragment was read and if all
fragments needed for reassembly were transmitted.
In my concrete setting I'm running OpenSSL on FreeBSD and try to
transmit a user message of say 2000 bytes. With no way of figuring
out the correct PMTU on FreeBSD OpenSSL makes an educated (wrong)
guess of 1472 and uses it to slice the message into chunks of
appropriate size. Since I'm using the loopback interface I can
transmit datagrams bigger than this.
The receiving application gets only junk: The first fragment can
not be processed because it was truncated. All remaining fragments
can not be used as well because they do not form a legitimate
message.
My suggestion is to return an error message in that case or just
to go ahead and send the message anyway. The socket interface will
eventually return a (correct) error message if OpenSSL tries to
send a packet too big for the PMTU.
This would make debugging easier. It took me some time to figure
out why I was receiving junk on the receiving end although DTLS
provides HMAC for integrity control.
After careful consideration I even think that this is a protocol
violation because the integrity of the message is indeed corrupted
although DTLS aims to guarantee integrity.
The situation with SCTP is slightly different: It sets the MTU to
an artificial value of 16384 because SCTP provides fragmentation
and reassembly on the transport layer. But if you send messages
bigger than that then your messages get fragmented again.
The DTLS/SCTP implementation must fail send calls when user
messages do not
fit into a DTLS record.
Please let me know your opinions.
Do you agree?
-Daniel
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]
______________________________________________________________________
OpenSSL Project http://
www.openssl.org
Development Mailing List openssl-
[email protected]
Automated List Manager
[email protected]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]