[openssl-users] DTLS fragmentation and mem BIO

Lorenzo Miniero lminiero at gmail.com
Fri Jun 5 16:12:17 UTC 2015

Eureka, I got it working! Thanks to the feedback from Matt and Alfred, I
managed to create a filter that does what I need. To those who may be
interested, it's available here:


Thanks for your great support!

2015-06-05 13:34 GMT+02:00 Lorenzo Miniero <lminiero at gmail.com>:

> 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/e79a7e03/attachment-0001.html>

More information about the openssl-users mailing list