From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13015 Path: news.gmane.org!.POSTED!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: getaddrinfo(3) / AI_ADDRCONFIG Date: Tue, 10 Jul 2018 20:38:16 -0400 Message-ID: <20180711003816.GV1392@brightrain.aerifal.cx> References: <20180709223805.GS1392@brightrain.aerifal.cx> <20180710005943.GT1392@brightrain.aerifal.cx> <20180710150854.GU1392@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1531269386 5326 195.159.176.226 (11 Jul 2018 00:36:26 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 11 Jul 2018 00:36:26 +0000 (UTC) User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-13031-gllmg-musl=m.gmane.org@lists.openwall.com Wed Jul 11 02:36:21 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1fd37F-0001IF-IS for gllmg-musl@m.gmane.org; Wed, 11 Jul 2018 02:36:21 +0200 Original-Received: (qmail 25957 invoked by uid 550); 11 Jul 2018 00:38:29 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 25939 invoked from network); 11 Jul 2018 00:38:29 -0000 Content-Disposition: inline In-Reply-To: Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:13015 Archived-At: On Tue, Jul 10, 2018 at 07:30:05PM -0400, Christopher Friedt wrote: > On Tue, Jul 10, 2018 at 7:21 PM Christopher Friedt > wrote: > > test.c, output, strace log, and ifconfig -a output here: > > > > https://pastebin.com/UmJi02px > > So it's definitely returning an IPv4 socket (which Thrift throws away > in favour of the IPv6 socket). Since no adapter has the IPv6 address > returned, bind(2) would fail on a subsequent call. Yes, musl seems to be behaving as expected here, and it's thrift that's choosing to use the first v6 result, or the last result if there are no v6 results. Even ignoring issues with inability to use ipv6, this is probably not desirable on v4-only systems since it may choose the worst, rather than the best, result, if the order was meaningful to begin with. > After applying the patch [1] to musl, > > # ./test -v > struct addrinfo { > ai_flags: 0 > ai_family: 2 > ai_socktype: 1 > ai_protocol: 6 > ai_addrlen: 16 > ai_addr: > family: 2 > addr: 127.0.0.1 > port: 0 > ai_canonname: localhost > ai_next: 0 > } > > [1] https://patch-diff.githubusercontent.com/raw/cfriedt/musl/pull/1.diff This patch isn't acceptable as-is, and I don't think it would even fix your problem if you just did "ip addr del ::1 dev lo" but had an ipv6 address available on some other interface. The only thing that would help is having AI_ADDRCONFIG omit non-routable results, which is "morally" what it should do, but contrary to what it's specified to do. Maybe you're okay with saying "having some ipv6 addresses but not supporting ::1 is a pathological configuration and doesn't need to be supported". If so, I'm happy to have AI_ADDRCONFIG check whether ::1 is routable, and disable IPv6 if it's not. This would basically look like: if (family != AF_INET && (flags & AI_ADDRCONFIG)) { /* attempt to connect a UDP socket to ::1 */ /* ... */ if (failed && errno==ENETUNREACH) { if (family == AF_INET6) return EAI_NONAME; family = AF_INET; } } Regardless of what's done on the musl side, I think it would make sense for thrift to change its strategy for selecting an address to use. If IPv6 is supported, getaddrinfo should always return ::1 before 127.0.0.1 (see RFC 3484/6724), so just using the first address returned should give the best behavior. For addresses other than localhost, I'm not sure what you want to happen, but I think if the hostname has both IPv4 and IPv6 addresses, just binding to the v6 one will _not_ get you the ability to accept v4 connections (since the address is different) and you need to bind to both. In general the correct pattern for listening with getaddrinfo is probably to attempt to bind each of the results. Rich