GNU bug report logs - #23982
[master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async connection

Previous Next

Package: emacs;

Reported by: Jun Hao <jun_hao <at> aol.com>

Date: Thu, 14 Jul 2016 14:18:01 UTC

Severity: normal

Tags: patch

Merged with 22929, 23225, 23503

Found in version 25.1.50

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 23982 in the body.
You can then email your comments to 23982 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Thu, 14 Jul 2016 14:18:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jun Hao <jun_hao <at> aol.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 14 Jul 2016 14:18:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jun Hao <jun_hao <at> aol.com>
To: bug-gnu-emacs <at> gnu.org
Subject: [master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async
 connection
Date: Thu, 14 Jul 2016 22:17:13 +0800
[Message part 1 (text/plain, inline)]
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

[0001-Treat-errno-EINPROGRESS-and-ENOTCONN-as-EAGAIN-for-a.patch (text/x-patch, inline)]
From 8c69cab078d4c51d5c8f76f2aacb7bb8dd46dd7f Mon Sep 17 00:00:00 2001
From: Jun Hao <jun_hao <at> 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


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Sat, 16 Jul 2016 03:34:02 GMT) Full text and rfc822 format available.

Message #8 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: npostavs <at> users.sourceforge.net
To: Jun Hao <jun_hao <at> aol.com>
Cc: 23982 <at> debbugs.gnu.org
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as
 EAGAIN for async connection
Date: Fri, 15 Jul 2016 23:33:00 -0400
Jun Hao <jun_hao <at> aol.com> writes:
>
> 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.

On both Window and GNU/Linux this successfully connect both with and
without the patch, i.e., patch seems not to be needed on non-OSX
platforms, but it doesn't seem to hurt either.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Sat, 16 Jul 2016 06:46:01 GMT) Full text and rfc822 format available.

Message #11 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: npostavs <at> users.sourceforge.net
Cc: jun_hao <at> aol.com, 23982 <at> debbugs.gnu.org
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN
 for async connection
Date: Sat, 16 Jul 2016 09:44:56 +0300
> From: npostavs <at> users.sourceforge.net
> Date: Fri, 15 Jul 2016 23:33:00 -0400
> Cc: 23982 <at> debbugs.gnu.org
> 
> > emacs -Q --eval "(erc-tls :server \"irc.freenode.net\" :port 6697 :nick \"test\")"
> >
> > Current master branch will gave up connecting.
> 
> On both Window and GNU/Linux this successfully connect both with and
> without the patch, i.e., patch seems not to be needed on non-OSX
> platforms, but it doesn't seem to hurt either.

I think this fact should be reflected in some comment to the code
changed by the patch.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Sat, 16 Jul 2016 15:04:01 GMT) Full text and rfc822 format available.

Message #14 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: jun_hao <at> aol.com
To: npostavs <at> users.sourceforge.net, 23982 <at> debbugs.gnu.org
Cc: 23982 <at> debbugs.gnu.org
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as
 EAGAIN for async connection
Date: Sat, 16 Jul 2016 23:03:22 +0800
> On Jul 16, 2016, at 11:33, npostavs <at> users.sourceforge.net wrote:
> 
> Jun Hao <jun_hao <at> aol.com> writes:
>> 
>> 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.
> 
> On both Window and GNU/Linux this successfully connect both with and
> without the patch, i.e., patch seems not to be needed on non-OSX
> platforms, but it doesn't seem to hurt either.

I think it depends on how fast is connect call succeed. If it's already connected before handshake, it'll be okay. The default method that gnutls uses is send(2), which requires the underlying socket to be in connected state. I'm not sure if it's because of OSX or maybe slow internet connection at this point.

Thanks - Jun




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Tue, 26 Jul 2016 07:36:01 GMT) Full text and rfc822 format available.

Message #17 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Jun Hao <jun_hao <at> aol.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 23982 <at> debbugs.gnu.org,
 Ted Zlatanov <tzz <at> lifelogs.com>, npostavs <at> users.sourceforge.net
Subject: Re: [master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN for async
 connection
Date: Tue, 26 Jul 2016 09:35:04 +0200
Thanks for the bug report and patch. Two thoughts:

* Passing GNUTLS_NONBLOCK to gnutls_init seems like a worthy change, but 
why does Emacs need to fiddle with an errno function? Surely GnuTLS 
should do the right thing with async connections, without Emacs having 
to insert a shim. Isn't this a bug in GnuTLS?

* The proposed patch uses gnutls_transport_set_errno_function, 
introduced in GnuTLS 2.12.0. Emacs master currently requires only GnuTLS 
2.6.6 or later. Would it be wise to bump the prerequisite version from 
2.6.6 to 2.12.0? I'll CC: this to Ted Zlanatov to see what he thinks.






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Tue, 26 Jul 2016 14:49:02 GMT) Full text and rfc822 format available.

Message #20 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: Jun Hao <jun_hao <at> aol.com>, 23982 <at> debbugs.gnu.org,
 npostavs <at> users.sourceforge.net
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as
 EAGAIN for async connection
Date: Tue, 26 Jul 2016 10:48:28 -0400
On Tue, 26 Jul 2016 09:35:04 +0200 Paul Eggert <eggert <at> cs.ucla.edu> wrote: 

