sockets Dual-Stack pour les applications Winsock IPv6

Pour prendre en charge À la fois IPv4 et IPv6 sur Windows XP avec Service Pack 1 (SP1) et sur Windows Server 2003, une application doit créer deux sockets, un socket à utiliser avec IPv4 et un socket pour une utilisation avec IPv6. Ces deux sockets doivent être gérés séparément par l’application.

Windows Vista et versions ultérieures offrent la possibilité de créer un seul socket IPv6 qui peut gérer à la fois le trafic IPv6 et IPv4. Par exemple, un socket d’écoute TCP pour IPv6 est créé, placé en mode double pile et lié au port 5001. Ce socket double pile peut accepter des connexions à partir de clients TCP IPv6 qui se connectent au port 5001 et à partir de clients TCP IPv4 se connectant au port 5001. Cette fonctionnalité permet une conception d’application considérablement simplifiée et réduit la surcharge de ressources requise pour les opérations de publication sur deux sockets distincts.

Création d’un socket Dual-Stack

Par défaut, un socket IPv6 créé sur Windows Vista et versions ultérieures fonctionne uniquement sur le protocole IPv6. Pour transformer un socket IPv6 en socket double pile, la fonction setsockopt doit être appelée avec l’option de socket IPV6_V6ONLY pour définir cette valeur sur zéro avant que le socket ne soit lié à une adresse IP. Lorsque l’option de socket IPV6_V6ONLY est définie sur zéro, un socket créé pour la famille d’adresses AF_INET6 peut être utilisé pour envoyer et recevoir des paquets vers et à partir d’une adresse IPv6 ou d’une adresse mappée IPv4.

Adresses IP avec un socket Dual-Stack

Les sockets à double pile nécessitent toujours des adresses IPv6. La possibilité d’interagir avec une adresse IPv4 nécessite l’utilisation du format d’adresse IPv6 mappé iPv4. Toutes les adresses IPv4 doivent être représentées dans le format d’adresse IPv6 mappée par IPv4, qui permet à une application IPv6 uniquement de communiquer avec un nœud IPv4. Le format d’adresse IPv6 mappé iPv4 permet de représenter l’adresse IPv4 d’un nœud IPv4 en tant qu’adresse IPv6. L’adresse IPv4 est encodée dans les 32 bits de bas ordre de l’adresse IPv6, et les 96 bits d’ordre élevé contiennent le préfixe fixe 0:0:0:0:0:0:FFFF. Le format d’adresse IPv6 mappé IPv4 est spécifié dans RFC 4291. Pour plus d’informations, consultez www.ietf.org/rfc/rfc4291.txt. La macro IN6ADDR_SETV4MAPPED dans Mstcpip.h peut être utilisée pour convertir une adresse IPv4 au format d’adresse IPv6 IPv4 requis.

Si le protocole sous-jacent est en fait IPv4, l’adresse IPv4 est mappée dans un format d’adresse IPv6 mappé. Le champ famille de la structure SOCKADDR indique AF_INET6, mais une adresse IPv6 mappée iPv4 est encodée dans la structure d’adresse IPv6. Pour un socket double pile en mode d’écoute, cela signifie que toutes les connexions IPv4 acceptées retournent une adresse IPv6 mappée. Pour un socket double pile qui se connecte à une destination IPv4, la structure SOCKADDR passée pour se connecter doit être une adresse IPv6 mappée. Les applications doivent prendre soin de gérer ces adresses IPv6 mappées IPv4 de manière appropriée et ne les utiliser qu’avec des sockets à double pile. Si une adresse IP doit être passée à un socket IPv4 normal, l’adresse doit être une adresse IPv4 standard et non une adresse IPv6 mappée.

Problèmes potentiels à l’aide d’un socket Dual-Stack

