Нестандартное применение ipset

Как выяснилось, поиск строк в потоке 500Мбит/с оказался достаточно накладным.

Был сделан велосипед из achocorasick из nDPI и ipset.

Функционал аналогичен модулю "string" из iptables (с поддержкой hex-string)

Из недостатков: на каждую букву в строки уходит не меннее 32 байт (для x86_64), если элемент дерева содержит более одного символа, то расходы увеличиваются: 68 байт + (72 байт на каждые 8 символов). Добавление/удаление строки требует перестройки всего дерева (чем оно больше, тем длительнее процесс)

Если можно было бы отследить момент начала использования набора (ref > 0), то можно было бы существенно с ократить расходы на добавление строк. Смысл в том, что из строк сначала строится дерево, которое потом хитрым образом преобразовывается. Именно это преобразование занимает много времени при большом дереве.

Особенности реализации

Набор может быть с счетчиком

ipset create NNN string counters

Конструкция |xx| заменяется байтом с кодом 0xXX, для последовательности из нескольких байт можно использовать конструкцию |xxxxxx| (число символов должно быть четным), для поиска символа '|' используте экранирование '\|'

ipset add NNN "abcde|0a00|efg\|"

Длина строки не более 256 символов (126 если используется hex).

Если счетчик не используется, то поиск слов прекращается после первого совпадения.

Если счетчик используется, то поиск производится по всему содержимому пакета. Т.е. если в пакете встретились несколько слов, то они все будут подсчитаны.

Для протоколов IPv4/{tcp,udp,icmp} будет пропущены заголовки сетевого и транспортного уровня.
Для всех остальных пакетов поиск будет с начала сетевого заголовка.
Я пока не понял как правильно найти данные в IPv6 с несколькими фрагментами :(

Тестировался только на ядрах 4.14.x (x86_64)