2222#include <gnutls/x509.h>
2323#include <rfb/rfbclient.h>
2424#include <errno.h>
25- #ifdef WIN32
26- #include <windows.h> /* for Sleep() */
27- #define sleep (X ) Sleep(1000*X) /* MinGW32 has no sleep() */
28- #endif
2925#include "tls.h"
3026
3127
@@ -228,6 +224,27 @@ PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len)
228224 }
229225}
230226
227+ static int
228+ PullTimeout (gnutls_transport_ptr_t transport , unsigned int timeout )
229+ {
230+ rfbClient * client = (rfbClient * )transport ;
231+ int ret ;
232+
233+ while (1 )
234+ {
235+ ret = gnutls_system_recv_timeout ((gnutls_transport_ptr_t )(long )client -> sock , timeout );
236+
237+ if (ret < 0 )
238+ {
239+ #ifdef WIN32
240+ WSAtoTLSErrno ((gnutls_session_t * )& client -> tlsSession );
241+ #endif
242+ if (errno == EINTR ) continue ;
243+ }
244+ return ret ;
245+ }
246+ }
247+
231248static rfbBool
232249InitializeTLSSession (rfbClient * client , rfbBool anonTLS )
233250{
@@ -252,6 +269,9 @@ InitializeTLSSession(rfbClient* client, rfbBool anonTLS)
252269 gnutls_transport_set_push_function ((gnutls_session_t )client -> tlsSession , PushTLS );
253270 gnutls_transport_set_pull_function ((gnutls_session_t )client -> tlsSession , PullTLS );
254271
272+ gnutls_transport_set_pull_timeout_function ((gnutls_session_t )client -> tlsSession , PullTimeout );
273+ gnutls_handshake_set_timeout ((gnutls_session_t )client -> tlsSession , 15000 );
274+
255275 INIT_MUTEX (client -> tlsRwMutex );
256276
257277 rfbClientLog ("TLS session initialized.\n" );
@@ -279,27 +299,16 @@ SetTLSAnonCredential(rfbClient* client)
279299static rfbBool
280300HandshakeTLS (rfbClient * client )
281301{
282- int timeout = 15 ;
283302 int ret ;
284303
285- while (timeout > 0 && (ret = gnutls_handshake ((gnutls_session_t )client -> tlsSession )) < 0 )
304+ while ((ret = gnutls_handshake ((gnutls_session_t )client -> tlsSession )) < 0 )
286305 {
287306 if (!gnutls_error_is_fatal (ret ))
288307 {
289- rfbClientLog ("TLS handshake blocking.\n" );
290- sleep (1 );
291- timeout -- ;
308+ rfbClientLog ("TLS handshake got a temporary error: %s.\n" , gnutls_strerror (ret ));
292309 continue ;
293310 }
294- rfbClientLog ("TLS handshake failed: %s.\n" , gnutls_strerror (ret ));
295-
296- FreeTLS (client );
297- return FALSE;
298- }
299-
300- if (timeout <= 0 )
301- {
302- rfbClientLog ("TLS handshake timeout.\n" );
311+ rfbClientLog ("TLS handshake failed: %s\n" , gnutls_strerror (ret ));
303312 FreeTLS (client );
304313 return FALSE;
305314 }
0 commit comments