五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

淺說下套接字緩存的內(nèi)存空間布局

2022-10-19 15:14 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

套接字?jǐn)?shù)據(jù)緩存(socket buffer)在Linux內(nèi)核中表示為:struct sk_buff,是Linux內(nèi)核中數(shù)據(jù)包管理的基本單元,主要包含兩個部分,其一:管理數(shù)據(jù),即數(shù)據(jù)包的管理信息;其二:報文數(shù)據(jù),保存了實際網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù),在內(nèi)核協(xié)議棧起承上啟下的作用,也有很多值得關(guān)注的sk_buff操作。

1、sk_buff四大指針與相關(guān)操作**分配初始化:**struct sk_buff中四個指針都指向數(shù)據(jù)區(qū),分別是head、data、tail、end,剛剛分配出來的sk_buff會立馬進(jìn)行四大指針的初始操作。


分配sk_buff如下所示:

sk_stream_alloc_skb最終調(diào)用__alloc_skb函數(shù)進(jìn)行內(nèi)存分配,分配skb后,進(jìn)行四大指針的初始化操作:

其中skb_reset_tail_pointer(skb):

最終四大指針初始化為以下圖所示:



此時head、data、tail三個指針指向一起,end指向數(shù)據(jù)緩沖區(qū)的尾部。

**預(yù)留協(xié)議頭空間:**在sk_stream_alloc_skb調(diào)用__alloc_skb函數(shù)進(jìn)行內(nèi)存分配后,下一步就會預(yù)留協(xié)議頭空間,使得head、tail、data指針分離:


skb_reserve如下,

操作后skb_buff的指針如下所示:



skb_reserve作用就是預(yù)留空間,而且是盡最大的空間預(yù)留,但它并沒有把數(shù)據(jù)放到該空間,只是簡單更新指針,預(yù)留空間!


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)??

因為很多頭都會有可選項,那么不知道頭部可選項是多大,所以只能按照最大的分配,同時也要明白一點,預(yù)留的空間headroom不一定使用完,可能還有剩余。當(dāng)我們要增加協(xié)議頭信息的時候,data指針向上移動,當(dāng)增加數(shù)據(jù)的時候tail指針向下移動,完成數(shù)據(jù)包的封裝。此時還沒有數(shù)據(jù),data和tail指向相同。

操作tailroom中用戶數(shù)據(jù)塊區(qū)域:skb_put用于修改指向數(shù)據(jù)區(qū)末尾的指針tail:


可以看到tail指針的移動是擴(kuò)大數(shù)據(jù)區(qū)域 ,即數(shù)據(jù)區(qū)向下擴(kuò)大len字節(jié),并更新數(shù)據(jù)區(qū)長度len。

增加headroom區(qū)域的協(xié)議頭: skb_push函數(shù)用于移動data指針,增加頭部協(xié)議,與skb_reserve()類似,也并沒有真正向數(shù)據(jù)緩存區(qū)中添加數(shù)據(jù),而只是移動數(shù)據(jù)緩存區(qū)的頭指針data。數(shù)據(jù)由其他函數(shù)復(fù)制到數(shù)據(jù)緩存區(qū)中。 函數(shù)如下:

如下兩張圖分別是由傳輸層、網(wǎng)絡(luò)層,數(shù)據(jù)包向下傳遞時data指針移動,進(jìn)行頭部協(xié)議的封裝。

  • TCP層添加TCP首部。

  • SKB傳遞到IP層,IP層為數(shù)據(jù)包添加IP首部。

  • SKB傳遞到鏈路層,鏈路層為數(shù)據(jù)包添加鏈路層首部。


可以看到在數(shù)據(jù)包封裝的過程中,每一層移動data指針進(jìn)行數(shù)據(jù)報頭的封裝。

數(shù)據(jù)報文解封裝,解除協(xié)議頭: skb_pull通過將data指針向下移動,進(jìn)行數(shù)據(jù)報文的解封裝,函數(shù)如下所示:

如下圖所示,在收包流程上,向上層協(xié)議,如下網(wǎng)絡(luò)層向傳輸層傳送的時候,調(diào)用skb_pull進(jìn)行數(shù)據(jù)包的解封裝。



