最大傳輸長(zhǎng)度
TCP提供的是一種面向連接的,可靠的字節(jié)流服務(wù),TCP提供可靠性的一種重要的方式就是MSS。通過(guò)MSS,應(yīng)用數(shù)據(jù)被分割成TCP認(rèn)為最適合發(fā)送的數(shù)據(jù)塊,由TCP傳遞給IP的信息單位稱為報(bào)文段或段(segment)。代表一個(gè)TCP socket的結(jié)構(gòu)體struct tcp_sock中有多個(gè)成員用于確定應(yīng)用數(shù)據(jù)被分割成最大為多大的數(shù)據(jù)塊較為合適(最大報(bào)文段長(zhǎng)度MSS)。
??? 我們不難聯(lián)想到,跟最大報(bào)文段長(zhǎng)度最為相關(guān)的一個(gè)參數(shù)是網(wǎng)絡(luò)設(shè)備接口的MTU,以太網(wǎng)的MTU是1500,基本IP首部長(zhǎng)度為20,TCP首部是20,所以MSS的值可達(dá)1460(MSS不包括協(xié)議首部,只包含應(yīng)用數(shù)據(jù))。
??? 前面的TCP三次握手協(xié)議中我們看到,通訊的雙方都通過(guò)TCP選項(xiàng)通告了自己期望接收的MSS值,該值直接來(lái)源于struct tcp_sock的成員advmss,而這個(gè)值直接取自于網(wǎng)絡(luò)設(shè)備接口的MTU減去IP首部和TCP首部的長(zhǎng)度。在本地以太網(wǎng)中可達(dá)1460(如果首部都不含選項(xiàng)的話)。而成員rx_opt是一個(gè)結(jié)構(gòu)體struct tcp_options_received,它記錄的是來(lái)自對(duì)端的TCP選項(xiàng)通告,其成員mss_clamp表示mss的上限值,其來(lái)源就是對(duì)端的MSS通告,而mss_user是用戶設(shè)置的mss,其優(yōu)先級(jí)最高,如果有user_mss,則使用user_mss,忽略其它。
??? 從上面我們可以看到,MSS是可以通過(guò)SYN段進(jìn)行協(xié)商的(MSS選項(xiàng)只能出現(xiàn)在SYN報(bào)文段中),但它并不是任何條件下都可以協(xié)商的,如果一方不接受來(lái)自另一方的MSS值,并且沒有user_mss,則MSS就定為默認(rèn)值536字節(jié)(加上首部,允許576字節(jié)的IP數(shù)據(jù)報(bào))。實(shí)際上,struct tcp_sock->rx_opt->mss_clamp的初始值就定為536,等收到來(lái)自對(duì)端的MSS通告后,才進(jìn)行修改。而結(jié)構(gòu)體struct
tcp_sock的成員mss_cache用于緩存上次的有效的mss,其初始值也被定為536。
??? 函數(shù)mytcp_sync_mss為一個(gè)tcp socket中的mss相關(guān)的成員進(jìn)行數(shù)據(jù)同步,其基本的一個(gè)算法是:
??? 1、當(dāng)前的MSS正常情況下應(yīng)該為mtu-IP首部-TCP首部(不包括選項(xiàng))。
??? 2、struct tcp_sock->rx_opt->mss_clamp中含有對(duì)端通告的能夠接受的MSS值,如果該值小于第一步計(jì)算所得到的MSS,則以該值為準(zhǔn)。
??? 3、IP首部如果帶有IP選項(xiàng),則MSS中要減去選項(xiàng)長(zhǎng)度。
??? 4、如果MSS已經(jīng)小于48了,則令其等于48。
??? 5、減去TCP首部中選項(xiàng)的長(zhǎng)度。
??? 6、如果MSS當(dāng)前已經(jīng)大于滑動(dòng)窗口大小的1/2,則取滑動(dòng)窗口大小的1/2作為MSS值(但不能小于48)。
??? 7、成員mss_cache用于緩存下剛剛計(jì)算所得的MSS。
??? 所以,說(shuō)本地以太網(wǎng)中MSS為1460的說(shuō)法并不正確,它還會(huì)動(dòng)態(tài)變化,如果IP首部和TCP首部中出現(xiàn)選項(xiàng),則MSS要相應(yīng)的減小,一般TCP首部中會(huì)有12字節(jié)的時(shí)間戳選項(xiàng)(外加兩字節(jié)的填充選項(xiàng)),這時(shí)的MSS就等于1448。
??? MSS的主要作用是限制另一端主機(jī)發(fā)送的數(shù)據(jù)的長(zhǎng)度,同時(shí),主機(jī)本身也控制自己發(fā)送數(shù)據(jù)報(bào)的長(zhǎng)度,這將使以較小MTU連接到一個(gè)網(wǎng)絡(luò)上的主機(jī)避免分段。
??? struct tcp_sock有一個(gè)成員xmit_size_goal,用于記錄該socket發(fā)送數(shù)據(jù)報(bào)時(shí)的segment的大小,一般情況下它的值就等于MSS(特殊情況有例外,以后再分析)。
最大傳輸單元(Maximum Transmission Unit,MTU)是指一種通信協(xié)議的某一層上面所能通過(guò)的最大數(shù)據(jù)包大?。ㄒ宰止?jié)為單位)。最大傳輸單元這個(gè)參數(shù)通常與通信接口有關(guān)(網(wǎng)絡(luò)接口卡、串口等)。
因特網(wǎng)協(xié)議允許IP分片,這樣就可以將數(shù)據(jù)報(bào)分成足夠小的片段以通過(guò)那些最大傳輸單元小于該數(shù)據(jù)報(bào)原始大小的鏈路了。這一分片過(guò)程發(fā)生在 IP 層(OSI模型的第三層,即網(wǎng)絡(luò)層),它使用的是將分組發(fā)送到鏈路上的網(wǎng)絡(luò)接口的最大傳輸單元的值。原始分組的分片都被加上了標(biāo)記,這樣目的主機(jī)的 IP 層就能將分組重組成原始的數(shù)據(jù)報(bào)了。
在因特網(wǎng)協(xié)議中,一條因特網(wǎng)傳輸路徑的“路徑最大傳輸單元”被定義為從源地址到目的地址所經(jīng)過(guò)“路徑”上的所有IP跳的最大傳輸單元的最小值。或者從另外一個(gè)角度來(lái)看,就是無(wú)需進(jìn)一步分片就能穿過(guò)這條“路徑”的最大傳輸單元的最大值。
RFC 1191?描述了“路徑最大傳輸單元發(fā)現(xiàn)方法”,這是一種確定兩個(gè) IP 主機(jī)之間路徑最大傳輸單元的技術(shù),其目的是為了避免 IP 分片。在這項(xiàng)技術(shù)中,源地址將設(shè)置數(shù)據(jù)報(bào)的 DF(Don't Fragment,不要分片)標(biāo)記位,再逐漸增大發(fā)送的數(shù)據(jù)報(bào)的大小——路徑上任何需要將分組進(jìn)行分片的設(shè)備都會(huì)將這種數(shù)據(jù)報(bào)丟棄并返回一個(gè)“數(shù)據(jù)報(bào)過(guò)大”的?ICMP?響應(yīng)到源地址——這樣,源主機(jī)就“獲取”到了不用進(jìn)行分片就能通過(guò)這條路徑的最大的最大傳輸單元了。
不幸的是,越來(lái)越多的網(wǎng)絡(luò)封殺了 ICMP 的傳輸(譬如說(shuō)為了防范?DoS?攻擊)——這使得路徑最大傳輸單元發(fā)現(xiàn)方法不能正常工作,其常見表現(xiàn)就是一個(gè)連接在低數(shù)據(jù)流量的情況下可以正常工作,但一旦有大量數(shù)據(jù)同時(shí)發(fā)送,就會(huì)立即掛起(例如在使用?IRC?的時(shí)候,客戶會(huì)發(fā)現(xiàn)在發(fā)送了一個(gè)禁止 IP 欺騙的 ping 之后就得不到任何響應(yīng)了,這是因?yàn)樵撨B接被大量的歡迎消息堵塞了)。而且,在一個(gè)使用因特網(wǎng)協(xié)議的網(wǎng)絡(luò)中,從源地址到目的地址的“路徑”常常會(huì)為了響應(yīng)各種各樣的事件(負(fù)載均衡、擁塞、斷電等等)而被動(dòng)態(tài)地修改——這可能導(dǎo)致路徑最大傳輸單元在傳輸過(guò)程中發(fā)生改變——有時(shí)甚至是反復(fù)的改變。其結(jié)果是,在主機(jī)尋找新的可以安全工作的最大傳輸單元的同時(shí),更多的分組被丟失掉了。
對(duì)于時(shí)下大多數(shù)使用以太網(wǎng)的局域網(wǎng)來(lái)說(shuō),最大傳輸單元的值是 1,500 字節(jié)。但是像?PPPoE?這樣的系統(tǒng)會(huì)減小這個(gè)數(shù)值,通常是1492(= 1500 - 2(PPP)- 6(PPPoE)),這就使得在使用最大傳輸單元發(fā)現(xiàn)方法時(shí)可能會(huì)產(chǎn)生這樣的結(jié)果:一些處于配置不當(dāng)?shù)姆阑饓χ蟮恼军c(diǎn)變得不可達(dá)了。對(duì)于這種情況,還是可能找到變通的方法的,但這取決于你控制的是網(wǎng)絡(luò)的哪一部分。這些方法包括改變用來(lái)在防火墻一端建立 TCP 連接的第一個(gè)分組的 MSS(Maximum Segment Size,最大分段大?。?。
對(duì)于一些支持老版本以太網(wǎng)協(xié)議的?IBM?系統(tǒng)(例如?XSeries),可能只有在把最大傳輸單元設(shè)為 1492 之后才能在當(dāng)下常見的局域網(wǎng)上進(jìn)行運(yùn)作。
[編輯]普通媒體的MTU表
這里的MTU所指的是無(wú)需分段的情況下,可以傳輸?shù)淖畲驣P報(bào)文(包含IP頭部,但不包含協(xié)議棧更下層的頭部)。
超通道
65535
16Mb/s令牌環(huán)
17914
4Mb/s令牌環(huán)
4464
FDDI
4352
以太網(wǎng)
1500
IEEE 802.3/802.2
1492
X.25
576
點(diǎn)對(duì)點(diǎn)(低時(shí)延)
296
網(wǎng)絡(luò) | MTU |
---|