最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

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

一文講解LinuxTCP數(shù)據(jù)接收-快路徑與慢路徑

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

一、快路徑與慢路徑簡(jiǎn)介

在Linux內(nèi)核的TCP/IP協(xié)議棧實(shí)現(xiàn)中,TCP數(shù)據(jù)接收分為快路徑處理與慢路徑進(jìn)行處理,快路徑用于處理預(yù)期的、理想情形的輸入數(shù)段,TCP連接中最常見的情形應(yīng)該被盡可能地檢測(cè)并最優(yōu)化處理,達(dá)到快速處理的目的。慢路徑用于處理那些非預(yù)期、非理想情況下的數(shù)據(jù)段,如亂序數(shù)據(jù)段、socket內(nèi)存管理和緊急數(shù)據(jù)等。

快路徑與慢路徑在Linux內(nèi)核中的處理流程:tcp握手完成后,收到數(shù)據(jù)包后,調(diào)用路徑為:

tcp_v4_rcv

->tcp_v4_do_rcv

->tcp_rcv_established,

在tcp_rcv_establisheed函數(shù)中處理TCP_ESTABLISHED狀態(tài)的包 ,并根據(jù)pred_flags預(yù)測(cè)字段來(lái)選擇著采用快路徑或慢路徑。

二、首部預(yù)測(cè)字段-pred_flags

預(yù)測(cè)字段存儲(chǔ)在struct tcp_sock中,pred_flag為0表示關(guān)閉首部預(yù)測(cè)使用慢速路徑,非0表示開啟快速路徑的前提,如果開啟會(huì)對(duì)該變量進(jìn)行設(shè)定。

可以看到pred_flags與網(wǎng)絡(luò)傳輸時(shí)一致采用大端存儲(chǔ),其大小為32位。該32位的pred_flags和TCP首部的第3個(gè)32位字(第0個(gè)32位:16位源端口號(hào),16位目的端口號(hào);第1個(gè)32位:32位序列號(hào);第2個(gè)32位:32位確認(rèn)號(hào);第3個(gè)32位:首部字段、標(biāo)志、窗口大小等,即首部預(yù)測(cè)字段需要的字段)對(duì)應(yīng),**如下圖1為TCP首部字段分布與第3個(gè)32位的細(xì)節(jié),**pred_flag變量的賦值通過(guò)調(diào)用tcp_fast_path_on函數(shù)或tcp_fast_path_on函數(shù)(include\net\tcp.h)中進(jìn)行設(shè)定,其中tcp_fast_path_on間接調(diào)用__tcp_fast_path_on,只不過(guò)是在調(diào)用__tcp_fast_path_on針對(duì)攜帶窗口擴(kuò)大因子的TCP傳輸進(jìn)行還原發(fā)送窗口的大小。

**pred_flags由三個(gè)部分組成:【首部長(zhǎng)度、ACK標(biāo)記、發(fā)送窗口大小】也就是與TCP首部字段(13-16字節(jié))中相應(yīng)的字段,******如圖2 pred_flags圖示,****內(nèi)核中的解釋如下:

進(jìn)行快速路徑判斷的時(shí)候只需要將預(yù)測(cè)字段與TCP首部中對(duì)應(yīng)的部分進(jìn)行對(duì)比即可。

__tcp_fast_path_on函數(shù)中:tp->header_len<<26的解釋如下:

1、關(guān)于header_len:是指TCP首部的字節(jié)數(shù)(TCP首部固定部分為20字節(jié)),在TCP頭部對(duì)應(yīng)的是4位的"首部長(zhǎng)度"字段,TCP的首部字節(jié)數(shù) header_len= 首部長(zhǎng)度*4,要得到”首部長(zhǎng)度“字段,需要將header_len右移兩位,即除以4:header_len>>2

2、”首部長(zhǎng)度“字段是4位,現(xiàn)在要得到的pred_flags應(yīng)該與TCP首部的第4個(gè)32位的位置(第13-16字節(jié))進(jìn)行對(duì)應(yīng),所以4位的首部字段左移28位得到:32位初始化(僅包含首部長(zhǎng)度字段)的pred_flags,即header_len右移兩位后,再左移28位:header_len<<26,即XXXX0000000000000000000000000000

其中XXXX表示首部長(zhǎng)度字段的值。

tp->header_len<<26得到了含首部長(zhǎng)度字段的pred_flags,但pred_flags除了首部長(zhǎng)度字段外還應(yīng)含有ACK標(biāo)記,發(fā)送窗口:

tp->tcp_header_len << 26) | ntohl(TCP_FLAG_ACK) | snd_wnd

其中TCP_FLAG_ACK定義如下:


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

TCP_FLAG_ACK字段為0x00100000,即對(duì)應(yīng)ACK標(biāo)志位為1。


三、首部預(yù)測(cè)字段的設(shè)定

首部預(yù)測(cè)字段的設(shè)定分為兩種過(guò)程 :

1、直接調(diào)用__tcp_fast_path_on函數(shù)進(jìn)行設(shè)定首部預(yù)測(cè)字段相應(yīng)的值

2、直接調(diào)用tcp_fast_path_on函數(shù)進(jìn)行設(shè)定首部預(yù)測(cè)字段相應(yīng)的值

