Mbedtls_ssl_write: partial writes

It seems one is able to retrieve ‘chunks’ of a single datagram via repeated calls to mbed_ssl_read with a len smaller than the full datagram size.

Is it possible to feed chunks to mbedtls_ssl_write somehow in a similar manner? The documentation indicates only one full outgoing buffer will do.

@malachi,
If you look at the code, you will see that if you try to write a buffer that is larger than the the maximal length you can write, in DTLS you will fail.

If you are referring to fragmantation in the DTLS layer, this is not supported yet.

However, if you call mbedtls_ssl_write() with differnt chunks of the same buffer, it should work, as long you have support on the remote peer, that will know how to assemble the chunks into one buffer. Note that since this is an unreliable transport layer, some packets might get lost or arrive in a different order. If you don’t have control on the remote peer, I doubt this will work.

In other words, although technically you will be able to sends the chunks, unless you have a way to reassemble those chunks in the remote peer, in the application layer ( note that the buffer is fragmented to chunks in the application layer), you might get unexpected results.
Regards,
Mbed TLS Team member,
Ron

Hi @roneld01, thanks for the fast response - I think there is a miscommunication here.

Although I am eagerly anticipating the DTLS fragmentation feature, the use case I’m describing here is simpler.

So yes, the API documentation for mbedtls_ssl_write indicates that ‘chunked’ writes will behave as you describe, generate distinct datagrams per write. My question specifically is is there a way to ‘build up’ just one datagram in this chunked way before sending it?

Hi @malachi,
If you want to send a single datagram but call several times mbedtls_ssl_write() with different chunks, the current implementation of Mbed TLS does not support it, however I have a suggestion:
You can supply your own send callback function to the mbedtls_ssl_set_bio() API, that will accumulate the chunks, into one buffer. You will probably need to add 16 bits for buffer length to the first chunk, so you will know how to accumulate, ignoring those 16 bits in the accumulation. Once all the chunks were accumulated, and the datagram reassembled, you will send it.
Of course, the total can’t exceed MBEDTLS_SSL_MAX_CONTENT_LEN ( or MBEDTLS_SSL_OUT_CONTENT_LEN in the next release). I am a bit puzzled by your query though, as this will not save RAM , as you will need a buffer in the stack to accumulate the data. ( It might work if you utilize the ssl->out_msg and modify ssl->out_msglen at the end with the total accumulated length ).
Note I haven’t tried this suggestion, and there might be some hickups along the way that I haven’t thought of at the moment.
Regards,
Mbed TLS Team member
Ron

It’s true, in the use case you present there would be little gain, since the bio-level buffer still needs to be fully ‘unchunked’.

If the native mbedtls_ssl_write itself could take chunks, then a full bio-level buffer would not be necessary, so a potential savings could occur.

My own use case is we have a state machine which can encode in very small chunks at a time, so preallocating the entire buffer is technically a waste. Fortunately, we have enough memory for that.

You’ve answered my question and I do appreciate it. Perhaps a future flavor of mbedtls_ssl_write can provide this capability.