小議TCP的MSS(最大分段)以及MTU

 

[前言]
漫漫51長假,沒有好的去處,只能每日上網消遣,某日逛到NBO灌水,見一帖
曰:無法通過2514路由器上MSN(出口爲ADSL線路,通過PPPoE)
吾心想,ADSL---PPPoE,那肯定就是MTU之問題。回帖告之:改PC之MTU。

過數日,又逛到NBO,又見這帖,後有人回曰:ip tcp adjust-mss 1452
後帖主又跟:問題解決。

吾納悶之,後百思而得其解,So決定將自己所得寫出來,分享給大家。

[背景知識]
MTU: Maxitum Transmission Unit 最大傳輸單元

MSS: Maxitum Segment Size 最大分段大小(偶是直譯,翻譯的不好,不要打
俺PP)

PPPoE: PPP Over Ethernet(在以太網上承載PPP協議)

[分析過程]
先說說這MTU最大傳輸單元,這個最大傳輸單元實際上和鏈路層協議有着密切
的關係,讓我們先仔細回憶一下EthernetII幀的結構
DMAC+SMAC+Type+Data+CRC
由於以太網傳輸電氣方面的限制,每個以太網幀都有最小的大小64bytes
最大不能超過1518bytes,對於小於或者大於這個限制的以太網幀我們都可以
視之爲錯誤的數據幀,一般的以太網轉發設備會丟棄這些數據幀。
(注:小於64Bytes的數據幀一般是由於以太網衝突產生的“碎片”或者線路干擾
或者壞的以太網接口產生的,對於大於1518Bytes的數據幀我們一般把它叫做
Giant幀,這種一般是由於線路干擾或者壞的以太網口產生)

由於以太網EthernetII最大的數據幀是1518Bytes這樣,刨去以太網幀的幀頭
(DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域
2bytes)14Bytes和幀尾CRC校驗部分4Bytes(這個部門有時候大家也把它叫做
FCS),那麼剩下承載上層協議的地方也就是Data域最大就只能有1500Bytes
這個值我們就把它稱之爲MTU。這個就是網絡層協議非常關心的地方,因爲網絡
層協議比如IP協議會根據這個值來決定是否把上層傳下來的數據進行分片。就好
比一個盒子沒法裝下一大塊麪包,我們需要把麪包切成片,裝在多個盒子裏面一
樣的道理。

當兩臺遠程PC互聯的時候,它們的數據需要穿過很多的路由器和各種各樣的網絡
媒介才能到達對端,網絡中不同媒介的MTU各不相同,就好比一長段的水管,由
不同粗細的水管組成(MTU不同 )通過這段水管最大水量就要由中間最細的水管決定。

對於網絡層的上層協議而言(我們以TCP/IP協議族爲例)它們對水管粗細不在意
它們認爲這個是網絡層的事情。網絡層IP協議會檢查每個從上層協議下來的數據
包的大小,並根據本機MTU的大小決定是否作“分片”處理。分片最大的壞處就是
降低了傳輸性能,本來一次可以搞定的事情,分成多次搞定,所以在網絡層更高
一層(就是傳輸層)的實現中往往會對此加以注意!有些高層因爲某些原因就會
要求我這個麪包不能切片,我要完整地面包,所以會在IP數據包包頭裏面加上一
個標籤:DF(Donot Fragment)。這樣當這個IP數據包在一大段網絡(水管裏
面)傳輸的時候,如果遇到MTU小於IP數據包的情況,轉發設備就會根據要求
丟棄這個數據包。然後返回一個錯誤信息給發送者。這樣往往會造成某些通訊上
的問題,不過幸運的是大部分網絡鏈路都是MTU1500或者大於1500。

對於UDP協議而言,這個協議本身是無連接的協議,對數據包的到達順序以及是
否正確到達不甚關心,所以一般UDP應用對分片沒有特殊要求。

對於TCP協議而言就不一樣了,這個協議是面向連接的協議,對於TCP協議而言
它非常在意數據包的到達順序以及是否傳輸中有錯誤發生。所以有些TCP應用對
分片有要求---不能分片(DF)。

