共用方式為


合併 TCP/IP 區段的規則

本節會定義規則,指定接收區段聯合 (RSC)功能迷你埠驅動程式何時必須聯合指定 TCP 連線的區段。 如果違反任何規則,就會產生例外狀況,而迷你埠驅動程序必須中止區段的聯合。

迷你埠驅動程序必須更新單一聯合單位 (SCU) 的IP和 TCP 標頭。 迷你埠驅動程序必須透過 SCU 重新計算 TCP 和 IPv4 總和檢查碼,並鏈結 TCP 承載。

下列兩個流程圖中的第一個描述聯合區段和更新 TCP 標頭的規則。 此流程圖涉及區分有效重複 ACK 和窗口更新的機制。 第二個流程圖描述這些機制。

這些流程圖是以瞭解 RSC 規則的參考方式提供。 只要維護正確性,硬體實作就可以優化流程圖。

流程圖中會使用下列詞彙:

術語 描述
SEG。SEQ 傳入區段的序號。
H.SEQ 目前正追蹤的 SCU 的序列號。
SEG。ACK 接收區段的確認號碼。
H.ACK 目前追蹤 SCU 的確認號碼。
SEG。WND 傳入區段所宣告的視窗。
H.WND 目前追蹤的 SCU 所顯示的視窗。
SEG。LEN 傳入區段的 TCP 承載長度。
H.LEN 目前追蹤 SCU 的 TCP 有效負載長度。
SEG。NXT SEG.SEQSEG.LEN的總和。
H.NXT H.SEQH.LEN的總和。
H.DupAckCount 已整合到 SCU 的重複 ACK 數量。 這個數位應該是零。
SEG。Tsval 目前接收到的區段中的 時間戳記 的值。 此值的格式定義於 RFC 1323中。
H.Tsval 目前正在追蹤的 SCU 中的 Timestamp 值。
SEG.TSecr 當前接收區段中的時間戳回應
H.TSecr 目前追蹤 SCU 中的 時間戳回應

流程圖,顯示合併區段和更新 TCP 標頭的規則。

流程圖,顯示區分有效重複 ACK 和視窗更新的機制。

流程圖顯示迷你埠驅動程式可能會將不同 ACK 數位的區段聯合在一起。 不過,迷你埠驅動程序必須遵守下列有關 ACK 號碼的規則,如上述第一個流程圖所示:

  • 執行序號檢查之後,如果傳入的純 ACK 符合下列其中一個或兩個條件,可能會合併到目前追蹤的 SCU:

    • H.ACK == SEG.ACK

    • 所追蹤之聯合區段中的 duplicate-ACK 計數為零。 換句話說,H.DupAckCount == 0。

      換句話說,任何不是重複 ACK 或視窗更新的純 ACK 都會觸發例外狀況,而且不得合併。 所有這類純 ACK 都必須以個別區段表示。 此規則可確保 RSC 不會影響 Windows TCP 壅塞控制演算法的行為或效能。

  • 傳入的數據區段(SEG.ACK == H.ACK)或傳入附帶的 ACK(SEG.ACK>H.ACK)如果符合下列兩個條件,可能會合併到目前追蹤的 SCU:

    • 區段在序列空間中與SCU相鄰。 換句話說,SEG。SEQ == H.NXT
    • 所追蹤之聯合區段中的 duplicate-ACK 計數為零。 換句話說,H.DupAckCount == 0。

重複 ACK 合併的其他注意事項

重複的 ACK 行為

迷你埠驅動程式應將重複的 ACK 區段視為等同於純 ACK,並不應將其合併。 在此情況下,它必須完成目前的SCU(如果有的話)以用於信號指示,並將重複的ACK區段標記為單獨的區段。 因為 Windows 用戶端預設會使用選擇性通知 (SACK),因此重複的 ACK 區段可能會產生例外狀況。 如需範例,請參閱接收區段聯合 範例。 如果指出具有 DupAckCount> 0 的區段,NDIS 會在介面上停用 RSC。

在追蹤由數據段組成的 SCU 時,處理重複的 ACK

使用 H.LEN> 0 追蹤 SCU 時(換句話說,包含數據的合併區段),如果後續出現重複的 ACK,則追蹤 SCU 應該如下所示完成:

  1. 新的 SCU 追蹤應該從重複的 ACK 開始。

  2. 新 SCU 的 DupAckCount 應設定為零。

  3. 如果收到額外的重複 ACK,則 DupAckCount 應增加。

