Dual Stack Sockets on Windows Vista

One of the changes in Windows Vista is that the IPv4 and IPv6 stacks are integrated -- on older OSes they were completely separate stacks. One benefit of this tighter coupling is the ability to create dual-mode sockets. That is, an application can create a single TCP (or UDP) socket and receive both IPv4 and IPv6 traffic. This is nice in the sense that the application only has to create a single server socket and can handle both IPv4 and IPv6 traffic which simplifies application development and reduces the amount of resources required.

This is done by creating an IPv6 socket (either TCP or UDP), setting the socket option IPV6_V6ONLY to false, followed by binding the socket. Setting the socket option must occur befor the bind. When the socket is bound and IPV6_V6ONLY is set to false, the stack actually opens an endpoint for both IPv4 and IPv6. If the specified port is already in use on either the IPv4 or IPv6 stack then the call will fail.

One other difference when using a dual stack socket is IPv4 addresses are returned in the IPv6 sockaddr structure (SOCKADDR_IN6). The family field of the structure will indicate AF_INET6; however, the address will be a IPv4 mapped address. The following TechNet article discusses the different types of IP addresses including IPv4 mapped:


The header file ws2ipdef.h contains several handy macros for determining if an address is V4 mapped. For example IN6_GET_ADDR_V4MAPPED will return the 4 byte IN_ADDR that is the IPv4 address while IN6_IS_ADDR_V4MAPPED will simply tell you if the given address is an IPv4 mapped address.

Of course, the drawback to dual stack sockets is that it is only available on Windows Vista. If an application has to run on downlevel OSes, it will still have to create one socket for each protocol.

Comments (2)

  1. This is good news for Java SE on Windows. Currently on Windows XP when we create a listener socket (via java.net.ServerSocket for example) it requires us to have two sockets when IPv6 is enabled – a crazy mess compared to our implementation on Solaris and Linux.

  2. mrm says:

    I know how to get the state with getsockopt, but

    What’s the admin command line program/args

    to determine what the Mapped IPv4 state is?

    On linux/freebsd/apple,use:

    $ sysctl  net.ipv6.bindv6only

    net.ipv6.bindv6only = 0

    netsh ???

Skip to main content