Unix Network Programming Episode 85

IPv4 and IPv6 Interoperability

Introduction

Over the coming years, there will probably be a gradual transition of the Internet from IPv4 to IPv6. During this transition phase, it is important that existing IPv4 applications continue to work with newer IPv6 applications. For example, a vendor cannot provide a telnet client that works only with IPv6 telnet servers but must provide one that works with IPv4 servers and one that works with IPv6 servers.

IPv4 Client, IPv6 Server

A general property of a dual-stack host is that IPv6 servers can handle both IPv4 and IPv6 clients. This is done using IPv4-mapped IPv6 addresses (Figure A.10(See 10.5)).

We can summarize the steps that allow an IPv4 TCP client to communicate with an IPv6 server as follows:

1.The IPv6 server starts, creates an IPv6 listening socket, and we assume it binds the wildcard address to the socket.
2.The IPv4 client calls gethostbyname and finds an A record for the server. The server host will have both an A record and a AAAA record since it supports both protocols, but the IPv4 client asks for only an A record.
3.The client calls connect and the client’s host sends an IPv4 SYN to the server.
4.The server host receives the IPv4 SYN directed to the IPv6 listening socket, sets a flag indicating that this connection is using IPv4-mapped IPv6 addresses, and responds with an IPv4 SYN/ACK. When the connection is established, the address returned to the server by accept is the IPv4-mapped IPv6 address.
5.When the server host sends to the IPv4-mapped IPv6 address, its IP stack generates IPv4 datagrams to the IPv4 address. Therefore, all communication between this client and server takes place using IPv4 datagrams.
6.Unless the server explicitly checks whether this IPv6 address is an IPv4-mapped IPv6 address (using the IN6_IS_ADDR_V4MAPPED macro described in Section 12.4(See 9.1.4)), the server never knows that it is communicating with an IPv4 client. The dual-protocol stack handles this detail. Similarly, the IPv4 client has no idea that it is communicating with an IPv6 server.

  • If an IPv4 datagram is received for an IPv4 socket, nothing special is done. These are the two arrows labeled “IPv4” in the figure: one to TCP and one to UDP. IPv4 datagrams are exchanged between the client and server.
  • If an IPv6 datagram is received for an IPv6 socket, nothing special is done. These are the two arrows labeled “IPv6” in the figure: one to TCP and one to UDP. IPv6 datagrams are exchanged between the client and server.
  • When an IPv4 datagram is received for an IPv6 socket, the kernel returns the corresponding IPv4-mapped IPv6 address as the address returned by accept (TCP) or recvfrom (UDP). These are the two dashed arrows in the figure. This mapping is possible because an IPv4 address can always be represented as an IPv6 address. IPv4 datagrams are exchanged between the client and server.
  • The converse of the previous bullet is false: In general, an IPv6 address cannot be represented as an IPv4 address; therefore, there are no arrows from the IPv6 protocol box to the two IPv4 sockets.

Most dual-stack hosts should use the following rules in dealing with listening sockets:

1.A listening IPv4 socket can accept incoming connections from only IPv4 clients.
2.If a server has a listening IPv6 socket that has bound the wildcard address and the IPV6_V6ONLY socket option (Section 7.8(See 8.5.8)) is not set, that socket can accept incoming connections from either IPv4 clients or IPv6 clients. For a connection from an IPv4 client, the server’s local address for the connection will be the corresponding IPv4-mapped IPv6 address.
3.If a server has a listening IPv6 socket that has bound an IPv6 address other than an IPv4-mapped IPv6 address, or has bound the wildcard address but has set the IPv6_V6ONLY socket option (Section 7.8(See 8.5.8)), that socket can accept incoming connections from IPv6 clients only.

  • If an IPv4 TCP client calls connect specifying an IPv4 address, or if an IPv4 UDP client calls sendto specifying an IPv4 address, nothing special is done. These are the two arrows labeled “IPv4” in the figure.
  • If an IPv6 TCP client calls connect specifying an IPv6 address, or if an IPv6 UDP client calls sendto specifying an IPv6 address, nothing special is done. These are the two arrows labeled “IPv6” in the figure.
  • If an IPv6 TCP client specifies an IPv4-mapped IPv6 address to connect or if an IPv6 UDP client specifies an IPv4-mapped IPv6 address to sendto, the kernel detects the mapped address and causes an IPv4 datagram to be sent instead of an IPv6 datagram. These are the two dashed arrows in the figure.
  • An IPv4 client cannot specify an IPv6 address to either connect or sendto because a 16-byte IPv6 address does not fit in the 4-byte in_addr structure within the IPv4 sockaddr_in structure. Therefore, there are no arrows from the IPv4 sockets to the IPv6 protocol box in the figure.
IPv6 Address-Testing Macros

There is a small class of IPv6 applications that must know whether they are talking to an IPv4 peer. These applications need to know if the peer’s address is an IPv4-mapped IPv6 address. The following 12 macros are defined to test an IPv6 address for certain properties.

#include 
int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *aptr);
int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *aptr);
int IN6_IS_ADDR_MULTICAST(const struct in6_addr *aptr);
int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *aptr);
int IN6_IS_ADDR_SITELOCAL(const struct in6_addr *aptr);
int IN6_IS_ADDR_V4MAPPED(const struct in6_addr *aptr);
int IN6_IS_ADDR_V4COMPAT(const struct in6_addr *aptr);
int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *aptr);
int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *aptr);
int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *aptr);
int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr *aptr);
int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr *aptr);

你可能感兴趣的:(Unix,Network,Programming,unix,网络,服务器)