]> code.delx.au - gnu-emacs/commitdiff
Ensure TLS negotiation progress
authorLars Ingebrigtsen <larsi@gnus.org>
Thu, 3 Mar 2016 05:14:48 +0000 (05:14 +0000)
committerLars Ingebrigtsen <larsi@gnus.org>
Thu, 3 Mar 2016 05:14:55 +0000 (05:14 +0000)
* 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
src/process.c

index d03332ec2b6b01d0ef98b60603882177a911af7f..7418f8f84f45b283dfafeb1420c4dac86672f972 100644 (file)
@@ -25,8 +25,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #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
 {
index 85a4885bbf46a84a2de1ea738ae9c1f5fb13025d..4359f681b452c305b38495a4c5478edc2edbac73 100644 (file)
@@ -120,6 +120,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #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)