1. 程式人生 > >TCP連接管理

TCP連接管理

補充 報文 udp協議 hot 初始化 問題 方法 cookie 釋放

TCP連接管理

??本節將介紹一條TCP連接是如何建立和拆除的。此處假設客戶機A上面的一個進程想要和服務
器B上的一個進程建立一條TCP連接。本文前面介紹的是比較正常的連接和拆除,特殊的會在後面介紹。

TCP連接建立

????????技術分享圖片

第一步

客戶機A的TCP會向服務器的TCP發送一個不包含應用層數據的數據的TCP報文段。該報文段中首部標誌位S YN被置為1,此報文段也被叫做SYN報文段。並且A會隨機地選擇一個初始序號(client_isn),將其填入首部中的序號字段(註意為了避免某些安全性的攻擊,此處的隨機化選擇有著不少研究,後面會補充)。然後,該報文被封裝進IP數據報,發送給服務器。

第二步

一旦TCP SYN報文段的IP數據包到達服務器後,服務器就會從IP數據包中提取出TCP SYN報文段,為該TCP連接分配TCP緩存和變量,並向客戶機發送允許TCP連接的報文段,這個報文段也不包含應用層數據。(這裏需要註意如果在完成三次握手的第三步之前分配緩存和變量會使得TCP易受到稱為SYN洪泛的拒絕服務攻擊服務

在發送的報文中,標誌位SYN被置為1,確認序號被置為client_isn+1,
服務器也會選用一個初始序號將其放入報文中的序號字段
。這個報文有時也會被稱為SYNACK報文段(SYNACK segment)。

第三步

在收到SYNACK報文段後,客戶也要給這個連接分配緩存和變量。然後,客戶機A會向服務器發送對允許連接

報文的確認,完成連接的建立。此時報文中,SYN置為0,確認序號為sever_isn+1。在此報文段中也可以攜帶客戶機到服務器的數據了

完成這三個步驟後,客戶機和服務器就可以相互發送包含數據的報文段啦。在以後的每個報文中SYN都為0。
創建連接需要發送三個報文,所以這個過程也叫3次握手(three-way shakehand)

那麽問題也出來了。為什麽需要三次握手,只交換兩次報文不可以嗎?
可以簡單地解釋下,客戶發送確認服務器發送的接收連接報文是為了防止以前的連接請求即失效連接請求發送到服務器而造成錯誤。

TCP連接釋放

有連接必然就有釋放的時候。釋放的過程可以見下圖。

???技術分享圖片

???????????????????TCP連接釋放示意圖

第一步

客戶進程發出關閉TCP連接命令。客戶TCP便會向服務器進程發送標誌位FIN=1的報文段,便進入FIN_WAIT_1階段服務器TCP收到該報文段後就向客戶機發送確認報文段並通知上層應用程序該TCP連接即將關閉,然後,服務器進入CLOSE_WAIT階段

第二步

客戶機TCP收到確認報文,然後進入FIN_WAIT_2階段,等待來自服務器的含有FIN=1的報文段。
服務器在這段時間還是可以向客戶機發送含上層應用程序數據的報文段,客戶機接收並發送確認報文。最後,服務器TCP向客戶機發送含FIN=1的報文段,便進入LASE_ACK階段

第三步

客戶機TCP收到含FIN=1的報文段向服務器發出確認報文,便進入TIME_WAIT階段,等待2MSL後便釋放所有連接所占資源。如果客戶給服務器發送的確認報文丟失,那麽在這段時間內,便可進行重傳操作。這段時間一過,客戶將釋放所有連接所占資源。
服務器TCP收到客戶機的確認ACK後便釋放連接所占資源。

附圖兩張客戶機和服務器在整個TCP連接期間的狀態序列

????????技術分享圖片

????????技術分享圖片

SYN洪泛攻擊

記得在前面說過服務器收到一個SYN後,會分配緩存並初始化一些相關變量。然後向客戶發送SYNACK進行響應,並等待來自客戶的ACK報文段。如果某個客戶不發送ACK完成三次握手的第三步,最終(通常在一分多鐘後)服務器將終止該半開連接並回收資源。
這種TCP連接管理協議為經典的DoS攻擊即SYN洪泛攻擊(SYN flood attack)提供了環境。在這種攻擊中,攻擊者發送大量的TCP SYN報文段,而不完成三次握手中的第三步,服務器為大量的這種半開連接分配資源,最終將導致服務器的連接資源殆盡
好的是,現在有一種有效的防禦系統——SYN cookie [RFC 4987],其工作方式可以描述如下:

  • 當服務器接收到一個SYN報文時,不為該報文段生成一個半開連接。相反,服務器為其生成一個初始TCP序列號,該序列號是用SYN報文段的源和目的IP地址與端口號以及僅有該服務器知道的秘鑰生成的散列函數值。這個初始序列號也被叫做"cookie"。服務器向發出連接請求的客戶發送TCP序號字段為這個初始序號的SYNACK分組 。
    但是最要的是,服務器並不記憶該初始序號和其他有關這個SYN報文段的信息

  • 如果客戶是合法的,那麽它會發送一個ACK報文段。當服務器收到該ACK後,需要驗證該ACK是與前面發送的某些SYN相對應。
    服務器將使用在SYNACK報文段中的源和目的IP地址與端口號和秘鑰運行相同的散列函數,計算該ACK報文段的散列函數值。如果散列函數值加1等同於客戶發來的這個ACK中確認號字段的值,那麽,服務器就認為該ACK報文段對應於較早的SYN報文段,因此它是合法的。然後,服務器生成一個具有套接字的全開連接!


????以上是正常的連接和釋放的過程,下面會對上面進行一些補充。


TCP連接建立和釋放的特殊情況

TCP半關閉

TCP支持半關閉操作,如前描述的釋放連接第二步中,客戶機發送了一個FIN報文給服務器,服務器發送了確認後,客戶機這邊就進入半關閉狀態,但是仍然可以接收來自服務器發送的數據。即“我完成了數據的發送工作,並發送了一個FIN給對方,但是我任然希望收到來自對方的數據直到它發送給一個FIN給我”。在服務器未發送FIN的這段時間裏,它可以傳任意數量的報文段給客戶。當服務器發送FIN然後FIN被確認,那麽整個連接將完全被關閉。

同時打開與關閉

兩個應用程序同時主動打開連接可能不大可能,但是在特定安排的情況下還有可能實現。這要求通信雙方收到對方SYN之前必須先發送一個SYN,兩個SYN必須經網絡到達對方,並要求通信雙方告知對方其IP地址和端口號。服務器始終未被動打開,所以不會出現這種情況。
與正常連接相比,多了一個報文段。數據包的SYN將置位直到接收到一個ACK數據包為止。
??技術分享圖片

同時關閉與前面的正常關閉並沒有太大的區別。在通信中,雙方都會主動發送FIN,然後進行關閉。
同時關閉和正常關閉是相同數量的報文段。兩者真正的區別在於報文段序列是交叉的還是順序的。
技術分享圖片

重置報文段

將TCP首部RST字段置位的報文段被稱為“重置報文段”或者“重置”。一般來說,當發現一個到達的報文段對於相關連接而言不正確時,TCP會發送一個重置報文段。(此處,相關連接是指由重置報文段的TCP與IP首部的四元組所指定的連接)。

針對不存在的端口的連接請求

通常,當一個連接請求到達本地卻沒有相關進程在目的端口偵聽時就會產生重置報文段。
UDP協議中規定,當一個數據報到達不能使用的目的端口時就會生成一個ICMP目的地不可達(端口不可達)的消息。
TCP則是使用重置報文段來代替相關工作。
對於被TCP重置的報文段而言,它的ACK位字段必須被置位,並且ACK號字段的數值必須在正確窗口範圍內。這樣有助於防止他人攻擊。

終止一條連接

終止一條正常連接的方法是由通信一方發送FIN。這種方法也被稱為有序釋放。在這種情況下,TCP緩存中所有排隊的數據都被發送,通常沒有數據丟失。
然而,在任何時刻,我們都可以通過發送一個重置報文段替代FIN來終止一條連接。這種方式也被稱為終止釋放


終止一條連接為應用程序提供兩大特性:

  • 任何排隊的數據都將被發送出去,一個重置報文段會被立即發送出去
  • 重置報文段的接收方會說明通信另一端采用可終止的方法而不是一次正常的關閉。

需要註意:

重置報文段不會被通信另外一端做出任何響應,即它不會被確認。接收重置報文段的另一段會終止連接並通知應用程序當前連接已被重置。

半開連接

如果在未告知另一端的情況下通信的一端關閉或者終止連接,那麽就認為該TCP連接處於半開狀態。這種情況一般發生在通信一方的主機崩潰。只要不嘗試通過半開連接傳輸數據,正常工作的一端不會檢測另一端已經崩潰。產生半開連接的另外一個共同原因是某臺主機的電源被切斷而非正常關機。

時間等待錯誤

設計TIME_WAIT狀態的目的是允許任何受制於一條關閉連接的數據報被丟棄。在這段期間,等待TCP通常不需要做任何操作,它只需要維持當前狀態直到2MSL的計時結束。然而,如果它在這段時間內收到任何關於這條連接的一些報文段,或者是更加特殊的重置報文,它將被破壞。這種情況被稱為時間等待錯誤(TIME-WAIT Assaaination TWA RFC[1337])

為解決這個問題,許多系統規定當處於TIME-WAIT狀態時不對重置報文做出反應。

TCP連接管理