花開兩朵,各表一枝,說完MTU的故事我們該講講今天的第二個豬腳---PPPoE
所謂PPPoE就是在以太網上面跑PPP協議,有人奇怪了,PPP協議和Ethernet不
都是鏈路層協議嗎?怎麼一個鏈路層跑到另外一個鏈路層上面去了,難道升級
成網絡層協議了不成。其實這是個誤區:就是某層協議只能承載更上一層協議。
爲什麼會產生這種奇怪的需求呢?這是因爲隨着寬帶接入(這種寬帶接入一般
爲Cable Modem或者xDSL或者以太網的接入)由於以太網缺乏認證計費機制
而傳統運營商是通過PPP協議來對撥號等接入服務進行認證計費的,所以就
出了這麼一個怪胎:PPPoE。(有關PPPoE的詳細介紹參見V大以及本站其他成
員的一些介紹文章,我就不囉裏囉唆的了)

PPPoE帶來了好處,也帶來了一些壞處,比如:二次封裝耗費資源,降低了傳輸
效能等等,這些壞處俺也不多說了,最大的壞處就是PPPoE導致MTU變小了
以太網的MTU是1500,再減去PPP的包頭包尾的開銷(8Bytes),就變成
1492。

如果兩臺主機之間的某段網絡使用了PPPoE那麼就會導致某些不能分片的應用
無法通訊。

這個時候就需要我們調整一下主機的MTU,通過降低主機的MTU,這樣我們
就能夠順利地進行通訊了。

當然對於TCP應用而言還有另外的解決方案。
馬上請出今天第三位豬腳:MSS。
MSS最大傳輸大小的縮寫,是TCP協議裏面的一個概念。
MSS就是TCP數據包每次能夠傳輸的最大數據分段。爲了達到最佳的傳輸效能
TCP協議在建立連接的時候通常要協商雙方的MSS值,這個值TCP協議在實現的
時候往往用MTU值代替(需要減去IP數據包包頭的大小20Bytes和TCP數據段的
包頭20Bytes)所以往往MSS爲1460。通訊雙方會根據雙方提供的MSS值得最小
值確定爲這次連接的最大MSS值。

介紹完這三位豬腳s
我們回過頭來看前言裏面的那個問題,我們試想一下,如果我們在中間路由器上
把每次TCP連接的最大MSS進行調整這樣使得通過PPPoE鏈路的最大MSS值加上
數據包頭包尾不會超過PPPoE的MTU大小1492這樣就不會造成無法通訊的問題

所以上面的問題可以通過ip tcp adjust-mss 1452來解決。

當然問題也可以通過修改PC機的MTU來解決。

[後記]
Cisco的TCP Adjust MSS Feature:

The TCP MSS Adjustment feature enables the configuration of the
maximum segment size (MSS) for transient packets that traverse a router,
specifically TCP segments in the SYN bit set, when Point to Point Protocol
over Ethernet (PPPoE) is being used in the network. PPPoE truncates the
Ethernet maximum transmission unit (MTU) 1492, and if the effective MTU
on the hosts (PCs) is not changed, the router in between the host and the
server can terminate the TCP sessions. The ip tcp adjust-mss command
specifies the MSS value on the intermediate router of the SYN packets to
avoid truncation.
俺太懶了就不翻譯了。。自己慢慢看

下面是一些mtu的修改方法:

在Win9X下面更改MaxMTU的方法: 
就可以了(當然也可以通過工具完成)
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/Class/
NetTrans/0000/
主鍵下面建立字符串鍵名爲MaxMTU,鍵值爲1450(十進制)。
在WinNT4.0下面更改MaxMTU的方法: 
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters/
中建立MTU鍵名,類型是REG_DWORD,鍵值爲1450(十進制)
在Win2000下面更改MaxMTU的方法: 
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters/
Interfaces/<ID for Adapter>
中建立MTU鍵名,類型是REG_DWORD,鍵值爲1450(十進制)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章