diff --git a/docs/manual.md b/docs/manual.md index aa2a070..065ff0f 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -31,13 +31,15 @@ - [Передача блобов](#передача-блобов) - [Внутрипрофильные фильтры](#внутрипрофильные-фильтры) - [Типичная схема вызова инстансов внутри профиля](#типичная-схема-вызова-инстансов-внутри-профиля) - - [Прототип Lua функции](#прототип-lua-функции) + - [Прототип Lua desync функции](#прототип-lua-desync-функции) - [Структура таблицы desync](#структура-таблицы-desync) - [Структура диссекта](#структура-диссекта) - [Особенности приема многопакетных пейлоадов](#особенности-приема-многопакетных-пейлоадов) - [Структура track](#структура-track) - [Особенности обработки icmp](#особенности-обработки-icmp) - [Особенности обработки raw ip](#особенности-обработки-raw-ip) + - [Таймеры](#таймеры) + - [Прототип функции таймера](#прототип-функции-таймера) - [С интерфейс nfqws2](#с-интерфейс-nfqws2) - [Базовые константы](#базовые-константы) - [Стандартные блобы](#стандартные-блобы) @@ -96,6 +98,9 @@ - [lua_cutoff](#lua_cutoff) - [execution_plan](#execution_plan) - [execution_plan_cancel](#execution_plan_cancel) + - [Управление таймерами](#управление-таймерами) + - [timer_set](#timer_set) + - [timer_del](#timer_del) - [Библиотека базовых функций zapret-lib.lua](#библиотека-базовых-функций-zapret-liblua) - [Базовые desync функции](#базовые-desync-функции) - [luaexec](#luaexec) @@ -705,6 +710,7 @@ nfqws2 использует стандартный парсер getopt_long_only --ipcache-lifetime= ; время жизни записей кэша IP в секундах. 0 - без ограничений. --ipcache-hostname=[0|1] ; 1 или отсутствие аргумента включают кэширование имен хостов для применения в стратегиях нулевой фазы --reasm-disable=[type[,type]] ; отключить сборку фрагментов для списка пейлоадов : tls_client_hello quic_initial . без аргумента - отключить reasm для всего. + --timer-res=msec ; разрешение таймеров в мс. по умолчанию - 50 DESYNC ENGINE INIT: --writeable[=] ; создать директорию для Lua с разрешением записи и поместить путь к ней в переменную env "WRITEABLE" (только одна директория) @@ -1140,7 +1146,7 @@ nfqws2 создает каталог, назначает на него таки ## Вызов Lua кода -Lua код вызывается в 2 этапа. +Lua код вызывается в 3 местах. 1. Однократно при запуске программы через `--lua-init=code|@file`. Если значение параметра начинается с `@`, выполняется файл, иначе значение параметра является Lua кодом. Поддерживается сжатие файлов gzip. Сначала проверяется "file", потом "file.gz". 2. При обработке профиля через `--lua-desync=function_name:arg1[=val1]:arg2[=val2]:argN[=valN]`. @@ -1150,6 +1156,7 @@ Lua код вызывается в 2 этапа. `%var` подставляет значение переменной `desync.var` или `var`, если первая отсутствует. `#var` подставляет длину переменной `desync.var` или `var`, если первая отсутствует. Двоеточия и знаки `%`, `#` в начале могут быть эскейпнуты через `\`. +3. При обработке таймеров И `--lua-init`, и `--lua-desync` может быть несколько. Выполнение производится строго в порядке указания. @@ -1229,7 +1236,7 @@ nfqws2 следит за превышением верхней границы с - Строчка `--lua-desync=fake:blob=fake_default_tls:badsum:strategy=1` вызывает функцию `fake` с 3 аргументами : `blob`, `badsum`, `strategy`. Значением аргумента `badsum` является пустая строка. -## Прототип Lua функции +## Прототип Lua desync функции Стандартная Lua функция имеет прототип @@ -1731,6 +1738,51 @@ conntrack работает только с tcp и udp, он не ведет уч В диссекте выдаются поля ip, ip6, payload. payload включает содержимое пакета после L3 заголовков. desync.track всегда отсутствует. +## Таймеры + +Lua код может вызываться и вне привязки к принимаемым данным из сети. +Источником события является время. +Таймер - это обьект nfqws2, идентифицируемый по уникальному имени и позволяющий вызывать +указанную Lua функцию с определенной периодичностью, либо однократно через какое-то время. +Установкой таймера занимается функция [timer_set](#timer_set), удаляет таймер функция [timer_del](#timer_del). + +nfqws2 - программа однопоточная, как и движок Lua. Таймеры вызываются в контексте того же потока, что и обработка сетевых данных. +В Linux и Windows пакеты принимаются не по одному, а блоками. Блок обрабатывается до полного исчерпания оставшихся пакетов. +Таймеры вызываются между обработкой блоков. Если обработка заняла достаточно много времени, то вызов таймера может быть +не идеальным по времени. + +Следует помнить о разрешении таймеров, которое задается в параметре `--timer-res`. По умолчанию - 50 мсек. +Это значит, что проверка необходимости вызова таймера может проводиться не чаще указанного времени. +Если вы сделаете period 70 мсек, таймер будет вызываться "рвано". +70 будет вызван при 100, +140 - при 150, +210 - при 250. +Поэтому период желательно делать кратным разрешению таймеров. +Увеличение разрешения (снижение `--timer-res`) может привести к некоторому увеличению нагрузки на CPU, +поскольку процессор будет просыпаться через каждый указанный период времени для проверки всех таймеров. +Чем больше таймеров, тем выше нагрузка на CPU для проверки. +Максимальное разрешение - 100 проверок в секунду, что соответствует `--timer-res=10`. + +Таймеры могут быть полезны для обработке ситуаций отсутствия реакции из сети на отсылаемые пакеты. +Например, вам надо что-то куда-то послать и прочитать ответ. Но оппонент может и не ответить или ответ может не дойти. +Чтобы ваша схема не подвисла в неопределенном состоянии и не оставила мусор в памяти, может помочь таймер. +С помощью таймеров, desync функций и функций отсылки можно построить полноценную машину состояний - вплоть +до собственной реализации tcp или иной системы гарантированной доставки. +Проектировать схему нужно асинхронно в стиле конечного автомата. Прямые задержки sleep в коде не предусмотрены, поскольку ломают +схему обработки трафика через очередь. Пока вы ждете - остальное повиснет. + +### Прототип функции таймера + +``` +function timer(name, data) +``` + +Таймер-функции может быть передана произвольная Lua переменная любого типа. +Таблицу можно использовать для хранения состояния, привязанного к таймеру. +Переменные простых типов могут односторонне передать какие-то read-only значения. +data задается при запуске таймера через [timer_set](#timer_set). +При удалении таймера переменная автоматически освобождается, если на нее нет других ссылок. + +Если таймер-функция вываливается с error, таймер удаляется принудительно. +Долбежки по error не будет - таймер просто останавливается и перестает работать. +Поэтому при разработке таймер функций особо важно не допускать варианты с error. # С интерфейс nfqws2 @@ -2514,6 +2566,38 @@ function execution_plan_cancel(ctx) Однократная отмена выполнения всех следующих инстансов внутри профиля. Инстанс, выполняющий отмену, берет на себя координацию дальнейших действий и называется оркестратором. +### Управление таймерами + +Функции создания и удаления таймера могут быть вызваны из любого Lua кода. +Это может быть lua-init, lua-desync или таймер функция. Таймер функция может в том числе действовать в отношении себя самой - +заменить период или прекратить собственные вызовы. + +Таймеры идентифицируются именем. Несколько таймеров с разными именами могут вызывать одну и ту же таймер-функцию. +Ей будет [передано](#прототип-функции-таймера) имя таймера и произвольные данные в качестве параметров. + +#### timer_set + +Создать или заменить таймер. + +``` +function timer_set(name, func, period, oneshot, data) +``` + +* name - уникальное имя таймера. если таймер с таким именем уже есть, он удаляется и замещается новым. При замещении отсчет времени начинается заново. +* func - имя таймер функции (string) +* period - периодичность вызова таймера в миллисекундах (см. [разрешение таймеров](#таймеры)) +* oneshot - bool признак является ли таймер однократным (true) или периодическим (false) +* data - произвольная переменная, передаваемая [таймер-функции](#прототип-функции-таймера) + +#### timer_del + +Удалить таймер. + +``` +function timer_del(name) +``` + + # Библиотека базовых функций zapret-lib.lua Почти каждая функция имеет подробные комментарии о своем предназначении и параметрах.