Condividi tramite


Dual-Stack Socket per le applicazioni Winsock IPv6

Per supportare sia IPv4 che IPv6 in Windows XP con Service Pack 1 (SP1) e in Windows Server 2003, un'applicazione deve creare due socket, un socket da usare con IPv4 e un socket da usare con IPv6. Questi due socket devono essere gestiti separatamente dall'applicazione.

Windows Vista e versioni successive offrono la possibilità di creare un singolo socket IPv6 in grado di gestire il traffico IPv6 e IPv4. Ad esempio, viene creato un socket di ascolto TCP per IPv6, viene inserito in modalità dual stack e associato alla porta 5001. Questo socket dual stack può accettare connessioni da client TCP IPv6 che si connettono alla porta 5001 e dai client TCP IPv4 che si connettono alla porta 5001. Questa funzionalità consente una progettazione dell'applicazione notevolmente semplificata e riduce il sovraccarico delle risorse necessario per la registrazione delle operazioni su due socket separati.

Creazione di un socket Dual-Stack

Per impostazione predefinita, un socket IPv6 creato in Windows Vista e versioni successive funziona solo tramite il protocollo IPv6. Per rendere un socket IPv6 in un socket dual stack, è necessario chiamare la funzione setsockopt con l'opzione socket IPV6_V6ONLY per impostare questo valore su zero prima che il socket sia associato a un indirizzo IP. Quando l'opzione socket IPV6_V6ONLY è impostata su zero, è possibile usare un socket creato per la famiglia di indirizzi AF_INET6 per inviare e ricevere pacchetti da e verso un indirizzo IPv6 o un indirizzo mappato IPv4.

Indirizzi IP con un socket Dual-Stack

I socket dual stack richiedono sempre indirizzi IPv6. La possibilità di interagire con un indirizzo IPv4 richiede l'uso del formato di indirizzo IPv4 mappato a IPv6. Tutti gli indirizzi IPv4 devono essere rappresentati nel formato di indirizzi IPv4 mappato a IPv6, che consente a un'applicazione solo IPv6 di comunicare con un nodo IPv4. Il formato di indirizzi IPv4 mappato a IPv6 consente di rappresentare l'indirizzo IPv4 di un nodo IPv4 come indirizzo IPv6. L'indirizzo IPv4 è codificato nei 32 bit di basso ordine dell'indirizzo IPv6 e i 96 bit di ordine elevato contengono il prefisso fisso 0:0:0:0:0:0:0:FFFF. Il formato di indirizzi IPv4 mappato a IPv6 è specificato in RFC 4291. Per altre informazioni, vedere www.ietf.org/rfc/rfc4291.txt. La macro IN6ADDR_SETV4MAPPED in Mstcpip.h può essere usata per convertire un indirizzo IPv4 nel formato di indirizzo IPv4 mappato APv6 richiesto.

Se il protocollo sottostante è effettivamente IPv4, l'indirizzo IPv4 viene mappato in un formato di indirizzo IPv4 mappato a IPv6. Ovvero il campo famiglia nella struttura SOCKADDR indica AF_INET6, ma nella struttura degli indirizzi IPv6 è codificato un indirizzo IPv4 mappato. Per un socket dual stack in modalità di ascolto, ciò significa che tutte le connessioni IPv4 accettate restituiranno un indirizzo IPv6 mappato per IPv4. Per un socket dual stack che si connette a una destinazione IPv4, la struttura SOCKADDR passata per la connessione deve essere un indirizzo IPv4 mappato a IPv6. Le applicazioni devono occuparsi di gestire questi indirizzi IPv4 mappati in modo appropriato e usarli solo con dual stack socket. Se un indirizzo IP deve essere passato a un normale socket IPv4, l'indirizzo deve essere un indirizzo IPv4 normale non un indirizzo IPv4 mappato a IPv6.

Potenziali problemi relativi all'uso di un socket Dual-Stack

