Поделиться через


Правила объединения сегментов TCP/IP

В этом разделе определяются правила, определяющие, когда драйвер мини-порта с поддержкой объединения сегментов получения (RSC) должен объединять сегмент для заданного TCP-подключения. Если какое-либо из правил нарушается, создается исключение, и драйвер мини-порта должен прервать объединение сегмента.

Драйвер мини-порта должен обновить заголовки IP и TCP для единой объединенной единицы (SCU). Драйвер мини-порта должен повторно вычислить контрольные суммы TCP и IPv4 через SCU и связать полезные данные TCP.

Первая из следующих двух блок-схем описывает правила объединения сегментов и обновления заголовков TCP. Эта блок-схема относится к механизмам для различения допустимых повторяющихся пакетов управления доступом и обновлений окон. Вторая блок-схема описывает эти механизмы.

Эти блок-схемы предоставляются в качестве справочных сведений о правилах RSC. Аппаратная реализация может оптимизировать блок-схему при условии, что сохраняется правильность.

В блок-схемах используются следующие термины:

Термин Описание
SEG. SEQ Порядковый номер входящего сегмента.
H.SEQ Порядковый номер отслеживаемого SCU.
SEG. ACK Номер подтверждения входящего сегмента.
H.ACK Номер подтверждения отслеживаемого SCU.
SEG. WND Окно, объявляемое входящим сегментом.
H.WND Окно, объявленное текущим отслеживаемым SCU.
SEG. ЛЕН Длина полезных данных TCP для входящего сегмента.
H.LEN Длина полезных данных TCP отслеживаемого SCU.
SEG. NXT Сумма SEG. SEQ и SEG. LEN.
H.NXT Сумма H.SEQ и H.LEN.
H.DupAckCount Количество повторяющихся ACL, объединенных в SCU. Значение должно быть нулевым.
SEG. Цваль Значение метки времени в текущем полученном сегменте. Формат для этого значения определен в RFC 1323.
Х.Цваль Значение Timestamp в отслеживаемом В данный момент SCU.
SEG. TSecr Метка времени эхо-ответа в текущем полученном сегменте.
H.TSecr Метка времени Echo Reply в отслеживаемой В настоящее время SCU.

Блок-схема, показывающая правила объединения сегментов и обновления заголовков TCP.

Блок-схема, демонстрирующая механизмы для различения допустимых повторяющихся пакетов управления доступом и обновлений окон.

Блок-схемы показывают, что драйвер мини-порта может объединять сегменты с разными номерами ACK. Однако драйвер мини-порта должен соблюдать следующие правила в отношении номеров ACK, как показано на первой блок-схеме выше:

  • После выполнения порядкового номера проверка входящий чистый ACK может быть объединена в отслеживаемый SCU, если он соответствует одному или обоим из следующих условий:

    • H.ACK == SEG. ОК.

    • Количество дубликатов в отслеживаемом сегменте равно нулю. Другими словами, H.DupAckCount == 0.

      Другими словами, любой чистый ACK, который не является дубликатом ACK или обновлением окна, вызывает исключение и не должен быть объединен. Все такие чистые пакеты ACL должны быть обозначены как отдельные сегменты. Это правило гарантирует, что RSC не влияет на поведение или производительность алгоритмов управления перегрузкой TCP в Windows.

  • Сегмент входящих данных (SEG. ACK == H.ACK) или входящий ACK с поддержкой piggy (SEG. ACK>H.ACK) может быть объединена в отслеживаемую в настоящее время SCU при выполнении обоих следующих условий:

    • Сегмент примыкает к SCU в пространстве последовательности. Другими словами, SEG. SEQ == H.NXT.
    • Количество дубликатов в отслеживаемом сегменте равно нулю. Другими словами, H.DupAckCount == 0.

Дополнительные примечания по дубликату объединения ACK

Повторяющееся поведение ACK

Драйвер минипорта должен обрабатывать дубликат сегмента ACK, эквивалентный чистой ACK, а не объединение его. В этом случае он должен завершить текущий SCU (если таковой есть) для указания и указать повторяющийся сегмент ACK как отдельный сегмент. Так как клиенты Windows по умолчанию используют селективные подтверждения (SACK), повторяющийся сегмент ACK, скорее всего, создаст исключение. Пример см. в разделе Примеры объединения сегментов получения . Если указан сегмент с DupAckCount> 0, NDIS отключит RSC в интерфейсе.

Обработка повторяющегося ACK при отслеживании SCU, состоящего из сегментов данных

При отслеживании SCU с помощью H.LEN> 0 (иными словами, объединенного сегмента, содержащего данные), если далее поступает дубликат ACK, то SCU отслеживания следует завершить следующим образом:

  1. Необходимо отслеживать новый SCU, начиная с дубликата ACK.

  2. DupAckCount для нового SCU должно быть равно нулю.

  3. DupAckCount следует увеличивать при получении дополнительных повторяющихся ACL.

