深入理解ip_conntrack的都知道,ip-conntrack本身對於tcp維護了乙個狀態機,值得注意的是,該狀態機和tcp協議本身的狀態機相似但不相同。其區別如下:
tcp狀態機:
為tcp的兩端分別維護乙個狀態機,tcp連線的主動發起/被動發起和主動關閉/被動關閉的狀態機轉換是不同的。
ip_conntrack的tcp狀態機:
只有乙個概念,即conntrack本身,因此也就只有乙個狀態機,並不區分主動和被動。ip_conntrack並沒有傳送端和接收端的概念,因此也就沒有雙工的概念,而tcp是全雙工的傳輸層協議,所以在連線開始和結束的時候才會分別有兩個狀態機轉換圖。
那麼,如何將tcp的狀態機對映到ip_conntrack的tcp狀態機呢?實際上很簡單,ip_conntrack的tcp狀態機要比tcp本身的狀態機簡單得多,它完全基於前乙個狀態以及收到的tcp段的標誌位決定要轉換到的狀態,沒有主動端和被動端一說,所以它可以實現成乙個多維陣列的方式!linux核心中的實現是三維陣列,第一維表示方向,第二維表示tcp段的標誌,第三維表示前乙個狀態。其具體實現就不多說了,前面也寫過一篇文章。
本文主要說一下ip_conntrack的tcp狀態機面臨tcp資料段時的表現以及其和幾個惱人的tcp狀態的關係。首先是一幅圖,展示tcp狀態和ip_conntrack的tcp狀態:
下面我直接瞄向time_wait!ip_conntrack的tcp狀態中也有time_wait,它和tcp本身的time_wait之間會不會有聯動呢?先給出答案:沒有!
這不會帶來任何問題。雖然conntrack的tw狀態並沒有過期,但是conntrack本身並不處理tw狀態的任何語義規範。正如conntrack的名稱所示,它沒有任何處理邏輯,只是有乙個記錄的功能,確認不管是什麼協議,tcp也好,udp也好,確保它們雁過留聲。當然,你可以基於留下的足跡來做一些工作,比如nat。
事實上,tcp只在終端系統的第四層根據詳細的tcp規範被處理!tcp當初在設計的時候就被設計成乙個端到端的協議,這是它的本質。tcp之所以複雜是因為它經得起被複雜化。tcp並不是一開始就很複雜的,它的核心超級簡單!乙個經得起被任意程度複雜化的協議只能是端到端的協議,否則乙個分布式的協議遇到的很多狀態同步問題以及功能疊加重複的問題會阻礙協議複雜化的程序。想一下乙個分布式的複雜協議ospf的發展就知道了。
因此,不管從原則上還是從實際實現上,conntrack都不過問tcp規範,也不強制保持狀態過期時間,所有這一切都在端系統的傳輸層處理(不考慮syn**!),conntrack只是單純的維持狀態機運轉,即簡單的「來了什麼資料,轉到什麼狀態,過了時間就超時刪除」。其任何狀態都有乙個超時時間,過期後的行為就是簡單的「被刪除」!
2.ip_conntrack不處理tcp,是的,但是並不絕對
conntrack不應該處理tcp,但是有時不得不處理,因為它首先要保證自身的狀態不會亂掉。乙個例子就是,conntrack處理邏輯會丟掉乙個tcp連線中視窗外的資料。
無狀態TCP的ip conntrack
linux的ip conntrack實現得過於沉重和精細。而實際上有時候,根本不需要在conntrack中對tcp的狀態進行跟蹤,只把它當udp好了,我們的需求就是讓系統可以將乙個資料報和乙個五元組標示的流相關聯,因為很多的基於流的策略都設定在conntrack結構中,所以當關聯好之後,就可以直接取...
無狀態TCP的ip conntrack
linux的ip conntrack實現得過於沉重和精細。而實際上有時候,根本不需要在conntrack中對tcp的狀態進行跟蹤,只把它當udp好了,我們的需求就是讓系統可以將乙個資料報和乙個五元組標示的流相關聯,因為很多的基於流的策略都設定在conntrack結構中,所以當關聯好之後,就可以直接取...
ip conntrack的TCP狀態機
深入理解ip conntrack的都知道,ip conntrack本身對於tcp維護了乙個狀態機,值得注意的是,該狀態機和tcp協議本身的狀態機相似但不相同。其區別如下 tcp狀態機 為tcp的兩端分別維護乙個狀態機,tcp連線的主動發起 被動發起和主動關閉 被動關閉的狀態機轉換是不同的。ip co...