TCPIP詳解卷三:TCP事務(wù)協(xié)議HTTPNNTP和UNIX域協(xié)議10_第1頁
TCPIP詳解卷三:TCP事務(wù)協(xié)議HTTPNNTP和UNIX域協(xié)議10_第2頁
TCPIP詳解卷三:TCP事務(wù)協(xié)議HTTPNNTP和UNIX域協(xié)議10_第3頁
TCPIP詳解卷三:TCP事務(wù)協(xié)議HTTPNNTP和UNIX域協(xié)議10_第4頁
TCPIP詳解卷三:TCP事務(wù)協(xié)議HTTPNNTP和UNIX域協(xié)議10_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第10章T/TCP實(shí)現(xiàn):TCPg數(shù)概述本章包括了T/TCP作過修改的各個(gè)TCP函數(shù)。也就是說,tcp_output(前一章)、tcp_input,和tcp_usrreq(后兩章)以外的所有函數(shù)。本章定義了兩個(gè)新的函數(shù),tcp_rtlookup和tcp_gettaocache,用于在TAO緩存中查找記錄項(xiàng)。tcp_close函數(shù)修改以后,當(dāng)使用T/TCP的連接關(guān)閉時(shí),可以在路由表中記錄往返時(shí)間估計(jì)值(平滑的平均值和平均偏差估計(jì))。常規(guī)協(xié)議只在連接上傳送了至少16個(gè)滿數(shù)據(jù)報(bào)文段后才記錄。然而,T/TCP通常只發(fā)送少量數(shù)據(jù),但與同一對(duì)等端之間的這些不同連接的估計(jì)值應(yīng)該保留下來。T/TCP中對(duì)MSS選項(xiàng)的處理也有所改變。有一部分改變是為了在Net/3中清理過載的tcp_mss函數(shù),這樣就把它分成了一個(gè)計(jì)算MSS以便發(fā)送的函數(shù)(tcp_mssend)和另一個(gè)處理接收到的MSS選項(xiàng)的函數(shù)(tcp_mssrcvd)。T/TCP同時(shí)也將從對(duì)等端收到的最新MSS值保存到TAO緩存記錄項(xiàng)中。在接收到服務(wù)器的SYN和最新的MSS之前,如果要隨SYN發(fā)送數(shù)據(jù),T/TCP就用這個(gè)記錄來初始化發(fā)送MSS。Net/3中的tcp_dooptions函數(shù)修改以后能夠識(shí)別三個(gè)新的T/TCP選項(xiàng):CC、CCnew和CCecho。tcp_newtcpcb函數(shù)用PRU_ATTACH請(qǐng)求創(chuàng)建新的插口時(shí)要調(diào)用該函數(shù)。圖10-1中的五行代碼用來代替卷2第tcp_subr.c667頁的第177~178行。tcp_subr.c100tp->t_mA3cs*g-=tcE)_jnssdfltrLSILf(tcp_do_rfcl323)={TF_REQ_SCALEfTF_REQ_TSTMP)jL自3ifftcp_do_rfcl€44}LE54tp->t_flags|=TF_REC_CC;■■—tcp_^ubrrc圖10-1tcp_newtcpcb函數(shù):T/TCP所做的修改180在前面圖8-3有關(guān)的介紹中提到過,t_maxopd是每個(gè)報(bào)文段中可以發(fā)送的TCP選項(xiàng)加上數(shù)據(jù)的最大字節(jié)數(shù)。它和t_maxseg的默認(rèn)值均為512(tcp_mssdflt)。由于這兩個(gè)值相等,表明報(bào)文段中不能再有TCP選項(xiàng)。在后面的圖10-13和圖10-14中,如果時(shí)間戳選項(xiàng)或者CC選項(xiàng)(或者兩者同時(shí))需要在報(bào)文段中發(fā)送,就要減小t_maxseg的值。183-184如果全局變量tcp_do_rfcl644非零(它的默認(rèn)值為1),且設(shè)置了TF_REQ_CC標(biāo)志,這將使tcp_output伴隨SYN發(fā)出CC或CCnew選項(xiàng)(圖9-6)。

10.3tcp_rtlookup函數(shù)tcp_mss(卷2第717-71頁)執(zhí)行的第一項(xiàng)操作是讀取為該連接所緩存的路由(存儲(chǔ)在一TGutehstructroutestructrtentcy*ro_rt;pointertostnuctwithinformation*/structso{:kaddrro_dst;/*destina-tlonofthisroute*/49};―Toute.l\圖10-2route結(jié)構(gòu)<32structrtentry*tcp_rtLookuptinp)structinpcb*inp;{structroute*ro^structrtentry*rtj4^3ra=fiiinp->iTip_route:439ft=ro->ro_rt:440i£Ut三=NULL|{411/*Narouteyet,satrytoacquireoneiE(iiip^^inp^faddr.s_addr:=iKaDm<ju<Y){ro->ro_dst.sa^family?AF_INET;ro->ro_clst=siseof(ro->uo_dst);<(struct3ockaddr_in*)f(ro->ro_dst)->ain_addr=44644744844945Q4514S2>inp*>inp_facitir44644744844945Q4514S2>)}圖10-3tcp_rtlookup函數(shù)return圖10-3tcp_rtlookup函數(shù)第一部分7C尸事務(wù)協(xié)議InternetPCB的inp_route字段中),如果該路由還沒有緩存過,則調(diào)用rtalloc查找路由?,F(xiàn)在這項(xiàng)操作安排在另一個(gè)獨(dú)立的函數(shù)tcp_rtlookup中實(shí)現(xiàn),我們將在圖10-3中介紹。這樣做是因?yàn)檫B接的路由表記錄項(xiàng)中包括有TAO信息,第一部分7C尸事務(wù)協(xié)議438-452如果這個(gè)連接的路由還沒有在緩存中記錄,rtalloc就計(jì)算出路由。但僅僅當(dāng)PCB中的外部地址非0時(shí)才能計(jì)算路由。在調(diào)用rtalloc之前,要先填寫route結(jié)構(gòu)中的sockaddr_in結(jié)構(gòu)。圖10-2給出了route結(jié)構(gòu),其中的一個(gè)結(jié)構(gòu)在每個(gè)InternetPCB中都有。圖10-4給出了這個(gè)結(jié)構(gòu)的全貌,圖中假定外部地址為128.32.33.5。10.4tcp_gettaocache函數(shù)一個(gè)給定主機(jī)的TAO信息保存在該主機(jī)的路由表記錄項(xiàng)中,確切地說,是在rtmetrics結(jié)構(gòu)的rmx_filler字段中(見6.5節(jié))。圖10-5所示的函數(shù)tcp_gettaocache返回指向該主機(jī)TAO緩存的指針。..-tcp_subr.c45日structntwcp_tao*tcp_gett?ficache(inp)structinpeb*inp;I4^2structrtentry=tcp_rtLookup(inp);i*Eiaiepurethisis&hostrouteandisup,*/if(rtNULL||(rt->rt_flagsA(RTF_UF|RTF_HQST))!=|RTF_HOST)}456return{HULL);467return(rTnx_taop(rt->rt_rnix>);"叩._,tcp_subr.C圖10-5tcp_gettaocache函數(shù)460-468tcp_rtlookup返回的指針指向外部主機(jī)的rtentry結(jié)構(gòu)。如果查找成功,并且RTF_UP和RTF_HOST標(biāo)志均打開了,則宏rmx_taop(見圖6-3)返回的指針指向rmxp_tao構(gòu)。0.5重傳超時(shí)間隔的計(jì)算Net/3的TCP要測量數(shù)據(jù)報(bào)文段往返時(shí)間、跟蹤平滑的RTT估計(jì)器(srtt)和平滑的平均偏差計(jì)器(rttvar),并據(jù)此計(jì)算重傳超時(shí)間隔(RTO)。平均偏差是標(biāo)準(zhǔn)差的良好逼近,比較容易計(jì),因?yàn)榕c標(biāo)準(zhǔn)差不一樣,平均偏差不需要做平方根運(yùn)算。文獻(xiàn)[Jacobson1988]給出了RTT測的其他細(xì)節(jié),并導(dǎo)出以下的計(jì)算公式:delta=data-srttsrtt—srtt+gxdelta

rttvar—rttvar+h(delta|-rttvar)RTO=srtt+4xrttvar中,delta是剛剛得到的往返時(shí)間測量值(data)與當(dāng)前的平滑的RTT估計(jì)器(srtt)之差;g是應(yīng)于RTT估計(jì)器的增益,等于1/8;h是應(yīng)用于平均偏差估計(jì)器的增益,等于1/4。在RTO計(jì)算中的兩個(gè)增益和乘數(shù)4特意取為2的乘冪,因此可以通過移位操作來代替乘除運(yùn)算。卷2的第25章給出了如何用定點(diǎn)整數(shù)來保存這些值的有關(guān)細(xì)節(jié)。在常規(guī)的TCP連接中,在計(jì)算s心和也wr這兩個(gè)估計(jì)器時(shí),通常要對(duì)多個(gè)RTT取樣,對(duì)于圖1-9中的給定最小TCP連接來說,至少要有兩個(gè)樣本。而且,在一定條件下,Net/3將對(duì)相同主機(jī)之間的多個(gè)連接運(yùn)用這兩個(gè)估計(jì)器。這是tcp_close函數(shù)實(shí)現(xiàn)的,在一個(gè)連接關(guān)閉時(shí),如果有關(guān)對(duì)等端的路由表記錄項(xiàng)不是默認(rèn)路由,并且至少得到了16個(gè)RTT樣值。估計(jì)的結(jié)果存儲(chǔ)在路由表記錄項(xiàng)中rt_metrics結(jié)構(gòu)的rmx_rtt和rmx_rttvar字段中。新連接建立時(shí),tcp_mssrcvd(見10.8節(jié))從路由表記錄項(xiàng)中取出這兩個(gè)值作為srtt和rttvar這兩個(gè)估計(jì)器的初始值。T/TCP中出現(xiàn)的問題是,一個(gè)最小連接只有一個(gè)RTT測量值,而且少于16個(gè)樣值是很正常的,因此在兩個(gè)對(duì)等端之間相繼建立拆除的T/TCP連接對(duì)上述測量和估計(jì)一點(diǎn)貢獻(xiàn)也沒有。這就意味著在T/TCP中,第一個(gè)報(bào)文段發(fā)出去時(shí)根本就不知道RTO的取值應(yīng)該是多少。卷2的25.8節(jié)討論了tcp_newtcpcb執(zhí)行初始化時(shí)是怎樣確定第一個(gè)RTO應(yīng)該是6秒的。讓tcp_close在即使只收集到少于16個(gè)樣值也存儲(chǔ)對(duì)T/TCP連接的平滑估計(jì)結(jié)果并不難(在10.6節(jié)中我們會(huì)看到為此所做的修改),但問題是:如何將新估計(jì)值與以前的估計(jì)值進(jìn)行歸并?不幸的是,這仍然還是一個(gè)正在研究的問題[Paxson1995a]。為了理解各種不同的可能性,請(qǐng)考慮圖10-6中的情況。從作者的一臺(tái)主機(jī)上通過Internet向另一臺(tái)主機(jī)上的回顯服務(wù)器發(fā)送100個(gè)400字節(jié)長的UDP數(shù)據(jù)報(bào)(在一個(gè)工作日的下午,通常是Internet上最為擁擠的時(shí)候)。93個(gè)數(shù)據(jù)報(bào)有回顯返回(還有7個(gè)不知在Internet的哪些地方丟失了),在圖10-6中給出了前91個(gè)數(shù)據(jù)報(bào)。樣值是在30分鐘的時(shí)間內(nèi)采集到的,前后數(shù)據(jù)報(bào)之間的時(shí)間間隔是在0~30秒之間均勻分布的隨機(jī)數(shù)。實(shí)際的RTT是在客戶主機(jī)上運(yùn)行Tcpdump得到的。黑點(diǎn)就是測量得到的RTT。另外的三條實(shí)線(從上至下依次是RTO、srtt和rttvar)是運(yùn)用本

第一部分7CP事務(wù)協(xié)議1^載節(jié)開頭的公式從測得的RTT計(jì)算出來的。計(jì)算是用浮點(diǎn)算術(shù)完成的,而不是Net/3中實(shí)際所用的定點(diǎn)整數(shù)方法。圖上所示的RTO就是從相應(yīng)的數(shù)據(jù)點(diǎn)計(jì)算出來的值。也就是說,第一個(gè)數(shù)據(jù)點(diǎn)(大約2200ms)的RTO第一部分7CP事務(wù)協(xié)議1^載盡管所測得的RTT值平均都在800ms以下(作者的客戶系統(tǒng)是通過撥號(hào)線上的PPP連接到Internet上的,穿越整個(gè)國家才能到達(dá)服務(wù)器),第26個(gè)樣值的RTT幾乎達(dá)到1400ms,此后有少量的一些點(diǎn)在1000ms左右。[Jacobson1994]指出,“只要是有競爭的連接共享一條路由,瞬間RTT波動(dòng)達(dá)到2倍最小值是完全正常的(它們僅僅表示另外一個(gè)連接的開始或丟失后重新開始),因此,RTO小于2XRTT從來就不會(huì)是合理的”。當(dāng)估計(jì)器有新值存儲(chǔ)到路由表記錄項(xiàng)中時(shí),必須做出判斷,對(duì)應(yīng)于已經(jīng)過去的歷史,有多少信息是新的。這樣,計(jì)算公式就為:savesrtt=gxsavesrtt+(1-g)xsrttsaverttvar=gxsaverttvar+(1-g)xrttvar這是一個(gè)低通濾波器,其中g(shù)是取值在0~1之間的過濾增益常量,savesrtt和saverttvar是存儲(chǔ)在路由表記錄項(xiàng)中的數(shù)值。當(dāng)Net/3用這些公式更新路由表記錄時(shí)(當(dāng)一個(gè)連接關(guān)閉,并假定得到了16個(gè)樣值),它采用的增益是0.5:存儲(chǔ)在路由表中的值有一半是路由表中的舊值,另有一半是當(dāng)前估計(jì)的值。BobBraden的T/TCP代碼中取增益為0.75。時(shí)間(ms)時(shí)間(ms)圖10-7給出了從圖10-6中的數(shù)據(jù)用常規(guī)TCP計(jì)算方法算出的結(jié)果與用濾波器增益0.75平滑的計(jì)算結(jié)果之間的比較。圖中的三條虛線就是圖10-6中的三個(gè)變量(RTO在最上方,srtt在中間,rttvar在底部)。三條實(shí)線則是假定每一個(gè)數(shù)據(jù)點(diǎn)都是一個(gè)獨(dú)立T/TCP連接(每一個(gè)連接有一個(gè)RTT測量值)所對(duì)應(yīng)的變量,并且采用濾波增益0.75進(jìn)行了平滑。要知道有這樣的差別:虛線對(duì)應(yīng)的是一個(gè)TCP連接在30分鐘內(nèi)的91個(gè)RTT樣本;而實(shí)線對(duì)應(yīng)的則是在同樣的30分鐘內(nèi)91個(gè)獨(dú)立的T/TCP連接,每個(gè)連接有一次RTT測量。實(shí)線同時(shí)還是91個(gè)連接的所有相繼兩個(gè)估計(jì)值歸并后記錄到兩個(gè)路由度量值中的。代表s沱的實(shí)線和虛線差別不大,但是代表rttvar的實(shí)線和虛線之間就有明顯的差別。rttvar的實(shí)線(T/TCP情況)取值通常大于虛線(單個(gè)TCP連接),使T/TCP的重傳超時(shí)間隔可以取更大的值。還有其他因素也在影響T/TCP中的RTT測量。從客戶端來看,所測得的RTT通常包括服務(wù)器的處理時(shí)間或者服務(wù)器的延遲ACK定時(shí)值,因?yàn)榉?wù)器的應(yīng)答通常會(huì)延遲到這些事件發(fā)生后才給出。在Net/3中,延遲ACK的定時(shí)器值是每200ms到時(shí)一次,而RTT測量的時(shí)間單位為500ms,因此應(yīng)答時(shí)延不會(huì)是一個(gè)大的因素。而且T/TCP報(bào)文段的處理常常會(huì)在TCP輸入處理中遭遇慢通道(例如,報(bào)文段常常不被用于首部預(yù)測),會(huì)加大測得的RTT值(然而快通道與慢通道的差別相對(duì)于200ms的延遲ACK定時(shí)器值來說很可能是可以忽略的)。最后,如果存儲(chǔ)在路由表中的值“過時(shí)”了(就是說,其最后一次更新是在一個(gè)小時(shí)以前),在當(dāng)前事務(wù)完成以后,或許應(yīng)該用當(dāng)前的測量值直接替換路由表中的值,而不是用新的測量值與已有的測量值歸并。如RFC1644中所指出的,需要對(duì)TCP中的動(dòng)態(tài)特性作更多的研究,特別是T/TCP,以及RTT估計(jì)。10.6tcp_close函數(shù)tcp_close的唯一改變是要為T/TCP事務(wù)記錄RTT估計(jì)值,即使還沒有湊足16個(gè)樣值。我們?cè)谇耙还?jié)中已經(jīng)敘述了這樣做的原因。圖10-8給出了代碼。

90第一部分TCP事務(wù)協(xié)議CWi^MM!1^載圖90第一部分TCP事務(wù)協(xié)議CWi^MM!1^載只對(duì)T/TCP事務(wù)進(jìn)行更新304-311只有在連接中使用了T/TCP(cc_recv非0)、有一路由表記錄項(xiàng)存在及不是默認(rèn)路由時(shí)才更新路由表記錄項(xiàng)中的度量值。而且,只有當(dāng)兩個(gè)RTT估計(jì)值沒有加鎖(RTV_RTT和RTV_RTTVAR位)時(shí)才更新。更新RTT312-324t_srtt是以500msX8為時(shí)間單位保存的,rmx_rtt則以s為單位保存。這樣,t_srtt就要乘1000000(RTM_RTTUNIT)除2(時(shí)間單位/秒)再乘8。如果rmx_rtt已經(jīng)有值,新記錄值就是舊值的四分之三加上新值的四分之一。這就是取濾波增益為0.75,我們?cè)谇耙还?jié)已討論過。否則,直接將新值保存到rmx_rtt中。更新平均偏差325-334對(duì)平均偏差估計(jì)值應(yīng)用同樣的算法。它也以ms為單位保存,需要將t_rttvar中的單位時(shí)間X4。10.7tcp_msssend函數(shù)在Net/3中,有一個(gè)函數(shù)tcp_mss(卷2的27.5節(jié)),在處理MSS選項(xiàng)時(shí)tcp_input要調(diào)用它,在需要發(fā)送MSS選項(xiàng)時(shí)tcp_output也要調(diào)用它。在T/TCP中,這個(gè)函數(shù)改名為tcp_mssrcvd,在執(zhí)行隱式連接建立時(shí),收到SYN后,tcp_input要調(diào)用它(在后面的圖10-18中,確定是否需要在SYN中包含MSS選項(xiàng)),以及PRU_SEND和PRU_SEND_EOF請(qǐng)求要調(diào)用它(見圖12-4)。有一個(gè)新的函數(shù)tcp_msssend,如圖10-9所示,只有當(dāng)發(fā)出了MSS選項(xiàng)時(shí),才會(huì)被tcp_output調(diào)用。tqrjnput.c1311inttcp_mBssend(tp)structtcpcb*tpi1314{structrtentryexterninttrp_Mssdflt:rt=tcp_rtlookup(tp->t_inpcb);1916iffrt—NULL)r*tum(tcp_jnasdfIt);/**iftherersanmtuassociatedwiththeroute,useitr

192219231924192519261927}*else192219231924192519261927}*/i£(rt->rt_iMac.?rmx_jntu}return(rt->rt_rrax.nnK_jntu-sizeaf£structtcpiphdr))jreturn(rt->i6t_ifp->ifjntu-siz.eof(structtcpiphdr))?frp_mpwt,c圖10-9(續(xù))讀取路由表記錄項(xiàng)1917-1919為每一個(gè)對(duì)等主機(jī)搜索路由表,如果沒有找到記錄項(xiàng),則返回默認(rèn)值512(tcp_mssdflt)。除非對(duì)等主機(jī)不可達(dá),否則總是可以查找到一個(gè)路由表記錄項(xiàng)的。返回MSS1920-1926如果路由表有一個(gè)關(guān)聯(lián)的MTU(rt_metrics結(jié)構(gòu)中的rmx_mtu字段,系統(tǒng)管理員可以用route程序設(shè)置),就返回該值。否則,一返回值就取輸出接口的一MTU減去40(例如,以太網(wǎng)上是1460)。因?yàn)槁酚梢呀?jīng)由tcp_rtlookup確定,輸出接口也是已知的。在路由表中存儲(chǔ)MTU度量的另一個(gè)來源是利用路由MTU發(fā)現(xiàn)過程(卷1的24.2節(jié)),盡管Net/3中還不支持這種方法。這個(gè)函數(shù)不同于通常的BSD做法。如果對(duì)等端是非本地主機(jī)(由in_localaddr函數(shù)決定),而且rmx_mtu度量值為0,則Net/3代碼(卷2第719頁)中總是將MSS取為512(tcp_mssdflt)。MSS選項(xiàng)的目的是告訴另一端,該選項(xiàng)發(fā)送者準(zhǔn)備接收多大報(bào)文段。RFC793中指出,MSS選項(xiàng)“用于交流發(fā)送這個(gè)報(bào)文段的TCP的最大可接收?qǐng)?bào)文段”。在一些實(shí)現(xiàn)中,這可能受主機(jī)能夠重裝的最大IP數(shù)據(jù)報(bào)限制。然而在當(dāng)前的大多數(shù)系統(tǒng)中,合理的限制決定于輸出接口的MTU,因?yàn)槿绻枰侄尾⑶野l(fā)生報(bào)文段丟失,貝【JTCP的性能會(huì)下降。下面的注釋摘抄于BobBraden的T/TCP源碼修改:“非常不幸,使用TCP選項(xiàng)要求對(duì)BSD作可觀的修改,因?yàn)樗鼘?duì)MSS的處理是錯(cuò)誤的。BSD總是要發(fā)出MSS選項(xiàng),并且對(duì)非本地網(wǎng)絡(luò)的主機(jī),這個(gè)選項(xiàng)的值是536。這是對(duì)MSS選項(xiàng)用途的誤解,這個(gè)選項(xiàng)是要告訴發(fā)送者,接收者準(zhǔn)備處理什么。這時(shí)發(fā)送主機(jī)要決定用多大的MSS,既要考慮它接收的MSS選項(xiàng),還要考慮到路由情況。當(dāng)我們有了MTU發(fā)現(xiàn)以后,這個(gè)路由很可能有一個(gè)大于536的MTU;這樣,BSD就會(huì)降低吞吐率。因此,這個(gè)程序只確定了應(yīng)該發(fā)送什么樣的MSS選項(xiàng):本地接口的MTU減去40?!保ㄟ@段注釋中講到的值536應(yīng)為512)。我們?cè)谙乱还?jié)(圖10-12)中會(huì)看到,如果對(duì)等端是非本地主機(jī),MSS選項(xiàng)的接收者才把MSS減到512。10.8tcp_mssrcvd函數(shù)在執(zhí)行隱式連接建立時(shí),收到USYN以后的tcp_input要調(diào)用tcp_mssrcvd,PRU_SEND和PRU_SEND_EOF也都要調(diào)用它。該函數(shù)與卷2中的tcp_mss函數(shù)相似,但是它們之間還是有足夠的差別「能夠完成我們所需的全部功能。這個(gè)函數(shù)的主要目標(biāo)是設(shè)置兩個(gè)變量,一個(gè)是t_maxseg(我們?cè)诿總€(gè)報(bào)文段中發(fā)送的最大數(shù)據(jù)量),另一個(gè)是t_maxopd(在每個(gè)報(bào)文段中發(fā)送的數(shù)據(jù)加選項(xiàng)的最大長度)。圖10-10給出了這個(gè)函數(shù)的第一部分。第一部分TCP事務(wù)協(xié)議

