35 Commits
v69.4 ... v69.6

Author SHA1 Message Date
bol-van
7b057491af update docs 2024-12-09 13:23:44 +03:00
bol-van
8e7b694076 init.d: 20-fw-extra 2024-12-09 13:20:05 +03:00
bol-van
e8395eea56 nfqws: pfsense split2->multisplit 2024-12-09 12:13:48 +03:00
bol-van
6e619eba1a nfqws: fix crash 2024-12-09 12:06:49 +03:00
bol-van
f8bd218e67 custom.d: DISABLE_CUSTOM switch 2024-12-09 11:04:13 +03:00
bol-van
207a6faf33 init.d: unify standard_mode_daemons 2024-12-09 10:49:43 +03:00
bol-van
991e3534a6 install_easy: copy custom.d.examples.linux in openwrt 2024-12-09 09:51:17 +03:00
bol-van
ebb22dfa3f init.d: unitfy custom scripts for linux 2024-12-09 09:28:25 +03:00
bol-van
9bd65e0c1d init.d: remove NFQWS_OPT_BASE from sysv custom scripts 2024-12-08 20:07:06 +03:00
bol-van
5b337b6015 50-wg4all: remove desync any protocol 2024-12-08 19:36:43 +03:00
bol-van
4189803693 init.d: custom script 50-wg4all 2024-12-08 19:31:29 +03:00
bol-van
1175b171ba nfqws: NETLINK_NO_ENOBUFS 2024-12-08 09:58:30 +03:00
bol-van
bea643c967 nfqws: more error checking fixing 2024-12-08 09:40:45 +03:00
bol-van
addc813956 tpws: fix dangling else 2024-12-08 08:38:17 +03:00
bol-van
0f1721d2c4 nfqws: dangling else fix 2024-12-07 22:41:55 +03:00
bol-van
abdc8d9449 nfqws: fix return value type 2024-12-07 22:05:26 +03:00
bol-van
9e9136cffd nfqws: static func 2024-12-07 20:54:22 +03:00
bol-van
c802069a11 nfqws: fix nfq recv result and error handling 2024-12-07 20:51:51 +03:00
bol-van
4e5caf4087 quick_start: improve link 2024-12-06 11:41:06 +03:00
bol-van
de63ee7321 quick_start_windows: improve link 2024-12-06 11:26:50 +03:00
bol-van
d6688b935d winws: fix non-working --dry-run 2024-12-05 21:55:48 +03:00
bol-van
21e08ca55e tpws,nfqws: fix recognition of CONNECT and OPTIONS http methods 2024-12-05 19:23:39 +03:00
bol-van
c4f53549b1 quick_start_windows: simplify win7 2024-12-05 18:05:02 +03:00
bol-van
08645997f8 50-tpws-ipset: fix var names 2024-12-04 16:23:44 +03:00
bol-van
e42a545ebc init.d: 50-tpws-ipset custom script example 2024-12-04 16:18:31 +03:00
bol-van
8324c04a41 Update windows.md 2024-12-04 10:59:57 +03:00
bol-van
166847ba92 Update windows.en.md 2024-12-04 10:59:22 +03:00
bol-van
1904f01cf4 Update windows.en.md 2024-12-04 10:58:25 +03:00
bol-van
4ae1ad053d Update windows.md 2024-12-04 10:57:09 +03:00
bol-van
7d9946b007 update docs 2024-12-03 18:23:13 +03:00
bol-van
86462f4cee update docs 2024-12-03 18:20:46 +03:00
bol-van
669182c133 install_easy: trim trailing space in editor 2024-12-03 17:33:02 +03:00
bol-van
f81bb51f4a install_easy: validate daemon options 2024-12-03 17:22:16 +03:00
bol-van
d4ff423add tpws: --dry-run 2024-12-03 15:57:21 +03:00
bol-van
b14ff9b647 nfqws: --dry-run 2024-12-03 15:56:37 +03:00
29 changed files with 863 additions and 633 deletions

View File

@@ -3,6 +3,8 @@ custom_runner()
# $1 - function name # $1 - function name
# $2+ - params # $2+ - params
[ "$DISABLE_CUSTOM" = 1 ] && return 0
local n script FUNC=$1 local n script FUNC=$1
shift shift

View File

@@ -140,7 +140,7 @@ echo_var()
eval v="\$$1" eval v="\$$1"
if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then
echo "$1=\"" echo "$1=\""
echo "$v\"" | sed "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g" echo "$v\"" | tr '\n' ' ' | tr -d '\r' | sed -e 's/^ *//' -e 's/ *$//' -e "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g"
else else
if contains "$v" " "; then if contains "$v" " "; then
echo $1=\"$v\" echo $1=\"$v\"
@@ -170,6 +170,7 @@ list_vars()
echo_var $1 echo_var $1
shift shift
done done
echo
} }
openrc_test() openrc_test()
@@ -837,3 +838,37 @@ select_fwtype()
echo select firewall type : echo select firewall type :
ask_list FWTYPE "iptables nftables" "$FWTYPE" && write_config_var FWTYPE ask_list FWTYPE "iptables nftables" "$FWTYPE" && write_config_var FWTYPE
} }
dry_run_tpws_()
{
local TPWS="$ZAPRET_BASE/tpws/tpws"
echo verifying tpws options
"$TPWS" --dry-run "$@"
}
dry_run_nfqws_()
{
local NFQWS="$ZAPRET_BASE/nfq/nfqws"
echo verifying nfqws options
"$NFQWS" --dry-run "$@"
}
dry_run_tpws()
{
[ "$TPWS_ENABLE" = 1 ] || return 0
local opt="$TPWS_OPT" port=${TPPORT_SOCKS:-988}
filter_apply_hostlist_target opt
dry_run_tpws_ --port=$port $opt
}
dry_run_tpws_socks()
{
[ "$TPWS_SOCKS_ENABLE" = 1 ] || return 0
local opt="$TPWS_SOCKS_OPT" port=${TPPORT:-987}
filter_apply_hostlist_target opt
dry_run_tpws_ --port=$port --socks $opt
}
dry_run_nfqws()
{
[ "$NFQWS_ENABLE" = 1 ] || return 0
local opt="$NFQWS_OPT" qn=${QNUM:-200}
filter_apply_hostlist_target opt
dry_run_nfqws_ --qnum=$qn $opt
}

View File

@@ -349,27 +349,37 @@ ipt_do_nfqws_in_out()
} }
} }
zapret_do_firewall_standard_rules_ipt() zapret_do_firewall_standard_tpws_rules_ipt()
{ {
# $1 - 1 - add, 0 - del # $1 - 1 - add, 0 - del
local f4 f6 local f4 f6
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && [ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && {
{
f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT" f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT"
f6=$f4 f6=$f4
filter_apply_ipset_target f4 f6 filter_apply_ipset_target f4 f6
fw_tpws $1 "$f4" "$f6" $TPPORT fw_tpws $1 "$f4" "$f6" $TPPORT
} }
[ "$NFQWS_ENABLE" = 1 ] && }
{ zapret_do_firewall_standard_nfqws_rules_ipt()
{
# $1 - 1 - add, 0 - del
[ "$NFQWS_ENABLE" = 1 ] && {
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN" ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN" ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN"
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN" ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN" ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN"
} }
} }
zapret_do_firewall_standard_rules_ipt()
{
# $1 - 1 - add, 0 - del
zapret_do_firewall_standard_tpws_rules_ipt $1
zapret_do_firewall_standard_nfqws_rules_ipt $1
}
zapret_do_firewall_rules_ipt() zapret_do_firewall_rules_ipt()
{ {

55
common/linux_daemons.sh Normal file
View File

@@ -0,0 +1,55 @@
standard_mode_tpws_socks()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
filter_apply_hostlist_target opt
do_tpws_socks $1 2 "$opt"
}
}
standard_mode_tpws()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
do_tpws $1 1 "$opt"
}
}
standard_mode_nfqws()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
opt="--qnum=$QNUM $NFQWS_OPT"
filter_apply_hostlist_target opt
do_nfqws $1 3 "$opt"
}
}
standard_mode_daemons()
{
# $1 - 1 - run, 0 - stop
standard_mode_tpws_socks $1
standard_mode_tpws $1
standard_mode_nfqws $1
}
zapret_do_daemons()
{
# $1 - 1 - run, 0 - stop
standard_mode_daemons $1
custom_runner zapret_custom_daemons $1
return 0
}
zapret_run_daemons()
{
zapret_do_daemons 1 "$@"
}
zapret_stop_daemons()
{
zapret_do_daemons 0 "$@"
}

View File

