From: Hyman Huang <yong.hu...@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;
+    }
     if (len < 0 && errno != ENOMSG) {
         virReportSystemError(errno, "%s",
                              _("Unable to read TLS confirmation"));
-- 
2.27.0

Reply via email to