Проверка потока
Встроенная проверка потока
Встроенные модификаторы потока могут изменять потоковые данные, разрешая или блокируя часть указанных данных, задавая значение члена countBytesEnforcedструктуры FWPS_STREAM_CALLOUT_IO_PACKET0 , когда они возвращают FWP_ACTION_PERMIT или FWP_ACTION_BLOCK из функции выноски classifyFn . Они также могут вызывать функцию FwpsStreamInjectAsync0 для добавления нового содержимого в поток. Это содержимое может быть новым или заменять заблокированные данные.
Чтобы заменить шаблон, найденный в середине указанного сегмента (например, n байтов, за которым следует шаблон p байтов, за которым следует m байт), выноска будет выполнять следующие действия:
Функция classifyFn выноски вызывается с использованием n + p + m байтов.
Выноска возвращает FWP_ACTION_PERMIT с элементом countBytesEnforced , равным n.
Функция classifyFn выноски вызывается снова с p + m байтами. МПП вызовет classifyFn снова, если аргумент countBytesEnforced меньше указанного значения.
Из функции classifyFn выноска вызывает функцию FwpsStreamInjectAsync0 для внедрения шаблона замены p'. Затем выноска возвращает FWP_ACTION_BLOCK с параметром countBytesEnforced , равным p.
Функция classifyFn выноски вызывается снова с м байтами.
Выноска возвращает FWP_ACTION_PERMIT с параметром countBytesEnforced , равным m.
Если указанных данных недостаточно для выноски для принятия решения о проверке, он может задать элемент streamActionструктуры FWPS_STREAM_CALLOUT_IO_PACKET0FWPS_STREAM_ACTION_NEED_MORE_DATA и задать для элемента countBytesRequired минимальное количество, которое МПП должен накапливать до повторного указания данных. Если параметр streamAction задан, выноска должна возвращать FWP_ACTION_NONE из функции classifyFn .
В FWPS_STREAM_ACTION_NEED_MORE_DATA может накапливаться до 8 МБ потоковых данных. МПП установит флаг FWPS_CLASSIFY_OUT_FLAG_BUFFER_LIMIT_REACHED при вызове функции classifyFn выноски и исчерпании буферного пространства. Если установлен последний флаг, выноска должна полностью принять указанные данные. При установке флага FWPS_CLASSIFY_OUT_FLAG_NO_MORE_DATA выноска не должна возвращать FWPS_STREAM_ACTION_NEED_MORE_DATA.
Для удобства сканирования шаблона потока из плоского буфера ПРОГРАММА МПП предоставляет служебную функцию FwpsCopyStreamDataToBuffer0 , которая может копировать указанные данные потока в непрерывный буфер.
Внеполосная проверка потока
Для внеполосной проверки или изменения выноска потока будет следовать аналогичной схеме, что и выноска проверки пакетов: сначала она клонирует все указанные сегменты потока для отложенной обработки, а затем блокирует эти сегменты. Проверяемые или измененные данные затем внедряются обратно в поток данных. При внедрении данных вне диапазона выноска должна возвращать FWP_ACTION_BLOCK на всех указанных сегментах, чтобы гарантировать целостность результирующего потока. Модуль внеполосной проверки не должен произвольно внедрять FIN (что указывает на отсутствие дополнительных данных от отправителя) в исходящий поток данных. Если модуль должен удалить подключение, его функция callout classifyFn должна задать элемент streamAction структуры FWPS_STREAM_CALLOUT_IO_PACKET0FWPS_STREAM_ACTION_DROP_CONNECTION.
Примечание Это нарушение контракта для выносок при переключении между внеполосными на встроенные и может привести к непредвиденному поведению. Убедитесь, что выноски соответствуют каждому из указанных критериев.
Так как потоковые данные можно указать как цепочку NET_BUFFER_LIST , FWP предоставляет служебные функции FwpsCloneStreamData0 и FwpsDiscardClonedStreamData0 , которые работают с цепочками списков чистых буферов.
МПП также поддерживает регулирование потоковой передачи данных для входящего направления. Если выноска не может идти в ногу с скоростью входящих данных, она может вернуть FWPS_STREAM_ACTION_DEFER для "приостановки" потока. Затем поток можно возобновить, вызвав функцию FwpsStreamContinue0 . При отсрочке потока с помощью этой функции стек TCP/IP перестает выполнять ack-обработку входящих данных. Это приводит к уменьшению скользящего окна TCP до 0.
Для выносок внеполосной проверки потока не следует вызывать FwpsStreamContinue0 при вызове функции FwpsStreamInjectAsync0 .
Внедренные потоковые данные не будут повторно указаны в выноске, но они будут доступны для потоковых выносок из подслоев с более низким весом.
Пример редактирования потока платформы фильтрации Windows в репозитории примеров драйверов Windows на сайте GitHub показывает, как выполнять встроенное и внеполосное редактирование на уровне потока.
Примечание Windows Server 2008 и более поздние версии не поддерживают удаление фильтра потока в следующих процессах:
Выноска выполняет внеполосное внедрение пакетов.
Выноска запрашивает дополнительные данные, задав члену streamActionструктуры FWPS_STREAM_CALLOUT_IO_PACKET0значение FWPS_STREAM_ACTION_NEED_MORE_DATA.
Выноска откладывает поток, задав элементу 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 . Эта выноска будет игнорироваться во всех остальных подключениях. Производительность будет повышена, и драйверу не придется хранить ненужные данные о состоянии.
Каскадная модель уровня потока
Потоковый слой в МПП следует строгой каскадной модели; то есть выноске в этом слое будет разрешено проверять сегмент потока только в том случае, если предыдущая выноска (если она есть) явно разрешила ее. Если выноска блокирует указанный сегмент, этот сегмент окончательно удаляется из потока и никакие выноски не будут разрешены для его проверки.
Кроме того:
- Каждой выноске без проверки на уровне потока необходимо явно присвоить значение члену actionType параметра classifyOut независимо от того, какое значение ранее могло быть задано в этом параметре.
- Флаг FWPS_RIGHT_ACTION_WRITE в элементе прав параметра classifyOut не имеет значения на уровне потока МПП. Выноски на этом уровне не должны проверка наличия этого флага. Выноски могут обрабатывать указанный параметр layerData независимо от значения classifyOut-rights>.