1、校验和作用

校验和是为防止报文在信道传输出现误码导致报文错误,或者传输过程中间网络设备错误造成报文错误等,并不保证报文被他人恶意篡改。防君子不防小人,而已修改报文内容重新计算校验和是无法检测的。

2、校验内容

网络报文校验和包括3层校验和4层校验,
3层校验:仅校验3层头(网络层ip头,ipv6协议中没有三层校验和,仅指ipv4);
csum(ip头)

4层校验:需要校验 伪头部+4层头+4层负载(应用层负载)。
csum(ip头)+csum(ip负载)=csum(ip头+ip负载)

3、计算方式

校验和的计算方法是统一的,即所有2字节数据的二进制反码求和。内核实现是以四字节求和取反得到校验和。

发送方填充校验和:
将校验和的2byte置0,计算校验和,将计算结果填充到校验和位置。

接收方验证校验和:
验证时按照同样的计算方式,如果计算结果为0则表示校验和正确,否则表示报错已出错。

几个关键点:
1、先取反再求和与先求和再取反结果一致;为了效率内核使用先求和再取反方式计算;
2、按16bit与32bit结果一致;内核使用32bit以减少运算次数;
3、计算过程中二进制溢出进位时,将进位加到低位,循环计算,直到高位为0;
//详细过程可阅读内核源码。反码求和逻辑比较复杂,自行研究。

4、伪首部相关问题

伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。这样的校验和,既校验了TCP&UDP用户数据的源端口号和目的端口号以及TCP&UDP用户数据报的数据部分,又检验了IP数据报的源IP地址和目的地址。伪报头保证TCP&UDP数据单元到达正确的目的地址。

Q:已经有了ip头校验,为什么还需要在tcp层再次校验ip相关信息?
A:网络报文传输需要进过很多中间网络设备,一般为路由器,rt会操作修改ip头信息(ttl等内容),然后重新计算ip校验和。比如,如果传输过程中由于软硬件异常导致ip头的目的地址错误将报文发送到了非正确的目的地,接收方检查ip头时未发现异常,此时上送到tcp层处理时,如果不检查ip头相关信息就无法检测出此报文是错误的。

Q:伪首部可以直接使用整个ip头吗?
A:不合理,ip头的部分自带经过路由器时会修改变化的,如果使用完整的ip头,中间设备每次都要重新计算tcp层校验和。并且完整的头也增加了计算量。

5、linux内核校验和

计算校验和需要遍历每个字节,对性能影响还是很大的,所以linux对校验和的计算做了很多优化处理
1、按需分多部计算,采用先求和最后取反的计算方式,可以将计算过程分多个步骤,包括报文分片时可以每片单独计算sum,最后再同一相加区分。
2、借助硬件加速,将校验和计算工作留给网卡硬件处理(接收发送都可以),但需要硬件支持此特性。

skb->ip_summed表明L3和L4的计算结果,区分接收和发送:

1、接收过程

skb->csum可能包含L4一部分校验和;
skb->ip_summed字段代表:设备驱动告诉L4软件当前校验和的状态,各取值含义如下:

(1) CHECKSUM_NONE:
skb->csum中的校验和无效,可能是硬件没有提供校验和(硬件不支持、未开启此功能等),此时将ip_summed设为CHECKSUM_NONE,让L4软件层重新校验;

(2) CHECKSUM_COMPLETE:
硬件已经校验了L4报头和其payload部分,并且校验和保存在了skb->csum中,L4软件只需要再计算伪报头然后检查校验结果即可。硬件计算稍复杂的伪头部比较好性能,因为伪头部需要提取ip头的信息。
伪头部包含ip信息、报文长度信息等,需要解析提取一些字段,此类工作对硬件来说比较复杂, 所以伪首部仍然交由软件计算。

(3) CHECKSUM_UNNECESSARY:
硬件已经进行了完整的校验,无需软件再进行检查,L4收到数据包后如果检查ip_summed是这种情况,就可以跳过校验过程;

(4) CHECKSUM_PARTIAL:
虚拟化环境同宿主机不同vm通信时收包会有此种情况(如virtio网卡),此时认为数据虽然未校验,但认为可靠,不过tcp头的校验和字段是错误的。tcp协议栈检查校验和时此种情况不会检查。

 * CHECKSUM_PARTIAL:**   A checksum is set up to be offloaded to a device as described in the*   output description for CHECKSUM_PARTIAL. This may occur on a packet*   received directly from another Linux OS, e.g., a virtualized Linux kernel*   on the same host, or it may be set in the input path in GRO or remote*   checksum offload. For the purposes of checksum verification, the checksum*   referred to by skb->csum_start + skb->csum_offset and any preceding*   checksums in the packet are considered verified. Any checksums in the*   packet that are after the checksum being offloaded are not considered to*   be verified.

2、发送过程

skb->ip_summed字段包含了L4软件告诉设备驱动程序当前校验和的状态,各取值含义如下:
(1) CHECKSUM_NONE:L4软件已经进行了校验,硬件无需做任何事情;

