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