下^載175S1756175717581159176017SI176217631764176517661767176817691770voidtcp-Sfis3revd(tPioffer)-atruettepeb*tp;irat(offer;;structstructintu_lQngstructstructstructintexternexternexternrteiitry*rt;ifnet*ifp;rtt?mes;bufsise;inpeb*inp;sa-cket*so;rraxp_tao*tacprorigaEfer=offerfinttcp_sfl^sdfltyinttcp_do_rfcl323;inttGp_do_rfC1644;1771177217711774177517761777inp-tp->t_inpcb;if({rt=tcp_rtlookup(lnp))tp->t_maxopd-tp=>t_maxsegreturn;Iifp=目令■inp->inp_soc]cet:NULL}(=twjnssdfIt;177S177917801781178217831784170517861787178817891790179117921793179417951796179717981799t點(diǎn)Op=rtix^taop(rt->rts?x)iOffer==-1meanswehavenJtusecachedvalueinthatcase.?/i£(offer1)offer=taop->tao_ms9Opt;receivedaSYNyet;offer"=0■maan.fithattherew<bn。MS9ontheSYNfornovalueintheTAOCache-Weusetcp_jns3dflt.*/i£(offez■舊0)offer=tcp_mssdflt?else/**Sanitychecks皿k白surethatmaxopdwillbelarffeenoughtoaLlgscimedataonBegmentsevenifalltheoptionisused(40bytes)?otliezwiBefunnythingamayhappenintcp__outpiit*offer=max(effete64);taop->tao_mssopt=offer;圖10-10tcp_mssrcvd函數(shù):第一部分1.取對(duì)等端的路由及其TAO緩存1771-1777tcp_rtlookup查找到達(dá)對(duì)等端的路由。如果由于某種原因,查找路由失敗了,t_maxseg和t_maxopd就同時(shí)設(shè)置為512(tcp_mssdflt)。1778-1799taop指向該對(duì)等端的TAO緩存,位于路由表的記錄項(xiàng)中。如果因?yàn)橛脩暨M(jìn)程調(diào)用了sendto(一次隱式連接建立,是PRU_SEND和PRU_SEND_EOF請(qǐng)求的一部分)而調(diào)用tcp_mssrcvd,則offer設(shè)置為TAO緩存中保存的值。如果TAO中的該值為0,offer就設(shè)置為512。TAO緩存中的值被更新。圖10-11給出了該函數(shù)的第二部分,與卷2第718頁完全相同。1900tcp_mpuLc1801*油ilewh*reh&reTcheckifth?reF£aninitialxttL8C2*rttvar.convertfromtheroute-taiileunits1003?toscaledmultiplesofttisslawtimeouttimer.1804*/1805i£(tp->t_srnc==C(rtt=rt->rt_nnx.rmx^rtt)}(18061807*XXXthslockbitforRTTindicate?thatth?vilue1808*isalsoa.minimumvalue;thisissubjecttotime.18051B10if(rt->rt_rmx.nnx_lockfi&htv_BTT)1811tp->t_rttmin=rtt/{RTH_RTTnNIT/PR_SIXJWHa}t1&12=rtt/(RTM_RTTUNITf(PE_SLOWHZ*TCP_RTT_SCALE)):1Mif(rt->rt_nnx.rmx_rttvar)1314tp->t_rttvar■.rmx_rttvax/1515(ftTM.RTTUNIT/(PR_SD0WBZ*TCP-RTTVAICSCALE));18161817/*defaultvariationis+-1rtt*/1&1Btp->t=xttvar=1&13?TCP_RTTVAR_SCALiE/TCP_RTT_£CALE;1?20TCPT_RANGESET(tp->t_rxtcur,1321((tp->t_artt2}+tp->t_rttvarj?lt1822TCPIV_REXMTMAX);1823}tcpjnput.c圖10-11tcp_mssrcvd函數(shù):用路由表度量值初始化RTT變量1800-1823如果還沒有該連接的RTT測量值(t_srtt為0),并且rmx_rtt度量值為非0,這時(shí)變量t_srtt、t_rttvar和t_rxtcur就用路由表記錄項(xiàng)中保存的度量值初始化。如果路由表度量值加鎖標(biāo)志中的RTV_RTT位已經(jīng)設(shè)置,則它表明還要用rmx_rtt來初始化這次連接的最小RTT(t_rttmin)。默認(rèn)情況下,t_rttmin初始化為兩個(gè)時(shí)鐘步進(jìn),這為系統(tǒng)管理員替換該默認(rèn)值提供了一個(gè)方法。圖10-12給出了tcp_mssrcvd的第三部分,用于設(shè)置自動(dòng)變量mss的值。tqiinput.cA*'1.825*rftherersanmtuassociatedwithth*routeTuseit.?$1827it[rt->rLmtKjiiLu)ms旦=rt->rt_nrK.rmx_nitu-siieof(structtcpiphdr);182Selse{mss=-sieeof(structtcpiphdr}iif(iin_loealaddr(inp->inp_faddr))1$32mss?mintcp_mssd£lt};isn}1035ms1&S7ISIS1643M4L11035ms1&S7ISIS1643M4L1心4t_maxopdcontainsthemaximmnlength,of3ataANDoptionsinasegment;t_naxsegistheamountOflaancrmaLsegment,WeneedtostoratillsvaLue(t_jiaxopd)apartfromtjnaxse^jneweverysegmentmcontainoptiodSthereforewenoinallyhav&sdra^wtiatileaadatainsegmerLts.*/tp-:>tmaxopd=mss;.frp_inpuLc1824-1834如果該路由關(guān)聯(lián)于一個(gè)MTU(rmx_mtu度量值),那就用這個(gè)值。否則,mss就取輸出接口的MTU減去40。另外,如果對(duì)等端是在另一個(gè)網(wǎng)絡(luò),或者也可能在另一個(gè)子網(wǎng)(由in_localaddr函數(shù)決定)中,這時(shí)mss的最大值取為512(tcp_mssdflt)。如果路由表記錄項(xiàng)中已經(jīng)保存有MTU,那就不再進(jìn)行本地-非本地測試。設(shè)置t_maxopd1835-1842t_maxopd設(shè)置為mss,包括了數(shù)據(jù)和選項(xiàng)的最大報(bào)文段長度。圖10-13給出的是第四部分代碼,將mss減去在每一個(gè)報(bào)文段中都有的選項(xiàng)長度。1843M44音A-djus-tmsstoleavespacefortheusual.Werr?*calledfrom,theendtcp_dooptionssowecanugthe1@4&*REQ/RCVDflagstae&eifoptionswillbeused.1047*Z18481949rIn口弋T/TCP,origcffer==-1indicatesthatnosegments185D*ww白receivedyst(iFclienthascall&dsefidto)rTnthis1851*Cisewejuatguess*otherwisEwedothesameasbeforeT/1t?P.1&52*/1H53if<(tp->t_flags&(TF.RECl^TSTMF|TF.JJQOPT))■?TF_RE(1,TSTMP&&18551S561S57(Otigoffar=■-1|[tp->t_fla5S&TF_ftCVE_TSTWP)==TF_RCVB_TSTMP))IU5H-=TCPaLEN_TSrAMP_JLPPAjif(&(TF_REQ_CCITF_NOaPT)]==TF_HEQ_CC1£58185S18601861(origoffer-1||(tp->t_£lag3&TF_RCVD_CC)==TF_RCVD_CC))mss—=TCE?OLEN_CC_APFA;#i£(MCLBYTeS&(MCLBYTES-1))==Q1662if(mss>MCLBYTES]LB6313641S65HISS&=(MCLEYTES-1);盹1日白i£[mssaMCLBYTES)18661867ms3=mss/MCLBYTES*MCLBYTESj-fendiftcp_input.c圖10-13tcpmssrcvd函數(shù):根據(jù)選項(xiàng)減小mss如果使用時(shí)間戳選項(xiàng)就減小mss1843-1856如果下面中的任何一個(gè)條件為真,則mss就減去時(shí)間戳選項(xiàng)的長度(TCPOLEN_TSTAMP_APPA,即12字節(jié)):1)本地端將使用時(shí)間戳選項(xiàng)(TF_REQ_TSTAMP),并且還沒有收到另一端發(fā)來的mss選項(xiàng)(origoffer等于-1);或2)已經(jīng)收到另一個(gè)端發(fā)來的時(shí)間戳選項(xiàng)。在代碼的注釋中指出,由于tcp_mssrcvd是在tcp_dooptions結(jié)束時(shí)所有的選項(xiàng)處理完以后調(diào)用的(見圖10-18),因此第二項(xiàng)測試是成功的。如果使用CC選項(xiàng),就減少mss1857-1860通過相似的邏輯,mss的值減去8字節(jié)(TCPOLEN_CC_APPA)。這兩個(gè)長度名稱中出現(xiàn)術(shù)語APPA是因?yàn)?,RFC1323的附錄A中建議在時(shí)間戳選項(xiàng)前面置兩個(gè)空字符NOP,以便兩個(gè)4字節(jié)時(shí)間戳值的長度都能取4字節(jié)的整數(shù)倍。同時(shí)RFC1644也有一個(gè)附錄A,它對(duì)選項(xiàng)排列沒有說什么。無論怎樣,在三個(gè)CC選項(xiàng)的任一個(gè)前面都置兩個(gè)NOP是有一定道理的,如圖9-6所示。舍入MSS為MCLBYTES的倍數(shù)1861-1867mss要舍入取整為MCLBYTES的整數(shù)倍,即每個(gè)mbuf簇的字節(jié)數(shù)(通常為1024或2048)。這段代碼有一個(gè)糟糕的優(yōu)化企圖,即如果MCLBYTES是2的整數(shù)冪,則可以用邏輯操作來代替乘法或除法運(yùn)算。自從Net/1開始,它就已經(jīng)是一條彎路,應(yīng)該清除掉。圖10-14給出了tcp_mssrcvd代碼的最后一部分,用于設(shè)置發(fā)送緩存和接收緩存的大小°tqjjnput.c1A68/**Ifthere1Saplpcslzejchangethesocketbuffex1870*tothatsize-Kakethesocketbuffersanintegral.1371*nuniberofunits;ifthetubsislargerthatt1372*thesocketbuffer,decreasethe腰73*/1374if{(bufsirmix:_5endpipe}=-0}1S?5hufsize=sq->eo_snd...sb_hiwat】1876if(bufsize<mssi1877msg=bufsize;1S7Selse{1079bufsiae=roundup(bufei3errass};1B80if(bufsize>sb_?ftaxl1BSLbufsize-:{void}sbrese*->sa_snd.bdfsise):188311834tp->t_jnaxseg-1885if(Ibufeize=rt->rt_rmx.rmx_recvpipe)==18B6buf&ize=so->.sb^hiwst;1887if(bufi&ize>mssj(1SB8bufsize=roundup(feufsisefitss)?18B9if>sb_jnax)ia?obufsize=sb_fnax;lagi(void)sbreserve(&so->so_rcv,bufsize);LW:■1B93/*1S94*DonJtEoirc-eslew-startonlocalnetwork.*/1896if(!i.n_localafldr(inp->inp_faddr})1897tp->9nd__?nd-mss?1393if(rt->rt_iniDc.thresh)(18991900**RiereMs$口:住sortofgatewayinterface1901?bufferLimitonthepath.Usethistoset1902*themlgBtittthreshhold.butEatttieL.303皆thr已shoLdtonolessthan耳1904*/1905tp->snd_ssthresh=max(2*mss,rmx_B5thresh】,}1907)Ifiwnufr改變插口發(fā)送緩存的大小1868-1883系統(tǒng)管理員可以用route程序設(shè)置rmx_sendpipe和rmx_recvpipe這兩個(gè)度量值。bufsize的值就設(shè)置為rmx_sendpipe的值(如果已有定義),或者當(dāng)前插口發(fā)送緩存的高位值。如果bufsize的值小于mss,mss值就減小為取bufsize的值(這是一種強(qiáng)迫MSS取比給定目標(biāo)的默認(rèn)值還小的取值方法)。否則,bufsize的值放大,取mss的整數(shù)倍(插口緩存的大小總是取報(bào)文段長度的整數(shù)倍)。上限為sb_max,在Net/3就是262144。插口緩存的高位值由sbreserve設(shè)置。設(shè)置t_maxseg1884t_maxseg設(shè)置為TCP將發(fā)給對(duì)等端的最大數(shù)據(jù)量(不包括常規(guī)選項(xiàng))。改變插口接收緩存的大小1885-1892插口接收緩存的高位值可以用類似的邏輯來設(shè)置。例如,對(duì)于以太網(wǎng)上的本地連接來說,假定時(shí)間戳選項(xiàng)和CC選項(xiàng)同時(shí)都在用,則t_maxopd將是1460,t_maxseg為1440(見圖2-4)。插口發(fā)送緩存和接收緩存都將從它們的默認(rèn)值8192倦2的圖16-4)舍入到8640(1440X6)。非本地對(duì)等端才有的慢啟動(dòng)1893-1897如果對(duì)等端不是在本地的網(wǎng)絡(luò)中(in_localaddr為假),則把擁塞窗口(snd_cwnd)設(shè)置為1個(gè)報(bào)文段就開始了慢啟動(dòng)過程。僅僅當(dāng)對(duì)等端在非本地網(wǎng)中才強(qiáng)迫使用慢啟動(dòng)是T/TCP修改后的結(jié)果。這就使T/TCP的客戶端或服務(wù)器端可以向本地對(duì)等端發(fā)送多個(gè)報(bào)文段,又不需要慢啟動(dòng)所要求的額外RTT等待時(shí)間(見3.6節(jié))。在Net/3中,總是執(zhí)行慢啟動(dòng)過程(卷2第721頁)。設(shè)置慢啟動(dòng)門限1898-1906如果慢啟動(dòng)門限度量值(rmx_ssthresh)非0,snd_ssthresh就設(shè)置取該值。我們?cè)趫D3-1和圖3-3中可以看到MSS和TAO緩存與接收緩存大小之間的交叉影響。在圖3-1中,客戶端執(zhí)行了一次隱式連接建立,PRU_SEND_EOF請(qǐng)求調(diào)用tcp_mssrcvd,其中offer為-1,該函數(shù)查找到對(duì)應(yīng)服務(wù)器的tao_mssopt值為0(因?yàn)榭蛻舳藙倓傊貑ⅲ?。取MSS為默認(rèn)值512,因?yàn)橹皇褂昧薈C選項(xiàng)(在第2章的例子中,時(shí)間戳無效),減去8字節(jié)后變?yōu)?04。注意,8192舍入為504的整數(shù)倍后為8568,這是客戶端SYN所通告的窗口。然而,當(dāng)服務(wù)器調(diào)用tcp_mssrcvd時(shí),它已經(jīng)接收到客戶端的SYN,其中給定MSS為1460。這個(gè)值減去8字節(jié)(選項(xiàng)長度)后為1452,8192舍入到1452的整數(shù)倍后為8172。這是服務(wù)器的SYN中通告的窗口。當(dāng)客戶端處理完服務(wù)器的SYN后(圖中第三段),客戶端再次調(diào)用tcp_mssrcvd,這一次offer為1460。這就將客戶端的t_maxopd增大至1460,客戶端的t_maxseg則增大至1452,客戶端的接收緩存因舍入而增至8172。這就是客戶端在對(duì)服務(wù)器的SYN作出ACK時(shí)通告的窗口。在圖3-3中,當(dāng)客戶端執(zhí)行了隱式連接建立時(shí),tao_mssopt值為1460-最近一次從對(duì)等端收到的值??蛻舳送ǜ娴拇翱跒?712,1452的整數(shù)倍且大于8192。10.9tcp_dooptions函數(shù)在Net/1和Net/2版中,tcp_dooptions只能識(shí)別NOP、EOL和MSS選項(xiàng),并且函數(shù)有3個(gè)參數(shù)。在Net/3中增加了對(duì)窗口寬度和時(shí)間戳選項(xiàng)的支持后,參數(shù)的數(shù)量也增加到7個(gè)(卷2第

745~746頁),其中有3個(gè)就是為了時(shí)間戳選項(xiàng)而加的?,F(xiàn)在又需要支持CC、CCnew和CCecho選項(xiàng),參數(shù)的數(shù)量不是增加反而減少到了5個(gè),因?yàn)椴捎昧肆硪环N技術(shù)來返回選項(xiàng)是否存在以及它們各自的取值信息。圖10-15給出了tcpopt結(jié)構(gòu)。其中的一個(gè)結(jié)構(gòu)是在tcp_input(唯一可以調(diào)用tcp_dooptions的函數(shù))中分配的,并且將指向該結(jié)構(gòu)的指針傳給tcp_dooptions,該函數(shù)填寫結(jié)構(gòu)的內(nèi)容。在處理接收到的報(bào)文段時(shí),tcp_input要用到存儲(chǔ)在該結(jié)構(gòu)中的值。圖10-15圖10-15tcpopt結(jié)構(gòu),由tcp_dooptms填寫數(shù)據(jù)圖10-16給出了to_flag字段可以組合出的4個(gè)值。to__flag說明CL滯T市中VrTOFCCTOF_CCNEWTOF_CCECHOTOF_TS圖10-16toCC選項(xiàng)存在CCnew選項(xiàng)存在CCecho選項(xiàng)存在時(shí)間戳選項(xiàng)存在)flag的取值15201521152215231524152515261527voidtep_dooption&(tprcp?entr15201521152215231524152515261527voidtep_dooption&(tprcp?entrti,to)structu^charintstructstructItcpcb*tppent;tcpiphdx*ti?tcpopt*to;圖10-17tcpdooptions函數(shù):參數(shù)因?yàn)樘幚鞥OL、NOP、MSS、窗口寬度和時(shí)間戳選項(xiàng)的代碼與卷2第745~747頁的代碼幾乎相同,所以這里不再重復(fù)介紹(差別主要在于對(duì)新參數(shù)的處理,我們剛剛討論過)。圖10-18給出了這個(gè)函數(shù)的最后一部分代碼,它們用于T/TCP處理3個(gè)新的選項(xiàng)。檢查長度和是否處理選項(xiàng)1580-1584選項(xiàng)長度要驗(yàn)證(所有3個(gè)CC選項(xiàng)的長度必須都是6)。處理接收到的CC選項(xiàng)時(shí),我們也必須發(fā)送相應(yīng)選項(xiàng)(如果內(nèi)核的tcp_do_rfcl644標(biāo)志已經(jīng)設(shè)置,貝Utcp_newtcpcb要設(shè)置TF_REQ_CC標(biāo)志),并且TF_NOOPT標(biāo)志不能設(shè)置(最后這個(gè)標(biāo)志不允許TCP在其SYN中發(fā)送任何選項(xiàng))。

