mirror of
https://github.com/bol-van/zapret.git
synced 2025-04-15 11:32:58 +03:00
Merge branch 'bol-van:master' into master
This commit is contained in:
commit
854218e82e
@ -125,3 +125,13 @@ resolve_lower_devices()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default_route_interfaces6()
|
||||
{
|
||||
sed -nre 's/^00000000000000000000000000000000 00 [0-9a-f]{32} [0-9a-f]{2} [0-9a-f]{32} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} +(.*)$/\1/p' /proc/net/ipv6_route | grep -v '^lo$' | sort -u | xargs
|
||||
}
|
||||
|
||||
default_route_interfaces4()
|
||||
{
|
||||
sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ Later you will add ipfw commands to `/etc/rc.firewall.my` to be reapplied after
|
||||
You can also run zapret daemons from there. Start them with `--daemon` options, for example
|
||||
```
|
||||
pkill ^dvtws$
|
||||
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=split2
|
||||
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
To restart firewall and daemons run : `/etc/rc.d/ipfw restart`
|
||||
@ -157,7 +157,7 @@ ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
|
||||
# required for autottl mode only
|
||||
ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
Process only table zapret with the exception of table nozapret:
|
||||
@ -167,7 +167,7 @@ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||
ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0
|
||||
# required for autottl mode only
|
||||
ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
Reinjection loop avoidance. FreeBSD artificially ignores sockarg for ipv6 in
|
||||
@ -245,7 +245,7 @@ sysctl net.inet6.ip6.pfil.inbound=ipfw,pf
|
||||
ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
|
||||
pkill ^dvtws$
|
||||
dvtws --daemon --port 989 --dpi-desync=split2
|
||||
dvtws --daemon --port 989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
|
||||
# required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state
|
||||
pfctl -d ; pfctl -e
|
||||
@ -280,7 +280,7 @@ Autostart `/usr/local/etc/rc.d/zapret.sh`:
|
||||
```
|
||||
pfctl -a zapret -f /etc/zapret.anchor
|
||||
pkill ^tpws$
|
||||
tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-http-req=method --split-pos=2
|
||||
tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-pos=2
|
||||
```
|
||||
|
||||
After reboot check that anchor is created and referred from the main ruleset:
|
||||
@ -342,7 +342,7 @@ pass out quick on em0 proto tcp to port {80,443} divert-packet port 989
|
||||
Then:
|
||||
```
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
`dwtws` only for table zapret with the exception of table nozapret :
|
||||
@ -375,7 +375,7 @@ pass out quick on em0 inet6 proto tcp to <zapret6-user> port {80,443} divert-p
|
||||
Then:
|
||||
```
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
divert-packet automatically adds the reverse rule. By default also incoming
|
||||
|
@ -372,7 +372,7 @@ nfqws: --dpi-desync-split-http-req, --dpi-desync-split-tls deprecated. compat :
|
||||
nfqws: --dpi-desync=split2|disorder2 deprecated. compat: they are now synonyms for multisplit/multidisorder
|
||||
nfqws: cancel seqovl if MTU is exceeded (linux only). cancel seqovl for disorder if seqovl>=first_part_size.
|
||||
nfqws: fixed splits in multiple TLS segments.
|
||||
tpws: --split-tls,--split-tls deprecated. compat : these parameters add split point to multisplit.
|
||||
tpws: --split-http-req,--split-tls deprecated. compat : these parameters add split point to multisplit.
|
||||
tpws: --tlsrec now takes pos markers. compat : old names are converted to pos markers
|
||||
tpws: --tlsrec-pos deprecated. compat : sets absolute pos marker
|
||||
nfqws,tpws: chown autohostlist, autohostlist debug log and debug log files after options parse
|
||||
|
@ -12,7 +12,7 @@ iptables -t mangle -I POSTROUTING -p udp --dport 443 -m mark ! --mark 0x40000000
|
||||
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||
iptables -t mangle -I POSTROUTING -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:12 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I PREROUTING -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I PREROUTING -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
|
||||
|
||||
For TPROXY :
|
||||
|
@ -19,8 +19,8 @@ For dpi desync attack :
|
||||
nft delete table inet ztest
|
||||
nft create table inet ztest
|
||||
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-12 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass
|
||||
|
||||
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||
|
File diff suppressed because it is too large
Load Diff
106
docs/readme.md
106
docs/readme.md
@ -325,9 +325,9 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
|
||||
* **method** - начало метода HTTP ('GET', 'POST', 'HEAD', ...). Метод обычно всегда находится на позиции 0, но поддерживается и нахождение метода после дурение методом `--methodeol` от tpws. Тогда позиция может стать 1 или 2.
|
||||
* **host** - начало имени хоста в известном протоколе (http, TLS)
|
||||
* **endhost** - конец имени хоста
|
||||
* **endhost** - байт, следующий за последним байтом имени хоста
|
||||
* **sld** - начало домена 2 уровня в имени хоста
|
||||
* **endsld** - конец домена 2 уровня в имени хоста
|
||||
* **endsld** - байт, следующий за последним байтом домена 2 уровня в имени хоста
|
||||
* **midsld** - середина домена 2 уровня в имени хоста
|
||||
* **sniext** - начало поля данных SNI extension в TLS. Любой extension состоит из 2-байтовых полей type и length, за ними идет поле данных.
|
||||
|
||||
@ -381,7 +381,7 @@ Windows оставляет старые данные, поэтому disorder с
|
||||
|
||||
### СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6
|
||||
|
||||
Режимы десинхронизации `hopbyhop`, `destopt` и `ipfrag1` (не путать с fooling !) относятся только к `ipv6` и заключается
|
||||
Режимы десинхронизации `hopbyhop`, `destopt` и `ipfrag1` (не путать с fooling !) относятся только к ipv6 и заключается
|
||||
в добавлении хедера `hop-by-hop options`, `destination options` или `fragment` во все пакеты, попадающие под десинхронизацию.
|
||||
Здесь надо обязательно понимать, что добавление хедера увеличивает размер пакета, потому не может быть применено
|
||||
к пакетам максимального размера. Это имеет место при передаче больших сообщений.
|
||||
@ -398,7 +398,7 @@ extension хедерам в поисках транспортного хедер
|
||||
|
||||
В параметре dpi-desync можно указать до 3 режимов через запятую.
|
||||
|
||||
* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata` `--wsize`, `--wssize`. На эту фазу не действуют фильтры по [hostlist](((#множественные-стратегии))).
|
||||
* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata`, `--wsize`, `--wssize`. На эту фазу не действуют фильтры по [hostlist](#множественные-стратегии).
|
||||
* 1 фаза - отсылка чего-либо до оригинального пакета данных : `fake`, `rst`, `rstack`.
|
||||
* 2 фаза - отсылка в модифицированном виде оригинального пакета данных (например, `fakedsplit` или `ipfrag2`).
|
||||
|
||||
@ -424,29 +424,10 @@ DPI может отстать от потока, если ClientHello его у
|
||||
|
||||
В документации по geneva это называется "TCB turnaround". Попытка ввести DPI в заблуждение относительно
|
||||
ролей клиента и сервера.
|
||||
!!! Поскольку режим нарушает работу NAT, техника может сработать только если между атакующим устройством
|
||||
|
||||
Поскольку режим нарушает работу NAT, техника может сработать только если между атакующим устройством
|
||||
и DPI нет NAT. Атака не сработает через NAT роутер, но может сработать с него.
|
||||
Для реализации атаки в linux обязательно требуется отключить стандартное правило firewall,
|
||||
дропающее инвалидные пакеты в цепочке OUTPUT. Например : `-A OUTPUT -m state --state INVALID -j DROP`
|
||||
В openwrt можно отключить drop INVALID в OUTPUT и FORWARD через опцию в /etc/config/firewall:
|
||||
|
||||
```
|
||||
config zone
|
||||
option name 'wan'
|
||||
.........
|
||||
option masq_allow_invalid '1'
|
||||
```
|
||||
|
||||
К сожалению, отключить только в OUTPUT таким образом нельзя. Но можно сделать иначе. Вписать в `/etc/firewall.user`:
|
||||
|
||||
```
|
||||
iptables -D zone_wan_output -m comment --comment '!fw3' -j zone_wan_dest_ACCEPT
|
||||
ip6tables -D zone_wan_output -m comment --comment '!fw3' -j zone_wan_dest_ACCEPT
|
||||
```
|
||||
|
||||
Лучше делать так, потому что отсутствие дропа INVALID в FORWARD может привести к нежелательным утечкам пакетов из LAN.
|
||||
Если не принять эти меры, отсылка SYN,ACK сегмента вызовет ошибку и операция будет прервана.
|
||||
Остальные режимы тоже не сработают. Если поймете, что вам synack не нужен, обязательно верните правило дропа INVALID.
|
||||
Для реализации атаки на проходящий трафик требуются nftables и схема [POSTNAT](#nftables-для-nfqws).
|
||||
|
||||
### РЕЖИМ SYNDATA
|
||||
|
||||
@ -480,7 +461,7 @@ conntrack - простенький, он не писался с учетом в
|
||||
|
||||
`--wssize` позволяет изменить с клиента размер tcp window для сервера, чтобы он послал следующие ответы разбитыми на части.
|
||||
Чтобы это подействовало на все серверные ОС, необходимо менять window size в каждом исходящем с клиента пакете до отсылки сообщения,
|
||||
ответ на который должен быть разбит (например, TLS ClientHello). Именно поэтому и необходим conntrack, чтобы
|
||||
ответ на которое должен быть разбит (например, TLS ClientHello). Именно поэтому и необходим conntrack, чтобы
|
||||
знать когда надо остановиться. Если не остановиться и все время устанавливать низкий wssize, скорость упадет катастрофически.
|
||||
В linux это может быть купировано через connbytes, но в BSD системах такой возможности нет.
|
||||
В случае http(s) останавливаемся сразу после отсылки первого http запроса или TLS ClientHello.
|
||||
@ -521,7 +502,7 @@ nfqws поддерживает реассемблинг некоторых ви
|
||||
На текущий момент это TLS и QUIC ClientHello. Они бывает длинными, если в chrome включить пост-квантовую
|
||||
криптографию tls-kyber, и занимают как правило 2 или 3 пакета. kyber включен по умолчанию, начиная с chromium 124.
|
||||
chrome рандомизирует фингерпринт TLS. SNI может оказаться как в начале, так и в конце, то есть
|
||||
попасть любой пакет. stateful DPI обычно реассемблирует запрос целиком, и только потом
|
||||
попасть в любой пакет. stateful DPI обычно реассемблирует запрос целиком, и только потом
|
||||
принимает решение о блокировке.
|
||||
В случае получения TLS или QUIC пакета с частичным ClientHello начинается процесс сборки, а пакеты
|
||||
задерживаются и не отсылаются до ее окончания. По окончании сборки пакеты проходит через десинхронизацию
|
||||
@ -614,7 +595,7 @@ options ip6table_raw raw_before_defrag=1
|
||||
|
||||
### МНОЖЕСТВЕННЫЕ СТРАТЕГИИ
|
||||
|
||||
`nfqws` способен по-разному реагировать на различные запросы и применять разные стратегии дурения.
|
||||
**nfqws** способен по-разному реагировать на различные запросы и применять разные стратегии дурения.
|
||||
Это реализовано посредством поддержки множества профилей дурения.
|
||||
Профили разделяются в командной строке параметром `--new`. Первый профиль создается автоматически.
|
||||
Для него не нужно `--new`. Каждый профиль имеет фильтр. По умолчанию он пуст, то есть профиль удовлетворяет
|
||||
@ -680,10 +661,9 @@ mark нужен, чтобы сгенерированный поддельный
|
||||
* 4-6 - на случай ретрансмиссии или запроса длиной в несколько пакетов (TLSClientHello с kyber, например)
|
||||
|
||||
Для режима autottl необходимо перенаправление входящего `SYN,ACK` пакета или первого пакета соединения (что обычно есть тоже самое).
|
||||
Можно построить фильтр на tcp flags и модуле u32 для поиска характерных паттернов http redirect, но проще использовать connbytes.
|
||||
|
||||
Для режима autohostlist необходимо перенаправление нескольких входящих пакетов, чтобы засечь RST или http redirect.
|
||||
Так же стоит увеличить лимит исходящих пакетов в connbytes, чтобы в него вошли все возможные ретрансмиссии, после которых идет реакция по autoostlist.
|
||||
Для режима autohostlist необходимы входящие RST и http redirect.
|
||||
Можно построить фильтр на tcp flags для выделения `SYN,ACK` и модуле u32 для поиска характерных паттернов http redirect,
|
||||
но проще использовать connbytes для выделения нескольких начальных входящих пакетов.
|
||||
|
||||
`
|
||||
iptables -t mangle -I PREROUTING -i <внешний интерфейс> -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
@ -812,7 +792,7 @@ tpws - это transparent proxy.
|
||||
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
|
||||
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
|
||||
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
|
||||
--fix-seg ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления
|
||||
--fix-seg=<int> ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления. ждать до N мс. по умолчанию 30 мс.
|
||||
|
||||
--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации
|
||||
--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS)
|
||||
@ -881,12 +861,16 @@ tpws, как и nfqws, поддерживает множественную се
|
||||
Как показывается практика, проблемы могут начаться , если количество сплит позиций превышает 8.
|
||||
При неудаче сегментации будет выводиться сообщение `WARNING ! segmentation failed`.
|
||||
Если вы его видите, это повод снизить количество сплит позиций.
|
||||
Если это не вариант, есть параметр `--fix-seg`. Он позволяет подождать завершение отсылки перед отправкой следующей части.
|
||||
Если это не вариант, для ядер Linux >=4.6 есть параметр `--fix-seg`. Он позволяет подождать завершение отсылки перед отправкой следующей части.
|
||||
Но этот вариант ломает модель асинхронной обработки событий. Пока идет ожидание, все остальные соединения не обрабатываются
|
||||
и кратковременно подвисают. На практике это может быть совсем небольшое ожидание - менее 10 мс.
|
||||
И производится оно только , если происходит split, и в ожидании есть реальная необходимость.
|
||||
В высоконагруженных системах данный вариант не рекомендуется. Но для домашнего использования может подойти, и вы эти задержки даже не заметите.
|
||||
|
||||
Если вы пытаетесь сплитнуть массивную передачу с `--split-any-protocol`, когда информация поступает быстрее отсылки,
|
||||
то без `--fix-seg` ошибки сегментации будут сыпаться сплошным потоком.
|
||||
Работа по массивному потоку без ограничителей `--tamper-start` и `--tamper-cutoff` обычно лишена смысла.
|
||||
|
||||
tpws работает на уровне сокетов, поэтому длинный запрос, не вмещающийся в 1 пакет (TLS с kyber), он получает целым блоком.
|
||||
На каждую сплит часть он делает отдельный вызов `send()`. Но ОС не сможет отослать данные в одном пакете, если размер превысит MTU.
|
||||
В случае слишком большого сегмента ОС дополнительно его порежет на более мелкие. Результат должен быть аналогичен nfqws.
|
||||
@ -947,8 +931,8 @@ tpws работает на уровне сокетов, поэтому длин
|
||||
|
||||
### МНОЖЕСТВЕННЫЕ СТРАТЕГИИ
|
||||
|
||||
Работают аналогично `nfqws`, кроме некоторых моментов.
|
||||
Нет параметра `--filter-udp`, поскольку `tpws` udp не поддерживает.
|
||||
Работают аналогично **nfqws**, кроме некоторых моментов.
|
||||
Нет параметра `--filter-udp`, поскольку **tpws** udp не поддерживает.
|
||||
Методы нулевой фазы (`--mss`) могут работать по хостлисту в одном единственном случае:
|
||||
если используется режим socks и удаленный ресолвинг хостов через прокси.
|
||||
То есть работоспособность вашей настройки в одном и том же режиме может зависеть от того,
|
||||
@ -1056,7 +1040,7 @@ iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j DROP
|
||||
```
|
||||
|
||||
Фильтр по owner необходим для исключения рекурсивного перенаправления соединений от самого tpws. tpws запускается под
|
||||
пользователем `tpws`, для него задается исключающее правило.
|
||||
пользователем **tpws**, для него задается исключающее правило.
|
||||
|
||||
ip6tables работают почти точно так же, как и ipv4, но есть ряд важных нюансов. В DNAT следует брать адрес --to в
|
||||
квадратные скобки. Например :
|
||||
@ -1287,7 +1271,7 @@ mdig --family=6 --dns-make-query=rutracker.org | curl --data-binary @- -H "Conte
|
||||
и 1 exclude список
|
||||
`ipset/zapret-hosts-users-exclude.txt.gz` или `ipset/zapret-hosts-users-exclude.txt`
|
||||
|
||||
При режимах фильтрации `MODE_FILTER=hostlist` или `MODE_FILTER=autohostlist` система запуска передает `nfqws` или `tpws` все листы, файлы которых присутствуют.
|
||||
При режимах фильтрации `MODE_FILTER=hostlist` или `MODE_FILTER=autohostlist` система запуска передает **nfqws** или **tpws** все листы, файлы которых присутствуют.
|
||||
Передача происходит через замену маркеров `<HOSTLIST>` и `<HOSTLIST_NOAUTO>` на реальные параметры `--hostlist`, `--hostlist-exclude`, `--hostlist-auto`.
|
||||
Если вдруг листы include присутствуют, но все они пустые, то работа аналогична отсутствию include листа.
|
||||
Файл есть, но не смотря на это дурится все, кроме exclude.
|
||||
@ -1316,21 +1300,21 @@ tpws и nfqws решают нужно ли применять дурение в
|
||||
Этот режим позволяет проанализировать как запросы со стороны клиента, так и ответы от сервера.
|
||||
Если хост еще не находится ни в каких листах и обнаруживается ситуация, похожая на блокировку,
|
||||
происходит автоматическое добавление хоста в список `autohostlist` как в памяти, так и в файле.
|
||||
`nfqws` или `tpws` сами ведут этот файл.
|
||||
**nfqws** или **tpws** сами ведут этот файл.
|
||||
Чтобы какой-то хост не смог попась в `autohostlist` используйте `hostlist-exclude`.
|
||||
Если он все-же туда попал - удалите запись из файла вручную. Процессы автоматически перечитают файл.
|
||||
`tpws`/`nfqws` сами назначают владельцем файла юзера, под которым они работают после сброса привилегий,
|
||||
**tpws**/**nfqws** сами назначают владельцем файла юзера, под которым они работают после сброса привилегий,
|
||||
чтобы иметь возможность обновлять лист.
|
||||
|
||||
В случае `nfqws` данный режим требует перенаправления в том числе и входящего трафика.
|
||||
Крайне рекомендовано использовать ограничитель `connbytes`, чтобы `nfqws` не обрабатывал гигабайты.
|
||||
В случае **nfqws** данный режим требует перенаправления в том числе и входящего трафика.
|
||||
Крайне рекомендовано использовать ограничитель `connbytes`, чтобы **nfqws** не обрабатывал гигабайты.
|
||||
По этой же причине не рекомендуется использование режима на BSD системах. Там нет фильтра `connbytes`.
|
||||
|
||||
На linux системах при использовании nfqws и фильтра connbytes может понадобится :
|
||||
`sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1`
|
||||
Было замечено, что некоторые DPI в России возвращают RST с неверным ACK. Это принимается tcp/ip стеком
|
||||
linux, но через раз приобретает статус INVALID в conntrack. Поэтому правила с `connbytes` срабатывают
|
||||
через раз, не пересылая RST пакет `nfqws`.
|
||||
через раз, не пересылая RST пакет **nfqws**.
|
||||
|
||||
Как вообще могут вести себя DPI, получив "плохой запрос" и приняв решение о блокировке:
|
||||
|
||||
@ -1340,7 +1324,7 @@ linux, но через раз приобретает статус INVALID в con
|
||||
4) Подмена сертификата: (только для https) полный перехват TLS сеанса с попыткой всунуть что-то
|
||||
свое клиенту. Применяется нечасто, поскольку броузеры на такое ругаются.
|
||||
|
||||
`nfqws` и `tpws` могут сечь варианты 1-3, 4 они не распознают.
|
||||
**nfqws** и **tpws** могут сечь варианты 1-3, 4 они не распознают.
|
||||
Всилу специфики работы с отдельными пакетами или с TCP каналом tpws и nfqws распознают эти ситуации
|
||||
по-разному.
|
||||
Что считается ситуацией, похожей на блокировку :
|
||||
@ -1371,7 +1355,7 @@ linux, но через раз приобретает статус INVALID в con
|
||||
незаблокированный сайт. Эту ситуацию, увы, придется вам контролировать вручную.
|
||||
Заносите такие домены в `ipset/zapret-hosts-user-exclude.txt`, чтобы избежать повторения.
|
||||
Чтобы впоследствии разобраться почему домен был занесен в лист, можно включить `autohostlist debug log`.
|
||||
Он полезен тем, что работает без постоянного просмотра вывода `nfqws` в режиме debug.
|
||||
Он полезен тем, что работает без постоянного просмотра вывода **nfqws** в режиме debug.
|
||||
В лог заносятся только основные события, ведущие к занесению хоста в лист.
|
||||
По логу можно понять как избежать ложных срабатываний и подходит ли вообще вам этот режим.
|
||||
|
||||
@ -1563,11 +1547,11 @@ nfqws начнет получать адреса пакетов из локал
|
||||
|
||||
`POSTNAT=0`
|
||||
|
||||
Существует 3 стандартных опции запуска, настраиваемых раздельно и независимо: `tpws-socks`, `tpws`, `nfqws`.
|
||||
Существует 3 стандартных опции запуска, настраиваемых раздельно и независимо: `tpws-socks`, **tpws**, **nfqws**.
|
||||
Их можно использовать как по отдельности, так и вместе. Например, вам надо сделать комбинацию
|
||||
из методов, доступных только в `tpws` и только в `nfqws`. Их можно задействовать вместе.
|
||||
`tpws` будет прозрачно локализовывать трафик на системе и применять свое дурение, `nfqws` будет дурить трафик,
|
||||
исходящий с самой системы после обработки на `tpws`.
|
||||
из методов, доступных только в **tpws** и только в **nfqws**. Их можно задействовать вместе.
|
||||
**tpws** будет прозрачно локализовывать трафик на системе и применять свое дурение, **nfqws** будет дурить трафик,
|
||||
исходящий с самой системы после обработки на **tpws**.
|
||||
А можно на эту же систему повесить без параметров socks proxy, чтобы получать доступ к обходу блокировок через прокси.
|
||||
Таким образом, все 3 режима вполне могут задействоваться вместе.
|
||||
Так же безусловно и независимо, в добавок к стандартным опциям, применяются все custom скрипты в `init.d/{sysv,openwrt,macos}/custom.d`.
|
||||
@ -1583,7 +1567,7 @@ nfqws начнет получать адреса пакетов из локал
|
||||
|
||||
Одновременное использование tpws и nfqws без пересечения по L3/L4 (то есть nfqws - udp, tpws - tcp или nfqws - port 443, tpws - port 80 или nfqws - ipv4, tpws - ipv6) проблем не представляет.
|
||||
|
||||
`tpws-socks` требует настройки параметров `tpws`, но не требует перехвата трафика.
|
||||
`tpws-socks` требует настройки параметров **tpws**, но не требует перехвата трафика.
|
||||
Остальные опции требуют раздельно настройки перехвата трафика и опции самих демонов.
|
||||
Каждая опция предполагает запуск одного инстанса соответствующего демона. Все различия методов дурения
|
||||
для `http`, `https`, `quic` и т.д. должны быть отражены через схему мультистратегий.
|
||||
@ -1881,7 +1865,7 @@ zapret_custom_firewall_v4
|
||||
zapret_custom_firewall_v6
|
||||
```
|
||||
|
||||
zapret_custom_daemons поднимает демоны `nfqws`/`tpws` в нужном вам количестве и с нужными вам параметрами.
|
||||
zapret_custom_daemons поднимает демоны **nfqws**/**tpws** в нужном вам количестве и с нужными вам параметрами.
|
||||
Для систем традиционного linux (sysv) и MacOS в первом параметре передается код операции: 1 = запуск, 0 = останов.
|
||||
Для openwrt логика останова отсутствует за ненадобностью.
|
||||
Схема запуска демонов в openwrt отличается - используется procd.
|
||||
@ -1910,7 +1894,7 @@ zapret_custom_firewall_nft поднимает правила nftables.
|
||||
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout,
|
||||
содержащий правила для pf-якоря. Остальное сделает обертка.
|
||||
|
||||
Особо обратите внимание на номер демона в функциях `run_daemon` и `do_daemon`, номера портов `tpws`
|
||||
Особо обратите внимание на номер демона в функциях `run_daemon` и `do_daemon`, номера портов **tpws**
|
||||
и очередей `nfqueue`.
|
||||
Они должны быть уникальными во всех скриптах. При накладке будет ошибка.
|
||||
Поэтому используйте функции динамического получения этих значений из пула.
|
||||
@ -1946,11 +1930,11 @@ zapret_custom_firewall_nft поднимает правила nftables.
|
||||
Имена интерфейсов WAN и LAN известны из настроек системы.
|
||||
Под другими системами роутер вы настраиваете самостоятельно. Инсталлятор в это не вмешивается.
|
||||
инсталлятор в зависимости от выбранного режима может спросить LAN и WAN интерфейсы.
|
||||
Нужно понимать, что заворот проходящего трафика на `tpws` в прозрачном режиме происходит до выполнения маршрутизации,
|
||||
Нужно понимать, что заворот проходящего трафика на **tpws** в прозрачном режиме происходит до выполнения маршрутизации,
|
||||
следовательно возможна фильтрация по LAN и невозможна по WAN.
|
||||
Решение о завороте на `tpws` локального исходящего трафика принимается после выполнения маршрутизации,
|
||||
Решение о завороте на **tpws** локального исходящего трафика принимается после выполнения маршрутизации,
|
||||
следовательно ситуация обратная: LAN не имеет смысла, фильтрация по WAN возможна.
|
||||
Заворот на `nfqws` происходит всегда после маршрутизации, поэтому к нему применима только фильтрация по WAN.
|
||||
Заворот на **nfqws** происходит всегда после маршрутизации, поэтому к нему применима только фильтрация по WAN.
|
||||
Возможность прохождения трафика в том или ином направлении настраивается вами в процессе конфигурации роутера.
|
||||
|
||||
Деинсталляция выполняется через `uninstall_easy.sh`. После выполнения деинсталляции можно удалить каталог `/opt/zapret`.
|
||||
@ -1978,7 +1962,7 @@ zapret_custom_firewall_nft поднимает правила nftables.
|
||||
|
||||
## Установка на openwrt в режиме острой нехватки места на диске
|
||||
|
||||
Требуется около 120-200 кб на диске. Придется отказаться от всего, кроме `tpws`.
|
||||
Требуется около 120-200 кб на диске. Придется отказаться от всего, кроме **tpws**.
|
||||
|
||||
**Инструкция для openwrt 22 и выше с nftables**
|
||||
|
||||
@ -1987,7 +1971,7 @@ zapret_custom_firewall_nft поднимает правила nftables.
|
||||
***Установка:***
|
||||
|
||||
1) Скопируйте все из `init.d/openwrt-minimal/tpws/*` в корень openwrt.
|
||||
2) Скопируйте бинарник `tpws` подходящей архитектуры в `/usr/bin/tpws`.
|
||||
2) Скопируйте бинарник **tpws** подходящей архитектуры в `/usr/bin/tpws`.
|
||||
3) Установите права на файлы: `chmod 755 /etc/init.d/tpws /usr/bin/tpws`
|
||||
4) Отредактируйте `/etc/config/tpws`
|
||||
* Если не нужен ipv6, отредактируйте `/etc/nftables.d/90-tpws.nft` и закомментируйте строки с редиректом ipv6.
|
||||
@ -2015,7 +1999,7 @@ zapret_custom_firewall_nft поднимает правила nftables.
|
||||
***Установка:***
|
||||
|
||||
1) Скопируйте все из `init.d/openwrt-minimal/tpws/*` в корень openwrt.
|
||||
2) Скопируйте бинарник `tpws` подходящей архитектуры в `/usr/bin/tpws`.
|
||||
2) Скопируйте бинарник **tpws** подходящей архитектуры в `/usr/bin/tpws`.
|
||||
3) Установите права на файлы: `chmod 755 /etc/init.d/tpws /usr/bin/tpws`
|
||||
4) Отредактируйте `/etc/config/tpws`
|
||||
* Если не нужен ipv6, отредактируйте /etc/firewall.user и установите там DISABLE_IPV6=1.
|
||||
@ -2045,7 +2029,7 @@ tpws будет работать в любом случае, он не треб
|
||||
|
||||
Хотя linux варианты под Android работают, рекомендуется использовать специально собранные под bionic бинарники.
|
||||
У них не будет проблем с DNS, с локальным временем и именами юзеров и групп.\
|
||||
Рекомендую использовать gid 3003 (AID_INET). Иначе можете получить permission denied на создание сокета.
|
||||
Рекомендуется использовать gid 3003 (AID_INET). Иначе можете получить permission denied на создание сокета.
|
||||
Например: `--uid 1:3003`\
|
||||
В iptables укажите: `! --uid-owner 1` вместо `! --uid-owner tpws`.\
|
||||
Напишите шелл скрипт с iptables и tpws, запускайте его средствами вашего рут менеджера.
|
||||
@ -2053,7 +2037,7 @@ tpws будет работать в любом случае, он не треб
|
||||
magisk : /data/adb/service.d\
|
||||
supersu: /system/su.d
|
||||
|
||||
`nfqws` может иметь такой глюк. При запуске с uid по умолчанию (0x7FFFFFFF) при условии работы на сотовом интерфейсе
|
||||
**nfqws** может иметь такой глюк. При запуске с uid по умолчанию (0x7FFFFFFF) при условии работы на сотовом интерфейсе
|
||||
и отключенном кабеле внешнего питания система может частично виснуть. Перестает работать тач и кнопки,
|
||||
но анимация на экране может продолжаться. Если экран был погашен, то включить его кнопкой power невозможно.
|
||||
Изменение UID на низкий (--uid 1 подойдет) позволяет решить эту проблему.
|
||||
|
22
init.d/sysv/custom.d.examples/10-keenetic-udp-fix
Normal file
22
init.d/sysv/custom.d.examples/10-keenetic-udp-fix
Normal file
@ -0,0 +1,22 @@
|
||||
# This script fixes keenetic issue with nfqws generated udp packets
|
||||
# Keenetic uses proprietary ndmmark and does not masquerade without this mark
|
||||
# If not masqueraded packets go to WAN with LAN IP and get dropped by ISP
|
||||
|
||||
# It's advised to set IFACE_WAN in config
|
||||
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - add, 0 - stop
|
||||
|
||||
local wan wanif rule
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
# use IFACE_WAN if defined. if not - search for interfaces with default route.
|
||||
wanif=${IFACE_WAN:-$(sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs)}
|
||||
for wan in $wanif; do
|
||||
rule="-o $wan -p udp -m mark --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
ipt_print_op $1 "$rule" "keenetic udp fix"
|
||||
ipt_add_del $1 POSTROUTING -t nat $rule -j MASQUERADE
|
||||
done
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
CC ?= gcc
|
||||
CFLAGS += -std=gnu99 -Os
|
||||
CFLAGS += -std=gnu99 -Os -flto=auto
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
CFLAGS_WIN = -static
|
||||
LIBS =
|
||||
|
@ -1,5 +1,5 @@
|
||||
CC ?= cc
|
||||
CFLAGS += -std=gnu99 -s -Os -Wno-address-of-packed-member
|
||||
CFLAGS += -std=gnu99 -s -Os -Wno-address-of-packed-member -flto=auto
|
||||
LIBS = -lz
|
||||
SRC_FILES = *.c crypto/*.c
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
CC ?= gcc
|
||||
CFLAGS += -std=gnu99 -Os
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
CFLAGS_MAC = -mmacosx-version-min=10.8
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member -flto=auto
|
||||
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
||||
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
|
||||
LIBS_BSD = -lz
|
||||
|
@ -1395,7 +1395,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
if (i==0)
|
||||
{
|
||||
if (seqovl_pos>=from)
|
||||
DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl for part %d.\n",seqovl,from,i+2);
|
||||
DLOG("seqovl>=split_pos (%zu>=%zu). cancelling seqovl for part %d.\n",seqovl,from,i+2);
|
||||
else
|
||||
{
|
||||
seqovl = seqovl_pos;
|
||||
@ -1440,7 +1440,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
if (seqovl_pos>=split_pos)
|
||||
{
|
||||
DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl.\n",seqovl_pos,split_pos);
|
||||
DLOG("seqovl>=split_pos (%zu>=%zu). cancelling seqovl.\n",seqovl_pos,split_pos);
|
||||
seqovl = 0;
|
||||
}
|
||||
else
|
||||
|
@ -1,5 +1,5 @@
|
||||
CC ?= cc
|
||||
CFLAGS += -std=gnu99 -s -Os
|
||||
CFLAGS += -std=gnu99 -s -Os -flto=auto
|
||||
LIBS = -lz -lpthread
|
||||
SRC_FILES = *.c
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
CC ?= gcc
|
||||
CFLAGS += -std=gnu99 -Os
|
||||
CFLAGS += -std=gnu99 -Os -flto=auto
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
LIBS = -lz -lpthread
|
||||
LIBS_ANDROID = -lz
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/tcp.h>
|
||||
@ -477,6 +478,24 @@ void msleep(unsigned int ms)
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
bool socket_supports_notsent()
|
||||
{
|
||||
int sfd;
|
||||
struct tcp_info tcpi;
|
||||
|
||||
sfd = socket(AF_INET,SOCK_STREAM,0);
|
||||
if (sfd<0) return false;
|
||||
|
||||
socklen_t ts = sizeof(tcpi);
|
||||
if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0)
|
||||
{
|
||||
close(sfd);
|
||||
return false;
|
||||
}
|
||||
close(sfd);
|
||||
|
||||
return ts>=((char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi.tcpi_state + sizeof(tcpi.tcpi_notsent_bytes));
|
||||
}
|
||||
bool socket_has_notsent(int sfd)
|
||||
{
|
||||
struct tcp_info tcpi;
|
||||
@ -484,10 +503,11 @@ bool socket_has_notsent(int sfd)
|
||||
|
||||
if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0)
|
||||
return false;
|
||||
if (tcpi.tcpi_state != 1)
|
||||
if (tcpi.tcpi_state != 1) // TCP_ESTABLISHED
|
||||
return false;
|
||||
size_t s = (char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi.tcpi_state;
|
||||
size_t s = (char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi + sizeof(tcpi.tcpi_notsent_bytes);
|
||||
if (ts < s)
|
||||
// old structure version
|
||||
return false;
|
||||
return !!tcpi.tcpi_notsent_bytes;
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ static inline const struct in6_addr *mask_from_preflen6(uint8_t preflen)
|
||||
|
||||
void msleep(unsigned int ms);
|
||||
#ifdef __linux__
|
||||
bool socket_supports_notsent();
|
||||
bool socket_has_notsent(int sfd);
|
||||
bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *wasted_ms);
|
||||
#endif
|
||||
|
@ -18,6 +18,8 @@
|
||||
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
|
||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||
|
||||
#define FIX_SEG_DEFAULT_MAX_WAIT 30
|
||||
|
||||
enum bindll { unwanted=0, no, prefer, force };
|
||||
|
||||
#define MAX_BINDS 32
|
||||
@ -102,13 +104,14 @@ struct params_s
|
||||
char connect_bind6_ifname[IF_NAMESIZE];
|
||||
|
||||
uint8_t proxy_type;
|
||||
unsigned int fix_seg;
|
||||
bool fix_seg_avail;
|
||||
bool no_resolve;
|
||||
bool skip_nodelay;
|
||||
bool fix_seg;
|
||||
bool droproot;
|
||||
bool daemon;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
bool daemon;
|
||||
char pidfile[256];
|
||||
int maxconn,resolver_threads,maxfiles,max_orphan_time;
|
||||
int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf;
|
||||
|
31
tpws/tpws.c
31
tpws/tpws.c
@ -171,7 +171,7 @@ static void exithelp(void)
|
||||
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
" --fix-seg\t\t\t\t; fix segmentation failures at the cost of possible slowdown\n"
|
||||
" --fix-seg=<int>\t\t\t; fix segmentation failures at the cost of possible slowdown. wait up to N msec (default %u)\n"
|
||||
#endif
|
||||
" --debug=0|1|2|syslog|@<filename>\t; 1 and 2 means log to console and set debug level. for other targets use --debug-level.\n"
|
||||
" --debug-level=0|1|2\t\t\t; specify debug level\n"
|
||||
@ -192,7 +192,7 @@ static void exithelp(void)
|
||||
"\nTAMPER:\n"
|
||||
" --split-pos=N|-N|marker+N|marker-N\t; comma separated list of split positions\n"
|
||||
"\t\t\t\t\t; markers: method,host,endhost,sld,endsld,midsld,sniext\n"
|
||||
" --split-any-protocol\t\t\t; split not only http and https\n"
|
||||
" --split-any-protocol\t\t\t; split not only http and TLS\n"
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
" --disorder[=http|tls]\t\t\t; when splitting simulate sending second fragment first (BSD sends entire message instead of first fragment, this is not good)\n"
|
||||
#else
|
||||
@ -218,6 +218,9 @@ static void exithelp(void)
|
||||
" --tamper-cutoff=[n]<pos>\t\t; do not tamper anymore after specified outbound stream position. default is unlimited.\n",
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
DEFAULT_TCP_USER_TIMEOUT_LOCAL,DEFAULT_TCP_USER_TIMEOUT_REMOTE,
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
FIX_SEG_DEFAULT_MAX_WAIT,
|
||||
#endif
|
||||
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT
|
||||
);
|
||||
@ -535,6 +538,10 @@ void parse_params(int argc, char *argv[])
|
||||
params.pf_enable = true; // OpenBSD and MacOS have no other choice
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
params.fix_seg_avail = socket_supports_notsent();
|
||||
#endif
|
||||
|
||||
LIST_INIT(¶ms.hostlists);
|
||||
LIST_INIT(¶ms.ipsets);
|
||||
|
||||
@ -638,7 +645,7 @@ void parse_params(int argc, char *argv[])
|
||||
{ "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62
|
||||
{ "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63
|
||||
{ "mss",required_argument,0,0 }, // optidx=64
|
||||
{ "fix-seg",no_argument,0,0 }, // optidx=65
|
||||
{ "fix-seg",optional_argument,0,0 }, // optidx=65
|
||||
#ifdef SPLICE_PRESENT
|
||||
{ "nosplice",no_argument,0,0 }, // optidx=66
|
||||
#endif
|
||||
@ -1233,7 +1240,23 @@ void parse_params(int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
case 65: /* fix-seg */
|
||||
params.fix_seg = true;
|
||||
if (!params.fix_seg_avail)
|
||||
{
|
||||
DLOG_ERR("--fix-seg is supported since kernel 4.6\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (optarg)
|
||||
{
|
||||
i = atoi(optarg);
|
||||
if (i < 0 || i > 1000)
|
||||
{
|
||||
DLOG_ERR("fix_seg value must be within 0..1000\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
params.fix_seg = i;
|
||||
}
|
||||
else
|
||||
params.fix_seg = FIX_SEG_DEFAULT_MAX_WAIT;
|
||||
break;
|
||||
#ifdef SPLICE_PRESENT
|
||||
case 66: /* nosplice */
|
||||
|
@ -1118,8 +1118,24 @@ static ssize_t send_oob(int fd, uint8_t *buf, size_t len, int ttl, bool oob, uin
|
||||
}
|
||||
|
||||
|
||||
static unsigned int segfail_count=0;
|
||||
static time_t segfail_report_time=0;
|
||||
static void report_segfail(void)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
segfail_count++;
|
||||
if (now==segfail_report_time)
|
||||
VPRINT("WARNING ! segmentation failed. total fails : %u\n", segfail_count);
|
||||
else
|
||||
{
|
||||
DLOG_ERR("WARNING ! segmentation failed. total fails : %u\n", segfail_count);
|
||||
segfail_report_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
#define RD_BLOCK_SIZE 65536
|
||||
#define MAX_WASTE (1024*1024)
|
||||
|
||||
static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32_t evt)
|
||||
{
|
||||
int numbytes;
|
||||
@ -1231,6 +1247,25 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
|
||||
bApplyDisorder = !(i & 1) && i<multisplit_count && (split_flags & SPLIT_FLAG_DISORDER);
|
||||
bApplyOOB = i==0 && (split_flags & SPLIT_FLAG_OOB);
|
||||
len = to-from;
|
||||
#ifdef __linux__
|
||||
if (params.fix_seg_avail)
|
||||
{
|
||||
if (params.fix_seg)
|
||||
{
|
||||
unsigned int wasted;
|
||||
bool bWaitOK = socket_wait_notsent(conn->partner->fd, params.fix_seg, &wasted);
|
||||
if (wasted)
|
||||
VPRINT("WARNING ! wasted %u ms to fix segmenation\n", wasted);
|
||||
if (!bWaitOK)
|
||||
report_segfail();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (socket_has_notsent(conn->partner->fd))
|
||||
report_segfail();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
VPRINT("Sending multisplit part %d %zd-%zd (len %zd)%s%s : ", i+1, from, to, len, bApplyDisorder ? " with disorder" : "", bApplyOOB ? " with OOB" : "");
|
||||
packet_debug(buf+from,len);
|
||||
wr = send_oob(conn->partner->fd, buf+from, len, bApplyDisorder, bApplyOOB, conn->track.dp ? conn->track.dp->oob_byte : 0);
|
||||
@ -1244,21 +1279,6 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
|
||||
if (wr>0) conn->partner->twr += wr;
|
||||
break;
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (params.fix_seg)
|
||||
{
|
||||
unsigned int wasted;
|
||||
if (!socket_wait_notsent(conn->partner->fd, 20, &wasted))
|
||||
DLOG_ERR("WARNING ! segmentation failed\n");
|
||||
if (wasted)
|
||||
VPRINT("WARNING ! wasted %u ms to fix segmenation\n", wasted);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (socket_has_notsent(conn->partner->fd))
|
||||
DLOG_ERR("WARNING ! segmentation failed\n");
|
||||
}
|
||||
#endif
|
||||
from = to;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user