2、先進(jìn)行條件檢驗(yàn),檢驗(yàn)通過(guò)后調(diào)用__tcp_fast_path_on函數(shù)進(jìn)行設(shè)定首部預(yù)測(cè)字段相應(yīng)的值直接調(diào)用__tcp_fast_path_on 的時(shí)機(jī):

客戶端connect系統(tǒng)調(diào)用即將結(jié)束的時(shí)

在tcp_finish_connect中沒(méi)有開啟窗口擴(kuò)大因子的時(shí),調(diào)用__tcp_fast_path_on來(lái)設(shè)置快速路徑條件,這時(shí)候客戶端進(jìn)入TCP_ESTABLISHED狀態(tài),服務(wù)端還在等待客戶端最后一次ACK才能發(fā)送數(shù)據(jù),因此不會(huì)收到服務(wù)端的數(shù)據(jù),也就不用考慮快速路徑。

直接調(diào)用tcp_fast_path_on的時(shí)機(jī):

服務(wù)器在收到SYN請(qǐng)求后的處理過(guò)程中,如下tcp_rcv_state_process函數(shù)中

進(jìn)行檢驗(yàn)后調(diào)用__tcp_fast_path_on函數(shù):

檢驗(yàn)函數(shù)檢查條件是否滿足,滿足后才能設(shè)置預(yù)測(cè)標(biāo)記,條件:** **

條件1:亂序隊(duì)列是否為空(沒(méi)有亂序數(shù)據(jù)時(shí)設(shè)定)

條件2:接收窗口是否還有剩余空間(接收窗口不為0時(shí)設(shè)定)

條件3:接收內(nèi)存是否受限(接收緩存未耗盡時(shí)設(shè)定)

條件4:是否有緊急數(shù)據(jù)需要傳輸(無(wú)緊急數(shù)據(jù)時(shí)設(shè)定)

檢驗(yàn)函數(shù)是tcp_fast_path_check,邏輯主要是進(jìn)行4個(gè)條件判斷,決定是否設(shè)定首部預(yù)測(cè)字段,如下所示:

先通過(guò)tcp_fast_check函數(shù)檢測(cè)后調(diào)用t cp_fast_path_on的時(shí)機(jī):

1、讀完緊急數(shù)據(jù)后:緊急數(shù)據(jù)是由慢路徑處理的,在慢速路徑上收完緊急數(shù)據(jù)后檢查是否可用開啟快速路徑模式

2、當(dāng)發(fā)送發(fā)收到ACK并調(diào)用tcp_ack_update_window更新窗口時(shí),通告窗口發(fā)生了變化,則必須更新預(yù)測(cè)標(biāo)記,以免后續(xù)的輸入報(bào)文因?yàn)榇翱诓环M(jìn)入慢速路徑:

3、當(dāng)調(diào)用tcp_data_queue將數(shù)據(jù)放入接收隊(duì)列時(shí),這時(shí)可用的接收緩存大小發(fā)生變化,即將輸入數(shù)據(jù)放入到接收隊(duì)列后,更新了字節(jié)的內(nèi)存占用量,tcp_fast_path_check會(huì)檢查這俄格緩存的變化是否允許開啟快速路徑模式。只有當(dāng)前包是非亂序包,且接收窗口非0的時(shí)候,才能調(diào)用tcp_fast_path_check嘗試開啟快速路徑

四、進(jìn)入快速路徑與慢速路徑處理

設(shè)置預(yù)測(cè)標(biāo)記后,使用它是在處理已連接TCP數(shù)據(jù)段的唯一入口函數(shù):tcp_rcv_estblished

是否能夠執(zhí)行快速路徑,pred_flags匹配只是前提條件,還有一些其他的判斷條件,在內(nèi)核中有相關(guān)的定義(net\ipv4\tcp_input.c):

在tcp_rcv_established函數(shù)中,關(guān)于快速路徑檢查與執(zhí)行部分如下:

其中:

tcp_flag_word(th)獲取的是TCP首部的第13-16字節(jié),也就是第3個(gè)32位(第0個(gè)32位:16位源端口號(hào),16位目的端口號(hào);第1個(gè)32位:32位序列號(hào);第2個(gè)32位:32位確認(rèn)號(hào);第3個(gè)32位:首部字段、標(biāo)志、窗口大小等,需要的首部預(yù)測(cè)字段)

得到TCP首部的第3個(gè)32位后,還不是首部預(yù)測(cè)字段,還要繼續(xù)屏蔽掉PSH字段,即 tcp_flag_word(th) & TCP_HP_BITS

慢速路徑處理:


一文講解LinuxTCP數(shù)據(jù)接收-快路徑與慢路徑的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
随州市| 金昌市| 常德市| 射阳县| 宝清县| 万荣县| 石首市| 阜平县| 宁海县| 苗栗市| 化德县| 孟津县| 印江| 安龙县| 思茅市| 德阳市| 竹山县| 宁化县| 望都县| 新竹县| 星座| 思茅市| 西畴县| 同心县| 项城市| 南充市| 定结县| 双辽市| 绍兴县| 清涧县| 阳江市| 湘乡市| 南康市| 海宁市| 山东| 西平县| 驻马店市| 东兰县| 简阳市| 鄄城县| 南通市|