@@ -640,25 +640,31 @@ nft_apply_nfqws_in_out()
} }
} }
zapret_apply_firewall_standard_rules_nft() zapret_apply_firewall_standard_tpws_rules_nft()
{ {
local f4 f6 local f4 f6
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && [ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && {
{
f4="tcp dport {$TPWS_PORTS}" f4="tcp dport {$TPWS_PORTS}"
f6=$f4 f6=$f4
nft_filter_apply_ipset_target f4 f6 nft_filter_apply_ipset_target f4 f6
nft_fw_tpws "$f4" "$f6" $TPPORT nft_fw_tpws "$f4" "$f6" $TPPORT
} }
[ "$NFQWS_ENABLE" = 1 ] && }
{ zapret_apply_firewall_standard_nfqws_rules_nft()
{
[ "$NFQWS_ENABLE" = 1 ] && {
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN" nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN" nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN"
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN" nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN" nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN"
} }
} }
zapret_apply_firewall_standard_rules_nft()
{
zapret_apply_firewall_standard_tpws_rules_nft
zapret_apply_firewall_standard_nfqws_rules_nft
}
zapret_apply_firewall_rules_nft() zapret_apply_firewall_rules_nft()
{ {

View File

@@ -410,5 +410,16 @@ repo: sha256sum
v69.4 v69.4
nfqws : fakedsplit/fakeddisorder fakes for both split segments nfqws: fakedsplit/fakeddisorder fakes for both split segments
nfqws : --dpi-desync-fakedsplit-pattern nfqws: --dpi-desync-fakedsplit-pattern
v69.5
nfqws,tpws: --dry-run
install_easy: check tpws and nfqws options validity
v69.6
nfqws: set NETLINK_NO_ENOBUFS to fix possible nfq recv errors
init.d: unify custom scripts for linux
init.d: new custom scripts : 20-fw-extra, 50-wg4all

View File

@@ -158,7 +158,7 @@
> >
> Далее, имея понимание что работает на http, https, quic нужно > Далее, имея понимание что работает на http, https, quic нужно
> сконструировать параметры запуска `tpws` и/или `nfqws` с использованием > сконструировать параметры запуска `tpws` и/или `nfqws` с использованием
> мультистратегии. Как работают мультистратегии описано в readme.txt. > мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md#множественные-стратегии).
> >
> Если кратко, то обычно параметры конструируются так: > Если кратко, то обычно параметры конструируются так:
> ```sh > ```sh

View File

@@ -59,7 +59,7 @@ _"Совсем ничего не могу, все очень сложно, да
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip. 1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
2) Если у вас Windows 7 x64, читайте [docs/windows.md](./windows.md). Без описанной там подготовки может не работать. 2) Если у вас Windows 7 x64, однократно запустите `win7/install_win7.cmd`. Батник заменит файлы windivert на совместимую с Windows 7 версию.
> [!WARNING] > [!WARNING]
> Для 32-битных систем Windows нет готового полного варианта. > Для 32-битных систем Windows нет готового полного варианта.
@@ -123,7 +123,7 @@ blockcheck перейдет в этом случае на **DoH** _(DNS over HTT
> она стабильна, на третьих полный хаос, и проще отказаться. > она стабильна, на третьих полный хаос, и проще отказаться.
> >
> Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws > Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
> с использованием мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md). > с использованием мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md#множественные-стратегии).
> >
> Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры > Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
> `--wf-l3`, `--wf-tcp`, `--wf-udp`. > `--wf-l3`, `--wf-tcp`, `--wf-udp`.

View File

@@ -1,4 +1,4 @@
# zapret v69.4 # zapret v69.6
# SCAMMER WARNING # SCAMMER WARNING
@@ -131,6 +131,7 @@ nfqws takes the following parameters:
@<config_file> ; read file for options. must be the only argument. other options are ignored. @<config_file> ; read file for options. must be the only argument. other options are ignored.
--debug=0|1 --debug=0|1
--dry-run ; verify parameters and exit with code 0 if successful
--qnum=<nfqueue_number> --qnum=<nfqueue_number>
--daemon ; daemonize --daemon ; daemonize
--pidfile=<filename> ; write pid to file --pidfile=<filename> ; write pid to file
@@ -639,6 +640,7 @@ tpws is transparent proxy.
--debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level. --debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level.
--debug-level=0|1|2 ; specify debug level for syslog and @<filename> --debug-level=0|1|2 ; specify debug level for syslog and @<filename>
--dry-run ; verify parameters and exit with code 0 if successful
--bind-addr=<v4_addr>|<v6_addr> ; for v6 link locals append %interface_name : fe80::1%br-lan --bind-addr=<v4_addr>|<v6_addr> ; for v6 link locals append %interface_name : fe80::1%br-lan
--bind-iface4=<interface_name> ; bind to the first ipv4 addr of interface --bind-iface4=<interface_name> ; bind to the first ipv4 addr of interface
--bind-iface6=<interface_name> ; bind to the first ipv6 addr of interface --bind-iface6=<interface_name> ; bind to the first ipv6 addr of interface

View File

@@ -1,4 +1,4 @@
# zapret v69.4 # zapret v69.6
# ВНИМАНИЕ, остерегайтесь мошенников # ВНИМАНИЕ, остерегайтесь мошенников
@@ -159,77 +159,78 @@ DPI. Все больше становится внереестровых бло
dvtws, собираемый из тех же исходников (см. [документация BSD](./bsd.md)). dvtws, собираемый из тех же исходников (см. [документация BSD](./bsd.md)).
``` ```
@<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются. @<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
--debug=0|1 ; 1=выводить отладочные сообщения --debug=0|1 ; 1=выводить отладочные сообщения
--daemon ; демонизировать прогу --dry-run ; проверить опции командной строки и выйти. код 0 - успешная проверка.
--pidfile=<file> ; сохранить PID в файл --daemon ; демонизировать прогу
--user=<username> ; менять uid процесса --pidfile=<file> ; сохранить PID в файл
--uid=uid[:gid] ; менять uid процесса --user=<username> ; менять uid процесса
--qnum=N ; номер очереди N --uid=uid[:gid] ; менять uid процесса
--bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов --qnum=N ; номер очереди N
--bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов --bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
--wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !) --bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов
--wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !) --wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
--wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N --wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)
--ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60 --wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:". --ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета --hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
--methodeol ; добавить перевод строки в unix стиле ('\n') перед методом и убрать пробел из Host: : "GET / ... Host: domain.com" => "\nGET / ... Host:domain.com" --hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase --methodeol ; добавить перевод строки в unix стиле ('\n') перед методом и убрать пробел из Host: : "GET / ... Host: domain.com" => "\nGET / ... Host:domain.com"
--domcase ; домен после Host: сделать таким : TeSt.cOm --hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper --domcase ; домен после Host: сделать таким : TeSt.cOm
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000 --dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов --dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl --dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. delta=0 отключает функцию. --dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6 --dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. delta=0 отключает функцию.
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2 --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты) --dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI --dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder --dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число. --dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число.
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap --dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
--dpi-desync-fakedsplit-pattern=<filename>|0xHEX ; чем заполнять фейки в fakedsplit/fakeddisorder --dpi-desync-fakedsplit-pattern=<filename>|0xHEX ; чем заполнять фейки в fakedsplit/fakeddisorder
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000 --dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000 --dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных --dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
--dpi-desync-fake-http=<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org --dpi-desync-fake-http=<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org
--dpi-desync-fake-tls=<filename>|0xHEX ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному --dpi-desync-fake-tls=<filename>|0xHEX ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному
--dpi-desync-fake-unknown=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт --dpi-desync-fake-unknown=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
--dpi-desync-fake-syndata=<filename>|0xHEX ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata --dpi-desync-fake-syndata=<filename>|0xHEX ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata
--dpi-desync-fake-quic=<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial --dpi-desync-fake-quic=<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial
--dpi-desync-fake-dht=<filename>|0xHEX ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт --dpi-desync-fake-dht=<filename>|0xHEX ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт --dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen --dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули --dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули
--dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N --dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N --dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. --hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
; в файле должен быть хост на каждой строке. ; в файле должен быть хост на каждой строке.
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска. ; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; при изменении времени модификации файла он перечитывается автоматически по необходимости ; при изменении времени модификации файла он перечитывается автоматически по необходимости
; список может быть запакован в gzip. формат автоматически распознается и разжимается ; список может быть запакован в gzip. формат автоматически распознается и разжимается
; списков может быть множество. пустой общий лист = его отсутствие ; списков может быть множество. пустой общий лист = его отсутствие
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello. ; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
--hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов. --hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам. --hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
--hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов. --hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика) --hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3) --hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60) --hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
--hostlist-auto-retrans-threshold=<int> ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3) --hostlist-auto-retrans-threshold=<int> ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3)
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты. --hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
--new ; начало новой стратегии (новый профиль) --new ; начало новой стратегии (новый профиль)
--skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров. --skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии --filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую. --filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.
--filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp. поддерживается список через запятую. --filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp. поддерживается список через запятую.
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую. --filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. --ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей. --ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. --ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей. --ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
``` ```
`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования `--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования
@@ -754,100 +755,101 @@ iptables target `FLOWOFFLOAD` - это проприетарное изобрет
tpws - это transparent proxy. tpws - это transparent proxy.
``` ```
@<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются. @<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
--debug=0|1|2|syslog|@<filename> ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка. --debug=0|1|2|syslog|@<filename> ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка.
--debug-level=0|1|2 ; указать уровень логирования для syslog и @<filename> --debug-level=0|1|2 ; указать уровень логирования для syslog и @<filename>
--daemon ; демонизировать прогу --dry-run ; проверить опции командной строки и выйти. код 0 - успешная проверка.
--pidfile=<file> ; сохранить PID в файл
--user=<username> ; менять uid процесса --daemon ; демонизировать прогу
--uid=uid[:gid] ; менять uid процесса --pidfile=<file> ; сохранить PID в файл
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес --user=<username> ; менять uid процесса
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan --uid=uid[:gid] ; менять uid процесса
--bind-linklocal=no|unwanted|prefer|force --bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес
; no : биндаться только на global ipv6 ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
; unwanted (default) : предпочтительно global, если нет - LL --bind-linklocal=no|unwanted|prefer|force ; no : биндаться только на global ipv6
; prefer : предпочтительно LL, если нет - global ; unwanted (default) : предпочтительно global, если нет - LL
; force : биндаться только на LL ; prefer : предпочтительно LL, если нет - global
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface ; force : биндаться только на LL
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface --bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-wait-ifup=<sec ; ждать до N секунд появления и поднятия интерфейса --bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса) --bind-wait-ifup=<sec> ; ждать до N секунд появления и поднятия интерфейса
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip-linklocal=<sec> --bind-wait-ip-linklocal=<sec>
; имеет смысл только при задании --bind-wait-ip ; имеет смысл только при задании --bind-wait-ip
; --bind-linklocal=unwanted : согласиться на LL после N секунд ; --bind-linklocal=unwanted : согласиться на LL после N секунд
; --bind-linklocal=prefer : согласиться на global address после N секунд ; --bind-linklocal=prefer : согласиться на global address после N секунд
--bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0. --bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0.
--connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес --connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan ; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
; опция может повторяться для v4 и v6 адресов ; опция может повторяться для v4 и v6 адресов
; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local. ; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local.
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy --socks ; вместо прозрачного прокси реализовать socks4/5 proxy
--no-resolve ; запретить ресолвинг имен через socks5 --no-resolve ; запретить ресолвинг имен через socks5
--resolve-threads ; количество потоков ресолвера --resolve-threads ; количество потоков ресолвера
--port=<port> ; на каком порту слушать --port=<port> ; на каком порту слушать
--maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси --maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси
--maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга. --maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга.
; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16 ; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16
--max-orphan-time=<sec> ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений, --max-orphan-time=<sec> ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений,
; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...) ; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...)
; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных, ; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных,
; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго. ; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго.
; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию ; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию
; эта функция не действует на успешно подключенные ранее соединения ; эта функция не действует на успешно подключенные ранее соединения
--local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy --local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy
--local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy --local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy
--remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target --remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target --remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
--nosplice ; не использовать splice на linux системах --nosplice ; не использовать splice на linux системах
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split. --skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение) --local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение) --remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--fix-seg=<int> ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления. ждать до N мс. по умолчанию 30 мс. --fix-seg=<int> ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления. ждать до N мс. по умолчанию 30 мс.
--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации --split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации
--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS) --split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS)
--disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса --disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
--oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита --oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита
--oob-data=<char>|0xHEX ; переопределить байт OOB. по умолчанию 0x00. --oob-data=<char>|0xHEX ; переопределить байт OOB. по умолчанию 0x00.
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:". --hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase --hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv." --hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t" --hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tv\t"
--hostnospace ; убрать пробел после "Host:" --hostnospace ; убрать пробел после "Host:"
--hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host: --hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host:
--domcase ; домен после Host: сделать таким : TeSt.cOm --domcase ; домен после Host: сделать таким : TeSt.cOm
--methodspace ; добавить пробел после метода : "GET /" => "GET /" --methodspace ; добавить пробел после метода : "GET /" => "GET /"
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /" --methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A --unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
--tlsrec=N|-N|marker+N|marker-N ; разбивка TLS ClientHello на 2 TLS records на указанной позиции. Минимальное смещение - 6. --tlsrec=N|-N|marker+N|marker-N ; разбивка TLS ClientHello на 2 TLS records на указанной позиции. Минимальное смещение - 6.
--mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость --mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость
--tamper-start=[n]<pos> ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока) --tamper-start=[n]<pos> ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока)
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока) --tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются. --hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
; в файле должен быть хост на каждой строке. ; в файле должен быть хост на каждой строке.
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска. ; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; при изменении времени модификации файла он перечитывается автоматически по необходимости ; при изменении времени модификации файла он перечитывается автоматически по необходимости
; список может быть запакован в gzip. формат автоматически распознается и разжимается ; список может быть запакован в gzip. формат автоматически распознается и разжимается
; списков может быть множество. пустой общий лист = его отсутствие ; списков может быть множество. пустой общий лист = его отсутствие
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello. ; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
--hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов. --hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам. --hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
--hostlist-exclude-domains=<domain_list>; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов. --hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика) --hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3) --hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60) --hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты. --hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
--new ; начало новой стратегии (новый профиль) --new ; начало новой стратегии (новый профиль)
--skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров. --skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии --filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую. --filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую.
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую. --filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. --ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей. --ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая. --ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей. --ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
``` ```
### TCP СЕГМЕНТАЦИЯ В TPWS ### TCP СЕГМЕНТАЦИЯ В TPWS
@@ -1864,8 +1866,9 @@ custom скрипты - это маленькие shell программы, уп
/opt/zapret/init.d/macos/custom.d /opt/zapret/init.d/macos/custom.d
``` ```
Директория будет просканирована в алфавитном порядке, и каждый скрипт будет применен. Директория будет просканирована в алфавитном порядке, и каждый скрипт будет применен.
Рядом имеется `custom.d.examples`. Это готовые скрипты, которые можно копировать в `custom.d`.
Их можно взять за основу для написания собственных. В `init.d` имеется `custom.d.examples.linux`, в `init.d/macos` - `custom.d.examples`.
Это готовые скрипты, которые можно копировать в `custom.d`. Их можно взять за основу для написания собственных.
***Для linux пишется код в функции*** ***Для linux пишется код в функции***
``` ```
@@ -1883,9 +1886,9 @@ zapret_custom_firewall_v6
``` ```
zapret_custom_daemons поднимает демоны **nfqws**/**tpws** в нужном вам количестве и с нужными вам параметрами. zapret_custom_daemons поднимает демоны **nfqws**/**tpws** в нужном вам количестве и с нужными вам параметрами.
Для систем традиционного linux (sysv) и MacOS в первом параметре передается код операции: 1 = запуск, 0 = останов. В первом параметре передается код операции: 1 = запуск, 0 = останов.
Для openwrt логика останова отсутствует за ненадобностью.
Схема запуска демонов в openwrt отличается - используется procd. Схема запуска демонов в openwrt отличается - используется procd.
Поэтому логика останова отсутствует за ненадобностью, останов никогда не вызывается.
zapret_custom_firewall поднимает и убирает правила `iptables`. zapret_custom_firewall поднимает и убирает правила `iptables`.
В первом параметре передается код операции: 1 = запуск, 0 = останов. В первом параметре передается код операции: 1 = запуск, 0 = останов.
@@ -1911,8 +1914,8 @@ zapret_custom_firewall_nft поднимает правила nftables.
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout, В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout,
содержащий правила для pf-якоря. Остальное сделает обертка. содержащий правила для pf-якоря. Остальное сделает обертка.
Особо обратите внимание на номер демона в функциях `run_daemon` и `do_daemon`, номера портов **tpws** Особо обратите внимание на номер демона в функциях `run_daemon` , `do_daemon`, `do_tpws`, `do_tpws_socks`, `do_nfqws` ,
и очередей `nfqueue`. номера портов **tpws** и очередей **nfqueue**.
Они должны быть уникальными во всех скриптах. При накладке будет ошибка. Они должны быть уникальными во всех скриптах. При накладке будет ошибка.
Поэтому используйте функции динамического получения этих значений из пула. Поэтому используйте функции динамического получения этих значений из пула.

View File

