Linux网络 IP/TCP校验和、checksum、伪首部相关问题
1、校驗和作用
校驗和是為防止報文在信道傳輸出現(xiàn)誤碼導(dǎo)致報文錯誤,或者傳輸過程中間網(wǎng)絡(luò)設(shè)備錯誤造成報文錯誤等,并不保證報文被他人惡意篡改。防君子不防小人,而已修改報文內(nèi)容重新計算校驗和是無法檢測的。
2、校驗內(nèi)容
網(wǎng)絡(luò)報文校驗和包括3層校驗和4層校驗,
3層校驗:僅校驗3層頭(網(wǎng)絡(luò)層ip頭,ipv6協(xié)議中沒有三層校驗和,僅指ipv4);
csum(ip頭)
4層校驗:需要校驗 偽頭部+4層頭+4層負載(應(yīng)用層負載)。
csum(ip頭)+csum(ip負載)=csum(ip頭+ip負載)
3、計算方式
校驗和的計算方法是統(tǒng)一的,即所有2字節(jié)數(shù)據(jù)的二進制反碼求和。內(nèi)核實現(xiàn)是以四字節(jié)求和取反得到校驗和。
發(fā)送方填充校驗和:
將校驗和的2byte置0,計算校驗和,將計算結(jié)果填充到校驗和位置。
接收方驗證校驗和:
驗證時按照同樣的計算方式,如果計算結(jié)果為0則表示校驗和正確,否則表示報錯已出錯。
幾個關(guān)鍵點:
1、先取反再求和與先求和再取反結(jié)果一致;為了效率內(nèi)核使用先求和再取反方式計算;
2、按16bit與32bit結(jié)果一致;內(nèi)核使用32bit以減少運算次數(shù);
3、計算過程中二進制溢出進位時,將進位加到低位,循環(huán)計算,直到高位為0;
//詳細過程可閱讀內(nèi)核源碼。反碼求和邏輯比較復(fù)雜,自行研究。
4、偽首部相關(guān)問題
偽首部并非TCP&UDP數(shù)據(jù)報中實際的有效成分。偽首部是一個虛擬的數(shù)據(jù)結(jié)構(gòu),其中的信息是從數(shù)據(jù)報所在IP分組頭的分組頭中提取的,既不向下傳送也不向上遞交,而僅僅是為計算校驗和。這樣的校驗和,既校驗了TCP&UDP用戶數(shù)據(jù)的源端口號和目的端口號以及TCP&UDP用戶數(shù)據(jù)報的數(shù)據(jù)部分,又檢驗了IP數(shù)據(jù)報的源IP地址和目的地址。偽報頭保證TCP&UDP數(shù)據(jù)單元到達正確的目的地址。
Q:已經(jīng)有了ip頭校驗,為什么還需要在tcp層再次校驗ip相關(guān)信息?
A:網(wǎng)絡(luò)報文傳輸需要進過很多中間網(wǎng)絡(luò)設(shè)備,一般為路由器,rt會操作修改ip頭信息(ttl等內(nèi)容),然后重新計算ip校驗和。比如,如果傳輸過程中由于軟硬件異常導(dǎo)致ip頭的目的地址錯誤將報文發(fā)送到了非正確的目的地,接收方檢查ip頭時未發(fā)現(xiàn)異常,此時上送到tcp層處理時,如果不檢查ip頭相關(guān)信息就無法檢測出此報文是錯誤的。
Q:偽首部可以直接使用整個ip頭嗎?
A:不合理,ip頭的部分自帶經(jīng)過路由器時會修改變化的,如果使用完整的ip頭,中間設(shè)備每次都要重新計算tcp層校驗和。并且完整的頭也增加了計算量。
5、linux內(nèi)核校驗和
計算校驗和需要遍歷每個字節(jié),對性能影響還是很大的,所以linux對校驗和的計算做了很多優(yōu)化處理
1、按需分多部計算,采用先求和最后取反的計算方式,可以將計算過程分多個步驟,包括報文分片時可以每片單獨計算sum,最后再同一相加區(qū)分。
2、借助硬件加速,將校驗和計算工作留給網(wǎng)卡硬件處理(接收發(fā)送都可以),但需要硬件支持此特性。
skb->ip_summed表明L3和L4的計算結(jié)果,區(qū)分接收和發(fā)送:
1、接收過程
skb->csum可能包含L4一部分校驗和;
skb->ip_summed字段代表:設(shè)備驅(qū)動告訴L4軟件當前校驗和的狀態(tài),各取值含義如下:
(1) CHECKSUM_NONE:
skb->csum中的校驗和無效,可能是硬件沒有提供校驗和(硬件不支持、未開啟此功能等),此時將ip_summed設(shè)為CHECKSUM_NONE,讓L4軟件層重新校驗;
(2) CHECKSUM_COMPLETE:
硬件已經(jīng)校驗了L4報頭和其payload部分,并且校驗和保存在了skb->csum中,L4軟件只需要再計算偽報頭然后檢查校驗結(jié)果即可。硬件計算稍復(fù)雜的偽頭部比較好性能,因為偽頭部需要提取ip頭的信息。
偽頭部包含ip信息、報文長度信息等,需要解析提取一些字段,此類工作對硬件來說比較復(fù)雜, 所以偽首部仍然交由軟件計算。
(3) CHECKSUM_UNNECESSARY:
硬件已經(jīng)進行了完整的校驗,無需軟件再進行檢查,L4收到數(shù)據(jù)包后如果檢查ip_summed是這種情況,就可以跳過校驗過程;
(4) CHECKSUM_PARTIAL:
虛擬化環(huán)境同宿主機不同vm通信時收包會有此種情況(如virtio網(wǎng)卡),此時認為數(shù)據(jù)雖然未校驗,但認為可靠,不過tcp頭的校驗和字段是錯誤的。tcp協(xié)議棧檢查校驗和時此種情況不會檢查。
2、發(fā)送過程
skb->ip_summed字段包含了L4軟件告訴設(shè)備驅(qū)動程序當前校驗和的狀態(tài),各取值含義如下:
(1) CHECKSUM_NONE:L4軟件已經(jīng)進行了校驗,硬件無需做任何事情;
(2) CHECKSUM_PARTIAL:L4軟件計算了偽報頭,并且將值保存在了tcp/udp首部的check字段中,硬件需要計算其余部分的校驗和。硬件適合做簡單的++操作,偽頭部稍復(fù)雜交給cpu。
(對應(yīng)網(wǎng)卡驅(qū)動程序會設(shè)置描述符相應(yīng)字段,硬件來處理)
參考:
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
總結(jié)
以上是生活随笔為你收集整理的Linux网络 IP/TCP校验和、checksum、伪首部相关问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpClient解析服务器返回的re
- 下一篇: 全国各省-土地转让收入(1995-201