顯示具有 tcp 標籤的文章。 顯示所有文章
顯示具有 tcp 標籤的文章。 顯示所有文章

12月 07, 2010

TCP 緩啟動 (slow start)

In Transmission Control Protocol (TCP), the congestion window is one of the factors that determines the number of bytes that can be outstanding at any time. Maintained on the sender, this is a means of stopping the link between two places from getting overloaded with too much traffic.

在 TCP 連線中,使用了 congestion window 來控制發送端的速度。
這個值是由 sender 來保管的。那 receiver 用什麼參數?! 聽說是叫 Advertise window

Initially:
cwnd = 1;
ssthresh = infinite;

New ack received:
if (cwnd < ssthresh)
cwnd = cwnd + 1; /* 每收到 1 個 ACK , cwnd 額度加 1 */
else
cwnd = cwnd + 1/cwnd; /* 每收到 1 個 ACK ,cwnd 額度加 1/cwnd */
/* 當 cwnd=32 時,送出 32 pkts,會收到 32 acks */
/* 這意味 NewCwnd= cwnd + 32 * 1/cwnd(=32) = 33 */
Timeout:
ssthresh = cwnd/2; /* 如果之前爆掉了 就把你原本的額度砍半*/
cwnd = 1; /* 並且讓你從頭來過,進行 slow start */

TCP 使用滑動視窗(sliding window)使得資料流傳輸更有效率。在滑動視窗協定中,將之定義為 window size ≦ min (cwnd,RAwnd),其中 cwnd 為 congestion window,限制封包傳送數率;RAwnd 為 Receiver Advertisment Window,接收端建議視窗的大小。ㄧ般來說,此值會大於 cwnd,因此 window size幾乎等於 cwnd。

緩慢啟動機制(Slow-Start)
起初發送端會分配 1 個 MSS 的額度量來發送資料,當在預期時間(Timeout)
內收到全部回覆時,發送端會分配為前次 cwnd 兩倍的量,接者都以2^n 指數形態成長。

壅塞避免機制(Congestion Avoidance)
當在預期時間內收到全部回覆時,發送端會將 cwnd 的值加 1 個 MSS,以線性的方式成長。

[Timeout]
設定 threshold = 當前 cwnd / 2
然後 cwnd = 1
重新進行 slow start

**

[TCP Tahoe]
TCP 早期的版本,Tahoe具備 TCP 基本架構,包括慢啟動、壅塞避免、重傳狀態。TCP 在 Tahoe 這版本中加入了快速重傳(Fast retransmit)的方法。快速重傳機制是依據重複(Duplicate) ACKs 作為重送封包的機制,當收到 3 個重複 ACKs,傳送端會將封包視為遺失,不需 Timeout 就進入重送機制(將 ssthresh 的值設為 cwnd 的 1/2,即 cwnd 的值設為 1),表示的確有個節段遺失,而不是因為順序混亂而引發重複 ACKs。

[TCP Reno]
Reno(RFC 2581)為目前最普遍的版本,修改 Tahoe 演算法並加入快速恢復
(Fast recovery)機制。Reno 以快速恢復取代 Tahoe在重傳遺失封包後就進入慢啟動狀態。在 Reno 版本中快速重傳機制在重傳遺失封包後,將 cwnd 設為偵測到遺失時的 1/2,並當每收到一個重複 ACKs 就繼續送出新的封包來提高頻寬利用率,可以更快達到 threshold 值,已進入壅塞避免階段。快速重傳及快速恢復都是使用計算重複 ACKs 的技巧,以維持節段號碼順序。

[TCP Vegas]
Brakmo 和 Peterson 提出採用觀察 RTT的變化量來控制 cwnd 的大小,以計
算預期的效能比較實際的效能來加以決定是否增加或減少 ssthresh 直,Vegas 修改了 Reno 的技術並重新設計了以下三種方法,如下介紹:
修改 slow-start ( Modified slow-start )
希望能更有效率的利用頻寬並且避免 cwnd 值上升太快而引發封包遺失情況。cwnd 值大約經過 2 個 RTT 時間(Round-Trip Time)後才會增加一倍,而非 Reno,每次的 RTT時間就會使得 cwnd 值改變。

