unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async connection
@ 2016-07-14 14:17 Jun Hao
  2016-07-16  3:33 ` npostavs
  2016-07-26  7:35 ` Paul Eggert
  0 siblings, 2 replies; 10+ messages in thread
From: Jun Hao @ 2016-07-14 14:17 UTC (permalink / raw)
  To: 23982

[-- Attachment #1: Type: text/plain, Size: 660 bytes --]

Hi,

For latest master branch, when try to use gnutls with async connection,
the handshake will return fatal error if socket is in ENOTCONN or
EINPROGRESS since gnutls treat these errors as fatal during push/pull
and gives up. The later retry will fail because gnutls will mark the
session invalid.

This patch is asking gnutls to treat them as EAGAIN which is non-fatal.

I only tested with OSX. Please see if you can reproduce it on Windows or
Linux and if this patch works for them too.

To reproduce run:

emacs -Q --eval "(erc-tls :server \"irc.freenode.net\" :port 6697 :nick \"test\")"

Current master branch will gave up connecting.

-- 
Thanks - Jun


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Treat-errno-EINPROGRESS-and-ENOTCONN-as-EAGAIN-for-a.patch --]
[-- Type: text/x-patch, Size: 2681 bytes --]

From 8c69cab078d4c51d5c8f76f2aacb7bb8dd46dd7f Mon Sep 17 00:00:00 2001
From: Jun Hao <jun_hao@aol.com>
Date: Thu, 14 Jul 2016 21:47:24 +0800
Subject: [PATCH] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async
 connection

* src/gnutls.c: (emacs_gnutls_non_blocking_errno): treat errno
EINPROGRESS and ENOTCONN as EAGAIN
(emacs_gnutls_handshake): set errno function to it when async
connection
(Fgnutls_boot): set state with GNUTLS_NONBLOCK flag when async
connection
---
 src/gnutls.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/gnutls.c b/src/gnutls.c
index 7f05ac4..449a971 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -35,6 +35,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 static bool emacs_gnutls_handle_error (gnutls_session_t, int);
 
+#ifndef WINDOWSNT
+static int emacs_gnutls_non_blocking_errno(gnutls_transport_ptr_t ptr);
+#endif
+
 static bool gnutls_global_initialized;
 
 static void gnutls_log_function (int, const char *);
@@ -383,6 +387,21 @@ gnutls_log_function2 (int level, const char *string, const char *extra)
   message ("gnutls.c: [%d] %s %s", level, string, extra);
 }
 
+#ifndef WINDOWSNT
+static int
+emacs_gnutls_non_blocking_errno(gnutls_transport_ptr_t ptr)
+{
+  switch (errno)
+    {
+    case EINPROGRESS:
+    case ENOTCONN:
+      return EAGAIN;
+    default:
+      return errno;
+    }
+}
+#endif
+
 int
 gnutls_try_handshake (struct Lisp_Process *proc)
 {
@@ -460,6 +479,11 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
       gnutls_transport_set_ptr2 (state,
 				 (void *) (intptr_t) proc->infd,
 				 (void *) (intptr_t) proc->outfd);
+      if (proc->is_non_blocking_client)
+        /* for non blocking connection
+           treat EINPROGRESS and ENOTCONN as EAGAIN */
+        gnutls_transport_set_errno_function(state,
+                                            emacs_gnutls_non_blocking_errno);
 #endif
 
       proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
@@ -1596,8 +1620,16 @@ one trustfile (usually a CA bundle).  */)
 
   /* Call gnutls_init here: */
 
-  GNUTLS_LOG (1, max_log_level, "gnutls_init");
-  ret = gnutls_init (&state, GNUTLS_CLIENT);
+  if (XPROCESS (proc)->is_non_blocking_client)
+    {
+      GNUTLS_LOG (1, max_log_level, "gnutls_init with nonblocking");
+      ret = gnutls_init(&state, GNUTLS_CLIENT|GNUTLS_NONBLOCK);
+    }
+  else
+    {
+      GNUTLS_LOG (1, max_log_level, "gnutls_init");
+      ret = gnutls_init (&state, GNUTLS_CLIENT);
+    }
   XPROCESS (proc)->gnutls_state = state;
   if (ret < GNUTLS_E_SUCCESS)
     return gnutls_make_error (ret);
-- 
2.8.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-08-04 14:22 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-14 14:17 bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async connection Jun Hao
2016-07-16  3:33 ` npostavs
2016-07-16  6:44   ` Eli Zaretskii
2016-07-16 15:03   ` jun_hao
2016-07-26  7:35 ` Paul Eggert
2016-07-26 14:48   ` Ted Zlatanov
2016-07-26 15:08     ` Eli Zaretskii
2016-07-26 15:14       ` Ted Zlatanov
2016-08-03  9:02       ` Paul Eggert
2016-08-04 14:22         ` Ted Zlatanov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).