c++ - tengo - ipv6 es compatible con ipv4
Cómo admitir conexiones IPv4 e IPv6 (4)
He estado jugando con esto en Windows y en realidad parece ser un problema de seguridad allí, si se vincula a la dirección de bucle invertido, entonces el socket IPv6 está ligado correctamente a [:: 1] pero el socket IPv4 asignado está obligado a INADDR_ANY , por lo que su aplicación (supuestamente) local segura solo está realmente expuesta al mundo.
Actualmente estoy trabajando en una aplicación de socket UDP y necesito crear soporte para que las conexiones IPV4 e IPV6 puedan enviar paquetes a un servidor.
Esperaba que alguien pudiera ayudarme y apuntarme en la dirección correcta; la mayoría de la documentación que encontré no estaba completa. También sería útil si pudieras señalar cualquier diferencia entre los sockets de Winsock y BSD.
¡Gracias por adelantado!
La API de socket está gobernada por IETF RFC y debe ser la misma en todas las plataformas, incluida Windows WRT IPv6.
Para aplicaciones IPv4 / IPv6 es TODO acerca de getaddrinfo()
y getnameinfo()
. getaddrinfo
es un genio: examina el DNS, los nombres de los puertos y las capacidades del cliente para resolver la eterna pregunta de "¿Puedo usar IPv4, IPv6 o ambos para llegar a un destino en particular?" O si va a la ruta de doble pila y quiere que devuelva direcciones IPv6 mapeadas IPv4, también lo hará.
Proporciona una estructura directa de sockaddr *
que se puede conectar a bind()
, recvfrom()
, sendto()
y la familia de direcciones para socket()
... En muchos casos esto significa que no hay estructuras sockaddr_in(6)
desordenadas para completar y tratar .
Para las implementaciones UDP, tendría cuidado al establecer sockets de doble pila o, de manera más general, vincular a todas las interfaces ( INADDR_ANY
). El problema clásico es que, cuando las direcciones no están bloqueadas (ver bind()
) a interfaces específicas y el sistema tiene múltiples solicitudes de interfaces, las respuestas pueden transitar desde diferentes direcciones para computadoras con múltiples direcciones basadas en los caprichos de la tabla de enrutamiento del sistema operativo. protocolos de aplicación confusos, especialmente cualquier sistema con requisitos de autenticación.
Para las implementaciones UDP donde esto no es un problema, o TCP, los sockets de doble pila pueden ahorrar mucho tiempo cuando IPv * -el funcionamiento de su sistema. Hay que tener cuidado de no confiar completamente en dual-stack donde no es absolutamente necesario ya que no hay escasez de plataformas razonables (Old Linux, BSD, Windows 2003) implementadas con pilas IPv6 que no sean capaces de sockets de doble pila.
Los RFC realmente no especifican la existencia de la opción de socket IPV6_V6ONLY, pero, si está ausente, los RFC son bastante claros de que la implementación debería ser como si esa opción fuera FALSA.
Donde la opción está presente, yo argumentaría que debería ser FALSE por defecto, pero, por razones que pasan comprensión, las implementaciones de BSD y Windows son predeterminadas a TRUE. Existe una extraña afirmación de que se trata de un problema de seguridad porque un programador de IPv6 desconocido podría vincularse pensando que solo estaban vinculados a IN6ADDR_ANY solo para IPv6 y accidentalmente aceptan una conexión IPv4 que causa un problema de seguridad. Creo que esto es absurdo y absurdo, además de una sorpresa para cualquiera que espera una implementación compatible con RFC.
En el caso de Windows, la falta de cumplimiento no suele ser una sorpresa. En el caso de BSD, esto es desafortunado en el mejor de los casos.
El mejor enfoque es crear un socket de servidor IPv6 que también pueda aceptar conexiones IPv4. Para hacerlo, cree un socket IPv6 regular, desactive la opción de socket IPV6_V6ONLY
, IPV6_V6ONLY
a la dirección "any" y comience a recibir. Las direcciones IPv4 se presentarán como direcciones IPv6, en el formato IPv4-mapped .
La principal diferencia entre sistemas es si IPV6_V6ONLY
está a) disponible, y b) está activado o desactivado de forma predeterminada. Está desactivado por defecto en Linux (es decir, permite sockets de doble pila sin setsockopt), y está activado en la mayoría de los otros sistemas.
Además, la pila IPv6 en Windows XP no admite esa opción. En estos casos, deberá crear dos sockets de servidor separados y colocarlos en seleccionar o en varios hilos.