8

传输层和网络层的checksum区别,TCP cksum为何包含伪首部 - philo_zhou

 1 year ago
source link: https://www.cnblogs.com/philo-zhou/p/17260182.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client



  一直搞不清传输层和网络层的校验和为什么校验内容不一样,最近问了一些前辈,找寻了一些答案,总结一下自己的思考。

先说一下传输层(TCP)和网络层(IP)的校验和:

  • TCP校验和有伪首部、TCP herder、数据段。而IP的校验和只覆盖IP header,不覆盖IP数据报中的任何数据。TCP校验和、IP校验和的计算方法是一致。
  • TCP的校验和是必需的,而UDP的校验和是可选的。
  • 12字节伪首部:源IP地址、目的IP地址、保留字节(置0)、传输层协议号(TCP是6)、TCP报文长度(报头+数据)。

先提出三个问题:

  1. 为什么IP算的cksum只有头部呢?TCP却包含数据?
  2. 这个伪首部啥意思,为什么叫'伪'?
  3. 为何TCP算的cksum又加上伪头部呢?

为什么IP算的只有ip header呢?TCP却包含数据?

  让我们先回顾一下计算机网络里说到的TCP五层模型,现实中是把物理层和数据链路层放一起了,都叫链路层。

  • 应用层 (application layer):应用进程提供服务
  • 传输层 (transport layer):为进程提供通信服务,为上层提供端到端(最终用户到最终用户)的透明的、可靠的数据传输服务。拥塞控制,流控都在这。
  • 网络层 (internet layer):为主机提供通信服务
  • 数据链路层 (data link layer):为同一链路主机提供数据传输服务
  • 物理层 (physical Layer):确保数据可以在各种物理媒介上进行传输,为数据的传输提供可靠的环境。

  首先,其实每一层都有自己的校验方法?为什么?校验算法没法百分百保证正确,越早发现越早丢弃。

  我自己的理解:每个层都是有自己负责的内容,按照这个思路去看。数据先加端口号封装传输层,传输层负责的是为进程通信确保了送到主机上正确的port(进程绑定的port)。加ip封装网络层,ip层只是负责送到正确的机器上。加mac封装物理层,控制网卡需要网卡驱动程序,网卡驱动从ip模块获得包后将其复制到网卡的缓存中,然后在头部加报头和起始帧分界符,末尾加上帧校验序列(循环冗余算法(CRC)生成的fcs校验序列)。经过网卡将数字信号转化为电信号,通过网线发送出去。这里负责的是真正传输内容。首先链路层这里是简单确保整个报文没有被改变,交换机会解析MAC然后校验这个fcs,这里链路层保证数据可靠专属。路由器收到之后会解析到ip header,计算fcs和ip校验和,也就是路由器里面相当于也有fcs保证数据的正确,尽管很羸弱,ip层的任务就是只确保ip是对的,就像贴在箱子上的快递单做的事情,不关心箱子里的东西对不对,当然路由器会查表封装新的MAC头从计算fcs。真正到了主机,也会校验fcs,ip校验和,到了传输层,需要向上交付数据,所以传输层这里校验和会包含数据段。

  TCP/IP地分层,让每一层注重自己的事情,IP不会过问数据,TCP层需要保证数据,但是为什么链路层有了校验,还需要其它层保证呢?举个简单的例子,路由器拆了以太帧头之后放到自己的缓冲区,在缓存去里这个时候报文出错了,路由器吧错误的报文计算一下fcs,封装好,继续发,这样之后链路层再校验,也没问题,还是需要更上层的校验。

  刚才说的这些校验都是低级的校验,TCP/IP提出的时代,设备能力还是很差的,只能用这种简单的CRC去校验,但比如一个"10 20"变成的"20 10",对于CRC是校验不出来的,因为CRC只管累加没问题。

这个伪首部啥意思,为什么叫'伪'? 

12字节伪首部:源IP地址、目的IP地址、保留字节(置0)、传输层协议号(TCP是6)、TCP报文长度(报头+数据)。

  计算checksum时,其实整个包的信息都可以获取,传输层直接从ip header拿出源ip、目的ip、传输协议号用来计算checksum,这些字段并不是在tcp报文里,所以是伪,只是计算时带上而已。

  收端也是,收到之后连带这几个字段校验一下,实际上tcp报文并没有这几个字段的内容。

为何TCP算的cksum又加上伪头部呢?

  这更算一个历史遗留问题,过去还没有光纤,没有现在这些可靠性高的传输技术,之前线路误码率非常高,为了确保数据包到收端的正确性,这又相当于多加了一点保证,并且几乎没有损失性能。

IPV6和IPV4

IPV6省略了IP层的校验和,引入了更加可靠的链路层错误检测和纠正机制。因为当前的设备不再像之前错误那么多,付出校验所有包的代价去转发,并不值得,有其他更好的错误检测,这样像路由器这样的网络设备,就不需要再校验了,提高了性能。

为什么应用层还要做数据完整性校验?

推荐读一下这个论文:https://zhuanlan.zhihu.com/p/55311553


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK