[openssl-users] DTLS fragmentation and mem BIO

Lorenzo Miniero lminiero at gmail.com
Fri Jun 5 11:34:17 UTC 2015


2015-06-05 12:30 GMT+02:00 Matt Caswell <matt at openssl.org>:

>
>
> On 05/06/15 10:20, Lorenzo Miniero wrote:
> > Just one quick question about this: are messages/packets passed to the
> > BIO actually splitted, and then just queued by the mem BIO in the
> > buffer, or can there be cases where a larger than normal buffer is
> > passed to the BIO anyway, meaning a manual splitting could be needed
> > nevertheless from time to time?
>
> No, there should be no need for the BIO to do any splitting. Everything
> that gets written to the BIO should be a datagram.
>
> One issue that does spring to mind is that in your filter BIO you may
> want to implement some of the dgram ctrls that DTLS uses. This depends
> on how you want to manage setting your MTU.
>
> Do you set an MTU size explicitly using SSL_set_mtu(ssl, mtu) or
> DTLS_set_link_mtu(ssl, mtu)? Also, do you set the option
> SSL_OP_NO_QUERY_MTU? If you use the option then you should set an MTU
> size explicitly.
>
> If you don't set the SSL_OP_NO_QUERY_MTU option then the DTLS code will
> attempt to query the underlying BIO for information about the mtu size.
> That would mean you would have to implement the following additional ctrls:
> BIO_CTRL_DGRAM_GET_FALLBACK_MTU - returns a "default" MTU size if
> querying fails for some reason
> BIO_CTRL_DGRAM_QUERY_MTU - queries the transport for the MTU size to be
> used
> BIO_CTRL_DGRAM_SET_MTU - sets the MTU size on the underlying transport
> BIO_CTRL_DGRAM_MTU_EXCEEDED - returns true if the datagram we just tried
> to send failed because we exceeded the max MTU size
>
> Matt
>
>
Hi Matt,

thanks for the clarification and for the hints.

I've started looking into filters and I have some doubts, though, also
taking into account what you suggested, and I apologize again if this turns
out to be silly. As far as I've understood, what I should do is changing
the current pattern I use for outgoing packets:

      application < memBIO < ssl

to something like this:

      application < memBIO < filter < ssl

or this:

      application < filter < memBIO < ssl

that is, a new BIO filter that enforces the fragmentation I talked about.
Not exactly sure about which one should be the way to go, but I've given
this some thought.

The first one seems conceptually correct, in the sense that the filter
receives the properly sized packets from the stack; I see issues in how to
progressively make them available to the memBIO, though, especially
considering that we cannot "relay" a BIO_read call (that is, have the mem
BIO ask for data to the next BIO in the chain when data is requested). My
guess, looking at the BIOs code, is that this is all asynchronous, that is,
the DTLS stack issues a BIO_write that reaches the filter, and then it's
the filter that forwards the written data (modified or not) to the next
BIO, in this case the mem one, using another BIO_write. My concern here is
how to figure out when to issue such a write: in fact, if we want to make
sure that the mem BIO never returns too much data when a BIO_read is
issued, we should never issue a new BIO_write to feed it with new data from
the filter until the previous one has been read, something we cannot do if
we don't know when the data has been read in the first place.

The second one, as a consequence, may actually be more suited for the
purpose, as we can always only return what we want to in a BIO_read. The
issue there is what I mentioned in my previous post, that is, my fear being
that the memBIO could feed too much data to my filter in a BIO_write, which
would force my filter to inspect the payload and manually split packets as
I'd do in my application. But according to what you said at the beginning
of your reply, this shouldn't be the case, right? That is, the DTLS stack
will issue different BIO_writes towards the memBIO for each
packet/fragment, and this would automatically we forwarded to my filter, am
I correct? Since in this case there wouldn't be any explicit BIO_read done
from the application that may return what's been buffered so far.

Apologies if I'm adding confusion with these questions, I'm just trying to
figure out the best approach to the new filter. As an alternative, I guess
I could just extend the existing mem BIO to a new, custom BIO, and handle
it all there, but my feeling is that a filter would be a cleaner way to do
that.

Thanks again!
Lorenzo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20150605/89698652/attachment.html>


More information about the openssl-users mailing list