2015-06-05 12:34 GMT+02:00 Alfred E. Heggestad <aeh at db.org>: > > > On 05/06/15 11:20, Lorenzo Miniero wrote: > >> 2015-06-05 10:31 GMT+02:00 Matt Caswell <matt at openssl.org <mailto: >> matt at openssl.org>>: >> >> >> >> >> On 05/06/15 08:09, Lorenzo Miniero wrote: >> > Hi all, >> > >> > first of all, apologies if this has been asked before. I've >> searched >> > archives pretty much everywhere, and only came to partial >> indications as >> > to how this should be dealt with. >> > >> > The problem I'm facing deals with using DTLS with mem BIOs, as I >> have to >> > take care of transport myself. Specifically, I've implemented a >> WebRTC >> > gateway called Janus, which means all the connectivity related >> stuff is >> > delegated to another library (libnice in this case). This mostly >> works >> > great (kudos to you guys!), but I have problems as soon as packets >> > exceed the MTU, which can easily happen whenever, for instance, >> you try >> > to handshake with certificates larger than 1024 bits. I read >> around that >> > the DTLS stack in OpenSSL automatically deals with this, and in >> fact >> > this seems to be happening: what isn't working is the BIO mem part >> of this. >> > >> > More specifically, OpenSSL does indeed take care of fragmenting the >> > packets according to what is assumed to be the MTU (1472 by >> default, or >> > the value as set in s->d1->mtu). The problem is that the mem BIO >> ignores >> > that fragmentation info completely, and so, when you do an >> BIO_read, >> > makes available at the application the whole packet anyway. This >> results >> > in the whole buffer being passed to nice_agent_send (the method >> libnice >> > exposes to send packets), which means it's just as not fragmenting >> > anything: the packet is too large and the network drops it. You can >> > verify this by using, e.g., a 4096 bits certificate, and capture >> the >> > DTLS traffic with Wireshark: you'll see that the message is >> recognized >> > as composed of not only multiple messages, but also fragments. >> > >> > Is there any way I can force the BIO to return the invididual >> > fragments/messages when I do a BIO_read, so that I can send >> properly >> > sized packets? I've tried looking around but found no insight on >> how to >> > do that. The only approach that came to my mind was to manually >> inspect >> > the buffer that is returned, and split messages/fragments myself, >> but >> > I'd rather avoid delving within the specifics of the protocol if >> possible. >> > >> > Thanks in advance for any help you may provide me with! >> >> Hmmmm. An interesting problem. >> >> The issue is that a mem BIO has no knowledge of datagram semantics >> (perhaps we need to add something for OpenSSL 1.1.0). >> >> In a dgram BIO each BIO_write translates to a single datagram being >> produced. In a mem BIO you just have a big bucket of memory, and every >> time you get a BIO_write you just add the data onto the end of >> everything that we've go so far, and so the packet boundaries are not >> respected. >> >> How about you create a custom filter BIO? All it would need to do is >> proxy all calls down to the underlying mem BIO. Along the way though >> it >> could take note of where the packet boundaries are, so when you call >> BIO_read it only gives it to you a datagram at a time. >> >> Matt >> >> >> >> Thanks for the very quick answer! >> >> Your suggestion does indeed make much more sense that manually inspecting >> the buffer as I thought of, as you don't need to know anything about the >> protocol but >> only to be ready to index the packets you see passing by. I never tried >> writing a BIO filter but there's a first time for everything :-) >> >> 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? >> >> > > hey, > > > I just want to point out that we have been using OpenSSL in the libre > stack for > a long time, with successful deployment. > > > the DTLS code is here: > > http://www.creytiv.com/doxygen/re-dox/html/tls__udp_8c_source.html > > > we are using 2 different BIOs; one for outgoing, one for incoming: > > > > tc->sbio_in = BIO_new(BIO_s_mem()); > if (!tc->sbio_in) { > ERR_clear_error(); > err = ENOMEM; > goto out; > } > > tc->sbio_out = BIO_new(&bio_udp_send); > if (!tc->sbio_out) { > ERR_clear_error(); > BIO_free(tc->sbio_in); > err = ENOMEM; > goto out; > } > > > Hi Alfred, thanks for sharing this. So you've basically created a new BIO source/sink type, and you use that one instead of a mem BIO for sending, right? That might be an interesting approach (e.g., creating a custom BIO based on BIO mem), especially if it turns out that implementing a filter will prove harder than I hope. Lorenzo -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20150605/5cc68ba9/attachment-0001.html>