PE> * The proposed patch uses gnutls_transport_set_errno_function, introduced in
PE> GnuTLS 2.12.0. Emacs master currently requires only GnuTLS 2.6.6 or later. Would
PE> it be wise to bump the prerequisite version from 2.6.6 to 2.12.0? I'll CC: this
PE> to Ted Zlanatov to see what he thinks.

2.12.2 was released on 2011-04-08 so I think 5 years is long enough, we
can bump the required version. From a security standpoint I think it's a
good upgrade and the majority of the users will see it as a good change.

If we do, however, we should also review the API changes and see if our
usage in gnutls.c and gnutls.el can be improved or simplified with new
features like `gnutls_transport_set_errno_function'.

Similarly, we should consider migrating to GnuTLS 3.x if anyone is
interested, it should be a fun project (especially if it maintains 2.12
compatibility).

Ted




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Tue, 26 Jul 2016 15:09:02 GMT) Full text and rfc822 format available.

Message #23 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ted Zlatanov <tzz <at> lifelogs.com>
Cc: jun_hao <at> aol.com, npostavs <at> users.sourceforge.net, eggert <at> cs.ucla.edu,
 23982 <at> debbugs.gnu.org
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as EAGAIN
 for async connection
Date: Tue, 26 Jul 2016 18:08:02 +0300
> Date: Tue, 26 Jul 2016 10:48:28 -0400
> Cc: Jun Hao <jun_hao <at> aol.com>, 23982 <at> debbugs.gnu.org,
> 	npostavs <at> users.sourceforge.net
> 
> Similarly, we should consider migrating to GnuTLS 3.x if anyone is
> interested, it should be a fun project (especially if it maintains 2.12
> compatibility).

??? I'm building Emacs with GnuTLS 3.3.11 since many moons ago.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Tue, 26 Jul 2016 15:16:01 GMT) Full text and rfc822 format available.

Message #26 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as
 EAGAIN for async connection
Date: Tue, 26 Jul 2016 11:14:54 -0400
On Tue, 26 Jul 2016 18:08:02 +0300 Eli Zaretskii <eliz <at> gnu.org> wrote: 

>> Date: Tue, 26 Jul 2016 10:48:28 -0400
>> Cc: Jun Hao <jun_hao <at> aol.com>, 23982 <at> debbugs.gnu.org,
>> npostavs <at> users.sourceforge.net
>> 
>> Similarly, we should consider migrating to GnuTLS 3.x if anyone is
>> interested, it should be a fun project (especially if it maintains 2.12
>> compatibility).

EZ> ??? I'm building Emacs with GnuTLS 3.3.11 since many moons ago.

Of course. I meant taking advantage of 3.x features and APIs while
maintaining 2.12 compatibility. It should be an incremental improvement,
theoretically, but since 3.0.1 was released on 2011-08-21 there have
been quite a few changes.

Ted





Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Wed, 03 Aug 2016 09:03:01 GMT) Full text and rfc822 format available.

Notification sent to Jun Hao <jun_hao <at> aol.com>:
bug acknowledged by developer. (Wed, 03 Aug 2016 09:03:02 GMT) Full text and rfc822 format available.

Message #31 received at 23982-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Eli Zaretskii <eliz <at> gnu.org>, Ted Zlatanov <tzz <at> lifelogs.com>
Cc: jun_hao <at> aol.com, 23982-done <at> debbugs.gnu.org, npostavs <at> users.sourceforge.net
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as
 EAGAIN for async connection
Date: Wed, 3 Aug 2016 02:02:11 -0700
[Message part 1 (text/plain, inline)]
Eli Zaretskii wrote:
> I'm building Emacs with GnuTLS 3.3.11 since many moons ago.

OK, I installed the attached patches to GNU Emacs master. The first one requires 
GnuTLS 2.12.2 or later. The second one uses the GNUTLS_NONBLOCK flag, and works 
around the apparent GnuTLS bug with EINPROGRESS and ENOTCONN.

[0001-Require-GnuTLS-2.12.2-or-later.txt (text/plain, attachment)]
[0002-Fix-non-blocking-GnuTLS-with-slow-connection.txt (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#23982; Package emacs. (Thu, 04 Aug 2016 14:23:02 GMT) Full text and rfc822 format available.

Message #34 received at 23982 <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: 23982 <at> debbugs.gnu.org
Cc: jun_hao <at> aol.com, eggert <at> cs.ucla.edu
Subject: Re: bug#23982: [master] Treat errno EINPROGRESS and ENOTCONN as
 EAGAIN for async connection
Date: Thu, 04 Aug 2016 10:22:29 -0400
On Wed, 3 Aug 2016 02:02:11 -0700 Paul Eggert <eggert <at> cs.ucla.edu> wrote: 

PE> Eli Zaretskii wrote:
>> I'm building Emacs with GnuTLS 3.3.11 since many moons ago.

PE> OK, I installed the attached patches to GNU Emacs master. The first one requires
PE> GnuTLS 2.12.2 or later. The second one uses the GNUTLS_NONBLOCK flag, and works
PE> around the apparent GnuTLS bug with EINPROGRESS and ENOTCONN.

Thank you!

Ted




Forcibly Merged 22929 23225 23503 23982. Request was from Noam Postavsky <npostavs <at> users.sourceforge.net> to control <at> debbugs.gnu.org. (Tue, 09 Aug 2016 12:58:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 07 Sep 2016 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 8 years and 282 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.