Dual-Stack Sockets für IPv6 Winsock-Anwendungen
Um sowohl IPv4 als auch IPv6 unter Windows XP mit Service Pack 1 (SP1) und Windows Server 2003 zu unterstützen, muss eine Anwendung zwei Sockets erstellen, einen Socket für die Verwendung mit IPv4 und einen Socket für die Verwendung mit IPv6. Diese beiden Sockets müssen separat von der Anwendung behandelt werden.
Windows Vista und höher bieten die Möglichkeit, einen einzelnen IPv6-Socket zu erstellen, der sowohl IPv6- als auch IPv4-Datenverkehr verarbeiten kann. Beispielsweise wird ein TCP-Überwachungssocket für IPv6 erstellt, in den Dual-Stack-Modus versetzt und an Port 5001 gebunden. Dieser Dualstapel-Socket kann Verbindungen von IPv6-TCP-Clients akzeptieren, die eine Verbindung mit Port 5001 herstellen, und von IPv4-TCP-Clients, die eine Verbindung mit Port 5001 herstellen. Dieses Feature ermöglicht einen erheblich vereinfachten Anwendungsentwurf und reduziert den Ressourcenaufwand für Buchungen in zwei separaten Sockets.
Erstellen eines Dual-Stack Sockets
Standardmäßig wird ein auf Windows Vista erstelltes IPv6-Socket und höher nur über das IPv6-Protokoll ausgeführt. Damit ein IPv6-Socket in einen Dualstapel-Socket umgewandelt werden kann, muss die setockopt--Funktion mit der IPV6_V6ONLY Socketoption aufgerufen werden, um diesen Wert auf Null festzulegen, bevor der Socket an eine IP-Adresse gebunden ist. Wenn die IPV6_V6ONLY Socketoption auf Null festgelegt ist, kann ein socket, der für die AF_INET6 Adressfamilie erstellt wurde, verwendet werden, um Pakete an und von einer IPv6-Adresse oder einer zugeordneten IPv4-Adresse zu senden und zu empfangen.
IP-Adressen mit einem Dual-Stack Socket
Dual-Stack-Sockets erfordern immer IPv6-Adressen. Für die Interaktion mit einer IPv4-Adresse ist die Verwendung des IPv4-zugeordneten IPv6-Adressformats erforderlich. Alle IPv4-Adressen müssen im IPv4-zugeordneten IPv6-Adressformat dargestellt werden, mit dem eine IPv6-Anwendung nur mit einem IPv4-Knoten kommunizieren kann. Mit dem IPv4-zugeordneten IPv6-Adressformat kann die IPv4-Adresse eines IPv4-Knotens als IPv6-Adresse dargestellt werden. Die IPv4-Adresse wird in die 32 Bits der IPv6-Adresse mit niedriger Reihenfolge codiert, und die 96-Bit-Hochreihenfolgen enthalten das feste Präfix 0:0:0:0:0:FFFF. Das IPv4-zugeordnete IPv6-Adressformat wird in RFC 4291 angegeben. Weitere Informationen finden Sie unter www.ietf.org/rfc/rfc4291.txt. Das IN6ADDR_SETV4MAPPED Makro in Mstcpip.h kann verwendet werden, um eine IPv4-Adresse in das erforderliche IPv4-zugeordnete IPv6-Adressformat zu konvertieren.
Wenn das zugrunde liegende Protokoll tatsächlich IPv4 ist, wird die IPv4-Adresse einem IPv4-zugeordneten IPv6-Adressformat zugeordnet. Das ist das Familienfeld in der SOCKADDR--Struktur, gibt AF_INET6 an, aber eine IPv4-zugeordnete IPv6-Adresse wird in der IPv6-Adressstruktur codiert. Bei einem Dualstapel-Socket im Überwachungsmodus bedeutet dies, dass alle akzeptierten IPv4-Verbindungen eine IPv4-zugeordnete IPv6-Adresse zurückgeben. Bei einem Dualstapel-Socket, der eine Verbindung mit einem IPv4-Ziel herstellt, muss die an die Verbindung übergebene SOCKADDR-Struktur eine IPv4-zugeordnete IPv6-Adresse sein. Anwendungen müssen diese IPv4-zugeordneten IPv6-Adressen entsprechend behandeln und nur mit dualen Stapelsockets verwenden. Wenn eine IP-Adresse an einen regulären IPv4-Socket übergeben werden soll, muss die Adresse eine normale IPv4-Adresse sein, keine IPv4-zugeordnete IPv6-Adresse.
Mögliche Probleme mit einem Dual-Stack Socket
Ein potenzieller Fall für Anwendungen besteht darin, eine IPv4-zugeordnete IPv6-Adresse in einem Dualstapel-Socket zu erhalten und dann zu versuchen, die zurückgegebene IP-Adresse für einen anderen IPv6-Socket zu verwenden. Beispielsweise können die getockname oder getpeername Funktionen eine IPv4-zugeordnete IPv6-Adresse zurückgeben, wenn sie in einem Dualstapel-Socket verwendet wird. Wenn die zurückgegebene IPv4-zugeordnete IPv6-Adresse anschließend für einen anderen Socket verwendet wird, der nicht auf dualen Stapel festgelegt wurde (ein IPv6-Socket, der das Standardverhalten ist, wenn ein Socket erstellt wird), schlägt jede Verwendung dieses IPv6-Nur-Sockets mit einer IPv4-zugeordneten IPv6-Adresse fehl. Das IPv4-zugeordnete IPv6-Adressformat kann nur in einem Dualstapel-Socket verwendet werden.
Bei einem Dualstapel-Datagrammsocket, wenn eine Anwendung die LPFN_WSARECVMSG (WSARecvMsg)-Funktion benötigt, um Paketinformationen in einer WSAMSG--Struktur für über IPv4 empfangene Datagramme zurückzugeben, muss IP_PKTINFO Socketoption für den Socket auf "true" festgelegt werden. Wenn nur die Option IPV6_PKTINFO auf "true" für den Socket festgelegt ist, werden Paketinformationen für über IPv6 empfangene Datagramme bereitgestellt, können jedoch nicht für über IPv4 empfangene Datagramme bereitgestellt werden.
Wenn eine Anwendung versucht, die IP_PKTINFO Socketoption für einen Dualstapel-Datagrammsocket festzulegen, und IPv4 im System deaktiviert ist, schlägt die setockopt--Funktion fehl, und WSAGetLastError wird mit einem Fehler von WSAEINVALzurückgegeben. Dieser Fehler wird auch durch die setockopt- Funktion als Ergebnis anderer Fehler zurückgegeben. Wenn eine Anwendung versucht, eine Socketoption auf IPPROTO_IP Ebene für einen Dualstapel-Socket festzulegen und mit WSAEINVALfehlschlägt, sollte die Anwendung ermitteln, ob IPv4 auf dem lokalen Computer deaktiviert ist. Eine Methode, die verwendet werden kann, um zu erkennen, ob IPv4 aktiviert oder deaktiviert ist, besteht darin, die Socket--Funktion aufzurufen, wobei der af-Parameter auf AF_INET festgelegt ist, um einen IPv4-Socket zu erstellen. Wenn die Socket--Funktion fehlschlägt und WSAGetLastError einen Fehler von WSAEAFNOSUPPORTzurückgibt, bedeutet dies, dass IPv4 nicht aktiviert ist. In diesem Fall kann ein setockopt- Funktionsfehler beim Festlegen der IP_PKTINFO Socketoption von der Anwendung ignoriert werden. Andernfalls sollte ein Fehler beim Festlegen der IP_PKTINFO Socketoption als unerwarteter Fehler behandelt werden.
Bei einem Dualstapel-Socket beim Senden von Datagrammen mit der WSASendMsg-Funktion und eine Anwendung möchte eine bestimmte lokale IP-Quelladresse angeben, die verwendet werden soll, hängt die Methode zur Verarbeitung von der Ziel-IP-Adresse ab. Beim Senden an eine IPv4-Zieladresse oder eine IPv4-zugeordnete IPv6-Zieladresse sollte eines der Steuerelementdatenobjekte, die in der WSAMSG- Struktur übergeben werden, auf die der lpMsg Parameter verweist, eine in_pktinfo Struktur enthalten, die die lokale IPv4-Quelladresse enthält, die zum Senden verwendet werden soll. Beim Senden an eine IPv6-Zieladresse, die keine IPv4-zugeordnete IPv6-Adresse ist, sollte eines der Steuerelementdatenobjekte, die in der WSAMSG- Struktur übergeben werden, auf die der lpMsg-Parameter verweist, eine in6_pktinfo Struktur enthalten, die die lokale IPv6-Quelladresse enthält, die zum Senden verwendet werden soll.
Verwandte Themen