From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#17976: 24.3; url-retrieve-synchronously doesn't fallback to IPv4 Date: Sun, 12 Jun 2016 11:36:43 -0700 Organization: UCLA Computer Science Department Message-ID: <575DABBB.4060908@cs.ucla.edu> References: <878uo2ogg6.wl-jch@pps.univ-paris-diderot.fr> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------050208000509010000050807" X-Trace: ger.gmane.org 1465756647 27622 80.91.229.3 (12 Jun 2016 18:37:27 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 12 Jun 2016 18:37:27 +0000 (UTC) Cc: 17976@debbugs.gnu.org, Lars Ingebrigtsen , Artur Malabarba , Andreas Schwab To: Juliusz Chroboczek Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Jun 12 20:37:15 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1bCAG3-0005t3-7c for geb-bug-gnu-emacs@m.gmane.org; Sun, 12 Jun 2016 20:37:15 +0200 Original-Received: from localhost ([::1]:52305 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCAG2-00044W-8k for geb-bug-gnu-emacs@m.gmane.org; Sun, 12 Jun 2016 14:37:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCAFv-00044E-9t for bug-gnu-emacs@gnu.org; Sun, 12 Jun 2016 14:37:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCAFq-00050j-ST for bug-gnu-emacs@gnu.org; Sun, 12 Jun 2016 14:37:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:54150) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCAFq-00050f-P1 for bug-gnu-emacs@gnu.org; Sun, 12 Jun 2016 14:37:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1bCAFq-0002Hj-HJ for bug-gnu-emacs@gnu.org; Sun, 12 Jun 2016 14:37:02 -0400 X-Loop: help-debbugs@gnu.org In-Reply-To: <878uo2ogg6.wl-jch@pps.univ-paris-diderot.fr> Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 12 Jun 2016 18:37:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 17976 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: confirmed Original-Received: via spool by 17976-submit@debbugs.gnu.org id=B17976.14657566188774 (code B ref 17976); Sun, 12 Jun 2016 18:37:02 +0000 Original-Received: (at 17976) by debbugs.gnu.org; 12 Jun 2016 18:36:58 +0000 Original-Received: from localhost ([127.0.0.1]:38254 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bCAFm-0002HR-9Z for submit@debbugs.gnu.org; Sun, 12 Jun 2016 14:36:58 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:58010) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bCAFh-0002HB-RO for 17976@debbugs.gnu.org; Sun, 12 Jun 2016 14:36:57 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 015311613E5; Sun, 12 Jun 2016 11:36:48 -0700 (PDT) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id l4k8oxL2VSrd; Sun, 12 Jun 2016 11:36:47 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id E9CD11613EC; Sun, 12 Jun 2016 11:36:46 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id q4iWpLhGdoUJ; Sun, 12 Jun 2016 11:36:46 -0700 (PDT) Original-Received: from [192.168.1.9] (unknown [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id BD08C1613E5; Sun, 12 Jun 2016 11:36:46 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:119460 Archived-At: This is a multi-part message in MIME format. --------------050208000509010000050807 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable I reproduced this bug in a test Fedora 23 environment where attempting to= =20 connect to one address failed (connection refused). The attached patch to= Emacs=20 master causes Emacs to try addresses addresses until one succeeds. Does t= his fix=20 your problem? I suspect the code should check for error codes other than=20 ECONNREFUSED, but I don't know what the list of such codes should be. --------------050208000509010000050807 Content-Type: text/x-diff; name="0001-Try-other-addresses-when-connecting-to-multihomed.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename*0="0001-Try-other-addresses-when-connecting-to-multihomed.patch" =46rom 958a23698c9f1b9b804aa79d410b11b07998b223 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 12 Jun 2016 11:08:41 -0700 Subject: [PATCH] Try other addresses when connecting to multihomed * src/process.c (decode_status, Fmake_network_process): Support (connect . ADDRINFOS) status. (connecting): New function, to support (connect . ADDRINFOS). (connect_network_socket, check_for_dns, wait_for_socket_fds) (wait_while_connecting, wait_reading_process_output, status_notify): Use it. (connect_network_socket) [!WINDOWSNT]: If the connection failed with ECONNREFUSED and there are other addresses to try, do not signal an error; instead, loop around to try the next address. (wait_reading_process_output): Advance to the next address if there are multiple addresses and the first remaining address failed. * src/process.h (struct Lisp_Process.status): Adjust comment to describe (connect . ADDRINFOS). --- src/process.c | 45 ++++++++++++++++++++++++++++++++------------- src/process.h | 4 +++- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/process.c b/src/process.c index e669278..a72bf20 100644 --- a/src/process.c +++ b/src/process.c @@ -542,6 +542,9 @@ decode_status (Lisp_Object l, Lisp_Object *symbol, Li= sp_Object *code, { Lisp_Object tem; =20 + if (CONSP (l) && EQ (XCAR (l), Qconnect)) + l =3D XCAR (l); + if (SYMBOLP (l)) { *symbol =3D l; @@ -3106,6 +3109,12 @@ finish_after_tls_connection (Lisp_Object proc) } #endif =20 +static bool +connecting (struct Lisp_Process *p) +{ + return CONSP (p->status) && EQ (XCAR (p->status), Qconnect); +} + static void connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos, Lisp_Object use_external_socket_p) @@ -3288,9 +3297,10 @@ connect_network_socket (Lisp_Object proc, Lisp_Obj= ect addrinfos, eassert (FD_ISSET (s, &fdset)); if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) report_file_error ("Failed getsockopt", Qnil); - if (xerrno) + if (xerrno =3D=3D 0) + break; + if (xerrno !=3D ECONNREFUSED || NILP (addrinfos)) report_file_errno ("Failed connect", Qnil, xerrno); - break; } #endif /* !WINDOWSNT */ =20 @@ -3399,7 +3409,8 @@ connect_network_socket (Lisp_Object proc, Lisp_Obje= ct addrinfos, /* We may get here if connect did succeed immediately. However, in that case, we still need to signal this like a non-blocking connection. */ - pset_status (p, Qconnect); + if (! (connecting (p) && EQ (XCDR (p->status), addrinfos))) + pset_status (p, Fcons (Qconnect, addrinfos)); if (!FD_ISSET (inch, &connect_wait_mask)) { FD_SET (inch, &connect_wait_mask); @@ -3960,7 +3971,7 @@ usage: (make-network-process &rest ARGS) */) if (!p->is_server && NILP (addrinfos)) { p->dns_request =3D dns_request; - p->status =3D Qconnect; + p->status =3D list1 (Qconnect); return proc; } #endif @@ -4673,7 +4684,7 @@ check_for_dns (Lisp_Object proc) addrinfos =3D Fnreverse (addrinfos); } /* The DNS lookup failed. */ - else if (EQ (p->status, Qconnect)) + else if (connecting (p)) { deactivate_process (proc); pset_status (p, (list2 @@ -4686,7 +4697,7 @@ check_for_dns (Lisp_Object proc) free_dns_request (proc); =20 /* This process should not already be connected (or killed). */ - if (!EQ (p->status, Qconnect)) + if (! connecting (p)) return Qnil; =20 return addrinfos; @@ -4697,8 +4708,7 @@ check_for_dns (Lisp_Object proc) static void wait_for_socket_fds (Lisp_Object process, char const *name) { - while (XPROCESS (process)->infd < 0 - && EQ (XPROCESS (process)->status, Qconnect)) + while (XPROCESS (process)->infd < 0 && connecting (XPROCESS (process))= ) { add_to_log ("Waiting for socket from %s...", build_string (name));= wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL= , 0); @@ -4708,7 +4718,7 @@ wait_for_socket_fds (Lisp_Object process, char cons= t *name) static void wait_while_connecting (Lisp_Object process) { - while (EQ (XPROCESS (process)->status, Qconnect)) + while (connecting (XPROCESS (process))) { add_to_log ("Waiting for connection..."); wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL= , 0); @@ -5010,7 +5020,7 @@ wait_reading_process_output (intmax_t time_limit, i= nt nsecs, int read_kbd, update_status (wait_proc); if (wait_proc && ! EQ (wait_proc->status, Qrun) - && ! EQ (wait_proc->status, Qconnect)) + && ! connecting (wait_proc)) { bool read_some_bytes =3D false; =20 @@ -5520,9 +5530,18 @@ wait_reading_process_output (intmax_t time_limit, = int nsecs, int read_kbd, #endif if (xerrno) { - p->tick =3D ++process_tick; - pset_status (p, list2 (Qfailed, make_number (xerrno))); + Lisp_Object addrinfos + =3D connecting (p) ? XCDR (p->status) : Qnil; + if (!NILP (addrinfos)) + XSETCDR (p->status, XCDR (addrinfos)); + else + { + p->tick =3D ++process_tick; + pset_status (p, list2 (Qfailed, make_number (xerrno))); + } deactivate_process (proc); + if (!NILP (addrinfos)) + connect_network_socket (proc, addrinfos, Qnil); } else { @@ -6999,7 +7018,7 @@ status_notify (struct Lisp_Process *deleting_proces= s, =20 /* If process is still active, read any output that remains. */ while (! EQ (p->filter, Qt) - && ! EQ (p->status, Qconnect) + && ! connecting (p) && ! EQ (p->status, Qlisten) /* Network or serial process not stopped: */ && ! EQ (p->command, Qt) diff --git a/src/process.h b/src/process.h index 4430377..6c227bc 100644 --- a/src/process.h +++ b/src/process.h @@ -83,7 +83,9 @@ struct Lisp_Process Lisp_Object mark; =20 /* Symbol indicating status of process. - This may be a symbol: run, open, closed, listen, connect, or fail= ed. + This may be a symbol: run, open, closed, listen, or failed. + Or it may be a pair (connect . ADDRINFOS) where ADDRINFOS is + a list of remaining (PROTOCOL . ADDRINFO) pairs to try. Or it may be (failed ERR) where ERR is an integer, string or symb= ol. Or it may be a list, whose car is stop, exit or signal and whose cdr is a pair (EXIT_CODE . COREDUMP_FLAG) --=20 2.5.5 --------------050208000509010000050807--