在此情況下,DupAckCount 會比重複 ACK 的數目少 1 個。 主機堆疊會正確處理計數。

追蹤由純累積 ACK 組成的 SCU 時處理重複的 ACK

追蹤由單一純累計 ACK 組成的 SCU 時(禁止合併多個純 ACK 的規則),如果後續出現重複的 ACK,則追蹤 SCU 的 DupAckCount 應該遞增。 如果收到其他重複的 ACK,該值也應該遞增。 在此情況下,DupAckCount 會等於合併的重複 ACK 數目。

當 DPC 中收到的第一個區段是重複的 ACK 時

在此情況下,NIC 無法判斷收到的區段是否為重複的 ACK,因為它不會維護任何狀態。 因此,區段應該視為純 ACK,如下所示:

  1. 從此區段開始,應當追蹤新的 SCU。

  2. 新 SCU 的 DupAckCount 應設定為零。

  3. 每當收到額外的重複 ACK 時,DupAckCount 應該遞增 1。

在此情況下,DupAckCount 將等於 1 小於實際重複 ACK 數目。 主系統堆疊程式會正確處理計數。

重複的 ACK 豁免

迷你埠驅動程式可能會將重複的 ACK 區段視為與純 ACK 等效,並且不會將其合併。 在此情況下,必須完成目前的 SCU(如果有的話)以進行指示,並將重複的 ACK 區段作為獨立區段指出。 因為 Windows 用戶端預設會使用 SACK,因此重複的 ACK 區段可能會產生例外狀況。 如需範例,請參閱 接收區段合併範例。 此豁免不適用於視窗更新區段。

使用時間戳記選項合併區段

TCP 時間戳選項是唯一可合法合併的選項。 將區段合併這一選項的決策交由具體實作來決定。 如果迷你埠驅動程式在使用時間戳記選項合併區段,則必須遵循下列流程圖中所述的規則:

流程圖,描述使用 TCP 時間戳選項聯合區段的規則。

注意

檢查 SEG。TSval>= H.TSval 必須使用模 232 算術進行,類似於 TCP 序號中使用的算法。 請參閱 RFC 793節 3.3。

當指出聯合區段時,必須如下所示地指出下列頻外資訊,方法是設定 NetBufferListInfo 描述聯合區段之 NET_BUFFER_LIST 結構的成員:

  • 合併的區段數目必須儲存到 NetBufferListInfo[TcpRecvSegCoalesceInfo] 的CoalescedSegCount 成員。 這個數位只代表已聯合的數據區段。 禁止純 ACK 聯合,且視窗更新區段不得計入此欄位的一部分。

  • 重複的 ACK 計數必須儲存至 NetBufferListInfo[TcpRecvSegCoalesceInfo] 中的DupAckCount 成員。 上述第一個流程圖說明如何計算此值。

  • 當具有 TCP 時間戳選項的區段合併時,NetBufferListInfo[RscTcpTimestampDelta] 必須填入組成 SCU 之聯合區段序列中最早與最新 TCP 時間戳值之間的絕對差異。 SCU 本身應該包含聯合區段序列中所見的最新 TCP 時間戳值。

DupAckCountRscTcpTimestampDelta 的值只有在 CoalescedSegCount 大於零時才會被解釋。 如果 CoalescedSegCount 為零,則會將區段視為非聯合的非 RSC 區段。

如需有關 NetBufferListInfo 成員內容的信息,請參閱 NDIS_NET_BUFFER_LIST_INFONDIS_RSC_NBL_INFO

所有聯合區段的 PSH 位應該是 ORed。 換句話說,如果在任何個別區段中設定 PSH 位,迷你埠驅動程序應該在 SCU 中設定 PSH 位。

完成 SCU 的過程涉及:

  • 重新計算 TCP 檢查碼,以及(如果適用)IPv4 檢查碼。

  • 更新IP標頭,如 更新聯合區段的IP標頭中所述。

  • 將 TCP 和 IP 標頭中的 ECN 位和 ECN 欄位設定為個別區段中設定的相同值。

處理 TCP/IP IPsec 區段

網路卡可能會顯示具備 RSC 和 IPsec 工作卸載功能的能力。 (請參閱 判斷網路適配器的 RSC 功能。)不過,如果支援 IPsec 工作卸除,它不可嘗試合併受 IPsec 保護的區段。