mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-30 05:50:53 +03:00
autottl, datanoack, oob, postnat
This commit is contained in:
parent
2157fed592
commit
8a161f1f49
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -337,19 +337,35 @@ pktws_ipt_prepare()
|
|||||||
# enable fragments
|
# enable fragments
|
||||||
IPT OUTPUT -f -j ACCEPT
|
IPT OUTPUT -f -j ACCEPT
|
||||||
fi
|
fi
|
||||||
IPT POSTROUTING -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
|
IPT OUTPUT -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
|
||||||
|
IPT INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
|
||||||
|
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
|
||||||
|
# raw table may not be present
|
||||||
|
IPT OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
|
||||||
;;
|
;;
|
||||||
nftables)
|
nftables)
|
||||||
nft add table inet $NFT_TABLE
|
nft add table inet $NFT_TABLE
|
||||||
[ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ] && {
|
# prenat
|
||||||
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }"
|
# [ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ] && {
|
||||||
nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} exthdr frag exists notrack"
|
# nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }"
|
||||||
}
|
# nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} exthdr frag exists notrack"
|
||||||
nft "add chain inet $NFT_TABLE premangle { type filter hook output priority -152; }"
|
# }
|
||||||
nft "add rule inet $NFT_TABLE premangle meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM"
|
# nft "add chain inet $NFT_TABLE premangle { type filter hook output priority -152; }"
|
||||||
|
# nft "add rule inet $NFT_TABLE premangle meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM"
|
||||||
|
# postnat. this is good because we need only output traffic
|
||||||
|
nft "add chain inet $NFT_TABLE postnat { type filter hook output priority 102; }"
|
||||||
|
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM"
|
||||||
|
# for strategies with incoming packets involved (autottl)
|
||||||
|
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }"
|
||||||
|
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1-1 queue num $QNUM"
|
||||||
|
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
|
||||||
|
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }"
|
||||||
|
nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} mark and $DESYNC_MARK !=0 notrack"
|
||||||
;;
|
;;
|
||||||
ipfw)
|
ipfw)
|
||||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from me to any $1 proto ip${IPV} out not diverted not sockarg
|
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from me to any $1 proto ip${IPV} out not diverted not sockarg
|
||||||
|
# this redirects all incoming traffic to the port, do not use it in real life !
|
||||||
|
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from any $1 to me proto ip${IPV} in not diverted not sockarg
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -358,7 +374,8 @@ pktws_ipt_unprepare()
|
|||||||
# $1 - port
|
# $1 - port
|
||||||
case "$FWTYPE" in
|
case "$FWTYPE" in
|
||||||
iptables)
|
iptables)
|
||||||
IPT_DEL POSTROUTING -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
|
IPT_DEL OUTPUT -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
|
||||||
|
IPT_DEL INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
|
||||||
|
|
||||||
IPT_DEL INPUT -p tcp --sport $1 ! --syn -j ACCEPT
|
IPT_DEL INPUT -p tcp --sport $1 ! --syn -j ACCEPT
|
||||||
IPT_DEL OUTPUT -p tcp --dport $1 -m conntrack --ctstate INVALID -j ACCEPT
|
IPT_DEL OUTPUT -p tcp --dport $1 -m conntrack --ctstate INVALID -j ACCEPT
|
||||||
@ -367,6 +384,8 @@ pktws_ipt_unprepare()
|
|||||||
elif [ "$IPV" = 4 ]; then
|
elif [ "$IPV" = 4 ]; then
|
||||||
IPT_DEL OUTPUT -f -j ACCEPT
|
IPT_DEL OUTPUT -f -j ACCEPT
|
||||||
fi
|
fi
|
||||||
|
# raw table may not be present
|
||||||
|
IPT_DEL OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
|
||||||
;;
|
;;
|
||||||
nftables)
|
nftables)
|
||||||
nft delete table inet $NFT_TABLE 2>/dev/null
|
nft delete table inet $NFT_TABLE 2>/dev/null
|
||||||
@ -556,9 +575,12 @@ test_has_split()
|
|||||||
{
|
{
|
||||||
contains "$1" split || contains "$1" disorder
|
contains "$1" split || contains "$1" disorder
|
||||||
}
|
}
|
||||||
warn_md5sig()
|
warn_fool()
|
||||||
{
|
{
|
||||||
echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.'
|
case "$1" in
|
||||||
|
md5sig) echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.' ;;
|
||||||
|
datanoack) echo 'WARNING ! although datanoack fooling worked it breaks NAT and can only work with external IP. Additionally it may require nftables to work correctly.' ;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
pktws_check_domain_bypass()
|
pktws_check_domain_bypass()
|
||||||
{
|
{
|
||||||
@ -615,11 +637,14 @@ pktws_check_domain_bypass()
|
|||||||
pktws_curl_test_update $1 $3 $s --dpi-desync-ttl=$ttl $e && break
|
pktws_curl_test_update $1 $3 $s --dpi-desync-ttl=$ttl $e && break
|
||||||
test_has_split $desync && pktws_curl_test_update $1 $3 $s --dpi-desync-split-pos=1 --dpi-desync-ttl=$ttl $e && break
|
test_has_split $desync && pktws_curl_test_update $1 $3 $s --dpi-desync-split-pos=1 --dpi-desync-ttl=$ttl $e && break
|
||||||
done
|
done
|
||||||
f="badsum badseq md5sig"
|
pktws_curl_test_update $1 $3 $s --dpi-desync-autottl $e || {
|
||||||
|
test_has_split $desync && pktws_curl_test_update $1 $3 $s --dpi-desync-split-pos=1 --dpi-desync-autottl $e
|
||||||
|
}
|
||||||
|
f="badsum badseq md5sig datanoack"
|
||||||
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
||||||
for fooling in $f; do
|
for fooling in $f; do
|
||||||
pktws_curl_test_update $1 $3 $s --dpi-desync-fooling=$fooling $e && [ "$fooling" = "md5sig" ] && warn_md5sig
|
pktws_curl_test_update $1 $3 $s --dpi-desync-fooling=$fooling $e && warn_fool $fooling
|
||||||
test_has_split $desync && pktws_curl_test_update $1 $3 $s --dpi-desync-split-pos=1 --dpi-desync-fooling=$fooling $e && [ "$fooling" = "md5sig" ] && warn_md5sig
|
test_has_split $desync && pktws_curl_test_update $1 $3 $s --dpi-desync-split-pos=1 --dpi-desync-fooling=$fooling $e && warn_fool $fooling
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
[ "$IPV" = 6 ] && {
|
[ "$IPV" = 6 ] && {
|
||||||
@ -657,19 +682,19 @@ tpws_check_domain_bypass()
|
|||||||
'--hostpad=1024' '--hostpad=2048' '--hostpad=4096' '--hostpad=8192' '--hostpad=16384' ; do
|
'--hostpad=1024' '--hostpad=2048' '--hostpad=4096' '--hostpad=8192' '--hostpad=16384' ; do
|
||||||
tpws_curl_test_update $1 $3 $s
|
tpws_curl_test_update $1 $3 $s
|
||||||
done
|
done
|
||||||
for s2 in '' '--disorder'; do
|
for s2 in '' '--disorder' '--oob'; do
|
||||||
for s in '--split-http-req=method' '--split-http-req=method --hostcase' '--split-http-req=host' '--split-http-req=host --hostcase' ; do
|
for s in '--split-http-req=method' '--split-http-req=method --hostcase' '--split-http-req=host' '--split-http-req=host --hostcase' ; do
|
||||||
tpws_curl_test_update $1 $3 $s $s2
|
tpws_curl_test_update $1 $3 $s $s2
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
for s2 in '' '--disorder'; do
|
for s2 in '' '--disorder' '--oob'; do
|
||||||
for pos in 1 2 3 4 5 10 50 100; do
|
for pos in 1 2 3 4 5 10 50 100; do
|
||||||
s="--split-pos=$pos"
|
s="--split-pos=$pos"
|
||||||
tpws_curl_test_update $1 $3 $s $s2 && break
|
tpws_curl_test_update $1 $3 $s $s2 && break
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
for s2 in '--tlsrec=sni' '--tlsrec=sni --split-pos=10' '--tlsrec=sni --split-pos=10 --disorder'; do
|
for s2 in '--tlsrec=sni' '--tlsrec=sni --split-pos=10' '--tlsrec=sni --split-pos=10 --disorder' '--tlsrec=sni --split-pos=10 --oob'; do
|
||||||
tpws_curl_test_update $1 $3 $s2 && [ "$FORCE" != 1 ] && break
|
tpws_curl_test_update $1 $3 $s2 && [ "$FORCE" != 1 ] && break
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
std_ports
|
std_ports
|
||||||
|
readonly ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes"
|
||||||
|
|
||||||
ipt()
|
ipt()
|
||||||
{
|
{
|
||||||
@ -319,22 +320,45 @@ fw_nfqws_pre()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
produce_reverse_nfqws_rule()
|
||||||
|
{
|
||||||
|
local rule="$1"
|
||||||
|
if contains "$rule" "$ipt_connbytes"; then
|
||||||
|
# autohostlist - need several incoming packets
|
||||||
|
# autottl - need only one incoming packet
|
||||||
|
[ "$MODE_FILTER" = autohostlist ] || rule=$(echo "$rule" | sed -re "s/$ipt_connbytes [0-9]+:[0-9]+/$ipt_connbytes 1:1/")
|
||||||
|
else
|
||||||
|
rule="$ipt_connbytes 1:$(first_packets_for_mode) $rule"
|
||||||
|
fi
|
||||||
|
echo "$rule" | reverse_nfqws_rule_stream
|
||||||
|
}
|
||||||
|
fw_reverse_nfqws_rule4()
|
||||||
|
{
|
||||||
|
fw_nfqws_pre4 $1 "$(produce_reverse_nfqws_rule "$2")" $3
|
||||||
|
}
|
||||||
|
fw_reverse_nfqws_rule6()
|
||||||
|
{
|
||||||
|
fw_nfqws_pre6 $1 "$(produce_reverse_nfqws_rule "$2")" $3
|
||||||
|
}
|
||||||
|
fw_reverse_nfqws_rule()
|
||||||
|
{
|
||||||
|
# ensure that modes relying on incoming traffic work
|
||||||
|
# $1 - 1 - add, 0 - del
|
||||||
|
# $2 - rule4
|
||||||
|
# $3 - rule6
|
||||||
|
# $4 - queue number
|
||||||
|
fw_reverse_nfqws_rule4 $1 "$2" $4
|
||||||
|
fw_reverse_nfqws_rule6 $1 "$3" $4
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt()
|
zapret_do_firewall_rules_ipt()
|
||||||
{
|
{
|
||||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||||
|
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:"
|
local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
local n f4 f6 ff qn qns qn6 qns6
|
local n f4 f6 qn qns qn6 qns6
|
||||||
|
|
||||||
# autohostlist mode requires incoming traffic sample
|
|
||||||
# always use conntrack packet limiter or nfqws will deal with gigabytes
|
|
||||||
if [ "$MODE_FILTER" = "autohostlist" ]; then
|
|
||||||
n=$((6+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
|
|
||||||
else
|
|
||||||
n=6
|
|
||||||
fi
|
|
||||||
first_packet_only="${first_packet_only}$n"
|
|
||||||
|
|
||||||
case "$mode" in
|
case "$mode" in
|
||||||
tpws)
|
tpws)
|
||||||
@ -356,23 +380,20 @@ zapret_do_firewall_rules_ipt()
|
|||||||
f4="$f4 $first_packet_only"
|
f4="$f4 $first_packet_only"
|
||||||
filter_apply_ipset_target4 f4
|
filter_apply_ipset_target4 f4
|
||||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre4 $1 "$(reverse_nfqws_rule $f4)" $qn
|
fw_reverse_nfqws_rule4 $1 "$f4" $qn
|
||||||
else
|
else
|
||||||
if [ -n "$qn" ]; then
|
if [ -n "$qn" ]; then
|
||||||
f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
||||||
ff="$f4"
|
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
||||||
ff="$ff $first_packet_only"
|
|
||||||
filter_apply_ipset_target4 f4
|
filter_apply_ipset_target4 f4
|
||||||
filter_apply_ipset_target4 ff
|
|
||||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre4 $1 "$(reverse_nfqws_rule $ff)" $qn
|
fw_reverse_nfqws_rule4 $1 "$f4" $qn
|
||||||
fi
|
fi
|
||||||
if [ -n "$qns" ]; then
|
if [ -n "$qns" ]; then
|
||||||
f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
||||||
filter_apply_ipset_target4 f4
|
filter_apply_ipset_target4 f4
|
||||||
fw_nfqws_post4 $1 "$f4 $desync" $qns
|
fw_nfqws_post4 $1 "$f4 $desync" $qns
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre4 $1 "$(reverse_nfqws_rule $f4)" $qns
|
fw_reverse_nfqws_rule4 $1 "$f4" $qns
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||||
@ -380,23 +401,20 @@ zapret_do_firewall_rules_ipt()
|
|||||||
f6="$f6 $first_packet_only"
|
f6="$f6 $first_packet_only"
|
||||||
filter_apply_ipset_target6 f6
|
filter_apply_ipset_target6 f6
|
||||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre6 $1 "$(reverse_nfqws_rule $f6)" $qn
|
fw_reverse_nfqws_rule6 $1 "$f6" $qn6
|
||||||
else
|
else
|
||||||
if [ -n "$qn6" ]; then
|
if [ -n "$qn6" ]; then
|
||||||
f6="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
f6="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
||||||
ff="$f6"
|
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
||||||
ff="$ff $first_packet_only"
|
|
||||||
filter_apply_ipset_target6 f6
|
filter_apply_ipset_target6 f6
|
||||||
filter_apply_ipset_target6 ff
|
|
||||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre6 $1 "$(reverse_nfqws_rule $ff)" $qn6
|
fw_reverse_nfqws_rule6 $1 "$f6" $qn6
|
||||||
fi
|
fi
|
||||||
if [ -n "$qns6" ]; then
|
if [ -n "$qns6" ]; then
|
||||||
f6="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
f6="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
||||||
filter_apply_ipset_target6 f6
|
filter_apply_ipset_target6 f6
|
||||||
fw_nfqws_post6 $1 "$f6 $desync" $qns6
|
fw_nfqws_post6 $1 "$f6 $desync" $qns6
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre6 $1 "$(reverse_nfqws_rule $f6)" $qns6
|
fw_reverse_nfqws_rule6 $1 "$f6" $qns6
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -38,3 +38,16 @@ zapret_unapply_firewall()
|
|||||||
{
|
{
|
||||||
zapret_do_firewall 0 "$@"
|
zapret_do_firewall 0 "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
first_packets_for_mode()
|
||||||
|
{
|
||||||
|
# autohostlist and autottl modes requires incoming traffic sample
|
||||||
|
# always use conntrack packet limiter or nfqws will deal with gigabytes
|
||||||
|
local n
|
||||||
|
if [ "$MODE_FILTER" = "autohostlist" ]; then
|
||||||
|
n=$((6+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
|
||||||
|
else
|
||||||
|
n=6
|
||||||
|
fi
|
||||||
|
echo $n
|
||||||
|
}
|
128
common/nft.sh
128
common/nft.sh
@ -1,4 +1,5 @@
|
|||||||
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
|
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
|
||||||
|
readonly nft_connbytes="ct original packets"
|
||||||
|
|
||||||
# required for : nft -f -
|
# required for : nft -f -
|
||||||
create_dev_stdin
|
create_dev_stdin
|
||||||
@ -94,18 +95,25 @@ cat << EOF | nft -f -
|
|||||||
flush chain inet $ZAPRET_NFT_TABLE postnat
|
flush chain inet $ZAPRET_NFT_TABLE postnat
|
||||||
add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; }
|
add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; }
|
||||||
flush chain inet $ZAPRET_NFT_TABLE prerouting
|
flush chain inet $ZAPRET_NFT_TABLE prerouting
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE prenat { type filter hook prerouting priority -101; }
|
||||||
|
flush chain inet $ZAPRET_NFT_TABLE prenat
|
||||||
add chain inet $ZAPRET_NFT_TABLE predefrag { type filter hook output priority -401; }
|
add chain inet $ZAPRET_NFT_TABLE predefrag { type filter hook output priority -401; }
|
||||||
flush chain inet $ZAPRET_NFT_TABLE predefrag
|
flush chain inet $ZAPRET_NFT_TABLE predefrag
|
||||||
add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 ip frag-off != 0 notrack comment "do not track nfqws generated ipfrag packets to avoid nat tampering and defragmentation"
|
add chain inet $ZAPRET_NFT_TABLE predefrag_nfqws
|
||||||
add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 exthdr frag exists notrack comment "do not track nfqws generated ipfrag packets to avoid nat tampering and defragmentation"
|
flush chain inet $ZAPRET_NFT_TABLE predefrag_nfqws
|
||||||
|
add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 jump predefrag_nfqws comment "nfqws generated : avoid drop by INVALID conntrack state"
|
||||||
|
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws mark and $DESYNC_MARK_POSTNAT !=0 notrack comment "postnat traffic"
|
||||||
|
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws ip frag-off != 0 notrack comment "ipfrag"
|
||||||
|
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws exthdr frag exists notrack comment "ipfrag"
|
||||||
|
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws tcp flags ! syn,rst,ack notrack comment "datanoack"
|
||||||
add set inet $ZAPRET_NFT_TABLE lanif { type ifname; }
|
add set inet $ZAPRET_NFT_TABLE lanif { type ifname; }
|
||||||
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
|
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
|
||||||
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
|
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
|
||||||
add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; }
|
add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; }
|
||||||
EOF
|
EOF
|
||||||
[ -n "$POSTNAT_ALL" ] && {
|
[ -n "$POSTNAT_ALL" ] && {
|
||||||
nft_flush_chain predefrag
|
nft_flush_chain predefrag_nfqws
|
||||||
nft_add_rule predefrag mark and $DESYNC_MARK !=0 notrack comment \"do not track nfqws generated packets to avoid nat tampering and defragmentation\"
|
nft_add_rule predefrag_nfqws notrack comment \"do not track nfqws generated packets to avoid nat tampering and defragmentation\"
|
||||||
}
|
}
|
||||||
# unfortunately this approach breaks udp desync of the connection initiating packet (new, first one)
|
# unfortunately this approach breaks udp desync of the connection initiating packet (new, first one)
|
||||||
# however without notrack ipfrag will not work
|
# however without notrack ipfrag will not work
|
||||||
@ -128,7 +136,9 @@ cat << EOF | nft -f - 2>/dev/null
|
|||||||
delete chain inet $ZAPRET_NFT_TABLE postrouting
|
delete chain inet $ZAPRET_NFT_TABLE postrouting
|
||||||
delete chain inet $ZAPRET_NFT_TABLE postnat
|
delete chain inet $ZAPRET_NFT_TABLE postnat
|
||||||
delete chain inet $ZAPRET_NFT_TABLE prerouting
|
delete chain inet $ZAPRET_NFT_TABLE prerouting
|
||||||
|
delete chain inet $ZAPRET_NFT_TABLE prenat
|
||||||
delete chain inet $ZAPRET_NFT_TABLE predefrag
|
delete chain inet $ZAPRET_NFT_TABLE predefrag
|
||||||
|
delete chain inet $ZAPRET_NFT_TABLE predefrag_nfqws
|
||||||
delete chain inet $ZAPRET_NFT_TABLE flow_offload
|
delete chain inet $ZAPRET_NFT_TABLE flow_offload
|
||||||
delete chain inet $ZAPRET_NFT_TABLE localnet_protect
|
delete chain inet $ZAPRET_NFT_TABLE localnet_protect
|
||||||
EOF
|
EOF
|
||||||
@ -445,14 +455,26 @@ nft_fw_tpws()
|
|||||||
nft_fw_tpws4 "$1" $3
|
nft_fw_tpws4 "$1" $3
|
||||||
nft_fw_tpws6 "$2" $3
|
nft_fw_tpws6 "$2" $3
|
||||||
}
|
}
|
||||||
|
is_postnat()
|
||||||
|
{
|
||||||
|
[ "$POSTNAT" = 1 -o "$POSTNAT_ALL" = 1 ]
|
||||||
|
}
|
||||||
get_postchain()
|
get_postchain()
|
||||||
{
|
{
|
||||||
if [ "$POSTNAT" = 1 -o "$POSTNAT_ALL" = 1 ] ; then
|
if is_postnat ; then
|
||||||
echo -n postnat
|
echo -n postnat
|
||||||
else
|
else
|
||||||
echo -n postrouting
|
echo -n postrouting
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
get_prechain()
|
||||||
|
{
|
||||||
|
if is_postnat ; then
|
||||||
|
echo -n prenat
|
||||||
|
else
|
||||||
|
echo -n prerouting
|
||||||
|
fi
|
||||||
|
}
|
||||||
_nft_fw_nfqws_post4()
|
_nft_fw_nfqws_post4()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv4
|
# $1 - filter ipv4
|
||||||
@ -460,10 +482,11 @@ _nft_fw_nfqws_post4()
|
|||||||
# $3 - not-empty if wan interface filtering required
|
# $3 - not-empty if wan interface filtering required
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||||
local filter="$1" port="$2" rule
|
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
|
||||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
|
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
|
||||||
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
|
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
|
||||||
nft_add_rule $(get_postchain) $rule queue num $port bypass
|
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
||||||
|
nft_add_rule $chain $rule $setmark queue num $port bypass
|
||||||
nft_add_nfqws_flow_exempt_rule "$rule"
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,10 +497,11 @@ _nft_fw_nfqws_post6()
|
|||||||
# $3 - not-empty if wan interface filtering required
|
# $3 - not-empty if wan interface filtering required
|
||||||
|
|
||||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||||
local filter="$1" port="$2" rule
|
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
|
||||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
|
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
|
||||||
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"
|
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"
|
||||||
nft_add_rule $(get_postchain) $rule queue num $port bypass
|
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
||||||
|
nft_add_rule $chain $rule $setmark queue num $port bypass
|
||||||
nft_add_nfqws_flow_exempt_rule "$rule"
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -501,7 +525,7 @@ _nft_fw_nfqws_pre4()
|
|||||||
local filter="$1" port="$2" rule
|
local filter="$1" port="$2" rule
|
||||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
||||||
rule="${3:+iifname @wanif }$filter ip saddr != @nozapret"
|
rule="${3:+iifname @wanif }$filter ip saddr != @nozapret"
|
||||||
nft_add_rule prerouting $rule queue num $port bypass
|
nft_add_rule $(get_prechain) $rule queue num $port bypass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_nft_fw_nfqws_pre6()
|
_nft_fw_nfqws_pre6()
|
||||||
@ -514,7 +538,7 @@ _nft_fw_nfqws_pre6()
|
|||||||
local filter="$1" port="$2" rule
|
local filter="$1" port="$2" rule
|
||||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
||||||
rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6"
|
rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6"
|
||||||
nft_add_rule prerouting $rule queue num $port bypass
|
nft_add_rule $(get_prechain) $rule queue num $port bypass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nft_fw_nfqws_pre()
|
nft_fw_nfqws_pre()
|
||||||
@ -566,22 +590,47 @@ zapret_list_table()
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
nft_produce_reverse_nfqws_rule()
|
||||||
|
{
|
||||||
|
local rule="$1"
|
||||||
|
if contains "$rule" "$nft_connbytes "; then
|
||||||
|
# autohostlist - need several incoming packets
|
||||||
|
# autottl - need only one incoming packet
|
||||||
|
[ "$MODE_FILTER" = autohostlist ] || rule=$(echo "$rule" | sed -re 's/$nft_connbytes [0-9]+-[0-9]+/$nft_connbytes 1-1/')
|
||||||
|
else
|
||||||
|
rule="$nft_connbytes 1-$(first_packets_for_mode) $rule"
|
||||||
|
fi
|
||||||
|
nft_reverse_nfqws_rule $rule
|
||||||
|
}
|
||||||
|
nft_fw_reverse_nfqws_rule4()
|
||||||
|
{
|
||||||
|
nft_fw_nfqws_pre4 "$(nft_produce_reverse_nfqws_rule "$1")" $2
|
||||||
|
}
|
||||||
|
nft_fw_reverse_nfqws_rule6()
|
||||||
|
{
|
||||||
|
nft_fw_nfqws_pre6 "$(nft_produce_reverse_nfqws_rule "$1")" $2
|
||||||
|
}
|
||||||
|
nft_fw_reverse_nfqws_rule()
|
||||||
|
{
|
||||||
|
# ensure that modes relying on incoming traffic work
|
||||||
|
# $1 - rule4
|
||||||
|
# $2 - rule6
|
||||||
|
# $3 - queue number
|
||||||
|
nft_fw_reverse_nfqws_rule4 "$1" $3
|
||||||
|
nft_fw_reverse_nfqws_rule6 "$2" $3
|
||||||
|
}
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft()
|
zapret_apply_firewall_rules_nft()
|
||||||
{
|
{
|
||||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||||
|
|
||||||
local first_packet_only
|
local first_packets_only
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
local f4 f6 ff qn qns qn6 qns6
|
local f4 f6 qn qns qn6 qns6
|
||||||
|
|
||||||
# autohostlist mode requires incoming traffic sample
|
first_packets_only="$nft_connbytes 1-$(first_packets_for_mode)"
|
||||||
# always use conntrack packet limiter or nfqws will deal with gigabytes
|
|
||||||
if [ "$MODE_FILTER" = "autohostlist" ]; then
|
|
||||||
first_packet_only=$((6+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
|
|
||||||
else
|
|
||||||
first_packet_only=6
|
|
||||||
fi
|
|
||||||
first_packet_only="ct original packets 1-$first_packet_only"
|
|
||||||
|
|
||||||
case "$mode" in
|
case "$mode" in
|
||||||
tpws)
|
tpws)
|
||||||
@ -595,69 +644,66 @@ zapret_apply_firewall_rules_nft()
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
nfqws)
|
nfqws)
|
||||||
|
local POSTNAT_SAVE=$POSTNAT
|
||||||
|
POSTNAT=1
|
||||||
# quite complex but we need to minimize nfqws processes to save RAM
|
# quite complex but we need to minimize nfqws processes to save RAM
|
||||||
get_nfqws_qnums qn qns qn6 qns6
|
get_nfqws_qnums qn qns qn6 qns6
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
||||||
nft_filter_apply_port_target f4
|
nft_filter_apply_port_target f4
|
||||||
f4="$f4 $first_packet_only"
|
f4="$f4 $first_packets_only"
|
||||||
nft_filter_apply_ipset_target4 f4
|
nft_filter_apply_ipset_target4 f4
|
||||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $f4)" $qn
|
nft_fw_reverse_nfqws_rule4 "$f4" $qn
|
||||||
else
|
else
|
||||||
if [ -n "$qn" ]; then
|
if [ -n "$qn" ]; then
|
||||||
f4="tcp dport {$HTTP_PORTS}"
|
f4="tcp dport {$HTTP_PORTS}"
|
||||||
ff="$f4"
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packets_only"
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
|
||||||
ff="$ff $first_packet_only"
|
|
||||||
nft_filter_apply_ipset_target4 f4
|
nft_filter_apply_ipset_target4 f4
|
||||||
nft_filter_apply_ipset_target4 ff
|
|
||||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $ff)" $qn
|
nft_fw_reverse_nfqws_rule4 "$f4" $qn
|
||||||
fi
|
fi
|
||||||
if [ -n "$qns" ]; then
|
if [ -n "$qns" ]; then
|
||||||
f4="tcp dport {$HTTPS_PORTS} $first_packet_only"
|
f4="tcp dport {$HTTPS_PORTS} $first_packets_only"
|
||||||
nft_filter_apply_ipset_target4 f4
|
nft_filter_apply_ipset_target4 f4
|
||||||
nft_fw_nfqws_post4 "$f4 $desync" $qns
|
nft_fw_nfqws_post4 "$f4 $desync" $qns
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $f4)" $qns
|
nft_fw_reverse_nfqws_rule4 "$f4" $qns
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||||
nft_filter_apply_port_target f6
|
nft_filter_apply_port_target f6
|
||||||
f6="$f6 $first_packet_only"
|
f6="$f6 $first_packets_only"
|
||||||
nft_filter_apply_ipset_target6 f6
|
nft_filter_apply_ipset_target6 f6
|
||||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $f6)" $qn
|
nft_fw_reverse_nfqws_rule6 "$f6" $qn6
|
||||||
else
|
else
|
||||||
if [ -n "$qn6" ]; then
|
if [ -n "$qn6" ]; then
|
||||||
f6="tcp dport {$HTTP_PORTS}"
|
f6="tcp dport {$HTTP_PORTS}"
|
||||||
ff="$f6"
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packets_only"
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
|
||||||
ff="$ff $first_packet_only"
|
|
||||||
nft_filter_apply_ipset_target6 f6
|
nft_filter_apply_ipset_target6 f6
|
||||||
nft_filter_apply_ipset_target6 ff
|
|
||||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $ff)" $qn6
|
nft_fw_reverse_nfqws_rule6 "$f6" $qn6
|
||||||
fi
|
fi
|
||||||
if [ -n "$qns6" ]; then
|
if [ -n "$qns6" ]; then
|
||||||
f6="tcp dport {$HTTPS_PORTS} $first_packet_only"
|
f6="tcp dport {$HTTPS_PORTS} $first_packets_only"
|
||||||
nft_filter_apply_ipset_target6 f6
|
nft_filter_apply_ipset_target6 f6
|
||||||
nft_fw_nfqws_post6 "$f6 $desync" $qns6
|
nft_fw_nfqws_post6 "$f6 $desync" $qns6
|
||||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $f6)" $qns6
|
nft_fw_reverse_nfqws_rule6 "$f6" $qns6
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
POSTNAT=$POSTNAT_SAVE
|
||||||
|
|
||||||
get_nfqws_qnums_quic qn qn6
|
get_nfqws_qnums_quic qn qn6
|
||||||
if [ -n "$qn" ]; then
|
if [ -n "$qn" ]; then
|
||||||
f4=
|
f4=
|
||||||
nft_filter_apply_port_target_quic f4
|
nft_filter_apply_port_target_quic f4
|
||||||
f4="$f4 $first_packet_only"
|
f4="$f4 $first_packets_only"
|
||||||
nft_filter_apply_ipset_target4 f4
|
nft_filter_apply_ipset_target4 f4
|
||||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||||
fi
|
fi
|
||||||
if [ -n "$qn6" ]; then
|
if [ -n "$qn6" ]; then
|
||||||
f6=
|
f6=
|
||||||
nft_filter_apply_port_target_quic f6
|
nft_filter_apply_port_target_quic f6
|
||||||
f6="$f6 $first_packet_only"
|
f6="$f6 $first_packets_only"
|
||||||
nft_filter_apply_ipset_target6 f6
|
nft_filter_apply_ipset_target6 f6
|
||||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||||
fi
|
fi
|
||||||
|
1
config
1
config
@ -63,6 +63,7 @@ MODE_FILTER=none
|
|||||||
|
|
||||||
# CHOOSE NFQWS DAEMON OPTIONS for DPI desync mode. run "nfq/nfqws --help" for option list
|
# CHOOSE NFQWS DAEMON OPTIONS for DPI desync mode. run "nfq/nfqws --help" for option list
|
||||||
DESYNC_MARK=0x40000000
|
DESYNC_MARK=0x40000000
|
||||||
|
DESYNC_MARK_POSTNAT=0x20000000
|
||||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-ttl6=0 --dpi-desync-fooling=badsum"
|
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-ttl6=0 --dpi-desync-fooling=badsum"
|
||||||
#NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
#NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||||
#NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
#NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||||
|
@ -26,8 +26,10 @@ ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
|
|||||||
|
|
||||||
|
|
||||||
ipfw delete 100
|
ipfw delete 100
|
||||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
|
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit vmx0
|
||||||
ipfw add 100 divert 989 udp from any to any 443 out not diverted not sockarg xmit em0
|
ipfw add 100 divert 989 udp from any to any 443 out not diverted not sockarg xmit em0
|
||||||
|
# this is required for autottl but very bad, all incoming traffic will be diverted, no way to limit like in linux (connbytes)
|
||||||
|
ipfw add 100 divert 989 tcp from any 80,443 to any in not diverted not sockarg recv em0
|
||||||
|
|
||||||
ipfw delete 100
|
ipfw delete 100
|
||||||
ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||||
|
@ -255,3 +255,10 @@ autohostlist mode
|
|||||||
v53
|
v53
|
||||||
|
|
||||||
nfqws: tcp session reassemble for TLS ClientHello
|
nfqws: tcp session reassemble for TLS ClientHello
|
||||||
|
|
||||||
|
v54
|
||||||
|
|
||||||
|
tpws: out of band send when splitting (--oob)
|
||||||
|
nfqws: autottl
|
||||||
|
nfqws: datanoack fooling
|
||||||
|
nftables: use POSTNAT path for tcp redirections to allow NAT-breaking strategies. use additional mark bit DESYNC_MARK_POSTNAT.
|
||||||
|
@ -97,6 +97,15 @@ Then we can reduce CPU load, refusing to process unnecessary packets.
|
|||||||
Mark filter does not allow nfqws-generated packets to enter the queue again.
|
Mark filter does not allow nfqws-generated packets to enter the queue again.
|
||||||
Its necessary to use this filter when also using `connbytes 1:6`. Without it packet ordering can be changed breaking the whole idea.
|
Its necessary to use this filter when also using `connbytes 1:6`. Without it packet ordering can be changed breaking the whole idea.
|
||||||
|
|
||||||
|
Some attacks require redirection of incoming packets :
|
||||||
|
|
||||||
|
iptables -t mangle -I PREROUTING -i <external_interface> -p tcp --sport 80 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:6 -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
|
||||||
|
|
||||||
|
Incoming packets are filtered by incoming interface, source port and IP. This is opposite to the direct rule.
|
||||||
|
|
||||||
|
Some techniques that break NAT are possible only with nftables.
|
||||||
|
|
||||||
|
|
||||||
## ip6tables
|
## ip6tables
|
||||||
|
|
||||||
ip6tables work almost exactly the same way as ipv4, but there are a number of important nuances.
|
ip6tables work almost exactly the same way as ipv4, but there are a number of important nuances.
|
||||||
@ -120,7 +129,10 @@ nf sets do not support overlapping intervals and that's why nft process applies
|
|||||||
There're equivalents to iptables for all other functions. Interface and protocol anonymous sets allow not to write multiple similar rules.
|
There're equivalents to iptables for all other functions. Interface and protocol anonymous sets allow not to write multiple similar rules.
|
||||||
Flow offloading is built-in into new linux kernels and nft versions.
|
Flow offloading is built-in into new linux kernels and nft versions.
|
||||||
|
|
||||||
nft version `1.0.2` or higher is recommended.
|
nft version `1.0.2` or higher is recommended. But the higher is version the better.
|
||||||
|
|
||||||
|
Some techniques can be fully used only with nftables. It's not possible to queue packets after NAT in iptables.
|
||||||
|
This limits techniques that break NAT.
|
||||||
|
|
||||||
|
|
||||||
## When it will not work
|
## When it will not work
|
||||||
@ -158,7 +170,9 @@ nfqws takes the following parameters:
|
|||||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
||||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum hopbyhop hopbyhop2
|
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; auto ttl mode for both ipv4 and ipv6. default: 1:3-20
|
||||||
|
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for ipv6 only
|
||||||
|
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||||
--dpi-desync-retrans=0|1 ; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission
|
--dpi-desync-retrans=0|1 ; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission
|
||||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||||
@ -181,7 +195,7 @@ nfqws takes the following parameters:
|
|||||||
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 2)
|
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
||||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||||
@ -234,6 +248,23 @@ add tcp option **MD5 signature**. All of them have their own disadvantages :
|
|||||||
Some ISPs/operators drop ipv6 packets with hop-by-hop options. Fakes will not be processed by the server either because
|
Some ISPs/operators drop ipv6 packets with hop-by-hop options. Fakes will not be processed by the server either because
|
||||||
ISP drops them or because there are two same headers.
|
ISP drops them or because there are two same headers.
|
||||||
DPIs may still anaylize packets with one or two hop-by-hop headers.
|
DPIs may still anaylize packets with one or two hop-by-hop headers.
|
||||||
|
* `datanoack` sends tcp fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||||
|
This mode breaks NAT and does not work with iptables if masquerade is used, even from the router itself.
|
||||||
|
Works with nftables properly. Requires external IP address.
|
||||||
|
* `autottl` tries to automatically guess TTL value that allows DPI to receive fakes and does not allow them to reach the server.
|
||||||
|
This tech relies on well known TTL values used by OS : 64,128,255. nfqws takes first incoming packet (YES, you need to redirect it too),
|
||||||
|
guesses path length and decreases by `delta` value (default 1). If resulting value is outside the range (min,max - default 3,20)
|
||||||
|
then its normalized to min or max. If the path shorter than the value then autottl fails and falls back to the fixed value.
|
||||||
|
This can help if multiple DPIs exists on backbone channels, not just near the ISP.
|
||||||
|
Can fail if inbound and outbound paths are not symmetric.
|
||||||
|
|
||||||
|
|
||||||
|
special knowledge what you are doing. Blockcheck can find a strategy with 'datanoack'
|
||||||
|
but it will not work with forwarded traffic unless POSTNAT mode is enabled.
|
||||||
|
POSTNAT mode brings some limits. No desync of the first UDP packet is possible (QUIC, for example).
|
||||||
|
That's why it's disabled by default. To enable write POSTNAT_ALL=1 to config.
|
||||||
|
Works only with nftables and from the system with an external IP address.
|
||||||
|
|
||||||
|
|
||||||
`--dpi-desync-fooling` takes multiple comma separated values.
|
`--dpi-desync-fooling` takes multiple comma separated values.
|
||||||
|
|
||||||
@ -538,7 +569,7 @@ tpws is transparent proxy.
|
|||||||
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 2)
|
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||||
|
|
||||||
@ -546,6 +577,7 @@ tpws is transparent proxy.
|
|||||||
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for http reqs.
|
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for http reqs.
|
||||||
--split-any-protocol ; split not only http and https
|
--split-any-protocol ; split not only http and https
|
||||||
--disorder ; when splitting simulate sending second fragment first
|
--disorder ; when splitting simulate sending second fragment first
|
||||||
|
--oob ; when splitting send out of band zero byte
|
||||||
--hostcase ; change Host: => host:
|
--hostcase ; change Host: => host:
|
||||||
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||||
--hostdot ; add "." after Host: name
|
--hostdot ; add "." after Host: name
|
||||||
@ -826,6 +858,7 @@ nfqws options for DPI desync attack:
|
|||||||
|
|
||||||
```
|
```
|
||||||
DESYNC_MARK=0x40000000
|
DESYNC_MARK=0x40000000
|
||||||
|
DESYNC_MARK_POSTNAT=0x20000000
|
||||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum --dpi-desync-fwmark=$DESYNC_MARK"
|
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum --dpi-desync-fwmark=$DESYNC_MARK"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
zapret v.53
|
zapret v.54
|
||||||
|
|
||||||
English
|
English
|
||||||
-------
|
-------
|
||||||
@ -137,6 +137,14 @@ iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp
|
|||||||
Если применяется фильтр по connbytes 1:6, то обязательно добавлять в iptables и фильтр по mark. Иначе возможно
|
Если применяется фильтр по connbytes 1:6, то обязательно добавлять в iptables и фильтр по mark. Иначе возможно
|
||||||
перепутывание порядка следования пакетов, что приведет к неработоспособности метода.
|
перепутывание порядка следования пакетов, что приведет к неработоспособности метода.
|
||||||
|
|
||||||
|
Для некоторых атак на DPI требуется перенаправлять один или несколько входящих пакетов от соединения :
|
||||||
|
|
||||||
|
iptables -t mangle -I PREROUTING -i <внешний_интерфейс> -p tcp --sport 80 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:6 -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass
|
||||||
|
|
||||||
|
Получаемые пакеты будут фильтровться по входящему интерфейсу, порту и IP источника, то есть наоборот прямому правилу.
|
||||||
|
|
||||||
|
Некоторые техники, ломающие NAT, не всегда можно реализовать через iptables. Требуются nftables.
|
||||||
|
|
||||||
|
|
||||||
Если ваше устройство поддерживает аппаратное ускорение (flow offloading, hardware nat, hardware acceleration), то iptables могут не работать.
|
Если ваше устройство поддерживает аппаратное ускорение (flow offloading, hardware nat, hardware acceleration), то iptables могут не работать.
|
||||||
При включенном offloading пакет не проходит по обычному пути netfilter.
|
При включенном offloading пакет не проходит по обычному пути netfilter.
|
||||||
@ -176,11 +184,17 @@ NFQUEUE работает без изменений.
|
|||||||
Если коротко, то в nftables невозможно работать с большими ip листами на системах с малым количеством RAM.
|
Если коротко, то в nftables невозможно работать с большими ip листами на системах с малым количеством RAM.
|
||||||
Остальные рассматриваемые здесь функции могут быть перенесены на nftables.
|
Остальные рассматриваемые здесь функции могут быть перенесены на nftables.
|
||||||
|
|
||||||
Рекомендуется версия nft 1.0.2 или выше.
|
Рекомендуется версия nft 1.0.2 или выше. Но чем выше версия, тем лучше. В nft регулярно находят баги.
|
||||||
|
|
||||||
Относительно старые версии ядра и/или утилиты nft могут вызывать ошибки.
|
Относительно старые версии ядра и/или утилиты nft могут вызывать ошибки.
|
||||||
В частности, на ubuntu 18.04 с ядром 4.15 будут проблемы. В 20.04 - работает.
|
В частности, на ubuntu 18.04 с ядром 4.15 будут проблемы. В 20.04 - работает.
|
||||||
|
|
||||||
|
Некоторые техники можно полноценно использовать только с nftables.
|
||||||
|
Например, в iptables невозможно перенаправить пакеты на nfqws после NAT.
|
||||||
|
Следовательно, при использовании NAT невозможно произвести атаку, не совместимую с NAT.
|
||||||
|
В nftables этой проблемы не существует, потому что приоритеты хука выставляете вы сами, а не привязаны к фиксированным
|
||||||
|
значениям, соответствующим разным таблицам iptables. В iptables нет таблицы, способной перехватить пакеты после MASQUERDADE.
|
||||||
|
|
||||||
|
|
||||||
Когда это работать не будет
|
Когда это работать не будет
|
||||||
---------------------------
|
---------------------------
|
||||||
@ -226,7 +240,9 @@ nfqws
|
|||||||
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
||||||
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
||||||
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
|
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
|
||||||
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum hopbyhop hopbyhop2
|
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. delta=0 отключает функцию.
|
||||||
|
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
|
||||||
|
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
|
||||||
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
|
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
|
||||||
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
||||||
--dpi-desync-skip-nosni=0| 1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
--dpi-desync-skip-nosni=0| 1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
||||||
@ -246,7 +262,7 @@ nfqws
|
|||||||
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие
|
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие
|
||||||
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются
|
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются
|
||||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 2)
|
--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. позволяет разобраться почему там появляются хосты.
|
||||||
@ -308,6 +324,19 @@ fakeknown отличается от fake тем, что применяется
|
|||||||
стеком протоколов во всех ОС. Один хедер hop-by-hop принимается всеми ОС, однако на некоторых каналах/провайдерах
|
стеком протоколов во всех ОС. Один хедер hop-by-hop принимается всеми ОС, однако на некоторых каналах/провайдерах
|
||||||
такие пакеты могут фильтроваться и не доходить. Расчет идет на то, что DPI проанализирует пакет с hop-by-hop,
|
такие пакеты могут фильтроваться и не доходить. Расчет идет на то, что DPI проанализирует пакет с hop-by-hop,
|
||||||
но он либо не дойдет до адресата всилу фильтров провайдера, либо будет отброшен сервером, потому что хедера два.
|
но он либо не дойдет до адресата всилу фильтров провайдера, либо будет отброшен сервером, потому что хедера два.
|
||||||
|
* datanoack высылает фейки со снятым tcp флагом ACK. Сервера такое не принимают, а DPI может принять.
|
||||||
|
Эта техника ломает NAT и не работает с iptables, если используется masquerade, даже с локальной системы
|
||||||
|
(почти всегда для ipv4). С nftables работает без ограничений. Требуется внешний IP адрес.
|
||||||
|
* autottl. Суть режима в автоматическом определении TTL, чтобы он почти наверняка прошел DPI и немного не дошел до сервера.
|
||||||
|
Берутся базовые значения TTL 64,128,255, смотрится входящий пакет (да, требуется направить первый входящий пакет на nfqws !).
|
||||||
|
Вычисляется длина пути, отнимается delta (1 по умолчанию). Если TTL вне диапазона (min,max - 3,20 по умолчанию),
|
||||||
|
то берутся значения min,max, чтобы вписаться в диапазон. Если при этом полученый TTL больше длины пути,
|
||||||
|
то автоматизм не сработал и берутся фиксированные значения TTL для атаки.
|
||||||
|
Техника позволяет решить вопрос , когда вся сеть перегорожена шлагбаумами (DPI, ТСПУ) везде где только можно,
|
||||||
|
включая магистралов. Но потенциально может давать сбои.
|
||||||
|
Например, при ассиметрии входящего и исходящего канала до конкретного сервера.
|
||||||
|
На каких-то провайдерах эта техника будет работать неплохо, на других доставит больше проблем, чем пользы.
|
||||||
|
Где-то может потребоваться тюнинг параметров. Лучше использовать с дополнительным ограничителем.
|
||||||
|
|
||||||
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
|
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
|
||||||
|
|
||||||
@ -617,6 +646,7 @@ tpws - это transparent proxy.
|
|||||||
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http.
|
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http.
|
||||||
--split-any-protocol ; применять split-pos к любым пакетам. по умолчанию - только к http и TLS ClientHello
|
--split-any-protocol ; применять split-pos к любым пакетам. по умолчанию - только к http и TLS ClientHello
|
||||||
--disorder ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
|
--disorder ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
|
||||||
|
--oob ; отправить 1 нулевой байт out-of-band data (OOB) в конце первой части сплита
|
||||||
--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."
|
||||||
@ -638,7 +668,7 @@ tpws - это transparent proxy.
|
|||||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов, они обьединяются
|
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов, они обьединяются
|
||||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 2)
|
--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. позволяет разобраться почему там появляются хосты.
|
||||||
|
|
||||||
@ -1087,6 +1117,7 @@ TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"
|
|||||||
Опции nfqws для атаки десинхронизации DPI :
|
Опции nfqws для атаки десинхронизации DPI :
|
||||||
|
|
||||||
DESYNC_MARK=0x40000000
|
DESYNC_MARK=0x40000000
|
||||||
|
DESYNC_MARK_POSTNAT=0x20000000
|
||||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||||
|
|
||||||
Задание раздельных опций nfqws для http и https и для версий ip протоколов 4,6 :
|
Задание раздельных опций nfqws для http и https и для версий ip протоколов 4,6 :
|
||||||
|
@ -21,7 +21,7 @@ zapret_custom_firewall()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f uf4 uf6
|
local f uf4 uf6
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1"
|
local first_packet_only="$ipt_connbytes 1:1"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt $1
|
zapret_do_firewall_rules_ipt $1
|
||||||
@ -37,7 +37,7 @@ zapret_custom_firewall_nft()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f
|
local f
|
||||||
local first_packet_only="ct original packets 1"
|
local first_packet_only="$nft_connbytes 1"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
zapret_apply_firewall_rules_nft
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering
|
# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering
|
||||||
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
||||||
# russian TSPU version : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake --dpi-desync-fake-quic=/opt/zapret/files/fake/quic_short_header.bin"
|
|
||||||
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
|
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
|
||||||
|
|
||||||
QNUM2=$(($QNUM+10))
|
QNUM2=$(($QNUM+10))
|
||||||
@ -23,7 +22,7 @@ zapret_custom_firewall()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f
|
local f
|
||||||
local first_packets_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3"
|
local first_packets_only="$ipt_connbytes 1:3"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt $1
|
zapret_do_firewall_rules_ipt $1
|
||||||
@ -38,7 +37,7 @@ zapret_custom_firewall_nft()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f
|
local f
|
||||||
local first_packets_only="ct original packets 1-3"
|
local first_packets_only="$nft_connbytes 1-3"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
zapret_apply_firewall_rules_nft
|
||||||
|
@ -24,7 +24,7 @@ zapret_custom_firewall()
|
|||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local f4 f6
|
local f4 f6
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4"
|
local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
[ "$MODE_HTTP" = "1" ] && {
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
@ -45,8 +45,10 @@ zapret_custom_firewall_nft()
|
|||||||
{
|
{
|
||||||
# stop logic is not required
|
# stop logic is not required
|
||||||
|
|
||||||
|
# do not use POSTNAT for udp first packet desync !
|
||||||
|
local POSTNAT=1
|
||||||
local f4 f6
|
local f4 f6
|
||||||
local first_packet_only="ct original packets 1-4"
|
local first_packet_only="$nft_connbytes 1-$(first_packets_for_mode)"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
[ "$MODE_HTTP" = "1" ] && {
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
@ -61,5 +63,7 @@ zapret_custom_firewall_nft()
|
|||||||
f6=$f4
|
f6=$f4
|
||||||
nft_filter_apply_ipset_target f4 f6
|
nft_filter_apply_ipset_target f4 f6
|
||||||
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
|
# for modes that require incoming traffic
|
||||||
|
nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
[ -n "$TPPORT" ] || TPPORT=988
|
[ -n "$TPPORT" ] || TPPORT=988
|
||||||
[ -n "$WS_USER" ] || WS_USER=daemon
|
[ -n "$WS_USER" ] || WS_USER=daemon
|
||||||
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
||||||
|
[ -n "$DESYNC_MARK_POSTNAT" ] || DESYNC_MARK_POSTNAT=0x20000000
|
||||||
[ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan
|
[ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan
|
||||||
|
|
||||||
TPWS_LOCALHOST4=127.0.0.127
|
TPWS_LOCALHOST4=127.0.0.127
|
||||||
|
@ -21,7 +21,7 @@ zapret_custom_firewall()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f uf4 uf6
|
local f uf4 uf6
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1"
|
local first_packet_only="$ipt_connbytes 1:1"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt $1
|
zapret_do_firewall_rules_ipt $1
|
||||||
@ -38,7 +38,7 @@ zapret_custom_firewall_nft()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f
|
local f
|
||||||
local first_packet_only="ct original packets 1"
|
local first_packet_only="$nft_connbytes 1"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
zapret_apply_firewall_rules_nft
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering
|
# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering
|
||||||
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
||||||
# russian TSPU version : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake --dpi-desync-fake-quic=/opt/zapret/files/fake/quic_short_header.bin"
|
|
||||||
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
|
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
|
||||||
|
|
||||||
QNUM2=$(($QNUM+10))
|
QNUM2=$(($QNUM+10))
|
||||||
@ -23,7 +22,7 @@ zapret_custom_firewall()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f
|
local f
|
||||||
local first_packets_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3"
|
local first_packets_only="$ipt_connbytes 1:3"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt $1
|
zapret_do_firewall_rules_ipt $1
|
||||||
@ -38,7 +37,7 @@ zapret_custom_firewall_nft()
|
|||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local MODE_OVERRIDE=nfqws
|
||||||
local f
|
local f
|
||||||
local first_packets_only="ct original packets 1-3"
|
local first_packets_only="$nft_connbytes 1-3"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
zapret_apply_firewall_rules_nft
|
||||||
|
@ -24,7 +24,7 @@ zapret_custom_firewall()
|
|||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local f4 f6
|
local f4 f6
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4"
|
local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
[ "$MODE_HTTP" = "1" ] && {
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
@ -39,14 +39,18 @@ zapret_custom_firewall()
|
|||||||
f6=$f4
|
f6=$f4
|
||||||
filter_apply_ipset_target f4 f6
|
filter_apply_ipset_target f4 f6
|
||||||
fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM
|
fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
|
# for modes that require incoming traffic
|
||||||
|
fw_reverse_nfqws_rule $1 "$f4" "$f6" $QNUM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zapret_custom_firewall_nft()
|
zapret_custom_firewall_nft()
|
||||||
{
|
{
|
||||||
# stop logic is not required
|
# stop logic is not required
|
||||||
|
|
||||||
|
# do not use POSTNAT for udp first packet desync !
|
||||||
|
local POSTNAT=1
|
||||||
local f4 f6
|
local f4 f6
|
||||||
local first_packet_only="ct original packets 1-4"
|
local first_packet_only="$nft_connbytes 1-$(first_packets_for_mode)"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
[ "$MODE_HTTP" = "1" ] && {
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
@ -61,5 +65,7 @@ zapret_custom_firewall_nft()
|
|||||||
f6=$f4
|
f6=$f4
|
||||||
nft_filter_apply_ipset_target f4 f6
|
nft_filter_apply_ipset_target f4 f6
|
||||||
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
|
# for modes that require incoming traffic
|
||||||
|
nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
init.d/sysv/custom.default
Normal file
34
init.d/sysv/custom.default
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# this script contain your special code to launch daemons and configure firewall
|
||||||
|
# use helpers from "functions" file
|
||||||
|
# in case of upgrade keep this file only, do not modify others
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Start daemon\(s\)
|
||||||
|
echo Study how other sections work
|
||||||
|
|
||||||
|
do_daemon $1 1 /bin/sleep 20
|
||||||
|
}
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure iptables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure nftables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
@ -64,6 +64,9 @@ fi
|
|||||||
PIDDIR=/var/run
|
PIDDIR=/var/run
|
||||||
IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
||||||
|
|
||||||
|
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
||||||
|
[ -n "$DESYNC_MARK_POSTNAT" ] || DESYNC_MARK_POSTNAT=0x20000000
|
||||||
|
|
||||||
[ -n "$QNUM" ] || QNUM=200
|
[ -n "$QNUM" ] || QNUM=200
|
||||||
[ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws"
|
[ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws"
|
||||||
NFQWS_OPT_BASE="$USEROPT --dpi-desync-fwmark=$DESYNC_MARK"
|
NFQWS_OPT_BASE="$USEROPT --dpi-desync-fwmark=$DESYNC_MARK"
|
||||||
@ -81,8 +84,6 @@ TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
|
|||||||
# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case
|
# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case
|
||||||
TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3"
|
TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3"
|
||||||
|
|
||||||
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
|
||||||
|
|
||||||
# max wait time for the link local ipv6 on the LAN interface
|
# max wait time for the link local ipv6 on the LAN interface
|
||||||
LINKLOCAL_WAIT_SEC=5
|
LINKLOCAL_WAIT_SEC=5
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ typedef struct
|
|||||||
bool req_seq_start_present, req_seq_present;
|
bool req_seq_start_present, req_seq_present;
|
||||||
uint32_t req_seq_start,req_seq_end; // sequence interval of the request (to track retransmissions)
|
uint32_t req_seq_start,req_seq_end; // sequence interval of the request (to track retransmissions)
|
||||||
|
|
||||||
|
uint8_t autottl;
|
||||||
|
|
||||||
bool b_cutoff; // mark for deletion
|
bool b_cutoff; // mark for deletion
|
||||||
bool b_wssize_cutoff, b_desync_cutoff;
|
bool b_wssize_cutoff, b_desync_cutoff;
|
||||||
|
|
||||||
|
@ -59,13 +59,14 @@ uint8_t tcp_find_scale_factor(const struct tcphdr *tcp)
|
|||||||
|
|
||||||
// n prefix (nsport, nwsize) means network byte order
|
// n prefix (nsport, nwsize) means network byte order
|
||||||
static void fill_tcphdr(
|
static void fill_tcphdr(
|
||||||
struct tcphdr *tcp, uint8_t fooling, uint8_t tcp_flags,
|
struct tcphdr *tcp, uint32_t fooling, uint8_t tcp_flags,
|
||||||
uint32_t nseq, uint32_t nack_seq,
|
uint32_t nseq, uint32_t nack_seq,
|
||||||
uint16_t nsport, uint16_t ndport,
|
uint16_t nsport, uint16_t ndport,
|
||||||
uint16_t nwsize, uint8_t scale_factor,
|
uint16_t nwsize, uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment)
|
uint32_t badseq_ack_increment,
|
||||||
|
uint16_t data_len)
|
||||||
{
|
{
|
||||||
char *tcpopt = (char*)(tcp+1);
|
char *tcpopt = (char*)(tcp+1);
|
||||||
uint8_t t=0;
|
uint8_t t=0;
|
||||||
@ -84,6 +85,8 @@ static void fill_tcphdr(
|
|||||||
tcp->th_ack = nack_seq;
|
tcp->th_ack = nack_seq;
|
||||||
}
|
}
|
||||||
tcp->th_off = 5;
|
tcp->th_off = 5;
|
||||||
|
if ((fooling & FOOL_DATANOACK) && !(tcp_flags & (TH_SYN|TH_RST)) && data_len)
|
||||||
|
tcp_flags &= ~TH_ACK;
|
||||||
*((uint8_t*)tcp+13)= tcp_flags;
|
*((uint8_t*)tcp+13)= tcp_flags;
|
||||||
tcp->th_win = nwsize;
|
tcp->th_win = nwsize;
|
||||||
if (fooling & FOOL_MD5SIG)
|
if (fooling & FOOL_MD5SIG)
|
||||||
@ -115,7 +118,7 @@ static void fill_tcphdr(
|
|||||||
tcp->th_off += t>>2;
|
tcp->th_off += t>>2;
|
||||||
tcp->th_sum = 0;
|
tcp->th_sum = 0;
|
||||||
}
|
}
|
||||||
static uint16_t tcpopt_len(uint8_t fooling, const uint32_t *timestamps, uint8_t scale_factor)
|
static uint16_t tcpopt_len(uint32_t fooling, const uint32_t *timestamps, uint8_t scale_factor)
|
||||||
{
|
{
|
||||||
uint16_t t=0;
|
uint16_t t=0;
|
||||||
if (fooling & FOOL_MD5SIG) t=18;
|
if (fooling & FOOL_MD5SIG) t=18;
|
||||||
@ -163,7 +166,7 @@ bool prepare_tcp_segment4(
|
|||||||
uint8_t scale_factor,
|
uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment,
|
uint32_t badseq_ack_increment,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -179,7 +182,7 @@ bool prepare_tcp_segment4(
|
|||||||
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
||||||
|
|
||||||
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_TCP, ttl);
|
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_TCP, ttl);
|
||||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment);
|
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment,len);
|
||||||
|
|
||||||
memcpy(payload,data,len);
|
memcpy(payload,data,len);
|
||||||
tcp4_fix_checksum(tcp,ip_payload_len,&ip->ip_src,&ip->ip_dst);
|
tcp4_fix_checksum(tcp,ip_payload_len,&ip->ip_src,&ip->ip_dst);
|
||||||
@ -197,7 +200,7 @@ bool prepare_tcp_segment6(
|
|||||||
uint8_t scale_factor,
|
uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment,
|
uint32_t badseq_ack_increment,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -262,7 +265,7 @@ bool prepare_tcp_segment6(
|
|||||||
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
||||||
|
|
||||||
fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, proto, ttl);
|
fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, proto, ttl);
|
||||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment);
|
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment,len);
|
||||||
|
|
||||||
memcpy(payload,data,len);
|
memcpy(payload,data,len);
|
||||||
tcp6_fix_checksum(tcp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
|
tcp6_fix_checksum(tcp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
|
||||||
@ -280,7 +283,7 @@ bool prepare_tcp_segment(
|
|||||||
uint8_t scale_factor,
|
uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment,
|
uint32_t badseq_ack_increment,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -298,7 +301,7 @@ bool prepare_tcp_segment(
|
|||||||
bool prepare_udp_segment4(
|
bool prepare_udp_segment4(
|
||||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
const uint8_t *padding, size_t padding_size,
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int padlen,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -338,7 +341,7 @@ bool prepare_udp_segment4(
|
|||||||
bool prepare_udp_segment6(
|
bool prepare_udp_segment6(
|
||||||
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
|
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
const uint8_t *padding, size_t padding_size,
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int padlen,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -426,7 +429,7 @@ bool prepare_udp_segment6(
|
|||||||
bool prepare_udp_segment(
|
bool prepare_udp_segment(
|
||||||
const struct sockaddr *src, const struct sockaddr *dst,
|
const struct sockaddr *src, const struct sockaddr *dst,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
const uint8_t *padding, size_t padding_size,
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int padlen,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -674,11 +677,11 @@ static void str_ip(char *s, size_t s_len, const struct ip *ip)
|
|||||||
char ss[35],s_proto[16];
|
char ss[35],s_proto[16];
|
||||||
str_srcdst_ip(ss,sizeof(ss),&ip->ip_src,&ip->ip_dst);
|
str_srcdst_ip(ss,sizeof(ss),&ip->ip_src,&ip->ip_dst);
|
||||||
str_proto_name(s_proto,sizeof(s_proto),ip->ip_p);
|
str_proto_name(s_proto,sizeof(s_proto),ip->ip_p);
|
||||||
snprintf(s,s_len,"%s proto=%s",ss,s_proto);
|
snprintf(s,s_len,"%s proto=%s ttl=%u",ss,s_proto,ip->ip_ttl);
|
||||||
}
|
}
|
||||||
void print_ip(const struct ip *ip)
|
void print_ip(const struct ip *ip)
|
||||||
{
|
{
|
||||||
char s[64];
|
char s[66];
|
||||||
str_ip(s,sizeof(s),ip);
|
str_ip(s,sizeof(s),ip);
|
||||||
printf("%s",s);
|
printf("%s",s);
|
||||||
}
|
}
|
||||||
@ -695,7 +698,7 @@ static void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uint
|
|||||||
char ss[83],s_proto[16];
|
char ss[83],s_proto[16];
|
||||||
str_srcdst_ip6(ss,sizeof(ss),&ip6hdr->ip6_src,&ip6hdr->ip6_dst);
|
str_srcdst_ip6(ss,sizeof(ss),&ip6hdr->ip6_src,&ip6hdr->ip6_dst);
|
||||||
str_proto_name(s_proto,sizeof(s_proto),proto);
|
str_proto_name(s_proto,sizeof(s_proto),proto);
|
||||||
snprintf(s,s_len,"%s proto=%s",ss,s_proto);
|
snprintf(s,s_len,"%s proto=%s ttl=%u",ss,s_proto,ip6hdr->ip6_hlim);
|
||||||
}
|
}
|
||||||
void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto)
|
void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto)
|
||||||
{
|
{
|
||||||
@ -1170,3 +1173,35 @@ nofix:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return guessed fake ttl value. 0 means unsuccessfull, should not perform autottl fooling
|
||||||
|
// ttl = TTL of incoming packet
|
||||||
|
uint8_t autottl_guess(uint8_t ttl, const autottl *attl)
|
||||||
|
{
|
||||||
|
uint8_t orig, path, fake;
|
||||||
|
|
||||||
|
// 18.65.168.125 ( cloudfront ) 255
|
||||||
|
// 157.254.246.178 128
|
||||||
|
// 1.1.1.1 64
|
||||||
|
// guess original ttl. consider path lengths less than 32 hops
|
||||||
|
if (ttl>223)
|
||||||
|
orig=255;
|
||||||
|
else if (ttl<128 && ttl>96)
|
||||||
|
orig=128;
|
||||||
|
else if (ttl<64 && ttl>32)
|
||||||
|
orig=64;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
path = orig - ttl;
|
||||||
|
|
||||||
|
if (path <=attl->delta) return 0;
|
||||||
|
|
||||||
|
fake = path - attl->delta;
|
||||||
|
if (fake<attl->min) fake=attl->min;
|
||||||
|
else if (fake>attl->max) fake=attl->max;
|
||||||
|
|
||||||
|
if (fake>=path) return 0;
|
||||||
|
|
||||||
|
return fake;
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
|
|||||||
#define FOOL_HOPBYHOP2 0x20
|
#define FOOL_HOPBYHOP2 0x20
|
||||||
#define FOOL_DESTOPT 0x40
|
#define FOOL_DESTOPT 0x40
|
||||||
#define FOOL_IPFRAG1 0x80
|
#define FOOL_IPFRAG1 0x80
|
||||||
|
#define FOOL_DATANOACK 0x100
|
||||||
|
|
||||||
#define SCALE_NONE ((uint8_t)-1)
|
#define SCALE_NONE ((uint8_t)-1)
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ bool prepare_tcp_segment4(
|
|||||||
uint8_t scale_factor,
|
uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment,
|
uint32_t badseq_ack_increment,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -49,7 +50,7 @@ bool prepare_tcp_segment6(
|
|||||||
uint8_t scale_factor,
|
uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment,
|
uint32_t badseq_ack_increment,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -62,7 +63,7 @@ bool prepare_tcp_segment(
|
|||||||
uint8_t scale_factor,
|
uint8_t scale_factor,
|
||||||
uint32_t *timestamps,
|
uint32_t *timestamps,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
uint32_t badseq_increment,
|
uint32_t badseq_increment,
|
||||||
uint32_t badseq_ack_increment,
|
uint32_t badseq_ack_increment,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -72,7 +73,7 @@ bool prepare_tcp_segment(
|
|||||||
bool prepare_udp_segment4(
|
bool prepare_udp_segment4(
|
||||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
const uint8_t *padding, size_t padding_size,
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int padlen,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -80,7 +81,7 @@ bool prepare_udp_segment4(
|
|||||||
bool prepare_udp_segment6(
|
bool prepare_udp_segment6(
|
||||||
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
|
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
const uint8_t *padding, size_t padding_size,
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int padlen,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -88,7 +89,7 @@ bool prepare_udp_segment6(
|
|||||||
bool prepare_udp_segment(
|
bool prepare_udp_segment(
|
||||||
const struct sockaddr *src, const struct sockaddr *dst,
|
const struct sockaddr *src, const struct sockaddr *dst,
|
||||||
uint8_t ttl,
|
uint8_t ttl,
|
||||||
uint8_t fooling,
|
uint32_t fooling,
|
||||||
const uint8_t *padding, size_t padding_size,
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int padlen,
|
||||||
const void *data, uint16_t len,
|
const void *data, uint16_t len,
|
||||||
@ -149,3 +150,15 @@ bool tcp_ack_segment(const struct tcphdr *tcphdr);
|
|||||||
// scale_factor=SCALE_NONE - do not change
|
// scale_factor=SCALE_NONE - do not change
|
||||||
void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor);
|
void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor);
|
||||||
void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_factor);
|
void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_factor);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t delta, min, max;
|
||||||
|
} autottl;
|
||||||
|
#define AUTOTTL_DEFAULT_DELTA 1
|
||||||
|
#define AUTOTTL_DEFAULT_MIN 3
|
||||||
|
#define AUTOTTL_DEFAULT_MAX 20
|
||||||
|
#define AUTOTTL_ENABLED(a) (!!(a).delta)
|
||||||
|
#define AUTOTTL_SET_DEFAULT(a) {(a).delta=AUTOTTL_DEFAULT_DELTA; (a).min=AUTOTTL_DEFAULT_MIN; (a).max=AUTOTTL_DEFAULT_MAX;}
|
||||||
|
|
||||||
|
uint8_t autottl_guess(uint8_t ttl, const autottl *attl);
|
||||||
|
22
nfq/desync.c
22
nfq/desync.c
@ -333,6 +333,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
uint32_t *timestamps;
|
uint32_t *timestamps;
|
||||||
|
|
||||||
if (!!ip == !!ip6hdr) return res; // one and only one must be present
|
if (!!ip == !!ip6hdr) return res; // one and only one must be present
|
||||||
|
ttl_orig = ip ? ip->ip_ttl : ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
|
|
||||||
ConntrackPoolPurge(¶ms.conntrack);
|
ConntrackPoolPurge(¶ms.conntrack);
|
||||||
if (ConntrackPoolFeed(¶ms.conntrack, ip, ip6hdr, tcphdr, NULL, len_payload, &ctrack, &bReverse))
|
if (ConntrackPoolFeed(¶ms.conntrack, ip, ip6hdr, tcphdr, NULL, len_payload, &ctrack, &bReverse))
|
||||||
@ -349,6 +350,19 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
|
|
||||||
if (bReverse)
|
if (bReverse)
|
||||||
{
|
{
|
||||||
|
if (ctrack && !ctrack->autottl && ctrack->pcounter_reply==1)
|
||||||
|
{
|
||||||
|
autottl *attl = ip ? ¶ms.desync_autottl : ¶ms.desync_autottl6;
|
||||||
|
if (AUTOTTL_ENABLED(*attl))
|
||||||
|
{
|
||||||
|
ctrack->autottl = autottl_guess(ttl_orig, attl);
|
||||||
|
if (ctrack->autottl)
|
||||||
|
DLOG("autottl: guessed %u\n",ctrack->autottl)
|
||||||
|
else
|
||||||
|
DLOG("autottl: could not guess\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// process reply packets for auto hostlist mode
|
// process reply packets for auto hostlist mode
|
||||||
// by looking at RSTs or HTTP replies we decide whether original request looks like DPI blocked
|
// by looking at RSTs or HTTP replies we decide whether original request looks like DPI blocked
|
||||||
// we only process first-sequence replies. do not react to subsequent redirects or RSTs
|
// we only process first-sequence replies. do not react to subsequent redirects or RSTs
|
||||||
@ -415,9 +429,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
|
|
||||||
if (params.desync_mode0!=DESYNC_NONE || params.desync_mode!=DESYNC_NONE) // save some cpu
|
if (params.desync_mode0!=DESYNC_NONE || params.desync_mode!=DESYNC_NONE) // save some cpu
|
||||||
{
|
{
|
||||||
ttl_orig = ip ? ip->ip_ttl : ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_fake = (ctrack && ctrack->autottl) ? ctrack->autottl : (ip6hdr ? (params.desync_ttl6 ? params.desync_ttl6 : ttl_orig) : (params.desync_ttl ? params.desync_ttl : ttl_orig));
|
||||||
if (ip6hdr) ttl_fake = params.desync_ttl6 ? params.desync_ttl6 : ttl_orig;
|
|
||||||
else ttl_fake = params.desync_ttl ? params.desync_ttl : ttl_orig;
|
|
||||||
flags_orig = *((uint8_t*)tcphdr+13);
|
flags_orig = *((uint8_t*)tcphdr+13);
|
||||||
scale_factor = tcp_find_scale_factor(tcphdr);
|
scale_factor = tcp_find_scale_factor(tcphdr);
|
||||||
timestamps = tcp_find_timestamps(tcphdr);
|
timestamps = tcp_find_timestamps(tcphdr);
|
||||||
@ -628,7 +640,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum dpi_desync_mode desync_mode = params.desync_mode;
|
enum dpi_desync_mode desync_mode = params.desync_mode;
|
||||||
uint8_t fooling_orig = FOOL_NONE;
|
uint32_t fooling_orig = FOOL_NONE;
|
||||||
bool b;
|
bool b;
|
||||||
|
|
||||||
pkt1_len = sizeof(pkt1);
|
pkt1_len = sizeof(pkt1);
|
||||||
@ -1026,7 +1038,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum dpi_desync_mode desync_mode = params.desync_mode;
|
enum dpi_desync_mode desync_mode = params.desync_mode;
|
||||||
uint8_t fooling_orig = FOOL_NONE;
|
uint32_t fooling_orig = FOOL_NONE;
|
||||||
|
|
||||||
ttl_orig = ip ? ip->ip_ttl : ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_orig = ip ? ip->ip_ttl : ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
if (ip6hdr) ttl_fake = params.desync_ttl6 ? params.desync_ttl6 : ttl_orig;
|
if (ip6hdr) ttl_fake = params.desync_ttl6 ? params.desync_ttl6 : ttl_orig;
|
||||||
|
172
nfq/nfqws.c
172
nfq/nfqws.c
@ -540,7 +540,9 @@ static void exithelp(void)
|
|||||||
#endif
|
#endif
|
||||||
" --dpi-desync-ttl=<int>\t\t\t\t; set ttl for desync packet\n"
|
" --dpi-desync-ttl=<int>\t\t\t\t; set ttl for desync packet\n"
|
||||||
" --dpi-desync-ttl6=<int>\t\t\t; set ipv6 hop limit for desync packet. by default ttl value is used.\n"
|
" --dpi-desync-ttl6=<int>\t\t\t; set ipv6 hop limit for desync packet. by default ttl value is used.\n"
|
||||||
" --dpi-desync-fooling=<mode>[,<mode>]\t\t; can use multiple comma separated values. modes : none md5sig ts badseq badsum hopbyhop hopbyhop2\n"
|
" --dpi-desync-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: %u:%u-%u\n"
|
||||||
|
" --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for ipv6 only\n"
|
||||||
|
" --dpi-desync-fooling=<mode>[,<mode>]\t\t; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2\n"
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
" --dpi-desync-retrans=0|1\t\t\t; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission\n"
|
" --dpi-desync-retrans=0|1\t\t\t; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission\n"
|
||||||
#endif
|
#endif
|
||||||
@ -573,6 +575,7 @@ static void exithelp(void)
|
|||||||
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
||||||
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
||||||
#endif
|
#endif
|
||||||
|
AUTOTTL_DEFAULT_DELTA,AUTOTTL_DEFAULT_MIN,AUTOTTL_DEFAULT_MAX,
|
||||||
DPI_DESYNC_MAX_FAKE_LEN,
|
DPI_DESYNC_MAX_FAKE_LEN,
|
||||||
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_UDP_DEFAULT,
|
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_UDP_DEFAULT,
|
||||||
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_TCP_DEFAULT,
|
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_TCP_DEFAULT,
|
||||||
@ -643,6 +646,31 @@ static void load_file_or_exit(const char *filename, void *buf, size_t *size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parse_autottl(const char *s, autottl *t)
|
||||||
|
{
|
||||||
|
unsigned int delta,min,max;
|
||||||
|
AUTOTTL_SET_DEFAULT(*t);
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
max = t->max;
|
||||||
|
switch (sscanf(s,"%u:%u-%u",&delta,&min,&max))
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
if (delta && !max || max>255) return false;
|
||||||
|
t->max=(uint8_t)max;
|
||||||
|
case 2:
|
||||||
|
if (delta && !min || min>255 || min>max) return false;
|
||||||
|
t->min=(uint8_t)min;
|
||||||
|
case 1:
|
||||||
|
if (delta>255) return false;
|
||||||
|
t->delta=(uint8_t)delta;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -727,37 +755,39 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
{"dpi-desync-ttl",required_argument,0,0}, // optidx=16
|
{"dpi-desync-ttl",required_argument,0,0}, // optidx=16
|
||||||
{"dpi-desync-ttl6",required_argument,0,0}, // optidx=17
|
{"dpi-desync-ttl6",required_argument,0,0}, // optidx=17
|
||||||
{"dpi-desync-fooling",required_argument,0,0}, // optidx=18
|
{"dpi-desync-autottl",optional_argument,0,0}, // optidx=18
|
||||||
{"dpi-desync-retrans",optional_argument,0,0}, // optidx=19
|
{"dpi-desync-autottl6",optional_argument,0,0}, // optidx=19
|
||||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=20
|
{"dpi-desync-fooling",required_argument,0,0}, // optidx=20
|
||||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=21
|
{"dpi-desync-retrans",optional_argument,0,0}, // optidx=21
|
||||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=22
|
{"dpi-desync-repeats",required_argument,0,0}, // optidx=22
|
||||||
{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=23
|
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=23
|
||||||
{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=24
|
{"dpi-desync-split-pos",required_argument,0,0},// optidx=24
|
||||||
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=25
|
{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=25
|
||||||
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=26
|
{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=26
|
||||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=27
|
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=27
|
||||||
{"dpi-desync-fake-http",required_argument,0,0},// optidx=28
|
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=28
|
||||||
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=29
|
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=29
|
||||||
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=30
|
{"dpi-desync-fake-http",required_argument,0,0},// optidx=30
|
||||||
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=31
|
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=31
|
||||||
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=32
|
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=32
|
||||||
{"dpi-desync-fake-dht",required_argument,0,0},// optidx=33
|
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=33
|
||||||
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=34
|
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=34
|
||||||
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=35
|
{"dpi-desync-fake-dht",required_argument,0,0},// optidx=35
|
||||||
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=36
|
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=36
|
||||||
{"dpi-desync-cutoff",required_argument,0,0},// optidx=37
|
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=37
|
||||||
{"hostlist",required_argument,0,0}, // optidx=38
|
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=38
|
||||||
{"hostlist-exclude",required_argument,0,0}, // optidx=39
|
{"dpi-desync-cutoff",required_argument,0,0},// optidx=39
|
||||||
{"hostlist-auto",required_argument,0,0}, // optidx=40
|
{"hostlist",required_argument,0,0}, // optidx=40
|
||||||
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=41
|
{"hostlist-exclude",required_argument,0,0}, // optidx=41
|
||||||
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=42
|
{"hostlist-auto",required_argument,0,0}, // optidx=42
|
||||||
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=43
|
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=43
|
||||||
{"hostlist-auto-debug",required_argument,0,0}, // optidx=44
|
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=44
|
||||||
|
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=45
|
||||||
|
{"hostlist-auto-debug",required_argument,0,0}, // optidx=46
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
{"bind-fix4",no_argument,0,0}, // optidx=45
|
{"bind-fix4",no_argument,0,0}, // optidx=47
|
||||||
{"bind-fix6",no_argument,0,0}, // optidx=46
|
{"bind-fix6",no_argument,0,0}, // optidx=48
|
||||||
#endif
|
#endif
|
||||||
{NULL,0,NULL,0}
|
{NULL,0,NULL,0}
|
||||||
};
|
};
|
||||||
@ -924,7 +954,21 @@ int main(int argc, char **argv)
|
|||||||
case 17: /* dpi-desync-ttl6 */
|
case 17: /* dpi-desync-ttl6 */
|
||||||
params.desync_ttl6 = (uint8_t)atoi(optarg);
|
params.desync_ttl6 = (uint8_t)atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 18: /* dpi-desync-fooling */
|
case 18: /* dpi-desync-autottl */
|
||||||
|
if (!parse_autottl(optarg, ¶ms.desync_autottl))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "dpi-desync-autottl value error\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 19: /* dpi-desync-autottl6 */
|
||||||
|
if (!parse_autottl(optarg, ¶ms.desync_autottl6))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "dpi-desync-autottl6 value error\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 20: /* dpi-desync-fooling */
|
||||||
{
|
{
|
||||||
char *e,*p = optarg;
|
char *e,*p = optarg;
|
||||||
while (p)
|
while (p)
|
||||||
@ -944,20 +988,22 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if (!strcmp(p,"badseq"))
|
else if (!strcmp(p,"badseq"))
|
||||||
params.desync_fooling_mode |= FOOL_BADSEQ;
|
params.desync_fooling_mode |= FOOL_BADSEQ;
|
||||||
|
else if (!strcmp(p,"datanoack"))
|
||||||
|
params.desync_fooling_mode |= FOOL_DATANOACK;
|
||||||
else if (!strcmp(p,"hopbyhop"))
|
else if (!strcmp(p,"hopbyhop"))
|
||||||
params.desync_fooling_mode |= FOOL_HOPBYHOP;
|
params.desync_fooling_mode |= FOOL_HOPBYHOP;
|
||||||
else if (!strcmp(p,"hopbyhop2"))
|
else if (!strcmp(p,"hopbyhop2"))
|
||||||
params.desync_fooling_mode |= FOOL_HOPBYHOP2;
|
params.desync_fooling_mode |= FOOL_HOPBYHOP2;
|
||||||
else if (strcmp(p,"none"))
|
else if (strcmp(p,"none"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum,hopbyhop,hopbyhop2\n");
|
fprintf(stderr, "dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum,datanoack,hopbyhop,hopbyhop2\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
p = e;
|
p = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 19: /* dpi-desync-retrans */
|
case 21: /* dpi-desync-retrans */
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
params.desync_retrans = !optarg || atoi(optarg);
|
params.desync_retrans = !optarg || atoi(optarg);
|
||||||
#else
|
#else
|
||||||
@ -965,24 +1011,24 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 20: /* dpi-desync-repeats */
|
case 22: /* dpi-desync-repeats */
|
||||||
if (sscanf(optarg,"%u",¶ms.desync_repeats)<1 || !params.desync_repeats || params.desync_repeats>20)
|
if (sscanf(optarg,"%u",¶ms.desync_repeats)<1 || !params.desync_repeats || params.desync_repeats>20)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-repeats must be within 1..20\n");
|
fprintf(stderr, "dpi-desync-repeats must be within 1..20\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 21: /* dpi-desync-skip-nosni */
|
case 23: /* dpi-desync-skip-nosni */
|
||||||
params.desync_skip_nosni = !optarg || atoi(optarg);
|
params.desync_skip_nosni = !optarg || atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 22: /* dpi-desync-split-pos */
|
case 24: /* dpi-desync-split-pos */
|
||||||
if (sscanf(optarg,"%u",¶ms.desync_split_pos)<1 || params.desync_split_pos<1 || params.desync_split_pos>DPI_DESYNC_MAX_FAKE_LEN)
|
if (sscanf(optarg,"%u",¶ms.desync_split_pos)<1 || params.desync_split_pos<1 || params.desync_split_pos>DPI_DESYNC_MAX_FAKE_LEN)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-split-pos must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
fprintf(stderr, "dpi-desync-split-pos must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 23: /* dpi-desync-ipfrag-pos-tcp */
|
case 25: /* dpi-desync-ipfrag-pos-tcp */
|
||||||
if (sscanf(optarg,"%u",¶ms.desync_ipfrag_pos_tcp)<1 || params.desync_ipfrag_pos_tcp<1 || params.desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN)
|
if (sscanf(optarg,"%u",¶ms.desync_ipfrag_pos_tcp)<1 || params.desync_ipfrag_pos_tcp<1 || params.desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-ipfrag-pos-tcp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
fprintf(stderr, "dpi-desync-ipfrag-pos-tcp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
||||||
@ -994,7 +1040,7 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 24: /* dpi-desync-ipfrag-pos-udp */
|
case 26: /* dpi-desync-ipfrag-pos-udp */
|
||||||
if (sscanf(optarg,"%u",¶ms.desync_ipfrag_pos_udp)<1 || params.desync_ipfrag_pos_udp<1 || params.desync_ipfrag_pos_udp>DPI_DESYNC_MAX_FAKE_LEN)
|
if (sscanf(optarg,"%u",¶ms.desync_ipfrag_pos_udp)<1 || params.desync_ipfrag_pos_udp<1 || params.desync_ipfrag_pos_udp>DPI_DESYNC_MAX_FAKE_LEN)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-ipfrag-pos-udp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
fprintf(stderr, "dpi-desync-ipfrag-pos-udp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
||||||
@ -1006,59 +1052,59 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 25: /* dpi-desync-badseq-increments */
|
case 27: /* dpi-desync-badseq-increments */
|
||||||
if (!parse_badseq_increment(optarg,¶ms.desync_badseq_increment))
|
if (!parse_badseq_increment(optarg,¶ms.desync_badseq_increment))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
|
fprintf(stderr, "dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 26: /* dpi-desync-badack-increment */
|
case 28: /* dpi-desync-badack-increment */
|
||||||
if (!parse_badseq_increment(optarg,¶ms.desync_badseq_ack_increment))
|
if (!parse_badseq_increment(optarg,¶ms.desync_badseq_ack_increment))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
|
fprintf(stderr, "dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 27: /* dpi-desync-any-protocol */
|
case 29: /* dpi-desync-any-protocol */
|
||||||
params.desync_any_proto = !optarg || atoi(optarg);
|
params.desync_any_proto = !optarg || atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 28: /* dpi-desync-fake-http */
|
case 30: /* dpi-desync-fake-http */
|
||||||
params.fake_http_size = sizeof(params.fake_http);
|
params.fake_http_size = sizeof(params.fake_http);
|
||||||
load_file_or_exit(optarg,params.fake_http,¶ms.fake_http_size);
|
load_file_or_exit(optarg,params.fake_http,¶ms.fake_http_size);
|
||||||
break;
|
break;
|
||||||
case 29: /* dpi-desync-fake-tls */
|
case 31: /* dpi-desync-fake-tls */
|
||||||
params.fake_tls_size = sizeof(params.fake_tls);
|
params.fake_tls_size = sizeof(params.fake_tls);
|
||||||
load_file_or_exit(optarg,params.fake_tls,¶ms.fake_tls_size);
|
load_file_or_exit(optarg,params.fake_tls,¶ms.fake_tls_size);
|
||||||
break;
|
break;
|
||||||
case 30: /* dpi-desync-fake-unknown */
|
case 32: /* dpi-desync-fake-unknown */
|
||||||
params.fake_unknown_size = sizeof(params.fake_unknown);
|
params.fake_unknown_size = sizeof(params.fake_unknown);
|
||||||
load_file_or_exit(optarg,params.fake_unknown,¶ms.fake_unknown_size);
|
load_file_or_exit(optarg,params.fake_unknown,¶ms.fake_unknown_size);
|
||||||
break;
|
break;
|
||||||
case 31: /* dpi-desync-fake-quic */
|
case 33: /* dpi-desync-fake-quic */
|
||||||
params.fake_quic_size = sizeof(params.fake_quic);
|
params.fake_quic_size = sizeof(params.fake_quic);
|
||||||
load_file_or_exit(optarg,params.fake_quic,¶ms.fake_quic_size);
|
load_file_or_exit(optarg,params.fake_quic,¶ms.fake_quic_size);
|
||||||
break;
|
break;
|
||||||
case 32: /* dpi-desync-fake-wireguard */
|
case 34: /* dpi-desync-fake-wireguard */
|
||||||
params.fake_wg_size = sizeof(params.fake_wg);
|
params.fake_wg_size = sizeof(params.fake_wg);
|
||||||
load_file_or_exit(optarg,params.fake_wg,¶ms.fake_wg_size);
|
load_file_or_exit(optarg,params.fake_wg,¶ms.fake_wg_size);
|
||||||
break;
|
break;
|
||||||
case 33: /* dpi-desync-fake-dht */
|
case 35: /* dpi-desync-fake-dht */
|
||||||
params.fake_dht_size = sizeof(params.fake_dht);
|
params.fake_dht_size = sizeof(params.fake_dht);
|
||||||
load_file_or_exit(optarg,params.fake_dht,¶ms.fake_dht_size);
|
load_file_or_exit(optarg,params.fake_dht,¶ms.fake_dht_size);
|
||||||
break;
|
break;
|
||||||
case 34: /* dpi-desync-fake-unknown-udp */
|
case 36: /* dpi-desync-fake-unknown-udp */
|
||||||
params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp);
|
params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp);
|
||||||
load_file_or_exit(optarg,params.fake_unknown_udp,¶ms.fake_unknown_udp_size);
|
load_file_or_exit(optarg,params.fake_unknown_udp,¶ms.fake_unknown_udp_size);
|
||||||
break;
|
break;
|
||||||
case 35: /* dpi-desync-udplen-increment */
|
case 37: /* dpi-desync-udplen-increment */
|
||||||
if (sscanf(optarg,"%d",¶ms.udplen_increment)<1 || params.udplen_increment>0x7FFF || params.udplen_increment<-0x8000)
|
if (sscanf(optarg,"%d",¶ms.udplen_increment)<1 || params.udplen_increment>0x7FFF || params.udplen_increment<-0x8000)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-udplen-increment must be integer within -32768..32767 range\n");
|
fprintf(stderr, "dpi-desync-udplen-increment must be integer within -32768..32767 range\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 36: /* dpi-desync-udplen-pattern */
|
case 38: /* dpi-desync-udplen-pattern */
|
||||||
{
|
{
|
||||||
char buf[sizeof(params.udplen_pattern)];
|
char buf[sizeof(params.udplen_pattern)];
|
||||||
size_t sz=sizeof(buf);
|
size_t sz=sizeof(buf);
|
||||||
@ -1066,28 +1112,28 @@ int main(int argc, char **argv)
|
|||||||
fill_pattern(params.udplen_pattern,sizeof(params.udplen_pattern),buf,sz);
|
fill_pattern(params.udplen_pattern,sizeof(params.udplen_pattern),buf,sz);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 37: /* desync-cutoff */
|
case 39: /* desync-cutoff */
|
||||||
if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode))
|
if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "invalid desync-cutoff value\n");
|
fprintf(stderr, "invalid desync-cutoff value\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 38: /* hostlist */
|
case 40: /* hostlist */
|
||||||
if (!strlist_add(¶ms.hostlist_files, optarg))
|
if (!strlist_add(¶ms.hostlist_files, optarg))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "strlist_add failed\n");
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 39: /* hostlist-exclude */
|
case 41: /* hostlist-exclude */
|
||||||
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "strlist_add failed\n");
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 40: /* hostlist-auto */
|
case 42: /* hostlist-auto */
|
||||||
if (*params.hostlist_auto_filename)
|
if (*params.hostlist_auto_filename)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "only one auto hostlist is supported\n");
|
fprintf(stderr, "only one auto hostlist is supported\n");
|
||||||
@ -1118,7 +1164,7 @@ int main(int argc, char **argv)
|
|||||||
strncpy(params.hostlist_auto_filename, optarg, sizeof(params.hostlist_auto_filename));
|
strncpy(params.hostlist_auto_filename, optarg, sizeof(params.hostlist_auto_filename));
|
||||||
params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0';
|
params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0';
|
||||||
break;
|
break;
|
||||||
case 41: /* hostlist-auto-fail-threshold */
|
case 43: /* hostlist-auto-fail-threshold */
|
||||||
params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
|
params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
|
||||||
if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20)
|
if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20)
|
||||||
{
|
{
|
||||||
@ -1126,7 +1172,7 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 42: /* hostlist-auto-fail-time */
|
case 44: /* hostlist-auto-fail-time */
|
||||||
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
|
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
|
||||||
if (params.hostlist_auto_fail_time<1)
|
if (params.hostlist_auto_fail_time<1)
|
||||||
{
|
{
|
||||||
@ -1134,7 +1180,7 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 43: /* hostlist-auto-retrans-threshold */
|
case 45: /* hostlist-auto-retrans-threshold */
|
||||||
params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg);
|
params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg);
|
||||||
if (params.hostlist_auto_retrans_threshold<2 || params.hostlist_auto_retrans_threshold>10)
|
if (params.hostlist_auto_retrans_threshold<2 || params.hostlist_auto_retrans_threshold>10)
|
||||||
{
|
{
|
||||||
@ -1142,7 +1188,7 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 44: /* hostlist-auto-debug */
|
case 46: /* hostlist-auto-debug */
|
||||||
{
|
{
|
||||||
FILE *F = fopen(optarg,"a+t");
|
FILE *F = fopen(optarg,"a+t");
|
||||||
if (!F)
|
if (!F)
|
||||||
@ -1158,10 +1204,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
case 45: /* bind-fix4 */
|
case 47: /* bind-fix4 */
|
||||||
params.bind_fix4 = true;
|
params.bind_fix4 = true;
|
||||||
break;
|
break;
|
||||||
case 46: /* bind-fix6 */
|
case 48: /* bind-fix6 */
|
||||||
params.bind_fix6 = true;
|
params.bind_fix6 = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -1169,6 +1215,12 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
// not specified - use desync_ttl value instead
|
// not specified - use desync_ttl value instead
|
||||||
if (params.desync_ttl6 == 0xFF) params.desync_ttl6=params.desync_ttl;
|
if (params.desync_ttl6 == 0xFF) params.desync_ttl6=params.desync_ttl;
|
||||||
|
if (!AUTOTTL_ENABLED(params.desync_autottl6)) params.desync_autottl6 = params.desync_autottl;
|
||||||
|
if (AUTOTTL_ENABLED(params.desync_autottl))
|
||||||
|
DLOG("autottl ipv4 %u:%u-%u\n",params.desync_autottl.delta,params.desync_autottl.min,params.desync_autottl.max)
|
||||||
|
if (AUTOTTL_ENABLED(params.desync_autottl6))
|
||||||
|
DLOG("autottl ipv6 %u:%u-%u\n",params.desync_autottl6.delta,params.desync_autottl6.min,params.desync_autottl6.max)
|
||||||
|
|
||||||
#ifdef BSD
|
#ifdef BSD
|
||||||
if (!params.port)
|
if (!params.port)
|
||||||
{
|
{
|
||||||
|
@ -27,11 +27,10 @@
|
|||||||
|
|
||||||
#define UDPLEN_INCREMENT_DEFAULT 2
|
#define UDPLEN_INCREMENT_DEFAULT 2
|
||||||
|
|
||||||
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 2
|
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
|
||||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||||
#define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3
|
#define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3
|
||||||
|
|
||||||
|
|
||||||
struct params_s
|
struct params_s
|
||||||
{
|
{
|
||||||
bool debug;
|
bool debug;
|
||||||
@ -53,7 +52,8 @@ struct params_s
|
|||||||
char desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
char desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||||
unsigned int desync_cutoff;
|
unsigned int desync_cutoff;
|
||||||
uint8_t desync_ttl, desync_ttl6;
|
uint8_t desync_ttl, desync_ttl6;
|
||||||
uint8_t desync_fooling_mode;
|
autottl desync_autottl, desync_autottl6;
|
||||||
|
uint32_t desync_fooling_mode;
|
||||||
uint32_t desync_fwmark; // unused in BSD
|
uint32_t desync_fwmark; // unused in BSD
|
||||||
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
||||||
uint8_t fake_http[1432],fake_tls[1432],fake_quic[1472],fake_wg[1472],fake_dht[1472],fake_unknown[1432],fake_unknown_udp[1472], udplen_pattern[1472];
|
uint8_t fake_http[1432],fake_tls[1432],fake_quic[1472],fake_wg[1472],fake_dht[1472],fake_unknown[1432],fake_unknown_udp[1472], udplen_pattern[1472];
|
||||||
|
@ -49,7 +49,7 @@ struct params_s
|
|||||||
int tlsrec_pos;
|
int tlsrec_pos;
|
||||||
bool split_any_protocol;
|
bool split_any_protocol;
|
||||||
int split_pos;
|
int split_pos;
|
||||||
bool disorder;
|
bool disorder, oob;
|
||||||
int ttl_default;
|
int ttl_default;
|
||||||
|
|
||||||
char pidfile[256];
|
char pidfile[256];
|
||||||
|
93
tpws/tpws.c
93
tpws/tpws.c
@ -176,6 +176,7 @@ static void exithelp(void)
|
|||||||
#else
|
#else
|
||||||
" --disorder\t\t\t\t; when splitting simulate sending second fragment first\n"
|
" --disorder\t\t\t\t; when splitting simulate sending second fragment first\n"
|
||||||
#endif
|
#endif
|
||||||
|
" --oob\t\t\t\t\t; when splitting send out of band zero byte\n"
|
||||||
" --hostcase\t\t\t\t; change Host: => host:\n"
|
" --hostcase\t\t\t\t; change Host: => host:\n"
|
||||||
" --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n"
|
" --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n"
|
||||||
" --hostdot\t\t\t\t; add \".\" after Host: name\n"
|
" --hostdot\t\t\t\t; add \".\" after Host: name\n"
|
||||||
@ -294,29 +295,30 @@ void parse_params(int argc, char *argv[])
|
|||||||
{ "split-pos",required_argument,0,0 },// optidx=24
|
{ "split-pos",required_argument,0,0 },// optidx=24
|
||||||
{ "split-any-protocol",optional_argument,0,0},// optidx=25
|
{ "split-any-protocol",optional_argument,0,0},// optidx=25
|
||||||
{ "disorder",no_argument,0,0 },// optidx=26
|
{ "disorder",no_argument,0,0 },// optidx=26
|
||||||
{ "methodspace",no_argument,0,0 },// optidx=27
|
{ "oob",no_argument,0,0 },// optidx=27
|
||||||
{ "methodeol",no_argument,0,0 },// optidx=28
|
{ "methodspace",no_argument,0,0 },// optidx=28
|
||||||
{ "hosttab",no_argument,0,0 },// optidx=29
|
{ "methodeol",no_argument,0,0 },// optidx=29
|
||||||
{ "unixeol",no_argument,0,0 },// optidx=30
|
{ "hosttab",no_argument,0,0 },// optidx=30
|
||||||
{ "tlsrec",required_argument,0,0 },// optidx=31
|
{ "unixeol",no_argument,0,0 },// optidx=31
|
||||||
{ "tlsrec-pos",required_argument,0,0 },// optidx=32
|
{ "tlsrec",required_argument,0,0 },// optidx=32
|
||||||
{ "hostlist",required_argument,0,0 },// optidx=33
|
{ "tlsrec-pos",required_argument,0,0 },// optidx=33
|
||||||
{ "hostlist-exclude",required_argument,0,0 },// optidx=34
|
{ "hostlist",required_argument,0,0 },// optidx=34
|
||||||
{ "hostlist-auto",required_argument,0,0}, // optidx=35
|
{ "hostlist-exclude",required_argument,0,0 },// optidx=35
|
||||||
{ "hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=36
|
{ "hostlist-auto",required_argument,0,0}, // optidx=36
|
||||||
{ "hostlist-auto-fail-time",required_argument,0,0}, // optidx=37
|
{ "hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=37
|
||||||
{ "hostlist-auto-debug",required_argument,0,0}, // optidx=38
|
{ "hostlist-auto-fail-time",required_argument,0,0}, // optidx=38
|
||||||
{ "pidfile",required_argument,0,0 },// optidx=39
|
{ "hostlist-auto-debug",required_argument,0,0}, // optidx=39
|
||||||
{ "debug",optional_argument,0,0 },// optidx=40
|
{ "pidfile",required_argument,0,0 },// optidx=40
|
||||||
{ "local-rcvbuf",required_argument,0,0 },// optidx=41
|
{ "debug",optional_argument,0,0 },// optidx=41
|
||||||
{ "local-sndbuf",required_argument,0,0 },// optidx=42
|
{ "local-rcvbuf",required_argument,0,0 },// optidx=42
|
||||||
{ "remote-rcvbuf",required_argument,0,0 },// optidx=43
|
{ "local-sndbuf",required_argument,0,0 },// optidx=43
|
||||||
{ "remote-sndbuf",required_argument,0,0 },// optidx=44
|
{ "remote-rcvbuf",required_argument,0,0 },// optidx=44
|
||||||
{ "socks",no_argument,0,0 },// optidx=45
|
{ "remote-sndbuf",required_argument,0,0 },// optidx=45
|
||||||
{ "no-resolve",no_argument,0,0 },// optidx=46
|
{ "socks",no_argument,0,0 },// optidx=46
|
||||||
{ "skip-nodelay",no_argument,0,0 },// optidx=47
|
{ "no-resolve",no_argument,0,0 },// optidx=47
|
||||||
|
{ "skip-nodelay",no_argument,0,0 },// optidx=48
|
||||||
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
|
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
|
||||||
{ "enable-pf",no_argument,0,0 },// optidx=48
|
{ "enable-pf",no_argument,0,0 },// optidx=49
|
||||||
#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
|
||||||
{ NULL,0,NULL,0 }
|
{ NULL,0,NULL,0 }
|
||||||
@ -505,23 +507,26 @@ void parse_params(int argc, char *argv[])
|
|||||||
params.disorder = true;
|
params.disorder = true;
|
||||||
save_default_ttl();
|
save_default_ttl();
|
||||||
break;
|
break;
|
||||||
case 27: /* methodspace */
|
case 27: /* oob */
|
||||||
|
params.oob = true;
|
||||||
|
break;
|
||||||
|
case 28: /* methodspace */
|
||||||
params.methodspace = true;
|
params.methodspace = true;
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 28: /* methodeol */
|
case 29: /* methodeol */
|
||||||
params.methodeol = true;
|
params.methodeol = true;
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 29: /* hosttab */
|
case 30: /* hosttab */
|
||||||
params.hosttab = true;
|
params.hosttab = true;
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 30: /* unixeol */
|
case 31: /* unixeol */
|
||||||
params.unixeol = true;
|
params.unixeol = true;
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 31: /* tlsrec */
|
case 32: /* tlsrec */
|
||||||
if (!strcmp(optarg, "sni"))
|
if (!strcmp(optarg, "sni"))
|
||||||
params.tlsrec = tlsrec_sni;
|
params.tlsrec = tlsrec_sni;
|
||||||
else
|
else
|
||||||
@ -531,7 +536,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 32: /* tlsrec-pos */
|
case 33: /* tlsrec-pos */
|
||||||
if ((params.tlsrec_pos = atoi(optarg))>0)
|
if ((params.tlsrec_pos = atoi(optarg))>0)
|
||||||
params.tlsrec = tlsrec_pos;
|
params.tlsrec = tlsrec_pos;
|
||||||
else
|
else
|
||||||
@ -541,7 +546,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 33: /* hostlist */
|
case 34: /* hostlist */
|
||||||
if (!strlist_add(¶ms.hostlist_files, optarg))
|
if (!strlist_add(¶ms.hostlist_files, optarg))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "strlist_add failed\n");
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
@ -549,7 +554,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 34: /* hostlist-exclude */
|
case 35: /* hostlist-exclude */
|
||||||
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "strlist_add failed\n");
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
@ -557,7 +562,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
break;
|
break;
|
||||||
case 35: /* hostlist-auto */
|
case 36: /* hostlist-auto */
|
||||||
if (*params.hostlist_auto_filename)
|
if (*params.hostlist_auto_filename)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "only one auto hostlist is supported\n");
|
fprintf(stderr, "only one auto hostlist is supported\n");
|
||||||
@ -589,7 +594,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0';
|
params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0';
|
||||||
params.tamper = true; // need to detect blocks and update autohostlist. cannot just slice.
|
params.tamper = true; // need to detect blocks and update autohostlist. cannot just slice.
|
||||||
break;
|
break;
|
||||||
case 36: /* hostlist-auto-fail-threshold */
|
case 37: /* hostlist-auto-fail-threshold */
|
||||||
params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
|
params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
|
||||||
if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20)
|
if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20)
|
||||||
{
|
{
|
||||||
@ -597,7 +602,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 37: /* hostlist-auto-fail-time */
|
case 38: /* hostlist-auto-fail-time */
|
||||||
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
|
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
|
||||||
if (params.hostlist_auto_fail_time<1)
|
if (params.hostlist_auto_fail_time<1)
|
||||||
{
|
{
|
||||||
@ -605,7 +610,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 38: /* hostlist-auto-debug */
|
case 39: /* hostlist-auto-debug */
|
||||||
{
|
{
|
||||||
FILE *F = fopen(optarg,"a+t");
|
FILE *F = fopen(optarg,"a+t");
|
||||||
if (!F)
|
if (!F)
|
||||||
@ -620,36 +625,36 @@ void parse_params(int argc, char *argv[])
|
|||||||
params.hostlist_auto_debuglog[sizeof(params.hostlist_auto_debuglog) - 1] = '\0';
|
params.hostlist_auto_debuglog[sizeof(params.hostlist_auto_debuglog) - 1] = '\0';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 39: /* pidfile */
|
case 40: /* pidfile */
|
||||||
strncpy(params.pidfile,optarg,sizeof(params.pidfile));
|
strncpy(params.pidfile,optarg,sizeof(params.pidfile));
|
||||||
params.pidfile[sizeof(params.pidfile)-1]='\0';
|
params.pidfile[sizeof(params.pidfile)-1]='\0';
|
||||||
break;
|
break;
|
||||||
case 40:
|
case 41:
|
||||||
params.debug = optarg ? atoi(optarg) : 1;
|
params.debug = optarg ? atoi(optarg) : 1;
|
||||||
break;
|
break;
|
||||||
case 41: /* local-rcvbuf */
|
case 42: /* local-rcvbuf */
|
||||||
params.local_rcvbuf = atoi(optarg)/2;
|
params.local_rcvbuf = atoi(optarg)/2;
|
||||||
break;
|
break;
|
||||||
case 42: /* local-sndbuf */
|
case 43: /* local-sndbuf */
|
||||||
params.local_sndbuf = atoi(optarg)/2;
|
params.local_sndbuf = atoi(optarg)/2;
|
||||||
break;
|
break;
|
||||||
case 43: /* remote-rcvbuf */
|
case 44: /* remote-rcvbuf */
|
||||||
params.remote_rcvbuf = atoi(optarg)/2;
|
params.remote_rcvbuf = atoi(optarg)/2;
|
||||||
break;
|
break;
|
||||||
case 44: /* remote-sndbuf */
|
case 45: /* remote-sndbuf */
|
||||||
params.remote_sndbuf = atoi(optarg)/2;
|
params.remote_sndbuf = atoi(optarg)/2;
|
||||||
break;
|
break;
|
||||||
case 45: /* socks */
|
case 46: /* socks */
|
||||||
params.proxy_type = CONN_TYPE_SOCKS;
|
params.proxy_type = CONN_TYPE_SOCKS;
|
||||||
break;
|
break;
|
||||||
case 46: /* no-resolve */
|
case 47: /* no-resolve */
|
||||||
params.no_resolve = true;
|
params.no_resolve = true;
|
||||||
break;
|
break;
|
||||||
case 47: /* skip-nodelay */
|
case 48: /* skip-nodelay */
|
||||||
params.skip_nodelay = true;
|
params.skip_nodelay = true;
|
||||||
break;
|
break;
|
||||||
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
|
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
|
||||||
case 48: /* enable-pf */
|
case 49: /* enable-pf */
|
||||||
params.pf_enable = true;
|
params.pf_enable = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -134,7 +134,7 @@ ssize_t send_with_ttl(int fd, const void *buf, size_t len, int flags, int ttl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool send_buffer_create(send_buffer_t *sb, const void *data, size_t len, int ttl)
|
static bool send_buffer_create(send_buffer_t *sb, const void *data, size_t len, int flags, int ttl)
|
||||||
{
|
{
|
||||||
if (sb->data)
|
if (sb->data)
|
||||||
{
|
{
|
||||||
@ -151,6 +151,7 @@ static bool send_buffer_create(send_buffer_t *sb, const void *data, size_t len,
|
|||||||
sb->len = len;
|
sb->len = len;
|
||||||
sb->pos = 0;
|
sb->pos = 0;
|
||||||
sb->ttl = ttl;
|
sb->ttl = ttl;
|
||||||
|
sb->flags = flags;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static void send_buffer_free(send_buffer_t *sb)
|
static void send_buffer_free(send_buffer_t *sb)
|
||||||
@ -185,7 +186,7 @@ static ssize_t send_buffer_send(send_buffer_t *sb, int fd)
|
|||||||
{
|
{
|
||||||
ssize_t wr;
|
ssize_t wr;
|
||||||
|
|
||||||
wr = send_with_ttl(fd, sb->data + sb->pos, sb->len - sb->pos, 0, sb->ttl);
|
wr = send_with_ttl(fd, sb->data + sb->pos, sb->len - sb->pos, sb->flags, sb->ttl);
|
||||||
DBGPRINT("send_buffer_send len=%zu pos=%zu wr=%zd err=%d",sb->len,sb->pos,wr,errno)
|
DBGPRINT("send_buffer_send len=%zu pos=%zu wr=%zd err=%d",sb->len,sb->pos,wr,errno)
|
||||||
if (wr>0)
|
if (wr>0)
|
||||||
{
|
{
|
||||||
@ -259,16 +260,16 @@ static bool conn_has_unsent_pair(tproxy_conn_t *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t send_or_buffer(send_buffer_t *sb, int fd, const void *buf, size_t len, int ttl)
|
static ssize_t send_or_buffer(send_buffer_t *sb, int fd, const void *buf, size_t len, int flags, int ttl)
|
||||||
{
|
{
|
||||||
ssize_t wr=0;
|
ssize_t wr=0;
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
wr = send_with_ttl(fd, buf, len, 0, ttl);
|
wr = send_with_ttl(fd, buf, len, flags, ttl);
|
||||||
if (wr<0 && errno==EAGAIN) wr=0;
|
if (wr<0 && errno==EAGAIN) wr=0;
|
||||||
if (wr>=0 && wr<len)
|
if (wr>=0 && wr<len)
|
||||||
{
|
{
|
||||||
if (!send_buffer_create(sb, buf+wr, len-wr, ttl))
|
if (!send_buffer_create(sb, buf+wr, len-wr, flags, ttl))
|
||||||
wr=-1;
|
wr=-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1007,20 +1008,28 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
|
|||||||
|
|
||||||
if (split_pos)
|
if (split_pos)
|
||||||
{
|
{
|
||||||
|
uint8_t oob;
|
||||||
|
|
||||||
VPRINT("Splitting at pos %zu", split_pos)
|
VPRINT("Splitting at pos %zu", split_pos)
|
||||||
wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, split_pos, params.disorder ? 1 : 0);
|
if (params.oob)
|
||||||
|
{
|
||||||
|
oob = buf[split_pos];
|
||||||
|
buf[split_pos] = 0;
|
||||||
|
}
|
||||||
|
wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, split_pos+1, params.oob ? MSG_OOB : 0, params.disorder ? 1 : 0);
|
||||||
|
if (params.oob) buf[split_pos] = oob;
|
||||||
DBGPRINT("send_or_buffer(1) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
|
DBGPRINT("send_or_buffer(1) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
|
||||||
if (wr >= 0)
|
if (wr >= 0)
|
||||||
{
|
{
|
||||||
conn->partner->twr += wr;
|
conn->partner->twr += wr;
|
||||||
wr = send_or_buffer(conn->partner->wr_buf + 1, conn->partner->fd, buf + split_pos, bs - split_pos, 0);
|
wr = send_or_buffer(conn->partner->wr_buf + 1, conn->partner->fd, buf + split_pos, bs - split_pos, 0, 0);
|
||||||
DBGPRINT("send_or_buffer(2) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
|
DBGPRINT("send_or_buffer(2) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
|
||||||
if (wr>0) conn->partner->twr += wr;
|
if (wr>0) conn->partner->twr += wr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, bs, 0);
|
wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, bs, 0, 0);
|
||||||
DBGPRINT("send_or_buffer(3) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
|
DBGPRINT("send_or_buffer(3) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
|
||||||
if (wr>0) conn->partner->twr += wr;
|
if (wr>0) conn->partner->twr += wr;
|
||||||
}
|
}
|
||||||
@ -1080,7 +1089,7 @@ static bool read_all_and_buffer(tproxy_conn_t *conn, int buffer_number)
|
|||||||
DBGPRINT("read_all_and_buffer(%d) numbytes=%d",buffer_number,numbytes)
|
DBGPRINT("read_all_and_buffer(%d) numbytes=%d",buffer_number,numbytes)
|
||||||
if (numbytes>0)
|
if (numbytes>0)
|
||||||
{
|
{
|
||||||
if (send_buffer_create(conn->partner->wr_buf+buffer_number, NULL, numbytes, 0))
|
if (send_buffer_create(conn->partner->wr_buf+buffer_number, NULL, numbytes, 0, 0))
|
||||||
{
|
{
|
||||||
ssize_t rd = recv(conn->fd, conn->partner->wr_buf[buffer_number].data, numbytes, MSG_DONTWAIT);
|
ssize_t rd = recv(conn->fd, conn->partner->wr_buf[buffer_number].data, numbytes, MSG_DONTWAIT);
|
||||||
if (rd>0)
|
if (rd>0)
|
||||||
|
@ -30,7 +30,7 @@ struct send_buffer
|
|||||||
{
|
{
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
size_t len,pos;
|
size_t len,pos;
|
||||||
int ttl;
|
int ttl, flags;
|
||||||
};
|
};
|
||||||
typedef struct send_buffer send_buffer_t;
|
typedef struct send_buffer send_buffer_t;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user