Site Tools


software:freebsd:ng_utp

FreeBSD uTP (udp torrent) netgraph node

Средство для работы с uTP проколом, заменяет uTPControl - block uTP torrent proto

Скачать: ng_utp
Лицензия: BSD

Возможности

Нода может работать на хуках:

  • L2 - (ng_ether и др) Ethernet, есть поддержка вланов: все тегированные пакеты обрабатываются в нормальном режиме, дополнительных действий не требуется, ограничений на количество вланов нет;
  • L3 - (ng_ipfw и др) IPv4, IPv6 (пока не реализовано).

Одну ноду одновременно можно подключать к различным источниками трафика, как L2 так и L3 одновременно, ограничений нет.

На основании таблицы соединений можно:

  • маркировать пакеты на L2 (PCP для тегированных пакетов 802.1P);
  • маркировать пакеты на L3 (ip_tos - DSCP);
  • уничтожать (drop);
  • заменять на uTP RST;
  • не производить никаких действий с пакетами - мониторинг/тестирование.

Принцип работы

uTP имеет достаточно чёткие сигнатуры только в пакетах установления соединения SYN и ответном STATE: 14 байт из 38 или 41 байта в зависимости от версии протокола. После установления uTP соединения передаются DATA и STATE, которые имеют меньше неизменных данных для сигнатур.
Блокировать или изменять приоритет по таким признакам чревато массой ложный срабатываний.

ng_utp отслеживает utp_conn - connid uTP (2 или 4 байта) пакетов, привязанных к ip_conn (IP src, IP dst, UDP src port, UDP dst port), а также то какого типа пакеты были отправлены, сколько пакетов с каждой стороны уже было отправлено и когда был отправлен последний пакет с каждой стороны. Обычно на одно ip_conn приходится 1-2 utp_conn, иногда больше.

Первый пакет - SYN (если нода выключена до начала обмена uTP пакетами) проходит ноду создавая (если такого ещё нет) ip_conn и внутри него utp_conn, при этом действий с пакетом не происходит и он не считается как uTP. Когда в ответ приходит STATE, который относится к тому же ip_conn (по src/dst IP и sport/dport UDP) и utp_conn (по connid uTP), то такой пакет считается uTP трафиком и к нему применяются действия в соответствии с настройками.
Если трафик через ноду перенаправили после того как uTP соединения установились то на работу ноды это не влияет: для неё важен двух сторонний обмен uTP пакетами. Нода выполняет действия определённые фильтром над: DATA и STATE uTP пакетами и не выполняет действий для FIN, RESET, SYN.
Результатом работы является выстраивание таблицы соединений IP-UDP-uTP (L3-L4-L5).
Таблица единая для экземпляра ноды и доступна/пополняется со всех хуков-фильтров.

Работа с нодой

Конфигурация

NGM_UTP_GET_NODE_CFG(“getcfg”) - прочитать конфигурацию.
NGM_UTP_SET_NODE_CFG(“setcfg”) - установить новые параметры конфигурации.

Параметры

  • ip_conns_max (uint32_t) - максимальное количество отслеживаемых L3-L4 соединений.
  • utp_conns_max (uint32_t) - максимальное количество отслеживаемых uTP (L5) внутри L3-L4 соединений, должно быть больше ip_conns_max.
  • conn_ack_timeout (uint32_t) - время (секунды) в течении которого должен придти ответный uTP пакет в соединении. Если пакет пришёл позднее - действия не применяются.
  • conn_idle_timeout (uint32_t) - максимальное время (секунды) не активности после которого соединение удаляется из таблицы.
ngctl msg ipfw:1000 getcfg
Rec'd response "getcfg" (1) from "[1a]:":
Args:   { conn_ack_timeout=30 conn_idle_timeout=60 }

Статус ноды

NGM_UTP_GET_NODE_STATUS(“getstatus”) - возвращает текущее состояние ноды
Все счётчики uint64_t.

  • ipv4_conns - количество IPv4+UDPv4 соединений в таблице
  • ipv6_conns - количество IPv6+UDPv6 соединений в таблице
  • ip_conns_total - общее количество IP+UDP соединений, сумма двух предыдущих
  • ip_conns_max - максимально возможное количество IP+UDP соединений. Обычно чуть больше или равно тому что задано в конфиге.
  • utpv0_conns - количество utp v0 соединений в таблице
  • utpv1_conns - количество utp v1 соединений в таблице
  • utp_conns_total - общее количество utp соединений, сумма двух предыдущих
  • utp_conns_max - максимально возможное количество utp соединений. Обычно чуть больше или равно тому что задано в конфиге.
  • mem_ip_conns - всего памяти использовано для хранения информации об IP-UDP соединениях
  • mem_utp_conns - всего памяти использовано для хранения информации об uTP соединениях
  • mem_total - всего памяти, сумма двух предыдущих