Un piège potentiel pour les applications consiste à obtenir une adresse IPv6 mappée IPv4 sur un socket double pile, puis à essayer d’utiliser l’adresse IP retournée sur un autre socket IPv6 uniquement. Par exemple, les fonctions getockname ou getpeername peuvent retourner une adresse IPv6 mappée IPv4 lorsqu’elles sont utilisées sur un socket à double pile. Si l’adresse IPv6 iPv4 retournée est ensuite utilisée sur un autre socket qui n’a pas été défini sur double pile (socket IPv6 uniquement qui est le comportement par défaut lors de la création d’un socket), toute utilisation de ce socket IPv6 uniquement avec une adresse IPv6 mappée IPv6 échouera. Le format d’adresse IPv6 mappé IPv4 ne peut être utilisé que sur un socket double pile.

Sur un socket de datagramme à double pile, si une application nécessite la fonction LPFN_WSARECVMSG (WSARecvMsg) pour retourner les informations de paquet dans une structure WSAMSG pour les datagrammes reçus via IPv4, IP_PKTINFO option de socket doit avoir la valeur true sur le socket. Si seule l’option IPV6_PKTINFO est définie sur true sur le socket, les informations de paquet sont fournies pour les datagrammes reçus via IPv6, mais ne peuvent pas être fournies pour les datagrammes reçus via IPv4.

Si une application tente de définir l’option de socket IP_PKTINFO sur un socket de datagramme à double pile et qu’IPv4 est désactivé sur le système, la fonction setsockopt échoue et WSAGetLastError retourne une erreur de WSAEINVAL. Cette même erreur est également retournée par la fonction setsockopt à la suite d’autres erreurs. Si une application tente de définir une option de socket de niveau IPPROTO_IP sur un socket à double pile et qu’elle échoue avec WSAEINVAL, l’application doit déterminer si IPv4 est désactivé sur l’ordinateur local. Une méthode qui peut être utilisée pour détecter si IPv4 est activé ou désactivé consiste à appeler la fonction socket avec le paramètre af défini sur AF_INET pour essayer de créer un socket IPv4. Si la fonction socket échoue et que WSAGetLastError retourne une erreur de WSAEAFNOSUPPORT, cela signifie qu’IPv4 n’est pas activé. Dans ce cas, un échec de la fonction setsockopt lors de la tentative de définition de l’option de socket IP_PKTINFO peut être ignoré par l’application. Sinon, un échec lors de la tentative de définition de l’option de socket IP_PKTINFO doit être traité comme une erreur inattendue.

Pour un socket à double pile lors de l’envoi de datagrammes avec la fonction WSASendMsg et qu’une application souhaite spécifier une adresse IP source locale spécifique à utiliser, la méthode pour gérer cela dépend de l’adresse IP de destination. Lors de l’envoi à une adresse de destination IPv4 ou à une adresse de destination IPv4 mappée par IPv4, l’un des objets de données de contrôle transmis dans la structure WSAMSG pointée par le paramètre lpMsg doit contenir une structure in_pktinfo contenant l’adresse source IPv4 locale à utiliser pour l’envoi. Lors de l’envoi à une adresse de destination IPv6 qui n’est pas une adresse IPv6 mappée par IPv4, l’un des objets de données de contrôle transmis dans la structure WSAMSG pointée par le paramètre lpMsg doit contenir une structure in6_pktinfo contenant l’adresse source IPv6 locale à utiliser pour l’envoi.

Guide IPv6 pour les applications de sockets Windows

Modification des structures de données pour les applications Winsock IPv6

Appels de fonction pour les applications Winsock IPv6

Utilisation d’adresses IPv4 codées en dur

Problèmes d’interface utilisateur pour les applications Winsock IPv6

Protocoles sous-jacents pour les applications Winsock IPv6

getpeername

getsockname

in_pktinfo

in6_pktinfo

IP_PKTINFO

IPV6_PKTINFO

setockopt

LPFN_WSARECVMSG (WSARecvMsg)

WSASendMsg