可悲窗口 (Silly Window Syndrome)

Silly Window Syndrome

發送端或接收端在發送、接收資料時,效率太差稱之。
現在有 1 Byte 的資料要送但因為 TCP 與 IP 的 Header 最小總計為40Bytes,變成資料使用率是 1/41 < 2.5% 如此的使用效率過於低落

解法:
Delayed ACK
接收端收到 Data 後,不用馬上回 ACK。等到之後要送資料封包回去後再一起夾帶 ACK 封包回去。如果在等待的時間,又收到第二個封包,那就要馬上回傳這兩個封包的 ACK 了。
Nagle's Algorithm
當有資料要送時,不會立刻送出,除非下面條件之一成立
1. 要送出的資料累績一定量(MSS)。
2. 收到前一個送出資料的 ACK 時(表示之前的資料已成功送達, 此時不送也是讓頻寬空著)
演算法示意:

if there is new data to send /* 有資料要送 */
if the window size >= MSS and available data is >= MSS
send complete MSS segment now /* 會累績到 MSS 的量才送*/
else
if there is unconfirmed data still in the pipe
enqueue data in the buffer until an acknowledge is received
else /* 或者等到 ACK 回應 */
send data immediately
end if
end if
end if

12月 05, 2010

TCP 協定

Sliding Window 是一個機制,就視窗在那邊滑呀滑的
可以控制的參就是 window size

來源端的 Sliding Window 稱為 Send Window
目的端的 Sliding Window 稱為 Receive Window

[Establish Connection]

0. 雙方皆處於『CLOSED』狀態

1. [Server 端]
當Server端發生『passive OPEN』的事件後,便會進行『create TCB』的動作,
並進入『LISTEN』的狀態。因為在Server端啟動『服務』(service),
並使用TCP協定時,是屬於被動的角色,所以在Server端對TCP的開啟,
稱之為『passive OPEN』,隨即便會在系統中,建立一個『傳輸控制區塊』
(Transmission Control Block,簡稱TCB),用來儲存Server端有關TCP的所有資訊。
也由於Server 端必須先進入『LISTEN』狀態才能接受Client端的連線請求

2. [Client 端]
當Client發生『active OPEN』事件後,即進行『create TCB and SYN』的動作,
並進入『SYN SENT』的狀態。因為在Client端使用TCP協定時,是屬於主動的角色,
所以在Client端對TCP的開啟,稱之為『active OPEN』,隨即便會在系統中,
建立一個『傳輸控制區塊』(Transmission Control Block, 簡稱TCB),
用來儲存Client端有關 TCP的所有資訊,同時也送出SYN同步訊息給Server端,
也就是進行『三向交握』的第一個動作

3. [Server端]
當Server發生『receive SYN』事件後,即進行『send SYN, ACK』的動作。
換言之,當Server端收到Client端傳送過來同步訊息SYN時,便會傳送SYN與ACK
給Client端,也就是進行『三向交握』的第二個動作

4. [Client端]
當Client發生『receive SYN, ACK』事件後,即進行『send ACK』的動作。
換言之,當Client端收到Server端回應的確認訊息ACK與同步訊息SYN時,
便會回應一個確認訊息ACK給Server端,也就是進行『三向交握』的第三個動作,
並進入『ESTABLISHED』狀態

5. [Server端]
當Server發生『receive ACK of SYN』事件後,不做任何動作,
直接進入『ESTABLISHED』狀態。換言之,就是在收到Client端回應的確認訊息
ACK後,不執行任何動作,直接進入『ESTABLISHED』狀態

[Close Connection]

