http://bugzilla.novell.com/show_bug.cgi?id=600864 http://bugzilla.novell.com/show_bug.cgi?id=600864#c0 Summary: Shortcoming in qemu's socket code disrupts IPv4/IPv6 coexistance Classification: openSUSE Product: openSUSE 11.3 Version: Factory Platform: All OS/Version: openSUSE 11.3 Status: NEW Severity: Normal Priority: P5 - None Component: Network AssignedTo: uli@novell.com ReportedBy: max@novell.com QAContact: qa@suse.de CC: radmanic@novell.com, agruen@novell.com, mana@novell.com, mkraft@novell.com, agraf@novell.com Found By: --- Blocker: --- Triggered by an alleged vnc problem with qemu that Matthias (cc) told me about, I had a look into qemu's server socket code (inet_listen() in qemu-sockets.c) that is used by qemu-char.c and vnc.c. This function and its users run into a problem when the listening address is given as a name that resolves to more than one IP address. In such a case qemu only listens on one of these addresses and clients trying to connect to a different address from the set get a connection refused error. The most common case for this is probably "localhost" for which getaddrinfo() returns a list of the two loopback addresses for IPv4 and IPv6 respectively (127.0.0.1 and ::1), but it could also happen for host names that resolve to more than a single address of the same family. The actual problem is, that the code in inet_listen() and its callers is not designed to listen on more than one socket at once for a given connection (e.g. -vnc localhost:42). The code already loops over the addresses returned by getaddrinfo, but it stops once the first socket has successfully been created and bound, leaving the port closed on all other addresses. IMO the correct behaviour would be to let the loop run thrugh the whole list, collect all the successfully bound sockets and only error out if none of them was successful. Unfortunately the data structures of the callers of inet_listen() only have space for a single file descriptor, so the change to support multiple of them is more intrusive than just changing the logic of the loop inside inet_listen(). I think I could implement the change, as I've done a similar patch for Tcl before. BTW, the feature that a listening IPv6 socket can also accept IPv4 connections doesn't help here, because it only works when the socket is bound to the wildcard address (::), but not for explicit address bindings such as ::1. Therefore it is another bug that the code unconditionally *clears* the IPV6_V6ONLY flag for all IPv6 sockets, which even disallows IPv4 sockets on the same port when the IPv6 socket is bound to an explicit address and hence won't ever get an incoming IPv4 connection. Instead it should *set* that flag on all IPv6 sockets, because even for wildcard bindings getaddrinfo() will return separate results for IPv4 and IPv6, so it wouldn't hurt to have separate sockets, because the code for that is needed anyways. -- Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.