Bug 787262 - RFE: when no addr=<address> is specified, assume addr=::
RFE: when no addr=<address> is specified, assume addr=::
Status: CLOSED WONTFIX
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: spice-server (Show other bugs)
6.4
Unspecified Unspecified
low Severity low
: beta
: 6.5
Assigned To: Default Assignee for SPICE Bugs
Desktop QE
: FutureFeature, Improvement, Reopened
Depends On: 880698
Blocks: 880347 RHEV_IPv6 637547
  Show dependency treegraph
 
Reported: 2012-02-03 12:54 EST by David Jaša
Modified: 2015-04-01 05:57 EDT (History)
10 users (show)

See Also:
Fixed In Version:
Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2015-03-16 11:11:33 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description David Jaša 2012-02-03 12:54:13 EST
Description of problem:
SSIA. When no addr=<address> is specified, listen on both ipv6 and ipv4.

Version-Release number of selected component (if applicable):
qemu-kvm-0.12.1.2-2.222.el6.x86_64

How reproducible:
always

Steps to Reproduce:
1. run /usr/libexec/qemu-kvm -spice port=<port>,disable-ticketing
2.
3.
  
Actual results:
# netstat -putna | grep <port>
tcp 0 0 0.0.0.0:<port> 0.0.0.0:* LISTEN <pid>/qemu-kvm

Expected results:
# netstat -putna | grep <port>
tcp 0 0 0.0.0.0:<port> 0.0.0.0:* LISTEN <pid>/qemu-kvm
tcp 0 0     ::0:<port>     ::0:* LISTEN <pid>/qemu-kvm

Additional info:
Comment 1 David Blechter 2012-02-14 14:00:20 EST
closed, see comments in RFE 787256
Comment 2 David Jaša 2012-02-15 04:51:28 EST
Reopening. I see this as a bug and the person who sees this as a RFE should reassing it accordingly.
Comment 3 David Jaša 2012-11-08 08:18:02 EST
The requested solution was unnecessarily complex: if we listen on ::, we also listen on 0.0.0.0 automatically thanks to dual-stack being default anywhere (except OpenBSD).

That said, if we listen on :: by default, the resulting behavior will be that superset of current clients will be able to connect. This should be both fairly easy to implement and QA so IMO it's fair to move this bug from FutureFeature and RFEs to Improvement and spice-server, and propose this for 6.5.
Comment 4 David Jaša 2012-11-08 08:21:06 EST
Just forgot to add: the default ip6tables configuration prohibits new connections on v6 by default so this should pose no new problems by default from security POV, too.
Comment 5 Christophe Fergeau 2012-11-23 13:53:11 EST
I've been looking at that a bit, but I still have a lot to learn about ipv6 ;)
When no address is given on QEMU commandline, reds_init_socket calls 
getaddrinfo(NULL, "5900", { .ai_family = AF_UNSPEC, .ai_flags = AI_ADDRCONFIG|AI_PASSIVE });
which gives us two results, one IPv4 and one IPv6 address (in that order). We try that IPv4 address first, which succeeds, so we only get bound on 0.0.0.0.

Chapter 11 of "UNIX Network Programming: Vol. 1: The Sockets Networking API
 Par W. Richard Stevens,Bill Fenner,Andrew M. Rudoff" (I could read it on Google Books) says that in this case we probably should get the IPv6 address first. glibc seems to disagree, as I understand getaddrinfo source code, it starts by building a list with IPv6 and then IPv4, sort it using what is described in RFC3484, and it must be deciding in this code that it needs to swap the 2 entries given the result we get.

I'm a bit wary of trying to be smarter than glibc here without knowing if it makes sense to override what it suggests.
Comment 7 David Jaša 2012-11-26 09:50:37 EST
I was talking about correct handling of this situation with Pavel again and the correct solution should essentially be:
1) if nothing is specified, bind to "in6addr_any" constant address ($SUBJ of this bug)
2) if IP is specified, bind to that IP right away
3) if "localhost" is specified, bind to "127.0.0.1"
4) if name is specified, use gettaddrinfo() to get the address

The general trouble with getaddrinfo in this respect reportedly is that it:
1. returns multiple results (because of bug 787256)
2. the order is not guaranteed
Comment 8 Pavel Šimerda (pavlix) 2012-11-26 15:51:24 EST
I already had enough time to change my mind a bit. And I also made some
tests on getaddrinfo() with the following results. The results are available at:

https://fedoraproject.org/wiki/Networking/NameResolution#Using_getaddrinfo.28.29_for_server_sockets

# ./getaddrinfo-test-ai-passive.py
None
   (2, 1, 6, '', ('0.0.0.0', 80))
   (10, 1, 6, '', ('::', 80, 0, 0))
localhost
   (10, 1, 6, '', ('::1', 80, 0, 0))
   (2, 1, 6, '', ('127.0.0.1', 80))
info.nix.cz
   (10, 1, 6, '', ('2a02:38::1001', 80, 0, 0))
   (2, 1, 6, '', ('195.47.235.3', 80))
www.google.com
   (10, 1, 6, '', ('2a00:1450:4016:801::1012', 80, 0, 0))
   (2, 1, 6, '', ('173.194.35.144', 80))
   (2, 1, 6, '', ('173.194.35.145', 80))
   (2, 1, 6, '', ('173.194.35.147', 80))
   (2, 1, 6, '', ('173.194.35.148', 80))
   (2, 1, 6, '', ('173.194.35.146', 80))

In the first case, you would have to use <code>::</code> (the second result). But in the second case, you have to use two sockets, one for <code>::1</code>, one for <code>127.0.0.1</code>. The
same applies to the third case. In the fourth case, you would have to use
the total of 6 sockets.

