Udostępnij za pośrednictwem


Dual-Stack Sockets for IPv6 Winsock Applications (Gniazda Dual-Stack dla aplikacji Winsock IPv6)

Aby obsługiwać zarówno protokoły IPv4, jak i IPv6 w systemie Windows XP z dodatkiem Service Pack 1 (SP1) i w systemie Windows Server 2003, aplikacja musi utworzyć dwa gniazda, jedno gniazdo do użycia z protokołem IPv4 i jedno gniazdo do użycia z protokołem IPv6. Te dwa gniazda muszą być obsługiwane oddzielnie przez aplikację.

System Windows Vista i nowsze oferują możliwość utworzenia pojedynczego gniazda IPv6, które może obsługiwać ruch IPv6 i IPv4. Na przykład jest tworzone gniazdo nasłuchiwania TCP dla protokołu IPv6, umieszczane w trybie podwójnego stosu i powiązane z portem 5001. To gniazdo z dwoma stosami może akceptować połączenia od klientów TCP IPv6 łączących się z portem 5001 i z klientów PROTOKOŁU IPv4 łączących się z portem 5001. Ta funkcja umożliwia znacznie uproszczone projektowanie aplikacji i zmniejsza nakład pracy związany z zasobami wymaganymi do delegowania operacji na dwóch oddzielnych gniazdach.

Tworzenie gniazda Dual-Stack

Domyślnie gniazdo IPv6 utworzone w systemie Windows Vista i nowszych działa tylko za pośrednictwem protokołu IPv6. Aby można było utworzyć gniazdo IPv6 do gniazda z dwoma stosami, funkcja setsockopt musi być wywoływana z opcją gniazda IPV6_V6ONLY, aby ustawić tę wartość na zero, zanim gniazdo jest powiązane z adresem IP. Gdy opcja gniazda IPV6_V6ONLY jest ustawiona na zero, gniazdo utworzone dla rodziny adresów AF_INET6 może służyć do wysyłania i odbierania pakietów do i z adresu IPv6 lub zamapowanego adresu IPv4.

Adresy IP z gniazdem Dual-Stack

Gniazda z dwoma stosami zawsze wymagają adresów IPv6. Możliwość interakcji z adresem IPv4 wymaga użycia formatu adresu IPv4 mapowanego protokołu IPv6. Wszystkie adresy IPv4 muszą być reprezentowane w formacie adresów IPv4 mapowanych IPv6, co umożliwia aplikacji IPv6 komunikowanie się tylko z węzłem IPv4. Format adresu IPv4 mapowany za pomocą protokołu IPv6 umożliwia reprezentowanie adresu IPv4 węzła IPv4 jako adresu IPv6. Adres IPv4 jest zakodowany w niskiej kolejności 32 bitów adresu IPv6, a high-order 96 bitów posiadają stały prefiks 0:0:0:0:0:FFFF. Format adresu IPv4 mapowany zamapowany na protokół IPv6 jest określony w specyfikacji RFC 4291. Aby uzyskać więcej informacji, zobacz www.ietf.org/rfc/rfc4291.txt. Makro IN6ADDR_SETV4MAPPED w Mstcpip.h może służyć do konwertowania adresu IPv4 na wymagany format adresu IPv4 mapowanego IPv6.

Jeśli podstawowy protokół jest rzeczywiście IPv4, adres IPv4 jest mapowany na format adresu IPv4 mapowany IPv6. Oznacza to, że pole rodziny w strukturze SOCKADDR wskazuje AF_INET6, ale adres IPv4 mapowany IPv6 jest zakodowany w strukturze adresów IPv6. W przypadku gniazda podwójnego stosu w trybie nasłuchiwania oznacza to, że wszystkie zaakceptowane połączenia IPv4 będą zwracać adres IPv4 mapowany za pomocą protokołu IPv6. W przypadku gniazda z dwoma stosami, które łączy się z miejscem docelowym IPv4, struktura SOCKADDR przekazana do nawiązania połączenia musi być adresem IPv4 mapowanym na protokół IPv6. Aplikacje muszą odpowiednio obsługiwać te adresy IPv4 mapowane za pomocą protokołu IPv6 i używać ich tylko z dwoma gniazdami stosu. Jeśli adres IP ma zostać przekazany do zwykłego gniazda IPv4, adres musi być zwykłym adresem IPv4, a nie adresem IPv4 mapowanym na adres IPv6.

Potencjalne problemy z używaniem Dual-Stack Socket

