Delen via


Dual-Stack Sockets voor IPv6 Winsock-toepassingen

Om zowel IPv4 als IPv6 op Windows XP te ondersteunen met Service Pack 1 (SP1) en windows Server 2003, moet een toepassing twee sockets maken, één socket voor gebruik met IPv4 en één socket voor gebruik met IPv6. Deze twee sockets moeten afzonderlijk worden verwerkt door de toepassing.

Windows Vista en hoger bieden de mogelijkheid om één IPv6-socket te maken die zowel IPv6- als IPv4-verkeer kan verwerken. Er wordt bijvoorbeeld een TCP-luistersocket voor IPv6 gemaakt, in de dual-stackmodus geplaatst en gebonden aan poort 5001. Deze dual-stack socket kan verbindingen van IPv6 TCP-clients accepteren die verbinding maken met poort 5001 en van IPv4 TCP-clients die verbinding maken met poort 5001. Deze functie biedt een aanzienlijk vereenvoudigd toepassingsontwerp en vermindert de resourceoverhead die nodig is voor het boeken van bewerkingen op twee afzonderlijke sockets.

Een Dual-Stack Socket maken

Standaard werkt een IPv6-socket die is gemaakt op Windows Vista en later alleen via het IPv6-protocol. Als u een IPv6-socket in een dubbele stack-socket wilt maken, moet de setsockopt--functie worden aangeroepen met de IPV6_V6ONLY socketoptie om deze waarde in te stellen op nul voordat de socket is gebonden aan een IP-adres. Wanneer de IPV6_V6ONLY socketoptie is ingesteld op nul, kan een socket die is gemaakt voor de AF_INET6-adresfamilie worden gebruikt voor het verzenden en ontvangen van pakketten naar en van een IPv6-adres of een toegewezen IPv4-adres.

IP-adressen met een Dual-Stack Socket

Dual-stack sockets vereisen altijd IPv6-adressen. De mogelijkheid om te communiceren met een IPv4-adres vereist het gebruik van de IPv4-adresindeling die is toegewezen aan IPv6. Alle IPv4-adressen moeten worden weergegeven in de IPv4-adresindeling die een IPv6-toepassing in staat stelt om alleen met een IPv4-knooppunt te communiceren. Met de IPv4-adresindeling voor IPv6-adressen kan het IPv4-adres van een IPv4-knooppunt worden weergegeven als een IPv6-adres. Het IPv4-adres wordt gecodeerd in de lage volgorde van 32 bits van het IPv6-adres en de 96 bits met hoge volgorde bevatten het vaste voorvoegsel 0:0:0:0:0:FFFF. De IPv4-adresindeling die is toegewezen aan IPv6 wordt opgegeven in RFC 4291. Zie www.ietf.org/rfc/rfc4291.txtvoor meer informatie. De IN6ADDR_SETV4MAPPED macro in Mstcpip.h kan worden gebruikt om een IPv4-adres te converteren naar de vereiste IPv4-adresindeling.

Als het onderliggende protocol in werkelijkheid IPv4 is, wordt het IPv4-adres toegewezen aan een IPv4-adresindeling die is toegewezen aan IPv6. Dat is het familieveld in de SOCKADDR structuur geeft AF_INET6 aan, maar een IPv4-toegewezen IPv6-adres wordt gecodeerd in de IPv6-adresstructuur. Voor een dual-stack socket in de luistermodus betekent dit dat alle geaccepteerde IPv4-verbindingen een IPv4-toegewezen IPv6-adres retourneren. Voor een dual-stack socket die verbinding maakt met een IPv4-doel, moet de SOCKADDR-structuur die is doorgegeven om verbinding te maken, een IPv4-adres zijn dat is toegewezen aan IPv6. Toepassingen moeten ervoor zorgen dat deze IPv4-toegewezen IPv6-adressen op de juiste wijze worden verwerkt en alleen worden gebruikt met dubbele stacksockets. Als een IP-adres moet worden doorgegeven aan een gewone IPv4-socket, moet het adres een normaal IPv4-adres zijn dat geen IPv4-toegewezen IPv6-adres is.

Mogelijke problemen met het gebruik van een Dual-Stack Socket