The easiest solution is to just use <code>::</code> and rely on the dualstack hack (sysctl: net.ipv6.bindv6only = 0). If you want to support full listening name resolution, you need to set the socket option IPV6_V6ONLY and createa
socket for each address.

I hope I didn't miss out something.
Comment 9 Pavel Šimerda (pavlix) 2012-11-26 16:05:01 EST
(In reply to comment #5)
> Chapter 11 of "UNIX Network Programming: Vol. 1: The Sockets Networking API
>  Par W. Richard Stevens,Bill Fenner,Andrew M. Rudoff" (I could read it on
> Google Books) says that in this case we probably should get the IPv6 address
> first. glibc seems to disagree, as I understand getaddrinfo source code, it
> starts by building a list with IPv6 and then IPv4, sort it using what is
> described in RFC3484, and it must be deciding in this code that it needs to
> swap the 2 entries given the result we get.

It makes sense to fix this in glibc, but it only solves for the wildcard
address case. All other cases would remain broken.
Comment 10 Christophe Fergeau 2012-11-27 07:16:56 EST
(In reply to comment #9)
> (In reply to comment #5)
> > Chapter 11 of "UNIX Network Programming: Vol. 1: The Sockets Networking API
> >  Par W. Richard Stevens,Bill Fenner,Andrew M. Rudoff" (I could read it on
> > Google Books) says that in this case we probably should get the IPv6 address
> > first. glibc seems to disagree, as I understand getaddrinfo source code, it
> > starts by building a list with IPv6 and then IPv4, sort it using what is
> > described in RFC3484, and it must be deciding in this code that it needs to
> > swap the 2 entries given the result we get.
> 
> It makes sense to fix this in glibc, but it only solves for the wildcard
> address case. All other cases would remain broken.

As I understand it, the other cases would require us creating 2 sockets, one ipv6 one and one ipv4 one, this is tracked by rhbz#787256. As for this bug, before adding code to second guess what libc returns, I'd prefer to know how libc people feel about the getaddrinfo(NULL) behaviour.
Comment 11 Pavel Šimerda (pavlix) 2012-11-27 10:29:43 EST
(In reply to comment #10)
> (In reply to comment #9)
> > (In reply to comment #5)
> > > Chapter 11 of "UNIX Network Programming: Vol. 1: The Sockets Networking API
> > >  Par W. Richard Stevens,Bill Fenner,Andrew M. Rudoff" (I could read it on
> > > Google Books) says that in this case we probably should get the IPv6 address
> > > first. glibc seems to disagree, as I understand getaddrinfo source code, it
> > > starts by building a list with IPv6 and then IPv4, sort it using what is
> > > described in RFC3484, and it must be deciding in this code that it needs to
> > > swap the 2 entries given the result we get.
> > 
> > It makes sense to fix this in glibc, but it only solves for the wildcard
> > address case. All other cases would remain broken.
> 
> As I understand it, the other cases would require us creating 2 sockets, one
> ipv6 one and one ipv4 one, this is tracked by rhbz#787256.

At the least. Two addresses are enough if "localhost" is special cased and
name resolution is suppressed.

> As for this bug,
> before adding code to second guess what libc returns, I'd prefer to know how
> libc people feel about the getaddrinfo(NULL) behaviour.

Sure. I would like to know their opinion on the whole bunch of getaddrinfo() problems. But I'm not aware of any glibc developers active in networking and
especially getaddrinfo(). They should definitely see:

https://fedoraproject.org/wiki/Networking/NameResolution
http://sourceware.org/bugzilla/buglist.cgi?quicksearch=getaddrinfo&list_id=7305
Comment 12 David Jaša 2012-11-27 11:02:04 EST
Given the information from comment 8 on, this is clearly a libc bug that essentially breaks dual-stack networking for all apps that rely on getaddrinfo(NULL). Therefore I'm clearing the release flag here and making this depend on the glibc bug so that we can verify spice-server behaviour after the glibc bug is fixed.
Comment 16 RHEL Product and Program Management 2013-10-14 01:07:38 EDT
This request was not resolved in time for the current release.
Red Hat invites you to ask your support representative to
propose this request, if still desired, for consideration in
the next release of Red Hat Enterprise Linux.
Comment 18 David Blechter 2015-03-02 11:51:13 EST
(In reply to David Jaša from comment #12)
> Given the information from comment 8 on, this is clearly a libc bug that
> essentially breaks dual-stack networking for all apps that rely on
> getaddrinfo(NULL). Therefore I'm clearing the release flag here and making
> this depend on the glibc bug so that we can verify spice-server behaviour
> after the glibc bug is fixed.

If this bug depends on 880698 as was suggested ( in NEW state for rhel 7.2 ), than we should select one of two following options:
1. Move this RFE to the rhel 7.2 as the earliest target ( prefer option );
2. Clone 880698 to the rhel 6.x, correct the dependency, and set the new target for both bugs to one of post rhel 6.7 releases.
Comment 19 Christophe Fergeau 2015-03-04 09:25:36 EST
Bug #880698 was moved from RHEL6 to RHEL7:
https://bugzilla.redhat.com/show_bug.cgi?id=880698#c11
"Unfortunately I think RHEL6 is going to have to stay as it is with applications working around the problem."
Comment 20 David Blechter 2015-03-16 11:11:33 EDT
(In reply to Christophe Fergeau from comment #19)
> Bug #880698 was moved from RHEL6 to RHEL7:
> https://bugzilla.redhat.com/show_bug.cgi?id=880698#c11
> "Unfortunately I think RHEL6 is going to have to stay as it is with
> applications working around the problem."

Agree, closing.

Note You need to log in before you can comment on or make changes to this bug.