В этом случае DupAckCount будет на 1 меньше количества повторяющихся ACL. Стек узлов будет правильно обрабатывать подсчет.

Обработка повторяющегося ACK при отслеживании SCU, состоящего из чистого интегрального ACK

При отслеживании SCU, состоящего из одного чистого интегрального ACK (правила запрещают объединение нескольких чистых пакетов ACL), если далее поступает дубликат ACK, DupAckCount для SCU отслеживания следует увеличить. При получении дополнительных повторяющихся ACL его также следует увеличивать. В этом случае DupAckCount будет равно количеству повторяющихся ACL, которые объединяются.

Когда первый сегмент, полученный в DPC, является дубликатом ACK

В этом случае сетевой адаптер не может определить, является ли полученный сегмент повторяющимся ACK, так как он не поддерживает какое-либо состояние. Таким образом, сегмент следует рассматривать как чистый ACK, а не следующим образом:

  1. Необходимо отслеживать новый SCU, начиная с этого сегмента.

  2. DupAckCount для нового SCU должно быть равно нулю.

  3. Значение DupAckCount должно увеличиваться на 1 для каждого дополнительного полученного дубликата ACK.

В этом случае DupAckCount будет на 1 меньше фактического числа повторяющихся ACL. Стек узлов будет правильно обрабатывать подсчет.

Дублирование исключения ACK

Драйвер минипорта может обрабатывать дубликат сегмента ACK, эквивалентный чистой ACK, а не объединение его. В этом случае он должен завершить текущий SCU (если таковой есть) для указания и указать повторяющийся сегмент ACK как отдельный сегмент. Так как клиенты Windows используют SACK по умолчанию, повторяющийся сегмент ACK, скорее всего, создаст исключение. Пример см. в разделе Примеры объединения сегментов получения. Это исключение не применяется к сегментам обновления окна.

Объединение сегментов с помощью параметра timestamp

Параметр tcp timestamp является единственным вариантом, который может быть юридически объединен. Объединение сегментов с этим параметром остается решением для конкретной реализации. Если драйвер мини-порта объединяет сегменты с параметром timestamp, он должен следовать правилам, изложенным в следующей блок-схеме:

Блок-схема, описывающая правила объединения сегментов с параметром

Примечание

SEG проверка. TSval>= H.TSval должен выполняться с использованием арифметики по модулю 232, аналогичной той, которая используется для порядковых номеров TCP. См. RFC 793, раздел 3.3.

При указании объединенного сегмента необходимо указать следующие сведения вне диапазона, задав элемент NetBufferListInfoNET_BUFFER_LIST структуры, описывающей объединяемый сегмент:

  • Количество сегментов, которые были объединялись, должно храниться в NetBufferListInfo[TcpRecvSegCoalesceInfo]. Элемент CoalescedSegCount . Это число представляет только сегменты данных, которые были объедины. Чистое объединение ACK запрещено, и сегменты обновления окна не должны учитываться как часть этого поля.

  • Повторяющееся число ACK должно храниться в NetBufferListInfo[TcpRecvSegCoalesceInfo]. Участник DupAckCount . На первой блок-схеме выше объясняется, как вычисляется это значение.

  • Если сегменты с параметром метки времени TCP объединяются, NetBufferListInfo[RscTcpTimestampDelta] должен заполняться абсолютной разницей между самым ранним и последним значением метки времени TCP, которое отображается в последовательности объединенных сегментов, составляющих SCU. Сам SCU должен содержать последнее значение метки времени TCP, которое можно увидеть в последовательности объединенных сегментов.

Члены DupAckCount и RscTcpTimestampDelta интерпретируются только в том случае, если элемент CoalescedSegCount больше нуля. Если значение CoalescedSegCount равно нулю, сегмент обрабатывается как несмеждаемый сегмент без RSC.

Сведения о содержимом элемента NetBufferListInfo см. в разделе NDIS_NET_BUFFER_LIST_INFO и NDIS_RSC_NBL_INFO.

Бит PSH должен быть ORed для всех объединенных сегментов. Другими словами, если бит PSH был задан в любом из отдельных сегментов, драйвер мини-порта должен задать бит PSH в SCU.

Завершение SCU включает в себя:

Обработка сегментов IPsec TCP/IP

Сетевой карта может сообщать о возможностях разгрузки задач RSC и IPsec. (См. раздел Определение возможностей RSC сетевого адаптера.) Однако если он поддерживает разгрузку задач IPsec, он не должен пытаться объединить сегменты, защищенные IPsec.