Compare commits

...

37 Commits

Author SHA1 Message Date
bol-van 87e058624c update docs 2026-07-21 09:17:51 +03:00
bol-van 906665d9a5 nfqws: fix minor compile warning 2026-07-21 09:14:01 +03:00
bol-van f97c22e96f init.d: discord media add port range 2026-07-21 09:10:49 +03:00
bol-van 9fb1f24808 init.d: remove KillMode=none in systemd unit 2026-07-21 09:08:52 +03:00
bol-van 1a1fc38c8e minor static analyzer fixes 2026-06-06 10:09:35 +03:00
bol-van 42a9b8e330 update docs 2026-05-09 08:14:30 +03:00
bol-van 363fbe6943 github: remove sdiv crash on old armv7 2026-03-12 20:55:17 +03:00
bol-van 5cc46a9815 update changes.txt 2026-03-12 14:36:58 +03:00
bol-van ef637c482c github: use 16K page size for android arm64 build 2026-03-05 19:37:57 +03:00
bol-van acccfc75e9 nfqws: backport QUICDefragCrypto 2026-03-05 10:32:26 +03:00
bol-van a92b4a543e nfqws: backport QUICDefragCrypto 2026-03-04 22:49:53 +03:00
bol-van 24e3b53165 github: move arm to armv6 2026-03-01 20:35:00 +03:00
bol-van 63e6215be0 github: use thumb in android armv7 build 2026-03-01 18:32:26 +03:00
bol-van cb382036f4 winws: -Wl,--gc-sections 2026-03-01 14:38:11 +03:00
bol-van 928134ca36 update docs 2026-03-01 14:15:36 +03:00
bol-van e5c3e4c706 optimize binaries size 2026-03-01 14:14:28 +03:00
bol-van 378411443f minor fixes 2026-03-01 09:50:52 +03:00
bol-van 74c5b58a1b AI fixes 2026-02-28 10:10:12 +03:00
bol-van 934903dfdf nfqws: cosmetic 2026-02-27 14:35:38 +03:00
bol-van 6cb394de4d Merge pull request #2096 from a1batross/master
Fix build on e2k
2026-02-26 16:30:36 +03:00
Alibek Omarov 003c540f24 tpws: fix building on e2k 2026-02-26 13:33:30 +00:00
Alibek Omarov 0870120cce nfqws: fix building on e2k 2026-02-26 13:33:08 +00:00
bol-van f0b0d89f02 nfqws: relax stun detector 2026-02-24 10:13:53 +03:00
bol-van a08a358342 nfqws: fix broken wifi ssid update 2026-02-24 10:12:38 +03:00
bol-van 61edd29b7e Revert "nfqws: fix broken wifi ssid update"
This reverts commit 7eb195e533.
2026-02-24 10:11:45 +03:00
bol-van 7eb195e533 nfqws: fix broken wifi ssid update 2026-02-24 10:11:11 +03:00
bol-van 3d567b0ac4 nfqws: optimize nfq buffers 2026-02-22 17:32:49 +03:00
bol-van 53eba046ce nfqws: fix quicv2 recognition 2026-02-19 10:05:09 +03:00
bol-van 5ef01d14a9 nfqws: fixes backport from z2 2026-02-16 12:50:52 +03:00
bol-van 0f0e748adb nfqws2: ensure old toolchains do not break 2026-02-16 12:03:42 +03:00
bol-van e0a2116880 Merge pull request #2083 from k0tran/master
Enable seccomp on loongarch64
2026-02-16 11:44:46 +03:00
Ilya Sorochan 3d12e32ee9 enable seccomp on loongarch64 2026-02-16 11:29:02 +03:00
bol-van be57475eee nfqws: fix possible OOB read 2026-02-06 16:14:04 +03:00
bol-van e59efa39db mdig: minor change 2026-02-05 18:51:47 +03:00
bol-van aa8b96d601 nfqws: some protocol.c fixes 2026-02-04 22:10:00 +03:00
bol-van 2d1858ebae update docs 2026-01-29 13:38:05 +03:00
bol-van 119e243b36 blockcheck: fix missing quic fake escape 2026-01-20 09:36:50 +03:00
29 changed files with 295 additions and 181 deletions
+26 -22
View File
@@ -25,27 +25,13 @@ jobs:
- arch: arm64 - arch: arm64
tool: aarch64-unknown-linux-musl tool: aarch64-unknown-linux-musl
- arch: arm - arch: arm
tool: arm-unknown-linux-musleabi tool: armv6-unknown-linux-musleabi
# - arch: armhf
# tool: arm-unknown-linux-musleabihf
# - arch: armv7
# tool: armv7-unknown-linux-musleabi
# - arch: armv7hf
# tool: armv7-unknown-linux-musleabihf
# - arch: mips64el
# tool: mips64el-unknown-linux-musl
- arch: mips64 - arch: mips64
tool: mips64-unknown-linux-musl tool: mips64-unknown-linux-musl
# - arch: mipsel
# tool: mipsel-unknown-linux-musl
- arch: mipselsf - arch: mipselsf
tool: mipsel-unknown-linux-muslsf tool: mipsel-unknown-linux-muslsf
# - arch: mips
# tool: mips-unknown-linux-musl
- arch: mipssf - arch: mipssf
tool: mips-unknown-linux-muslsf tool: mips-unknown-linux-muslsf
# - arch: ppc64
# tool: powerpc64-unknown-linux-musl
- arch: ppc - arch: ppc
tool: powerpc-unknown-linux-musl tool: powerpc-unknown-linux-musl
- arch: x86 - arch: x86
@@ -69,7 +55,7 @@ jobs:
env: env:
ARCH: ${{ matrix.arch }} ARCH: ${{ matrix.arch }}
TOOL: ${{ matrix.tool }} TOOL: ${{ matrix.tool }}
REPO: ${{ matrix.arch == 'lexra' && matrix.repo || 'spvkgn/musl-cross' }} REPO: ${{ matrix.arch == 'lexra' && matrix.repo || 'bol-van/musl-cross' }}
DIR: ${{ matrix.arch == 'lexra' && matrix.dir || matrix.tool }} DIR: ${{ matrix.arch == 'lexra' && matrix.dir || matrix.tool }}
run: | run: |
if [[ "$ARCH" == lexra ]]; then if [[ "$ARCH" == lexra ]]; then
@@ -102,6 +88,15 @@ jobs:
export STRIP=$TARGET-strip export STRIP=$TARGET-strip
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
export STAGING_DIR=$RUNNER_TEMP export STAGING_DIR=$RUNNER_TEMP
OPTIMIZE=-Oz
case "$ARCH" in
lexra)
OPTIMIZE=-Os
;;
arm)
CPU="-mcpu=arm1176jzf-s -mthumb"
;;
esac
# netfilter libs # netfilter libs
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
@@ -111,7 +106,7 @@ jobs:
for i in libmnl libnfnetlink libnetfilter_queue ; do for i in libmnl libnfnetlink libnetfilter_queue ; do
( (
cd $i-* cd $i-*
CFLAGS="-Os -flto=auto $CFLAGS" \ CFLAGS="$OPTIMIZE $CPU -flto=auto $CFLAGS" \
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking ./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
make install -j$(nproc) DESTDIR=$DEPS_DIR make install -j$(nproc) DESTDIR=$DEPS_DIR
) )
@@ -123,7 +118,7 @@ jobs:
xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz
( (
cd zlib-* cd zlib-*
CFLAGS="-Os -flto=auto $CFLAGS" \ CFLAGS="$OPTIMIZE $CPU -flto=auto $CFLAGS" \
./configure --prefix= --static ./configure --prefix= --static
make install -j$(nproc) DESTDIR=$DEPS_DIR make install -j$(nproc) DESTDIR=$DEPS_DIR
) )
@@ -134,7 +129,8 @@ jobs:
install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h
# zapret # zapret
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -static -I$DEPS_DIR/include $CFLAGS" \ OPTIMIZE=$OPTIMIZE \
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -static $CPU -I$DEPS_DIR/include $CFLAGS" \
LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \ LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \
make -C zapret -j$(nproc) make -C zapret -j$(nproc)
tar -C zapret/binaries/my -cJf zapret-linux-$ARCH.tar.xz . tar -C zapret/binaries/my -cJf zapret-linux-$ARCH.tar.xz .
@@ -340,6 +336,14 @@ jobs:
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip export STRIP=$TOOLCHAIN/bin/llvm-strip
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
case "$ABI" in
armeabi-v7a)
CPU="-mthumb"
;;
arm64-v8a)
PAGESIZE="-Wl,-z,max-page-size=16384"
;;
esac
# netfilter libs # netfilter libs
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
@@ -350,7 +354,7 @@ jobs:
for i in libmnl libnfnetlink libnetfilter_queue ; do for i in libmnl libnfnetlink libnetfilter_queue ; do
( (
cd $i-* cd $i-*
CFLAGS="-Os -flto=auto -Wno-implicit-function-declaration" \ CFLAGS="$CPU -Os -flto=auto -Wno-implicit-function-declaration" \
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking ./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
make install -j$(nproc) DESTDIR=$DEPS_DIR make install -j$(nproc) DESTDIR=$DEPS_DIR
) )
@@ -358,8 +362,8 @@ jobs:
done done
# zapret # zapret
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -I$DEPS_DIR/include" \ CFLAGS="$CPU -DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -I$DEPS_DIR/include" \
LDFLAGS="-L$DEPS_DIR/lib" \ LDFLAGS="-L$DEPS_DIR/lib $PAGESIZE" \
make -C zapret android -j$(nproc) make -C zapret android -j$(nproc)
# strip unwanted ELF sections to prevent warnings on old Android versions # strip unwanted ELF sections to prevent warnings on old Android versions
+1 -1
View File
@@ -1573,7 +1573,7 @@ pktws_check_domain_http3_bypass_()
for fake in '' "--dpi-desync-fake-quic=$ZAPRET_BASE/files/fake/quic_initial_www_google_com.bin"; do for fake in '' "--dpi-desync-fake-quic=$ZAPRET_BASE/files/fake/quic_initial_www_google_com.bin"; do
for rep in '' 2 5 10 20; do for rep in '' 2 5 10 20; do
pktws_curl_test_update $1 $2 --dpi-desync=fake ${fake:+$fake }${rep:+--dpi-desync-repeats=$rep} && [ "$SCANLEVEL" != force ] && { pktws_curl_test_update $1 $2 --dpi-desync=fake ${fake:+"$fake" }${rep:+--dpi-desync-repeats=$rep} && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
break break
} }
+29 -6
View File
@@ -568,30 +568,53 @@ nfqws: --wssize-forced-cutoff
nfqws: --orig-tcp-flags, --dup-tcp-flags, --dpi-desync-tcp-flags nfqws: --orig-tcp-flags, --dup-tcp-flags, --dpi-desync-tcp-flags
nfqws: --dup-ip-id nfqws: --dup-ip-id
73.3 72.3
blockcheck: support URIs blockcheck: support URIs
blockcheck: CURL_HTTPS_GET=1 suppresses -I curl option for https (HEAD -> GET) blockcheck: CURL_HTTPS_GET=1 suppresses -I curl option for https (HEAD -> GET)
73.4 72.4
blockcheck: fix broken dns cache blockcheck: fix broken dns cache
73.5 72.5
nfqws: fix broken l7proto profile rediscovery nfqws: fix broken l7proto profile rediscovery
nfqws: backport from nfqws2 nl80211 ssid discovery fix for newer kernels nfqws: backport from nfqws2 nl80211 ssid discovery fix for newer kernels
73.6 72.6
ipset: remove zapret-info based scripts because it's gone ipset: remove zapret-info based scripts because it's gone
blockcheck: fix tpws test regression blockcheck: fix tpws test regression
73.7 72.7
nfqws,tpws: memleak fix nfqws,tpws: memleak fix
mdig: --eagain, --eagain-delay mdig: --eagain, --eagain-delay
73.8 72.8
nfqws: fix breaking tcp if ts fooling is enabled but no timestamps present nfqws: fix breaking tcp if ts fooling is enabled but no timestamps present
72.9
blockcheck: fix detection of http redirection if domain/URI specified
install_easy: fix writing of ask_list variables
72.10
* nfqws2: fix broken wifi ssid update
* minor AI fixes
72.12
* github: reduce binaries size
* github: use 16K page size for android arm64 build
* nfqws: join fragments in quic CRYPTO reconstruction. allow intersections.
72.13
* github: compile armv6. fix idiv illegal instruction on early armv7
* init.d: add port range for discord media
* init.d: remove KillMode=none in systemd unit
+8 -1
View File
@@ -4,6 +4,11 @@ This software is free and open source under [MIT license](./LICENSE.txt).
If anyone demands you to download this software only from their webpage, telegram channel, forces you to delete links, videos, makes copyright claims, you are dealing with scammers. If anyone demands you to download this software only from their webpage, telegram channel, forces you to delete links, videos, makes copyright claims, you are dealing with scammers.
However, [donations](#donations) are welcome. However, [donations](#donations) are welcome.
# zapret2
zapret 1 is EOL (End-Of-Life). Will be no more new features, no PR will be accepted.
Current version is [zapret2](https://github.com/bol-van/zapret2).
# Multilanguage/Мультиязычный README # Multilanguage/Мультиязычный README
___ ___
[![en](https://img.shields.io/badge/lang-en-red.svg)](https://github.com/bol-van/zapret/tree/master/docs/readme.en.md) [![en](https://img.shields.io/badge/lang-en-red.svg)](https://github.com/bol-van/zapret/tree/master/docs/readme.en.md)
@@ -1702,7 +1707,9 @@ If this is the case then run another script in background and add some delay the
Are welcome here : Are welcome here :
USDT `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E` USDT ERC `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E`
USDT TRC `TEzAAtn4VhndqEaAyuCM78xh5W2gCjwWEo`
BTC `bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve` BTC `bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve`
+4 -2
View File
@@ -6,7 +6,7 @@ zapret является свободным и open source.
# zapret2 # zapret2
Эта версия zapret более не развивается и находится в режиме EOL (End-Of-Life). Никаких новых функций больше не будет. Только багфиксы. Эта версия zapret более не развивается и находится в режиме EOL (End-Of-Life). Никаких новых функций больше не будет. Только багфиксы. Pull реквесты с новыми фичами не принимаются.
[Актуальная версия - zapret 2](https://github.com/bol-van/zapret2) [Актуальная версия - zapret 2](https://github.com/bol-van/zapret2)
@@ -2724,7 +2724,9 @@ VPS можно приобрести в множестве мест. Сущест
## Поддержать разработчика ## Поддержать разработчика
USDT `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E` USDT ERC `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E`
USDT TRC `TEzAAtn4VhndqEaAyuCM78xh5W2gCjwWEo`
BTC `bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve` BTC `bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve`
@@ -3,7 +3,7 @@
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---dpi-desync=fake --dpi-desync-repeats=2}" NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---dpi-desync=fake --dpi-desync-repeats=2}"
DISCORD_MEDIA_PORT_RANGE="${DISCORD_MEDIA_PORT_RANGE:-50000-50099}" DISCORD_MEDIA_PORT_RANGE="${DISCORD_MEDIA_PORT_RANGE:-50000-50099,19294-19344}"
alloc_dnum DNUM_DISCORD_MEDIA alloc_dnum DNUM_DISCORD_MEDIA
alloc_qnum QNUM_DISCORD_MEDIA alloc_qnum QNUM_DISCORD_MEDIA
@@ -21,7 +21,7 @@ zapret_custom_firewall()
local DISABLE_IPV6=1 local DISABLE_IPV6=1
local port_range=$(replace_char - : $DISCORD_MEDIA_PORT_RANGE) local port_range=$(replace_char - : $DISCORD_MEDIA_PORT_RANGE)
local f="-p udp --dport $port_range -m u32 --u32" local f="-p udp -m multiport --dports $port_range -m u32 --u32"
# this is simplified test to skip writing monstrous rule. instead of checking 64 bytes for zeroes only check 2 dwords for zero # this is simplified test to skip writing monstrous rule. instead of checking 64 bytes for zeroes only check 2 dwords for zero
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x52&&0>>22&0x3C@8=0x00010046&&0>>22&0x3C@16=0&&0>>22&0x3C@76=0" '' $QNUM_DISCORD_MEDIA fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x52&&0>>22&0x3C@8=0x00010046&&0>>22&0x3C@16=0&&0>>22&0x3C@76=0" '' $QNUM_DISCORD_MEDIA
} }
@@ -30,6 +30,7 @@ zapret_custom_firewall_nft()
# stop logic is not required # stop logic is not required
local DISABLE_IPV6=1 local DISABLE_IPV6=1
local f="udp dport $DISCORD_MEDIA_PORT_RANGE udp length == 82 @ih,0,32 0x00010046 @ih,64,128 0x00000000000000000000000000000000 @ih,192,128 0x00000000000000000000000000000000 @ih,320,128 0x00000000000000000000000000000000 @ih,448,128 0x00000000000000000000000000000000" local f="udp dport {$DISCORD_MEDIA_PORT_RANGE} udp length == 82 @ih,0,32 0x00010046 @ih,64,128 0x00000000000000000000000000000000 @ih,192,128 0x00000000000000000000000000000000 @ih,320,128 0x00000000000000000000000000000000 @ih,448,128 0x00000000000000000000000000000000"
nft_fw_nfqws_post "$f" '' $QNUM_DISCORD_MEDIA nft_fw_nfqws_post "$f" '' $QNUM_DISCORD_MEDIA
} }
-1
View File
@@ -7,7 +7,6 @@ Type=forking
Restart=no Restart=no
TimeoutSec=30sec TimeoutSec=30sec
IgnoreSIGPIPE=no IgnoreSIGPIPE=no
KillMode=none
GuessMainPID=no GuessMainPID=no
RemainAfterExit=no RemainAfterExit=no
ExecStart=/opt/zapret/init.d/sysv/zapret start ExecStart=/opt/zapret/init.d/sysv/zapret start
@@ -1,5 +1,5 @@
outbound and ip and outbound and ip and
udp.DstPort>=50000 and udp.DstPort<=50099 and (udp.DstPort>=50000 and udp.DstPort<=50099 or udp.DstPort>=19294 and udp.DstPort<=19344) and
udp.PayloadLength=74 and udp.PayloadLength=74 and
udp.Payload32[0]=0x00010046 and udp.Payload32[0]=0x00010046 and
udp.Payload32[2]=0 and udp.Payload32[2]=0 and
+7 -7
View File
@@ -80,15 +80,15 @@ static bool dom_valid(char *dom)
{ {
if (!dom || *dom=='.') return false; if (!dom || *dom=='.') return false;
for (; *dom; dom++) for (; *dom; dom++)
if (*dom < 0x20 || (*dom & 0x80) || !(*dom == '.' || *dom == '-' || *dom == '_' || (*dom >= '0' && *dom <= '9') || (*dom >= 'a' && *dom <= 'z') || (*dom >= 'A' && *dom <= 'Z'))) if (!(*dom == '.' || *dom == '-' || *dom == '_' || (*dom >= '0' && *dom <= '9') || (*dom >= 'a' && *dom <= 'z') || (*dom >= 'A' && *dom <= 'Z')))
return false; return false;
return true; return true;
} }
static void invalid_domain_beautify(char *dom) static void invalid_domain_beautify(char *dom)
{ {
for (int i = 0; *dom && i < 64; i++, dom++) for (int i = 0; *dom && i < 64; i++, dom++)
if (*dom < 0x20 || *dom<0) *dom = '?'; if (*dom < 0x20 || (*dom & 0x80)) *dom = '?';
if (*dom) *dom = 0; if (*dom) *dom = 0;
} }
@@ -220,7 +220,7 @@ static void *t_resolver(void *arg)
{ {
if ((family == AF_INET && (glob.family & FAMILY4)) || (family == AF_INET6 && (glob.family & FAMILY6))) if ((family == AF_INET && (glob.family & FAMILY4)) || (family == AF_INET6 && (glob.family & FAMILY6)))
{ {
unsigned int mask; unsigned int mask=0;
bool mask_needed = false; bool mask_needed = false;
if (s_mask) if (s_mask)
{ {
@@ -436,7 +436,7 @@ int dns_parse_query()
_setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdin), _O_BINARY);
#endif #endif
l = fread(a,1,sizeof(a),stdin); l = fread(a,1,sizeof(a),stdin);
if (!l || !feof(stdin)) if (!l || ferror(stdin))
{ {
fprintf(stderr, "could not read DNS reply blob from stdin\n"); fprintf(stderr, "could not read DNS reply blob from stdin\n");
return 10; return 10;
@@ -455,8 +455,8 @@ static void exithelp(void)
printf( printf(
" --family=<4|6|46>\t\t; ipv4, ipv6, ipv4+ipv6\n" " --family=<4|6|46>\t\t; ipv4, ipv6, ipv4+ipv6\n"
" --threads=<threads_number>\n" " --threads=<threads_number>\n"
" --eagain=<eagain_retries>\t; how many times to retry if EAGAIN received. default %u\n" " --eagain=<eagain_retries>\t; how many times to retry if EAI_AGAIN received. default %u\n"
" --eagain-delay=<ms>\t\t; time in msec to wait between EAGAIN attempts. default %u\n" " --eagain-delay=<ms>\t\t; time in msec to wait between EAI_AGAIN attempts. default %u\n"
" --verbose\t\t\t; print query progress to stderr\n" " --verbose\t\t\t; print query progress to stderr\n"
" --stats=N\t\t\t; print resolve stats to stderr every N domains\n" " --stats=N\t\t\t; print resolve stats to stderr every N domains\n"
" --log-resolved=<file>\t\t; log successfully resolved domains to a file\n" " --log-resolved=<file>\t\t; log successfully resolved domains to a file\n"
+14 -9
View File
@@ -1,10 +1,15 @@
CC ?= cc CC ?= cc
OPTIMIZE ?= -Os OPTIMIZE ?= -Os
CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto -ffunction-sections -fdata-sections
CFLAGS_SYSTEMD = -DUSE_SYSTEMD CFLAGS_SYSTEMD = -DUSE_SYSTEMD
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
LDFLAGS_ANDROID = -llog LDFLAGS += -flto=auto
LDFLAGS_ANDROID = -Wl,--gc-sections -llog
LDFLAGS_BSD = -Wl,--gc-sections
LDFLAGS_LINUX = -Wl,--gc-sections
LDFLAGS_MAC = -Wl,-dead_strip
LDFLAGS_WIN = -Wl,--gc-sections
LIBS_LINUX = -lz -lnetfilter_queue -lnfnetlink -lmnl LIBS_LINUX = -lz -lnetfilter_queue -lnfnetlink -lmnl
LIBS_SYSTEMD = -lsystemd LIBS_SYSTEMD = -lsystemd
LIBS_BSD = -lz LIBS_BSD = -lz
@@ -18,28 +23,28 @@ SRC_FILES = *.c crypto/*.c
all: nfqws all: nfqws
nfqws: $(SRC_FILES) nfqws: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) $(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) $(LDFLAGS_LINUX)
systemd: $(SRC_FILES) systemd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS) $(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS) $(LDFLAGS_LINUX)
android: $(SRC_FILES) android: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) $(LDFLAGS_ANDROID) $(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) $(LDFLAGS_ANDROID)
bsd: $(SRC_FILES) bsd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o dvtws $(SRC_FILES) $(LIBS_BSD) $(LDFLAGS) $(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o dvtws $(SRC_FILES) $(LIBS_BSD) $(LDFLAGS) $(LDFLAGS_BSD)
mac: $(SRC_FILES) mac: $(SRC_FILES)
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsa $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) $(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsa $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) $(LDFLAGS_MAC)
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) $(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) $(LDFLAGS_MAC)
strip dvtwsa dvtwsx strip dvtwsa dvtwsx
lipo -create -output dvtws dvtwsx dvtwsa lipo -create -output dvtws dvtwsx dvtwsa
rm -f dvtwsx dvtwsa rm -f dvtwsx dvtwsa
cygwin64: cygwin64:
$(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(RES_CYGWIN64) $(LDFLAGS) $(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(RES_CYGWIN64) $(LDFLAGS) $(LDFLAGS_WIN)
cygwin32: cygwin32:
$(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(RES_CYGWIN32) $(LDFLAGS) $(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(RES_CYGWIN32) $(LDFLAGS) $(LDFLAGS_WIN)
cygwin: cygwin64 cygwin: cygwin64
clean: clean:
+2
View File
@@ -5,6 +5,8 @@ int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_
int ret = 0; int ret = 0;
gcm_context ctx; gcm_context ctx;
gcm_initialize();
if (!(ret = gcm_setkey(&ctx, key, (const uint)key_len))) if (!(ret = gcm_setkey(&ctx, key, (const uint)key_len)))
{ {
ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len); ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len);
+18 -9
View File
@@ -391,7 +391,9 @@ int gcm_finish(gcm_context *ctx, // pointer to user-provided GCM context
uint64_t orig_add_len = ctx->add_len * 8; uint64_t orig_add_len = ctx->add_len * 8;
size_t i; size_t i;
if (tag_len != 0) memcpy(tag, ctx->base_ectr, tag_len); if (tag_len>16) return -1;
if (tag_len) memcpy(tag, ctx->base_ectr, tag_len);
if (orig_len || orig_add_len) { if (orig_len || orig_add_len) {
memset(work_buf, 0x00, 16); memset(work_buf, 0x00, 16);
@@ -443,10 +445,12 @@ int gcm_crypt_and_tag(
prepare the gcm context with the keying material, we simply prepare the gcm context with the keying material, we simply
invoke each of the three GCM sub-functions in turn... invoke each of the three GCM sub-functions in turn...
*/ */
gcm_start(ctx, mode, iv, iv_len, add, add_len); if (tag_len>16) return -1;
gcm_update(ctx, length, input, output);
gcm_finish(ctx, tag, tag_len); int ret;
return(0); if ((ret=gcm_start(ctx, mode, iv, iv_len, add, add_len))) return ret;
if ((ret=gcm_update(ctx, length, input, output))) return ret;
return gcm_finish(ctx, tag, tag_len);
} }
@@ -477,23 +481,28 @@ int gcm_auth_decrypt(
uchar check_tag[16]; // the tag generated and returned by decryption uchar check_tag[16]; // the tag generated and returned by decryption
int diff; // an ORed flag to detect authentication errors int diff; // an ORed flag to detect authentication errors
size_t i; // our local iterator size_t i; // our local iterator
int ret;
if (tag_len>16) return -1;
/* /*
we use GCM_DECRYPT_AND_TAG (above) to perform our decryption we use GCM_DECRYPT_AND_TAG (above) to perform our decryption
(which is an identical XORing to reverse the previous one) (which is an identical XORing to reverse the previous one)
and also to re-generate the matching authentication tag and also to re-generate the matching authentication tag
*/ */
gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len, if ((ret = gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len, input, output, length, check_tag, tag_len))) return ret;
input, output, length, check_tag, tag_len);
// now we verify the authentication tag in 'constant time' // now we verify the authentication tag in 'constant time'
for (diff = 0, i = 0; i < tag_len; i++) for (diff = 0, i = 0; i < tag_len; i++)
diff |= tag[i] ^ check_tag[i]; diff |= tag[i] ^ check_tag[i];
if (diff != 0) { // see whether any bits differed? if (diff)
{
// see whether any bits differed?
memset(output, 0, length); // if so... wipe the output data memset(output, 0, length); // if so... wipe the output data
return(GCM_AUTH_FAILURE); // return GCM_AUTH_FAILURE return(GCM_AUTH_FAILURE); // return GCM_AUTH_FAILURE
} }
return(0); return 0;
} }
/****************************************************************************** /******************************************************************************
-1
View File
@@ -29,7 +29,6 @@
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <basetsd.h> #include <basetsd.h>
typedef unsigned int size_t;// use the right type for length declarations
typedef UINT32 uint32_t; typedef UINT32 uint32_t;
typedef UINT64 uint64_t; typedef UINT64 uint64_t;
#else #else
+12 -20
View File
@@ -60,9 +60,9 @@ int hkdf(SHAversion whichSha,
uint8_t okm[], size_t okm_len) uint8_t okm[], size_t okm_len)
{ {
uint8_t prk[USHAMaxHashSize]; uint8_t prk[USHAMaxHashSize];
return hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk) || int ret;
hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, if ((ret=hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk))) return ret;
info_len, okm, okm_len); return hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, info_len, okm, okm_len);
} }
/* /*
@@ -103,9 +103,6 @@ int hkdfExtract(SHAversion whichSha,
salt_len = USHAHashSize(whichSha); salt_len = USHAHashSize(whichSha);
memset(nullSalt, '\0', salt_len); memset(nullSalt, '\0', salt_len);
} }
else if (salt_len < 0) {
return shaBadParam;
}
return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk); return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk);
} }
@@ -149,16 +146,13 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
size_t hash_len, N; size_t hash_len, N;
unsigned char T[USHAMaxHashSize]; unsigned char T[USHAMaxHashSize];
size_t Tlen, where, i; size_t Tlen, where, i;
int ret;
if (info == 0) { if (info == 0) {
info = (const unsigned char *)""; info = (const unsigned char *)"";
info_len = 0; info_len = 0;
} }
else if (info_len < 0) { if (!okm || !okm_len) return shaBadParam;
return shaBadParam;
}
if (okm_len <= 0) return shaBadParam;
if (!okm) return shaBadParam;
hash_len = USHAHashSize(whichSha); hash_len = USHAHashSize(whichSha);
if (prk_len < hash_len) return shaBadParam; if (prk_len < hash_len) return shaBadParam;
@@ -171,12 +165,11 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
for (i = 1; i <= N; i++) { for (i = 1; i <= N; i++) {
HMACContext context; HMACContext context;
unsigned char c = i; unsigned char c = i;
int ret = hmacReset(&context, whichSha, prk, prk_len) || if ((ret=hmacReset(&context, whichSha, prk, prk_len))) return ret;
hmacInput(&context, T, Tlen) || if ((ret=hmacInput(&context, T, Tlen))) return ret;
hmacInput(&context, info, info_len) || if ((ret=hmacInput(&context, info, info_len))) return ret;
hmacInput(&context, &c, 1) || if ((ret=hmacInput(&context, &c, 1))) return ret;
hmacResult(&context, T); if ((ret=hmacResult(&context, T))) return ret;
if (ret != shaSuccess) return ret;
memcpy(okm + where, T, memcpy(okm + where, T,
(i != N) ? hash_len : (okm_len - where)); (i != N) ? hash_len : (okm_len - where));
where += hash_len; where += hash_len;
@@ -328,9 +321,8 @@ int hkdfResult(HKDFContext *context,
if (!okm) return context->Corrupted = shaBadParam; if (!okm) return context->Corrupted = shaBadParam;
if (!prk) prk = prkbuf; if (!prk) prk = prkbuf;
ret = hmacResult(&context->hmacContext, prk) || if (!(ret = hmacResult(&context->hmacContext, prk)))
hkdfExpand(context->whichSha, prk, context->hashSize, info, ret = hkdfExpand(context->whichSha, prk, context->hashSize, info, info_len, okm, okm_len);
info_len, okm, okm_len);
context->Computed = 1; context->Computed = 1;
return context->Corrupted = ret; return context->Corrupted = ret;
} }
+14 -21
View File
@@ -49,9 +49,10 @@ int hmac(SHAversion whichSha,
uint8_t digest[USHAMaxHashSize]) uint8_t digest[USHAMaxHashSize])
{ {
HMACContext context; HMACContext context;
return hmacReset(&context, whichSha, key, key_len) || int ret;
hmacInput(&context, message_array, length) || if ((ret=hmacReset(&context, whichSha, key, key_len))) return ret;
hmacResult(&context, digest); if ((ret=hmacInput(&context, message_array, length))) return ret;
return hmacResult(&context, digest);
} }
/* /*
@@ -101,10 +102,8 @@ int hmacReset(HMACContext *context, enum SHAversion whichSha,
*/ */
if (key_len > blocksize) { if (key_len > blocksize) {
USHAContext tcontext; USHAContext tcontext;
int err = USHAReset(&tcontext, whichSha) || if ((ret=USHAReset(&tcontext, whichSha)) || (ret=USHAInput(&tcontext, key, key_len)) || (ret=USHAResult(&tcontext, tempkey)))
USHAInput(&tcontext, key, key_len) || return ret;
USHAResult(&tcontext, tempkey);
if (err != shaSuccess) return err;
key = tempkey; key = tempkey;
key_len = hashsize; key_len = hashsize;
@@ -134,9 +133,9 @@ int hmacReset(HMACContext *context, enum SHAversion whichSha,
/* perform inner hash */ /* perform inner hash */
/* init context for 1st pass */ /* init context for 1st pass */
ret = USHAReset(&context->shaContext, whichSha) || if (!(ret = USHAReset(&context->shaContext, whichSha)))
/* and start with inner pad */ /* and start with inner pad */
USHAInput(&context->shaContext, k_ipad, blocksize); ret = USHAInput(&context->shaContext, k_ipad, blocksize);
return context->Corrupted = ret; return context->Corrupted = ret;
} }
@@ -197,8 +196,7 @@ int hmacFinalBits(HMACContext *context,
if (context->Corrupted) return context->Corrupted; if (context->Corrupted) return context->Corrupted;
if (context->Computed) return context->Corrupted = shaStateError; if (context->Computed) return context->Corrupted = shaStateError;
/* then final bits of datagram */ /* then final bits of datagram */
return context->Corrupted = return context->Corrupted = USHAFinalBits(&context->shaContext, bits, bit_count);
USHAFinalBits(&context->shaContext, bits, bit_count);
} }
/* /*
@@ -229,21 +227,16 @@ int hmacResult(HMACContext *context, uint8_t *digest)
/* finish up 1st pass */ /* finish up 1st pass */
/* (Use digest here as a temporary buffer.) */ /* (Use digest here as a temporary buffer.) */
ret = if (!(ret=USHAResult(&context->shaContext, digest)) &&
USHAResult(&context->shaContext, digest) ||
/* perform outer SHA */ /* perform outer SHA */
/* init context for 2nd pass */ /* init context for 2nd pass */
USHAReset(&context->shaContext, context->whichSha) || !(ret=USHAReset(&context->shaContext, context->whichSha)) &&
/* start with outer pad */ /* start with outer pad */
USHAInput(&context->shaContext, context->k_opad, !(ret=USHAInput(&context->shaContext, context->k_opad, context->blockSize)) &&
context->blockSize) ||
/* then results of 1st hash */ /* then results of 1st hash */
USHAInput(&context->shaContext, digest, context->hashSize) || !(ret=USHAInput(&context->shaContext, digest, context->hashSize)))
/* finish up 2nd pass */ /* finish up 2nd pass */
USHAResult(&context->shaContext, digest); ret=USHAResult(&context->shaContext, digest);
context->Computed = 1; context->Computed = 1;
return context->Corrupted = ret; return context->Corrupted = ret;
+6 -6
View File
@@ -64,12 +64,12 @@
* Add "length" to the length. * Add "length" to the length.
* Set Corrupted when overflow has occurred. * Set Corrupted when overflow has occurred.
*/ */
static uint32_t addTemp; static int SHA224_256AddLength(SHA256Context *context, uint32_t length)
#define SHA224_256AddLength(context, length) \ {
(addTemp = (context)->Length_Low, (context)->Corrupted = \ uint32_t addTemp = context->Length_Low;
(((context)->Length_Low += (length)) < addTemp) && \ if (((context->Length_Low += length) < addTemp) && (++(context)->Length_High == 0)) context->Corrupted = shaInputTooLong;
(++(context)->Length_High == 0) ? shaInputTooLong : \ return context->Corrupted;
(context)->Corrupted ) }
/* Local Function Prototypes */ /* Local Function Prototypes */
static int SHA224_256Reset(SHA256Context *context, uint32_t *H0); static int SHA224_256Reset(SHA256Context *context, uint32_t *H0);
+2
View File
@@ -928,6 +928,7 @@ void proto_skip_ipv6(uint8_t **data, size_t *len, uint8_t *proto_type, uint8_t *
if (proto_type) *proto_type = 0; // put error in advance if (proto_type) *proto_type = 0; // put error in advance
HeaderType = (*data)[6]; // NextHeader field HeaderType = (*data)[6]; // NextHeader field
if (proto_type) *proto_type = HeaderType;
if (last_header_type) *last_header_type = (*data)+6; if (last_header_type) *last_header_type = (*data)+6;
*data += 40; *len -= 40; // skip ipv6 base header *data += 40; *len -= 40; // skip ipv6 base header
while (*len > 0) // need at least one byte for NextHeader field while (*len > 0) // need at least one byte for NextHeader field
@@ -2095,6 +2096,7 @@ static bool scan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wla
// wlan_info does not return ssid since kernel 5.19 // wlan_info does not return ssid since kernel 5.19
// it's used to enumerate all wifi interfaces then call scan_info on each // it's used to enumerate all wifi interfaces then call scan_info on each
if (!wlan_info(nl, wlan_family_id, &wc_all, false)) return false; if (!wlan_info(nl, wlan_family_id, &wc_all, false)) return false;
w->count=0;
for(int i=0;i<wc_all.count;i++) for(int i=0;i<wc_all.count;i++)
if (!netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0, scan_prepare, (void*)&wc_all.wlan[i].ifindex, scan_info_cb, w)) if (!netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0, scan_prepare, (void*)&wc_all.wlan[i].ifindex, scan_info_cb, w))
return false; return false;
+4 -2
View File
@@ -221,7 +221,8 @@ void print_sockaddr(const struct sockaddr *sa)
bool pton4_port(const char *s, struct sockaddr_in *sa) bool pton4_port(const char *s, struct sockaddr_in *sa)
{ {
char ip[16],*p; char ip[16];
const char *p;
size_t l; size_t l;
unsigned int u; unsigned int u;
@@ -241,7 +242,8 @@ bool pton4_port(const char *s, struct sockaddr_in *sa)
} }
bool pton6_port(const char *s, struct sockaddr_in6 *sa) bool pton6_port(const char *s, struct sockaddr_in6 *sa)
{ {
char ip[40],*p; char ip[40];
const char *p;
size_t l; size_t l;
unsigned int u; unsigned int u;
+7 -4
View File
@@ -256,6 +256,8 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh)
// dot not fail. not supported on old linuxes <3.6 // dot not fail. not supported on old linuxes <3.6
} }
nfnl_rcvbufsiz(nfq_nfnlh(*h), Q_RCVBUF);
DLOG_CONDUP("initializing raw sockets bind-fix4=%u bind-fix6=%u\n", params.bind_fix4, params.bind_fix6); DLOG_CONDUP("initializing raw sockets bind-fix4=%u bind-fix6=%u\n", params.bind_fix4, params.bind_fix6);
if (!rawsend_preinit(params.bind_fix4, params.bind_fix6)) if (!rawsend_preinit(params.bind_fix4, params.bind_fix6))
goto exiterr; goto exiterr;
@@ -350,7 +352,7 @@ static int nfq_main(void)
if (rd) if (rd)
{ {
int r = nfq_handle_packet(h, (char *)buf, (int)rd); int r = nfq_handle_packet(h, (char *)buf, (int)rd);
if (r) DLOG_ERR("nfq_handle_packet error %d\n", r); if (r<0) DLOG_ERR("nfq_handle_packet result %d, errno %d : %s\n", r, errno, strerror(errno));
} }
else else
DLOG("recv from nfq returned 0 !\n"); DLOG("recv from nfq returned 0 !\n");
@@ -2304,6 +2306,7 @@ int main(int argc, char **argv)
#endif #endif
srandom(time(NULL)); srandom(time(NULL));
aes_init_keygen_tables(); // required for aes
PRINT_VER; PRINT_VER;
@@ -3166,7 +3169,7 @@ int main(int argc, char **argv)
} }
break; break;
case IDX_HOSTLIST_AUTO_FAIL_THRESHOLD: case IDX_HOSTLIST_AUTO_FAIL_THRESHOLD:
dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg); dp->hostlist_auto_fail_threshold = atoi(optarg);
if (dp->hostlist_auto_fail_threshold < 1 || dp->hostlist_auto_fail_threshold>20) if (dp->hostlist_auto_fail_threshold < 1 || dp->hostlist_auto_fail_threshold>20)
{ {
DLOG_ERR("auto hostlist fail threshold must be within 1..20\n"); DLOG_ERR("auto hostlist fail threshold must be within 1..20\n");
@@ -3174,7 +3177,7 @@ int main(int argc, char **argv)
} }
break; break;
case IDX_HOSTLIST_AUTO_FAIL_TIME: case IDX_HOSTLIST_AUTO_FAIL_TIME:
dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg); dp->hostlist_auto_fail_time = atoi(optarg);
if (dp->hostlist_auto_fail_time < 1) if (dp->hostlist_auto_fail_time < 1)
{ {
DLOG_ERR("auto hostlist fail time is not valid\n"); DLOG_ERR("auto hostlist fail time is not valid\n");
@@ -3182,7 +3185,7 @@ int main(int argc, char **argv)
} }
break; break;
case IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD: case IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD:
dp->hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg); dp->hostlist_auto_retrans_threshold = atoi(optarg);
if (dp->hostlist_auto_retrans_threshold < 2 || dp->hostlist_auto_retrans_threshold>10) if (dp->hostlist_auto_retrans_threshold < 2 || dp->hostlist_auto_retrans_threshold>10)
{ {
DLOG_ERR("auto hostlist fail threshold must be within 2..10\n"); DLOG_ERR("auto hostlist fail threshold must be within 2..10\n");
+1 -1
View File
@@ -50,7 +50,7 @@ static char log_buf[1024];
static size_t log_buf_sz=0; static size_t log_buf_sz=0;
static void syslog_log_function(int priority, const char *line) static void syslog_log_function(int priority, const char *line)
{ {
syslog(priority,"%s",log_buf); syslog(priority,"%s",line);
} }
#ifdef __ANDROID__ #ifdef __ANDROID__
static enum android_LogPriority syslog_priority_to_android(int priority) static enum android_LogPriority syslog_priority_to_android(int priority)
+2 -1
View File
@@ -23,7 +23,8 @@
#define RAW_SNDBUF (64*1024) // in bytes #define RAW_SNDBUF (64*1024) // in bytes
#define Q_MAXLEN 1024 // in packets #define Q_MAXLEN 4986 // in packets
#define Q_RCVBUF (1024*1024) // in bytes
#define BADSEQ_INCREMENT_DEFAULT -10000 #define BADSEQ_INCREMENT_DEFAULT -10000
#define BADSEQ_ACK_INCREMENT_DEFAULT -66000 #define BADSEQ_ACK_INCREMENT_DEFAULT -66000
+63 -48
View File
@@ -310,7 +310,7 @@ size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz)
if (sz<10) break; if (sz<10) break;
if (*method=='\n' || *method=='\r') method++; if (*method=='\n' || *method=='\r') method++;
if (*method=='\n' || *method=='\r') method++; if (*method=='\n' || *method=='\r') method++;
for (p=method,i=0;i<7;i++) if (*p>='A' && *p<='Z') p++; for (p=method,i=0; i<9 && *p>='A' && *p<='Z'; i++,p++);
if (i<3 || *p!=' ') break; if (i<3 || *p!=' ') break;
return CheckPos(sz,method-data+pos); return CheckPos(sz,method-data+pos);
case PM_HOST: case PM_HOST:
@@ -587,7 +587,7 @@ static uint8_t tvb_get_varint(const uint8_t *tvb, uint64_t *value)
return 8; return 8;
} }
// impossible case // impossible case
if (*value) *value = 0; if (value) *value = 0;
return 0; return 0;
} }
static uint8_t tvb_get_size(uint8_t tvb) static uint8_t tvb_get_size(uint8_t tvb)
@@ -795,21 +795,19 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
return false; return false;
} }
uint64_t payload_len,token_len; uint64_t payload_len,token_len,pn_offset;
size_t pn_offset;
pn_offset = 1 + 4 + 1 + data[5]; pn_offset = 1 + 4 + 1 + data[5];
if (pn_offset >= data_len) return false; if (pn_offset >= data_len) return false;
// SCID length
pn_offset += 1 + data[pn_offset]; pn_offset += 1 + data[pn_offset];
if ((pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false; if (pn_offset >= data_len || (pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
// token length
pn_offset += tvb_get_varint(data + pn_offset, &token_len); pn_offset += tvb_get_varint(data + pn_offset, &token_len);
pn_offset += token_len; pn_offset += token_len;
if (pn_offset >= data_len) return false; if (pn_offset >= data_len || (pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
if ((pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
pn_offset += tvb_get_varint(data + pn_offset, &payload_len); pn_offset += tvb_get_varint(data + pn_offset, &payload_len);
if (payload_len<20 || (pn_offset + payload_len)>data_len) return false; if (payload_len<20 || (pn_offset + payload_len)>data_len) return false;
aes_init_keygen_tables();
uint8_t sample_enc[16]; uint8_t sample_enc[16];
aes_context ctx; aes_context ctx;
if (aes_setkey(&ctx, 1, aeshp, sizeof(aeshp)) || aes_cipher(&ctx, data + pn_offset + 4, sample_enc)) return false; if (aes_setkey(&ctx, 1, aeshp, sizeof(aeshp)) || aes_cipher(&ctx, data + pn_offset + 4, sample_enc)) return false;
@@ -827,13 +825,13 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
phton64(aesiv + sizeof(aesiv) - 8, pntoh64(aesiv + sizeof(aesiv) - 8) ^ pkn); phton64(aesiv + sizeof(aesiv) - 8, pntoh64(aesiv + sizeof(aesiv) - 8) ^ pkn);
size_t cryptlen = payload_len - pkn_len - 16; uint64_t cryptlen = payload_len - pkn_len - 16;
if (cryptlen > *clean_len) return false; if (cryptlen > *clean_len) return false;
*clean_len = cryptlen; *clean_len = (size_t)cryptlen;
const uint8_t *decrypt_begin = data + pn_offset + pkn_len; const uint8_t *decrypt_begin = data + pn_offset + pkn_len;
uint8_t atag[16],header[256]; uint8_t atag[16],header[2048];
size_t header_len = pn_offset + pkn_len; uint64_t header_len = pn_offset + pkn_len;
if (header_len > sizeof(header)) return false; // not likely header will be so large if (header_len > sizeof(header)) return false; // not likely header will be so large
memcpy(header, data, header_len); memcpy(header, data, header_len);
header[0] = packet0; header[0] = packet0;
@@ -868,7 +866,7 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
uint64_t offset,sz,szmax=0,zeropos=0,pos=0; uint64_t offset,sz,szmax=0,zeropos=0,pos=0;
bool found=false; bool found=false;
struct range64 ranges[MAX_DEFRAG_PIECES]; struct range64 ranges[MAX_DEFRAG_PIECES];
int i,range=0; int i,j,range=0;
while(pos<clean_len) while(pos<clean_len)
{ {
@@ -890,24 +888,54 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
if ((pos+sz)>clean_len) return false; if ((pos+sz)>clean_len) return false;
if ((offset+sz)>defrag_data_len) return false; // defrag buf overflow if ((offset+sz)>defrag_data_len) return false; // defrag buf overflow
// remove exact duplicates early to save cpu
for(i=0;i<range;i++)
if (ranges[i].offset==offset && ranges[i].len==sz)
goto skip_range;
if (zeropos < offset) if (zeropos < offset)
// make sure no uninitialized gaps exist in case of not full fragment coverage // make sure no uninitialized gaps exist in case of not full fragment coverage
memset(defrag_data+zeropos,0,offset-zeropos); memset(defrag_data+zeropos,0,offset-zeropos);
if ((offset+sz) > zeropos) if ((offset+sz) > zeropos)
zeropos=offset+sz; zeropos=offset+sz;
memcpy(defrag_data+offset,clean+pos,sz);
if ((offset+sz) > szmax) szmax = offset+sz;
found=true; found=true;
pos+=sz; if ((offset+sz) > szmax) szmax = offset+sz;
memcpy(defrag_data+offset,clean+pos,sz);
ranges[range].offset = offset; ranges[range].offset = offset;
ranges[range].len = sz; ranges[range].len = sz;
range++; range++;
skip_range:
pos+=sz;
} }
} }
if (found) if (found)
{ {
qsort(ranges, range, sizeof(*ranges), cmp_range64);
// for(i=0 ; i<range ; i++)
// printf("range1 %llu-%llu\n",ranges[i].offset,ranges[i].offset+ranges[i].len);
if (range>0)
{
for (j=0,i=1; i < range; i++)
{
uint64_t current_end = ranges[j].offset + ranges[j].len;
uint64_t next_start = ranges[i].offset;
uint64_t next_end = ranges[i].offset + ranges[i].len;
if (next_start <= current_end)
ranges[j].len = MAX(next_end,current_end) - ranges[j].offset;
else
ranges[++j] = ranges[i];
}
range = j+1;
}
// for(i=0 ; i<range ; i++)
// printf("range2 %llu-%llu\n",ranges[i].offset,ranges[i].offset+ranges[i].len);
defrag[0] = 6; defrag[0] = 6;
defrag[1] = 0; // offset defrag[1] = 0; // offset
// 2..9 - length 64 bit // 2..9 - length 64 bit
@@ -916,21 +944,7 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
defrag[2] |= 0xC0; // 64 bit value defrag[2] |= 0xC0; // 64 bit value
*defrag_len = (size_t)(szmax+10); *defrag_len = (size_t)(szmax+10);
qsort(ranges, range, sizeof(*ranges), cmp_range64); *bFull = range==1 && !ranges[0].offset;
//for(i=0 ; i<range ; i++)
// printf("RANGE %zu len %zu\n",ranges[i].offset,ranges[i].len);
for(i=0,offset=0,*bFull=true ; i<range ; i++)
{
if (ranges[i].offset!=offset)
{
*bFull = false;
break;
}
offset += ranges[i].len;
}
//printf("bFull=%u\n",*bFull); //printf("bFull=%u\n",*bFull);
} }
return found; return found;
@@ -962,40 +976,41 @@ bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host
bool IsQUICInitial(const uint8_t *data, size_t len) bool IsQUICInitial(const uint8_t *data, size_t len)
{ {
// too small packets are not likely to be initials with client hello // too small packets are not likely to be initials
// long header, fixed bit // long header, fixed bit
if (len < 256 || (data[0] & 0xC0)!=0xC0) return false; if (len < 128) return false;
uint32_t ver = QUICExtractVersion(data,len); uint32_t ver = QUICExtractVersion(data,len);
if (QUICDraftVersion(ver) < 11) return false; if (QUICDraftVersion(ver) < 11) return false;
// quic v1 : initial packets are 00b if ((data[0] & 0xF0) != (is_quic_v2(ver) ? 0xD0 : 0xC0)) return false;
// quic v2 : initial packets are 01b
if ((data[0] & 0x30) != (is_quic_v2(ver) ? 0x10 : 0x00)) return false;
uint64_t offset=5, sz; uint64_t offset=5, sz, sz2;
// DCID. must be present // DCID
if (!data[offset] || data[offset] > QUIC_MAX_CID_LENGTH) return false; if (data[offset] > QUIC_MAX_CID_LENGTH) return false;
offset += 1 + data[offset]; offset += 1 + data[offset];
if (offset>=len) return false;
// SCID // SCID
if (data[offset] > QUIC_MAX_CID_LENGTH) return false; if (data[offset] > QUIC_MAX_CID_LENGTH) return false;
offset += 1 + data[offset]; offset += 1 + data[offset];
// token length // token length
if (offset>=len || (offset + tvb_get_size(data[offset])) > len) return false;
offset += tvb_get_varint(data + offset, &sz); offset += tvb_get_varint(data + offset, &sz);
offset += sz; offset += sz;
if (offset >= len) return false; if (offset >= len) return false;
// payload length // payload length
if ((offset + tvb_get_size(data[offset])) > len) return false; sz2 = tvb_get_size(data[offset]);
if ((offset + sz2) > len) return false;
tvb_get_varint(data + offset, &sz); tvb_get_varint(data + offset, &sz);
offset += sz; offset += sz2 + sz;
if (offset > len) return false; if (offset > len) return false;
// client hello cannot be too small. likely ACK return true;
return sz>=96;
} }
@@ -1020,7 +1035,7 @@ bool IsStunMessage(const uint8_t *data, size_t len)
{ {
return len>=20 && // header size return len>=20 && // header size
(data[0]&0xC0)==0 && // 2 most significant bits must be zeroes (data[0]&0xC0)==0 && // 2 most significant bits must be zeroes
(data[3]&0b11)==0 && // length must be a multiple of 4 (data[3]&3)==0 && // length must be a multiple of 4
ntohl(*(uint32_t*)(&data[4]))==0x2112A442 && // magic cookie pntoh32(data+4)==0x2112A442 && // magic cookie
ntohs(*(uint16_t*)(&data[2]))==len-20; pntoh16(data+2)<=(len-20);
} }
+27
View File
@@ -18,6 +18,25 @@ bool dropcaps(void);
#define arch_nr (offsetof(struct seccomp_data, arch)) #define arch_nr (offsetof(struct seccomp_data, arch))
#define syscall_arg(x) (offsetof(struct seccomp_data, args[x])) #define syscall_arg(x) (offsetof(struct seccomp_data, args[x]))
#ifndef __AUDIT_ARCH_64BIT
#define __AUDIT_ARCH_64BIT 0x80000000
#endif
#ifndef __AUDIT_ARCH_LE
#define __AUDIT_ARCH_LE 0x40000000
#endif
#ifndef EM_RISCV
#define EM_RISCV 243
#endif
#ifndef AUDIT_ARCH_RISCV64
#define AUDIT_ARCH_RISCV64 (EM_RISCV | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#endif
#ifndef EM_LOONGARCH
#define EM_LOONGARCH 258
#endif
#ifndef AUDIT_ARCH_LOONGARCH64
#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#endif
#if defined(__aarch64__) #if defined(__aarch64__)
# define ARCH_NR AUDIT_ARCH_AARCH64 # define ARCH_NR AUDIT_ARCH_AARCH64
@@ -72,6 +91,14 @@ bool dropcaps(void);
# define ARCH_NR AUDIT_ARCH_RISCV64 # define ARCH_NR AUDIT_ARCH_RISCV64
#elif defined(__loongarch__) && __loongarch_grlen == 64
# define ARCH_NR AUDIT_ARCH_LOONGARCH64
#elif defined(__e2k__)
# define ARCH_NR AUDIT_ARCH_E2K
#else #else
# error "Platform does not support seccomp filter yet" # error "Platform does not support seccomp filter yet"
+1 -1
View File
@@ -4,7 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
bool service_run(); bool service_run(int argc, char *argv[]);
#endif #endif
+11 -7
View File
@@ -1,9 +1,13 @@
CC ?= cc CC ?= cc
OPTIMIZE ?= -Os OPTIMIZE ?= -Os
CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto -ffunction-sections -fdata-sections
CFLAGS_SYSTEMD = -DUSE_SYSTEMD CFLAGS_SYSTEMD = -DUSE_SYSTEMD
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member
LDFLAGS_ANDROID = -llog LDFLAGS += -flto=auto
LDFLAGS_ANDROID = -Wl,--gc-sections -llog
LDFLAGS_BSD = -Wl,--gc-sections
LDFLAGS_LINUX = -Wl,--gc-sections
LDFLAGS_MAC = -Wl,-dead_strip
LIBS = -lz -lpthread LIBS = -lz -lpthread
LIBS_SYSTEMD = -lsystemd LIBS_SYSTEMD = -lsystemd
LIBS_ANDROID = -lz LIBS_ANDROID = -lz
@@ -13,20 +17,20 @@ SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c
all: tpws all: tpws
tpws: $(SRC_FILES) tpws: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LIBS) $(LDFLAGS) $(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LIBS) $(LDFLAGS) $(LDFLAGS_LINUX)
systemd: $(SRC_FILES) systemd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o tpws $(SRC_FILES) $(LIBS) $(LIBS_SYSTEMD) $(LDFLAGS) $(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o tpws $(SRC_FILES) $(LIBS) $(LIBS_SYSTEMD) $(LDFLAGS) $(LDFLAGS_LINUX)
android: $(SRC_FILES) android: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LIBS_ANDROID) $(LDFLAGS) $(LDFLAGS_ANDROID) $(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LIBS_ANDROID) $(LDFLAGS) $(LDFLAGS_ANDROID)
bsd: $(SRC_FILES) bsd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) $(CC) -s $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) $(LDFLAGS_BSD)
mac: $(SRC_FILES) mac: $(SRC_FILES)
$(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsa -target arm64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) $(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsa -target arm64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) $(LDFLAGS_MAC)
$(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsx -target x86_64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) $(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsx -target x86_64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) $(LDFLAGS_MAC)
strip tpwsa tpwsx strip tpwsa tpwsx
lipo -create -output tpws tpwsx tpwsa lipo -create -output tpws tpwsx tpwsa
rm -f tpwsx tpwsa rm -f tpwsx tpwsa
+1 -1
View File
@@ -74,7 +74,7 @@ struct desync_profile
struct hostlist_collection_head hl_collection, hl_collection_exclude; struct hostlist_collection_head hl_collection, hl_collection_exclude;
// pointer to autohostlist. NULL if no autohostlist for the profile. // pointer to autohostlist. NULL if no autohostlist for the profile.
struct hostlist_file *hostlist_auto; struct hostlist_file *hostlist_auto;
int hostlist_auto_fail_threshold, hostlist_auto_fail_time, hostlist_auto_retrans_threshold; int hostlist_auto_fail_threshold, hostlist_auto_fail_time;
hostfail_pool *hostlist_auto_fail_counters; hostfail_pool *hostlist_auto_fail_counters;
}; };
+27
View File
@@ -20,6 +20,25 @@ bool dropcaps(void);
#define arch_nr (offsetof(struct seccomp_data, arch)) #define arch_nr (offsetof(struct seccomp_data, arch))
#define syscall_arg(x) (offsetof(struct seccomp_data, args[x])) #define syscall_arg(x) (offsetof(struct seccomp_data, args[x]))
#ifndef __AUDIT_ARCH_64BIT
#define __AUDIT_ARCH_64BIT 0x80000000
#endif
#ifndef __AUDIT_ARCH_LE
#define __AUDIT_ARCH_LE 0x40000000
#endif
#ifndef EM_RISCV
#define EM_RISCV 243
#endif
#ifndef AUDIT_ARCH_RISCV64
#define AUDIT_ARCH_RISCV64 (EM_RISCV | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#endif
#ifndef EM_LOONGARCH
#define EM_LOONGARCH 258
#endif
#ifndef AUDIT_ARCH_LOONGARCH64
#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#endif
#if defined(__aarch64__) #if defined(__aarch64__)
# define ARCH_NR AUDIT_ARCH_AARCH64 # define ARCH_NR AUDIT_ARCH_AARCH64
@@ -74,6 +93,14 @@ bool dropcaps(void);
# define ARCH_NR AUDIT_ARCH_RISCV64 # define ARCH_NR AUDIT_ARCH_RISCV64
#elif defined(__loongarch__) && __loongarch_grlen == 64
# define ARCH_NR AUDIT_ARCH_LOONGARCH64
#elif defined(__e2k__)
# define ARCH_NR AUDIT_ARCH_E2K
#else #else
# error "Platform does not support seccomp filter yet" # error "Platform does not support seccomp filter yet"
+2 -2
View File
@@ -1273,7 +1273,7 @@ void parse_params(int argc, char *argv[])
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 IDX_HOSTLIST_AUTO_FAIL_THRESHOLD: case IDX_HOSTLIST_AUTO_FAIL_THRESHOLD:
dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg); dp->hostlist_auto_fail_threshold = atoi(optarg);
if (dp->hostlist_auto_fail_threshold<1 || dp->hostlist_auto_fail_threshold>20) if (dp->hostlist_auto_fail_threshold<1 || dp->hostlist_auto_fail_threshold>20)
{ {
DLOG_ERR("auto hostlist fail threshold must be within 1..20\n"); DLOG_ERR("auto hostlist fail threshold must be within 1..20\n");
@@ -1281,7 +1281,7 @@ void parse_params(int argc, char *argv[])
} }
break; break;
case IDX_HOSTLIST_AUTO_FAIL_TIME: case IDX_HOSTLIST_AUTO_FAIL_TIME:
dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg); dp->hostlist_auto_fail_time = atoi(optarg);
if (dp->hostlist_auto_fail_time<1) if (dp->hostlist_auto_fail_time<1)
{ {
DLOG_ERR("auto hostlist fail time is not valid\n"); DLOG_ERR("auto hostlist fail time is not valid\n");
+1 -4
View File
@@ -835,8 +835,6 @@ static bool handle_unsent(tproxy_conn_t *conn)
static bool proxy_mode_connect_remote(tproxy_conn_t *conn, struct tailhead *conn_list) static bool proxy_mode_connect_remote(tproxy_conn_t *conn, struct tailhead *conn_list)
{ {
int remote_fd;
if (params.debug>=1) if (params.debug>=1)
{ {
char ip_port[48]; char ip_port[48];
@@ -850,9 +848,8 @@ static bool proxy_mode_connect_remote(tproxy_conn_t *conn, struct tailhead *conn
return false; return false;
} }
if (!(conn->partner = new_conn(remote_fd, true))) if (!(conn->partner = new_conn(0, true)))
{ {
close(remote_fd);
DLOG_ERR("socks out-of-memory (1)\n"); DLOG_ERR("socks out-of-memory (1)\n");
socks_send_rep(conn->socks_ver, conn->fd, S5_REP_GENERAL_FAILURE); socks_send_rep(conn->socks_ver, conn->fd, S5_REP_GENERAL_FAILURE);
return false; return false;