ngctl msg ipfw:1000 getstatus
Rec'd response "getstatus" (3) from "[1a]:":
Args:   { ipv4_conns=85 ip_conns_total=85 ip_conns_max=100021 utpv0_conns=2 utpv1_conns=85 utp_conns_total=87 utp_conns_max=400008 mem_ip_conns=10880 mem_utp_conns=5568 mem_total=16448 }

Статистика ноды

NGM_UTP_GET_NODE_STAT(“getstat”) - получить
NGM_UTP_CLR_NODE_STAT(“clrstat”) - очистить
NGM_UTP_GETCLR_NODE_STAT(“getclrstat”) - получить и очистить
Все счётчики uint64_t.

  • ipv4_conns - всего IPv4 соединений было добавлено в таблицу
  • ipv6_conns - всего IPv6 соединений было добавлено в таблицу
  • ip_conns_total - всего IP соединений, сумма двух предыдущих
  • utpv0_conns - всего uTPv0 соединений было добавлено в таблицу
  • utpv1_conns - всего uTPv1 соединений было добавлено в таблицу
  • utp_conns_total - всего uTP соединений, сумма двух предыдущих
  • memoryFailures - ошибок выделения памяти
ngctl msg ipfw:1000 getstat
Rec'd response "getstat" (4) from "[1a]:":
Args:   { ipv4_conns=399 ip_conns_total=399 utpv0_conns=46 utpv1_conns=397 utp_conns_total=443 }

Очистка таблицы соединений IP-UDP

NGM_UTP_FLUSH_CONN4 (“flushconn4”) - IPv4
NGM_UTP_FLUSH_CONN6 (“flushconn6”) - IPv6

ngctl msg ipfw:1000 flushconn4

Дамп таблицы соединений IP-UDP

NGM_UTP_GET_CONN_TABLE4 (“getconntbl4”) - IPv4
NGM_UTP_GET_CONN_TABLE6 (“getconntbl6”) - IPv6 - не реализовано.

ngctl msg ipfw:1000 getconntbl4
Rec'd response "getconntbl4" (12) from "[1a]:":
Args:   { count=46 conn_entryes=[ { 
saddr=178.236.129.230 daddr=172.16.0.3 sport=46537 dport=40443 conns=1 } { 
saddr=91.223.178.3 daddr=172.16.0.3 sport=32786 dport=40443 conns=2 lifetime=46 idle=9 } { 
saddr=81.9.62.210 daddr=172.16.0.3 sport=56690 dport=40443 conns=1 lifetime=54 idle=39 } { 
...
saddr=78.30.247.193 daddr=172.16.0.3 sport=45070 dport=40443 conns=1 lifetime=75 idle=54 } { 
saddr=95.25.30.128 daddr=172.16.0.3 sport=54682 dport=40443 conns=1 lifetime=91 idle=54 } { 
saddr=188.32.168.23 daddr=172.16.0.3 sport=50022 dport=40443 conns=1 lifetime=120 idle=30 } ] }

Добавление фильтра

NGM_UTP_ADD_FILTER(“addfilter”) - добавить L2:Ethernet или L3:IPv4/IPv6 фильтр

l3_proto (uint16_t) - тип фильтра: 0 в случае ethernet, 0x0800 - для IPv4, 0x86DD - для IPv6
action (uint16_t) - действие выполняемое фильтром:

  • 0 - UTP_FLT_ACCTION_PASS - ничего не делать с uTP, только выстраивать таблицу соединений
  • 1 - UTP_FLT_ACCTION_PASS_MARK - маркировать все uTP пакеты относящиеся к uTP соединениям (см флаги UTP_FLT_FLAG_MARK_L2 и UTP_FLT_FLAG_MARK_L3)
  • 2 - UTP_FLT_ACCTION_DROP - уничтожать все uTP пакеты относящиеся к uTP соединениям
  • 3 - UTP_FLT_ACCTION_SND_RST - заменять на uTP RST все uTP пакеты относящиеся к uTP соединениям

