From 0c5c04d58e4efc04905a3f42e984d5f24c554a34 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Thu, 3 Mar 2016 05:14:48 +0000 Subject: [PATCH] Ensure TLS negotiation progress * src/gnutls.h (GNUTLS_EMACS_HANDSHAKES_LIMIT): Increase the number of retries so that we try for about a minute. * src/process.c (wait_reading_process_output): Ensure progress for DNS resolution and TLS negotiation. --- src/gnutls.h | 5 +++-- src/process.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/gnutls.h b/src/gnutls.h index d03332ec2b6..7418f8f84f4 100644 --- a/src/gnutls.h +++ b/src/gnutls.h @@ -25,8 +25,9 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" -/* This limits the attempts to handshake per process (connection). */ -#define GNUTLS_EMACS_HANDSHAKES_LIMIT 100 +/* This limits the attempts to handshake per process (connection). It + should work out to about one minute in asynchronous cases. */ +#define GNUTLS_EMACS_HANDSHAKES_LIMIT 6000 typedef enum { diff --git a/src/process.c b/src/process.c index 85a4885bbf4..4359f681b45 100644 --- a/src/process.c +++ b/src/process.c @@ -120,6 +120,11 @@ along with GNU Emacs. If not, see . */ #endif #endif +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS +/* This is 0.1s in nanoseconds. */ +#define ASYNC_RETRY_NSEC 100000000 +#endif + #ifdef WINDOWSNT extern int sys_select (int, fd_set *, fd_set *, fd_set *, struct timespec *, void *); @@ -4870,6 +4875,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, struct timespec got_output_end_time = invalid_timespec (); enum { MINIMUM = -1, TIMEOUT, INFINITY } wait; int got_some_output = -1; +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS + bool retry_for_async; +#endif ptrdiff_t count = SPECPDL_INDEX (); /* Close to the current time if known, an invalid timespec otherwise. */ @@ -4922,6 +4930,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, Lisp_Object process_list_head, aproc; struct Lisp_Process *p; + retry_for_async = false; FOR_EACH_PROCESS(process_list_head, aproc) { p = XPROCESS (aproc); @@ -4935,6 +4944,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, Lisp_Object ip_addresses = check_for_dns (aproc); if (!NILP (ip_addresses) && !EQ (ip_addresses, Qt)) connect_network_socket (aproc, ip_addresses); + else + retry_for_async = true; } #endif #ifdef HAVE_GNUTLS @@ -4950,12 +4961,16 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, gnutls_verify_boot (aproc, Qnil); finish_after_tls_connection (aproc); } - else if (p->gnutls_handshakes_tried - > GNUTLS_EMACS_HANDSHAKES_LIMIT) + else { - deactivate_process (aproc); - pset_status (p, list2 (Qfailed, - build_string ("TLS negotiation failed"))); + retry_for_async = true; + if (p->gnutls_handshakes_tried + > GNUTLS_EMACS_HANDSHAKES_LIMIT) + { + deactivate_process (aproc); + pset_status (p, list2 (Qfailed, + build_string ("TLS negotiation failed"))); + } } } #endif @@ -5222,6 +5237,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) now = invalid_timespec (); +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS + if (retry_for_async + && (timeout.tv_sec > 0 || timeout.tv_nsec > ASYNC_RETRY_NSEC)) + { + timeout.tv_sec = 0; + timeout.tv_nsec = ASYNC_RETRY_NSEC; + } +#endif + #if defined (HAVE_NS) nfds = ns_select #elif defined (HAVE_GLIB) -- 2.39.2