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#23620: 24.3; url-retrieve-synchronously doesn't fallback to IPv4 Date: Sun, 26 Jun 2016 23:58:29 +0200 Message-ID: <57705005.2060608@cs.ucla.edu> References: <87oa7uou2t.fsf@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------080704050302000603090504" X-Trace: ger.gmane.org 1467008092 1041 80.91.229.3 (27 Jun 2016 06:14:52 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 27 Jun 2016 06:14:52 +0000 (UTC) Cc: Juliusz Chroboczek , Andreas Schwab , 23620@debbugs.gnu.org, Artur Malabarba , Lars Ingebrigtsen To: 17976@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Jun 26 23:59:16 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 1bHI5E-0006Ni-CJ for geb-bug-gnu-emacs@m.gmane.org; Sun, 26 Jun 2016 23:59:16 +0200 Original-Received: from localhost ([::1]:55378 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHI5D-0002zC-75 for geb-bug-gnu-emacs@m.gmane.org; Sun, 26 Jun 2016 17:59:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45348) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHI55-0002z2-DS for bug-gnu-emacs@gnu.org; Sun, 26 Jun 2016 17:59:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bHI50-00016b-MP for bug-gnu-emacs@gnu.org; Sun, 26 Jun 2016 17:59:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:44763) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHI50-00016X-JP for bug-gnu-emacs@gnu.org; Sun, 26 Jun 2016 17:59:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1bHI50-0006T1-EN for bug-gnu-emacs@gnu.org; Sun, 26 Jun 2016 17:59:02 -0400 X-Loop: help-debbugs@gnu.org In-Reply-To: <87oa7uou2t.fsf@gmail.com> Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 26 Jun 2016 21:59:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 23620 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: moreinfo confirmed patch Original-Received: via spool by 23620-submit@debbugs.gnu.org id=B23620.146697833124834 (code B ref 23620); Sun, 26 Jun 2016 21:59:02 +0000 Original-Received: (at 23620) by debbugs.gnu.org; 26 Jun 2016 21:58:51 +0000 Original-Received: from localhost ([127.0.0.1]:57099 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bHI4o-0006SP-IJ for submit@debbugs.gnu.org; Sun, 26 Jun 2016 17:58:50 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:56152) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bHI4m-0006S5-DP; Sun, 26 Jun 2016 17:58:49 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 6E764160255; Sun, 26 Jun 2016 14:58:42 -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 OZcxVWX_plC5; Sun, 26 Jun 2016 14:58:40 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id ACA8A1613DB; Sun, 26 Jun 2016 14:58:40 -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 s7l70LjzsmwX; Sun, 26 Jun 2016 14:58:40 -0700 (PDT) Original-Received: from [192.168.1.15] (host243-162-static.0-79-b.business.telecomitalia.it [79.0.162.243]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id ADE30160255; Sun, 26 Jun 2016 14:58:38 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; Linux i686; 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:120118 This is a multi-part message in MIME format. --------------080704050302000603090504 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit No further comment on the proposed patch, and as it should be a win for non-WINDOWSNT I decided to install it on the Emacs master branch. I looked into how libcurl addresses the issue, and it doesn't care whether the errno value reported by getsockopt is ECONNREFUSED so I adjusted the Emacs patch accordingly (see attached) before installing. Please give it a try if you have the time. This patch does not affect behavior if WINDOWSNT. If the bug does not occur on MS-Windows I hope we can close Bug#17976. Otherwise we should leave the bug open for the WINDOWSNT case. --------------080704050302000603090504 Content-Type: text/x-patch; name="0001-Try-other-addresses-when-connecting-to-multihomed.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Try-other-addresses-when-connecting-to-multihomed.patch" >From 6a90b600323afc42ae3bd644d82ba7ea054a816a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 26 Jun 2016 23:27:21 +0200 Subject: [PATCH] Try other addresses when connecting to multihomed Problem reported by Juliusz Chroboczek (Bug#17976) and by Artur Malabarba (Bug#23620). Patch from a suggestion by Andreas Schwab in: http://bugs.gnu.org/17976#39 This patch is for non-MS-Windows platforms. I don't know the situation on MS-Windows. * src/process.c (connecting_status): New function, for (connect . ADDRINFOS). (connect_network_socket, check_for_dns, wait_for_socket_fds) (wait_while_connecting, wait_reading_process_output, status_notify): Use it. (decode_status, Fmake_network_process): Support (connect . ADDRINFOS) status. (connect_network_socket) [!WINDOWSNT]: If the connection failed 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 | 47 +++++++++++++++++++++++++++++++++++------------ src/process.h | 4 +++- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/process.c b/src/process.c index e669278..ed0c529 100644 --- a/src/process.c +++ b/src/process.c @@ -533,6 +533,14 @@ status_convert (int w) return Qrun; } +/* True if STATUS is that of a process attempting connection. */ + +static bool +connecting_status (Lisp_Object status) +{ + return CONSP (status) && EQ (XCAR (status), Qconnect); +} + /* Given a status-list, extract the three pieces of information and store them individually through the three pointers. */ @@ -542,6 +550,9 @@ decode_status (Lisp_Object l, Lisp_Object *symbol, Lisp_Object *code, { Lisp_Object tem; + if (connecting_status (l)) + l = XCAR (l); + if (SYMBOLP (l)) { *symbol = l; @@ -3288,9 +3299,10 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 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 == 0) + break; + if (NILP (addrinfos)) report_file_errno ("Failed connect", Qnil, xerrno); - break; } #endif /* !WINDOWSNT */ @@ -3399,7 +3411,9 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 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_status (p->status) + && 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 +3974,7 @@ usage: (make-network-process &rest ARGS) */) if (!p->is_server && NILP (addrinfos)) { p->dns_request = dns_request; - p->status = Qconnect; + p->status = list1 (Qconnect); return proc; } #endif @@ -4673,7 +4687,7 @@ check_for_dns (Lisp_Object proc) addrinfos = Fnreverse (addrinfos); } /* The DNS lookup failed. */ - else if (EQ (p->status, Qconnect)) + else if (connecting_status (p->status)) { deactivate_process (proc); pset_status (p, (list2 @@ -4686,7 +4700,7 @@ check_for_dns (Lisp_Object proc) free_dns_request (proc); /* This process should not already be connected (or killed). */ - if (!EQ (p->status, Qconnect)) + if (! connecting_status (p->status)) return Qnil; return addrinfos; @@ -4698,7 +4712,7 @@ static void wait_for_socket_fds (Lisp_Object process, char const *name) { while (XPROCESS (process)->infd < 0 - && EQ (XPROCESS (process)->status, Qconnect)) + && connecting_status (XPROCESS (process)->status)) { 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 +4722,7 @@ wait_for_socket_fds (Lisp_Object process, char const *name) static void wait_while_connecting (Lisp_Object process) { - while (EQ (XPROCESS (process)->status, Qconnect)) + while (connecting_status (XPROCESS (process)->status)) { add_to_log ("Waiting for connection..."); wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); @@ -5010,7 +5024,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, update_status (wait_proc); if (wait_proc && ! EQ (wait_proc->status, Qrun) - && ! EQ (wait_proc->status, Qconnect)) + && ! connecting_status (wait_proc->status)) { bool read_some_bytes = false; @@ -5520,9 +5534,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, #endif if (xerrno) { - p->tick = ++process_tick; - pset_status (p, list2 (Qfailed, make_number (xerrno))); + Lisp_Object addrinfos + = connecting_status (p->status) ? XCDR (p->status) : Qnil; + if (!NILP (addrinfos)) + XSETCDR (p->status, XCDR (addrinfos)); + else + { + p->tick = ++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 +7022,7 @@ status_notify (struct Lisp_Process *deleting_process, /* If process is still active, read any output that remains. */ while (! EQ (p->filter, Qt) - && ! EQ (p->status, Qconnect) + && ! connecting_status (p->status) && ! 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; /* Symbol indicating status of process. - This may be a symbol: run, open, closed, listen, connect, or failed. + 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 symbol. Or it may be a list, whose car is stop, exit or signal and whose cdr is a pair (EXIT_CODE . COREDUMP_FLAG) -- 2.5.5 --------------080704050302000603090504--