設(shè)置相應(yīng)標(biāo)志并復(fù)制4字節(jié)值1585-1588設(shè)置相應(yīng)的to_flag值。四個(gè)字節(jié)的選項(xiàng)值存儲(chǔ)在tcpopt結(jié)構(gòu)的to_cc字段中,并且要先轉(zhuǎn)換成主機(jī)的字節(jié)順序。1589-1595如果這是一個(gè)SYN報(bào)文段,要為該連接設(shè)置TF_RCVD_CC標(biāo)志,因?yàn)槭盏搅薈C選項(xiàng)。CCnew和CCecho選項(xiàng)1596-1623CCnew和CCecho選項(xiàng)的處理步驟與CC選項(xiàng)的相似。但因?yàn)镃Cnew和CCecho選項(xiàng)僅在SYN報(bào)文段中有效,所以要附加一項(xiàng)檢測,檢查報(bào)文段中是否包含SYN標(biāo)志。盡管TOF_CCNEW標(biāo)志都有正確設(shè)置,但從來不去檢查它。這是因?yàn)樵趫D11-6中,如果CC選項(xiàng)不存在,則緩存的CC值是無效的(即需設(shè)置為0)。如果存在CCnew選項(xiàng),則cc_recv仍然有正確設(shè)置(注意,在圖10-18中,CC和CCnew選項(xiàng)都在to_cc中存儲(chǔ)其值),并且當(dāng)三次握手完成時(shí)(圖11-14),所緩存的值tao_cc是從cc_recv中復(fù)制過來的。處理收到的MSS1625-1626局部變量mss記錄的或者是MSS選項(xiàng)的值(如果選項(xiàng)存在),或者是表示選項(xiàng)不存在的0值。在這兩種情況下,tcp_mssrcvd都要設(shè)置變量t_maxseg和t_maxopd的值。在tcp_dooptions快結(jié)束時(shí)要調(diào)用該函數(shù),因?yàn)槿鐖D10-13所示,tcp_mssrcvd使用了TF_RCVD_TSTMP和TF_RCVD_CC標(biāo)志。10.10tcp_reass函數(shù)當(dāng)服務(wù)器收到包含數(shù)據(jù)的SYN時(shí),假定TAO測試失敗或報(bào)文段中不包含CC選項(xiàng),那么tcp_input就將數(shù)據(jù)存入緩存隊(duì)列,等待三次握手過程的完成。在圖11-6中,協(xié)議的狀態(tài)設(shè)置為SYN_RCVD,程序有一個(gè)分支trimthenstep6,在標(biāo)號(hào)為dodata的程序行(卷2第790頁),宏TCP_REASS發(fā)現(xiàn)協(xié)議狀態(tài)不是ESTABLISHED,因此調(diào)用tcp_reass將報(bào)文段存入該連接的失序報(bào)文隊(duì)列(其中的數(shù)據(jù)并非真的失序;只是因?yàn)樗窃谌挝帐诌^程完成之前到達(dá)的。然而,卷2的圖27-19底部的兩個(gè)統(tǒng)計(jì)計(jì)數(shù)器tcps_rcvoopack和tcps_rcvoobyte的累進(jìn)是不正確的)。1590158115S215?3158415851590158115S215?31584158515S61

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論