On Tue, Apr 08, 2025 at 12:55:04AM +0800, yong.huang(a)smartx.com wrote:
From: Hyman Huang <yong.huang(a)smartx.com>
If EAGAIN or EINTR are returned from the gnutls_record_recv,
GNU TLS suggests calling the gnutls_record_recv once again to
get the data. Refer to the following link to see details:
https://www.gnutls.org/manual/html_node/Data-transfer-and-termination.html
To follow this guidance, add the re-read logic in the
virNetClientSetTLSSession function. This prevent the upper application,
when calling the virConnectOpenAuth API, from receiving the
follwoing error message:
Unable to read TLS confirmation: Resource temporarily unavailable
---
src/rpc/virnetclient.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 92933220e2..69b8cac481 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1003,7 +1003,16 @@ int virNetClientSetTLSSession(virNetClient *client,
ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
#endif /* !WIN32 */
+ reread:
len = virNetTLSSessionRead(client->tls, buf, 1);
+ /*
+ * GNU TLS advises calling the function again to obtain the data if EAGAIN is
returned.
+ * See reference:
https://www.gnutls.org/manual/html_node/Data-transfer-and-termination.html
+ * */
+ if (len < 0 && (errno == EAGAIN || errno == EINTR)) {
+ VIR_WARN("Try reading data from the TLS session again");
+ goto reread;
+ }
This would surely be wrong for EAGAIN - if the socket is blocking we must
return to the main loop and wait for it to indicate that the socket has
new data. If we don't wait in the main loop, this code will busy-loop on
a non-blocking socket
if (len < 0 && errno != ENOMSG) {
virReportSystemError(errno, "%s",
_("Unable to read TLS confirmation"));
--
2.27.0
With regards,
Daniel
--
|:
https://berrange.com -o-
https://www.flickr.com/photos/dberrange :|
|:
https://libvirt.org -o-
https://fstop138.berrange.com :|
|:
https://entangle-photo.org -o-
https://www.instagram.com/dberrange :|