linux 虚拟机大量udp请求失败_理解 Linux 网络栈:Linux 网络协议栈简单总结分析...
1. Linux 網絡路徑
1.1 發送端
1.1.1 應用層
(1) Socket
應用層的各種網絡應用程序基本上都是通過 Linux Socket 編程接口來和內核空間的網絡協議棧通信的。Linux Socket 是從 BSD Socket 發展而來的,它是 Linux 操作系統的重要組成部分之一,它是網絡應用程序的基礎。從層次上來說,它位于應用層,是操作系統為應用程序員提供的 API,通過它,應用程序可以訪問傳輸層協議。
- socket 位于傳輸層協議之上,屏蔽了不同網絡協議之間的差異
- socket 是網絡編程的入口,它提供了大量的系統調用,構成了網絡程序的主體
- 在Linux系統中,socket 屬于文件系統的一部分,網絡通信可以被看作是對文件的讀取,使得我們對網絡的控制和對文件的控制一樣方便。
UDP socket 處理過程
Linuxc/c++服務器開發高階視頻學習資料+主頁qun獲取
TCP Socket 處理過程
(2) 應用層處理流程
1.1.2 傳輸層
傳輸層的最終目的是向它的用戶提供高效的、可靠的和成本有效的數據傳輸服務,主要功能包括
(1)構造 TCP segment
(2)計算 checksum
(3)發送回復(ACK)包
(4)滑動窗口(sliding windown)等保證可靠性的操作
TCP 協議棧的大致處理過程如下圖所示:
TCP 棧簡要過程:
UDP 棧簡要過程:
1.1.3 IP 網絡層 - 添加header 和 checksum,路由處理,IP fragmentation
網絡層的任務就是選擇合適的網間路由和交換結點, 確保數據及時傳送。網絡層將數據鏈路層提供的幀組成數據包,包中封裝有網絡層包頭,其中含有邏輯地址信息- -源站點和目的站點地址的網絡地址。其主要任務包括
(1)路由處理,即選擇下一跳
(2)添加 IP header
(3)計算 IP header checksum,用于檢測 IP 報文頭部在傳播過程中是否出錯
(4)可能的話,進行 IP 分片
(5)處理完畢,獲取下一跳的 MAC 地址,設置鏈路層報文頭,然后轉入鏈路層處理。
IP 頭:
IP 棧基本處理過程如下圖所示:
1.1.4 數據鏈路層
功能上,在物理層提供比特流服務的基礎上,建立相鄰結點之間的數據鏈路,通過差錯控制提供數據幀(Frame)在信道上無差錯的傳輸,并進行各電路上的動作系列。數據鏈路層在不可靠的物理介質上提供可靠的傳輸。該層的作用包括:物理地址尋址、數據的成幀、流量控制、數據的檢錯、重發等。在這一層,數據的單位稱為幀(frame)。數據鏈路層協議的代表包括:SDLC、HDLC、PPP、STP、幀中繼等。
實現上,Linux 提供了一個 Network device 的抽象層,其實現在 linux/net/core/dev.c。具體的物理網絡設備在設備驅動中(driver.c)需要實現其中的虛函數。Network Device 抽象層調用具體網絡設備的函數。
1.1.5 物理層 - 物理層封裝和發送
1.1.6 簡單總結
1.2 接收端
1.2.1 物理層和數據鏈路層
簡要過程:
1.2.2 網絡層
1.2.3 傳輸層 (TCP/UDP)
1.2.4 接收端 - 應用層
1.2.5 報文接收過程簡單總結
2. Linux sk_buff struct 數據結構和隊列(Queue)
2.1 sk_buff
(本章節摘選自 http://amsekharkernel.blogspot.com/2014/08/what-is-skb-in-linux-kernel-what-are.html)
2.1.1 sk_buff 是什么
當網絡包被內核處理時,底層協議的數據被傳送更高層,當數據傳送時過程反過來。由不同協議產生的數據(包括頭和負載)不斷往下層傳遞直到它們最終被發送。因為這些操作的速度對于網絡層的表現至關重要,內核使用一個特定的結構叫 sk_buff, 其定義文件在 skbuffer.h。Socket buffer被用來在網絡實現層交換數據而不用拷貝來或去數據包 –這顯著獲得速度收益。
- sk_buff 是 Linux 網絡的一個核心數據結構,其定義文件在 skbuffer.h。
- socket kernel buffer (skb) 是 Linux 內核網絡棧(L2 到 L4)處理網絡包(packets)所使用的 buffer,它的類型是 sk_buffer。簡單來說,一個 skb 表示 Linux 網絡棧中的一個 packet;TCP 分段和 IP 分組生產的多個 skb 被一個 skb list 形式來保存。
- struct sock 有三個 skb 隊列(sk_buffer queue),分別是 rx , tx 和 err。
它的主要結構成員:
struct sk_buff {/* These two members must be first. */ # packet 可以存在于 list 或者 queue 中,這兩個成員用于鏈表處理struct sk_buff *next;struct sk_buff *prev;struct sk_buff_head *list; #該 packet 所在的 list...struct sock *sk; #跟該 skb 相關聯的 socketstruct timeval stamp; # packet 發送或者接收的時間,主要用于 packet sniffersstruct net_device *dev; #這三個成員跟蹤該 packet 相關的 devices,比如接收它的設備等struct net_device *input_dev;struct net_device *real_dev;union { #指向各協議層 header 結構struct tcphdr *th;struct udphdr *uh;struct icmphdr *icmph;struct igmphdr *igmph;struct iphdr *ipiph;struct ipv6hdr *ipv6h;unsigned char *raw;} h;union {struct iphdr *iph;struct ipv6hdr *ipv6h;struct arphdr *arph;unsigned char *raw;} nh;union {unsigned char *raw;} mac;struct dst_entry *dst; #指向該 packet 的路由目的結構,告訴我們它會被如何路由到目的地char cb[40]; # SKB control block,用于各協議層保存私有信息,比如 TCP 的順序號和幀的重發狀態unsigned int len, #packet 的長度data_len,mac_len, # MAC header 長度csum; # packet 的 checksum,用于計算保存在 protocol header 中的校驗和。發送時,當 checksum offloading 時,不設置;接收時,可以由device計算unsigned char local_df, #用于 IPV4 在已經做了分片的情況下的再分片,比如 IPSEC 情況下。cloned:1, #在 skb 被 cloned 時設置,此時,skb 各成員是自己的,但是數據是shared的nohdr:1, #用于支持 TSOpkt_type, #packet 類型ip_summed; # 網卡能支持的校驗和計算的類型,NONE 表示不支持,HW 表示支持,__u32 priority; #用于 QoSunsigned short protocol, # 接收 packet 的協議security;2.1.2 skb 的主要操作
(1)分配 skb = alloc_skb(len, GFP_KERNEL)
(2)添加 payload (skb_put(skb, user_data_len))
(3)使用 skb->push 添加 protocol header,或者 skb->pull 刪除 header
2.2 Linux 網絡棧使用的驅動隊列 (driver queue)
2.2.1 隊列
在 IP 棧和 NIC 驅動之間,存在一個 driver queue (驅動隊列)。典型地,它被實現為 FIFO ring buffer,簡單地可以認為它是固定大小的。這個隊列不包含 packet data,相反,它只是保存 socket kernel buffer (skb)的指針,而 skb 的使用如上節所述是貫穿內核網絡棧處理過程的始終的。
該隊列的輸入時 IP 棧處理完畢的 packets。這些packets 要么是本機的應用產生的,要么是進入本機又要被路由出去的。被 IP 棧加入隊列的 packets 會被網絡設備驅動(hardware driver)取出并且通過一個數據通道(data bus)發到 NIC 硬件設備并傳輸出去。
在不使用 TSO/GSO 的情況下,IP 棧發到該隊列的 packets 的長度必須小于 MTU。
2.2.2 skb 大小 - 默認最大大小為 NIC MTU
絕大多數的網卡都有一個固定的最大傳輸單元(maximum transmission unit, MTU)屬性,它是該網絡設備能夠傳輸的最大幀(frame)的大小。對以太網來說,默認值為 1500 bytes,但是有些以太網絡可以支持巨幀(jumbo frame),最大能到 9000 bytes。在 IP 網絡棧內,MTU 表示能發給 NIC 的最大 packet 的大小。比如,如果一個應用向一個 TCP socket 寫入了 2000 bytes 數據,那么 IP 棧需要創建兩個 IP packets 來保持每個 packet 的大小等于或者小于 1500 bytes。可見,對于大數據傳輸,相對較小的 MTU 會導致產生大量的小網絡包(small packets)并被傳入 driver queue。這成為 IP 分片 (IP fragmentation)。
下圖表示 payload 為 1500 bytes 的 IP 包,在 MTU 為 1000 和 600 時候的分片情況:
備注:
以上資料是從網絡上獲取的各種資料整理而來
這一塊本身就比較復雜,而且不同的 linux 內核的版本之間也有差異,文中的內容還需要進一步加工,錯誤在所難免。
原文:理解 Linux 網絡棧(1):Linux 網絡協議棧簡單總結
總結
以上是生活随笔為你收集整理的linux 虚拟机大量udp请求失败_理解 Linux 网络栈:Linux 网络协议栈简单总结分析...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eas 在linux下安装_Linux下
- 下一篇: 开正交时候卡顿_王者荣耀:不管用WiFi