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


Проверка потока

Встроенная проверка потоков данных

Встроенные модификаторы потоков могут изменять данные потока, разрешая или блокируя часть указанных данных, задав значение countBytesEnforced члена структуры FWPS_STREAM_CALLOUT_IO_PACKET0 при возвращении FWP_ACTION_PERMIT или FWP_ACTION_BLOCK из функции classifyFn. Они также могут вызывать функцию FwpsStreamInjectAsync0, чтобы добавить новое содержимое в поток. Это содержимое может быть новым или может заменить заблокированные данные.

Чтобы заменить шаблон, найденный в середине указанного сегмента (например, n байт, за которым следует шаблон p байт, а затем m байт), выноска будет выполнять следующие действия:

  1. Функция classifyFn вызывается с использованием + + байт.

  2. Выноска возвращает FWP_ACTION_PERMIT с элементом countBytesEnforced, равным n.

  3. Функция выноски снова вызывается с p + байтами. МПП снова вызовет функцию классифицироватьFn, если примененный подсчет байт будет меньше указанного количества.

  4. Из функции classifyFn выноска вызывает функцию FwpsStreamInjectAsync0, чтобы внедрить шаблон замены p'. Затем выноска возвращает FWP_ACTION_BLOCK с countBytesEnforced, установленным на p.

  5. Функция классификации выноски вызывается снова с m байтами.

  6. Выноска возвращает FWP_ACTION_PERMIT с countBytesEnforced значением m.

Если указанные данные недостаточны для принятия решения о проведении инспекции, он может установить значение streamAction в члене структуры FWPS_STREAM_CALLOUT_IO_PACKET0 как FWPS_STREAM_ACTION_NEED_MORE_DATA и задать для элемента countBytesRequired минимальное количество, которое МПП должен накопить, прежде чем данные будут указаны снова. При установке streamAction вызов должен возвращать FWP_ACTION_NONE из функции classifyFn.

МПП может накапливать до 8 МБ потоковых данных, когда установлено FWPS_STREAM_ACTION_NEED_MORE_DATA. ЦПП установит флаг FWPS_CLASSIFY_OUT_FLAG_BUFFER_LIMIT_REACHED, когда вызывает функцию classifyFn и буферное пространство исчерпано. При установке последнего флага выноска должна принять указанные данные в полном объеме. Вызов не должен возвращать FWPS_STREAM_ACTION_NEED_MORE_DATA, когда установлен флаг FWPS_CLASSIFY_OUT_FLAG_NO_MORE_DATA.

Для удобства сканирования шаблона потока из плоского буфера, МПП предоставляет функцию FwpsCopyStreamDataToBuffer0, которая может копировать указанные данные потока в непрерывный буфер.

Внеполосная проверка потока данных

Для внеполосной проверки или модификации вызов для поточного анализа будет следовать аналогичной схеме, как вызов для проверки пакетов: сначала клонирует все указанные сегменты потока для отложенной обработки, а затем блокирует эти сегменты. Проверенные или измененные данные позже внедряются обратно в поток данных. При внедрении данных вне диапазона обработчик должен возвращать FWP_ACTION_BLOCK на всех указанных сегментах, чтобы гарантировать целостность результирующего потока. Модуль проверки вне полосы не должен произвольно внедрять FIN (который указывает на отсутствие данных от отправителя) в исходящий поток данных. Если модуль должен удалить подключение, то его классифицировать функцию выноскиFn необходимо задать для элемента streamAction элемента структуры FWPS_STREAM_CALLOUT_IO_PACKET0 значение FWPS_STREAM_ACTION_DROP_CONNECTION.

Примечание Это нарушение контракта для вызовов, чтобы переключиться из внеполосного в встроенный, что может привести к непредвиденному поведению. Убедитесь, что вызовы вне основного диапазона соответствуют каждому из указанных критериев.

Так как потоковые данные можно указывать как цепочку NET_BUFFER_LIST, FWP предоставляет FwpsCloneStreamData0 и FwpsDiscardClonedStreamData0 служебные функции, работающие в цепочках списков чистых буферов.

МПП также поддерживает регулирование потоковой передачи данных для входящего направления. Если функция не может обрабатывать входящие данные с требуемой скоростью, она может вернуть FWPS_STREAM_ACTION_DEFER для приостановки потока. Затем поток можно возобновить, вызвав функцию FwpsStreamContinue0. Отложение потока с этой функцией приводит к остановке обработки ACK входящих данных в стеке TCP/IP. Это приводит к уменьшению скользящего окна TCP в сторону 0.

Для вызовов проверки потока вне основной полосы FwpsStreamContinue0 нельзя вызывать, пока вызывается функция FwpsStreamInjectAsync0.

Внедренные потоковые данные не будут повторно переданы в внешний интерфейс, но они будут доступны для потоковых интерфейсов из более легковесных подслоев.

Пример в репозитории драйверов Windows на сайте GitHub показывает, как выполнять встроенное и внеполосное редактирование на уровне потока.

примечание Windows Server 2008 и более поздних версий не поддерживают удаление фильтра потока во время следующих процессов:

  • Вызов внедряет пакеты вне полосы.

  • Вызов запрашивает больше данных, устанавливая член streamAction структуры FWPS_STREAM_CALLOUT_IO_PACKET0 в состояние FWPS_STREAM_ACTION_NEED_MORE_DATA.

  • Вызов откладывает поток, задав элемент streamAction streamAction структуры FWPS_STREAM_CALLOUT_IO_PACKET0 в значение FWPS_STREAM_ACTION_DEFER.

Динамическая проверка потока

Windows 7 и более поздних версий поддерживают динамические проверки потоков. Динамическая проверка потоков работает в существующем потоке данных, а не создает и удаляет новый поток. Драйвер выноски, который может выполнять динамические проверки потока, должен задать флаг FWP_CALLOUT_FLAG_ALLOW_MID_STREAM_INSPECTION в члене Flags структуры FWPS_CALLOUT1 или FWPS_CALLOUT2.

Предотвращение ненужных проверок

Для выполнения инспекций потоков только на соединениях, которые интересуют драйвера, вызов может задать флаг FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW в члене Flags структуры FWPS_CALLOUT0. Этот выносок будет игнорироваться во всех остальных подключениях. Производительность будет улучшена, и драйверу не придется поддерживать ненужные данные о состоянии.

Каскадная модель потокового слоя

Слой потока в МПП следует строгой каскадной модели; то есть, вызов в этом слое будет разрешен для проверки сегмента потока только в том случае, если предыдущий вызов (если таковой имеется) явно разрешил это. Если выноска блокирует указанный сегмент, этот сегмент безвозвратно удаляется из потока, и выноски больше не могут использоваться для его проверки.

Сверх того:

  1. Каждый вызов без проверки на уровне потока должны явно назначать значение члену actionType параметра classifyOut независимо от того, какое значение ранее было задано в этом параметре.
  2. Флаг FWPS_RIGHT_ACTION_WRITE в правах элемента параметра classifyOut не имеет значения в потоковом уровне WFP. Надписи на этом слое не должны проверять наличие этого флага. Выноски могут обрабатывать указанный параметр layerData независимо от значения classifyOut—>прав.