以上就是struct sk_buff的四大指針的相關(guān)操作,通過分析可得:

  • head指向緩沖區(qū)的首地址,作為上邊界

  • end指向緩沖區(qū)的尾地址,作為下邊界

  • data指針在數(shù)據(jù)包頭部封裝和解封裝的過程中移動,指向各層的協(xié)議頭,skb_push函數(shù)將data的指向,向低地址移動(向上),完成協(xié)議頭空間的占據(jù),skb_pull函數(shù)將data的指向,向高地址移動(向下),完成協(xié)議頭的解封裝。

  • tail指針在增加應(yīng)用層用戶緩沖數(shù)據(jù)時移動,skb_put函數(shù)將該指針向高地址移動(向上),完成用戶數(shù)據(jù)空間的占據(jù)。

2、非線性區(qū)域

在1、中,可以看到每張sk_buff的圖:在end指針緊挨著一個非線性區(qū)域 ;

在struct sk_buff中沒有指向skb_shared_info結(jié)構(gòu)的指針,利用end指針,,可以用skb_shinfo宏 來訪問:

其中skb_end_pointer函數(shù)如下,返回end指針

具體地,struct skb_shared_info如下:

其中skb_frag_t如下:

nr_frags,frags,frag_list與IP分片存儲有關(guān)。

frag_list的用法:

  • 用于在接收分組后鏈接多個分片,組成一個完整的IP數(shù)據(jù)報

  • 在UDP數(shù)據(jù)報輸出中,將待分片的SKB鏈接到第一個SKB中,然后在輸出過程中能夠快速的分片

  • 用于存放FRAGLIST類型的聚合分散I/O數(shù)據(jù)包

判斷是否存在非線性緩沖區(qū):

  • 先說明struct sk_buff中關(guān)于長度的兩個字段

  1. len字段:無分片的報文,數(shù)據(jù)報文的大小

  2. data_len字段:存在分散報文,data_len表示分片的部分大小

如下所示,沒有開啟分片的報文len = x,data_len = 0:



如下所示在Linux內(nèi)核中,使用skb_is_nonlinear函數(shù)判斷是否存在分片,即通過判斷data_len的大小是否為0:

  • 在沒有開啟分片的報文中,數(shù)據(jù)包長度在struct sk_buff中為len字段的大小,即data到tail的長度,nf_frags為0,frag_list為NULL。

普通聚合分散I/O的報文:

采用聚合分散I/O的報文,frag_list為 NULL,nf_frags不等于0 ,說明這不是一個普通的分片,而是聚合分散I/O的報文。

如下所示:

nr_frags為2,而frag_list為NULL,說明這不是普通的分片,而是聚合分散I/O分片,數(shù)量為2,這兩個分片指向同一物理分頁,各自在分頁中的偏移和長度分別是0/S1和S1/S2。



FRAGLIST類型的分散聚合I/O的報文:

采用FRAGLIST類型的分散聚合I/O報文, frag_list不為NULL,nf_frags等于0, 數(shù)據(jù)長度len為x+S1,data_len為S1,



以上從struct sk_buff的四大指針以及操作、非線性區(qū)域?qū)μ捉幼志彺?socket buffer)進(jìn)行分析,更多sk_buff的分析、實操等將在以后的文章中梳理。




淺說下套接字緩存的內(nèi)存空間布局的評論 (共 條)

分享到微博請遵守國家法律
四会市| 吉水县| 康保县| 黄平县| 新营市| 离岛区| 永吉县| 正镶白旗| 通辽市| 元江| 外汇| 中宁县| 永善县| 德庆县| 大港区| 昂仁县| 衡阳市| 抚松县| 元朗区| 东兴市| 繁昌县| 遂川县| 中山市| 海盐县| 扎赉特旗| 大悟县| 辽阳市| 高台县| 治县。| 嘉荫县| 宁晋县| 重庆市| 旌德县| 德化县| 静乐县| 岳阳市| 肃南| 海盐县| 虹口区| 遵化市| 彭泽县|