Zapret: what's new

Несколько тестов скорости ипсетов , реализованных в tpws/nfqws, чтобы примерно представлять степень их эффективности.

Тестовая схема : загоняем 100000 случайных записей со случайным prefix length в диапазоне 16-128 для ipv6, 16-32 для ipv4.
Выполняем 100000 проверок на вхождение случайного адреса. Вычисляем время выполнения, из него высчитываем пропорцией количество проверок за секунду.

core i7 12700K : ipv4 1000000/s ipv6 125000/s
MT7621 : ipv4 29000/s ipv6 8300/s

Почему так отличается ? Потому что для проверки ipv6 нужно 128 проверок по hash, а для ipv4 - 32 проверки. Возросшая длина ключа с 8 до 20 байт, для которого считается hash, дополнительная операция ip6_and для 16 байт по пред-вычисленной маске подсети.
К тому же имеет значение вероятность попадания тестового адреса в ipset. Как только попадание случилось, дальнейшая проверка по другим маскам подсетей останавливается.
Но примерную картину себе представить можно.

Вероятно, реализация не самая эффективная, но есть как есть.
К счастью, операция проверки выполняется не на каждый пакет, если задействован conntrack. Выбранный профиль запоминается, перепроверка профиля происходит только при появлении имени хоста или опознавании L7 протокола.

Проблема бездумного использования ipset есть, но она не связана с эффективностью алгоритма ipset в tpws/nfqws, а связана с тяжелым процессом перенаправления трафика из ядра в процесс.

Если у вас есть стратегия для https, но надо еще и сделать частный случай для cloudflare, написать --ipset можно без проблем. Это удобно, не надо мучаться с поднятием отдельного инстанса через кастом скрипт.

Но если у вас появляется условный discord на порту udp 50000, а не дай бог еще и 50000-65535, и вам ничего больше оттуда не надо, вы не используете ограничитель в ядре connbytes (например, перенаправление идет через NFQWS_PORTS_UDP_KEEPALIVE или вовсе без скриптов запуска zapret, своими правилами для таблиц) и вы пишите --ipset, то это плохо. Пошел торент, попал на эти порты, и ваш nfqws мучается. А так бы в ядре сразу отсекалось по ipset-у ядра, и на nfqws даже не приходило.
ipset-ы ядра есть на всех системах , кроме windows. На windows при небольшом количестве адресов эти адреса можно загнать в собственный windivert фильтр --wf-raw, который можно построить на базе фильтра, генерируемого winws (–wf-save)

UPD. Ипсеты перведены но другой способ хранения в памяти с использованием AVL tree.
Эффективность по CPU выше в десятки раз, тк там нужна только одна проверка, а не до 32 или до 128, когда применялся hash поиск по равенству