Uso de getaddrinfo () con AI_PASSIVE

Losgetaddrinfo()a función @ no solo permite que los programas cliente encuentren eficientemente los datos correctos para crear un socket a un host dado, sino que también permite que los servidores se unan al socket correcto, en teoría.

Yo soloprendí sobre eso y comenzó a jugar con él a través de Python:

from socket import *
for i in getaddrinfo(None, 22, AF_UNSPEC, SOCK_STREAM, IPPROTO_IP, AI_PASSIVE): i

rendimientos

(2, 1, 6, '', ('0.0.0.0', 22))
(10, 1, 6, '', ('::', 22, 0, 0))

lo que me hace preguntarme si hay algo mal.

¿Qué se supone que debo hacer exactamente con estas respuestas? Deberí

hacer unalisten()ing socket de todas estas respuestas, o debería solo elige el primero que realmente funciona?

El ejemplo en el manpage me sugiere que solo tome el primero y esté contento con él si no tiene errores, pero luego solo obtengo una conexión a través de IPv4 en mi ejemplo.

Pero si los pruebo todos, me tengo que preocupar con 2 zócalos de servidor, lo cual es innecesario debido al hecho de que los zócalos de servidor IPv6 también escuchan IPv4 si se cumplen ciertas condiciones (SO, banderas de zócalo, etc.).

¿Dónde estoy pensando mal?

EDIT: Obviamente, no estoy pensando mal, pero mi PC hace lo incorrecto. Yo uso el predeterminado/etc/gai.conf enviado con OpenSUSE. Sería bueno si alguien pudiera señalarme en la dirección correcta.

EDIT 2: en el caso dado,strace da las siguientes llamadas realizadas internamente después de leer/etc/gai.conf (ahora con el puerto 54321, ya que pensé que usar el puerto 22 podría tener alguna mala influencia, que no era el caso):

socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET6, sin6_port=htons(54321), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
getsockname(3, {sa_family=AF_INET6, sin6_port=htons(38289), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
connect(3, {sa_family=AF_UNSPEC, sa_data="\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(54321), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(3, {sa_family=AF_INET6, sin6_port=htons(60866), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
close(3)                                = 0

Obviamente, la decisión está destinada a tomar lugar de acuerdo con los resultados de lagetsockname() llamadas ...

BTW:https: //bugs.launchpad.net/ubuntu/+source/eglibc/+bug/67370 y los otros informes de errores mencionados allí confirman mis observaciones. Varias personas afirman que el nuevo comportamiento es correcto, por lo que obviamente estoy atascado en usarAF_INET6 ...: -

Respuestas a la pregunta(2)

Su respuesta a la pregunta