Thank you for quick response.
Are you using blocking or non-blocking I/O?
Non-blocking IO I've preset bio_send/recv callbacks I have pair of buffers, transport buffer and application buffer, for reading and writing (4 buffers total). Application buffers are protected by mutexes. Transport buffers are written/read in bio_send/recv (if no async op pending, otherwise WANT_READ/WRITE). mbedtls_ssl_xxx work with application buffers.
Are you using TLS or DTLS? What protocol version, what cipher suite
and what extensions are negotiated? TLS (over tcp, no lossy channel involved) version 1.2
Does your application call mbedtls_ssl_write() and mbedtls_ssl_read()
again with the same buffer if they return MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE? Well, actually, no. AND it's quite possible, that application outgoing buffer (std::vector) has been relocated between mbedtls_ssl_write calls, because app could push data several times while async op was pending and bio_send returned WANT_WRITE, causing these buffers to resize. So buf.data() will not be equal to that from previous mbedtls_ssl_write call. Is this what causes trouble? It's somehow connected to partial sends? I do call ssl_write inside while-loop, counting sent and unsent bytes - thought this was enough. But if mbedtls somehow remembers addresses from previos calls - that might cause problems.
Do you close the TLS connection if mbedtls_ssl_xxx() returns an error
other than WANT_XXX (or XXX_IN_PROGRESS if you use these features)? Yes, but that never happens (from handshake to until problem appears)
What is the value of MBEDTLS_SSL_MAX_CONTENT_LEN (or
MBEDTLS_SSL_OUT_CONTENT_LEN if it's defined)? Not defined in config, looks like both 16834
What operating system are you using?
Ubuntu 20, Kali 20
Is this a client or a server? What TLS stack does the other side run?
Both are written same way, both using same library.
I'll try to prepare test-case code, that reproduces the problem, and logs, but that will require some time.
10.12.2020 1:07, Gilles Peskine via mbed-tls пишет:
Hi Андрей,
The behavior you describe is a bug. But there isn't enough information to tell whether the bug is in Mbed TLS, in asio-standalone, in some other third-party code, or in your application.
Some things to consider:
- Are you using blocking or non-blocking I/O?
- Are you using TLS or DTLS? What protocol version, what cipher suite
and what extensions are negotiated?
- Does your application call mbedtls_ssl_write() and mbedtls_ssl_read()
again with the same buffer if they return MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE?
- Do you close the TLS connection if mbedtls_ssl_xxx() returns an error
other than WANT_XXX (or XXX_IN_PROGRESS if you use these features)?
- What is the value of MBEDTLS_SSL_MAX_CONTENT_LEN (or
MBEDTLS_SSL_OUT_CONTENT_LEN if it's defined)?
- What operating system are you using?
- Is this a client or a server? What TLS stack does the other side run?
You'll give others the most chance to help you if you post small, complete code to reproduce the problem. I realize this may be difficult. A good intermediate way to see what is going on would be to post debug logs. To get debug logs, make sure that MBEDTLS_DEBUG_C is enabled and call these functions before opening the TLS connection:
mbedtls_ssl_conf_dbg(&ssl_conf, my_debug, stdout); mbedtls_debug_set_threshold(2);
See https://tls.mbed.org/kb/how-to/mbedtls-tutorial for a sample version of my_debug().
Calls to bio_send() are shown in the logs as
=> flush output message length: %d, out_left: %d ssl->f_send() returned %d <= flush output
If they don't show expected numbers, the rest of the logs should give a clue as to why.
Hope this helps,