[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