Een mogelijke valkuil voor toepassingen is het verkrijgen van een IPv4-toegewezen IPv6-adres op een dual-stack socket en vervolgens probeert het geretourneerde IP-adres op een andere IPv6-socket te gebruiken. De functie getockname of getpeername functies kan bijvoorbeeld een IPv4-toegewezen IPv6-adres retourneren wanneer deze wordt gebruikt op een dual-stack-socket. Als het geretourneerde IPv4-toegewezen IPv6-adres vervolgens wordt gebruikt op een andere socket die niet is ingesteld op dual-stack (een IPv6-alleen socket die het standaardgedrag is wanneer een socket wordt gemaakt), mislukt elk gebruik van deze IPv6-socket met een IPv4-toegewezen IPv6-adres. De IPv4-adresindeling die is toegewezen aan IPv6 kan alleen worden gebruikt op een dubbele stack-socket.

Als voor een toepassing de LPFN_WSARECVMSG (WSARecvMsg) functie is vereist voor het retourneren van pakketgegevens in een WSAMSG- structuur voor gegevensgrammen die via IPv4 zijn ontvangen, moet IP_PKTINFO socketoptie worden ingesteld op waar op de socket. Als alleen de IPV6_PKTINFO optie is ingesteld op true op de socket, wordt pakketinformatie verstrekt voor gegevensgrammen die zijn ontvangen via IPv6, maar mogelijk niet worden opgegeven voor datagrammen die zijn ontvangen via IPv4.

Als een toepassing probeert de IP_PKTINFO socketoptie in te stellen op een datagramsocket met dubbele stack en IPv4 is uitgeschakeld op het systeem, mislukt de setsockopt functie en WSAGetLastError- wordt geretourneerd met een fout van WSAEINVAL. Dezelfde fout wordt ook geretourneerd door de setsockopt functie als gevolg van andere fouten. Als een toepassing probeert een IPPROTO_IP level socket-optie in te stellen op een dubbele stack socket en deze mislukt met WSAEINVAL, moet de toepassing bepalen of IPv4 is uitgeschakeld op de lokale computer. Een methode die kan worden gebruikt om te detecteren of IPv4 is ingeschakeld of uitgeschakeld, is door de socket--functie aan te roepen met de parameter af ingesteld op AF_INET om een IPv4-socket te maken. Als de socket functie mislukt en WSAGetLastError een fout retourneert van WSAEAFNOSUPPORT-, betekent dit dat IPv4 niet is ingeschakeld. In dit geval kan een setsockopt functiefout bij het instellen van de IP_PKTINFO socketoptie worden genegeerd door de toepassing. Anders moet een fout bij het instellen van de IP_PKTINFO socketoptie worden behandeld als een onverwachte fout.

Voor een dual-stack socket bij het verzenden van datagrammen met de WSASendMsg-functie en een toepassing wil een specifiek lokaal IP-bronadres opgeven dat moet worden gebruikt, is de methode om dit te verwerken afhankelijk van het doel-IP-adres. Bij het verzenden naar een IPv4-doeladres of een IPv4-doeladres dat is toegewezen aan IPv6, moet een van de besturingsgegevensobjecten die zijn doorgegeven in de WSAMSG--structuur waarnaar wordt verwezen door de parameter lpMsg- een in_pktinfo structuur bevatten die het lokale IPv4-bronadres bevat dat moet worden gebruikt voor verzenden. Wanneer u verzendt naar een IPv6-doeladres dat geen IPv4-adres is dat is toegewezen aan IPv6, moet een van de besturingsgegevensobjecten die zijn doorgegeven in de WSAMSG--structuur waarnaar wordt verwezen door de parameter lpMsg een in6_pktinfo structuur bevatten die het lokale IPv6-bronadres bevat dat moet worden gebruikt voor verzenden.

IPv6-handleiding voor Windows Sockets-toepassingen

Gegevensstructuren wijzigen voor IPv6 Winsock-appications

functieoproepen voor IPv6 Winsock-toepassingen

Gebruik van in code vastgelegde IPv4-adressen

problemen met de gebruikersinterface voor IPv6 Winsock-toepassingen

onderliggende protocollen voor IPv6 Winsock-toepassingen

getpeername

getsockname

in_pktinfo

in6_pktinfo

IP_PKTINFO

IPV6_PKTINFO

setsockopt-

LPFN_WSARECVMSG (WSARecvMsg)

WSASendMsg-