[gnutls-devel] GnuTLS | kTLS gets desynchronised when sending (in gnutls_record_send) (#1470)
Read-only notification of GnuTLS library development activities
gnutls-devel at lists.gnutls.org
Fri Mar 10 11:40:52 CET 2023
Richard W_M_ Jones commented:
I think I may understand the problem. I collected an `strace` of the server when the desynchronisation happens, and the pattern of syscalls is odd. We see:
```
sendmsg(7, {msg_name=NULL, msg_namelen=0, msg_iov=[{... iov_len=262144}], msg_iovlen=1, msg_control=[{cmsg_len=17, cmsg_
level=SOL_TLS, cmsg_type=0x1}], msg_controllen=17, msg_flags=0}, MSG_DONTWAIT = 245760
```
In other words, a short write. We wanted to send 262144 bytes, but only sent 245760 (16K less).
Then I see:
```
sendmsg(7, {msg_name=NULL, msg_namelen=0, msg_iov=[{... iov_len=16384}], msg_iovlen=1, msg_control=[{cmsg_len=17, cmsg_level=SOL_TLS, cmsg_type=0x1}], msg_controllen=17, msg_flags=0}, MSG_DONTWAIT = -1 EAGAIN (Resource temporarily unavailable)
```
It's trying to follow on with the remaining 16K of data, and gets EAGAIN. But immediately after:
```
sendmsg(7, {msg_name=NULL, msg_namelen=0, msg_iov=[{... iov_len=262144}], msg_iovlen=1, msg_control=[{cmsg_len=17, cmsg_level=SOL_TLS, cmsg_type=0x1}], msg_controllen=17, msg_flags=0}, MSG_DONTWAIT= -1 EAGAIN (Resource temporarily unavailable)
```
It's trying to send the full block (the data is the same as before) again, which is definitely wrong.
The documentation for `GNUTLS_E_INTERRUPTED` is quite confusing to be honest:
> If the EINTR is returned by the internal push function then GNUTLS_E_INTERRUPTED will be returned. If GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned, you must call this function again with the exact same parameters, or provide a NULL pointer for data and 0 for data_size , in order to write the same data as before. If you wish to discard the previous data instead of retrying, you must call gnutls_record_discard_queued() before calling this function with different parameters. Note that the latter works only on special transports (e.g., UDP). cf. gnutls_record_get_direction().
Our code is here, and I think it's doing the right thing but I'm not certain of it:
https://gitlab.com/nbdkit/nbdkit/-/blob/45b72f5bd8fc1b475fa130d06c86cd877bf595d5/server/crypto.c#L399
--
Reply to this email directly or view it on GitLab: https://gitlab.com/gnutls/gnutls/-/issues/1470#note_1308821019
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gnutls-devel/attachments/20230310/a5ad90bd/attachment-0001.html>
More information about the Gnutls-devel
mailing list