Dela via


Dual-Stack Sockets för IPv6 Winsock-program

För att stödja både IPv4 och IPv6 i Windows XP med Service Pack 1 (SP1) och på Windows Server 2003 måste ett program skapa två socketar, en socket för användning med IPv4 och en socket för användning med IPv6. Dessa två socketar måste hanteras separat av programmet.

Windows Vista och senare erbjuder möjligheten att skapa en enda IPv6-socket som kan hantera både IPv6- och IPv4-trafik. Till exempel skapas en TCP-lyssningssocket för IPv6, placeras i läget för dubbla staplar och binds till port 5001. Den här socketen med dubbla staplar kan acceptera anslutningar från IPv6 TCP-klienter som ansluter till port 5001 och från IPv4 TCP-klienter som ansluter till port 5001. Den här funktionen möjliggör mycket förenklad programdesign och minskar de resurskostnader som krävs för att publicera åtgärder på två separata socketar.

Skapa en Dual-Stack Socket

Som standard fungerar en IPv6-socket som skapats i Windows Vista och senare endast via IPv6-protokollet. För att kunna göra en IPv6-socket till en socket med dubbla staplar måste funktionen setsockopt anropas med alternativet IPV6_V6ONLY socket för att ange värdet till noll innan socketen är bunden till en IP-adress. När alternativet IPV6_V6ONLY socket är inställt på noll kan en socket som skapats för AF_INET6-adressfamiljen användas för att skicka och ta emot paket till och från en IPv6-adress eller en IPv4-mappad adress.

IP-adresser med en Dual-Stack Socket

Socketar med dubbla staplar kräver alltid IPv6-adresser. Möjligheten att interagera med en IPv4-adress kräver användning av IPv4-mappat IPv6-adressformat. Alla IPv4-adresser måste representeras i IPv4-mappat IPv6-adressformat som gör att ett IPv6-program endast kan kommunicera med en IPv4-nod. Med IPv4-mappat IPv6-adressformat kan IPv4-adressen för en IPv4-nod representeras som en IPv6-adress. IPv4-adressen kodas till 32 bitar av IPv6-adressen i låg ordning och 96 bitar med hög ordning innehåller det fasta prefixet 0:0:0:0:0:FFFF. IPv4-mappat IPv6-adressformat anges i RFC 4291. Mer information finns i www.ietf.org/rfc/rfc4291.txt. Det IN6ADDR_SETV4MAPPED makrot i Mstcpip.h kan användas för att konvertera en IPv4-adress till det IPv4-mappade IPv6-adressformatet.

Om det underliggande protokollet faktiskt är IPv4 mappas IPv4-adressen till ett IPv4-mappat IPv6-adressformat. Det är familjefältet i SOCKADDR- struktur anger AF_INET6, men en IPv4-mappad IPv6-adress kodas i IPv6-adressstrukturen. För en socket med dubbla staplar i lyssningsläge innebär det att alla godkända IPv4-anslutningar returnerar en IPv4-mappad IPv6-adress. För en socket med dubbla staplar som ansluter till ett IPv4-mål måste SOCKADDR-strukturen som skickas för att ansluta vara en IPv4-mappad IPv6-adress. Program måste vara noga med att hantera dessa IPv4-mappade IPv6-adresser på rätt sätt och endast använda dem med dubbla stack-socketar. Om en IP-adress ska skickas till en vanlig IPv4-socket måste adressen vara en vanlig IPv4-adress, inte en IPv4-mappad IPv6-adress.

Potentiella problem med att använda en Dual-Stack Socket

En potentiell fallgrop för program är att få en IPv4-mappad IPv6-adress på en socket med dubbla staplar och sedan försöka använda den returnerade IP-adressen på en annan IPv6-socket. Till exempel kan funktionerna getockname eller getpeername returnera en IPv4-mappad IPv6-adress när den används på en socket med dubbla staplar. Om den returnerade IPv4-mappade IPv6-adressen sedan används på en annan socket som inte har angetts till dubbelstack (endast en IPv6-socket som är standardbeteendet när en socket skapas), misslyckas all användning av den här IPv6-socketen med en IPv4-mappad IPv6-adress. Det IPv4-mappade IPv6-adressformatet kan bara användas på en socket med dubbla staplar.

Om ett program kräver funktionen LPFN_WSARECVMSG (WSARecvMsg) för att returnera paketinformation i en WSAMSG- struktur för datagram som tagits emot via IPv4 måste alternativet för IP_PKTINFO socket anges till true på socketen på ett datagram som tas emot via IPv4. Om endast alternativet IPV6_PKTINFO är inställt på true på socketen, kommer paketinformation att tillhandahållas för datagram som tas emot via IPv6 men kanske inte tillhandahålls för datagram som tagits emot via IPv4.

Om ett program försöker ange alternativet IP_PKTINFO socket på ett datagramsockel med dubbla staplar och IPv4 är inaktiverat i systemet, kommer funktionen setsockopt att misslyckas och WSAGetLastError- returneras med felet WSAEINVAL. Samma fel returneras också av funktionen setsockopt till följd av andra fel. Om ett program försöker ange ett IPPROTO_IP socketalternativ på en socket med dubbla staplar och det misslyckas med WSAEINVAL-bör programmet avgöra om IPv4 är inaktiverat på den lokala datorn. En metod som kan användas för att identifiera om IPv4 är aktiverad eller inaktiverad är att anropa funktionen socket med parametern af inställd på AF_INET för att försöka skapa en IPv4-socket. Om funktionen socket misslyckas och WSAGetLastError returnerar ett fel i WSAEAFNOSUPPORTbetyder det att IPv4 inte är aktiverat. I det här fallet kan ett setsockopt funktionsfel när du försöker ange alternativet IP_PKTINFO socket ignoreras av programmet. Annars bör ett fel vid försök att ange alternativet IP_PKTINFO socket behandlas som ett oväntat fel.

För en socket med dubbla staplar när du skickar datagram med funktionen WSASendMsg och ett program vill ange en specifik lokal IP-källadress som ska användas, beror metoden för att hantera detta på målets IP-adress. När du skickar till en IPv4-måladress eller en IPv4-mappad IPv6-måladress ska ett av kontrolldataobjekten som skickas i WSAMSG- struktur som pekas på av lpMsg-parametern innehålla en in_pktinfo struktur som innehåller den lokala IPv4-källadressen som ska användas för att skicka. När du skickar till en IPv6-måladress som inte är en IPv4-mappad IPv6-adress ska ett av kontrolldataobjekten som skickas i WSAMSG- struktur som pekas på av lpMsg-parametern innehålla en in6_pktinfo struktur som innehåller den lokala IPv6-källadressen som ska användas för att skicka.

IPv6-guide för Windows Sockets-program

Ändra datastrukturer för IPv6 Winsock-appicationer

Funktionsanrop för IPv6 Winsock-program

användning av hårdkodade IPv4-adresser

problem med användargränssnittet för IPv6 Winsock-program

underliggande protokoll för IPv6 Winsock-program

getpeername

getsockname

in_pktinfo

in6_pktinfo

IP_PKTINFO

IPV6_PKTINFO

setsockopt

LPFN_WSARECVMSG (WSARecvMsg)

WSASendMsg