LibVNC / libvncserver

LibVNCServer/LibVNCClient are cross-platform C libraries that allow you to easily implement VNC server or client functionality in your program.
GNU General Public License v2.0
1.08k stars 483 forks source link

slow TLS handshake (2 seconds) when gnutls is used #525

Closed dinutine closed 1 year ago

dinutine commented 2 years ago

gnutls_handshake returns GNUTLS_E_AGAIN, when it is waiting for data to be received by the server. gnutls_handshake should be called again when new data is received (as soon as possible)

Suggestion: replace the sleep of 1 second with a poll on the tcp socket with a 1000ms timeout

diff --git a/libvncclient/tls_gnutls.c b/libvncclient/tls_gnutls.c
index a87baf2..964a675 100644
--- a/libvncclient/tls_gnutls.c
+++ b/libvncclient/tls_gnutls.c
@@ -22,6 +22,7 @@
 #include <gnutls/x509.h>
 #include <rfb/rfbclient.h>
 #include <errno.h>
+#include <poll.h>
 #ifdef WIN32
 #include <windows.h>           /* for Sleep() */
 #define sleep(X) Sleep(1000*X) /* MinGW32 has no sleep() */
@@ -286,8 +287,14 @@ HandshakeTLS(rfbClient* client)
   {
     if (!gnutls_error_is_fatal(ret))
     {
-      rfbClientLog("TLS handshake blocking.\n");
-      sleep(1);
+      rfbClientLog("TLS handshake blocking, ret=%d.\n", ret);
+
+      // wait until new data is received on the socket
+      struct pollfd poll_fd;
+      poll_fd.fd = client->sock;
+      poll_fd.events = POLLIN;
+      poll_fd.revents = 0;
+      poll(&poll_fd, 1, 1000);
       timeout--;
       continue;
     }
-- 
bk138 commented 2 years ago

I reckon this won't work on Win32. Why not simply shorten the sleep?

mdevaev commented 2 years ago

I tried to fix it the right way (lol) with native GNUTLS timeouts #531