Non-blocking calls to transport layer I/O
I’m using PolarSSL 1.2.6 on a non OS embedded platform, supporting a https server for remote access to setup web pages etc. on the server/embedded system. My non OS environment can not handle blocking functions, and I’ve invested quite a lot of time in integrating the 1.2.6. ssl_tls/ssl_srv core functionality to a non-blocking style of execution. Therefore I’m pretty much committed to my current 1.2.6 version, and I’m reluctant to upgrade to newer versions, if they don’t support non-blocking calls to transport layer. So, my question is, does any of the newer versions support non-blocking calls, or is any such version planned? Thanks,
As I replied in the other thread both the current 2.x stable/development branch and the 1.3 stable/maintenance branch support non-blocking I/O. All you need to do is provide non-blocking functions to
mbedtls_ssl_set_bio() and make sure they return the right codes for "not available now, would block, please try again later", namely
MBEDTLS_ERR_SSL_WANT_WRITE in the 2.x branch.
We have automated tests for non-blocking I/O and for all new features that involve I/O in SSL/TLS, we add tests with both blocking and non-blocking I/O. As such, I would consider our support of non-blocking I/O in the 1.3 and 2.x branches quite stable.
If support for non-blocking I/O is the main reason why you didn't upgrade yet, I think you can upgrade with confidence.
Thanks, Sorry for double-posting this question, but after posting in the other thread, I thought the question and the topic didn’t relate and could cause confusion. I will strongly consider an upgrade to either 1.3 or 2.x Best Regards Anders
No problem with double-posting, you're right, it's clearer in its own thread.
Please let us know if you encounter any issue with your migration!
I've successfully used mbedTLS with async IO (using IO completion ports on Windows), so while not exactly straight forward, it is quite doable.
When performing an mbedTLS read/write/handshake operation I check for WANT_READ and WANT_WRITE, and issue an async read/write operation respectively. When async read/write operations complete, I retry the mbedTLS read/write/handshake operation.
Read callback is pretty plain, async reads are done into an internal read-buffer, and in the read callback I just return what I got in my read-buffer or WANT_READ.
For writes I'm switching between two different callback functions: one stores the buffer info (pointer and length) and simply returns WANT_WRITE, which will trigger the async write of the entire buffer. The other returns the number of bytes actually written during the async write. Each one also changes the active write callback to the other one.