@@ -101,10 +101,11 @@ There are several options :
Replace these 2 files in every location they are present. Replace these 2 files in every location they are present.
In `zapret-win-bundle` they are in `zapret-winws` и `blockcheck/zapret/nfq` folders. In `zapret-win-bundle` they are in `zapret-winws` и `blockcheck/zapret/nfq` folders.
However this option still requires 10+ year old patch that enables SHA256 signatures. However this option still requires 10+ year old patch that enables SHA256 signatures.
If you're using win bundle you can simply run `win7\install_win7.cmd`
2. [Hack ESU](https://hackandpwn.com/windows-7-esu-patching) 3. [Hack ESU](https://hackandpwn.com/windows-7-esu-patching)
3. Use `UpdatePack7R2` from simplix : https://blog.simplix.info 4. Use `UpdatePack7R2` from simplix : https://blog.simplix.info
If you are in Russia or Belarus temporary change region in Control Panel. If you are in Russia or Belarus temporary change region in Control Panel.
### blockcheck ### blockcheck

View File

@@ -159,6 +159,7 @@ _windivert 2.2.2-A_, который идет в поставке zapret.
и заменить эти 2 файла. и заменить эти 2 файла.
В [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle) есть отдельных 2 места, где находится **winws** : [_zapret-winws_](https://github.com/bol-van/zapret-win-bundle/tree/master/zapret-winws) и [_blockcheck/zapret/nfq_](https://github.com/bol-van/zapret-win-bundle/tree/master/blockcheck). В [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle) есть отдельных 2 места, где находится **winws** : [_zapret-winws_](https://github.com/bol-van/zapret-win-bundle/tree/master/zapret-winws) и [_blockcheck/zapret/nfq_](https://github.com/bol-van/zapret-win-bundle/tree/master/blockcheck).
Надо менять в обоих местах. Надо менять в обоих местах.
Альтернативный вариант при использовании win bundle - запустить `win7\install_win7.cmd`
> [!NOTE] > [!NOTE]
> Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим. > Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим.

View File

@@ -0,0 +1,66 @@
# this custom script runs standard mode with extra firewall rules
# config: use TPWS_ENABLE_OVERRIDE, NFQWS_ENABLE_OVERRIDE to enable standard mode daemons
# standard and override switches cannot be enabled simultaneously !
TPWS_ENABLE_OVERRIDE=${TPWS_ENABLE_OVERRIDE:-0}
NFQWS_ENABLE_OVERRIDE=${NFQWS_ENABLE_OVERRIDE:-0}
# config: some if these values must be set in config. not setting any of these makes this script meaningless.
# pre vars put ipt/nft code to the rule beginning
#FW_EXTRA_PRE_TPWS_IPT=
#FW_EXTRA_PRE_TPWS_NFT=
#FW_EXTRA_PRE_NFQWS_IPT="-m mark --mark 0x10000000/0x10000000"
#FW_EXTRA_PRE_NFQWS_NFT="mark and 0x10000000 != 0"
# post vars put ipt/nft code to the rule end
#FW_EXTRA_POST_TPWS_IPT=
#FW_EXTRA_POST_TPWS_NFT=
#FW_EXTRA_POST_NFQWS_IPT=
#FW_EXTRA_POST_NFQWS_NFT=
check_std_intersect()
{
[ "$TPWS_ENABLE_OVERRIDE" = 1 -a "$TPWS_ENABLE" = 1 ] && {
echo "ERROR ! both TPWS_ENABLE_OVERRIDE and TPWS_ENABLE are enabled"
return 1
}
[ "$NFQWS_ENABLE_OVERRIDE" = 1 -a "$NFQWS_ENABLE" = 1 ] && {
echo "ERROR ! both NFQWS_ENABLE_OVERRIDE and NFQWS_ENABLE are enabled"
return 1
}
return 0
}
zapret_custom_daemons()
{
# $1 - 1 - add, 0 - stop
check_std_intersect || return
local TPWS_SOCKS_ENABLE=0 TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE
standard_mode_daemons "$1"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
check_std_intersect || return
local FW_EXTRA_PRE FW_EXTRA_POST TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE
FW_EXTRA_PRE="$FW_EXTRA_PRE_TPWS_IPT" FW_EXTRA_POST="$FW_EXTRA_POST_TPWS_IPT"
zapret_do_firewall_standard_tpws_rules_ipt $1
FW_EXTRA_PRE="$FW_EXTRA_PRE_NFQWS_IPT" FW_EXTRA_POST="$FW_EXTRA_POST_NFQWS_IPT"
zapret_do_firewall_standard_nfqws_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
check_std_intersect || return
local FW_EXTRA_PRE FW_EXTRA_POST TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE
FW_EXTRA_PRE="$FW_EXTRA_PRE_TPWS_NFT" FW_EXTRA_POST="$FW_EXTRA_POST_TPWS_NFT"
zapret_apply_firewall_standard_tpws_rules_nft
FW_EXTRA_PRE="$FW_EXTRA_PRE_NFQWS_NFT" FW_EXTRA_POST="$FW_EXTRA_POST_NFQWS_NFT"
zapret_apply_firewall_standard_nfqws_rules_nft
}

View File

@@ -8,9 +8,9 @@ alloc_qnum QNUM_DHT4ALL
zapret_custom_daemons() zapret_custom_daemons()
{ {
# stop logic is managed by procd # $1 - 1 - add, 0 - stop
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT" local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_DESYNC_DHT"
do_nfqws $1 $DNUM_DHT4ALL "$opt" do_nfqws $1 $DNUM_DHT4ALL "$opt"
} }
zapret_custom_firewall() zapret_custom_firewall()

View File

@@ -14,7 +14,7 @@ zapret_custom_daemons()
{ {
# $1 - 1 - run, 0 - stop # $1 - 1 - run, 0 - stop
local opt="--qnum=$QNUM_DISCORD $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DISCORD" local opt="--qnum=$QNUM_DISCORD $NFQWS_OPT_DESYNC_DISCORD"
do_nfqws $1 $DNUM_DISCORD "$opt" do_nfqws $1 $DNUM_DISCORD "$opt"
} }

View File

@@ -0,0 +1,89 @@
# this custom script demonstrates how to launch extra tpws instance limited by ipset
# can override in config :
TPWS_MY1_OPT="${TPWS_MY1_OPT:---oob --split-pos=midsld}"
TPWS_MY1_PORTS=${TPWS_MY1_PORTS:-$TPWS_PORTS}
TPWS_MY1_SUBNETS4="${TPWS_MY1_SUBNETS4:-142.250.0.0/15 64.233.160.0/19 172.217.0.0/16 173.194.0.0/16 108.177.0.0/17 74.125.0.0/16 209.85.128.0/17 216.58.192.0/19}"
TPWS_MY1_SUBNETS6="${TPWS_MY1_SUBNETS6:-2607:F8B0::/32 2a00:1450:4000::/37}"
TPWS_MY1_IPSET_SIZE=${TPWS_MY1_IPSET_SIZE:-4096}
TPWS_MY1_IPSET_OPT="${TPWS_MY1_IPSET_OPT:-hash:net hashsize 8192 maxelem $TPWS_MY1_IPSET_SIZE}"
alloc_dnum DNUM_TPWS_MY1
alloc_tpws_port PORT_TPWS_MY1
TPWS_MY1_NAME4=my1tpws4
TPWS_MY1_NAME6=my1tpws6
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
local opt="--port=$PORT_TPWS_MY1 $TPWS_MY1_OPT"
do_tpws $1 $DNUM_TPWS_MY1 "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local f4 f6 subnet
local PORTS_IPT=$(replace_char - : $TPWS_MY1_PORTS)
local dest_set="-m set --match-set $TPWS_MY1_NAME4 dst"
[ "$1" = 1 -a "$DISABLE_IPV4" != 1 ] && {
ipset create $TPWS_MY1_NAME4 $TPWS_MY1_IPSET_OPT family inet 2>/dev/null
ipset flush $TPWS_MY1_NAME4
for subnet in $TPWS_MY1_SUBNETS4; do
echo add $TPWS_MY1_NAME4 $subnet
done | ipset -! restore
}
[ "$1" = 1 -a "$DISABLE_IPV6" != 1 ] && {
ipset create $TPWS_MY1_NAME6 $TPWS_MY1_IPSET_OPT family inet6 2>/dev/null
ipset flush $TPWS_MY1_NAME6
for subnet in $TPWS_MY1_SUBNETS6; do
echo add $TPWS_MY1_NAME6 $subnet
done | ipset -! restore
}
f4="-p tcp -m multiport --dports $PORTS_IPT -m set --match-set"
f6="$f4 $TPWS_MY1_NAME6 dst"
f4="$f4 $TPWS_MY1_NAME4 dst"
fw_tpws $1 "$f4" "$f6" $PORT_TPWS_MY1
[ "$1" = 1 ] || {
ipset destroy $TPWS_MY1_NAME4 2>/dev/null
ipset destroy $TPWS_MY1_NAME6 2>/dev/null
}
}
zapret_custom_firewall_nft()
{
local f4 f6 subnet
[ "$DISABLE_IPV4" != 1 ] && {
make_comma_list subnets $TPWS_MY1_SUBNETS4
nft_create_set $TPWS_MY1_NAME4 "type ipv4_addr; size $TPWS_MY1_IPSET_SIZE; auto-merge; flags interval;"
nft_flush_set $TPWS_MY1_NAME4
nft_add_set_element $TPWS_MY1_NAME4 "$subnets"
}
[ "$DISABLE_IPV6" != 1 ] && {
make_comma_list subnets $TPWS_MY1_SUBNETS6
nft_create_set $TPWS_MY1_NAME6 "type ipv6_addr; size $TPWS_MY1_IPSET_SIZE; auto-merge; flags interval;"
nft_flush_set $TPWS_MY1_NAME6
nft_add_set_element $TPWS_MY1_NAME6 "$subnets"
}
f4="tcp dport {$TPWS_MY1_PORTS}"
f6="$f4 ip6 daddr @$TPWS_MY1_NAME6"
f4="$f4 ip daddr @$TPWS_MY1_NAME4"
nft_fw_tpws "$f4" "$f6" $PORT_TPWS_MY1
}
zapret_custom_firewall_nft_flush()
{
# this function is called after all nft fw rules are deleted
# however sets are not deleted. it's desired to clear sets here.
nft_del_set $TPWS_MY1_NAME4 2>/dev/null
nft_del_set $TPWS_MY1_NAME6 2>/dev/null
}

View File

@@ -0,0 +1,30 @@
# this custom script runs desync to all wireguard handshake initiation packets
# can override in config :
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---dpi-desync=fake}"
alloc_dnum DNUM_WG4ALL
alloc_qnum QNUM_WG4ALL
zapret_custom_daemons()
{
# $1 - 1 - add, 0 - stop
local opt="--qnum=$QNUM_WG4ALL $NFQWS_OPT_DESYNC_WG"
do_nfqws $1 $DNUM_WG4ALL "$opt"
}
# size = 156 (8 udp header + 148 payload) && payload starts with 0x01000000
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local f='-p udp -m u32 --u32'
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x9c&&0>>22&0x3C@8=0x01000000" "$f 44>>16=0x9c&&48=0x01000000" $QNUM_WG4ALL
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local f="udp length 156 @th,64,32 0x01000000"
nft_fw_nfqws_post "$f" "$f" $QNUM_WG4ALL
}

View File

@@ -1,38 +0,0 @@
# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering
# can override in config :
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}"
alloc_dnum DNUM_DHT4ALL
alloc_qnum QNUM_DHT4ALL
zapret_custom_daemons()
{
# stop logic is managed by procd
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
run_daemon $DNUM_DHT4ALL $NFQWS "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local f uf4 uf6
local first_packet_only="$ipt_connbytes 1:1"
f='-p udp -m length --length 109:407 -m u32 --u32'
uf4='0>>22&0x3C@8>>16=0x6431'
uf6='48>>16=0x6431'
fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local f
local first_packet_only="$nft_connbytes 1"
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL
}

File diff suppressed because one or more lines are too long

View File

@@ -10,6 +10,7 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
. "$ZAPRET_BASE/common/ipt.sh" . "$ZAPRET_BASE/common/ipt.sh"
. "$ZAPRET_BASE/common/nft.sh" . "$ZAPRET_BASE/common/nft.sh"
. "$ZAPRET_BASE/common/linux_fw.sh" . "$ZAPRET_BASE/common/linux_fw.sh"
. "$ZAPRET_BASE/common/linux_daemons.sh"
. "$ZAPRET_BASE/common/list.sh" . "$ZAPRET_BASE/common/list.sh"
. "$ZAPRET_BASE/common/custom.sh" . "$ZAPRET_BASE/common/custom.sh"
CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt" CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"

View File

@@ -81,6 +81,10 @@ run_tpws()
} }
run_daemon $1 "$TPWS" "$OPT $2" run_daemon $1 "$TPWS" "$OPT $2"
} }
do_tpws()
{
[ "$1" = 0 ] || { shift; run_tpws "$@"; }
}
run_tpws_socks() run_tpws_socks()
{ {
[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0 [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0
@@ -90,13 +94,10 @@ run_tpws_socks()
tpws_apply_socks_binds opt tpws_apply_socks_binds opt
run_daemon $1 "$TPWS" "$opt $2" run_daemon $1 "$TPWS" "$opt $2"
} }
do_tpws_socks()
stop_tpws()
{ {
stop_daemon $1 "$TPWS" [ "$1" = 0 ] || { shift; run_tpws_socks "$@"; }
} }
tpws_apply_socks_binds() tpws_apply_socks_binds()
{ {
local o local o
@@ -105,39 +106,27 @@ tpws_apply_socks_binds()
[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1" [ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1"
for lan in $OPENWRT_LAN; do for lan in $OPENWRT_LAN; do
network_get_device DEVICE $lan network_get_device DEVICE $lan
[ -n "$DEVICE" ] || continue [ -n "$DEVICE" ] || continue
[ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$DEVICE $TPWS_WAIT" [ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$DEVICE $TPWS_WAIT"
[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$DEVICE --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6" [ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$DEVICE --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6"
done done
eval $1="\"\$$1 $o\"" eval $1="\"\$$1 $o\""
} }
run_nfqws()
standard_mode_daemons()
{ {
local opt run_daemon $1 "$NFQWS" "$NFQWS_OPT_BASE $2"
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$TPWS_OPT" && { }
opt="--port=$TPPORT $TPWS_OPT" do_nfqws()
filter_apply_hostlist_target opt {
run_tpws 1 "$opt" [ "$1" = 0 ] || { shift; run_nfqws "$@"; }
}
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
filter_apply_hostlist_target opt
run_tpws_socks 2 "$opt"
}
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$NFQWS_OPT" && {
opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT"
filter_apply_hostlist_target opt
run_daemon 3 "$NFQWS" "$opt"
}
} }
start_daemons_procd() start_daemons_procd()
{ {
standard_mode_daemons standard_mode_daemons 1
custom_runner zapret_custom_daemons custom_runner zapret_custom_daemons 1
return 0 return 0
} }

View File

@@ -21,4 +21,4 @@ pfctl -d ; pfctl -e
ipfw delete 100 ipfw delete 100
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg
pkill ^dvtws$ pkill ^dvtws$
dvtws --daemon --port 989 --dpi-desync=split2 dvtws --daemon --port 989 --dpi-desync=multisplit

View File

@@ -10,6 +10,7 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
. "$ZAPRET_BASE/common/ipt.sh" . "$ZAPRET_BASE/common/ipt.sh"
. "$ZAPRET_BASE/common/nft.sh" . "$ZAPRET_BASE/common/nft.sh"
. "$ZAPRET_BASE/common/linux_fw.sh" . "$ZAPRET_BASE/common/linux_fw.sh"
. "$ZAPRET_BASE/common/linux_daemons.sh"
. "$ZAPRET_BASE/common/list.sh" . "$ZAPRET_BASE/common/list.sh"
. "$ZAPRET_BASE/common/custom.sh" . "$ZAPRET_BASE/common/custom.sh"
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv" CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
@@ -275,45 +276,3 @@ create_ipset()
echo "Creating ip list table (firewall type $FWTYPE)" echo "Creating ip list table (firewall type $FWTYPE)"
"$IPSET_CR" "$@" "$IPSET_CR" "$@"
} }
standard_mode_daemons()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
do_tpws $1 1 "$opt"
}
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
filter_apply_hostlist_target opt
do_tpws_socks $1 2 "$opt"
}
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
opt="--qnum=$QNUM $NFQWS_OPT"
filter_apply_hostlist_target opt
do_nfqws $1 3 "$opt"
}
}
zapret_do_daemons()
{
# $1 - 1 - run, 0 - stop
standard_mode_daemons $1
custom_runner zapret_custom_daemons $1
return 0
}
zapret_run_daemons()
{
zapret_do_daemons 1 "$@"
}
zapret_stop_daemons()
{
zapret_do_daemons 0 "$@"
}

