linux 服務器收到網絡數據包,需求經過哪些處置,一步步將數據傳給應用進程的呢?應用進程發送數據包時,Linux 又是如何操作將數據包發送進來的呢?今天我們就來聊聊這個話題。
在準備好接納網絡數據包之前,Linux需求做很多準備工作,例如:網絡子系統的初始化、協議棧的注冊、網卡驅動的初始化、啟動網卡等等,只要這些都準備好了之后,才敢真正開端接納網絡包。
網絡協議棧
在引見Linux收發網絡數據包之前,我們先來理解一下Linux網絡協議棧。
國際規范化組織制定了開放式系統互聯通訊參考模型(Open System Interconnection Reference Model),也就是 OSI 網絡模型,該模型主要有 7 層,分別是應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層以及物理層。
由于 OSI 模型太復雜,提出的只是存在于概念和理論上的一種模型,分層太多,增加了網絡工作的復雜性,所以沒有大范圍應用。
我們比擬常見是TCP/IP 網絡模型,Linux 系統正是依照這套網絡模型來完成網絡協議棧的。
TCP/IP 網絡模型共有 4 層,分別是應用層、傳輸層、網絡層和網絡接口層,每一層擔任的職能如下:
1、應用層 對應于OSI參考模型的高層,為用戶提供所需求的各種效勞,例如:FTP、Te.NET、DNS、SMTP等.
2、傳輸層 對應于OSI參考模型的傳輸層,為應用層實體提供端到端的通訊功用,保證了數據包的次第傳送及數據的完好性。該層定義了兩個主要的協議:傳輸控制協議(TCP)和用戶數據報協議(UDP).
3、網絡層 對應于OSI參考模型的網絡層,主要處理主機到主機的通訊問題。它所包含的協議設計數據包在整個網絡上的邏輯傳輸。注重重新賦予主機一個IP地址來完成對主機的尋址,它還擔任數據包在多種網絡中的路由。該層有三個主要協議:網際協議(IP)、互聯網組管理協議(IGMP)和互聯網控制報文協議(ICMP)。
4、網絡接口層 與OSI參考模型中的物理層和數據鏈路層相對應。它擔任監視數據在主機和網絡之間的交流。事實上,TCP/IP自身并未定義該層的協議,而由參與互連的各網絡運用本人的物理層和數據鏈路層協議,然后與TCP/IP的網絡接入層停止銜接。地址解析協議(ARP)工作在此層,即OSI參考模型的數據鏈路層。

接納網絡數據包

網絡數據包抵達網卡后,依照FIFO次第被存入網卡的接納隊列,網卡經過 DMA 技術,將網絡包寫入到指定的內存地址(Ring Buffer)。
Ring Buffer是在網卡驅動程序啟動時創立和初始化的,存儲的是sk_buff緩沖區的描繪符(物理地址和大小等)。
當網絡包抵達時,從Ring Buffer獲取指向的sk_buff描繪符,經過DMA將數據寫入該地址。等sk_buff中的數據交由上層協議棧處置后,Ring Buffer中的描繪更新為新分配的sk_buff。
接著網卡向 CPU 發起硬件中綴,當 CPU 收到硬件中綴懇求后,依據中綴注冊表,找到注冊的中綴處置函數。
硬件中綴處置函數會做如下的事情:
1、屏蔽網卡的中綴
目的是防止CPU被頻繁中綴而無法處置其他任務,屏蔽中綴是通知網卡曾經曉得內存中有數據了,下次再收到數據包直接寫內存就能夠了,不要再通知 CPU 了。
2、發起軟中綴,恢復方才屏蔽的中綴
內核中的 ksoftirqd 線程收到軟中綴后,就會調用相應軟中綴的處置函數來輪詢處置數據,即:從Ring Buffer 中獲取一個數據幀,用 sk_buff 表示,作為一個網絡包交給網絡協議棧從下到上停止逐層處置。
網絡協議棧對網絡包的處置流程如下:
1、網絡接口層
首先,網絡接口層檢查報文的合法性和正確性,假如不合法或報文校驗不正確則丟棄,否則找出上層協議的類型(IPv4還是IPv6),去掉幀頭、幀尾,然后交給上層即網絡層處置。
2、網絡層
網絡層取出IP頭,判別網絡包下一步的走向,是轉發還是交給上層。當確認網絡包是要發送給本機后,就取出上層協議的類型(比方TCP或UDP),去掉IP頭,然后交給傳輸層處置。
3、傳輸層
傳輸層取出 TCP 頭或者 UDP 頭后,依據四元組【 源 IP、源端口、目的 IP、目的端口 】,找出對應的 Socket,并把數據拷貝到 Socket 的接納緩沖區。
4、應用層
最后,應用層程序調用 Socket 接口,將內核的 Socket 接納緩沖區的數據拷貝到應用層的緩沖區。
到這里,一個網絡包的接納過程就完畢了。
發送網絡數據包
我們理解了網絡包的接納流程后,就很容易了解網絡包的發送流程了。網絡包的發送方向,正好跟接納方向相反。
首先,應用程序調用 Socket 發送網絡包的接口。這是一個系統調用,會從用戶態墮入到內核態的套接字層中。
套接字層會申請一個內核態的 sk_buff 內存,將用戶待發送的數據拷貝到 sk_buff 內存,并將其參加到Socket發送緩沖區等候網絡協議棧的處置。
由于網絡數據包從應用程序傳到內核時是原始數據,協議棧要在原始數據中參加通訊商定才干保證數據抵達效勞端能被正確辨認。網絡協議棧從 Socket 發送緩沖區中,取出數據包,然后依照 TCP/IP 棧的分層(傳輸層、網絡層、網絡接口層),從上到下逐層停止處置,各層將協議的頭信息不時插入到數據包中。
協議棧對發送數據包的處置流程如下:
1、傳輸層
在傳輸層,會為器添加TCP頭,同時拷貝一個新的 sk_buff 副本 ,這是由于 sk_buff 在抵達網卡發送完成的時分,會被釋放掉,而TCP 協議是支持重傳的,為確保網絡包牢靠傳輸,在收到對方的 ACK 之前,這個 sk_buff 不能被刪除。
2、網絡層
在網絡層,主要會做這些工作:選取路由(確認下一跳的 IP)、填充 IP 頭、netfilter 過濾、對超越 MTU 大小的數據包停止分片。處置完這些工作后會交給網絡接口層處置。
3、網絡接口層
網絡接口層會停止物理地址尋址,以找到下一跳的 mac 地址,填充幀頭和幀尾,將其放到發送隊列中。然后觸發軟中綴通知網卡驅動程序:隊列中有新的網絡包需求發送。驅動程序收到通知會經過 DMA ,從發送包隊列中讀出網絡幀,并經過DMA將數據寫入網卡的FIFO發送隊列。
4、網卡設備
網卡設備從FIFO發送隊列中取出數據包,將其發送到網絡;當發送完成的時分,網卡設備會觸發一個硬中綴來釋放內存,主要是釋放 sk_buff內存和清算 RingBuffer 內存。最后,當收到這個 TCP 報文的 ACK 應對時,傳輸層就會釋放原始的 sk_buff。
至此,一個網絡包的發送流程就完畢了。
來源: 碼農猿星球