Un potenziale problema per le applicazioni è ottenere un indirizzo IPv4 mappato IPv6 su un socket dual stack e quindi tentare di usare l'indirizzo IP restituito in un socket IPv6 diverso. Ad esempio, le funzioni getpeername o getpeername possono restituire un indirizzo IPv4 mappato APv6 se usato in un socket dual stack. Se l'indirizzo IPv4 con mapping IPv6 restituito viene successivamente usato su un socket diverso che non è stato impostato su dual stack (un socket solo IPv6 che è il comportamento predefinito quando viene creato un socket), qualsiasi uso di questo socket solo IPv6 con un indirizzo IPv4 mappato APv6 avrà esito negativo. Il formato di indirizzi IPv4 mappato a IPv6 può essere usato solo in un socket a doppio stack.

In un socket di datagrammi dual stack, se un'applicazione richiede la funzione LPFN_WSARECVMSG (WSARecvMsg) per restituire informazioni sui pacchetti in una struttura WSAMSG per i datagrammi ricevuti su IPv4, IP_PKTINFO'opzione socket deve essere impostata su true nel socket. Se solo l'opzione IPV6_PKTINFO è impostata su true nel socket, le informazioni sui pacchetti verranno fornite per i datagrammi ricevuti su IPv6, ma potrebbero non essere fornite per i datagrammi ricevuti su IPv4.

Se un'applicazione tenta di impostare l'opzione socket IP_PKTINFO su un socket datagram a doppio stack e IPv4 è disabilitata nel sistema, la funzione setsockopt avrà esito negativo e WSAGetLastError restituirà un errore WSAEINVAL. Lo stesso errore viene restituito anche dalla funzione setsockopt in seguito ad altri errori. Se un'applicazione tenta di impostare un'opzione socket a livello di IPPROTO_IP su un socket a doppio stack e ha esito negativo con WSAEINVAL, l'applicazione deve determinare se IPv4 è disabilitato nel computer locale. Un metodo che può essere usato per rilevare se IPv4 è abilitato o disabilitato consiste nel chiamare la funzione socket con il parametro af impostato su AF_INET per provare a creare un socket IPv4. Se la funzione socket ha esito negativo e WSAGetLastError restituisce un errore WSAEAFNOSUPPORT, significa che IPv4 non è abilitato. In questo caso, un errore della funzione setsockopt quando si tenta di impostare l'opzione socket IP_PKTINFO può essere ignorata dall'applicazione. In caso contrario, un errore durante il tentativo di impostare l'opzione socket IP_PKTINFO deve essere considerata come un errore imprevisto.

Per un socket a doppio stack quando si inviano datagrammi con la funzione WSASendMsg e un'applicazione vuole specificare un indirizzo di origine IP locale specifico da usare, il metodo da gestire dipende dall'indirizzo IP di destinazione. Quando si invia a un indirizzo di destinazione IPv4 o a un indirizzo di destinazione IPv4 mappato IPv6, uno degli oggetti dati del controllo passati nella struttura WSAMSG a cui punta il parametro lpMsg deve contenere una struttura in_pktinfo contenente l'indirizzo di origine IPv4 locale da usare per l'invio. Quando si invia a un indirizzo di destinazione IPv6 che non è un indirizzo IPv4 mappato APv6, uno degli oggetti dati del controllo passati nella struttura WSAMSG a cui punta il parametro lpMsg deve contenere una struttura in6_pktinfo contenente l'indirizzo di origine IPv6 locale da usare per l'invio.

Guida IPv6 per le applicazioni Windows Sockets

Modifica delle strutture di dati per le app di Winsock IPv6

Chiamate di funzione per le applicazioni Winsock IPv6

Uso di indirizzi IPv4 hardcoded

Problemi dell'interfaccia utente per le applicazioni Winsock IPv6

Protocolli sottostanti per le applicazioni Winsock IPv6

getpeername

getsockname

in_pktinfo

in6_pktinfo

IP_PKTINFO

IPV6_PKTINFO

Setsockopt

LPFN_WSARECVMSG (WSARecvMsg)

WSASendMsg