0. 雙方皆已處於『ESTABLISHED』狀態。
1. A端的程式要準備關閉連線,會發生『CLOSE』的事件,進行『send FIN』的動作
進入『FIN WAIT-1』的狀態

2. 當 B 端『receive FIN』後,會進行『send ACK』的動作,
並進入『CLOSE WAIT』狀態。

3. 當 A 端發生『receive ACK of FIN』事件後,便直接進入『FIN WAIT-2』狀態。
換言之,收到 B 端回應的確認訊息ACK之後,不執行任何動作直接進入 FIN WAIT-2

4. 之後 B 端會發生『CLOSE』事件後,進行『send FIN』 進入『LAST ACK』狀態

5. 當 A 端發生『receive FIN』的事件後,便會進行『send ACK』的動作,
並進入『TIME WAIT』的狀態。

6. 當 B 端發生『receive ACK of FIN』事件,直接進入『CLOSED』狀態,
不執行任何動作。 B 的動作到此完成。

7. A 會在 TIME WAIT 狀態等待 [Timeout=2MSL] 事件後,便會執行[delete TCB]
進入[CLOSED]的狀態。換言之,就是A端等待2MSL(Max Segment Lifetime, 簡稱MSL)
時間過後,便將系統在『建立連線』階段所建立的 TCB 刪除,

2MSL:
TCP 的封包在傳輸時,不一定會同時到達;當"連線中止"後,有可能收到先前傳送
但延遲到達的封包。

若新連線在舊連線關閉後,又立刻建立起來(新舊用同 port),這樣會造成錯誤。
延遲到達的封包,應該是歸屬前個連線,現在卻送到新的連線。舊封包送給新連線。

所以 2MSL 表示,如果一條 TCP 連線之前已經用過了,為了避免已關閉連線
干擾到新建立的連線,規定連線關閉 2MSL 時間內,不可以建立相同連線。

MSL 這個單位是指 max segment lifetime 封包最長存活時間
在網路中封包只能存活 1 MSL ,現在等待 2MSL 可以放心了。

**

TCP 的 SYN 氾濫攻擊法(TCP SYN Flooding Attack)
1) Client端送出一個 SYN 的訊息給伺服端,要求連線。
2) 伺服端在收到,會做兩件事:
a. 回應 SYN-ACK 表示準備連線
b. 在 Queue 中建立一個 TCP Connection Entry,直到完成連線後才移除
3) 正常的 Client 收到 SYN-ACK 之後,會回應一個 ACK 表示連線正式建立完成。

SYN 攻擊,惡意連線不會做第3步,此時 server 會一直等,直到 timeout
才會移除該筆 tcp connection entry。每個伺服器的佇列能容納 TCP Connection Entry
個數有線,一旦佇列存滿後,後來的連線將會被丟棄(discard)

方法
偽造自己的IP Address為其他主機或是不存在的主機
進行三向交握,此時受攻擊者伺服器將會一直等待(wait)『三向交握』的
第三步驟ACK回應,直到逾時,形成『半開啟連線』(half-open connection)

**

在 TCP 封包內有 options 欄位,主要有幾種選擇性的功能可用:

1. MSS (maximum segment size)
連線建立時,用來指定 tcp payload 可以承載的最大 size ,這個值是不包含 HDR的
雙方在初始溝通後,會選定最小值,也就是 min(MSSa , MSSb)

{ 乙太HDR | [ IP HDR | (TCP HDR | TCP BODY) ] }

因為 TCP 是封裝再 IP 內,再丟給乙太,而乙太最大 payload 是 1500

所以 TCP payload = 1500 - IP HDR(20) - TCP HDR(20) = 1460

MSS = Transport 層最大 payload = 1460 byte (可以承載的 淨容量 就對了)

(註) MTU(Maximum Tansmission Unit)
則是代表 Data Link 層最大的 Payload (如果是乙太的話, MTU=1500)