View File

@@ -26,6 +26,7 @@ IPSET_DIR="$ZAPRET_BASE/ipset"
. "$ZAPRET_BASE/common/ipt.sh" . "$ZAPRET_BASE/common/ipt.sh"
. "$ZAPRET_BASE/common/installer.sh" . "$ZAPRET_BASE/common/installer.sh"
. "$ZAPRET_BASE/common/virt.sh" . "$ZAPRET_BASE/common/virt.sh"
. "$ZAPRET_BASE/common/list.sh"
GET_LIST="$IPSET_DIR/get_config.sh" GET_LIST="$IPSET_DIR/get_config.sh"
@@ -115,6 +116,30 @@ ws_opt_validate()
} }
return 0 return 0
} }
tpws_opt_validate()
{
ws_opt_validate "$1" || return 1
dry_run_tpws || {
echo invalid tpws options
return 1
}
}
tpws_socks_opt_validate()
{
# --ipset allowed here
dry_run_tpws_socks || {
echo invalid tpws options
return 1
}
}
nfqws_opt_validate()
{
ws_opt_validate "$1" || return 1
dry_run_nfqws || {
echo invalid nfqws options
return 1
}
}
select_mode_group() select_mode_group()
{ {
@@ -162,18 +187,17 @@ select_mode_group()
select_mode_tpws_socks() select_mode_tpws_socks()
{ {
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_SOCKS_OPT" local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_SOCKS_OPT"
# --ipset allowed here select_mode_group TPWS_SOCKS_ENABLE "enable tpws socks mode on port $TPPORT_SOCKS ?" "TPPORT_SOCKS TPWS_SOCKS_OPT" tpws_socks_opt_validate TPWS_SOCKS_OPT
select_mode_group TPWS_SOCKS_ENABLE "enable tpws socks mode on port $TPPORT_SOCKS ?" "TPPORT_SOCKS TPWS_SOCKS_OPT"
} }
select_mode_tpws() select_mode_tpws()
{ {
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_OPT" local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_OPT"
select_mode_group TPWS_ENABLE "enable tpws transparent mode ?" "TPWS_PORTS TPWS_OPT" ws_opt_validate TPWS_OPT select_mode_group TPWS_ENABLE "enable tpws transparent mode ?" "TPWS_PORTS TPWS_OPT" tpws_opt_validate TPWS_OPT
} }
select_mode_nfqws() select_mode_nfqws()
{ {
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="NFQWS_OPT" local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="NFQWS_OPT"
select_mode_group NFQWS_ENABLE "enable nfqws ?" "NFQWS_PORTS_TCP NFQWS_PORTS_UDP NFQWS_TCP_PKT_OUT NFQWS_TCP_PKT_IN NFQWS_UDP_PKT_OUT NFQWS_UDP_PKT_IN NFQWS_PORTS_TCP_KEEPALIVE NFQWS_PORTS_UDP_KEEPALIVE NFQWS_OPT" ws_opt_validate NFQWS_OPT select_mode_group NFQWS_ENABLE "enable nfqws ?" "NFQWS_PORTS_TCP NFQWS_PORTS_UDP NFQWS_TCP_PKT_OUT NFQWS_TCP_PKT_IN NFQWS_UDP_PKT_OUT NFQWS_UDP_PKT_IN NFQWS_PORTS_TCP_KEEPALIVE NFQWS_PORTS_UDP_KEEPALIVE NFQWS_OPT" nfqws_opt_validate NFQWS_OPT
} }
select_mode_mode() select_mode_mode()
@@ -370,7 +394,7 @@ copy_openwrt()
mkdir "$2/tpws" "$2/nfq" "$2/ip2net" "$2/mdig" "$2/binaries" "$2/binaries/$ARCH" "$2/init.d" "$2/tmp" "$2/files" mkdir "$2/tpws" "$2/nfq" "$2/ip2net" "$2/mdig" "$2/binaries" "$2/binaries/$ARCH" "$2/init.d" "$2/tmp" "$2/files"
cp -R "$1/files/fake" "$2/files" cp -R "$1/files/fake" "$2/files"
cp -R "$1/common" "$1/ipset" "$2" cp -R "$1/common" "$1/ipset" "$2"
cp -R "$1/init.d/openwrt" "$2/init.d" cp -R "$1/init.d/openwrt" "$1/init.d/custom.d.examples.linux" "$2/init.d"
cp "$1/config" "$1/config.default" "$1/install_easy.sh" "$1/uninstall_easy.sh" "$1/install_bin.sh" "$1/install_prereq.sh" "$1/blockcheck.sh" "$2" cp "$1/config" "$1/config.default" "$1/install_easy.sh" "$1/uninstall_easy.sh" "$1/install_bin.sh" "$1/install_prereq.sh" "$1/blockcheck.sh" "$2"
cp "$BINDIR/tpws" "$BINDIR/nfqws" "$BINDIR/ip2net" "$BINDIR/mdig" "$2/binaries/$ARCH" cp "$BINDIR/tpws" "$BINDIR/nfqws" "$BINDIR/ip2net" "$BINDIR/mdig" "$2/binaries/$ARCH"
} }

View File