Potencjalną pułapką dla aplikacji jest uzyskanie adresu IPv4 mapowanego IPv6 na gniazdo dwustosu, a następnie próbuje użyć zwróconego adresu IP na innym gniazdo tylko IPv6. Na przykład funkcja getockname lub getpeername funkcji może zwrócić adres IPv4 mapowany na protokół IPv6, gdy jest używany w gniazdie z dwoma stosami. Jeśli zwrócony adres IPv4-mapowany IPv6 jest następnie używany na innym gniazda, które nie zostało ustawione na podwójny stos (tylko gniazdo IPv6, które jest zachowaniem domyślnym podczas tworzenia gniazda), każde użycie tego gniazda tylko IPv6 z mapowanym adresem IPv4 zakończy się niepowodzeniem. Format adresu IPv4 mapowany za pomocą protokołu IPv6 można używać tylko w gniazdach z dwoma stosami.

W przypadku gniazda datagramu z dwoma stosami, jeśli aplikacja wymaga LPFN_WSARECVMSG (WSARecvMsg) funkcji zwracania informacji o pakiecie w strukturze WSAMSG dla datagramów odebranych za pośrednictwem protokołu IPv4, należy ustawić opcję gniazda IP_PKTINFO na wartość true w gniazdach. Jeśli tylko IPV6_PKTINFO opcja jest ustawiona na wartość true w gniazdie, informacje o pakiecie będą udostępniane dla datagramów odebranych za pośrednictwem protokołu IPv6, ale mogą nie być udostępniane dla datagramów odebranych za pośrednictwem protokołu IPv4.

Jeśli aplikacja spróbuje ustawić opcję gniazda IP_PKTINFO dla gniazda datagramu z dwoma stosami, a protokół IPv4 zostanie wyłączony w systemie, funkcja zakończy się niepowodzeniem, a WSAGetLastError zwróci błąd WSAEINVAL. Ten sam błąd jest również zwracany przez funkcję setsockopt w wyniku innych błędów. Jeśli aplikacja próbuje ustawić opcję gniazda na poziomie IPPROTO_IP na gniazdach z dwoma stosami i kończy się niepowodzeniem z WSAEINVAL, aplikacja powinna określić, czy protokół IPv4 jest wyłączony na komputerze lokalnym. Jedną z metod, które mogą służyć do wykrywania, czy protokół IPv4 jest włączony lub wyłączony, jest wywołanie funkcjigniazdaz parametrem af ustawionym na AF_INET, aby spróbować utworzyć gniazdo IPv4. Jeśli funkcja gniazda kończy się niepowodzeniem i WSAGetLastError zwraca błąd WSAEAFNOSUPPORT, oznacza to, że protokół IPv4 nie jest włączony. W takim przypadku błąd funkcji setsockopt podczas próby ustawienia opcji gniazda IP_PKTINFO można zignorować przez aplikację. W przeciwnym razie błąd podczas próby ustawienia opcji gniazda IP_PKTINFO powinien być traktowany jako nieoczekiwany błąd.

W przypadku gniazda dwustosowego podczas wysyłania datagramów za pomocą funkcji WSASendMsg i aplikacja chce określić określony lokalny adres źródłowy IP do użycia, metoda do obsługi tego zależy od docelowego adresu IP. Podczas wysyłania do adresu docelowego IPv4 lub adresu docelowego IPv4 mapowanego protokołu IPv6 jeden z obiektów danych kontrolnych przekazanych w WSAMSG struktury wskazywanej przez lpMsg parametr powinien zawierać in_pktinfo strukturę zawierającą lokalny adres źródłowy IPv4 do użycia do wysyłania. Podczas wysyłania do adresu docelowego IPv6, który nie jest adresem IPv4 mapowanym IPv6, jeden z obiektów danych kontrolnych przekazanych w WSAMSG struktury wskazywanej przez lpMsg parametr powinien zawierać in6_pktinfo strukturę zawierającą lokalny adres źródłowy IPv6 do użycia do wysyłania.

przewodnik IPv6 dla aplikacji Windows Sockets

zmienianie struktur danych dla IPv6 Winsock Appications

wywołania funkcji dla aplikacji winsock protokołu IPv6

używanie zakodowanych na stałe adresów IPv4

problemy z interfejsem użytkownika dla aplikacji IPv6 Winsock

podstawowych protokołów dla aplikacji Winsock protokołu IPv6

getpeername

getsockname

in_pktinfo

in6_pktinfo

IP_PKTINFO

IPV6_PKTINFO

setsockopt

(WSARecvMsg)LPFN_WSARECVMSG

WSASendMsg