(2) CHECKSUM_PARTIAL:L4软件计算了伪报头,并且将值保存在了tcp/udp首部的check字段中,硬件需要计算其余部分的校验和。硬件适合做简单的++操作,伪头部稍复杂交给cpu。
(对应网卡驱动程序会设置描述符相应字段,硬件来处理)

参考:
https://blog.csdn.net/qy532846454/article/details/7010852
https://blog.csdn.net/weixin_39631017/article/details/111845098
https://blog.csdn.net/zhangwenxinzck/article/details/107574202
https://blog.csdn.net/weixin_29159127/article/details/116691805

Linux网络 IP/TCP校验和、checksum、伪首部相关问题相关推荐

  1. Linux网络-UDP/TCP协议详解

    Linux网络-UDP/TCP协议详解 零.前言 一.UDP协议 二.TCP协议 1.应答机制 2.序号机制 3.超时重传机制 4.连接管理机制 三次握手 四次挥手 5.理解CLOSE_WAIT状态 ...

  2. Linux 网络编程 TCP

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客 ...

  3. UDP和TCP中的伪首部

     伪首部,通常有TCP伪首部和UDP伪首部.在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位协议,16位UDP长度.通过伪首部的校验,UDP可以确定该数据报是不是发给本机的,通过首 ...

  4. Linux网络编程——tcp并发服务器(poll实现)

    https://blog.csdn.net/lianghe_work/article/details/46535859 想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程--I/ ...

  5. 基于iproute命令集配置Linux网络(ip命令)

    iproute是Linux下一个网络管理工具包合集,用于取代先前的如ifconfig,route,ifup,ifdown,netstat等历史网络管理工具.该工具包功能强大,它通过网络链路套接字接口与 ...

  6. Linux 网络编程——TCP/IP 数据包格式解析

    图中括号中的数字代表的是当前域所占的空间大小,单位是bit位. 黄色的是数据链路层的头部,一共14字节 绿色的部分是IP头部,一般是20字节 紫色部分是TCP头部,一般是20字节 最内部的是数据包内容 ...

  7. [linux] Linux网络之TCP协议详解

    目录 1. 传输层 2. 端口号 3. TCP协议 3.1 TCP协议的特性 3.1.1 面向连接 3.1.2 可靠传输 3.1.3 面向字节流 3.2 TCP报头 3.3 TCP连接管理及可靠性问题 ...

  8. Linux网络-IP协议

    文章目录 零.前言 一.网络层 理解路由选择 二.IP协议 三.网段划分 四.IP地址数量限制 五.私有和公网IP地址 NAT技术 六.路由 零.前言 本章主要讲解学习网络层的作用, 深入理解IP协议 ...

  9. Linux网络编程——tcp并发服务器(多进程)

    https://blog.csdn.net/lianghe_work/article/details/46503895 一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多 ...

最新文章

  1. 是什么让数据科学家从优秀变得伟大?
  2. Mysql INSERT INTO .. ON DUPLICATE KEY更新多行记录
  3. Begin Your Service Journey
  4. 假笨说-我是如何走上JVM这条贼船的
  5. 179. 最大数 golang (自定义sort)
  6. api网关 android,如何通过Android上的retrofit2使用Cognito Credentials调用API网关?
  7. php显示json,PHP解决JSON中文显示问题
  8. php中find的函数_filter()、find()函数的区别
  9. 如何使用Visual Studio无需成本即可实现连续集成
  10. asp.net 独立缓存服务器的研究
  11. 算法上均匀分布的随机抽奖,如何避免现实的现场抽奖的中奖号码有时出现集中扎堆的现象?
  12. MySQL提取字符串中数字(自定义函数)
  13. Linux Vue环境搭建
  14. USPS国际快递查询单号
  15. 代码坏的味道17:狎昵关系 (Inappropriate Intimacy)
  16. 微信公众号开发技术要点
  17. 创建多媒体APP 之 音频播放:管理音频焦点
  18. LINKERD 2.11 中文实战手册
  19. 将栅格影像转换为CAD/GIS矢量的3种方法
  20. 孩子该不该学编程?学编程有用吗?

热门文章

  1. 竟然有人把VSCode玩成了IDEA的效果,有点东西
  2. alpha测试和Beta测试有何区别
  3. 如何测试nginx服务器性能测试,Nginx性能测试工具--httperf
  4. stream銆俠oxed_电脑关机时显示OX100672ed指令引用的OX0000000C内存,该内存不能为written是什么意思...
  5. 1688/阿里巴巴按关键字搜索新品数据 API 使用说明
  6. 90后技术宅研发Magi一夜爆红,新一代知识化结构搜索新时代来了?
  7. MATLAB Handle类的set和get方法
  8. Django解决css样式失效问题最终方法
  9. css3 烟 蚊香_如何用纯 CSS 创作一盘传统蚊香
  10. 官网下载eclipse被墙、无法访问解决