@@ -152,50 +152,62 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
DLOG("packet: id=%d pass unmodified\n", id); DLOG("packet: id=%d pass unmodified\n", id);
return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, 0, NULL); return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, 0, NULL);
} }
static int nfq_main(void) static void nfq_deinit(struct nfq_handle **h,struct nfq_q_handle **qh)
{ {
struct nfq_handle *h = NULL; if (*qh)
struct nfq_q_handle *qh = NULL; {
int fd,rv; DLOG_CONDUP("unbinding from queue %u\n", params.qnum);
uint8_t buf[16384] __attribute__((aligned)); nfq_destroy_queue(*qh);
*qh = NULL;
}
if (*h)
{
DLOG_CONDUP("closing library handle\n");
nfq_close(*h);
*h = NULL;
}
}
static bool nfq_init(struct nfq_handle **h,struct nfq_q_handle **qh)
{
nfq_deinit(h,qh);
DLOG_CONDUP("opening library handle\n"); DLOG_CONDUP("opening library handle\n");
h = nfq_open(); *h = nfq_open();
if (!h) { if (!*h) {
DLOG_PERROR("nfq_open()"); DLOG_PERROR("nfq_open()");
goto exiterr; goto exiterr;
} }
DLOG_CONDUP("unbinding existing nf_queue handler for AF_INET (if any)\n"); DLOG_CONDUP("unbinding existing nf_queue handler for AF_INET (if any)\n");
if (nfq_unbind_pf(h, AF_INET) < 0) { if (nfq_unbind_pf(*h, AF_INET) < 0) {
DLOG_PERROR("nfq_unbind_pf()"); DLOG_PERROR("nfq_unbind_pf()");
goto exiterr; goto exiterr;
} }
DLOG_CONDUP("binding nfnetlink_queue as nf_queue handler for AF_INET\n"); DLOG_CONDUP("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
if (nfq_bind_pf(h, AF_INET) < 0) { if (nfq_bind_pf(*h, AF_INET) < 0) {
DLOG_PERROR("nfq_bind_pf()"); DLOG_PERROR("nfq_bind_pf()");
goto exiterr; goto exiterr;
} }
DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum); DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum);
qh = nfq_create_queue(h, params.qnum, &nfq_cb, &params); *qh = nfq_create_queue(*h, params.qnum, &nfq_cb, &params);
if (!qh) { if (!*qh) {
DLOG_PERROR("nfq_create_queue()"); DLOG_PERROR("nfq_create_queue()");
goto exiterr; goto exiterr;
} }
DLOG_CONDUP("setting copy_packet mode\n"); DLOG_CONDUP("setting copy_packet mode\n");
if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { if (nfq_set_mode(*qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
DLOG_PERROR("can't set packet_copy mode"); DLOG_PERROR("can't set packet_copy mode");
goto exiterr; goto exiterr;
} }
if (nfq_set_queue_maxlen(qh, Q_MAXLEN) < 0) { if (nfq_set_queue_maxlen(*qh, Q_MAXLEN) < 0) {
DLOG_PERROR("can't set queue maxlen"); DLOG_PERROR("can't set queue maxlen");
goto exiterr; goto exiterr;
} }
// accept packets if they cant be handled // accept packets if they cant be handled
if (nfq_set_queue_flags(qh, NFQA_CFG_F_FAIL_OPEN , NFQA_CFG_F_FAIL_OPEN)) if (nfq_set_queue_flags(*qh, NFQA_CFG_F_FAIL_OPEN , NFQA_CFG_F_FAIL_OPEN))
{ {
DLOG_ERR("can't set queue flags. its OK on linux <3.6\n"); DLOG_ERR("can't set queue flags. its OK on linux <3.6\n");
// dot not fail. not supported on old linuxes <3.6 // dot not fail. not supported on old linuxes <3.6
@@ -205,6 +217,27 @@ static int nfq_main(void)
if (!rawsend_preinit(params.bind_fix4,params.bind_fix6)) if (!rawsend_preinit(params.bind_fix4,params.bind_fix6))
goto exiterr; goto exiterr;
int yes=1, fd = nfq_fd(*h);
#if defined SOL_NETLINK && defined NETLINK_NO_ENOBUFS
if (setsockopt(fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &yes, sizeof(yes)) == -1)
DLOG_PERROR("setsockopt(NETLINK_NO_ENOBUFS)");
#endif
return true;
exiterr:
nfq_deinit(h,qh);
return false;
}
static int nfq_main(void)
{
uint8_t buf[16384] __attribute__((aligned));
struct nfq_handle *h = NULL;
struct nfq_q_handle *qh = NULL;
int fd,e;
ssize_t rd;
#ifndef __CYGWIN__ #ifndef __CYGWIN__
sec_harden(); sec_harden();
@@ -216,36 +249,31 @@ static int nfq_main(void)
pre_desync(); pre_desync();
fd = nfq_fd(h); if (!nfq_init(&h,&qh))
// increase socket buffer size. on slow systems reloading hostlist can take a while.
// if too many unhandled packets are received its possible to get "no buffer space available" error
if (!set_socket_buffers(fd,Q_RCVBUF/2,Q_SNDBUF/2))
goto exiterr; goto exiterr;
fd = nfq_fd(h);
do do
{ {
while ((rv = recv(fd, buf, sizeof(buf), 0)) > 0) while ((rd = recv(fd, buf, sizeof(buf), 0)) >= 0)
{ {
int r = nfq_handle_packet(h, (char *)buf, rv); if (rd)
if (r) DLOG_ERR("nfq_handle_packet error %d\n", r); {
int r = nfq_handle_packet(h, (char *)buf, (int)rd);
if (r) DLOG_ERR("nfq_handle_packet error %d\n", r);
}
else
DLOG("recv from nfq returned 0 !\n");
} }
DLOG_ERR("recv: errno %d\n",errno); e=errno;
DLOG_ERR("recv: recv=%zd errno %d\n",rd,e);
errno=e;
DLOG_PERROR("recv"); DLOG_PERROR("recv");
// do not fail on ENOBUFS // do not fail on ENOBUFS
} while(errno==ENOBUFS); } while(e==ENOBUFS);
DLOG_CONDUP("unbinding from queue %u\n", params.qnum); nfq_deinit(&h,&qh);
nfq_destroy_queue(qh);
#ifdef INSANE
/* normally, applications SHOULD NOT issue this command, since
* it detaches other programs/sockets from AF_INET, too ! */
DLOG_CONDUP("unbinding from AF_INET\n");
nfq_unbind_pf(h, AF_INET);
#endif
DLOG_CONDUP("closing library handle\n");
nfq_close(h);
return 0; return 0;
exiterr: exiterr:
@@ -1030,6 +1058,7 @@ static void exithelp(void)
" @<config_file>|$<config_file>\t\t\t; read file for options. must be the only argument. other options are ignored.\n\n" " @<config_file>|$<config_file>\t\t\t; read file for options. must be the only argument. other options are ignored.\n\n"
#endif #endif
" --debug=0|1|syslog|@<filename>\n" " --debug=0|1|syslog|@<filename>\n"
" --dry-run\t\t\t\t\t; verify parameters and exit with code 0 if successful\n"
#ifdef __linux__ #ifdef __linux__
" --qnum=<nfqueue_number>\n" " --qnum=<nfqueue_number>\n"
#elif defined(BSD) #elif defined(BSD)
@@ -1195,7 +1224,7 @@ int main(int argc, char **argv)
#endif #endif
int result, v; int result, v;
int option_index = 0; int option_index = 0;
bool daemon = false, bSkip = false; bool daemon = false, bSkip = false, bDry = false;
char pidfile[256]; char pidfile[256];
struct hostlist_file *anon_hl = NULL, *anon_hl_exclude = NULL; struct hostlist_file *anon_hl = NULL, *anon_hl_exclude = NULL;
struct ipset_file *anon_ips = NULL, *anon_ips_exclude = NULL; struct ipset_file *anon_ips = NULL, *anon_ips_exclude = NULL;
@@ -1263,108 +1292,115 @@ int main(int argc, char **argv)
const struct option long_options[] = { const struct option long_options[] = {
{"debug",optional_argument,0,0}, // optidx=0 {"debug",optional_argument,0,0}, // optidx=0
{"dry-run",no_argument,0,0}, // optidx=1
#ifdef __linux__ #ifdef __linux__
{"qnum",required_argument,0,0}, // optidx=1 {"qnum",required_argument,0,0}, // optidx=2
#elif defined(BSD) #elif defined(BSD)
{"port",required_argument,0,0}, // optidx=1 {"port",required_argument,0,0}, // optidx=2
#else #else
{"disabled_argument_1",no_argument,0,0},// optidx=1 {"disabled_argument_1",no_argument,0,0},// optidx=2
#endif #endif
{"daemon",no_argument,0,0}, // optidx=2 {"daemon",no_argument,0,0}, // optidx=3
{"pidfile",required_argument,0,0}, // optidx=3 {"pidfile",required_argument,0,0}, // optidx=4
#ifndef __CYGWIN__ #ifndef __CYGWIN__
{"user",required_argument,0,0 }, // optidx=4 {"user",required_argument,0,0 }, // optidx=5
{"uid",required_argument,0,0 }, // optidx=5 {"uid",required_argument,0,0 }, // optidx=6
#else #else
{"disabled_argument_2",no_argument,0,0}, // optidx=4 {"disabled_argument_2",no_argument,0,0}, // optidx=5
{"disabled_argument_3",no_argument,0,0}, // optidx=5 {"disabled_argument_3",no_argument,0,0}, // optidx=6
#endif #endif
{"wsize",required_argument,0,0}, // optidx=6 {"wsize",required_argument,0,0}, // optidx=7
{"wssize",required_argument,0,0}, // optidx=7 {"wssize",required_argument,0,0}, // optidx=8
{"wssize-cutoff",required_argument,0,0},// optidx=8 {"wssize-cutoff",required_argument,0,0},// optidx=9
{"ctrack-timeouts",required_argument,0,0},// optidx=9 {"ctrack-timeouts",required_argument,0,0},// optidx=10
{"hostcase",no_argument,0,0}, // optidx=10 {"hostcase",no_argument,0,0}, // optidx=11
{"hostspell",required_argument,0,0}, // optidx=11 {"hostspell",required_argument,0,0}, // optidx=12
{"hostnospace",no_argument,0,0}, // optidx=12 {"hostnospace",no_argument,0,0}, // optidx=13
{"domcase",no_argument,0,0 }, // optidx=13 {"domcase",no_argument,0,0 }, // optidx=14
{"methodeol",no_argument,0,0 }, // optidx=14 {"methodeol",no_argument,0,0 }, // optidx=15
{"dpi-desync",required_argument,0,0}, // optidx=15 {"dpi-desync",required_argument,0,0}, // optidx=17
#ifdef __linux__ #ifdef __linux__
{"dpi-desync-fwmark",required_argument,0,0}, // optidx=16 {"dpi-desync-fwmark",required_argument,0,0}, // optidx=17
#elif defined(SO_USER_COOKIE) #elif defined(SO_USER_COOKIE)
{"dpi-desync-sockarg",required_argument,0,0}, // optidx=16 {"dpi-desync-sockarg",required_argument,0,0}, // optidx=17
#else #else
{"disabled_argument_4",no_argument,0,0}, // optidx=16 {"disabled_argument_4",no_argument,0,0}, // optidx=17
#endif #endif
{"dpi-desync-ttl",required_argument,0,0}, // optidx=17 {"dpi-desync-ttl",required_argument,0,0}, // optidx=18
{"dpi-desync-ttl6",required_argument,0,0}, // optidx=18 {"dpi-desync-ttl6",required_argument,0,0}, // optidx=19
{"dpi-desync-autottl",optional_argument,0,0}, // optidx=19 {"dpi-desync-autottl",optional_argument,0,0}, // optidx=20
{"dpi-desync-autottl6",optional_argument,0,0}, // optidx=20 {"dpi-desync-autottl6",optional_argument,0,0}, // optidx=21
{"dpi-desync-fooling",required_argument,0,0}, // optidx=21 {"dpi-desync-fooling",required_argument,0,0}, // optidx=22
{"dpi-desync-repeats",required_argument,0,0}, // optidx=22 {"dpi-desync-repeats",required_argument,0,0}, // optidx=23
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=23 {"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=24
{"dpi-desync-split-pos",required_argument,0,0},// optidx=24 {"dpi-desync-split-pos",required_argument,0,0},// optidx=25
{"dpi-desync-split-http-req",required_argument,0,0 },// optidx=25 {"dpi-desync-split-http-req",required_argument,0,0 },// optidx=26
{"dpi-desync-split-tls",required_argument,0,0 },// optidx=26 {"dpi-desync-split-tls",required_argument,0,0 },// optidx=27
{"dpi-desync-split-seqovl",required_argument,0,0 },// optidx=27 {"dpi-desync-split-seqovl",required_argument,0,0 },// optidx=28
{"dpi-desync-split-seqovl-pattern",required_argument,0,0 },// optidx=28 {"dpi-desync-split-seqovl-pattern",required_argument,0,0 },// optidx=29
{"dpi-desync-fakedsplit-pattern",required_argument,0,0 },// optidx=29 {"dpi-desync-fakedsplit-pattern",required_argument,0,0 },// optidx=30
{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=30 {"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=31
{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=31 {"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=32
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=32 {"dpi-desync-badseq-increment",required_argument,0,0},// optidx=33
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=33 {"dpi-desync-badack-increment",required_argument,0,0},// optidx=34
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=34 {"dpi-desync-any-protocol",optional_argument,0,0},// optidx=35
{"dpi-desync-fake-http",required_argument,0,0},// optidx=35 {"dpi-desync-fake-http",required_argument,0,0},// optidx=36
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=36 {"dpi-desync-fake-tls",required_argument,0,0},// optidx=37
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=37 {"dpi-desync-fake-unknown",required_argument,0,0},// optidx=38
{"dpi-desync-fake-syndata",required_argument,0,0},// optidx=38 {"dpi-desync-fake-syndata",required_argument,0,0},// optidx=39
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=39 {"dpi-desync-fake-quic",required_argument,0,0},// optidx=40
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=40 {"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=41
{"dpi-desync-fake-dht",required_argument,0,0},// optidx=41 {"dpi-desync-fake-dht",required_argument,0,0},// optidx=42
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=42 {"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=43
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=43 {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=44
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=44 {"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=45
{"dpi-desync-cutoff",required_argument,0,0},// optidx=45 {"dpi-desync-cutoff",required_argument,0,0},// optidx=46
{"dpi-desync-start",required_argument,0,0},// optidx=46 {"dpi-desync-start",required_argument,0,0},// optidx=47
{"hostlist",required_argument,0,0}, // optidx=47 {"hostlist",required_argument,0,0}, // optidx=48
{"hostlist-domains",required_argument,0,0},// optidx=48 {"hostlist-domains",required_argument,0,0},// optidx=49
{"hostlist-exclude",required_argument,0,0}, // optidx=49 {"hostlist-exclude",required_argument,0,0}, // optidx=50
{"hostlist-exclude-domains",required_argument,0,0},// optidx=50 {"hostlist-exclude-domains",required_argument,0,0},// optidx=51
{"hostlist-auto",required_argument,0,0}, // optidx=51 {"hostlist-auto",required_argument,0,0}, // optidx=52
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=52 {"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=53
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=53 {"hostlist-auto-fail-time",required_argument,0,0}, // optidx=54
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=54 {"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=55
{"hostlist-auto-debug",required_argument,0,0}, // optidx=55 {"hostlist-auto-debug",required_argument,0,0}, // optidx=56
{"new",no_argument,0,0}, // optidx=56 {"new",no_argument,0,0}, // optidx=57
{"skip",no_argument,0,0}, // optidx=57 {"skip",no_argument,0,0}, // optidx=58
{"filter-l3",required_argument,0,0}, // optidx=58 {"filter-l3",required_argument,0,0}, // optidx=59
{"filter-tcp",required_argument,0,0}, // optidx=59 {"filter-tcp",required_argument,0,0}, // optidx=60
{"filter-udp",required_argument,0,0}, // optidx=60 {"filter-udp",required_argument,0,0}, // optidx=61
{"filter-l7",required_argument,0,0}, // optidx=61 {"filter-l7",required_argument,0,0}, // optidx=62
{"ipset",required_argument,0,0}, // optidx=62 {"ipset",required_argument,0,0}, // optidx=63
{"ipset-ip",required_argument,0,0}, // optidx=63 {"ipset-ip",required_argument,0,0}, // optidx=64
{"ipset-exclude",required_argument,0,0},// optidx=64 {"ipset-exclude",required_argument,0,0},// optidx=65
{"ipset-exclude-ip",required_argument,0,0}, // optidx=65 {"ipset-exclude-ip",required_argument,0,0}, // optidx=66
#ifdef __linux__ #ifdef __linux__
{"bind-fix4",no_argument,0,0}, // optidx=66 {"bind-fix4",no_argument,0,0}, // optidx=67
{"bind-fix6",no_argument,0,0}, // optidx=67 {"bind-fix6",no_argument,0,0}, // optidx=68
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
{"wf-iface",required_argument,0,0}, // optidx=66 {"wf-iface",required_argument,0,0}, // optidx=67
{"wf-l3",required_argument,0,0}, // optidx=67 {"wf-l3",required_argument,0,0}, // optidx=68
{"wf-tcp",required_argument,0,0}, // optidx=68 {"wf-tcp",required_argument,0,0}, // optidx=69
{"wf-udp",required_argument,0,0}, // optidx=69 {"wf-udp",required_argument,0,0}, // optidx=70
{"wf-raw",required_argument,0,0}, // optidx=70 {"wf-raw",required_argument,0,0}, // optidx=71
{"wf-save",required_argument,0,0}, // optidx=71 {"wf-save",required_argument,0,0}, // optidx=72
{"ssid-filter",required_argument,0,0}, // optidx=72 {"ssid-filter",required_argument,0,0}, // optidx=73
{"nlm-filter",required_argument,0,0}, // optidx=73 {"nlm-filter",required_argument,0,0}, // optidx=74
{"nlm-list",optional_argument,0,0}, // optidx=74 {"nlm-list",optional_argument,0,0}, // optidx=75
#endif #endif
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
if (argc < 2) exithelp(); if (argc < 2) exithelp_clean();
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
{ {
if (v) exithelp(); if (v)
{
if (bDry)
exit_clean(1);
else
exithelp_clean();
}
switch (option_index) switch (option_index)
{ {
case 0: /* debug */ case 0: /* debug */
@@ -1401,8 +1437,10 @@ int main(int argc, char **argv)
params.debug_target = LOG_TARGET_CONSOLE; params.debug_target = LOG_TARGET_CONSOLE;
} }
break; break;
#ifndef __CYGWIN__ case 1: /* dry-run */
case 1: /* qnum or port */ bDry=true;
break;
case 2: /* qnum or port */
#ifdef __linux__ #ifdef __linux__
params.qnum = atoi(optarg); params.qnum = atoi(optarg);
if (params.qnum < 0 || params.qnum>65535) if (params.qnum < 0 || params.qnum>65535)
@@ -1422,16 +1460,15 @@ int main(int argc, char **argv)
} }
#endif #endif
break; break;
#endif case 3: /* daemon */
case 2: /* daemon */
daemon = true; daemon = true;
break; break;
case 3: /* pidfile */ case 4: /* pidfile */
strncpy(pidfile, optarg, sizeof(pidfile)); strncpy(pidfile, optarg, sizeof(pidfile));
pidfile[sizeof(pidfile) - 1] = '\0'; pidfile[sizeof(pidfile) - 1] = '\0';
break; break;
#ifndef __CYGWIN__ #ifndef __CYGWIN__
case 4: /* user */ case 5: /* user */
{ {
struct passwd *pwd = getpwnam(optarg); struct passwd *pwd = getpwnam(optarg);
if (!pwd) if (!pwd)
@@ -1444,7 +1481,7 @@ int main(int argc, char **argv)
params.droproot = true; params.droproot = true;
break; break;
} }
case 5: /* uid */ case 6: /* uid */
params.gid = 0x7FFFFFFF; // default gid. drop gid=0 params.gid = 0x7FFFFFFF; // default gid. drop gid=0
params.droproot = true; params.droproot = true;
if (sscanf(optarg, "%u:%u", &params.uid, &params.gid)<1) if (sscanf(optarg, "%u:%u", &params.uid, &params.gid)<1)
@@ -1454,32 +1491,32 @@ int main(int argc, char **argv)
} }
break; break;
#endif #endif
case 6: /* wsize */ case 7: /* wsize */
if (!parse_ws_scale_factor(optarg,&dp->wsize,&dp->wscale)) if (!parse_ws_scale_factor(optarg,&dp->wsize,&dp->wscale))
exit_clean(1); exit_clean(1);
break; break;
case 7: /* wssize */ case 8: /* wssize */
if (!parse_ws_scale_factor(optarg,&dp->wssize,&dp->wsscale)) if (!parse_ws_scale_factor(optarg,&dp->wssize,&dp->wsscale))
exit_clean(1); exit_clean(1);
break; break;
case 8: /* wssize-cutoff */ case 9: /* wssize-cutoff */
if (!parse_cutoff(optarg, &dp->wssize_cutoff, &dp->wssize_cutoff_mode)) if (!parse_cutoff(optarg, &dp->wssize_cutoff, &dp->wssize_cutoff_mode))
{ {
DLOG_ERR("invalid wssize-cutoff value\n"); DLOG_ERR("invalid wssize-cutoff value\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 9: /* ctrack-timeouts */ case 10: /* ctrack-timeouts */
if (sscanf(optarg, "%u:%u:%u:%u", &params.ctrack_t_syn, &params.ctrack_t_est, &params.ctrack_t_fin, &params.ctrack_t_udp)<3) if (sscanf(optarg, "%u:%u:%u:%u", &params.ctrack_t_syn, &params.ctrack_t_est, &params.ctrack_t_fin, &params.ctrack_t_udp)<3)
{ {
DLOG_ERR("invalid ctrack-timeouts value\n"); DLOG_ERR("invalid ctrack-timeouts value\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 10: /* hostcase */ case 11: /* hostcase */
dp->hostcase = true; dp->hostcase = true;
break; break;
case 11: /* hostspell */ case 12: /* hostspell */
if (strlen(optarg) != 4) if (strlen(optarg) != 4)
{ {
DLOG_ERR("hostspell must be exactly 4 chars long\n"); DLOG_ERR("hostspell must be exactly 4 chars long\n");
@@ -1488,7 +1525,7 @@ int main(int argc, char **argv)
dp->hostcase = true; dp->hostcase = true;
memcpy(dp->hostspell, optarg, 4); memcpy(dp->hostspell, optarg, 4);
break; break;
case 12: /* hostnospace */ case 13: /* hostnospace */
if (dp->methodeol) if (dp->methodeol)
{ {
DLOG_ERR("--hostnospace and --methodeol are incompatible\n"); DLOG_ERR("--hostnospace and --methodeol are incompatible\n");
@@ -1496,10 +1533,10 @@ int main(int argc, char **argv)
} }
dp->hostnospace = true; dp->hostnospace = true;
break; break;
case 13: /* domcase */ case 14: /* domcase */
dp->domcase = true; dp->domcase = true;
break; break;
case 14: /* methodeol */ case 15: /* methodeol */
if (dp->hostnospace) if (dp->hostnospace)
{ {
DLOG_ERR("--hostnospace and --methodeol are incompatible\n"); DLOG_ERR("--hostnospace and --methodeol are incompatible\n");
@@ -1507,7 +1544,7 @@ int main(int argc, char **argv)
} }
dp->methodeol = true; dp->methodeol = true;
break; break;
case 15: /* dpi-desync */ case 16: /* dpi-desync */
{ {
char *mode=optarg,*mode2,*mode3; char *mode=optarg,*mode2,*mode3;
mode2 = mode ? strchr(mode,',') : NULL; mode2 = mode ? strchr(mode,',') : NULL;
@@ -1553,7 +1590,7 @@ int main(int argc, char **argv)
} }
break; break;
#ifndef __CYGWIN__ #ifndef __CYGWIN__
case 16: /* dpi-desync-fwmark/dpi-desync-sockarg */ case 17: /* dpi-desync-fwmark/dpi-desync-sockarg */
#if defined(__linux__) || defined(SO_USER_COOKIE) #if defined(__linux__) || defined(SO_USER_COOKIE)
params.desync_fwmark = 0; params.desync_fwmark = 0;
if (sscanf(optarg, "0x%X", &params.desync_fwmark)<=0) sscanf(optarg, "%u", &params.desync_fwmark); if (sscanf(optarg, "0x%X", &params.desync_fwmark)<=0) sscanf(optarg, "%u", &params.desync_fwmark);
@@ -1568,27 +1605,27 @@ int main(int argc, char **argv)
#endif #endif
break; break;
#endif #endif
case 17: /* dpi-desync-ttl */ case 18: /* dpi-desync-ttl */
dp->desync_ttl = (uint8_t)atoi(optarg); dp->desync_ttl = (uint8_t)atoi(optarg);
break; break;
case 18: /* dpi-desync-ttl6 */ case 19: /* dpi-desync-ttl6 */
dp->desync_ttl6 = (uint8_t)atoi(optarg); dp->desync_ttl6 = (uint8_t)atoi(optarg);
break; break;
case 19: /* dpi-desync-autottl */ case 20: /* dpi-desync-autottl */
if (!parse_autottl(optarg, &dp->desync_autottl)) if (!parse_autottl(optarg, &dp->desync_autottl))
{ {
DLOG_ERR("dpi-desync-autottl value error\n"); DLOG_ERR("dpi-desync-autottl value error\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 20: /* dpi-desync-autottl6 */ case 21: /* dpi-desync-autottl6 */
if (!parse_autottl(optarg, &dp->desync_autottl6)) if (!parse_autottl(optarg, &dp->desync_autottl6))
{ {
DLOG_ERR("dpi-desync-autottl6 value error\n"); DLOG_ERR("dpi-desync-autottl6 value error\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 21: /* dpi-desync-fooling */ case 22: /* dpi-desync-fooling */
{ {
char *e,*p = optarg; char *e,*p = optarg;
while (p) while (p)
@@ -1623,17 +1660,17 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 22: /* dpi-desync-repeats */ case 23: /* dpi-desync-repeats */
if (sscanf(optarg,"%u",&dp->desync_repeats)<1 || !dp->desync_repeats || dp->desync_repeats>20) if (sscanf(optarg,"%u",&dp->desync_repeats)<1 || !dp->desync_repeats || dp->desync_repeats>20)
{ {
DLOG_ERR("dpi-desync-repeats must be within 1..20\n"); DLOG_ERR("dpi-desync-repeats must be within 1..20\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 23: /* dpi-desync-skip-nosni */ case 24: /* dpi-desync-skip-nosni */
dp->desync_skip_nosni = !optarg || atoi(optarg); dp->desync_skip_nosni = !optarg || atoi(optarg);
break; break;
case 24: /* dpi-desync-split-pos */ case 25: /* dpi-desync-split-pos */
{ {
int ct; int ct;
if (!parse_split_pos_list(optarg,dp->splits+dp->split_count,MAX_SPLITS-dp->split_count,&ct)) if (!parse_split_pos_list(optarg,dp->splits+dp->split_count,MAX_SPLITS-dp->split_count,&ct))
@@ -1644,7 +1681,7 @@ int main(int argc, char **argv)
dp->split_count += ct; dp->split_count += ct;
} }
break; break;
case 25: /* dpi-desync-split-http-req */ case 26: /* dpi-desync-split-http-req */
// obsolete arg // obsolete arg
DLOG_CONDUP("WARNING ! --dpi-desync-split-http-req is deprecated. use --dpi-desync-split-pos with markers.\n",MAX_SPLITS); DLOG_CONDUP("WARNING ! --dpi-desync-split-http-req is deprecated. use --dpi-desync-split-pos with markers.\n",MAX_SPLITS);
if (dp->split_count>=MAX_SPLITS) if (dp->split_count>=MAX_SPLITS)
@@ -1659,7 +1696,7 @@ int main(int argc, char **argv)
} }
dp->split_count++; dp->split_count++;
break; break;
case 26: /* dpi-desync-split-tls */ case 27: /* dpi-desync-split-tls */
// obsolete arg // obsolete arg
DLOG_CONDUP("WARNING ! --dpi-desync-split-tls is deprecated. use --dpi-desync-split-pos with markers.\n",MAX_SPLITS); DLOG_CONDUP("WARNING ! --dpi-desync-split-tls is deprecated. use --dpi-desync-split-pos with markers.\n",MAX_SPLITS);
if (dp->split_count>=MAX_SPLITS) if (dp->split_count>=MAX_SPLITS)
@@ -1674,7 +1711,7 @@ int main(int argc, char **argv)
} }
dp->split_count++; dp->split_count++;
break; break;
case 27: /* dpi-desync-split-seqovl */ case 28: /* dpi-desync-split-seqovl */
if (!strcmp(optarg,"0")) if (!strcmp(optarg,"0"))
{ {
// allow zero = disable seqovl // allow zero = disable seqovl
@@ -1687,7 +1724,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 28: /* dpi-desync-split-seqovl-pattern */ case 29: /* dpi-desync-split-seqovl-pattern */
{ {
char buf[sizeof(dp->seqovl_pattern)]; char buf[sizeof(dp->seqovl_pattern)];
size_t sz=sizeof(buf); size_t sz=sizeof(buf);
@@ -1695,7 +1732,7 @@ int main(int argc, char **argv)
fill_pattern(dp->seqovl_pattern,sizeof(dp->seqovl_pattern),buf,sz); fill_pattern(dp->seqovl_pattern,sizeof(dp->seqovl_pattern),buf,sz);
} }
break; break;
case 29: /* dpi-desync-fakedsplit-pattern */ case 30: /* dpi-desync-fakedsplit-pattern */
{ {
char buf[sizeof(dp->fsplit_pattern)]; char buf[sizeof(dp->fsplit_pattern)];
size_t sz=sizeof(buf); size_t sz=sizeof(buf);
@@ -1703,7 +1740,7 @@ int main(int argc, char **argv)
fill_pattern(dp->fsplit_pattern,sizeof(dp->fsplit_pattern),buf,sz); fill_pattern(dp->fsplit_pattern,sizeof(dp->fsplit_pattern),buf,sz);
} }
break; break;
case 30: /* dpi-desync-ipfrag-pos-tcp */ case 31: /* dpi-desync-ipfrag-pos-tcp */
if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_tcp)<1 || dp->desync_ipfrag_pos_tcp<1 || dp->desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN) if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_tcp)<1 || dp->desync_ipfrag_pos_tcp<1 || dp->desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN)
{ {
DLOG_ERR("dpi-desync-ipfrag-pos-tcp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN); DLOG_ERR("dpi-desync-ipfrag-pos-tcp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
@@ -1715,7 +1752,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 31: /* dpi-desync-ipfrag-pos-udp */ case 32: /* dpi-desync-ipfrag-pos-udp */
if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_udp)<1 || dp->desync_ipfrag_pos_udp<1 || dp->desync_ipfrag_pos_udp>DPI_DESYNC_MAX_FAKE_LEN) if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_udp)<1 || dp->desync_ipfrag_pos_udp<1 || dp->desync_ipfrag_pos_udp>DPI_DESYNC_MAX_FAKE_LEN)
{ {
DLOG_ERR("dpi-desync-ipfrag-pos-udp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN); DLOG_ERR("dpi-desync-ipfrag-pos-udp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
@@ -1727,63 +1764,63 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 32: /* dpi-desync-badseq-increments */ case 33: /* dpi-desync-badseq-increments */
if (!parse_badseq_increment(optarg,&dp->desync_badseq_increment)) if (!parse_badseq_increment(optarg,&dp->desync_badseq_increment))
{ {
DLOG_ERR("dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n"); DLOG_ERR("dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 33: /* dpi-desync-badack-increment */ case 34: /* dpi-desync-badack-increment */
if (!parse_badseq_increment(optarg,&dp->desync_badseq_ack_increment)) if (!parse_badseq_increment(optarg,&dp->desync_badseq_ack_increment))
{ {
DLOG_ERR("dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n"); DLOG_ERR("dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 34: /* dpi-desync-any-protocol */ case 35: /* dpi-desync-any-protocol */
dp->desync_any_proto = !optarg || atoi(optarg); dp->desync_any_proto = !optarg || atoi(optarg);
break; break;
case 35: /* dpi-desync-fake-http */ case 36: /* dpi-desync-fake-http */
dp->fake_http_size = sizeof(dp->fake_http); dp->fake_http_size = sizeof(dp->fake_http);
load_file_or_exit(optarg,dp->fake_http,&dp->fake_http_size); load_file_or_exit(optarg,dp->fake_http,&dp->fake_http_size);
break; break;
case 36: /* dpi-desync-fake-tls */ case 37: /* dpi-desync-fake-tls */
dp->fake_tls_size = sizeof(dp->fake_tls); dp->fake_tls_size = sizeof(dp->fake_tls);
load_file_or_exit(optarg,dp->fake_tls,&dp->fake_tls_size); load_file_or_exit(optarg,dp->fake_tls,&dp->fake_tls_size);
break; break;
case 37: /* dpi-desync-fake-unknown */ case 38: /* dpi-desync-fake-unknown */
dp->fake_unknown_size = sizeof(dp->fake_unknown); dp->fake_unknown_size = sizeof(dp->fake_unknown);
load_file_or_exit(optarg,dp->fake_unknown,&dp->fake_unknown_size); load_file_or_exit(optarg,dp->fake_unknown,&dp->fake_unknown_size);
break; break;
case 38: /* dpi-desync-fake-syndata */ case 39: /* dpi-desync-fake-syndata */
dp->fake_syndata_size = sizeof(dp->fake_syndata); dp->fake_syndata_size = sizeof(dp->fake_syndata);
load_file_or_exit(optarg,dp->fake_syndata,&dp->fake_syndata_size); load_file_or_exit(optarg,dp->fake_syndata,&dp->fake_syndata_size);
break; break;
case 39: /* dpi-desync-fake-quic */ case 40: /* dpi-desync-fake-quic */
dp->fake_quic_size = sizeof(dp->fake_quic); dp->fake_quic_size = sizeof(dp->fake_quic);
load_file_or_exit(optarg,dp->fake_quic,&dp->fake_quic_size); load_file_or_exit(optarg,dp->fake_quic,&dp->fake_quic_size);
break; break;
case 40: /* dpi-desync-fake-wireguard */ case 41: /* dpi-desync-fake-wireguard */
dp->fake_wg_size = sizeof(dp->fake_wg); dp->fake_wg_size = sizeof(dp->fake_wg);
load_file_or_exit(optarg,dp->fake_wg,&dp->fake_wg_size); load_file_or_exit(optarg,dp->fake_wg,&dp->fake_wg_size);
break; break;
case 41: /* dpi-desync-fake-dht */ case 42: /* dpi-desync-fake-dht */
dp->fake_dht_size = sizeof(dp->fake_dht); dp->fake_dht_size = sizeof(dp->fake_dht);
load_file_or_exit(optarg,dp->fake_dht,&dp->fake_dht_size); load_file_or_exit(optarg,dp->fake_dht,&dp->fake_dht_size);
break; break;
case 42: /* dpi-desync-fake-unknown-udp */ case 43: /* dpi-desync-fake-unknown-udp */
dp->fake_unknown_udp_size = sizeof(dp->fake_unknown_udp); dp->fake_unknown_udp_size = sizeof(dp->fake_unknown_udp);
load_file_or_exit(optarg,dp->fake_unknown_udp,&dp->fake_unknown_udp_size); load_file_or_exit(optarg,dp->fake_unknown_udp,&dp->fake_unknown_udp_size);
break; break;
case 43: /* dpi-desync-udplen-increment */ case 44: /* dpi-desync-udplen-increment */
if (sscanf(optarg,"%d",&dp->udplen_increment)<1 || dp->udplen_increment>0x7FFF || dp->udplen_increment<-0x8000) if (sscanf(optarg,"%d",&dp->udplen_increment)<1 || dp->udplen_increment>0x7FFF || dp->udplen_increment<-0x8000)
{ {
DLOG_ERR("dpi-desync-udplen-increment must be integer within -32768..32767 range\n"); DLOG_ERR("dpi-desync-udplen-increment must be integer within -32768..32767 range\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 44: /* dpi-desync-udplen-pattern */ case 45: /* dpi-desync-udplen-pattern */
{ {
char buf[sizeof(dp->udplen_pattern)]; char buf[sizeof(dp->udplen_pattern)];
size_t sz=sizeof(buf); size_t sz=sizeof(buf);
@@ -1791,21 +1828,21 @@ int main(int argc, char **argv)
fill_pattern(dp->udplen_pattern,sizeof(dp->udplen_pattern),buf,sz); fill_pattern(dp->udplen_pattern,sizeof(dp->udplen_pattern),buf,sz);
} }
break; break;
case 45: /* desync-cutoff */ case 46: /* desync-cutoff */
if (!parse_cutoff(optarg, &dp->desync_cutoff, &dp->desync_cutoff_mode)) if (!parse_cutoff(optarg, &dp->desync_cutoff, &dp->desync_cutoff_mode))
{ {
DLOG_ERR("invalid desync-cutoff value\n"); DLOG_ERR("invalid desync-cutoff value\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 46: /* desync-start */ case 47: /* desync-start */
if (!parse_cutoff(optarg, &dp->desync_start, &dp->desync_start_mode)) if (!parse_cutoff(optarg, &dp->desync_start, &dp->desync_start_mode))
{ {
DLOG_ERR("invalid desync-start value\n"); DLOG_ERR("invalid desync-start value\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 47: /* hostlist */ case 48: /* hostlist */
if (bSkip) break; if (bSkip) break;
if (!RegisterHostlist(dp, false, optarg)) if (!RegisterHostlist(dp, false, optarg))
{ {
@@ -1813,7 +1850,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 48: /* hostlist-domains */ case 49: /* hostlist-domains */
if (bSkip) break; if (bSkip) break;
if (!anon_hl && !(anon_hl=RegisterHostlist(dp, false, NULL))) if (!anon_hl && !(anon_hl=RegisterHostlist(dp, false, NULL)))
{ {
@@ -1826,7 +1863,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 49: /* hostlist-exclude */ case 50: /* hostlist-exclude */
if (bSkip) break; if (bSkip) break;
if (!RegisterHostlist(dp, true, optarg)) if (!RegisterHostlist(dp, true, optarg))
{ {
@@ -1834,7 +1871,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 50: /* hostlist-exclude-domains */ case 51: /* hostlist-exclude-domains */
if (bSkip) break; if (bSkip) break;
if (!anon_hl_exclude && !(anon_hl_exclude=RegisterHostlist(dp, true, NULL))) if (!anon_hl_exclude && !(anon_hl_exclude=RegisterHostlist(dp, true, NULL)))
{ {
@@ -1847,7 +1884,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 51: /* hostlist-auto */ case 52: /* hostlist-auto */
if (bSkip) break; if (bSkip) break;
if (dp->hostlist_auto) if (dp->hostlist_auto)
{ {
@@ -1875,7 +1912,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 52: /* hostlist-auto-fail-threshold */ case 53: /* hostlist-auto-fail-threshold */
dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg); dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
if (dp->hostlist_auto_fail_threshold<1 || dp->hostlist_auto_fail_threshold>20) if (dp->hostlist_auto_fail_threshold<1 || dp->hostlist_auto_fail_threshold>20)
{ {
@@ -1883,7 +1920,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 53: /* hostlist-auto-fail-time */ case 54: /* hostlist-auto-fail-time */
dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg); dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg);
if (dp->hostlist_auto_fail_time<1) if (dp->hostlist_auto_fail_time<1)
{ {
@@ -1891,7 +1928,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 54: /* hostlist-auto-retrans-threshold */ case 55: /* hostlist-auto-retrans-threshold */
dp->hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg); dp->hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg);
if (dp->hostlist_auto_retrans_threshold<2 || dp->hostlist_auto_retrans_threshold>10) if (dp->hostlist_auto_retrans_threshold<2 || dp->hostlist_auto_retrans_threshold>10)
{ {
@@ -1899,7 +1936,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 55: /* hostlist-auto-debug */ case 56: /* hostlist-auto-debug */
{ {
FILE *F = fopen(optarg,"a+t"); FILE *F = fopen(optarg,"a+t");
if (!F) if (!F)
@@ -1913,7 +1950,7 @@ int main(int argc, char **argv)
} }
break; break;
case 56: /* new */ case 57: /* new */
if (bSkip) if (bSkip)
{ {
dp_clear(dp); dp_clear(dp);
@@ -1934,18 +1971,18 @@ int main(int argc, char **argv)
anon_hl = anon_hl_exclude = NULL; anon_hl = anon_hl_exclude = NULL;
anon_ips = anon_ips_exclude = NULL; anon_ips = anon_ips_exclude = NULL;
break; break;
case 57: /* skip */ case 58: /* skip */
bSkip = true; bSkip = true;
break; break;
case 58: /* filter-l3 */ case 59: /* filter-l3 */
if (!wf_make_l3(optarg,&dp->filter_ipv4,&dp->filter_ipv6)) if (!wf_make_l3(optarg,&dp->filter_ipv4,&dp->filter_ipv6))
{ {
DLOG_ERR("bad value for --filter-l3\n"); DLOG_ERR("bad value for --filter-l3\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 59: /* filter-tcp */ case 60: /* filter-tcp */
if (!parse_pf_list(optarg,&dp->pf_tcp)) if (!parse_pf_list(optarg,&dp->pf_tcp))
{ {
DLOG_ERR("Invalid port filter : %s\n",optarg); DLOG_ERR("Invalid port filter : %s\n",optarg);
@@ -1955,7 +1992,7 @@ int main(int argc, char **argv)
if (!port_filters_deny_if_empty(&dp->pf_udp)) if (!port_filters_deny_if_empty(&dp->pf_udp))
exit_clean(1); exit_clean(1);
break; break;
case 60: /* filter-udp */ case 61: /* filter-udp */
if (!parse_pf_list(optarg,&dp->pf_udp)) if (!parse_pf_list(optarg,&dp->pf_udp))
{ {
DLOG_ERR("Invalid port filter : %s\n",optarg); DLOG_ERR("Invalid port filter : %s\n",optarg);
@@ -1965,14 +2002,14 @@ int main(int argc, char **argv)
if (!port_filters_deny_if_empty(&dp->pf_tcp)) if (!port_filters_deny_if_empty(&dp->pf_tcp))
exit_clean(1); exit_clean(1);
break; break;
case 61: /* filter-l7 */ case 62: /* filter-l7 */
if (!parse_l7_list(optarg,&dp->filter_l7)) if (!parse_l7_list(optarg,&dp->filter_l7))
{ {
DLOG_ERR("Invalid l7 filter : %s\n",optarg); DLOG_ERR("Invalid l7 filter : %s\n",optarg);
exit_clean(1); exit_clean(1);
} }
break; break;
case 62: /* ipset */ case 63: /* ipset */
if (bSkip) break; if (bSkip) break;
if (!RegisterIpset(dp, false, optarg)) if (!RegisterIpset(dp, false, optarg))
{ {
@@ -1980,7 +2017,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 63: /* ipset-ip */ case 64: /* ipset-ip */
if (bSkip) break; if (bSkip) break;
if (!anon_ips && !(anon_ips=RegisterIpset(dp, false, NULL))) if (!anon_ips && !(anon_ips=RegisterIpset(dp, false, NULL)))
{ {
@@ -1993,7 +2030,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 64: /* ipset-exclude */ case 65: /* ipset-exclude */
if (bSkip) break; if (bSkip) break;
if (!RegisterIpset(dp, true, optarg)) if (!RegisterIpset(dp, true, optarg))
{ {
@@ -2001,7 +2038,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 65: /* ipset-exclude-ip */ case 66: /* ipset-exclude-ip */
if (bSkip) break; if (bSkip) break;
if (!anon_ips_exclude && !(anon_ips_exclude=RegisterIpset(dp, true, NULL))) if (!anon_ips_exclude && !(anon_ips_exclude=RegisterIpset(dp, true, NULL)))
{ {
@@ -2017,28 +2054,28 @@ int main(int argc, char **argv)
#ifdef __linux__ #ifdef __linux__
case 66: /* bind-fix4 */ case 67: /* bind-fix4 */
params.bind_fix4 = true; params.bind_fix4 = true;
break; break;
case 67: /* bind-fix6 */ case 68: /* bind-fix6 */
params.bind_fix6 = true; params.bind_fix6 = true;
break; break;
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
case 66: /* wf-iface */ case 67: /* wf-iface */
if (!sscanf(optarg,"%u.%u",&IfIdx,&SubIfIdx)) if (!sscanf(optarg,"%u.%u",&IfIdx,&SubIfIdx))
{ {
DLOG_ERR("bad value for --wf-iface\n"); DLOG_ERR("bad value for --wf-iface\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 67: /* wf-l3 */ case 68: /* wf-l3 */
if (!wf_make_l3(optarg,&wf_ipv4,&wf_ipv6)) if (!wf_make_l3(optarg,&wf_ipv4,&wf_ipv6))
{ {
DLOG_ERR("bad value for --wf-l3\n"); DLOG_ERR("bad value for --wf-l3\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 68: /* wf-tcp */ case 69: /* wf-tcp */
hash_wf_tcp=hash_jen(optarg,strlen(optarg)); hash_wf_tcp=hash_jen(optarg,strlen(optarg));
if (!wf_make_pf(optarg,"tcp","SrcPort",wf_pf_tcp_src,sizeof(wf_pf_tcp_src)) || if (!wf_make_pf(optarg,"tcp","SrcPort",wf_pf_tcp_src,sizeof(wf_pf_tcp_src)) ||
!wf_make_pf(optarg,"tcp","DstPort",wf_pf_tcp_dst,sizeof(wf_pf_tcp_dst))) !wf_make_pf(optarg,"tcp","DstPort",wf_pf_tcp_dst,sizeof(wf_pf_tcp_dst)))
@@ -2047,7 +2084,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 69: /* wf-udp */ case 70: /* wf-udp */
hash_wf_udp=hash_jen(optarg,strlen(optarg)); hash_wf_udp=hash_jen(optarg,strlen(optarg));
if (!wf_make_pf(optarg,"udp","SrcPort",wf_pf_udp_src,sizeof(wf_pf_udp_src)) || if (!wf_make_pf(optarg,"udp","SrcPort",wf_pf_udp_src,sizeof(wf_pf_udp_src)) ||
!wf_make_pf(optarg,"udp","DstPort",wf_pf_udp_dst,sizeof(wf_pf_udp_dst))) !wf_make_pf(optarg,"udp","DstPort",wf_pf_udp_dst,sizeof(wf_pf_udp_dst)))
@@ -2056,7 +2093,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 70: /* wf-raw */ case 71: /* wf-raw */
hash_wf_raw=hash_jen(optarg,strlen(optarg)); hash_wf_raw=hash_jen(optarg,strlen(optarg));
if (optarg[0]=='@') if (optarg[0]=='@')
{ {
@@ -2070,11 +2107,11 @@ int main(int argc, char **argv)
windivert_filter[sizeof(windivert_filter) - 1] = '\0'; windivert_filter[sizeof(windivert_filter) - 1] = '\0';
} }
break; break;
case 71: /* wf-save */ case 72: /* wf-save */
strncpy(wf_save_file, optarg, sizeof(wf_save_file)); strncpy(wf_save_file, optarg, sizeof(wf_save_file));
wf_save_file[sizeof(wf_save_file) - 1] = '\0'; wf_save_file[sizeof(wf_save_file) - 1] = '\0';
break; break;
case 72: /* ssid-filter */ case 73: /* ssid-filter */
hash_ssid_filter=hash_jen(optarg,strlen(optarg)); hash_ssid_filter=hash_jen(optarg,strlen(optarg));
{ {
char *e,*p = optarg; char *e,*p = optarg;
@@ -2092,7 +2129,7 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 73: /* nlm-filter */ case 74: /* nlm-filter */
hash_nlm_filter=hash_jen(optarg,strlen(optarg)); hash_nlm_filter=hash_jen(optarg,strlen(optarg));
{ {
char *e,*p = optarg; char *e,*p = optarg;
@@ -2110,7 +2147,7 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 74: /* nlm-list */ case 75: /* nlm-list */
if (!nlm_list(optarg && !strcmp(optarg,"all"))) if (!nlm_list(optarg && !strcmp(optarg,"all")))
{ {
DLOG_ERR("could not get list of NLM networks\n"); DLOG_ERR("could not get list of NLM networks\n");
@@ -2242,6 +2279,12 @@ int main(int argc, char **argv)
SplitDebug(); SplitDebug();
DLOG("\n"); DLOG("\n");
if (bDry)
{
DLOG_CONDUP("command line parameters verified\n");
exit_clean(0);
}
if (daemon) daemonize(); if (daemon) daemonize();
if (*pidfile && !writepid(pidfile)) if (*pidfile && !writepid(pidfile))

View File

@@ -151,7 +151,7 @@ void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const st
} }
const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL }; const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS ","PUT /","DELETE /","CONNECT ","TRACE /",NULL };
const char *HttpMethod(const uint8_t *data, size_t len) const char *HttpMethod(const uint8_t *data, size_t len)
{ {
const char **method; const char **method;

View File

@@ -151,7 +151,7 @@ void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const st
} }
const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL }; const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS ","PUT /","DELETE /","CONNECT ","TRACE /",NULL };
const char *HttpMethod(const uint8_t *data, size_t len) const char *HttpMethod(const uint8_t *data, size_t len)
{ {
const char **method; const char **method;

View File

@@ -175,6 +175,7 @@ static void exithelp(void)
#endif #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=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" " --debug-level=0|1|2\t\t\t; specify debug level\n"
" --dry-run\t\t\t\t; verify parameters and exit with code 0 if successful\n"
"\nMULTI-STRATEGY:\n" "\nMULTI-STRATEGY:\n"
" --new\t\t\t\t\t; begin new strategy\n" " --new\t\t\t\t\t; begin new strategy\n"
" --skip\t\t\t\t\t; do not use this strategy\n" " --skip\t\t\t\t\t; do not use this strategy\n"
@@ -569,7 +570,7 @@ void parse_params(int argc, char *argv[])
{ {
int option_index = 0; int option_index = 0;
int v, i; int v, i;
bool bSkip=false; bool bSkip=false, bDry=false;
struct hostlist_file *anon_hl = NULL, *anon_hl_exclude = NULL; struct hostlist_file *anon_hl = NULL, *anon_hl_exclude = NULL;
struct ipset_file *anon_ips = NULL, *anon_ips_exclude = NULL; struct ipset_file *anon_ips = NULL, *anon_ips_exclude = NULL;
@@ -667,40 +668,41 @@ void parse_params(int argc, char *argv[])
{ "pidfile",required_argument,0,0 },// optidx=44 { "pidfile",required_argument,0,0 },// optidx=44
{ "debug",optional_argument,0,0 },// optidx=45 { "debug",optional_argument,0,0 },// optidx=45
{ "debug-level",required_argument,0,0 },// optidx=46 { "debug-level",required_argument,0,0 },// optidx=46
{ "local-rcvbuf",required_argument,0,0 },// optidx=47 { "dry-run",no_argument,0,0 },// optidx=47
{ "local-sndbuf",required_argument,0,0 },// optidx=48 { "local-rcvbuf",required_argument,0,0 },// optidx=48
{ "remote-rcvbuf",required_argument,0,0 },// optidx=49 { "local-sndbuf",required_argument,0,0 },// optidx=49
{ "remote-sndbuf",required_argument,0,0 },// optidx=50 { "remote-rcvbuf",required_argument,0,0 },// optidx=50
{ "socks",no_argument,0,0 },// optidx=51 { "remote-sndbuf",required_argument,0,0 },// optidx=51
{ "no-resolve",no_argument,0,0 },// optidx=52 { "socks",no_argument,0,0 },// optidx=52
{ "resolver-threads",required_argument,0,0 },// optidx=53 { "no-resolve",no_argument,0,0 },// optidx=53
{ "skip-nodelay",no_argument,0,0 },// optidx=54 { "resolver-threads",required_argument,0,0 },// optidx=54
{ "tamper-start",required_argument,0,0 },// optidx=55 { "skip-nodelay",no_argument,0,0 },// optidx=55
{ "tamper-cutoff",required_argument,0,0 },// optidx=56 { "tamper-start",required_argument,0,0 },// optidx=56
{ "connect-bind-addr",required_argument,0,0 },// optidx=57 { "tamper-cutoff",required_argument,0,0 },// optidx=57
{ "connect-bind-addr",required_argument,0,0 },// optidx=58
{ "new",no_argument,0,0 }, // optidx=58 { "new",no_argument,0,0 }, // optidx=59
{ "skip",no_argument,0,0 }, // optidx=59 { "skip",no_argument,0,0 }, // optidx=60
{ "filter-l3",required_argument,0,0 }, // optidx=60 { "filter-l3",required_argument,0,0 }, // optidx=61
{ "filter-tcp",required_argument,0,0 }, // optidx=61 { "filter-tcp",required_argument,0,0 }, // optidx=63
{ "filter-l7",required_argument,0,0 }, // optidx=62 { "filter-l7",required_argument,0,0 }, // optidx=64
{ "ipset",required_argument,0,0 }, // optidx=63 { "ipset",required_argument,0,0 }, // optidx=65
{ "ipset-ip",required_argument,0,0 }, // optidx=64 { "ipset-ip",required_argument,0,0 }, // optidx=66
{ "ipset-exclude",required_argument,0,0 }, // optidx=65 { "ipset-exclude",required_argument,0,0 }, // optidx=67
{ "ipset-exclude-ip",required_argument,0,0 }, // optidx=66 { "ipset-exclude-ip",required_argument,0,0 }, // optidx=68
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
{ "enable-pf",no_argument,0,0 },// optidx=67 { "enable-pf",no_argument,0,0 },// optidx=68
#elif defined(__APPLE__) #elif defined(__APPLE__)
{ "local-tcp-user-timeout",required_argument,0,0 }, // optidx=67 { "local-tcp-user-timeout",required_argument,0,0 }, // optidx=68
{ "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=68 { "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=69
#elif defined(__linux__) #elif defined(__linux__)
{ "local-tcp-user-timeout",required_argument,0,0 }, // optidx=67 { "local-tcp-user-timeout",required_argument,0,0 }, // optidx=68
{ "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=68 { "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=69
{ "mss",required_argument,0,0 }, // optidx=69 { "mss",required_argument,0,0 }, // optidx=70
{ "fix-seg",optional_argument,0,0 }, // optidx=70 { "fix-seg",optional_argument,0,0 }, // optidx=71
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
{ "nosplice",no_argument,0,0 }, // optidx=71 { "nosplice",no_argument,0,0 }, // optidx=72
#endif #endif
#endif #endif
{ "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility { "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility
@@ -708,7 +710,13 @@ void parse_params(int argc, char *argv[])
}; };
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
{ {
if (v) exithelp_clean(); if (v)
{
if (bDry)
exit_clean(1);
else
exithelp_clean();
}
switch (option_index) switch (option_index)
{ {
case 0: case 0:
@@ -1142,41 +1150,44 @@ void parse_params(int argc, char *argv[])
case 46: /* debug-level */ case 46: /* debug-level */
params.debug = atoi(optarg); params.debug = atoi(optarg);
break; break;
case 47: /* local-rcvbuf */ case 47: /* dry-run */
bDry = true;
break;
case 48: /* local-rcvbuf */
#ifdef __linux__ #ifdef __linux__
params.local_rcvbuf = atoi(optarg)/2; params.local_rcvbuf = atoi(optarg)/2;
#else #else
params.local_rcvbuf = atoi(optarg); params.local_rcvbuf = atoi(optarg);
#endif #endif
break; break;
case 48: /* local-sndbuf */ case 49: /* local-sndbuf */
#ifdef __linux__ #ifdef __linux__
params.local_sndbuf = atoi(optarg)/2; params.local_sndbuf = atoi(optarg)/2;
#else #else
params.local_sndbuf = atoi(optarg); params.local_sndbuf = atoi(optarg);
#endif #endif
break; break;
case 49: /* remote-rcvbuf */ case 50: /* remote-rcvbuf */
#ifdef __linux__ #ifdef __linux__
params.remote_rcvbuf = atoi(optarg)/2; params.remote_rcvbuf = atoi(optarg)/2;
#else #else
params.remote_rcvbuf = atoi(optarg); params.remote_rcvbuf = atoi(optarg);
#endif #endif
break; break;
case 50: /* remote-sndbuf */ case 51: /* remote-sndbuf */
#ifdef __linux__ #ifdef __linux__
params.remote_sndbuf = atoi(optarg)/2; params.remote_sndbuf = atoi(optarg)/2;
#else #else
params.remote_sndbuf = atoi(optarg); params.remote_sndbuf = atoi(optarg);
#endif #endif
break; break;
case 51: /* socks */ case 52: /* socks */
params.proxy_type = CONN_TYPE_SOCKS; params.proxy_type = CONN_TYPE_SOCKS;
break; break;
case 52: /* no-resolve */ case 53: /* no-resolve */
params.no_resolve = true; params.no_resolve = true;
break; break;
case 53: /* resolver-threads */ case 54: /* resolver-threads */
params.resolver_threads = atoi(optarg); params.resolver_threads = atoi(optarg);
if (params.resolver_threads<1 || params.resolver_threads>300) if (params.resolver_threads<1 || params.resolver_threads>300)
{ {
@@ -1184,10 +1195,10 @@ void parse_params(int argc, char *argv[])
exit_clean(1); exit_clean(1);
} }
break; break;
case 54: /* skip-nodelay */ case 55: /* skip-nodelay */
params.skip_nodelay = true; params.skip_nodelay = true;
break; break;
case 55: /* tamper-start */ case 56: /* tamper-start */
{ {
const char *p=optarg; const char *p=optarg;
if (*p=='n') if (*p=='n')
@@ -1201,7 +1212,7 @@ void parse_params(int argc, char *argv[])
} }
params.tamper_lim = true; params.tamper_lim = true;
break; break;
case 56: /* tamper-cutoff */ case 57: /* tamper-cutoff */
{ {
const char *p=optarg; const char *p=optarg;
if (*p=='n') if (*p=='n')
@@ -1215,7 +1226,7 @@ void parse_params(int argc, char *argv[])
} }
params.tamper_lim = true; params.tamper_lim = true;
break; break;
case 57: /* connect-bind-addr */ case 58: /* connect-bind-addr */
{ {
char *p = strchr(optarg,'%'); char *p = strchr(optarg,'%');
if (p) *p++=0; if (p) *p++=0;
@@ -1243,7 +1254,7 @@ void parse_params(int argc, char *argv[])
break; break;
case 58: /* new */ case 59: /* new */
if (bSkip) if (bSkip)
{ {
dp_clear(dp); dp_clear(dp);
@@ -1264,31 +1275,31 @@ void parse_params(int argc, char *argv[])
anon_hl = anon_hl_exclude = NULL; anon_hl = anon_hl_exclude = NULL;
anon_ips = anon_ips_exclude = NULL; anon_ips = anon_ips_exclude = NULL;
break; break;
case 59: /* skip */ case 60: /* skip */
bSkip = true; bSkip = true;
break; break;
case 60: /* filter-l3 */ case 61: /* filter-l3 */
if (!wf_make_l3(optarg,&dp->filter_ipv4,&dp->filter_ipv6)) if (!wf_make_l3(optarg,&dp->filter_ipv4,&dp->filter_ipv6))
{ {
DLOG_ERR("bad value for --filter-l3\n"); DLOG_ERR("bad value for --filter-l3\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 61: /* filter-tcp */ case 62: /* filter-tcp */
if (!parse_pf_list(optarg,&dp->pf_tcp)) if (!parse_pf_list(optarg,&dp->pf_tcp))
{ {
DLOG_ERR("Invalid port filter : %s\n",optarg); DLOG_ERR("Invalid port filter : %s\n",optarg);
exit_clean(1); exit_clean(1);
} }
break; break;
case 62: /* filter-l7 */ case 63: /* filter-l7 */
if (!parse_l7_list(optarg,&dp->filter_l7)) if (!parse_l7_list(optarg,&dp->filter_l7))
{ {
DLOG_ERR("Invalid l7 filter : %s\n",optarg); DLOG_ERR("Invalid l7 filter : %s\n",optarg);
exit_clean(1); exit_clean(1);
} }
break; break;
case 63: /* ipset */ case 64: /* ipset */
if (bSkip) break; if (bSkip) break;
if (!RegisterIpset(dp, false, optarg)) if (!RegisterIpset(dp, false, optarg))
{ {
@@ -1297,7 +1308,7 @@ void parse_params(int argc, char *argv[])
} }
params.tamper = true; params.tamper = true;
break; break;
case 64: /* ipset-ip */ case 65: /* ipset-ip */
if (bSkip) break; if (bSkip) break;
if (!anon_ips && !(anon_ips=RegisterIpset(dp, false, NULL))) if (!anon_ips && !(anon_ips=RegisterIpset(dp, false, NULL)))
{ {
@@ -1311,7 +1322,7 @@ void parse_params(int argc, char *argv[])
} }
params.tamper = true; params.tamper = true;
break; break;
case 65: /* ipset-exclude */ case 66: /* ipset-exclude */
if (bSkip) break; if (bSkip) break;
if (!RegisterIpset(dp, true, optarg)) if (!RegisterIpset(dp, true, optarg))
{ {
@@ -1320,7 +1331,7 @@ void parse_params(int argc, char *argv[])
} }
params.tamper = true; params.tamper = true;
break; break;
case 66: /* ipset-exclude-ip */ case 67: /* ipset-exclude-ip */
if (bSkip) break; if (bSkip) break;
if (!anon_ips_exclude && !(anon_ips_exclude=RegisterIpset(dp, true, NULL))) if (!anon_ips_exclude && !(anon_ips_exclude=RegisterIpset(dp, true, NULL)))
{ {
@@ -1336,11 +1347,11 @@ void parse_params(int argc, char *argv[])
break; break;
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
case 67: /* enable-pf */ case 68: /* enable-pf */
params.pf_enable = true; params.pf_enable = true;
break; break;
#elif defined(__linux__) || defined(__APPLE__) #elif defined(__linux__) || defined(__APPLE__)
case 67: /* local-tcp-user-timeout */ case 68: /* local-tcp-user-timeout */
params.tcp_user_timeout_local = atoi(optarg); params.tcp_user_timeout_local = atoi(optarg);
if (params.tcp_user_timeout_local<0 || params.tcp_user_timeout_local>86400) if (params.tcp_user_timeout_local<0 || params.tcp_user_timeout_local>86400)
{ {
@@ -1348,7 +1359,7 @@ void parse_params(int argc, char *argv[])
exit_clean(1); exit_clean(1);
} }
break; break;
case 68: /* remote-tcp-user-timeout */ case 69: /* remote-tcp-user-timeout */
params.tcp_user_timeout_remote = atoi(optarg); params.tcp_user_timeout_remote = atoi(optarg);
if (params.tcp_user_timeout_remote<0 || params.tcp_user_timeout_remote>86400) if (params.tcp_user_timeout_remote<0 || params.tcp_user_timeout_remote>86400)
{ {
@@ -1359,7 +1370,7 @@ void parse_params(int argc, char *argv[])
#endif #endif
#if defined(__linux__) #if defined(__linux__)
case 69: /* mss */ case 70: /* mss */
// this option does not work in any BSD and MacOS. OS may accept but it changes nothing // this option does not work in any BSD and MacOS. OS may accept but it changes nothing
dp->mss = atoi(optarg); dp->mss = atoi(optarg);
if (dp->mss<88 || dp->mss>32767) if (dp->mss<88 || dp->mss>32767)
@@ -1368,7 +1379,7 @@ void parse_params(int argc, char *argv[])
exit_clean(1); exit_clean(1);
} }
break; break;
case 70: /* fix-seg */ case 71: /* fix-seg */
if (!params.fix_seg_avail) if (!params.fix_seg_avail)
{ {
DLOG_ERR("--fix-seg is supported since kernel 4.6\n"); DLOG_ERR("--fix-seg is supported since kernel 4.6\n");
@@ -1388,7 +1399,7 @@ void parse_params(int argc, char *argv[])
params.fix_seg = FIX_SEG_DEFAULT_MAX_WAIT; params.fix_seg = FIX_SEG_DEFAULT_MAX_WAIT;
break; break;
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
case 71: /* nosplice */ case 72: /* nosplice */
params.nosplice = true; params.nosplice = true;
break; break;
#endif #endif
@@ -1463,6 +1474,11 @@ void parse_params(int argc, char *argv[])
// do not need args from file anymore // do not need args from file anymore
cleanup_args(); cleanup_args();
#endif #endif
if (bDry)
{
DLOG_CONDUP("command line parameters verified\n");
exit_clean(0);
}
} }