flags (uint32_t) - флаги:

  • 0x00000001 - UTP_FLT_FLAG_FORCE_QUEUE_H0
  • 0x00000002 - UTP_FLT_FLAG_FORCE_QUEUE_H1 - принудительно использовать очередь для хука в фильтре. Включение очередей может помочь равномерно распределять нагрузку между процессорами.
  • 0x00000004 - UTP_FLT_FLAG_NO_PASS - не пропускать транзитом, только сгенерированные RST будут отправлены
  • 0x00000010 - UTP_FLT_FLAG_MARK_L2 - маркировать на L2 пакеты относящиеся к uTP соединениями. Действие фильтра должно быть UTP_FLT_ACCTION_PASS_MARK. Метка - PCP хранится в label_l2, первые 3 бита.
  • 0x00000020 - UTP_FLT_FLAG_MARK_L3 - маркировать на L3 пакеты относящиеся к uTP соединениями. Действие фильтра должно быть UTP_FLT_ACCTION_PASS_MARK. Метка - DSCP хранится в label_l3, первые 6 бит.
  • 0x00000100 - UTP_FLT_FLAG_CSUM_IP_CHK - проверять контрольную сумму IPv4 пакетов.
  • 0x00000200 - UTP_FLT_FLAG_CSUM_UDP_CHK - проверять контрольную сумму UDP пакетов.
  • 0x00000400 - UTP_FLT_FLAG_CSUM_UDP_NO_CSUMM - не рассчитывать контрольную сумму для сгенерированных uTP RST пакетов.

label_l2 (uint8_t) - L2 - Priority Code Point метка пакета, первые 3 бита.
label_l3 (uint8_t) - L3 ip_tos/Traffic Class code (rfc2474) метка пакета, первые 6 бит.
h0 (char) -
h1 (char) - имя хука добавляемого в фильтр

Для L2:

ngctl mkpeer vlan777: utp lower lower
ngctl connect vlan777: vlan777:lower upper upper
ngctl msg vlan777:lower addfilter '{ l3_proto=0 action=3 flags=0x00000000 h0="lower" h1="upper" }'

Для L3-IPv4:

ngctl mkpeer ipfw: utp 1000 in
ngctl connect ipfw: ipfw:1000 1001 out
ngctl msg ipfw:1000 addfilter '{ l3_proto=0x0800 action=3 flags=0x00000000 h0="in" h1="out" }'

(здесь по идее достаточно одного хука, но такое “одноногое” поведение пока не реализовано)

Получить настройки фильтра

NGM_UTP_GET_FILTER (“getfilter”) - получить настройки фильтра по имени одного из хуков, который в него входит.

ngctl msg ipfw:1000 getfilter '"io"'
Rec'd response "getfilter" (13) from "[46]:":
Args:   { l3_proto=0x800 action=3 flags=0x3 h0="io" }

Удаление фильтра

NGM_UTP_DEL_FILTER (“delfilter”) - удалить фильтр по имени одного из хуков, который в него входит, хуки при этом не отключаются от нод

ngctl msg ipfw:1000 delfilter '"in"'

Статистика фильтра

NGM_UTP_GET_FILTER_STATS (“getfilterstats”)
NGM_UTP_CLR_FILTER_STATS (“clrfilterstats”)
NGM_UTP_GETCLR_FILTER_STATS (“getclrfilterstats”)
Все счётчики uint64_t.

  • Octets - байт прошло через фильтр.
  • Packets - количество пакетов прошедших через фильтр.
  • IPv4_Packets - количество IPv4 пакетов прошедших через фильтр.
  • IPv6_Packets - количество IPv6 пакетов прошедших через фильтр.
  • MatchedPackets - пакеты опознанные как uTP, к которым были применены действия.
  • BypassPackets - пакетов прошедшие через фильтр без изменений.
  • DroppedPackets - отброшенные пакеты.
  • recvErrors - ошибки приёма: отсутствует заголовок, не удалось выделить память, неправильный заголовок, ошибочная контрольная сумма и тп.
  • xmitErrors - ошибки отправки.
ngctl msg ipfw:1000 getfilterstats '"in"'
Rec'd response "getfilterstats" (9) from "[1a]:":
Args:   { Octets=5982246 Packets=38489 IPv4_Packets=38492 MatchedPackets=8760 BypassPackets=38978 recvErrors=8760 }

Проверка работоспособности

software/freebsd/ng_utp.txt · Last modified: 2022/02/05 04:19 by root