




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第29 TCP的輸入(續(xù)本章從前一章結(jié)束的地方開始,繼續(xù)介紹TCP輸入處理。回想一下圖28-37中最后的測試本章處理ACK標(biāo)志,更新窗口信息,處理URG標(biāo)志及報(bào)文段中攜帶的所有數(shù)據(jù),最后處在本章中,首先ACK的處理,圖29-1給出了ACK處理的框架。SYN_RCVD狀態(tài)需要特殊處理,緊跟著是其他狀態(tài)的通用處理代碼(前一章已過在LISTEN和SYN_SENT狀態(tài)下收到ACK時(shí)的處理邏輯)TCPS_FIN_AIT_1、TCPS_CLOSING和TCPS_LAST_ACKACK會(huì)導(dǎo)致狀態(tài)的轉(zhuǎn)移。此外,在TIME_AIT狀態(tài)下收到ACK還會(huì)導(dǎo)致2MSL定時(shí)器的重啟。圖29-1ACK圖29-1(續(xù)圖29-2給出了如何處理SYN_RCVD狀態(tài)下收到的ACK報(bào)文段。如前一章中提到過的,這也將完成打開(一般情況),或者是同時(shí)打開及自連接(特殊情況)的連接建立過程。驗(yàn)證收到的801-806Na(將snd_una設(shè)定為連接的ISS,SYN報(bào)文段的序號),且小于等于snd_max。如果條件滿足,則插口進(jìn)入連接狀態(tài)ESABLISHED。在收到三次握手的最后一個(gè)報(bào)文段后,調(diào)用soisconnected喚醒打開的應(yīng)用進(jìn)程一般為服務(wù)器)。如果服務(wù)器在調(diào)用accept上阻塞,則該調(diào)用現(xiàn)在返回。如果服務(wù)器調(diào)用807-812如果TCP曾發(fā)送窗口大小選項(xiàng),并且收到了對方的窗口大小選項(xiàng),則在TCP控制塊中保存發(fā)送縮放因子和接收縮放因子。另外,TCP控制塊中的snd_scale和rcv_scale的默認(rèn)值為0無縮放)。813現(xiàn)在可以向應(yīng)用進(jìn)程提交連接重組隊(duì)列中的數(shù)據(jù),調(diào)用tcp_reass,第二個(gè)參數(shù)為空。重組隊(duì)列中的數(shù)據(jù)可能是SYN報(bào)文段中攜帶的,它同時(shí)將連接狀態(tài)變遷為SYN_RCVD。81 snd_wl1等于收到的序號減1,從圖29-15可知,這樣將導(dǎo)致更新3圖29-3給出了ACK處理的下一部分代碼,處理重復(fù)ACK,并決定是否起用TCP的快速重傳和快速恢復(fù)算法[Jacobson1990c][Floyd1994]??焖僦貍魉惴ㄓ糜谶B續(xù)出現(xiàn)幾次(一般為3次)重復(fù)ACK時(shí),TCP認(rèn)為某個(gè)報(bào)文段已丟失并且從中推斷出丟失報(bào)文段的起始序號,丟失報(bào)文段被重傳。RFC1122中的1節(jié)提到了這一算法,建議TCP收到亂序報(bào)文段后,立即發(fā)送ACK??吹?,在圖27-15中,Net/3正是這樣做的。這個(gè)算法最早出現(xiàn)在4.3BSDTahoe版及后續(xù)的Net/1實(shí)現(xiàn)中,(即丟失報(bào)文段已重傳),應(yīng)執(zhí)行擁塞避免算法,而非慢起動(dòng)。這樣,如果擁塞不嚴(yán)重,還能保證較大的吞吐量,尤其窗口較大時(shí)。這個(gè)算法最早出現(xiàn)在4.3BSDReno版和后續(xù)的Net/2實(shí)現(xiàn)中。在圖24-17節(jié)中,提到有效的ACK必須滿足下面的不等式:snd_una確認(rèn)字段第一步只與snd_una29-5中再進(jìn)行不等式第二部分的比較。分開比較的原因是為了能對收到的ACK完成下列5項(xiàng)測試:如果確認(rèn)字段小于等于snd_una;并接收報(bào)文段長度為0;并窗口通告大小未變連接上部分發(fā)送數(shù)據(jù)未被確認(rèn)(重傳定時(shí)器非零);并接收報(bào)文段的確認(rèn)字段是TCP收到的最大的確認(rèn)序號(確認(rèn)字段等于snd_una)之后可確認(rèn)報(bào)文段是完全重復(fù)的ACK(測試項(xiàng)1、2和3在圖29-3中,測試4和5在圖29-4的起始TCP統(tǒng)計(jì)連續(xù)收到的重復(fù)ACK的個(gè)數(shù),保存在變量t_dupacks中,次數(shù)超過門限(tcprexmtthresh,3)時(shí),丟失報(bào)文段被重傳。這也就是卷1第21.7節(jié)中介紹的快速重傳算法。它與圖27-15中的代碼互相配合:當(dāng)TCP收到亂序報(bào)文段時(shí),立即生成一個(gè)重復(fù)的ACK,告訴對端報(bào)文段有可能丟失和等待接收的下一個(gè)序號值??焖僦貍魉惴ㄊ菫榱俗孴CP立即重傳看上去已經(jīng)丟失的報(bào)文段,而不是地等待重傳定時(shí)器超時(shí)。卷1第21.7節(jié)舉例詳細(xì)說明了圖29-3tcp_input函數(shù):判定完全重復(fù)的ACK了一個(gè)亂序報(bào)文段,從而開始發(fā)送重復(fù)的ACK??焖倩謴?fù)算法要求連續(xù)收到幾個(gè)重復(fù)ACK后,TCP應(yīng)該執(zhí)行擁塞避免算法(如降低速度),而不一定必需等待連接兩端間的管道清空(慢起動(dòng))。“離開了網(wǎng)絡(luò)”指數(shù)據(jù)分組已被對端接收,并加入到連接的重組隊(duì)列中,不再滯留在傳輸途如果前述5項(xiàng)測試條件只有前3項(xiàng)為真,說明ACK是重復(fù)報(bào)文段,統(tǒng)計(jì)值ck加1,而連續(xù)重復(fù)ACK計(jì)數(shù)器(t_dupacks)復(fù)位為0。如果僅有第一項(xiàng)測試條件為真,則計(jì)數(shù)器t_dupacks復(fù)位為0。圖29-4給出了快速重傳算法其余的代碼,當(dāng)所有5個(gè)測試條件全部滿足時(shí),根據(jù)已連續(xù)收t_dupacks等于3(tcprexmtthresh),則執(zhí)行擁塞避免算法,并重傳丟失報(bào)文t_dupacks大于3,則增大擁塞窗口,執(zhí)行正常的TCP輸出t_dupacks小于3,不做圖29-4tcp_input函數(shù):處理重復(fù)的連續(xù)收到的重復(fù)ACK次數(shù)己達(dá)到門限值861-868t_dupacks等于3(tcprexmtthresh)時(shí),在變量onxt中保存snd_nxt值,令慢起動(dòng)門限(ssthresh)等于當(dāng)前擁塞窗口大小的一半,最小值為兩個(gè)最大報(bào)文段長度。這與圖25-27中重傳定時(shí)器超時(shí)處理中的慢起動(dòng)門限設(shè)定操作類似,但看到,超時(shí)處理中把擁塞窗口設(shè)定為一個(gè)最大報(bào)文段長度,快速重傳算法并不這樣做。869870關(guān)閉重傳定時(shí)器。為防止TCPt_rtt871873從連續(xù)收到的重復(fù)ACK報(bào)文段中可判斷出丟失報(bào)文段的起始序號(重復(fù)ACK的確認(rèn)發(fā)送丟失報(bào)文段(參見卷1的圖21-7中的63號報(bào)文段)。874-875擁塞窗口等于慢起動(dòng)門限加上對端高速緩存的報(bào)文段數(shù)?!案咚倬彺妗敝笇Χ艘咽盏降膩y序報(bào)文段數(shù),且為這些報(bào)文段發(fā)送了重復(fù)的ACK。除非對端收到了丟失的報(bào)文段(剛剛發(fā)送),這些緩存報(bào)文段中的數(shù)據(jù)不會(huì)被提交給應(yīng)用進(jìn)程。卷1的圖21-10和圖21-11給出了快速設(shè)定876-878比較下一發(fā)送序號(snd_nxt)的先前值(onxt)和當(dāng)前值,將兩者中最大的一個(gè)重新賦還給snd_nxt,因?yàn)橹貍鲌?bào)文段時(shí),tcp_output會(huì)改變snd_nxt。一般情況下,snd_nxt將等于原來保存的值,意味著只有丟失報(bào)文段被重傳,下一次調(diào)用tcp_output時(shí),連續(xù)收到的重復(fù)ACK數(shù)超過門限879-883 因?yàn)閠_dupacks等于3時(shí),已重傳了丟失的報(bào)文段,再次收到重復(fù)ACK說明又有另一個(gè)報(bào)文段離開了網(wǎng)絡(luò)。擁塞窗口大小加1,調(diào)用tcp_output發(fā)送序列中的下一報(bào)文段,884885ACK,且長度非零或者通告窗口大小發(fā)生變化,則執(zhí)行這些語句。此時(shí),前面提到的5個(gè)測試條件中只有第一個(gè)為真,連續(xù)收到的重復(fù)ACK數(shù)被略過ACK處理的其余部886 break語句在下列3(1)前述5(2)只有前3個(gè)條件為真;(3)重復(fù)ACK次數(shù)小于門限值3。任何一種情況下,盡管收到的是重復(fù)ACK,將執(zhí)行break語句,控制跳到圖29-2中switch語句的結(jié)尾處,在標(biāo)注step6處繼續(xù)8而本地報(bào)文段1~8已發(fā)送。報(bào)文段1丟失,其余報(bào)文段均正常到達(dá)且被確認(rèn)。收到對報(bào)文段2、3和4的確認(rèn)后,重傳丟失的報(bào)文段(15~8TCP夠發(fā)送報(bào)文段9,以高的吞率但窗口小于8,送報(bào)文段9及其后續(xù)報(bào)文段。因此,每當(dāng)再次收到一個(gè)重復(fù)的ACK,就暫時(shí)把擁塞窗口加1,因?yàn)槭盏街貜?fù)的ACK告訴TCP1的確認(rèn)后,下面將介紹的代碼會(huì)減少擁塞窗口大小,令其等于慢起動(dòng)門限。卷1的圖21-10舉例說明了這一過程,重復(fù)ACK到達(dá)時(shí),增加擁塞窗口大小,之后收到新的ACK時(shí),再相應(yīng)地減少擁塞窗口。圖29-5中的代碼繼續(xù)處理ACK888-895如果連續(xù)收到的重復(fù)ACK數(shù)超過了門限值3,說明這是在收到了4個(gè)或4個(gè)以上的重復(fù)ACK后,收到的第一個(gè)非重復(fù)的ACK??焖僦貍魉惴ńY(jié)束。因?yàn)閺氖盏降牡?個(gè)重復(fù)ACK開始,每收到一個(gè)重復(fù)ACK就會(huì)導(dǎo)致?lián)砣翱诩?,如果它已超過了慢起動(dòng)門限,令其檢查ACK的有效896899前面介紹過,有效的ACKsnd_una確認(rèn)字段<=如果確認(rèn)字段大于snd_max,可對端正在確認(rèn)了TCP尚未發(fā)送的數(shù)據(jù)??赡艿脑蚴牵瑢τ诟咚龠B接,某個(gè)的ACK再次出現(xiàn)時(shí),序號已回繞,從圖24-5可知,這是極為罕見的900902經(jīng)過前面的測試,已知這是一個(gè)有效的ACK。acked等于確認(rèn)的字節(jié)數(shù)。903-915如果(1)時(shí)間戳選項(xiàng)存在;或者(2)TCP對某個(gè)報(bào)文段計(jì)時(shí),且收到的確認(rèn)字段大于該報(bào)文段的起始序號,則調(diào)用tcp_xmit_timer更新RTT測算值。注意,使用時(shí)間戳?xí)r,tcp_xmit_timer的第二個(gè)參數(shù)等于當(dāng)前時(shí)間(tcp_now)減去收到的時(shí)間戳回顯(ts_ecr)由于延遲ACK的存在,面的測試不等式中應(yīng)采用大于號。例如,假定TCP發(fā)送了一1~10241025~2048。如果收到的確認(rèn)字段等于2049,因?yàn)?049大于1(計(jì)文段的起始序號),TCP將更新TT測算值。916-924如果收到報(bào)文段的確認(rèn)字段(ti_ack)等于TCP的最大發(fā)送序號(snd_max),說明所有已發(fā)送數(shù)據(jù)都已被確認(rèn)。關(guān)閉重傳定時(shí)器,并置位needoutput標(biāo)志,從而在函數(shù)結(jié)束時(shí)強(qiáng)迫調(diào)用tcp_output。這是因?yàn)樵诖酥?,有可能因?yàn)榘l(fā)送窗口已滿,TCP了等待發(fā)送的數(shù)據(jù),而現(xiàn)在收到了新的ACK,確認(rèn)了全部已發(fā)送數(shù)據(jù),發(fā)送窗口能夠向右移動(dòng)(圖29-8中的snd_una被更新),允許發(fā)送的數(shù)據(jù)。925-926 注意,時(shí)間戳的運(yùn)用取消了Karn算法的部分規(guī)定(卷1的21.3節(jié)):如果重傳定時(shí)器超時(shí),則報(bào)文段被重傳,收到對重傳報(bào)文段的確認(rèn)時(shí),不應(yīng)據(jù)此更新TT測算值(重傳確認(rèn)的二義性問題)。在圖25-26中,看到當(dāng)發(fā)生重傳時(shí),遵從Karn,t_rtt被設(shè)為0。如果時(shí)間戳不存在,且收到的是對重傳報(bào)文段的確認(rèn),則圖29-中的代碼不會(huì)更新TT測算值,因?yàn)榇藭r(shí)t_rtt等于0。但如果時(shí)間戳存在,則不查看t_rtt值,允許利用收到的時(shí)間戳回顯字段更新TT測算值。根據(jù)RFC1323,時(shí)間戳的運(yùn)用不存在二義性,因?yàn)閠s_ecr的值自被確認(rèn)的報(bào)文段。Karn算法中關(guān)于重傳報(bào)文段時(shí)應(yīng)采用指數(shù)退避的策略依舊有效。圖29-7給出了ACK處理的下一部分代碼,更新?lián)砣皥D29-7tcp_input函數(shù):響應(yīng)收到的ACK
圖29-7續(xù)927-94 慢起動(dòng)和擁塞避免的一條原則是收到ACK到一個(gè)ACK(慢起動(dòng)),擁塞窗口將加1。但如果當(dāng)前擁塞窗口大于慢起動(dòng)門限,增加值等于incr*incr/t_maxseg*t_maxseg/即1除以擁塞窗口,因?yàn)閟nd_cwnd的單位為字節(jié),而非報(bào)文段。表達(dá)式的常量部分等于最大報(bào)文段長度的1/8。此外,擁塞窗口的上限等于連接發(fā)送窗口的最大值。算法的舉例參見卷的21.8添加一個(gè)常量最大報(bào)文段長度的1/8)是錯(cuò)誤的[Floyd1994]BSD源碼中,從4.3BSD到4.4BSD和Net/3圖29-8給出了tcp_input下一部分的代碼,從發(fā)送緩存中刪除已確認(rèn)的數(shù)94394 如果確認(rèn)字節(jié)數(shù)超過發(fā)送緩存中的字節(jié)數(shù),則從snd_wnd節(jié)數(shù),并且可知本地發(fā)送的FIN已被確認(rèn)。調(diào)用sbdrop從發(fā)送緩存中刪除所有字節(jié)。能夠以這種方式檢查對FIN報(bào)文段的確認(rèn),是因?yàn)镕IN在序號空間中只占一個(gè)字節(jié)。947-951如果確認(rèn)字節(jié)數(shù)小于或等于發(fā)送緩存中的字節(jié)數(shù),ourfinisacked等于0,并從951-956調(diào)用sowwakeup喚醒所有等待發(fā)送緩存的應(yīng)用進(jìn)程,更新snd_una保存最老的未被確認(rèn)的序號。如果snd_una的新值超過了snd_nxt,則更新后者,因?yàn)檫@說明中間的數(shù)據(jù)也被確認(rèn)。圖29-9舉例說明了為什么snd_nxt保存的序號有可能小于snd_una。假定傳輸了兩個(gè)報(bào)文段,第一個(gè)攜帶字節(jié)1~512,而第二個(gè)攜帶字節(jié)513~1024。一一個(gè)報(bào)一個(gè)報(bào)圖29-9確認(rèn)返回前,重傳定時(shí)器超時(shí)。圖25-26中的代碼將snd_nxt設(shè)定為snd_una,進(jìn)入慢起動(dòng)狀態(tài),調(diào)用tcp_output重傳攜帶1~512字節(jié)的報(bào)文段。tcp_output將snd_nxt增加為513,如圖29-10所示。 報(bào)文段重 圖29-10重傳定時(shí)器超時(shí)后的連接(接圖29-此時(shí),確認(rèn)字段等于1025的ACK到達(dá)(或者是最初發(fā)送的兩個(gè)報(bào)文段或者是ACK在網(wǎng)絡(luò)中被延遲)。這個(gè)ACK是有效的,因?yàn)樗∮诘扔趕nd_max,但它也將小于更新后的snd_una值。一般性的ACK處理現(xiàn)在已結(jié)束,圖29-11中的switch語句接著處理了4種特殊情況圖29-11tcp_input函數(shù):在FIN_WAIT_1狀態(tài)時(shí)收到了在FIN_WAIT_1狀態(tài)時(shí)收到了
圖29-11(續(xù)958-971TCP已發(fā)送了FIN,但還有可能收到對在FIN之前發(fā)送的報(bào)文段的確認(rèn)。因此,只有在收到FIN的確認(rèn)后,連接才會(huì)轉(zhuǎn)移到FIN_AIT_2圖29-8ourfinisacked標(biāo)志已置位,這取決于確認(rèn)的字節(jié)數(shù)是否超過發(fā)送緩存中的數(shù)據(jù)量。設(shè)定FIN_WAIT_2定時(shí)972-975在256節(jié)中介紹了Net3如何設(shè)定FINAI_定時(shí)器,以防止在INWAI_2狀態(tài)無限等待。只有當(dāng)應(yīng)用進(jìn)程完全關(guān)閉了連接(如號量終止時(shí)與類似的內(nèi)核調(diào)用),而不是半關(guān)閉時(shí)(如已發(fā)送了FIN上接收數(shù)據(jù)圖29-12給出了在CLOSING狀態(tài)收到ACK時(shí)的處理代碼圖29-12tcp_input函數(shù):在CLOSING狀態(tài)收到在CLOSING狀態(tài)收到979-992如果收到的ACK是對FIN的確認(rèn)()MEAIT狀態(tài)。所有等待的定時(shí)器都被清除(如等待的重傳定時(shí)器),IMEAIT定時(shí)器被啟動(dòng),時(shí)限等于兩倍的MS。圖29-13給出了在LAST_ACK狀態(tài)收到ACK的處理代碼圖29-13tcp_input函數(shù):在LAST_ACK狀態(tài)收到在LAST_ACK狀態(tài)收到993-1004如果FIN已確認(rèn),連接將轉(zhuǎn)移到CLOSED狀態(tài)。tcp_close將負(fù)責(zé)這一狀態(tài)變遷,并同時(shí)InternetPCB和TCP控制塊。圖29-14給出了在TIME_WAIT狀態(tài)收到ACK的處理代在TIME_WAIT狀態(tài)收到1005-1014此時(shí),連接兩端都已發(fā)送過FIN,且兩個(gè)FIN都已被確認(rèn)。但如果TCP對遠(yuǎn)端FIN的確認(rèn)丟失,對端將重傳FIN帶有ACK。TCP丟棄報(bào)文段并重傳ACK。此外,TCP控制塊中還有兩個(gè)窗口變量未曾提及:snd_wl1和snd_wl2nd_wl1記錄最后接收報(bào)文段的序號,用于更新發(fā)送窗口(snd_wnd)snd_wl2記錄最后接收報(bào)文段的確認(rèn)序號,用于更新發(fā)送窗到目前為止,只在連接建立時(shí)(主動(dòng)打開、打開或同時(shí)打開)遇到過這兩個(gè)變量,snd_wl1被設(shè)定為ti_seq減1。當(dāng)時(shí)說是為了保證窗口更新,下面的代碼將證明這一如果下列3個(gè)條件中的任一個(gè)被滿足,則應(yīng)根據(jù)接收報(bào)文段中的通告窗口值(tiwin)更新發(fā)報(bào)文段攜帶了新數(shù)據(jù)。因?yàn)閟nd_wl1保存了用于更新窗口的最后接收報(bào)文段的起號,如果snd_wl1<ti_seq,說明此條件為報(bào)文段未攜帶新數(shù)據(jù)(snd_wl1等于ti_seq),但報(bào)文段確認(rèn)了新數(shù)據(jù)。因?yàn)閟nd_wl2<ti_ack報(bào)文段未攜帶新數(shù)據(jù),也未確認(rèn)新數(shù)據(jù),但通告窗口大于當(dāng)前發(fā)送這些測試條件的目的是為了防止舊的報(bào)文段影響發(fā)送窗口,因?yàn)榘l(fā)送窗口并非序號序列,而是從snd_una算起的偏移量。10151023if語句檢查報(bào)文段的ACK標(biāo)志是否置位,且前述3個(gè)條件中是否有一個(gè)被滿足。前面介紹過,在LISTEN狀態(tài)或SYN_SENT狀態(tài)收到SYN后,控制將跳轉(zhuǎn)到step6,而在注釋中的TAC指“終端接入控制器(terminalaccesscontroller)”,是ARPANET上 1024-1027如果收到一個(gè)純窗口更文段(長度為0,ACK未確認(rèn)新數(shù)據(jù),但通告窗口增1028-1033更新發(fā)送窗口,保存新的snd_wl1和snd_wl2值。此外,如果新的通告窗口是TCP從對端收到的所有窗口通告中的最大值,則新值被保存在max_sndwnd中。這是為了猜測對端接收緩存的大小,在圖26-8中用到了此變量。更新snd_wnd后,發(fā)送窗口可用空間增加,從而能夠發(fā)送新的報(bào)文段,因此,needoutput標(biāo)志置位。TCP輸入處理的下一部分是URG標(biāo)志置位時(shí)的報(bào)文段。如圖29-16所示是否需要處理URG1035-1039只有滿足下列條件的報(bào)文段才會(huì)被處理:URG標(biāo)志置位,緊急數(shù)據(jù)偏移量(ti_urp)非零,連接還未收到FIN。只有當(dāng)連接的狀態(tài)等于TIME_WAIT時(shí),宏TCPS_HAVERCVDFIN才會(huì)為真,因此,連接處于任何其他狀態(tài)時(shí),URG都會(huì)被處理。在后面的注釋中提到,連接處于CLOSE_WAIT、CLOSING、LAST_ACK和TIME_AIT等幾個(gè)狀態(tài)時(shí),URG標(biāo)志會(huì)被忽略,這種說法是錯(cuò)誤的。1040-1050如果緊急數(shù)據(jù)偏移量加上接收緩存中已有的數(shù)據(jù)超過了插口緩存可容納的數(shù)據(jù)量,則忽略緊急標(biāo)志。緊急數(shù)據(jù)偏移量被清零,URG標(biāo)志被清除,剩余的緊急方式處理邏輯圖29-17給出了tcp_input下一部分的代碼,處理緊急圖29-17(續(xù)1051-1065明已收到了一個(gè)新的緊急指針。例如,圖26-30中的攜帶3字節(jié)的報(bào)文段到達(dá)接收方,如圖29-接收報(bào)緊急數(shù)據(jù)偏移一般情況下,收到的緊急指針(rcv_up)等于rcv_nxt。這個(gè)例子中,因?yàn)閕f語句接收報(bào)緊急數(shù)據(jù)偏移1066-1070的分界點(diǎn),應(yīng)計(jì)入接收緩存中已有的數(shù)據(jù)(so_rcv.sb_cc)在面的例中假定接收緩存為空, 等2:序號為
圖29- 點(diǎn)上。如果發(fā)送帶外數(shù)據(jù)的d系統(tǒng)調(diào)用給定長度為1,并且這個(gè)報(bào)文段到達(dá)對端時(shí)接收緩存為空,就會(huì)發(fā)生這一現(xiàn)象,同時(shí)也再次重申了Bkeley系統(tǒng)認(rèn)為緊急指針應(yīng)指向帶外數(shù)據(jù)后的向應(yīng)用進(jìn)程通告TCP的緊1071-1072調(diào)用sohasoutofbandTCPOOB_HAVEDATA和TCPOOB_HADDATA,它們用于圖30-8中的PRU_RCVOOB請求處理1074-1085 如果緊急數(shù)據(jù)偏移量小于等于接收報(bào)文段中的字節(jié)數(shù),說明帶外數(shù)據(jù)包含在報(bào)文段中。TCP的緊急方式允許緊急數(shù)據(jù)偏移量指向尚未收到的數(shù)據(jù)。如果定義了SO_OOBINLINE常量(Net/3定義了此常量),而且未選用對應(yīng)的插口選項(xiàng),則接收進(jìn)程從常的數(shù)流提取帶數(shù),并保在t_iobc變量中。完成這能的函數(shù),是在下一節(jié)介紹的tcp_pulloutofband。注意,無論緊急指針指向的字節(jié)是否可讀,TCP都將通知接收進(jìn)程發(fā)送方已進(jìn)入緊急方式。1086-1093在接收處理緊急指針時(shí),如果rcv_nxt大于接收緊急指針,則rcv_up向右移動(dòng),并等于rcv_nxt。這使接收緊急指針一直指向接收窗口的左側(cè),確保在收到URG標(biāo)如果要實(shí)現(xiàn)習(xí)題26.6中方案,也必須相應(yīng)修改圖29-16和圖29-17中的接收報(bào)文段中帶有緊急方式標(biāo)志帶外數(shù)據(jù)包含在接收報(bào)文段中(如,緊急指針指向接收報(bào)文段);并未選用SO_OOBINLINE選項(xiàng)函數(shù)從正常的數(shù)據(jù)流(保存接收報(bào)文段的mbuf鏈中提取帶外字節(jié),并保存在連接TCP控制塊中的t_iobc變量中。應(yīng)用進(jìn)程通過recv系統(tǒng)調(diào)用,置位MSG_OOB標(biāo)志,這個(gè)變量圖30-8中的PRU_RCVOOB請求。圖29-19給出了函數(shù)代碼。圖29-19(續(xù)12821289考慮圖29-203,因此緊急指針等于7,帶外字節(jié)變量cnt等于2,因?yàn)閙_len(等于5)大于2,執(zhí)行if語句為真部分的代12901298cp指向序號6的字節(jié),它被放入保存帶外字節(jié)的變量t_iobc中。置位TCPOOB_HAVEDATA標(biāo)志,調(diào)用bcopy將接下來的兩個(gè)字節(jié)(序號7和8)左移1字節(jié),如圖29-接收接收報(bào)緊急數(shù)據(jù)偏移圖29- 圖29- 移走帶外數(shù)據(jù)后的結(jié)果(接圖29-注意,數(shù)字7和8指數(shù)據(jù)字節(jié)的序號,而不是其內(nèi)容。mbuf的長度從5減為4但ti_len仍等于5不變,這是為了按序把報(bào)文段放入插口的接收緩存。TCP_REASS宏和tcp_reass函數(shù)(在下一節(jié)調(diào)用)會(huì)給rcv_nxt增加ti_len,本例中ti_len必須等于5,因?yàn)橄乱粋€(gè)等待接收的序號等于9。還請注意,函數(shù)沒有對第一個(gè) mbuf中的數(shù)據(jù)分組首部長度(m_pkthdr.len)減1,這是因?yàn)樨?fù)責(zé)把數(shù)據(jù)添加到插口接收緩存的sbappend不使用此長度值。跳至鏈中的下一個(gè)1299-1302如果帶外數(shù)據(jù)未保存在此mbuf中,則從cnt中減去mbuf中的字節(jié)數(shù),處理鏈中的下一個(gè)mbuf。因?yàn)橹挥挟?dāng)緊急數(shù)據(jù)移量指向接收報(bào)文段時(shí),才會(huì)調(diào)用此函數(shù),所以,如果鏈已結(jié)束,不存在下一個(gè)mbuf,則執(zhí)行break語句,跳轉(zhuǎn)到標(biāo)注panic處。tcp_input接著提取收到的數(shù)據(jù)(如果存在),將其添加到插口接收緩存,或者放入插口的亂序重組隊(duì)列中。圖29-22給出了完成此項(xiàng)功能的代碼。10941105接收數(shù)據(jù)的長度大于0,或者FIN標(biāo)志置位;并連接還未收到則調(diào)用宏TCP_REASS處理數(shù)據(jù)。如果數(shù)據(jù)次序正確(如,連接等待接收的下一序號),置位延遲ACK標(biāo)志,增加rcv_nxt,并把數(shù)據(jù)添加到插口的接收緩存中。如果數(shù)據(jù)次序錯(cuò)誤,宏會(huì)調(diào)用tcp_reass函數(shù),把數(shù)據(jù)加入到連接的重組隊(duì)列中(新到數(shù)據(jù)有可能填充隊(duì)列中的缺口,從而將已排隊(duì)的數(shù)據(jù)添加到插口的接收緩存中)。前面介紹過,宏的最后一個(gè)參數(shù)(tiflags)是可修改的。特別地,如果數(shù)據(jù)次序錯(cuò)誤,tcp_reass令tiflags等于0,清除FIN標(biāo)志(如果它已置位)。這也就是為什么即使報(bào)文段中沒有數(shù)據(jù),只要FIN置位,if語句也為真??紤]下面的例子。連接建立后,發(fā)送方立即發(fā)送報(bào)文段:一個(gè)攜帶字節(jié)1~1024,另一個(gè)攜帶字節(jié)1025~2048,還有一個(gè)未帶數(shù)據(jù)的FIN。第一個(gè)報(bào)文段丟失,因此,第二個(gè)報(bào)文段到達(dá)時(shí)(字節(jié)1025~2048)ACK。當(dāng)?shù)谌齻€(gè)帶有FIN29-220,因?yàn)镕IN置位,導(dǎo)致調(diào)用TCP_REASS,它接著調(diào)用tcp_reass。因?yàn)閠i_seq(2049,F(xiàn)IN的序號)不等于rcv_nxt(1),tcp_reass返回0(圖27-23)。在TCP_REASStiflags被設(shè)為0,從而清除了FIN標(biāo)志,后續(xù)代碼(圖29-10)繼續(xù)處理FIN。1106-1111計(jì)算len,實(shí)際上是在猜測對端發(fā)送緩存的大小??紤]下面的例子。插口接收緩存大小等于8192(Net/3的默認(rèn)值)TCP在SYN8192。之后收到第一個(gè)報(bào)文段,攜帶字節(jié)1~1024。圖29-23給出了在TCP_REASS增加rcv_nxt以反應(yīng)收到的數(shù)據(jù)后接收空間的狀態(tài)。圖29-23大小為8192的接收窗口收到字節(jié)1~1024此時(shí),經(jīng)計(jì)算,len等于1024。對端向接收窗口發(fā)送數(shù)據(jù)后,len值將增加,但絕不會(huì)超過對端發(fā)送緩存的大小。前面介紹過,圖29-15中對變量max_sndwnd的計(jì)算,是在猜測事實(shí)上,變量len從未被使用。它是從Net/1遺留下來的,len計(jì)算后被TCP控制塊的max_rcvd變量中if(len>tp->max_rcvd)tp->max_rcvd=len;但即使在Net/1中,變量max_rcvd也未被使用1112-1115如果len等于0,且FIN標(biāo)志未置位,或者連接上已收到了FIN,則丟棄保存接tcp_input的下一步,在圖29-24中給出,處理FIN標(biāo)志處理收到的第一個(gè)1116-112 如果接收報(bào)文段FIN置位,并且是連接上收到的第一 FIN,則調(diào)socantrcvmore,把插口設(shè)為只讀,置位TF_ACKNOW,從而立即發(fā)送ACK()rcv_nxt加1,越過FIN占用的序號1126FIN處理的其余部分是一個(gè)大的switch語句,根據(jù)連接的狀態(tài)進(jìn)行轉(zhuǎn)換。注意,連接處于CLOSE、LISTEN和SYN_SENT狀態(tài)時(shí),不處理FIN,因?yàn)樘幱谶@3個(gè)狀態(tài)時(shí),還未收到對端發(fā)送的SYN,無法同步接收序號,也就無法驗(yàn)證FIN序號的有效性。此外,連接處于CLOSING、CLOSE_WAIT和LAST_ACK狀態(tài)時(shí),也不處理FIN,因?yàn)樵谶@3個(gè)狀態(tài)下收到的FIN必然是一個(gè)重復(fù)報(bào)文段。SYN_RCVD和ESTABLISHED1127-1134如果連接處于SYN_RCVD或ESTABLISHED狀態(tài),收到FIN盡管在SYN_RCVD狀態(tài)下收到FIN是合法的,但卻極為罕見。圖24-15的狀態(tài)圖未列出這一狀態(tài)變遷。它意味著處于LISTEN狀態(tài)的插口收到一個(gè)同時(shí)帶有SYN和FIN的報(bào)文段?;蛘?,正在的插口收到了SYN,連接轉(zhuǎn)移到SYN_RCVD狀態(tài),但在收到ACK之前,先收到了FIN(FIN未攜帶有效的ACK,否則,圖29-2中的代碼會(huì)使連接轉(zhuǎn)移到ESABLISHED狀態(tài))。圖29-25給出了FIN處理的下一部FIN_WAIT_11135-1141因?yàn)閳?bào)文段的ACK處理已結(jié)束,如果處理FIN時(shí),連接處于FIN_WAIT_1狀態(tài),意味著連接兩端同時(shí)關(guān)閉連接—兩端發(fā)送的兩個(gè)FIN在網(wǎng)絡(luò)錯(cuò)。連接進(jìn)入CLOSING狀態(tài)FIN_WAIT_21142-1148 收到FIN將使連接進(jìn)入TIME_AIT狀態(tài)。當(dāng)在FIN_AIT_1狀態(tài)收到攜帶ACK和FIN的報(bào)文段時(shí)(典型情況),盡管圖24-15顯示連接直接從FIN_WAIT_1轉(zhuǎn)移到TIME_AIT狀態(tài),但在圖29-1中處理ACK時(shí),連接實(shí)際已進(jìn)入FIN_AIT_2狀態(tài)。此處的FIN處理再將連接轉(zhuǎn)到TIME_AIT狀態(tài)。因?yàn)锳CK在FIN之前處理,所以連接總會(huì)經(jīng)過FIN_AIT_2盡管是暫時(shí)性的。啟動(dòng)TIME_WAIT定時(shí)1149-1152 關(guān)閉所有等待的TCP定時(shí)器,并啟動(dòng)TIME_AIT定時(shí)器,時(shí)限等于MSL(接收報(bào)文段中包含ACK和FIN,圖29-1中的代碼會(huì)啟動(dòng)FIN_AIT_2定時(shí)器)TIME_WAIT1153-1159如果在TIME_WAIT狀態(tài)時(shí)收到FIN,說明這是一個(gè)重復(fù)報(bào)文段。與圖29-14中圖29-26給出了tcp_input函數(shù)中首部失敗時(shí),較慢的執(zhí)行路徑中最后一部分的代碼,以及標(biāo)注dropafterack。SO_DEBUG插口選
1161-1162如果選用了SO_DEBUG插口選項(xiàng),則調(diào)用tcp_trace向內(nèi)核的環(huán)形緩存中添加記錄。回想一下,圖28-7中的代碼同時(shí)保存了原有連接狀態(tài),IP和TCP的首部,因?yàn)楹瘮?shù)有調(diào)用1163-1168如果needoutput標(biāo)志置位(圖29-6和圖29-15),或者需要立即發(fā)送ACK,則調(diào)1169-1179只有當(dāng)RST標(biāo)志未置位時(shí),才會(huì)生成ACK(帶有RST的報(bào)文段不會(huì)被確認(rèn)),釋圖29-27結(jié)束tcp_input函數(shù)
11801188除了接收報(bào)文段也有RST此處的代碼存在與圖28-16同樣的錯(cuò)誤:它查接收報(bào)文段的目的地址是否為類似地 IN_MULTICAST的目的地址參數(shù)應(yīng)轉(zhuǎn)換為主機(jī)字節(jié)序11891196RST報(bào)文段的序號字段值、確認(rèn)字段值和ACK標(biāo)志取決于接收報(bào)文段中是否帶圖29-28總結(jié)了生成RST報(bào)文段中的這些字段接收到的報(bào)文生成的RST序號不帶接收到的確認(rèn)字00接收到的序號字圖29- 生成RST報(bào)文段各字段的正常情況下,除了起始的SYN(圖24-16),所有報(bào)文段都帶有ACK。tcp_respond的第1192-1193 如果SYN置位,則ti_len必須加1,從而生成RST的確認(rèn)字段比收到的SYN報(bào)1。如果到達(dá)的SYN請求與不存在的服務(wù)器建立連接,會(huì)執(zhí)行這一段代碼。此時(shí),由于圖28-6中的代碼找不到請求的InternetPCB,控制跳轉(zhuǎn)到dropwithreset。但為了使發(fā)送的RST能被對端接受,報(bào)文段必須確認(rèn)SYN(圖28-18)。卷1的18.14節(jié)舉例說明了這種類型的RST。最后請注意,tcp_respond利用保存接收報(bào)文段的第一個(gè)mbuf構(gòu)造RST,并且鏈上1197-1199如果在圖28-7中為的服務(wù)器創(chuàng)建了臨時(shí)的插口,但圖28-16中的代碼發(fā)現(xiàn)接收報(bào)文段有錯(cuò)誤,它會(huì)置位dropsocket。如果出現(xiàn)了這種情況,插口在此處被。丟棄(不帶ACK或1201-1206 如果接收報(bào)文段被丟棄,且不生成ACK或RST,則調(diào)用tcp_trace。如果SO_DEBUG置位且生成了ACK,則tcp_output將向內(nèi)核的環(huán)形緩存中添加一條記錄。如果SO_DEBUG置位且生成了RST,系統(tǒng)不會(huì)為RST添加新的記錄。1207-1211保存接收報(bào)文段的mbuf鏈。如果dropsocket非零,則臨時(shí)創(chuàng)建的插為了加速TCP處理而進(jìn)行的優(yōu)化與UDP類似(23.12節(jié))。應(yīng)利用數(shù)據(jù)計(jì)算檢驗(yàn)和,并避免在處理中多次遍歷數(shù)據(jù)。[Daltonetal.1993]了這些修訂。連接數(shù)增加時(shí),對TCPPCB的線性搜索也是一個(gè)處理瓶頸。[McKenneyandDove1992]討[Partridge1993]介紹了VanJacobson開發(fā)的一個(gè)用于研究目的的協(xié)議實(shí)現(xiàn),極大地減少了TCPIP進(jìn)行處理(RISC系統(tǒng)中約有25條指令),之后由分用器(demultiplexer)尋找PCB(約10條指令),最后由TCP處理(約30條指令)。這30條指令完成了首部,并計(jì)算偽首部檢驗(yàn)和。如果數(shù)據(jù)報(bào)文段通過了首部,且應(yīng)用進(jìn)程正等待接收數(shù)據(jù),則數(shù)據(jù)到應(yīng)用進(jìn)程緩存,計(jì)算TCP檢驗(yàn)和并完成驗(yàn)證(一次遍歷中完成數(shù)據(jù)和檢驗(yàn)和計(jì)算)。如果TCP首部失敗,則執(zhí)行TCP輸入處理中較慢的路徑。下面介紹TCP首部壓縮。盡管首部壓縮不是TCP輸入處理的一部分,但需要徹底了解的工作機(jī)制后,才能很好地理解首部壓縮。RFC1144[Jacobson1994a]中詳細(xì)定義了首部壓縮,因?yàn)閂anJacobson首先提出了這一算法,通常也稱為VJ首部壓縮。本節(jié)的目的不是詳細(xì)首部壓縮的源代碼(RFC1144給出了實(shí)現(xiàn)代碼,其中有很好的注釋,程序量與tcp_output差不多),而是概括性地介紹一下算法的思想。請注意區(qū)分首部(28.4節(jié))和首部壓縮。多數(shù)的SLIP和PPP實(shí)現(xiàn)支持首部壓縮。盡管首部壓縮,在理論上,適用于任何數(shù)據(jù)鏈路,但主要是向慢速行路。首壓只處理TCP報(bào)文段—與其他的IP協(xié)議無關(guān)(如ICM、IGMP、UDP等等)。它能夠把IP/TC組合首部從正常的40字節(jié)壓縮到只有3字節(jié),從而降低了交互性應(yīng)用,如登錄或 net中TCP報(bào)文段的大小,從典型的41字節(jié)減少到只剩4字節(jié)—大大提高了慢速串行鏈路的效串行鏈路的兩端,每端都著兩個(gè)連接狀態(tài)表,一個(gè)用于數(shù)據(jù)報(bào)的發(fā)送,另一個(gè)用于256條記錄,但典型的只有1616條不同的TCP8bit的連接ID(限制記錄數(shù)最多只能為256)、某些標(biāo)志和最近接收/96bit的插口對可惟一確定一條連接—源端IP地址和TCP端口、目的IP地址和TCP端口—這些信息都保存在未壓縮的首部中。圖29-29舉例說明了這些表的結(jié)構(gòu)。發(fā)送連接狀態(tài)標(biāo)號標(biāo) 最近的/P首接收連接狀態(tài)標(biāo)號標(biāo) 最近的IP/T首接收連接狀態(tài)標(biāo)號標(biāo) 最近的IP/T首發(fā)送連接狀態(tài)標(biāo)號標(biāo) 最近的IP/T發(fā)送連接狀態(tài)標(biāo)號標(biāo) 最近的/P首接收連接狀態(tài)標(biāo)號標(biāo) 最近的IP/T首接收連接狀態(tài)標(biāo)號標(biāo) 最近的IP/T首發(fā)送連接狀態(tài)標(biāo)號標(biāo) 最近的IP/T首圖29- 鏈路(如SLIP鏈路)兩端的一組連接狀態(tài)在圖29-29中利用數(shù)組表示這些表,但在源代碼中,表項(xiàng)定義為一個(gè)結(jié)構(gòu),連接狀態(tài)表定義為這些結(jié)構(gòu)組成的環(huán)形鏈表,最近一次用過的結(jié)構(gòu)位于表頭。因?yàn)檫B接兩端都保存了最近用過的未壓縮的數(shù)據(jù)報(bào)首部,所以只需在鏈傳送當(dāng)前數(shù)據(jù)報(bào)與前一數(shù)據(jù)報(bào)不同的字段及一個(gè)特殊的前導(dǎo)字節(jié),指明后續(xù)的是哪一個(gè)字段)。因?yàn)槟承┦撞孔侄卧谙噜彽臄?shù)據(jù)報(bào)之間不會(huì)變化,而其他的首部字段變化也很小,這種差分處理是壓縮算法的。首部壓縮只適用于IP和TCP首部—TCP報(bào)文段的數(shù)據(jù)部分不圖29-30給出了發(fā)送方利用首部壓縮算法,在串行鏈發(fā)送IP數(shù)據(jù)報(bào)時(shí)采取的步驟待待發(fā)送的數(shù)據(jù)非TCP報(bào)文壓縮的TCPIP其 找COMPRESSED_TCP無 壓未找PRESSED_TCP壓配的96-bit插口檢查數(shù)圖29- IP型數(shù)據(jù)報(bào),前導(dǎo)字節(jié)的4比特等于4。這也是IP首部中正常的IP版本號(圖8-8),COMPRESSED_TCP型數(shù)據(jù)報(bào),前導(dǎo)字節(jié)的最置為1,類似于IP版本號介于8和15之間(剩余的7bit由壓縮算法使用),說明鏈發(fā)送的是壓縮過的首部和未壓縮的數(shù)據(jù),接下來PRESSED_TCP型數(shù)據(jù)報(bào),前導(dǎo)字節(jié)的4比特等于7,說明鏈發(fā)送的是正常的、未壓縮的數(shù)據(jù)報(bào),但I(xiàn)P的協(xié)議字段(等于6,對TCP)被替換為連接ID,接收方可據(jù)此看數(shù)個(gè)導(dǎo)其代圖5-13。圖5-16中,發(fā)送方調(diào)用 press_tcp確認(rèn)TCP報(bào)文段是可壓縮的,函數(shù)返回值與數(shù)據(jù)報(bào)首字節(jié)邏輯或后,結(jié)果依然保存在首字節(jié)中。圖29-31列出了鏈傳送的前導(dǎo)字節(jié),其中4位“-”表示正常的IP首部長度字段。7位“C、I、P、S、A、W和E”指明后續(xù)的是哪些可選字段,后面會(huì)簡單地介紹這些字母的含 4bit4bit圖29- 圖29-32給出了使用壓縮算法之后,不同類型的完整的IPIPIP數(shù)據(jù)報(bào)的頭協(xié)議 0-65515字節(jié)的IP數(shù) 20-60字節(jié)的IP協(xié)議=TCP 20-60字節(jié)的TCP首 0-65495字節(jié)的TCP數(shù)20-60字節(jié)的IP 20-60字節(jié)的TCP首 0-65495字節(jié)的TCP數(shù) 0-65495字節(jié)的TCP 3-16字 協(xié)議=連接TCP非TCP圖29- 采用首部壓縮后的不同類型的IP數(shù)據(jù)圖中給出了兩個(gè)IP型數(shù)據(jù)報(bào):一個(gè)攜帶了非TCP報(bào)文段(如UDP、ICMP或IGMP段),另一個(gè)攜帶了TCP報(bào)文段。這是為了說明做為IP型數(shù)據(jù)報(bào)發(fā)送的TCP報(bào)文段與做為PRESSED_TCP型數(shù)據(jù)報(bào)發(fā)送的TCP報(bào)文段間的差異:前導(dǎo)字節(jié)的4比特互不相同,數(shù)據(jù)報(bào)是一個(gè)IP分片:分片偏移量非零或者分片標(biāo)志 、FIN或RST中的任何一個(gè)置ACK標(biāo)志未置位上述3個(gè)條件中只要有一個(gè)為真,都將作為IP型數(shù)據(jù)此外,即使數(shù)據(jù)報(bào)攜帶了可壓縮的TCP報(bào)文段,壓縮算法也可能失敗,生成PRESSED_TCP型的數(shù)據(jù)報(bào)??赡芤?yàn)楫?dāng)前數(shù)據(jù)報(bào)與連接上發(fā)送的上一個(gè)數(shù)據(jù)報(bào)比較時(shí),有些特殊字段發(fā)生了變化,而正常情況下,對于給定的連接,它們應(yīng)該不變,從而導(dǎo)致壓縮算法無法反映存在的變化。例如,TOS字段,分片標(biāo)志位。此外,如果某些字段數(shù)值的29-33中給出的IP和TCP的首部字段,陰影字段指對于給定連接,正常情況下不會(huì)發(fā)生變化的字段。4- 4-版本4- 4-版本 首部長8-服務(wù)類型16-bit總長(字節(jié)16-bit標(biāo)識3-標(biāo)13-bit8-bit存活時(shí)間(8-bit協(xié)16-bit32-bit源IP32-bit目的IP16-bit16-bit32-bit序32-bit4-bit首長保留(6UAPPSFRCSSYIGKHTN16-bit16-bitTCP檢驗(yàn)16-bit20字20字圖29- 組合的IP和TCP首部:陰影字段通常不變?nèi)绻B接上發(fā)送的前一個(gè)報(bào)文段與當(dāng)前報(bào)文段之間,有陰影字段發(fā)生變化,則壓縮算法失敗,報(bào)文段被直接發(fā)送。圖中未列出IP和TCP選項(xiàng),但如果它們存在,且這些選項(xiàng)字段發(fā)生了變化,則報(bào)文段也不壓縮,而被直接發(fā)送(習(xí)題29.7)。如果陰影字段均未變化,即使算法只傳輸非陰影字段,也會(huì)節(jié)省50%的傳輸容量。VJ首最小的壓縮后的IP/TCP首部只有3個(gè)字節(jié):第一個(gè)字節(jié)(標(biāo)志比特),加上16bit的TCP檢驗(yàn)和。為了防止可能的鏈路錯(cuò)誤,一般不改動(dòng)TCP檢驗(yàn)和(SLIP不提供鏈路層的檢驗(yàn)和,盡管 16-bitTCP如果U=1:TCP如果W=1:TCP窗口大小差值如果A=1:TCP確認(rèn)序號差值圖29-34壓縮后的IP/TCP其他的6個(gè)字段:connid、urgoff、win、ack、seq和ipid,都是可選的。圖29-34的最左側(cè)列出了各字段壓縮后所需的字節(jié)數(shù)。讀者可能認(rèn)為壓縮后的首部最大應(yīng)占用19字節(jié),但實(shí)際上壓縮后的首部中4bit的SAWU絕不可能同時(shí)置位,因此,壓縮首部最大為16字節(jié),后面第一個(gè)字節(jié)的最比特必須設(shè)為1,說明這是COMPRESSED_TCP型的數(shù)據(jù)報(bào)。其余7bit中的6個(gè)規(guī)定了后續(xù)首部中存在哪些可選字段,圖29-35小結(jié)了這7bit的用法。 標(biāo)志等于0說標(biāo)志等于1說連接連接ID不connid=連接ipid=IPPSHseq=TCP序號差ack=TCP確認(rèn)序號差值urgoff=緊急數(shù)據(jù)偏移IPip_id已加TCPPSH標(biāo)志清TCP序th_seq不TCPth_ack不TCP窗TCPth_win不URG標(biāo)志未置圖29-35壓縮首部中的7C如果C比特等于0,則當(dāng)前報(bào)文段與前一報(bào)文段(無論是壓縮的或非壓縮的)具有相同的 如果I比特等于0,當(dāng)前報(bào)文段的IP標(biāo)識符較前一報(bào)文1(典型情況)。如果等于ipid等于ip_id的當(dāng)前值減去它的前一P這個(gè)比特自TCP報(bào)文段中的PSH標(biāo)志位。因?yàn)镻SH標(biāo)志不同于其他的正常方式,S如果S比特等于0,TCP序號不變。如果等于1,seq等于th_seq的當(dāng)前值減去它的前一個(gè)值。A如果A比特等于0,TCP確認(rèn)序號不變(典型情況)。如果等于1,ack等于th_ack的當(dāng)前W如果W比特等于0,TCP窗口大小不變。如果等于1,win等于th_win的當(dāng)前值減去U如果U比特等于0,報(bào)文段的URG標(biāo)志未置位,緊急數(shù)據(jù)偏移量不變(典型情況)等于1URG標(biāo)志置位,urgoff等于th_urg的當(dāng)前值。如果URG標(biāo)志未置位時(shí),緊急數(shù)據(jù)偏移量發(fā)生改變,報(bào)文段將被直接發(fā)送(這種現(xiàn)象通常發(fā)生在緊急數(shù)據(jù)傳送完畢后的第一個(gè)報(bào)文段)。通過字段的當(dāng)前值減去它的前一個(gè)值,得到需傳輸?shù)牟钪怠UG闆r下,得到的是一個(gè)小正數(shù)(wi是個(gè)例外)。請注意,圖29-34中有5個(gè)字段的長度可變,可占用0、1或31字節(jié):發(fā)送值在1~255之間,只需占用13字節(jié):如果發(fā)送值等于0或者在26~6535之間,則需要用3個(gè)字節(jié)才能表示:第一個(gè)字節(jié)全0,后兩個(gè)字節(jié)保存實(shí)際值。這種方法一般用于3個(gè)16biturgoff、n和ipid。但如果兩個(gè)32bi字段ack和eq的差值小于0或者大于6553如果把圖93中不帶陰影的字段與圖94中可能的傳輸字段進(jìn)行比較,會(huì)發(fā)現(xiàn)有些字段IP總長度字段不會(huì)被傳輸,因?yàn)榻^大多數(shù)鏈路層向接收方提供接收數(shù)據(jù)分組的長因?yàn)镮P首部中被傳輸?shù)奈┮蛔侄问?6bit的IP標(biāo)識符,IP檢驗(yàn)和被忽略。因?yàn)樗辉谝凰惴z查輸入報(bào)文段,如果出現(xiàn)兩種特定情況,則用前導(dǎo)字節(jié)的低位4比特—的兩種特殊組合,分別加以表示。因?yàn)榫o急數(shù)據(jù)很少出現(xiàn),如果報(bào)文段中URG標(biāo)志置位,并且與前一報(bào)文段相比,序號與窗口字段都發(fā)生了變化(意味著低位4比特應(yīng)為1011或1111), 4比特等于1011(稱為*SA)或SA序號與確認(rèn)序號都增加,差值等于前一報(bào)文段的數(shù)據(jù)量,窗口大小與緊急數(shù)據(jù)偏移量不變,URG標(biāo)志未置位。采用這種表示法可以避免傳送seq和ack。如果對端回送終端數(shù)據(jù),那么兩個(gè)傳輸方向上的數(shù)據(jù)報(bào)文段中都會(huì)經(jīng)常出現(xiàn)這一現(xiàn)象。卷1的圖19-3和圖19-4,舉例說明了登錄應(yīng)用中出現(xiàn)的這種類型的數(shù)據(jù)。S序號增加,差值等于前一報(bào)文段的數(shù)據(jù)量,確認(rèn)序號、窗口大小與緊急數(shù)據(jù)偏移量均不變,URG標(biāo)志未置位。采用這種表示法可以避免傳送seq。這種類型的數(shù)據(jù)通常出現(xiàn)在單向數(shù)據(jù)傳輸(如FTP)的發(fā)送方。卷1的圖20-1、圖20-和圖20-3舉例說明了這種類型的數(shù)據(jù)傳輸。此外,如果對端不回送終端數(shù)據(jù),那么在數(shù)據(jù)發(fā)送方的數(shù)據(jù)報(bào)文段中也會(huì)出現(xiàn)這種現(xiàn)象。下面的兩個(gè)例子,在圖1-17中的bsdi和slip兩個(gè)系統(tǒng)間,利用SLIP鏈路傳輸數(shù)據(jù)。這條SLIP鏈路在兩個(gè)傳輸方向上都采用了首部壓縮算法。在主機(jī)bsdi上運(yùn)行tcpdump程序(卷1的附錄A),保存所有數(shù)據(jù)幀的備份。這個(gè)程序還支持一個(gè)選項(xiàng),能夠輸出壓縮后的首部,列出圖29-34中的所有字段。在主機(jī)間已建立了兩條連接:一條登錄連接,另一條是從bsdi到slip的文件傳(FTP)。圖29-36列出了兩條連接上不同類型數(shù)據(jù)幀出現(xiàn)的次幀類登輸輸輸輸11553223特殊情況00特殊情況119總圖29-36登錄和FTP連接上,不同類型數(shù)據(jù)幀出現(xiàn)的次登錄連接中,在兩個(gè)傳輸方向上,*SA都出現(xiàn)了75次,從而證明了在對端回顯終端流量時(shí),這一特定
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廠房買賣及配套設(shè)施交易合同樣本
- 知名餐廳商鋪?zhàn)赓U及品牌加盟合作協(xié)議
- 白糖生產(chǎn)項(xiàng)目安全生產(chǎn)與應(yīng)急預(yù)案合同
- 推動(dòng)空氣質(zhì)量持續(xù)改善的策略及實(shí)施路徑
- 水利工程就業(yè)前景分析報(bào)告
- 公司愛衛(wèi)活動(dòng)方案
- 公司派涼茶活動(dòng)方案
- 建筑結(jié)構(gòu)設(shè)計(jì)創(chuàng)新案例集錦
- 公司教育活動(dòng)方案
- 人工智能在醫(yī)藥課程教學(xué)中的應(yīng)用與研究
- 地生中考模擬試題及答案
- 慢性病管理中心建設(shè)實(shí)施方案
- T/CCMA 0163-2023履帶式液壓挖掘機(jī)維修工時(shí)定額
- 2025年下半年山西焦煤西山煤電集團(tuán)公司招聘270人易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 小紅書《家的一平米》招商方案
- 2025海南中考:歷史必考知識點(diǎn)
- 2025年二十大黨章試題庫
- 尺骨骨折護(hù)理課件
- 處世奇書《解厄鑒》全文譯解
- 導(dǎo)彈的介紹教學(xué)課件
- DB32-T 5082-2025 建筑工程消防施工質(zhì)量驗(yàn)收標(biāo)準(zhǔn)
評論
0/150
提交評論