现在的位置: 首页 > 综合 > 正文

IPv4和IPv6的互操作性

2014年02月19日 ⁄ 综合 ⁄ 共 2100字 ⁄ 字号 评论关闭

最近几年,IPv4可能是已经接近枯竭了,所以我们又推出了IPv6,在未来几年内,我们的IP可能是IPv6的了,但是对于现存的大量的基于IPv4代码的服务器和客户端,我们是不是都得做出大量的更新?或许我们要看互操作性了!

 

对于IPv4和IPv6,我们可以分为IPv4和IPv6的客户端和服务器,下面我们来分别讨论一下对于不同的服务器我们怎么建立这个连接,

 

第一:IPv4/IPv6客户和IPv4/IPv6服务器

这个情况很明了,也是现在大部分服务器和客户端所应用的,我们所讲的socket和网络编程里,最先设计的就是这个方面了,对于服务器和客户端运行着相同协议的程序,我们基本上不用怎么讨论,我们觉得对于他们运行着不同协议时,我们才觉得有趣!

 

第二:IPv4客户端和IPv6服务器

1,先启动IPv6服务器,创建一个IPv6的监听套接字接口,我们假定已经绑定了通配地址。

2,IPv4客户端调用gethostbyname找到一个服务器对应的A记录,因为这个服务器同时支持IPv4和IPv6,所以它既有一个A记录,又有一个AAAA记录,但是IPv4只要一个A记录。(对于什么是A记录和AAAA记录,这是DNS服务器内容)

3,客户进程调用一个connect向IPv6服务器发送一个IPv4的SNY,用于请求连接。

4,IPv6服务器接收到了来自客户IPv4发送的SNY,设置一个标记位,表明这个连接使用了是IPv4映射的IPv6地址,然后响应一个IPv4的SNY/ACK,这个链接建立后,accept返回给服务器的地址就是这个IPv4映射的IPv6地址。

5,在客户端和服务器之间都使用IPv4开始通讯。

6,除非服务器明确的是去检查这个IPv6地址是不是由IPv4映射的IPv6地址(在套接字上我们使用IN6_IS_ADDR_V4MAPPED),服务器也不知道我们通讯的对方也是一个IPv4客户,双重协议栈屏蔽着这个细节,同样,客户端也不知道他是在和一个IPv6的服务器建立的通讯!

对于UDP来说,情况也是类似的,但是每个数据报都将改变一次地址格式,对于TCP,我们只要得到一次IPv4到IPv6得映射地址,我们直接在链路层使用就可以了,没必要每次都得计算出来IPv4到IPv6得映射地址。

对于上面的一些消息,我详细的解释一下:

IPv4所发布的分片在互联网上是一个以以太网首部,紧接着是一个IPv4首部,一个TCP头部和TCP数据,以太网中包含了Ox0800,这个标示了这个是一个IPv4帧,还有服务器的端口和目的地址。

IPv6所发出的分片在互联网上市一个以以太网首部,紧接着是一个IPv6首部,一个TCP头部和TCP数据,以太网中包含了Ox86dd的字段类型,这个标识了这是一个IPv6帧,还有目的端口和目的地址。

当accpet调用将接受的IPv6的客户的链接返回给服务器时,该客户的IPv6地址就是出现在IPv6头部的中的源地址,不做任何改动。这个链接上的其余数据报都是IPv6数据报。

 

在一个双重协议栈的主机上,根据接受套接字的类型(TCP或者UDP),对一个收到的IPv4和IPv6的数据报进行处理的流程如下:

1,如果一个IPv4的套接口上接收到一个IPv4的数据报,不做任何处理。

2,如果在一个IPv6的套接口上接收到了一个IPv6数据报,也不需要任何处理。

3,但是,如果一个IPv6套接口上接收到了一个IPv4的数据报,系统内核会在accept(TCP)或者是recvfrom(UDP)调用返回地址时将对应的IPv4映射的IPv6地址返回。

4,和上一条相反的过程是不存在的:通常一个IPv6地址是不能表示成一个IPv4的地址。

 

大多数的双重协议栈的主机应使用以下规则来处理监听套接口:

1,监听IPv4套接口只能接受来自IPv4客户的外来链接。

2,如果服务器上有一个绑定在统配地址上饿监听IPv6套接口,这个套接口就能接受来自IPv4客户和IPv6客户的外来连接。对于来自IPv4客户的外来连接,其在服务器端的本地地址是对应的IPv4映射的IPv6地址。

3,如果有服务器绑定在非IPv4映射的IPv6地址上的监听套接口,该套接口就只能接受来自IPv6的外来连接。

 

第三:IPv6客户和IPv4服务器

1,如果IPv4的TCP客户调用connect时或者IPv4的UDP客户调用sendto时指定的是IPv4地址,不需要做任何处理。

2,如果IPv6的TCP客户调用connect时或者IPv6的UDP客户调用sendto时指定的是一个IPv6地址,不许做任何处理。

3,如果IPv6的TCP客户调用connect时或者IPv6的UDP客户调用sendto时指定的是一个IPv4映射的IPv6地址,内核会检测出这各映射地址,并发送一个IPv4数据报而不是IPv6数据报。

4,IPv4客户不能再调用connect或者sendto是指定一个IPv6地址,因为在IPv4sockaddr_in结构里的4字节的in_addr结构中,放不下一个16字节的IPv6地址。

 

 

本文参考:《unix网络编程》,《TCP/IP详解》

抱歉!评论已关闭.