天天看點

從小白到大佬!入門Linux系統收發網絡資料包的秘密!

作者:郭主任講網絡

Linux 伺服器收到網絡資料包,需求經過哪些處置,一步步将資料傳給應用程序的呢?應用程序發送資料包時,Linux 又是如何操作将資料包發送進來的呢?今天我們就來聊聊這個話題。

在準備好接納網絡資料包之前,Linux需求做很多準備工作,例如:網絡子系統的初始化、協定棧的注冊、網卡驅動的初始化、啟動網卡等等,隻要這些都準備好了之後,才敢真正開端接納網絡包。

網絡協定棧

在引見Linux收發網絡資料包之前,我們先來了解一下Linux網絡協定棧。

國際規範化組織制定了開放式系統互聯通訊參考模型(Open System Interconnection Reference Model),也就是 OSI 網絡模型,該模型主要有 7 層,分别是應用層、表示層、會話層、傳輸層、網絡層、資料鍊路層以及實體層。

由于 OSI 模型太複雜,提出的隻是存在于概念和理論上的一種模型,分層太多,增加了網絡工作的複雜性,是以沒有大範圍應用。

我們比拟常見是TCP/IP 網絡模型,Linux 系統正是依照這套網絡模型來完成網絡協定棧的。

TCP/IP 網絡模型共有 4 層,分别是應用層、傳輸層、網絡層和網絡接口層,每一層擔任的職能如下:

1、應用層 對應于OSI參考模型的高層,為使用者提供所需求的各種效勞,例如:FTP、Telnet、DNS、SMTP等.

2、傳輸層 對應于OSI參考模型的傳輸層,為應用層實體提供端到端的通訊功用,保證了資料包的次第傳送及資料的完好性。該層定義了兩個主要的協定:傳輸控制協定(TCP)和使用者資料報協定(UDP).

3、網絡層 對應于OSI參考模型的網絡層,主要處理主機到主機的通訊問題。它所包含的協定設計資料包在整個網絡上的邏輯傳輸。注重重新賦予主機一個IP位址來完成對主機的尋址,它還擔任資料包在多種網絡中的路由。該層有三個主要協定:網際協定(IP)、網際網路組管理協定(IGMP)和網際網路控制封包協定(ICMP)。

4、網絡接口層 與OSI參考模型中的實體層和資料鍊路層相對應。它擔任監視資料在主機和網絡之間的交流。事實上,TCP/IP自身并未定義該層的協定,而由參與互連的各網絡運用本人的實體層和資料鍊路層協定,然後與TCP/IP的網絡接入層停止銜接。位址解析協定(ARP)工作在此層,即OSI參考模型的資料鍊路層。

從小白到大佬!入門Linux系統收發網絡資料包的秘密!

接納網絡資料包

從小白到大佬!入門Linux系統收發網絡資料包的秘密!

網絡資料包抵達網卡後,依照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。

至此,一個網絡包的發送流程就完畢了。

來源: 碼農猿星球

繼續閱讀